b6bb6e56b9
- Thread focus mode: threads open centered in the main pane (expand button, room-list thread rows, and any ShowThread while focus mode is active); back bar / Escape / channel click return to the timeline. Centering strips the sidebar's thread cards so no duplicate remains. - Room list: active-thread rows under channels (unread threads plus the one currently open), collapsible section headers with per-space persistence, live space-membership DM filtering (fixes the DM section capping at ~6 rooms after a space switch). - CSS: Compound token overrides now also target the body theme class so remapped tokens stop shadowing back to green; reply-quote restyle; min-width on the room body so the message action bar can't render off-pane with a thread panel open in narrow windows (edit "did nothing"). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1584 lines
53 KiB
Plaintext
1584 lines
53 KiB
Plaintext
/*
|
||
* Yap reskin — base token + foundation overlay.
|
||
* Loaded as the top-priority `yap` @layer from the dark-custom theme entry,
|
||
* so these win over upstream Element/Compound styles.
|
||
*
|
||
* Scope: global tokens, fonts, base surfaces, scrollbars.
|
||
* Per-surface restyles (rail, room list, etc.) live in their own files and
|
||
* consume the --yap-* tokens defined here.
|
||
*/
|
||
@layer yap {
|
||
/* Compound defines its dark tokens on `.cpd-theme-dark.cpd-theme-dark`, and
|
||
element-web puts that class on <body>. Custom properties resolve by nearest
|
||
ancestor, so overrides declared only on :root (<html>) are shadowed by
|
||
Compound's body-level values for everything inside the app (this is how the
|
||
send button / unread bar stayed green). Declare on the theme-class elements
|
||
too so our values win on <body> and inside nested cpd-theme-* wrappers. */
|
||
:root,
|
||
[class*="cpd-theme-"] {
|
||
/* ---- Typography ---- */
|
||
--yap-font-sans: "Hanken Grotesk", "Inter", system-ui, sans-serif;
|
||
--yap-font-mono: "JetBrains Mono", "Courier New", monospace;
|
||
|
||
/* Override both legacy + Compound font tokens */
|
||
--font-family: var(--yap-font-sans);
|
||
--font-family-monospace: var(--yap-font-mono);
|
||
--cpd-font-family-sans: var(--yap-font-sans);
|
||
--cpd-font-family-mono: var(--yap-font-mono);
|
||
|
||
/* ---- Surfaces (dark only) ---- */
|
||
--yap-surface-titlebar: #101017;
|
||
--yap-surface-rail: #101017;
|
||
--yap-surface-roomlist: #1a1922;
|
||
--yap-surface-main: #201e29;
|
||
--yap-surface-userpanel: #131219;
|
||
--yap-surface-composer: #2a2735;
|
||
--yap-surface-card: rgba(255, 255, 255, 0.025);
|
||
--yap-surface-card-hover: rgba(255, 255, 255, 0.06);
|
||
--yap-hairline: rgba(255, 255, 255, 0.06);
|
||
--yap-divider-heavy: rgba(0, 0, 0, 0.25);
|
||
|
||
/* ---- Text ---- */
|
||
--yap-text-primary: #ece9f5;
|
||
--yap-text-secondary: #b8b4c6;
|
||
--yap-text-muted: #8b8799;
|
||
--yap-text-faint: #6b6878;
|
||
|
||
/* ---- Accent (themeable) ---- */
|
||
--yap-accent: #7c66e0;
|
||
--yap-accent-soft: color-mix(in srgb, var(--yap-accent) 16%, transparent);
|
||
|
||
/* ---- Status / semantic ---- */
|
||
--yap-success: #46c08d;
|
||
--yap-idle: #e8b04b;
|
||
--yap-danger: #e5697a;
|
||
|
||
/* ---- Network (bridge) brand colors ---- */
|
||
--yap-net-telegram: #2aabee;
|
||
--yap-net-discord: #5b6ee8;
|
||
--yap-net-meta: #0a7cff;
|
||
|
||
/* ---- Squircle radius scale (consumed per-surface) ---- */
|
||
--yap-radius-space: 15px;
|
||
--yap-radius-avatar-chat: 14px;
|
||
--yap-radius-avatar-member: 11px;
|
||
--yap-radius-avatar-user: 12px;
|
||
--yap-radius-avatar-dm: 10px;
|
||
--yap-radius-card: 16px;
|
||
--yap-radius-row: 8px;
|
||
|
||
/* ---- Accent remap: override Compound's green accent → Yap purple ----
|
||
(Was in config.json custom theme; moved here so it loads on the
|
||
built-in Dark theme instead of the fragile custom-theme path.) */
|
||
--cpd-color-text-action-accent: var(--yap-accent) !important;
|
||
--cpd-color-icon-accent-primary: var(--yap-accent) !important;
|
||
--cpd-color-icon-accent-tertiary: #9580ea !important;
|
||
/* Compound's token defs are unlayered, so these MUST be !important to win
|
||
over them — otherwise primary buttons (Sign in, Continue, Got it, the
|
||
E2E verify dialogs) render Element-default white instead of accent.
|
||
Note the canonical name is `-hovered`, not `-hover`. */
|
||
--cpd-color-bg-action-primary-rest: var(--yap-accent) !important;
|
||
--cpd-color-bg-action-primary-hovered: #8b78e8 !important;
|
||
--cpd-color-bg-action-primary-pressed: #6e58d0 !important;
|
||
--cpd-color-border-interactive-primary: var(--yap-accent) !important;
|
||
|
||
/* Remap the WHOLE Compound green scale → purple. Element's brand accent is
|
||
green and legacy `$accent-*` resolve to these tokens, so any leftover
|
||
default (new-message bar, jump-to-bottom badge, read marker, links, etc.)
|
||
inherits Blap purple from here in one shot. Dark ramp: low = subtle bg,
|
||
~900 = solid accent, high = light text. */
|
||
--cpd-color-green-100: #18151f;
|
||
--cpd-color-green-200: #1e1a2b;
|
||
--cpd-color-green-300: #271f3d;
|
||
--cpd-color-green-400: #322852;
|
||
--cpd-color-green-500: #3f3469;
|
||
--cpd-color-green-600: #4f4185;
|
||
--cpd-color-green-700: #6253a8;
|
||
--cpd-color-green-800: #6f5ecb;
|
||
--cpd-color-green-900: #7c66e0;
|
||
--cpd-color-green-1000: #8b78e8;
|
||
--cpd-color-green-1100: #9d8bec;
|
||
--cpd-color-green-1200: #b3a5f1;
|
||
--cpd-color-green-1300: #ccc1f6;
|
||
--cpd-color-green-1400: #e2dbfb;
|
||
|
||
/* Squircle ALL Compound avatars (people + rooms) in one shot:
|
||
the Avatar component renders `border-radius: var(--cpd-avatar-radius)`.
|
||
!important to beat the unlayered default. */
|
||
--cpd-avatar-radius: 30% !important;
|
||
|
||
/* ---- Background canvas tokens (the MAIN pane). Without these the
|
||
main content area falls back to light. Force the Yap surfaces. ---- */
|
||
--cpd-color-bg-canvas-default: var(--yap-surface-main) !important;
|
||
--cpd-color-bg-canvas-disabled: #1a1922 !important;
|
||
--cpd-color-bg-subtle-primary: #26242f !important;
|
||
--cpd-color-bg-subtle-secondary: var(--yap-surface-roomlist) !important;
|
||
}
|
||
|
||
body {
|
||
font-family: var(--yap-font-sans);
|
||
-webkit-font-smoothing: antialiased;
|
||
-moz-osx-font-smoothing: grayscale;
|
||
}
|
||
|
||
/* Mono everywhere timestamps / ids / code render */
|
||
.mx_MessageTimestamp,
|
||
code,
|
||
kbd,
|
||
pre {
|
||
font-family: var(--yap-font-mono);
|
||
}
|
||
|
||
/* ---- Scrollbars (README spec) ---- */
|
||
::-webkit-scrollbar {
|
||
width: 8px;
|
||
height: 8px;
|
||
}
|
||
::-webkit-scrollbar-thumb {
|
||
background: rgba(255, 255, 255, 0.07);
|
||
border-radius: 8px;
|
||
}
|
||
::-webkit-scrollbar-thumb:hover {
|
||
background: rgba(255, 255, 255, 0.14);
|
||
}
|
||
|
||
/* ============================================================
|
||
Per-surface restyle
|
||
(yap is the top @layer, so these win over Element's app-web
|
||
layer without specificity fights; !important only where
|
||
Element sets values inline.)
|
||
============================================================ */
|
||
|
||
/* ---- Three distinct pane tiers ---- */
|
||
.mx_SpacePanel {
|
||
background-color: var(--yap-surface-rail);
|
||
}
|
||
.mx_LeftPanel,
|
||
.mx_RoomListPanel {
|
||
background-color: var(--yap-surface-roomlist);
|
||
}
|
||
/* main column (mirrors Element's own canvas selector) */
|
||
.mx_MatrixChat
|
||
> :not(.mx_LeftPanel):not(.mx_SpacePanel):not(.mx_ResizeHandle):not(.mx_LeftPanel_outerWrapper) {
|
||
background-color: var(--yap-surface-main);
|
||
}
|
||
.mx_RoomView,
|
||
.mx_HomePage {
|
||
background-color: var(--yap-surface-main);
|
||
}
|
||
|
||
/* ---- Spaces rail ---- */
|
||
.mx_SpacePanel,
|
||
.mx_SpacePanel.collapsed {
|
||
width: 74px;
|
||
padding-block: 10px;
|
||
}
|
||
.mx_SpacePanel {
|
||
/* chunkier top-level space icons (mockup ~46px) */
|
||
--height-topLevel: 44px;
|
||
--gutterSize: 0px;
|
||
}
|
||
/* center the icons in the rail. The selectionWrapper is flex:1 / calc(100%-32px)
|
||
(reserving room for the removed label+chevron), so the avatar sits left.
|
||
Shrink it to the avatar, then center the button content. */
|
||
.mx_SpacePanel .mx_SpaceItem,
|
||
.mx_SpacePanel .mx_SpaceItem > .mx_SpaceButton,
|
||
.mx_SpacePanel .mx_SpaceItem.hasSubSpaces > .mx_SpaceButton {
|
||
margin-left: 0 !important;
|
||
padding-left: 0 !important;
|
||
}
|
||
.mx_SpacePanel .mx_SpaceButton {
|
||
justify-content: center !important;
|
||
padding: 4px !important;
|
||
}
|
||
.mx_SpacePanel .mx_SpaceButton_selectionWrapper {
|
||
flex: 0 0 auto !important;
|
||
width: auto !important;
|
||
margin: 0 !important;
|
||
}
|
||
/* force centering at every level of the rail (panel > list > item) */
|
||
.mx_SpacePanel,
|
||
.mx_SpacePanel > .mx_AutoHideScrollbar,
|
||
.mx_SpacePanel .mx_SpaceTreeLevel,
|
||
.mx_SpacePanel ul,
|
||
.mx_SpacePanel .mx_SpaceItem {
|
||
align-items: center !important;
|
||
}
|
||
.mx_SpacePanel .mx_SpaceItem {
|
||
width: 100% !important;
|
||
padding-inline: 0 !important;
|
||
margin-inline: 0 !important;
|
||
justify-content: center !important;
|
||
}
|
||
/* squircle space icons (Element sets avatar radius inline) */
|
||
.mx_SpacePanel .mx_BaseAvatar {
|
||
border-radius: var(--yap-radius-space) !important;
|
||
}
|
||
/* active space = accent ring, no Discord pill */
|
||
.mx_SpacePanel .mx_SpaceButton_active {
|
||
--activeBorder-color: var(--yap-accent);
|
||
--activeBackground-color: transparent;
|
||
}
|
||
/* Clean icon-only rail: kill overflowing name labels, the inline subspace
|
||
dropdown chevrons (just open the space in the main view), and the
|
||
redundant Settings button (now in the bottom user panel). */
|
||
.mx_SpacePanel .mx_SpaceButton_name,
|
||
.mx_SpacePanel .mx_SpaceButton_toggleCollapse,
|
||
.mx_SpacePanel_toggleCollapse,
|
||
.mx_QuickSettingsButton,
|
||
.mx_SpacePanel .mx_ThreadsActivityCentreButton,
|
||
.mx_SpacePanel .mx_UserMenu {
|
||
display: none !important;
|
||
}
|
||
/* Threads moved into the bottom user panel — normalise it to a centered
|
||
32px box matching the settings button. */
|
||
.mx_YapUserPanel_threads {
|
||
flex-shrink: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.mx_YapUserPanel_threads .mx_ThreadsActivityCentreButton_Text,
|
||
.mx_YapUserPanel_threads .mx_ThreadsActivityCentreButton_Icon + * {
|
||
display: none !important;
|
||
}
|
||
.mx_YapUserPanel_threads .mx_ThreadsActivityCentreButton,
|
||
.mx_YapUserPanel_threads button {
|
||
width: 32px !important;
|
||
min-width: 32px !important;
|
||
height: 32px !important;
|
||
padding: 0 !important;
|
||
margin: 0 !important;
|
||
display: flex !important;
|
||
align-items: center !important;
|
||
justify-content: center !important;
|
||
color: var(--yap-text-muted) !important;
|
||
}
|
||
/* center the icons now that labels are gone */
|
||
.mx_SpacePanel .mx_SpaceButton {
|
||
justify-content: center;
|
||
}
|
||
|
||
/* ---- Space "..." options context menu (mx_SpacePanel_contextMenu) ----
|
||
Opened from the narrow rail it rendered too narrow, ellipsizing labels
|
||
("Home" -> "Ho") and clipping the option tooltips, and it sat on the
|
||
default surface. Give it a Blap surface + enough room so nothing clips. */
|
||
.mx_ContextualMenu.mx_SpacePanel_contextMenu,
|
||
.mx_SpacePanel_contextMenu {
|
||
min-width: 240px;
|
||
max-width: 320px;
|
||
background-color: var(--yap-surface-composer, var(--cpd-color-bg-canvas-default));
|
||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||
border-radius: 14px;
|
||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
|
||
overflow: visible; /* let option tooltips escape the menu box */
|
||
}
|
||
.mx_SpacePanel_contextMenu .mx_IconizedContextMenu_optionList,
|
||
.mx_SpacePanel_contextMenu .mx_IconizedContextMenu_optionList > * {
|
||
overflow: visible;
|
||
}
|
||
/* never ellipsize the option labels — there's room for them now */
|
||
.mx_SpacePanel_contextMenu .mx_IconizedContextMenu_label {
|
||
overflow: visible;
|
||
text-overflow: clip;
|
||
white-space: nowrap;
|
||
}
|
||
.mx_SpacePanel_contextMenu_header {
|
||
color: var(--yap-text-primary, inherit);
|
||
}
|
||
|
||
/* ---- Image lightbox: make the top toolbar + tools clearly visible ----
|
||
The panel was transparent over the dark backdrop, so the zoom/rotate/
|
||
download/close tools nearly vanished. Give it a translucent bar and
|
||
brighten the icons with a hover affordance. */
|
||
.mx_ImageView_panel {
|
||
background: rgba(20, 18, 26, 0.82);
|
||
backdrop-filter: blur(8px);
|
||
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||
}
|
||
.mx_ImageView_button svg {
|
||
color: var(--yap-text-primary) !important;
|
||
}
|
||
.mx_ImageView_button:hover {
|
||
background: rgba(255, 255, 255, 0.1);
|
||
border-radius: 8px;
|
||
}
|
||
.mx_ImageView_info_sender,
|
||
.mx_ImageView_title {
|
||
color: var(--yap-text-primary);
|
||
}
|
||
|
||
/* ---- Toasts (incl. the "New update" ping) → Blap surface ----
|
||
Was Element-default; match the app surface + rounding. The primary
|
||
"Update" button picks up the accent fix automatically. */
|
||
.mx_Toast_toast {
|
||
background-color: var(--yap-surface-composer) !important;
|
||
border: 1px solid rgba(255, 255, 255, 0.07);
|
||
border-radius: 14px;
|
||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
|
||
}
|
||
.mx_Toast_title h2 {
|
||
color: var(--yap-text-primary);
|
||
}
|
||
.mx_Toast_description {
|
||
color: var(--yap-text-secondary);
|
||
}
|
||
|
||
/* ---- Room list: the LIVE list is shared-components mx_RoomListItemView,
|
||
NOT the legacy mx_RoomTile. Target the real class. ---- */
|
||
.mx_RoomListItemView .mx_BaseAvatar {
|
||
border-radius: var(--yap-radius-avatar-dm) !important;
|
||
}
|
||
/* ---- Yap channel-row room list (replaces Element's filter-list) ---- */
|
||
.mx_YapRoomList {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 1px;
|
||
padding: 6px;
|
||
overflow-y: auto;
|
||
flex: 1 1 0;
|
||
min-height: 0;
|
||
}
|
||
.mx_YapRoomRow {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
height: 34px;
|
||
padding: 0 8px;
|
||
border-radius: var(--yap-radius-row);
|
||
color: var(--yap-text-muted);
|
||
cursor: pointer;
|
||
font-size: 15px;
|
||
font-weight: 500;
|
||
user-select: none;
|
||
}
|
||
.mx_YapRoomRow:hover {
|
||
background-color: rgba(255, 255, 255, 0.04);
|
||
color: var(--yap-text-secondary);
|
||
}
|
||
.mx_YapRoomRow_unread {
|
||
color: var(--yap-text-primary);
|
||
}
|
||
.mx_YapRoomRow_unread .mx_YapRoomRow_name {
|
||
font-weight: 600;
|
||
color: var(--yap-text-primary);
|
||
}
|
||
.mx_YapRoomRow_active,
|
||
.mx_YapRoomRow_active:hover {
|
||
background-color: var(--yap-accent-soft);
|
||
box-shadow: inset 3px 0 0 var(--yap-accent);
|
||
color: var(--yap-text-primary);
|
||
}
|
||
.mx_YapRoomRow_active .mx_YapRoomRow_name {
|
||
color: var(--yap-text-primary);
|
||
font-weight: 600;
|
||
}
|
||
.mx_YapRoomRow_glyph {
|
||
font-size: 20px;
|
||
color: var(--yap-text-faint);
|
||
flex-shrink: 0;
|
||
width: 20px;
|
||
text-align: center;
|
||
}
|
||
.mx_YapRoomRow_glyphSvg {
|
||
flex-shrink: 0;
|
||
color: var(--yap-text-faint);
|
||
}
|
||
.mx_YapRoomRow_name {
|
||
flex: 1 1 0;
|
||
min-width: 0;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
.mx_YapRoomRow_dm .mx_BaseAvatar {
|
||
flex-shrink: 0;
|
||
}
|
||
.mx_YapRoomRow_badge {
|
||
flex-shrink: 0;
|
||
min-width: 18px;
|
||
height: 18px;
|
||
padding: 0 5px;
|
||
border-radius: 9px;
|
||
background-color: var(--yap-text-faint);
|
||
color: var(--yap-surface-rail);
|
||
font-size: 11px;
|
||
font-weight: 700;
|
||
font-variant-numeric: tabular-nums;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.mx_YapRoomRow_badge_mention {
|
||
background-color: var(--yap-danger);
|
||
color: #fff;
|
||
}
|
||
/* bridge-platform badge (which network a DM is from) */
|
||
.mx_YapPlatformBadge {
|
||
flex-shrink: 0;
|
||
padding: 1px 5px;
|
||
border-radius: 6px;
|
||
font-size: 9.5px;
|
||
font-weight: 800;
|
||
letter-spacing: 0.03em;
|
||
line-height: 1.5;
|
||
color: #fff;
|
||
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.25);
|
||
}
|
||
/* invite pill */
|
||
.mx_YapRoomRow_inviteBadge {
|
||
margin-left: auto;
|
||
flex-shrink: 0;
|
||
padding: 1px 7px;
|
||
border-radius: 8px;
|
||
background-color: var(--yap-accent);
|
||
color: #fff;
|
||
font-size: 10.5px;
|
||
font-weight: 700;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.04em;
|
||
}
|
||
/* draggable room rows */
|
||
.mx_YapRoomRow[draggable="true"] {
|
||
cursor: pointer;
|
||
}
|
||
.mx_YapRoomRow[draggable="true"]:active {
|
||
cursor: grabbing;
|
||
}
|
||
/* drop-line indicator: shows where the dragged room will land */
|
||
.mx_YapRoomRow_dropBefore {
|
||
position: relative;
|
||
}
|
||
.mx_YapRoomRow_dropAfter {
|
||
position: relative;
|
||
}
|
||
.mx_YapRoomRow_dropBefore::before,
|
||
.mx_YapRoomRow_dropAfter::after {
|
||
content: "";
|
||
position: absolute;
|
||
left: 8px;
|
||
right: 8px;
|
||
height: 2px;
|
||
border-radius: 1px;
|
||
background-color: var(--yap-accent);
|
||
box-shadow: 0 0 4px var(--yap-accent);
|
||
pointer-events: none;
|
||
}
|
||
.mx_YapRoomRow_dropBefore::before {
|
||
top: -2px;
|
||
}
|
||
.mx_YapRoomRow_dropAfter::after {
|
||
bottom: -2px;
|
||
}
|
||
.mx_YapBrowseRooms {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
height: 36px;
|
||
margin: 2px 0 4px;
|
||
padding: 0 8px;
|
||
border-radius: var(--yap-radius-row);
|
||
color: var(--yap-accent);
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
cursor: pointer;
|
||
}
|
||
.mx_YapBrowseRooms:hover {
|
||
background-color: rgba(255, 255, 255, 0.04);
|
||
}
|
||
/* "N new rooms since you last looked" count badge */
|
||
.mx_YapBrowseRooms_count {
|
||
margin-left: auto;
|
||
flex-shrink: 0;
|
||
min-width: 18px;
|
||
height: 18px;
|
||
padding: 0 5px;
|
||
border-radius: 9px;
|
||
background-color: var(--yap-accent);
|
||
color: #fff;
|
||
font-size: 11px;
|
||
font-weight: 700;
|
||
font-variant-numeric: tabular-nums;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
.mx_YapRoomList_header {
|
||
padding: 14px 10px 4px;
|
||
font-size: 11.5px;
|
||
font-weight: 700;
|
||
letter-spacing: 0.05em;
|
||
text-transform: uppercase;
|
||
color: var(--yap-text-faint);
|
||
}
|
||
/* threads nested under their channel (Discord-style) */
|
||
.mx_YapThreadRow {
|
||
margin-left: 22px;
|
||
padding-block: 3px;
|
||
font-size: 13px;
|
||
color: var(--yap-text-muted);
|
||
}
|
||
.mx_YapThreadRow .mx_YapRoomRow_name {
|
||
font-weight: 500;
|
||
}
|
||
.mx_YapThreadRow_glyph {
|
||
color: var(--yap-text-faint);
|
||
font-size: 13px;
|
||
width: 16px;
|
||
text-align: center;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
/* collapsible section headers (Discord-style) */
|
||
.mx_YapRoomList_header_toggle {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
cursor: pointer;
|
||
user-select: none;
|
||
}
|
||
.mx_YapRoomList_header_toggle:hover {
|
||
color: var(--yap-text-secondary);
|
||
}
|
||
.mx_YapRoomList_header_chevron {
|
||
display: inline-block;
|
||
font-size: 9px;
|
||
line-height: 1;
|
||
transition: transform 0.15s ease;
|
||
}
|
||
.mx_YapRoomList_header_collapsed .mx_YapRoomList_header_chevron {
|
||
transform: rotate(-90deg);
|
||
}
|
||
/* in-call members shown under a voice channel (who's in before you join) */
|
||
.mx_YapVoiceMembers {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 1px;
|
||
padding: 2px 0 4px 18px;
|
||
}
|
||
.mx_YapVoiceMember {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
height: 28px;
|
||
padding: 0 8px;
|
||
border-radius: var(--yap-radius-row);
|
||
color: var(--yap-text-secondary);
|
||
font-size: 14px;
|
||
}
|
||
.mx_YapVoiceMember:hover {
|
||
background-color: rgba(255, 255, 255, 0.04);
|
||
}
|
||
.mx_YapVoiceMember_name {
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
/* ---- Bottom user panel + voice-connected strip ---- */
|
||
.mx_YapUserPanel {
|
||
margin-top: auto;
|
||
flex-shrink: 0;
|
||
background-color: var(--yap-surface-userpanel);
|
||
border-top: 1px solid var(--yap-hairline);
|
||
}
|
||
.mx_YapVoiceConnected {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
margin: 8px;
|
||
padding: 8px 10px;
|
||
border-radius: 10px;
|
||
background-color: color-mix(in srgb, var(--yap-success) 7%, transparent);
|
||
border: 1px solid color-mix(in srgb, var(--yap-success) 18%, transparent);
|
||
cursor: pointer;
|
||
}
|
||
.mx_YapVoiceConnected_icon {
|
||
color: var(--yap-success);
|
||
flex-shrink: 0;
|
||
}
|
||
.mx_YapVoiceConnected_text {
|
||
display: flex;
|
||
flex-direction: column;
|
||
min-width: 0;
|
||
}
|
||
.mx_YapVoiceConnected_label {
|
||
color: var(--yap-success);
|
||
font-size: 12.5px;
|
||
font-weight: 700;
|
||
}
|
||
.mx_YapVoiceConnected_room {
|
||
color: var(--yap-text-muted);
|
||
font-size: 12px;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
.mx_YapUserPanel_row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
height: 56px;
|
||
padding: 0 10px;
|
||
}
|
||
.mx_YapUserPanel_info {
|
||
display: flex;
|
||
flex-direction: column;
|
||
min-width: 0;
|
||
flex: 1 1 0;
|
||
}
|
||
.mx_YapUserPanel_name {
|
||
color: var(--yap-text-primary);
|
||
font-size: 14px;
|
||
font-weight: 700;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
.mx_YapUserPanel_id {
|
||
color: var(--yap-text-faint);
|
||
font-size: 11.5px;
|
||
font-family: var(--yap-font-mono);
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
.mx_YapUserPanel_btn {
|
||
flex-shrink: 0;
|
||
width: 32px;
|
||
height: 32px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border: none;
|
||
background: transparent;
|
||
color: var(--yap-text-muted);
|
||
border-radius: 8px;
|
||
cursor: pointer;
|
||
}
|
||
.mx_YapUserPanel_btn:hover {
|
||
background-color: rgba(255, 255, 255, 0.06);
|
||
color: var(--yap-text-primary);
|
||
}
|
||
|
||
.mx_RoomListItemView {
|
||
border-radius: var(--yap-radius-row);
|
||
margin-inline: 6px;
|
||
}
|
||
.mx_RoomListItemView:hover {
|
||
background-color: rgba(255, 255, 255, 0.04);
|
||
}
|
||
.mx_RoomListItemView_selected {
|
||
background-color: var(--yap-accent-soft) !important;
|
||
box-shadow: inset 3px 0 0 var(--yap-accent);
|
||
}
|
||
/* legacy list (kept harmless in case it ever renders) */
|
||
.mx_RoomTile_avatarContainer .mx_BaseAvatar {
|
||
border-radius: var(--yap-radius-avatar-dm) !important;
|
||
}
|
||
.mx_RoomTile_selected {
|
||
background-color: var(--yap-accent-soft);
|
||
box-shadow: inset 3px 0 0 var(--yap-accent);
|
||
}
|
||
|
||
/* ============================================================
|
||
Room view (header / timeline / composer)
|
||
============================================================ */
|
||
|
||
/* ---- Room header ---- */
|
||
.mx_RoomHeader {
|
||
height: 50px;
|
||
background-color: var(--yap-surface-main);
|
||
border-bottom: 1px solid var(--yap-divider-heavy);
|
||
}
|
||
|
||
/* ---- Timeline surface ---- */
|
||
.mx_RoomView_messagePanel,
|
||
.mx_RoomView_messageListWrapper {
|
||
background-color: var(--yap-surface-main);
|
||
}
|
||
|
||
/* squircle chat avatars (Element sets radius inline) */
|
||
.mx_EventTile_avatar .mx_BaseAvatar {
|
||
border-radius: var(--yap-radius-avatar-chat) !important;
|
||
}
|
||
|
||
/* sender name weight */
|
||
.mx_DisambiguatedProfile_displayName {
|
||
font-weight: 700;
|
||
}
|
||
|
||
/* image-spoiler upload checkbox */
|
||
.mx_UploadConfirmDialog_spoiler {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
margin: 14px 0 2px;
|
||
color: var(--yap-text-secondary);
|
||
font-size: 14px;
|
||
cursor: pointer;
|
||
}
|
||
|
||
/* message links in accent */
|
||
.mx_EventTile_body a,
|
||
.mx_EventTile_content a {
|
||
color: var(--yap-accent);
|
||
text-decoration: none;
|
||
}
|
||
.mx_EventTile_body a:hover,
|
||
.mx_EventTile_content a:hover {
|
||
text-decoration: underline;
|
||
}
|
||
/* subtle per-message hover */
|
||
.mx_EventTile:not([data-layout="bubble"]):hover .mx_EventTile_line {
|
||
background-color: rgba(255, 255, 255, 0.02);
|
||
border-radius: 6px;
|
||
}
|
||
/* comfortable message vertical rhythm */
|
||
.mx_EventTile {
|
||
padding-top: 6px;
|
||
}
|
||
|
||
/* ---- Discord-style sender row: name + timestamp inline ----
|
||
In group layout Element renders the timestamp absolutely at the left
|
||
of the message line, which lands it under the avatar on the first
|
||
message of a group. We render an inline copy next to the sender name
|
||
(see EventTile.tsx mx_EventTile_senderRow) and hide the gutter one on
|
||
first-in-group tiles. Continuation lines keep the gutter timestamp. */
|
||
.mx_EventTile_senderRow {
|
||
display: flex;
|
||
align-items: baseline;
|
||
gap: 7px;
|
||
margin-left: 64px; /* $left-gutter */
|
||
max-width: calc(100% - 64px);
|
||
}
|
||
.mx_EventTile_senderRow .mx_DisambiguatedProfile {
|
||
margin-left: 0;
|
||
min-width: 0;
|
||
}
|
||
.mx_EventTile_senderRow .mx_MessageTimestamp {
|
||
position: static;
|
||
text-align: left;
|
||
opacity: 0.5;
|
||
flex: 0 0 auto;
|
||
font-size: 11px;
|
||
}
|
||
/* hide the gutter timestamp on the first message of a group (now inline) */
|
||
.mx_EventTile[data-layout="group"]:not(.mx_EventTile_continuation) > .mx_EventTile_line > .mx_MessageTimestamp {
|
||
display: none;
|
||
}
|
||
|
||
/* ---- Composer pill ---- */
|
||
.mx_MessageComposer {
|
||
background-color: var(--yap-surface-main);
|
||
}
|
||
.mx_MessageComposer_wrapper {
|
||
background-color: var(--yap-surface-composer);
|
||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||
border-radius: 13px;
|
||
margin: 0 16px 6px;
|
||
padding: 2px 10px;
|
||
}
|
||
.mx_MessageComposer_input {
|
||
background-color: transparent;
|
||
border: none;
|
||
padding: 4px 4px;
|
||
}
|
||
.mx_MessageComposer_input textarea {
|
||
background-color: transparent !important;
|
||
}
|
||
/* remove the left-gutter e2e-status + avatar icons that overlapped the
|
||
placeholder (encryption status is in the room header; mockup composer
|
||
has no left icon) and reclaim their padding. */
|
||
.mx_MessageComposer_e2eIconWrapper,
|
||
.mx_MessageComposer .mx_MessageComposer_avatar {
|
||
display: none !important;
|
||
}
|
||
.mx_MessageComposer {
|
||
padding-left: 8px !important;
|
||
}
|
||
|
||
/* ============================================================
|
||
Call presence — in-call avatar stack on room rows (headline feature)
|
||
============================================================ */
|
||
.mx_YapCallFacepile {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
margin-inline-start: auto; /* push to trailing edge of the row */
|
||
padding-inline: 4px;
|
||
flex-shrink: 0;
|
||
}
|
||
/* squircle peek avatars with a list-colored border, slight overlap */
|
||
.mx_YapCallFacepile .mx_BaseAvatar {
|
||
border-radius: 7px !important;
|
||
box-shadow: 0 0 0 2px var(--yap-surface-roomlist);
|
||
}
|
||
.mx_YapCallFacepile_more {
|
||
font: var(--cpd-font-body-xs-medium, 11px/1 var(--yap-font-mono));
|
||
font-family: var(--yap-font-mono);
|
||
color: var(--yap-accent);
|
||
font-weight: 700;
|
||
}
|
||
|
||
/* ============================================================
|
||
Right panel — Members
|
||
============================================================ */
|
||
.mx_MemberListView,
|
||
.mx_MemberList {
|
||
background-color: var(--yap-surface-roomlist);
|
||
}
|
||
/* squircle member avatars */
|
||
.mx_MemberTileView_avatar .mx_BaseAvatar {
|
||
border-radius: var(--yap-radius-avatar-member) !important;
|
||
}
|
||
.mx_MemberTileView_name {
|
||
font-weight: 600;
|
||
}
|
||
/* role / section separators (OWNER · ONLINE · OFFLINE) */
|
||
.mx_MemberListView_separator {
|
||
color: var(--yap-text-muted);
|
||
font-size: 11.5px;
|
||
font-weight: 700;
|
||
letter-spacing: 0.05em;
|
||
text-transform: uppercase;
|
||
}
|
||
/* presence dot colors */
|
||
.mx_PresenceLabel_online {
|
||
color: var(--yap-success);
|
||
}
|
||
.mx_PresenceLabel_unavailable {
|
||
color: var(--yap-idle);
|
||
}
|
||
|
||
/* ============================================================
|
||
Reactions — pills
|
||
============================================================ */
|
||
.mx_ReactionsRowButton {
|
||
background-color: var(--yap-accent-soft);
|
||
border: 1px solid color-mix(in srgb, var(--yap-accent) 30%, transparent);
|
||
border-radius: 999px;
|
||
}
|
||
.mx_ReactionsRowButton_count {
|
||
color: var(--yap-accent);
|
||
font-weight: 700;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
|
||
/* Never let the chat pane collapse when the right panel (threads, members…)
|
||
is open in a smaller window: below ~340px the message lines shrink so far
|
||
that the hover action bar (Edit, React…) positions outside the pane —
|
||
invisible and unclickable ("clicking edit does nothing"). The panel
|
||
resizer yields to this minimum instead. */
|
||
.mx_MainSplit > .mx_RoomView_body {
|
||
min-width: 340px;
|
||
}
|
||
|
||
/* ============================================================
|
||
Focused thread view — a thread taking over the main pane
|
||
(Discord "open as page"), plus the header button that opens it.
|
||
============================================================ */
|
||
.mx_BlapCenteredThread {
|
||
display: flex;
|
||
flex-direction: column;
|
||
min-height: 0;
|
||
}
|
||
.mx_BlapCenteredThread_back {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
padding: 10px 16px;
|
||
color: var(--yap-text-secondary);
|
||
font-size: 13.5px;
|
||
border-bottom: 1px solid var(--yap-hairline);
|
||
}
|
||
.mx_BlapCenteredThread_back:hover {
|
||
color: var(--yap-text-primary);
|
||
}
|
||
.mx_BlapCenteredThread_back svg {
|
||
color: var(--yap-accent);
|
||
}
|
||
.mx_BlapCenteredThread .mx_ThreadView {
|
||
flex: 1 1 0;
|
||
min-height: 0;
|
||
/* keep long threads readable in the wide pane */
|
||
max-width: 960px;
|
||
width: 100%;
|
||
margin: 0 auto;
|
||
}
|
||
/* the back bar owns "leave this view" in centered mode — drop the card's ×
|
||
and let the timeline breathe a little */
|
||
.mx_BlapCenteredThread .mx_BaseCard_close {
|
||
display: none;
|
||
}
|
||
.mx_BlapCenteredThread .mx_BaseCard_header {
|
||
border-bottom: none;
|
||
}
|
||
|
||
/* the "open as page" button in the thread panel header */
|
||
.mx_BlapThreadCenterButton {
|
||
display: flex;
|
||
align-items: center;
|
||
color: var(--yap-text-muted);
|
||
margin-left: auto;
|
||
}
|
||
.mx_BlapThreadCenterButton:hover {
|
||
color: var(--yap-accent);
|
||
}
|
||
/* the header title already flexes; keep the context menu at the edge */
|
||
.mx_ThreadView .mx_BaseCard_header_title {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
/* ============================================================
|
||
Reply quotes — Blap card (matches the thread chip vocabulary):
|
||
soft rounded card + accent edge instead of Element's bare
|
||
2px username-colored border.
|
||
============================================================ */
|
||
.mx_ReplyChain {
|
||
background-color: rgba(255, 255, 255, 0.035);
|
||
border-left: 3px solid var(--yap-accent);
|
||
border-radius: 10px;
|
||
padding: 5px 10px;
|
||
margin-bottom: 4px;
|
||
}
|
||
.mx_ReplyChain .mx_ReplyTile > a {
|
||
color: var(--yap-text-secondary);
|
||
}
|
||
.mx_ReplyChain .mx_ReplyChain_show.mx_AccessibleButton_kind_link_inline {
|
||
color: var(--yap-text-muted);
|
||
font-size: 11.5px;
|
||
}
|
||
/* the quoted sender name reads as a Blap label, not a rainbow username */
|
||
.mx_ReplyChain .mx_DisambiguatedProfile > span {
|
||
color: var(--yap-accent) !important;
|
||
font-weight: 600;
|
||
}
|
||
/* composer reply preview ("Replying to …") gets the same card */
|
||
.mx_ReplyPreview {
|
||
background-color: var(--yap-surface-composer);
|
||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||
border-radius: 13px 13px 0 0;
|
||
margin: 0 16px;
|
||
}
|
||
.mx_ReplyPreview .mx_ReplyPreview_header {
|
||
color: var(--yap-text-muted);
|
||
}
|
||
/* markdown blockquotes match the quote language too */
|
||
.mx_EventTile_content blockquote {
|
||
border-left: 3px solid var(--yap-accent);
|
||
background-color: rgba(255, 255, 255, 0.03);
|
||
border-radius: 0 8px 8px 0;
|
||
margin: 4px 0;
|
||
padding: 4px 10px;
|
||
}
|
||
|
||
/* ============================================================
|
||
Thread summary — chip
|
||
============================================================ */
|
||
.mx_ThreadSummary {
|
||
background-color: rgba(255, 255, 255, 0.035);
|
||
border-radius: 12px;
|
||
}
|
||
.mx_ThreadSummary_replyCount,
|
||
.mx_ThreadSummary .mx_ThreadSummary_content {
|
||
color: var(--yap-accent);
|
||
}
|
||
|
||
/* ============================================================
|
||
Room intro block
|
||
============================================================ */
|
||
.mx_NewRoomIntro {
|
||
color: var(--yap-text-secondary);
|
||
}
|
||
|
||
/* ============================================================
|
||
Notification badges (rail + room list, consistent)
|
||
mention = red, unread dot = accent
|
||
============================================================ */
|
||
.mx_NotificationBadge_level_highlight {
|
||
background-color: var(--yap-danger);
|
||
}
|
||
.mx_NotificationBadge_dot {
|
||
background-color: var(--yap-accent);
|
||
}
|
||
|
||
/* ============================================================
|
||
Space landing (the space "directory" head start) — #5
|
||
============================================================ */
|
||
.mx_SpaceRoomView_landing_name {
|
||
font-size: 30px;
|
||
font-weight: 800;
|
||
color: var(--yap-text-primary);
|
||
}
|
||
.mx_SpaceRoomView_landing_topic {
|
||
color: var(--yap-text-muted);
|
||
}
|
||
/* "this is a space, not a server" explainer callout (mockup) */
|
||
.mx_YapSpaceExplainer {
|
||
margin: 18px 0 6px;
|
||
padding: 11px 14px;
|
||
border-radius: 12px;
|
||
background-color: color-mix(in srgb, var(--yap-accent) 9%, transparent);
|
||
border: 1px solid color-mix(in srgb, var(--yap-accent) 22%, transparent);
|
||
color: var(--yap-text-secondary);
|
||
font-size: 13.5px;
|
||
line-height: 1.5;
|
||
}
|
||
.mx_YapSpaceExplainer strong {
|
||
color: var(--yap-text-primary);
|
||
font-weight: 700;
|
||
}
|
||
|
||
/* ============================================================
|
||
Room header — icon cluster + header facepile
|
||
============================================================ */
|
||
.mx_RoomHeader_icon {
|
||
color: var(--yap-text-muted);
|
||
}
|
||
.mx_RoomHeader_heading {
|
||
font-weight: 700;
|
||
color: var(--yap-text-primary);
|
||
}
|
||
/* # glyph + topic line in the header (mockup) */
|
||
.mx_RoomHeader_info {
|
||
display: flex !important;
|
||
align-items: center;
|
||
min-width: 0;
|
||
}
|
||
.mx_YapHeader_hash {
|
||
color: var(--yap-text-faint);
|
||
font-weight: 700;
|
||
margin-right: 3px;
|
||
}
|
||
.mx_YapHeader_topic {
|
||
margin-left: 12px;
|
||
padding-left: 12px;
|
||
border-left: 1px solid var(--yap-hairline);
|
||
color: var(--yap-text-muted);
|
||
font-size: 13.5px;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
flex: 1 1 auto;
|
||
min-width: 0;
|
||
}
|
||
.mx_RoomHeader .mx_FacePile .mx_BaseAvatar {
|
||
border-radius: 7px !important;
|
||
}
|
||
/* make the call control read as the mockup's accent "Call" affordance */
|
||
.mx_RoomHeader_videoCallOption {
|
||
color: var(--yap-accent);
|
||
}
|
||
|
||
/* ============================================================
|
||
Polish — selection bar, composer buttons, rail add button
|
||
============================================================ */
|
||
/* active room: inset accent left-bar (mockup) */
|
||
.mx_RoomTile_selected {
|
||
box-shadow: inset 3px 0 0 var(--yap-accent);
|
||
}
|
||
/* composer: send in accent, other actions muted */
|
||
.mx_MessageComposer_sendMessage {
|
||
color: var(--yap-accent);
|
||
}
|
||
.mx_MessageComposer_button {
|
||
color: var(--yap-text-muted);
|
||
}
|
||
/* spaces rail: "add" utility reads green (mockup) */
|
||
.mx_SpaceButton_new .mx_SpaceButton_icon {
|
||
color: var(--yap-success);
|
||
}
|
||
|
||
/* ============================================================
|
||
Space Directory — browse & join card grid (#5)
|
||
Restyle of SpaceHierarchy's list into the mockup card grid.
|
||
(Element shows joined + unjoined in one list with View/Join
|
||
buttons; a two-section split would need React.)
|
||
============================================================ */
|
||
.mx_SpaceHierarchy_list {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fill, minmax(282px, 1fr));
|
||
gap: 14px;
|
||
list-style: none;
|
||
padding: 0;
|
||
}
|
||
.mx_SpaceHierarchy_roomTileWrapper {
|
||
margin: 0;
|
||
}
|
||
.mx_SpaceHierarchy_roomTile {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: stretch;
|
||
gap: 10px;
|
||
background-color: var(--yap-surface-card);
|
||
border: 1px solid var(--yap-hairline);
|
||
border-radius: var(--yap-radius-card);
|
||
padding: 16px;
|
||
}
|
||
.mx_SpaceHierarchy_roomTile:hover {
|
||
background-color: var(--yap-surface-card-hover);
|
||
}
|
||
.mx_SpaceHierarchy_roomTile_avatar .mx_BaseAvatar {
|
||
border-radius: 13px !important;
|
||
}
|
||
.mx_SpaceHierarchy_roomTile_name {
|
||
font-weight: 700;
|
||
color: var(--yap-text-primary);
|
||
}
|
||
.mx_SpaceHierarchy_listHeader {
|
||
color: var(--yap-text-muted);
|
||
font-weight: 700;
|
||
letter-spacing: 0.05em;
|
||
text-transform: uppercase;
|
||
}
|
||
/* join-state section headers (Your rooms / haven't joined / Spaces) span the grid */
|
||
.mx_YapHierarchy_sectionHeader {
|
||
grid-column: 1 / -1;
|
||
margin: 16px 0 2px;
|
||
font-size: 11.5px;
|
||
font-weight: 700;
|
||
letter-spacing: 0.05em;
|
||
text-transform: uppercase;
|
||
color: var(--yap-text-muted);
|
||
}
|
||
/* hide the admin "manage suggested rooms" clutter (checkboxes + ADD/REMOVE/
|
||
MARK buttons) — not in the mockup; cards are clean + clickable.
|
||
The checkbox is a Compound <Form>/InlineField, not .mx_Checkbox. */
|
||
.mx_SpaceHierarchy_listHeader_buttons,
|
||
.mx_SpaceHierarchy_actions form,
|
||
.mx_SpaceHierarchy_actions [class*="_inline-field"],
|
||
.mx_SpaceHierarchy_actions input[type="checkbox"] {
|
||
display: none !important;
|
||
}
|
||
/* show the Open/Join button always (Element hides it until hover), bottom-right */
|
||
.mx_SpaceHierarchy_roomTile .mx_SpaceHierarchy_actions {
|
||
margin: 8px 0 0 auto;
|
||
align-self: flex-end;
|
||
}
|
||
.mx_SpaceHierarchy_roomTile .mx_SpaceHierarchy_actions .mx_AccessibleButton {
|
||
visibility: visible !important;
|
||
border-radius: 9px;
|
||
font-weight: 700;
|
||
}
|
||
.mx_SpaceHierarchy_roomTile .mx_AccessibleButton_kind_primary {
|
||
background-color: var(--yap-accent) !important;
|
||
}
|
||
|
||
/* ============================================================
|
||
Bridges panel (#6) — static bridge cards in the right panel
|
||
============================================================ */
|
||
.mx_YapBridgesView {
|
||
background-color: var(--yap-surface-roomlist);
|
||
}
|
||
.mx_YapBridgesView_list {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 10px;
|
||
padding: 12px;
|
||
}
|
||
.mx_YapBridgesView_empty {
|
||
color: var(--yap-text-muted);
|
||
font-size: 13.5px;
|
||
padding: 8px 4px;
|
||
}
|
||
|
||
/* ---- Pinned messages (banner + right-panel card + tiles) ---- */
|
||
.mx_PinnedMessageBanner {
|
||
background-color: var(--yap-surface-main);
|
||
border-bottom: 1px solid var(--yap-hairline);
|
||
box-shadow: none;
|
||
}
|
||
.mx_PinnedMessageBanner_main {
|
||
border-radius: 8px;
|
||
}
|
||
.mx_PinnedMessageBanner_main:hover {
|
||
background-color: var(--yap-surface-card);
|
||
}
|
||
.mx_PinnedMessageBanner_title {
|
||
color: var(--yap-accent) !important;
|
||
}
|
||
.mx_PinnedMessageBanner_PinIcon {
|
||
fill: var(--yap-text-muted) !important;
|
||
}
|
||
.mx_PinnedMessageBanner_Indicator {
|
||
background-color: var(--yap-hairline) !important;
|
||
}
|
||
.mx_PinnedMessageBanner_Indicator--active {
|
||
background-color: var(--yap-accent) !important;
|
||
}
|
||
|
||
/* right-panel card */
|
||
.mx_PinnedMessagesCard .mx_PinnedMessagesCard_Separator hr,
|
||
.mx_PinnedMessagesCard .mx_Separator {
|
||
border-color: var(--yap-hairline);
|
||
}
|
||
.mx_PinnedMessagesCard_unpin {
|
||
background: var(--yap-surface-roomlist);
|
||
box-shadow: none;
|
||
border-top: 1px solid var(--yap-hairline);
|
||
}
|
||
|
||
/* each pinned message rendered as a soft card */
|
||
.mx_PinnedEventTile {
|
||
padding: 10px 12px;
|
||
border-radius: 12px;
|
||
background-color: var(--yap-surface-card);
|
||
border: 1px solid var(--yap-hairline);
|
||
transition: background-color 0.12s ease;
|
||
}
|
||
.mx_PinnedEventTile:hover {
|
||
background-color: var(--yap-surface-card-hover);
|
||
}
|
||
.mx_PinnedEventTile_sender {
|
||
color: var(--yap-text-primary);
|
||
}
|
||
.mx_PinnedEventTile_thread span {
|
||
color: var(--yap-text-muted) !important;
|
||
}
|
||
.mx_PinnedEventTile_thread svg {
|
||
fill: var(--yap-text-faint) !important;
|
||
}
|
||
.mx_PinnedEventTile_thread button,
|
||
.mx_PinnedEventTile .mx_EventTile_body a {
|
||
color: var(--yap-accent);
|
||
}
|
||
|
||
/* ---- Right panel: room info card ---- */
|
||
.mx_RoomSummaryCard_roomName {
|
||
color: var(--yap-text-primary);
|
||
font-weight: 700;
|
||
}
|
||
.mx_RoomSummaryCard_alias {
|
||
color: var(--yap-text-muted);
|
||
}
|
||
.mx_RoomSummaryCard_topic,
|
||
.mx_RoomSummaryCard_topic_box {
|
||
color: var(--yap-text-secondary);
|
||
}
|
||
/* info pills (encryption state / history visibility) themed off Element blue/green */
|
||
.mx_RoomSummaryCard_badges [data-kind] {
|
||
background-color: var(--yap-surface-card) !important;
|
||
border: 1px solid var(--yap-hairline) !important;
|
||
color: var(--yap-text-secondary) !important;
|
||
box-shadow: none !important;
|
||
}
|
||
.mx_RoomSummaryCard_badges [data-kind] svg {
|
||
color: currentColor !important;
|
||
fill: currentColor !important;
|
||
}
|
||
.mx_RoomSummaryCard_badges [data-kind="green"] {
|
||
color: #5ed1a0 !important; /* encrypted = positive */
|
||
border-color: color-mix(in srgb, #5ed1a0 32%, transparent) !important;
|
||
}
|
||
/* separators + menu rows */
|
||
.mx_RoomSummaryCard hr,
|
||
.mx_RoomSummaryCard [role="separator"] {
|
||
border-color: var(--yap-hairline) !important;
|
||
background-color: var(--yap-hairline) !important;
|
||
}
|
||
.mx_RoomSummaryCard [role="menuitem"]:hover,
|
||
.mx_RoomSummaryCard [role="menuitemcheckbox"]:hover {
|
||
background-color: var(--yap-surface-card) !important;
|
||
border-radius: 8px;
|
||
}
|
||
/* accent the edit/links + the search field */
|
||
.mx_RoomSummaryCard_topic_edit,
|
||
.mx_RoomSummaryCard a {
|
||
color: var(--yap-accent);
|
||
}
|
||
.mx_RoomSummaryCard_search {
|
||
background-color: var(--yap-surface-card);
|
||
border: 1px solid var(--yap-hairline);
|
||
border-radius: 10px;
|
||
}
|
||
|
||
/* ---- Polls (timeline poll body + options) ---- */
|
||
.mx_MPollBody_totalVotes {
|
||
color: var(--yap-text-muted);
|
||
}
|
||
.mx_PollOption {
|
||
border: 1px solid var(--yap-hairline) !important;
|
||
background-color: var(--yap-surface-card) !important;
|
||
border-radius: 10px !important;
|
||
}
|
||
.mx_PollOption.mx_PollOption_live-option:hover {
|
||
background-color: var(--yap-surface-card-hover) !important;
|
||
border-color: var(--yap-accent) !important;
|
||
}
|
||
/* selected option gets an accent outline */
|
||
.mx_PollOption_checked {
|
||
border-color: var(--yap-accent) !important;
|
||
}
|
||
/* popularity bar: track + accent fill */
|
||
.mx_PollOption_popularityBackground {
|
||
background-color: var(--yap-hairline) !important;
|
||
}
|
||
.mx_PollOption_popularityAmount {
|
||
background-color: var(--yap-accent) !important;
|
||
}
|
||
.mx_PollOption_checked .mx_PollOption_popularityBackground .mx_PollOption_popularityAmount,
|
||
.mx_PollOption_ended.mx_PollOption_checked .mx_PollOption_popularityBackground .mx_PollOption_popularityAmount {
|
||
background-color: var(--yap-accent) !important;
|
||
}
|
||
/* checked radio → accent fill + checkmark */
|
||
.mx_PollOption_checked .mx_StyledRadioButton_checked input[type="radio"]:checked + div,
|
||
.mx_PollOption_ended.mx_PollOption_checked .mx_StyledRadioButton_checked input[type="radio"]:checked + div {
|
||
border-color: var(--yap-accent) !important;
|
||
background-color: var(--yap-accent) !important;
|
||
}
|
||
.mx_PollOption_optionVoteCount {
|
||
color: var(--yap-text-secondary);
|
||
}
|
||
|
||
/* ---- Poll create dialog ---- */
|
||
.mx_PollCreateDialog_option {
|
||
background-color: var(--yap-surface-card);
|
||
border: 1px solid var(--yap-hairline);
|
||
border-radius: 10px;
|
||
}
|
||
.mx_PollCreateDialog_addOption {
|
||
color: var(--yap-accent);
|
||
}
|
||
|
||
/* ---- Settings menus (dialog: tabs, sections, fields) ---- */
|
||
/* left tab list: active tab → accent */
|
||
.mx_TabbedView_tabLabel_active {
|
||
background-color: var(--yap-accent-soft) !important;
|
||
color: var(--yap-accent) !important;
|
||
}
|
||
.mx_TabbedView_tabLabel_active .mx_TabbedView_tabLabel_text {
|
||
color: var(--yap-accent) !important;
|
||
}
|
||
.mx_TabbedView_tabLabel:hover {
|
||
background-color: var(--yap-surface-card) !important;
|
||
}
|
||
.mx_UserSettingsDialog_title_strong,
|
||
.mx_SettingsSection_header,
|
||
.mx_SettingsSubsectionHeading_heading {
|
||
color: var(--yap-text-primary);
|
||
}
|
||
.mx_SettingsSubsection_description,
|
||
.mx_SettingsTab_subsectionText,
|
||
.mx_SettingsFieldset_description,
|
||
.mx_SettingsTab_section_caption {
|
||
color: var(--yap-text-muted);
|
||
}
|
||
/* dividers between sections */
|
||
.mx_SettingsTab .mx_SettingsSubsection + .mx_SettingsSubsection,
|
||
.mx_SettingsSection + .mx_SettingsSection {
|
||
border-color: var(--yap-hairline);
|
||
}
|
||
/* form fields + dropdowns in settings → Yap surfaces */
|
||
.mx_SettingsTab .mx_Field,
|
||
.mx_SettingsTab .mx_Dropdown,
|
||
.mx_SettingsTab select,
|
||
.mx_SettingsTab input[type="text"],
|
||
.mx_SettingsTab input[type="password"] {
|
||
background-color: var(--yap-surface-card);
|
||
border-color: var(--yap-hairline);
|
||
}
|
||
.mx_SettingsTab .mx_Field:focus-within {
|
||
border-color: var(--yap-accent);
|
||
}
|
||
|
||
/* toggle switches → accent when on (app-wide) */
|
||
.mx_ToggleSwitch_on,
|
||
.mx_ToggleSwitch.mx_ToggleSwitch_on {
|
||
background-color: var(--yap-accent) !important;
|
||
}
|
||
|
||
/* ---- leftover Element-green defaults → Blap accent ---- */
|
||
/* "new messages" bar above the timeline + jump-to-bottom */
|
||
.mx_TopUnreadMessagesBar_scrollUp,
|
||
.mx_TopUnreadMessagesBar_markAsRead {
|
||
color: var(--yap-accent) !important;
|
||
}
|
||
.mx_JumpToBottomButton_highlight .mx_JumpToBottomButton_badge {
|
||
background-color: var(--yap-accent) !important;
|
||
}
|
||
/* read-marker line ("new messages" divider) */
|
||
.mx_RoomView_myReadMarker {
|
||
background-color: var(--yap-accent) !important;
|
||
border-top-color: var(--yap-accent) !important;
|
||
}
|
||
/* one-off hardcoded brand green */
|
||
.mx_AnalyticsLearnMoreDialog a {
|
||
color: var(--yap-accent) !important;
|
||
}
|
||
|
||
/* ---- Login / auth screen (Blap branded) ----
|
||
Target = the blap mockup: one centered card on the molecule background,
|
||
NOT Element's two-pane (left logo / right form) layout. */
|
||
.mx_AuthPage {
|
||
background-color: var(--yap-surface-rail) !important;
|
||
background-image:
|
||
linear-gradient(180deg, rgba(15, 13, 20, 0.5), rgba(15, 13, 20, 0.8)),
|
||
url("../../../img/blap-login-bg.png") !important;
|
||
background-size: cover !important;
|
||
background-position: center !important;
|
||
background-repeat: no-repeat !important;
|
||
align-items: center !important;
|
||
justify-content: center !important;
|
||
}
|
||
/* collapse the two-pane modal into a single transparent wrapper */
|
||
.mx_AuthPage_modal {
|
||
margin: auto !important;
|
||
background-color: transparent !important;
|
||
backdrop-filter: none;
|
||
border: none !important;
|
||
box-shadow: none !important;
|
||
border-radius: 20px !important;
|
||
}
|
||
.mx_AuthPage_modalContent {
|
||
flex-direction: column !important;
|
||
background-color: transparent !important;
|
||
}
|
||
/* hide the left logo / language pane — the card carries its own brand */
|
||
.mx_AuthHeader {
|
||
display: none !important;
|
||
}
|
||
/* the card itself */
|
||
.mx_AuthBody {
|
||
width: 384px !important;
|
||
box-sizing: border-box;
|
||
background-color: var(--yap-surface-main) !important;
|
||
border: 1px solid rgba(255, 255, 255, 0.07) !important;
|
||
border-radius: 20px !important;
|
||
box-shadow: 0 24px 70px rgba(0, 0, 0, 0.55) !important;
|
||
padding: 30px 30px 24px !important;
|
||
color: var(--yap-text-secondary) !important;
|
||
}
|
||
/* branded welcome header (rendered by Login.tsx) */
|
||
.mx_AuthBody_blapWelcome {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
text-align: center;
|
||
gap: 4px;
|
||
margin-bottom: 22px;
|
||
}
|
||
.mx_AuthBody_blapWelcome_mark {
|
||
width: 58px;
|
||
height: 58px;
|
||
border-radius: 17px;
|
||
background: linear-gradient(135deg, #7c66e0, #b16ae0);
|
||
padding: 11px;
|
||
object-fit: contain;
|
||
box-shadow: 0 8px 24px rgba(124, 102, 224, 0.4);
|
||
margin-bottom: 8px;
|
||
}
|
||
.mx_AuthBody .mx_AuthBody_blapWelcome_title {
|
||
margin: 0 !important;
|
||
font-size: 27px !important;
|
||
font-weight: 800 !important;
|
||
color: var(--yap-text-primary) !important;
|
||
}
|
||
.mx_AuthBody_blapWelcome_tagline {
|
||
color: var(--yap-text-muted);
|
||
font-size: 14px;
|
||
}
|
||
/* server picker → boxed homeserver field */
|
||
.mx_AuthBody .mx_ServerPicker {
|
||
background-color: rgba(0, 0, 0, 0.22);
|
||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||
border-radius: 11px;
|
||
padding: 9px 14px;
|
||
margin: 0 0 16px !important;
|
||
align-items: center;
|
||
}
|
||
.mx_AuthBody .mx_ServerPicker_change {
|
||
color: var(--yap-accent);
|
||
}
|
||
/* gradient sign-in button */
|
||
.mx_AuthBody .mx_Login_submit {
|
||
width: 100%;
|
||
margin-top: 6px;
|
||
background: linear-gradient(135deg, #7c66e0, #b16ae0) !important;
|
||
border: none !important;
|
||
border-radius: 12px !important;
|
||
padding: 11px !important;
|
||
font-weight: 700 !important;
|
||
color: #fff !important;
|
||
}
|
||
.mx_AuthBody .mx_Login_submit:hover {
|
||
filter: brightness(1.07);
|
||
}
|
||
.mx_AuthBody .mx_SSOButtons {
|
||
margin-top: 14px;
|
||
}
|
||
.mx_AuthBody,
|
||
.mx_AuthFooter {
|
||
color: var(--yap-text-secondary);
|
||
}
|
||
.mx_AuthBody a,
|
||
.mx_AuthFooter a {
|
||
color: var(--yap-accent);
|
||
}
|
||
|
||
/* ============================================================
|
||
Blap call layout — call as a compact right-hand column
|
||
(chat stays in the main pane; see RoomView.tsx callColumn).
|
||
============================================================ */
|
||
.mx_RoomView_callColumn {
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: 100%;
|
||
min-height: 0;
|
||
background: var(--yap-surface-roomlist);
|
||
overflow: hidden;
|
||
}
|
||
.mx_RoomView_callColumn .mx_CallView {
|
||
flex: 1;
|
||
min-height: 0;
|
||
background: transparent;
|
||
}
|
||
/* "IN THE CALL 5" header atop the call column. */
|
||
.mx_BlapCallColumnHeader {
|
||
flex: 0 0 auto;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
padding: 12px 16px 8px;
|
||
font-size: 11px;
|
||
font-weight: 700;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
color: var(--yap-text-muted);
|
||
}
|
||
.mx_BlapCallColumnHeader_count {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
min-width: 18px;
|
||
height: 18px;
|
||
padding: 0 5px;
|
||
border-radius: 9px;
|
||
background: var(--yap-accent-soft);
|
||
color: var(--yap-accent);
|
||
font-size: 11px;
|
||
letter-spacing: 0;
|
||
}
|
||
/* Keep the call mounted (so it doesn't disconnect) but out of view while a
|
||
right-panel card such as Room info is open over the call column. */
|
||
.mx_RoomView_callColumn_hidden {
|
||
display: none;
|
||
}
|
||
/* When a screen share takes the main pane, chat moves here (never hidden).
|
||
It carries mx_RoomView_body too, so the timeline/composer layout is inherited;
|
||
these rules just frame it as a full-height column. */
|
||
.mx_RoomView_chatColumn.mx_RoomView_body {
|
||
height: 100%;
|
||
min-height: 0;
|
||
overflow: hidden;
|
||
background: var(--yap-surface-roomlist);
|
||
border-left: 1px solid var(--yap-hairline);
|
||
}
|
||
/* Give the call column a subtle divider from the chat pane. */
|
||
.mx_MainSplit_callColumn + .mx_RightPanel_ResizeWrapper,
|
||
.mx_RoomView_callColumn {
|
||
border-left: 1px solid var(--yap-hairline);
|
||
}
|
||
}
|