* Define the shared EventTile shell contract * Create a functional shared shell skeleton * Implement the thread rendering branch * Implement notification and threads-list branches * Implement file and default timeline branches * Add shared stories and complete shell tests * Adding state flags, stories and styling * Correct DOM order for IRC branch * Refine EventTileView Storybook shell and fixtures * Fix the room story for modern layout * Fix Bubble layout * Fix IRC layout * Fix ThreadsList and Thread * Fix File and Notification * Cleanup of stories and styling * Fix lint errors * Added baseline screenshots * Rename to avoid knip errors * Avoid the knip error * Fix test fail on click * Use separate div wrappers for slots instead of relying on cloning components. * Renamed names for slot classes * Changed to conditional state classes * Change layout and shape variants to classes * Clean up and reorder for better readability * Fix Sonar issues * Fix Sonar issues
784 lines
19 KiB
CSS
784 lines
19 KiB
CSS
/*
|
|
* Copyright 2026 Element Creations Ltd.
|
|
*
|
|
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
|
* Please see LICENSE files in the repository root for full details.
|
|
*/
|
|
|
|
/* Shared root and slot-boundary baseline. */
|
|
.root {
|
|
/* Group geometry. */
|
|
--event-tile-group-gutter: 64px;
|
|
--event-tile-group-line-spacing-block-start: 1px;
|
|
--event-tile-group-line-spacing-block-end: 3px;
|
|
--event-tile-group-line-height: 22px;
|
|
|
|
/* IRC geometry. */
|
|
--event-tile-irc-line-height: 18px;
|
|
--event-tile-irc-name-width: 80px;
|
|
--event-tile-irc-icon-width: 14px;
|
|
--event-tile-irc-timestamp-width: 48px;
|
|
--event-tile-irc-right-padding: 5px;
|
|
|
|
/* Bubble geometry. */
|
|
--event-tile-bubble-corner-radius: 12px;
|
|
--event-tile-bubble-gap: 5px;
|
|
--event-tile-bubble-gutter: 11px;
|
|
--event-tile-bubble-other-background: var(--cpd-color-gray-300, #e9edf2);
|
|
--event-tile-bubble-self-background: var(--cpd-color-green-300, #d8f5ed);
|
|
|
|
/* Shared preview, action-bar, bubble, and interaction values. */
|
|
--event-tile-preview-offset: 48px;
|
|
--event-tile-action-bar-size: 28px;
|
|
--event-tile-action-bar-margin: 3px;
|
|
--event-tile-action-bar-offset: 8px;
|
|
--event-tile-state-hover-background: var(--cpd-color-bg-subtle-secondary, #e9edf2);
|
|
--event-tile-state-highlight-background: var(--cpd-color-yellow-200, #fff8e3);
|
|
--event-tile-state-selected-background: var(--cpd-color-bg-subtle-secondary, #e9edf2);
|
|
--event-tile-state-marker-width: 4px;
|
|
--event-tile-state-marker-color: var(--cpd-color-bg-action-primary-rest, #0dbd8b);
|
|
|
|
position: relative;
|
|
flex-shrink: 0;
|
|
max-width: 100%;
|
|
clear: both;
|
|
padding-top: 18px;
|
|
|
|
&.stateContinuation {
|
|
padding-top: 0;
|
|
}
|
|
}
|
|
|
|
.line {
|
|
position: relative;
|
|
min-width: 0;
|
|
}
|
|
|
|
/* Slot wrappers are the public styling boundary. The supplied content may be
|
|
a component, fragment, or multiple elements and does not need to forward
|
|
layout props. */
|
|
.slotActionBar,
|
|
.slotAvatar,
|
|
.slotBody,
|
|
.slotContextMenu,
|
|
.slotFooter,
|
|
.slotNotificationBadge,
|
|
.slotNotificationRoomLabel,
|
|
.slotPadlock,
|
|
.slotReceipt,
|
|
.slotReplyChain,
|
|
.slotSender,
|
|
.slotThreadInfo,
|
|
.slotTimestamp {
|
|
min-width: 0;
|
|
}
|
|
|
|
.slotContextMenu {
|
|
z-index: 1;
|
|
}
|
|
|
|
/* Shared structural containers. */
|
|
.senderDetails {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
}
|
|
|
|
.details {
|
|
display: flex;
|
|
width: 100%;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: var(--cpd-space-2x, 8px);
|
|
}
|
|
|
|
/* The shell owns the action-bar boundary. The action-bar contents own their controls.
|
|
Presence of the slot is the render/show signal supplied by the host. */
|
|
.slotActionBar {
|
|
position: absolute;
|
|
z-index: 10;
|
|
inset-block-start: calc(
|
|
-1 *
|
|
(var(--event-tile-action-bar-size) + 2 *
|
|
(var(--event-tile-action-bar-margin) + var(--cpd-border-width-1, 1px)))
|
|
);
|
|
inset-inline-end: var(--event-tile-action-bar-offset);
|
|
user-select: none;
|
|
}
|
|
|
|
/* Group layout. */
|
|
.root.layoutGroup {
|
|
&:hover .line,
|
|
&:focus-within .line {
|
|
background-color: var(--event-tile-state-hover-background);
|
|
}
|
|
|
|
&.stateHighlighted .line {
|
|
background-color: var(--event-tile-state-highlight-background);
|
|
}
|
|
|
|
&.stateSelected .line,
|
|
&.stateEditing .line {
|
|
background-color: var(--event-tile-state-selected-background);
|
|
}
|
|
|
|
&.stateSelected .line::before,
|
|
&.stateEditing .line::before {
|
|
content: "";
|
|
position: absolute;
|
|
z-index: 0;
|
|
inset-block: 0;
|
|
inset-inline-start: 0;
|
|
width: var(--event-tile-state-marker-width);
|
|
border-start-start-radius: inherit;
|
|
border-end-start-radius: inherit;
|
|
background: var(--event-tile-state-marker-color);
|
|
pointer-events: none;
|
|
}
|
|
|
|
.line {
|
|
padding-block: var(--event-tile-group-line-spacing-block-start) var(--event-tile-group-line-spacing-block-end);
|
|
padding-inline-start: var(--event-tile-group-gutter);
|
|
margin-inline-end: 80px;
|
|
min-height: 14px;
|
|
border-radius: 8px;
|
|
line-height: var(--event-tile-group-line-height);
|
|
}
|
|
|
|
.slotSender {
|
|
display: flex;
|
|
align-items: center;
|
|
max-width: calc(100% - var(--event-tile-group-gutter));
|
|
margin-inline-start: var(--event-tile-group-gutter);
|
|
min-height: 26px;
|
|
line-height: 20px;
|
|
}
|
|
|
|
.slotAvatar {
|
|
position: absolute;
|
|
z-index: 9;
|
|
inset-block-start: 14px;
|
|
inset-inline-start: var(--cpd-space-2x, 8px);
|
|
}
|
|
|
|
.slotTimestamp {
|
|
position: absolute;
|
|
inset-inline-start: 0;
|
|
width: var(--MessageTimestamp-width, 46px);
|
|
text-align: center;
|
|
}
|
|
|
|
.slotPadlock {
|
|
position: absolute;
|
|
inset-block-start: 0;
|
|
inset-inline-start: 44px;
|
|
height: var(--event-tile-group-line-height);
|
|
margin: 1px;
|
|
}
|
|
|
|
.slotThreadInfo {
|
|
margin-inline-start: var(--event-tile-group-gutter);
|
|
}
|
|
|
|
.slotReplyChain {
|
|
margin-inline-start: 0;
|
|
margin-bottom: var(--cpd-space-2x, 8px);
|
|
}
|
|
|
|
.slotFooter {
|
|
margin: var(--cpd-space-1x, 4px) 0 var(--cpd-space-1x, 4px) var(--event-tile-group-gutter);
|
|
}
|
|
|
|
.slotReceipt {
|
|
margin-inline-end: 10px;
|
|
float: inline-end;
|
|
position: relative;
|
|
inset-block-start: calc(-1 * (var(--event-tile-group-line-height) + 3px));
|
|
width: 90px;
|
|
height: 1px;
|
|
text-align: end;
|
|
overflow: visible;
|
|
}
|
|
|
|
&.stateContinuation .line {
|
|
clear: both;
|
|
}
|
|
}
|
|
|
|
/* IRC layout. */
|
|
.root.layoutIrc {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
padding-top: 0;
|
|
line-height: var(--event-tile-irc-line-height);
|
|
|
|
&:hover .line,
|
|
&:focus-within .line {
|
|
background-color: var(--event-tile-state-hover-background);
|
|
}
|
|
|
|
&.stateHighlighted .line {
|
|
background-color: var(--event-tile-state-highlight-background);
|
|
}
|
|
|
|
&.stateSelected .line,
|
|
&.stateEditing .line {
|
|
background-color: var(--event-tile-state-selected-background);
|
|
}
|
|
|
|
&.stateSelected .line::before,
|
|
&.stateEditing .line::before {
|
|
content: "";
|
|
position: absolute;
|
|
z-index: 0;
|
|
inset-block: 0;
|
|
inset-inline-start: 0;
|
|
width: var(--event-tile-state-marker-width);
|
|
background: var(--event-tile-state-marker-color);
|
|
pointer-events: none;
|
|
}
|
|
|
|
> .slotActionBar,
|
|
> .slotAvatar,
|
|
> .slotBody,
|
|
> .slotContextMenu,
|
|
> .slotFooter,
|
|
> .slotNotificationBadge,
|
|
> .slotNotificationRoomLabel,
|
|
> .slotPadlock,
|
|
> .slotReceipt,
|
|
> .slotReplyChain,
|
|
> .slotSender,
|
|
> .slotThreadInfo,
|
|
> .slotTimestamp,
|
|
> .line {
|
|
margin-inline-end: var(--event-tile-irc-right-padding);
|
|
}
|
|
|
|
.slotTimestamp {
|
|
min-width: var(--event-tile-irc-timestamp-width);
|
|
flex-shrink: 0;
|
|
text-align: end;
|
|
}
|
|
|
|
.slotAvatar {
|
|
display: flex;
|
|
align-items: center;
|
|
flex: 0 0 var(--event-tile-irc-icon-width);
|
|
position: relative;
|
|
width: var(--event-tile-irc-icon-width);
|
|
height: var(--event-tile-irc-line-height);
|
|
}
|
|
|
|
.slotSender {
|
|
flex-shrink: 0;
|
|
width: var(--event-tile-irc-name-width);
|
|
margin-inline-end: 0;
|
|
}
|
|
|
|
.slotPadlock,
|
|
.slotFooter,
|
|
.slotThreadInfo,
|
|
.slotReceipt {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.slotPadlock {
|
|
position: absolute;
|
|
}
|
|
|
|
.line {
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex-grow: 1;
|
|
flex-shrink: 1;
|
|
padding-block: 1px;
|
|
}
|
|
|
|
.slotReplyChain {
|
|
margin: 0;
|
|
}
|
|
|
|
.slotFooter {
|
|
margin-block: var(--cpd-space-1-5x, 6px);
|
|
}
|
|
}
|
|
|
|
/* Bubble layout. */
|
|
.root.layoutBubble {
|
|
max-width: unset;
|
|
margin-inline: var(--EventTile_bubble-margin-inline-start, 49px) var(--EventTile_bubble-margin-inline-end, 60px);
|
|
padding-top: 0;
|
|
|
|
&::before {
|
|
content: "";
|
|
position: absolute;
|
|
z-index: -1;
|
|
inset: -1px calc(-1 * var(--EventTile_bubble-margin-inline-end, 60px)) -1px
|
|
calc(-1 * var(--EventTile_bubble-margin-inline-start, 49px));
|
|
border-radius: 4px;
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* Bubble geometry and slot placement. */
|
|
.line {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: var(--event-tile-bubble-gap);
|
|
width: fit-content;
|
|
max-width: 70%;
|
|
margin-block: 0;
|
|
margin-inline: -9px -12px;
|
|
border-radius: var(--event-tile-bubble-corner-radius) var(--event-tile-bubble-corner-radius) 0 0;
|
|
line-height: 18px;
|
|
padding: calc(var(--event-tile-bubble-gutter) - 1px);
|
|
padding-inline-end: 60px;
|
|
background: var(--event-tile-bubble-other-background);
|
|
border-end-end-radius: var(--event-tile-bubble-corner-radius);
|
|
}
|
|
|
|
.slotAvatar {
|
|
position: absolute;
|
|
z-index: 9;
|
|
inset-block-start: 6px;
|
|
inset-inline-start: -36px;
|
|
line-height: 0;
|
|
border: 4px solid var(--cpd-color-bg-canvas-default, #fff);
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.slotAvatar > * {
|
|
border-radius: 50%;
|
|
box-shadow: 0 0 0 3px var(--cpd-color-bg-canvas-default, #fff);
|
|
}
|
|
|
|
.slotSender,
|
|
.line {
|
|
width: fit-content;
|
|
max-width: 70%;
|
|
line-height: 18px;
|
|
}
|
|
|
|
.slotSender {
|
|
position: relative;
|
|
inset-block-start: -2px;
|
|
inset-inline-start: 2px;
|
|
font-size: 15px;
|
|
white-space: normal;
|
|
}
|
|
|
|
.slotTimestamp {
|
|
position: absolute;
|
|
z-index: 3;
|
|
inset-block-end: 0;
|
|
inset-inline-end: 0;
|
|
padding: 4px 8px;
|
|
}
|
|
|
|
> .slotReceipt {
|
|
position: absolute;
|
|
z-index: 1;
|
|
inset-block-end: -3px;
|
|
inset-inline-end: -78px;
|
|
}
|
|
|
|
.slotPadlock {
|
|
flex-shrink: 0;
|
|
height: calc(18px + 2px);
|
|
}
|
|
|
|
.slotActionBar {
|
|
inset-block-start: -28px;
|
|
inset-inline-start: calc(
|
|
100% - var(--event-tile-action-bar-size) - 2 * (var(--event-tile-action-bar-margin) + 1px)
|
|
);
|
|
inset-inline-end: auto;
|
|
}
|
|
|
|
.slotFooter {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-block: var(--cpd-space-1-5x, 6px);
|
|
margin-inline: -9px -12px;
|
|
}
|
|
|
|
.slotThreadInfo {
|
|
margin-inline-start: -11px;
|
|
margin-inline-end: auto;
|
|
}
|
|
|
|
.slotReplyChain,
|
|
.slotThreadInfo {
|
|
clear: both;
|
|
}
|
|
|
|
/* Own-event modifiers. */
|
|
&.stateOwnEvent .slotSender {
|
|
display: none;
|
|
}
|
|
|
|
&.stateOwnEvent .line {
|
|
border-end-start-radius: var(--event-tile-bubble-corner-radius);
|
|
border-end-end-radius: 0;
|
|
background: var(--event-tile-bubble-self-background);
|
|
margin-inline-start: auto;
|
|
}
|
|
|
|
&.stateOwnEvent .slotAvatar {
|
|
inset-block-start: -19px;
|
|
inset-inline-start: auto;
|
|
inset-inline-end: -38px;
|
|
}
|
|
|
|
&.stateOwnEvent .slotActionBar {
|
|
inset-block-start: -28px;
|
|
inset-inline-start: auto;
|
|
inset-inline-end: 0;
|
|
}
|
|
|
|
&.stateOwnEvent .slotFooter {
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
&.stateOwnEvent .slotThreadInfo {
|
|
margin-inline-start: auto;
|
|
margin-inline-end: -11px;
|
|
}
|
|
|
|
/* Interaction state. */
|
|
&.stateSelected .line::before {
|
|
content: "";
|
|
position: absolute;
|
|
z-index: 0;
|
|
inset-block: 0;
|
|
inset-inline-start: 0;
|
|
width: var(--event-tile-state-marker-width);
|
|
border-start-start-radius: inherit;
|
|
border-end-start-radius: inherit;
|
|
background: var(--event-tile-state-marker-color);
|
|
pointer-events: none;
|
|
}
|
|
|
|
&:hover::before,
|
|
&.stateSelected::before {
|
|
background: var(--event-tile-state-hover-background);
|
|
}
|
|
|
|
&.stateHighlighted::before {
|
|
background: var(--event-tile-state-highlight-background);
|
|
}
|
|
|
|
&:hover .slotAvatar {
|
|
border-color: var(--event-tile-state-hover-background);
|
|
}
|
|
|
|
&.stateHighlighted .slotAvatar {
|
|
border-color: var(--event-tile-state-highlight-background);
|
|
}
|
|
|
|
&:hover .slotAvatar > *,
|
|
&.stateSelected .slotAvatar > * {
|
|
box-shadow: 0 0 0 3px var(--event-tile-state-hover-background);
|
|
}
|
|
|
|
&.stateHighlighted .slotAvatar > * {
|
|
box-shadow: 0 0 0 3px var(--event-tile-state-highlight-background);
|
|
}
|
|
|
|
/* Section state. */
|
|
&.stateContinuation {
|
|
margin-top: 2px;
|
|
}
|
|
|
|
&.stateContinuation .line {
|
|
border-start-start-radius: 0;
|
|
}
|
|
|
|
&.stateContinuation.stateOwnEvent .line {
|
|
border-start-start-radius: var(--event-tile-bubble-corner-radius);
|
|
border-start-end-radius: 0;
|
|
}
|
|
|
|
&.stateLastInSection {
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
&.stateLastInSection .line {
|
|
border-end-start-radius: var(--event-tile-bubble-corner-radius);
|
|
}
|
|
|
|
&.stateLastInSection.stateOwnEvent .line {
|
|
border-end-start-radius: 0;
|
|
border-end-end-radius: var(--event-tile-bubble-corner-radius);
|
|
}
|
|
}
|
|
|
|
/* ThreadView adds a narrower group timeline around EventTile. */
|
|
.root.shapeThread {
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: 100%;
|
|
padding-top: 0;
|
|
|
|
&.layoutGroup {
|
|
.senderDetails {
|
|
align-items: center;
|
|
gap: var(--cpd-space-4x, 16px);
|
|
padding-inline-start: var(--cpd-space-2x, 8px);
|
|
}
|
|
|
|
.senderDetails .slotAvatar {
|
|
/* ThreadView keeps the avatar in the sender-details flex row. */
|
|
position: relative;
|
|
inset: auto;
|
|
}
|
|
|
|
.senderDetails .slotSender {
|
|
margin-inline-start: 0;
|
|
max-width: 100%;
|
|
min-height: 0;
|
|
line-height: normal;
|
|
}
|
|
|
|
.line {
|
|
padding-block: 2px;
|
|
padding-inline-start: 56px;
|
|
margin-inline-end: 8px;
|
|
}
|
|
|
|
.slotTimestamp {
|
|
/* ThreadView aligns this with the event content, not the bottom of
|
|
the line's flex/content flow. */
|
|
inset-block-start: 2px;
|
|
}
|
|
|
|
.slotFooter {
|
|
margin-inline-start: 56px;
|
|
margin-inline-end: 8px;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ThreadsList layout. */
|
|
.root.shapeThreadsList {
|
|
display: flex;
|
|
flex-flow: row wrap;
|
|
align-items: center;
|
|
margin-block: 13px;
|
|
padding: 8px;
|
|
border-radius: 8px;
|
|
|
|
&:hover {
|
|
background-color: var(--cpd-color-bg-subtle-primary, #f0f1f2);
|
|
}
|
|
|
|
&::after {
|
|
content: "";
|
|
position: absolute;
|
|
inset: auto -8px -13px 56px;
|
|
height: 1px;
|
|
}
|
|
|
|
&:last-child::after {
|
|
content: unset;
|
|
}
|
|
|
|
&:first-child {
|
|
margin-top: 0;
|
|
}
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.details {
|
|
width: calc(100% - var(--event-tile-preview-offset));
|
|
margin-inline-start: var(--event-tile-preview-offset);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.slotSender {
|
|
/* In preview tiles the sender is a metadata-row profile, not the
|
|
group-layout sender above the event line. */
|
|
display: inline-flex;
|
|
align-items: center;
|
|
flex: 1;
|
|
max-width: 100%;
|
|
min-height: 0;
|
|
margin-inline-start: 0;
|
|
line-height: normal;
|
|
}
|
|
|
|
.slotAvatar {
|
|
position: absolute;
|
|
inset: 8px auto auto 8px;
|
|
}
|
|
|
|
.line {
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
padding-inline-start: var(--event-tile-preview-offset);
|
|
padding-bottom: 0;
|
|
}
|
|
|
|
.slotThreadInfo {
|
|
/* The preview is inside the padded line in this mode; it does not use
|
|
the group-layout thread-summary gutter. */
|
|
margin-inline-start: 0;
|
|
}
|
|
|
|
.slotTimestamp {
|
|
display: block;
|
|
font-size: 12px;
|
|
overflow: hidden;
|
|
margin-inline-start: auto;
|
|
align-self: flex-start;
|
|
position: initial;
|
|
inset: auto;
|
|
width: unset;
|
|
text-align: initial;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
&.layoutGroup:hover .line {
|
|
background-color: inherit;
|
|
box-shadow: none;
|
|
}
|
|
}
|
|
|
|
/* Notification layout. */
|
|
.root.shapeNotification {
|
|
display: flex;
|
|
flex-flow: row wrap;
|
|
align-items: center;
|
|
margin-block: 13px;
|
|
padding: 8px;
|
|
border-radius: 8px;
|
|
|
|
&:hover {
|
|
background-color: var(--cpd-color-bg-subtle-primary, #f0f1f2);
|
|
}
|
|
|
|
&::after {
|
|
content: "";
|
|
position: absolute;
|
|
inset: auto -8px -13px 56px;
|
|
height: 1px;
|
|
}
|
|
|
|
&:last-child::after {
|
|
content: unset;
|
|
}
|
|
|
|
&:first-child {
|
|
margin-top: 0;
|
|
}
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.details {
|
|
width: calc(100% - var(--event-tile-preview-offset));
|
|
margin-inline-start: var(--event-tile-preview-offset);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.slotSender {
|
|
/* In preview tiles the sender is a metadata-row profile, not the
|
|
group-layout sender above the event line. */
|
|
display: inline-flex;
|
|
align-items: center;
|
|
flex: 1;
|
|
max-width: 100%;
|
|
min-height: 0;
|
|
margin-inline-start: 0;
|
|
line-height: normal;
|
|
}
|
|
|
|
.slotAvatar {
|
|
position: absolute;
|
|
inset: 8px auto auto 8px;
|
|
}
|
|
|
|
.line {
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
padding-inline-start: var(--event-tile-preview-offset);
|
|
padding-bottom: 0;
|
|
}
|
|
|
|
.slotThreadInfo {
|
|
/* The preview is inside the padded line in these modes; it does not use
|
|
the group-layout thread-summary gutter. */
|
|
margin-inline-start: 0;
|
|
}
|
|
|
|
.slotTimestamp {
|
|
display: block;
|
|
font-size: 12px;
|
|
overflow: hidden;
|
|
margin-inline-start: auto;
|
|
align-self: flex-start;
|
|
position: initial;
|
|
inset: auto;
|
|
width: unset;
|
|
text-align: initial;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
&.layoutGroup:hover .line {
|
|
background-color: inherit;
|
|
box-shadow: none;
|
|
}
|
|
}
|
|
|
|
/* File panel layout. The application File branch does not apply a timeline
|
|
layout class, so explicitly reset the group-layout defaults owned by this
|
|
shared shell. */
|
|
.root.shapeFile {
|
|
padding-top: 0;
|
|
overflow-wrap: anywhere;
|
|
|
|
.senderDetailsLink {
|
|
display: block;
|
|
margin-bottom: var(--cpd-space-1x, 4px);
|
|
text-decoration: none;
|
|
}
|
|
|
|
.senderDetails {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: var(--cpd-space-2x, 8px);
|
|
margin-top: -2px;
|
|
}
|
|
|
|
.senderDetails .slotAvatar {
|
|
position: relative;
|
|
inset: auto;
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
.senderDetails .slotSender {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
max-width: 100%;
|
|
min-height: 0;
|
|
margin-inline-start: 0;
|
|
line-height: normal;
|
|
}
|
|
|
|
.senderDetails .slotTimestamp {
|
|
position: initial;
|
|
inset: auto;
|
|
width: unset;
|
|
margin-inline-start: auto;
|
|
text-align: initial;
|
|
}
|
|
|
|
.line {
|
|
margin-inline-end: 0;
|
|
padding: 0;
|
|
border-radius: 0;
|
|
}
|
|
}
|