Fossil

Artifact [4677d44e]
Login

Artifact 4677d44e7eb72a1c05505bd13b0a4de57fb5fa045ef1fbf95e5c120312014225:


/* Chat-related */
body.chat span.at-name { /* for @USERNAME references */
  text-decoration: underline;
  font-weight: bold;
}
/* A wrapper for a single single chat message (one row of the UI) */
body.chat .message-widget {
  margin-bottom: 0.75em;
  border: none;
  display: flex;
  flex-direction: column;
  border: none;
  align-items: flex-start;
}
body.chat button,
body.chat input[type=button] {
  line-height: inherit/*undo skin-specific funkiness*/;
}
body.chat .message-widget:last-of-type {
  /* Latest message: reduce bottom gap */
  margin-bottom: 0.1em;
}
body.chat.my-messages-right .message-widget.mine {
  /* Right-aligns a user's own chat messages, similar to how
     most/some mobile messaging apps do it. */
  align-items: flex-end;
}
body.chat.my-messages-right .message-widget.notification {
  /* Center-aligns a system-level notification message. */
  align-items: center;
}
/* The content area of a message. */
body.chat .message-widget-content {
  border-radius: 0.25em;
  border: 1px solid rgba(0,0,0,0.2);
  box-shadow: 0.2em 0.2em 0.2em rgba(0, 0, 0, 0.29);
  padding: 0.25em 0.5em;
  margin-top: 0;
  min-width: 9em /*avoid unsightly "underlap" with the neighboring
                   .message-widget-tab element*/;
  white-space: normal;
  word-break: break-word /* so that full hashes wrap on narrow screens */;
}

body.chat .message-widget-content.wide {
  /* Special case for when embedding content which we really want to
     expand, namely iframes. */
  width: 98%;
}
body.chat .message-widget-content label[for] {
  margin-left: 0.25em;
  cursor: pointer;
}
body.chat .message-widget-content > .attachment-link {
  display: flex;
  flex-direction: row;
}
body.chat .message-widget-content > .attachment-link > a {
  margin-right: 1em;
}
body.chat .message-widget-content > iframe {
  width: 100%;
  max-width: 100%;
  resize: both;
}
body.chat .message-widget-content> a {
  /* Cosmetic: keep skin-induced on-hover underlining from shifting
     content placed below this. */
  border-bottom: 1px transparent;
}
body.chat.monospace-messages .message-widget-content,
body.chat.monospace-messages .chat-input-field{
  font-family: monospace;
}
body.chat .message-widget-content > * {
  margin: 0;
  padding: 0;
}
body.chat .message-widget-content > pre {
  white-space: pre-wrap;
}
body.chat .message-widget-content > .markdown > *:first-child {
  margin-top: 0;
}
body.chat .message-widget-content > .markdown > *:last-child {
  margin-bottom: 0;
}
body.chat .message-widget-content.error .buttons {
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  flex-wrap: wrap;
}
body.chat .message-widget-content.error .buttons > button {
  margin: 0.25em;
}

body.chat .message-widget-content.error a {
  color: inherit;
}
body.chat .message-widget-content.error .failed-message {
  display: flex;
  flex-direction: column;
}
body.chat .message-widget-content.error .failed-message textarea {
  min-height: 5rem;
}

/* User name and timestamp (a LEGEND-like element) */
body.chat .message-widget .message-widget-tab {
  border-radius: 0.25em 0.25em 0 0;
  margin: 0 0.25em 0em 0.15em;
  padding: 0 0.5em 0.15em 0.5em;
  cursor: pointer;
  white-space: nowrap;
}
body.chat .fossil-tooltip.help-buttonlet-content {
  font-size: 80%;
}
body.chat .message-widget .message-widget-tab .xfrom {
  /* Element which holds the "this message is from user X" part
     of the message banner. */
  font-style: italic;
  font-weight: bold;
}

body.chat .message-widget .match {
  font-weight: bold;
  background-color: yellow;
}

body.chat.fossil-dark-style .message-widget .match {
  background-color: #ff4800;
}

/* The popup element for displaying message timestamps
   and deletion controls. */
body.chat .chat-message-popup {
  font-family: monospace;
  font-size: 0.9em;
  text-align: left;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  padding: 0.25em;
  margin-top: 0.25em;
  border: 1px outset;
  border-radius: 0.5em;
}
/* Full message timestamps. */
body.chat .chat-message-popup > span { white-space: nowrap; }
/* Container for the message deletion buttons. */
body.chat .chat-message-popup > .toolbar {
  padding: 0;
  margin: 0;
  border: 2px inset rgba(0,0,0,0.3);
  border-radius: 0.25em;
  display: flex;
  flex-direction: row;
  justify-content: stretch;
  flex-wrap: wrap;
  align-items: center;
}
body.chat .chat-message-popup > .toolbar > * {
  margin: 0.35em;
}
body.chat .chat-message-popup > .toolbar > button {
  flex: 1 1 auto;
}
/* The widget for loading more/older chat messages. */
body.chat #load-msg-toolbar  {
  border-radius: 0.25em;
  padding: 0.1em 0.2em;
  margin-bottom: 1em;
}
/* .all-done is set when chat has loaded all of the available
   historical messages */
body.chat #load-msg-toolbar.all-done {
  opacity: 0.5;
}
body.chat #load-msg-toolbar > div {
  display: flex;
  flex-direction: row;
  justify-content: stretch;
  flex-wrap: wrap;
}
body.chat #load-msg-toolbar > div > button {
  flex: 1 1 auto;
}
/* "Chat-only mode" hides the site header/footer, showing only
   the chat app. */
body.chat.chat-only-mode{
  padding: 0;
  margin: 0 auto;
}
body.chat #chat-button-settings {}

/** Container for the list of /chat messages. */
body.chat #chat-messages-wrapper {
  overflow: auto;
  padding: 0 0.25em;
}
body.chat #chat-messages-wrapper.loading > * {
  /* An attempt at reducing flicker when loading lots of messages. */
  visibility: hidden;
}
body.chat div.content {
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column-reverse;
  /* ^^^^ In order to get good automatic scrolling of new messages on
     the BOTTOM in bottom-up chat mode, such that they scroll up
     instead of down, we have to use column-reverse layout, which
     changes #chat-messages-wrapper's "gravity" for purposes of
     scrolling! If we instead use flex-direction:column then each new
     message pushes #chat-input-area down further off the screen!
 */
  align-items: stretch;
}
/* Wrapper for /chat user input controls */
body.chat #chat-input-area {
  display: flex;
  flex-direction: column;
  padding: 0;
  margin: 0;
  flex: 0 1 auto;
}
body.chat:not(.chat-only-mode) #chat-input-area{
  /* Safari user reports that 2em is necessary to keep the file selection
     widget from overlapping the page footer, whereas a margin of 0 is fine
     for FF/Chrome (and 2em is a *huge* waste of space for those). */
  margin-bottom: 0;
}
.chat-input-field {
  flex: 10 1 auto;
  margin: 0;
}
#chat-input-field-x,
#chat-input-field-multi {
  overflow: auto;
  resize: vertical;
}
#chat-input-field-x {
  display: inline-block/*supposed workaround for Chrome weirdness*/;
  padding: 0.2em;
  background-color: rgba(156,156,156,0.3);
  white-space: pre-wrap;
  /* ^^^ Firefox, when pasting plain text into a contenteditable field,
     loses all newlines unless we explicitly set this. Chrome does not. */
  cursor: text;
  /* ^^^ In some browsers the cursor may not change for a contenteditable
     element until it has focus, causing potential confusion. */
}
#chat-input-field-x:empty::before {
  content: attr(data-placeholder);
  opacity: 0.6;
}
.chat-input-field:not(:focus){
  border-width: 1px;
  border-style: solid;
  border-radius: 0.25em;
}
.chat-input-field:focus{
  /* This transparent border helps avoid the text shifting around
     when the contenteditable attribute causes a border (which we
     apparently cannot style) to be added. */
  border-width: 1px;
  border-style: solid;
  border-color: transparent;
  border-radius: 0.25em;
}
/* Widget holding the chat message input field, send button, and
   settings button. */
body.chat #chat-input-line-wrapper {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  flex-wrap: nowrap;
}
body.chat.chat-only-mode #chat-input-line-wrapper {
  padding: 0 0.25em;
}

/*body.chat #chat-input-line-wrapper:not(.compact) {
  flex-wrap: nowrap;
}*/
body.chat #chat-input-line-wrapper.compact {
  /* "The problem" with wrapping, together with a contenteditable input
     field, is that the latter grows as the user types, so causes
     wrapping to happen while they type, then to unwrap as soon as the
     input field is cleared (when the message is sent). When we stay
     wrapped in compact mode, the wrapped buttons simply take up too
     much space. */
  /*flex-wrap: wrap;
  justify-content: flex-end;*/
  flex-direction: column;
  /**
     We "really do" need column orientation here because it's the
     only way to eliminate the possibility that (A) the buttons
     get truncated in very narrow windows and (B) that they keep
     stable positions.
 */
}
body.chat #chat-input-line-wrapper.compact #chat-input-field-x {
}

body.chat #chat-buttons-wrapper {
  flex: 0 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 4em;
  min-height: 1.5em;
  align-self: flex-end
  /*keep buttons stable at bottom/right even when input field
    resizes */;
}
body.chat #chat-input-line-wrapper.compact #chat-buttons-wrapper {
  flex-direction: row;
  flex: 1 1 auto;
  align-self: stretch;
  justify-content: flex-end;
  /*flex-wrap: wrap;*/
  /* Wrapping would be ideal except that the edit widget
     grows in width as the user types, moving the buttons
     around */
}
body.chat #chat-buttons-wrapper > .cbutton {
  padding: 0;
  display: inline-block;
  border-width: 1px;
  border-style: solid;
  border-radius: 0.25em;
  min-width: 4ex;
  max-width: 4ex;
  min-height: 3ex;
  max-height: 3ex;
  margin: 0.125em;
  display: inline-flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  font-size: 130%;
}
body.chat #chat-buttons-wrapper > .cbutton:hover {
  background-color: rgba(200,200,200,0.3);
}
body.chat #chat-input-line-wrapper.compact #chat-buttons-wrapper > .cbutton {
  margin: 2px 0.125em 0 0.125em;
  min-width: 4.5ex;
  max-width: 4.5ex;
  min-height: 2.3ex;
  max-height: 2.3ex;
  font-size: 120%;
}
body.chat #chat-input-line-wrapper.compact #chat-buttons-wrapper #chat-button-submit {
  min-width: 10ex;
}
.chat-input-field {
  font-family: inherit
}
body.chat #chat-input-line-wrapper:not(.compact) #chat-input-field-multi,
body.chat #chat-input-line-wrapper:not(.compact) #chat-input-field-x {
  min-height: 4rem;
/*
  Problems related to max-height:

  - If we do NOT set a max-height then pasting/typing a large amount
  of text can cause this element to grow without bounds, larger than
  the window, and there's no way to navigate it sensibly.  In this
  case, manually resizing the element (desktop only - mobile doesn't
  offer that) will force it to stay at the selected size even if more
  content is added to it later.

  - If we DO set a max-height then its growth is bounded but it also
  cannot manually expanded by the user.

  The lesser of the two evils seems to be to rely on the browser
  feature that a manual resize of the element will pin its size.
*/
}

body.chat #chat-input-line-wrapper > #chat-button-settings{
  margin: 0 0 0 0.25em;
  max-width: 2em;
}
body.chat #chat-input-line-wrapper > input[type=text],
body.chat #chat-input-line-wrapper > textarea {
  flex: 20 1 auto;
  max-width: revert;
  min-width: 20em;
}
body.chat #chat-input-line-wrapper.compact > input[type=text] {
  margin: 0 0 0.25em 0/* gap for if/when buttons wrap*/;
}
/* Widget holding the file selection control and preview */
body.chat #chat-input-file-area  {
  display: flex;
  flex-direction: row;
  margin: 0;
}
body.chat #chat-input-file-area > .file-selection-wrapper {
  align-self: flex-start;
  margin-right: 0.5em;
  flex: 0 1 auto;
  padding: 0.25em 0.5em;
  white-space: nowrap;
}
body.chat #chat-input-file {
  border:1px solid rgba(0,0,0,0);/*avoid UI shift during drop-targeting*/
  border-radius: 0.25em;
  padding: 0.25em;
}
body.chat #chat-input-file > input {
  flex: 1 0 auto;
}
/* Indicator when a drag/drop is in progress */
body.chat #chat-input-file.dragover {
  border: 1px dashed green;
}
/* Widget holding the details of a selected/dropped file/image. */
body.chat #chat-drop-details {
  padding: 0 1em;
  white-space: pre;
  font-family: monospace;
  margin: auto;
  flex: 0;
}
body.chat #chat-drop-details:empty {
  padding: 0;
  margin: 0;
}
body.chat #chat-drop-details img {
  max-width: 45%;
  max-height: 45%;
}
body.chat .chat-view {
  flex: 20 1 auto
  /*ensure that these grow more than the non-.chat-view elements.
    Note that setting flex shrink to 0 breaks/disables scrolling!*/;
  margin-bottom: 0.2em;
}
body.chat #chat-config,
body.chat #chat-search,
body.chat #chat-preview {
  /* /chat configuration widget */
  display: flex;
  flex-direction: column;
  overflow: auto;
  padding: 0;
  margin: 0;
  align-items: stretch;
  min-height: 6em;
}
body.chat #chat-config #chat-config-options {
  /* /chat config options go here */
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  overflow: auto;
  align-items: stretch;
}
body.chat #chat-config #chat-config-options .menu-entry {
  display: flex;
  align-items: center;
  flex-direction: row-reverse;
  flex-wrap: nowrap;
  padding: 1em;
  flex: 1 1 auto;
  align-self: stretch;
}
body.chat #chat-config #chat-config-options .menu-entry.parent{
  border-radius: 1em 1em 0 1em;
  margin-top: 1em;
}
body.chat #chat-config #chat-config-options .menu-entry.child {
  /*padding-left: 2.5em;*/
  margin-left: 2em;
}
body.chat #chat-config #chat-config-options .menu-entry:nth-of-type(even){
  background-color: rgba(175,175,175,0.15);
}
body.chat #chat-config #chat-config-options .menu-entry:nth-of-type(odd){
  background-color: rgba(175,175,175,0.35);
}
body.chat #chat-config #chat-config-options .menu-entry:first-child {
  /* Config list header */
  border-radius: 0 0 1em 1em;
}
body.chat #chat-config #chat-config-options .menu-entry:first-child .label-wrapper {
  align-items: start;
}
body.chat #chat-config #chat-config-options .menu-entry > .toggle-wrapper {
  /* Holder for a checkbox, if any */
  min-width: 1.5rem;
  margin-right: 1rem;
}
body.chat #chat-config #chat-config-options .menu-entry .label-wrapper {
  /* Wrapper for a LABEL and a .hint element. */
  display: flex;
  flex-direction: column;
  align-self: baseline;
  flex: 1 1 auto;
}
body.chat #chat-config #chat-config-options .menu-entry label {
  /* Config option label. */
  font-weight: bold;
  white-space: initial;
}
body.chat #chat-config #chat-config-options .menu-entry label[for] {
  cursor: pointer;
}
body.chat #chat-config #chat-config-options .menu-entry .hint {
  /* Config menu hint text */
  font-size: 85%;
  font-weight: normal;
  white-space: pre-wrap;
  display: inline-block;
  opacity: 0.85;
}
body.chat #chat-config #chat-config-options .menu-entry select {
}
body.chat #chat-preview .message-widget-content,
body.chat #chat-search .message-widget-content {
  overflow: auto;
  flex: 1 1 auto;
  padding: 0.5em;
  border: 1px dotted;
}

body.chat #chat-preview #chat-preview-content > * {
  margin: 0;
  padding: 0;
}
body.chat .chat-view .button-bar {
  flex: 0 1 auto;
  display: flex;
  flex-direction: column;
}
body.chat .chat-view .button-bar button {
  padding: 0.5em;
  flex: 1 1 auto;
  margin: 0.25em 0;
}

body.chat #chat-search .button-bar {
  flex: 0 1 auto;
  display: flex;
  flex-direction: row;
}

body.chat #chat-user-list-wrapper {
  /* Safari can't do fieldsets right, so we emulate one. */
  border-radius: 0.5em;
  margin: 1em 0 0.2em 0;
  padding: 0 0.5em;
  border-style: inset;
  border-width: 0 1px 1px 1px/*else collides with the LEGEND*/;
}
body.chat #chat-user-list-wrapper.collapsed {
  padding: 0;
}
body.chat #chat-user-list-wrapper > .legend {
  font-weight: initial;
  padding: 0 0.5em 0 0.5em;
  position: relative;
  top: -1.75ex/* place it like a fieldset legend */;
  cursor: pointer;
}
body.chat #chat-user-list-wrapper > .legend > * {
  vertical-align: middle;
}
body.chat #chat-user-list-wrapper > .legend > *:nth-child(2){
  /* Title label */
  opacity: 0.6;
  font-size: 0.8em;
}
body.chat #chat-user-list-wrapper.collapsed > .legend > *:nth-child(2)::after {
  content: " (tap to toggle)";
}
body.chat #chat-user-list-wrapper .help-buttonlet {
  margin: 0;
}
body.chat #chat-user-list-wrapper.collapsed #chat-user-list {
  position: absolute !important;
  opacity: 0 !important;
  pointer-events: none !important;
  display: none !important;
}
body.chat #chat-user-list {
  margin-top: -1.25ex;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
}
body.chat #chat-user-list .chat-user {
  margin: 0.2em;
  padding: 0.1em 0.5em 0.2em 0.5em;
  border-radius: 0.5em;
  cursor: pointer;
  text-align: center;
  white-space: pre;
}
body.chat #chat-user-list .timestamp {
  font-size: 85%;
  font-family: monospace;
}
body.chat #chat-user-list:not(.timestamps) .timestamp {
  display: none;
}
body.chat #chat-user-list .chat-user.selected {
  font-weight: bold;
  text-decoration: underline;
}

body.chat.fossil-dark-style #chat-button-attach > svg {
  /* The black paperclip is barely visible in dark-mode
     skins when they have dark buttons */
  filter: invert(0.8);
  transform: scale(130%);
}

body.cpage-chat-search .searchForm {
  margin-top: 1em;
}
body.cpage-chat-search .spacer-widget button {
  margin-left: 1ex;
  margin-right: 1ex;
  display: block;
}

body.chat .spacer-widget-buttons .up {
  margin-top: 0.5em;
  margin-bottom: 1em;
}
body.chat .spacer-widget-buttons .down {
  margin-top: 1em;
  margin-bottom: 0.5em;
}
body.chat .spacer-widget-buttons .all {
  margin-bottom: 0.75em;
}


body.chat .anim-rotate-360 {
  animation: rotate-360 750ms linear;
}
@keyframes rotate-360 {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
body.chat .anim-flip-h {
  animation: flip-h 750ms linear;
}
@keyframes flip-h{
  from { transform: rotateY(0deg); }
  to { transform: rotateY(360deg); }
}
body.chat .anim-flip-v {
  animation: flip-v 750ms linear;
}
@keyframes flip-v{
  from { transform: rotateX(0deg); }
  to { transform: rotateX(360deg); }
}
body.chat .anim-fade-in {
  animation: fade-in 750ms linear;
}
body.chat .anim-fade-in-fast {
  animation: fade-in 350ms linear;
}
@keyframes fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
body.chat .anim-fade-out-fast {
  animation: fade-out 250ms linear;
}
@keyframes fade-out {
  from { opacity: 1; }
  to { opacity: 0; }
}