#compose_buttons { text-align: right; display: flex; flex-direction: row; align-items: center; .new_message_button { margin-left: 4px; .button.small { font-size: 1em; padding: 3px 10px; vertical-align: middle; } .compose_mobile_button { & span { font-size: 1.2em !important; font-weight: 400; line-height: 1em; } } } .reply_button_container { flex: 1; min-width: 0; margin-left: 0; .compose_reply_button { width: 100%; text-align: left; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } } .mobile_button_container { @media (width >= $sm_min) { display: none; } } .stream_button_container, .private_button_container { @media (width < $sm_min) { display: none; } } } /* Main geometry for this element is in zulip.css */ #compose-content { background-color: hsl(232deg 30% 92%); transition: background-color 200ms linear; padding: 4px 4px 8px; border: 1px solid hsl(0deg 0% 0% / 10%); border-radius: 9px 9px 0 0; box-shadow: 0 0 0 hsl(236deg 11% 28%); height: 100%; display: flex; flex-flow: column; box-sizing: border-box; } .message_comp { display: none; padding: 5px 10px 0 5px; #compose_banners { max-height: min(25vh, 240px); overflow-y: auto; } } .autocomplete_secondary { opacity: 0.8; font-size: 85%; } .active .autocomplete_secondary { opacity: 1; } .narrow_to_compose_recipient_current_view_help { margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .compose_table { height: 100%; display: flex; flex-flow: column; .stream-selection-header-colorblock { box-shadow: none; border: 1px solid hsl(0deg 0% 80%); border-right: none; &.message_header_private_message { border-radius: 3px 0 0 3px; border-bottom: 0; background-color: hsl(0deg 0% 27%); } } #compose-recipient { &.compose-recipient-direct-selected { #compose_select_recipient_widget { border-radius: 4px !important; } .stream_header_colorblock { display: none; } } .topic-marker-container { /* Ensure the marker ( < ) stays centered vertically with the dropdown, even when adjacent stacking pills in, e.g., a group DM. */ display: flex; align-items: center; height: var(--compose-recipient-box-min-height); .fa-angle-right { font-size: 0.9em; -webkit-text-stroke: 0.05em; align-self: center; margin: 0 5px; } } & a.narrow_to_compose_recipients { background: transparent; font-size: 18px; padding: 0 1px; align-self: center; line-height: 20px; opacity: 0.7; border: 0; margin-left: 3px; text-decoration: none; color: inherit; &:hover { opacity: 1; } } } #compose-direct-recipient { flex-grow: 1; } .message_header { background: none; background-color: hsl(0deg 0% 92%); border: none; border-radius: 0; box-shadow: none !important; } .messagebox { box-shadow: none !important; } } #send_message_form { margin: 0; height: 100%; .messagebox-wrapper { flex: 1; } .messagebox { /* normally 5px 14px; pull in the right and bottom a bit */ cursor: default; padding: 0; background: none; box-shadow: none; border: none; height: 100%; display: flex; flex-flow: column; } .message_content { margin-right: 0; } } #below-compose-content { display: flex; flex-direction: column; width: 100%; margin-top: 6px; margin-bottom: -2px; .compose_bottom_top_container { display: flex; } .compose_bottom_bottom_container { display: flex; justify-content: space-between; } } #compose_limit_indicator { margin-right: 8px; font-size: 12px; color: hsl(39deg 100% 50%); align-self: center; &.over_limit { color: hsl(0deg 76% 65%); font-weight: bold; } } #compose { position: fixed; bottom: 0; left: 0; z-index: 4; } #compose-container { display: flex; flex-direction: column; width: 100%; margin: auto; } #compose_top { display: flex; justify-content: space-between; align-items: flex-start; padding-bottom: 5px; } #compose_top_right { display: flex; align-items: center; height: var(--compose-recipient-box-min-height); & button { background: transparent; color: inherit; font-size: 15px; font-weight: normal; line-height: 20px; opacity: 0.7; border: 0; padding: 0; margin-left: 4px; vertical-align: unset; text-shadow: none; &:hover { opacity: 1; } } } .collapse_composebox_button, #compose_close { display: none; } .main-view-banner { margin-bottom: 20px; border-radius: 5px; border: 1px solid; display: flex; /* Baseline alignment ensures the closing X appears centered with the banner text. */ align-items: baseline; font-size: 15px; line-height: 18px; .main-view-banner-elements-wrapper { display: flex; /* Baseline alignment ensures the banner and button text appear centered with each other. */ align-items: baseline; /* Allow this flex container to grow or shrink to fit the outer container. */ flex: 1 1 auto; /* Allow items to wrap; this supports an intrinsic layout for banner text and buttons, which will always occupy the space available, without our having to fiddle with tons of media queries. */ flex-wrap: wrap; } & p { margin: 0; /* override bootstrap */ /* 5px right padding + 10px left-margin of the neighbouring button will match the left padding */ padding: 8px 5px 8px 15px; /* The banner text uses a flex-basis of 150px, which is roughly the width at which banner text lines are still comfortably readable. Still, it can grow and shrink as needed. */ flex: 1 1 150px; } .main-view-banner-action-button, .upload_banner_cancel_button { border: none; border-radius: 4px; padding: 5px 10px; font-weight: 600; margin-top: 4.5px; margin-bottom: 4.5px; /* Buttons take a minimum height for when their text fits on a single line. */ min-height: 32px; /* When we're larger than large mobile scales ($ml_min), flex the button to its max-content, i.e., all its text on a single line. But do not grow in order to avoid awkward, oversized buttons within the flex group. */ flex: 0 1 max-content; /* Use this margin-left hack to keep the button to the righthand side of the banner. */ margin-left: auto; @media (width < $ml_min) { /* When we're smaller than large mobile scales, we allow the button to grow, so that it can span the full width of narrow, mobile-scale banners as it wraps onto a second line. We also allow the button to shrink, so that, for example, the text can wrap on the schedule-message button that appears when undoing a scheduled message. */ flex: 1 1 max-content; /* Use a 10px left margin to keep the button away from the edge of the banner box to match the banner text; we need this only at small scales, when the button grows to the full width of the flex container. */ margin-left: 10px; } /* Extra margin to ensure the layout is identical when there is no close button. */ &.right_edge { margin-right: 10px; } } .main-view-banner-close-button { font-size: 16px; text-decoration: none; padding: 9px 8px; } &.success { background-color: hsl(147deg 43% 92%); border: 1px solid hsl(147deg 57% 25% / 40%); color: hsl(147deg 57% 25%); .main-view-banner-close-button { color: hsl(147deg 57% 25% / 50%); &:hover { color: hsl(147deg 57% 25%); } &:active { color: hsl(147deg 57% 25% / 75%); } } .main-view-banner-action-button { background-color: hsl(147deg 57% 25% / 10%); color: inherit; &:hover { background-color: hsl(147deg 57% 25% / 12%); } &:active { background-color: hsl(147deg 57% 25% / 15%); } } } /* warning and warning-style classes have the same CSS; this is since the warning class has some associated javascript which we do not want for some of the banners, for which we use the warning-style class. */ &.warning, &.warning-style { background-color: hsl(50deg 75% 92%); border-color: hsl(38deg 44% 27% / 40%); color: hsl(38deg 44% 27%); .main-view-banner-close-button { color: hsl(38deg 44% 27% / 50%); &:hover { color: hsl(38deg 44% 27%); } &:active { color: hsl(38deg 44% 27% / 75%); } } .main-view-banner-action-button { background-color: hsl(38deg 44% 27% / 10%); color: inherit; &:hover { background-color: hsl(38deg 44% 27% / 12%); } &:active { background-color: hsl(38deg 44% 27% / 15%); } } } &.error { background-color: hsl(4deg 35% 90%); border-color: hsl(3deg 57% 33% / 40%); color: hsl(4deg 58% 33%); .main-view-banner-close-button { color: hsl(4deg 58% 33% / 50%); &:hover { color: hsl(4deg 58% 33%); } &:active { color: hsl(4deg 58% 33% / 75%); } } .main-view-banner-action-button { background-color: hsl(3deg 57% 33% / 10%); color: inherit; &:hover { background-color: hsl(3deg 57% 33% / 12%); } &:active { background-color: hsl(3deg 57% 33% / 15%); } } } &.info { background-color: hsl(204deg 58% 92%); border-color: hsl(204deg 49% 29% / 40%); position: relative; color: hsl(204deg 49% 29%); .main-view-banner-close-button { color: hsl(204deg 49% 29% / 50%); &:hover { color: hsl(204deg 49% 29%); } &:active { color: hsl(204deg 49% 29% / 75%); } } .main-view-banner-action-button, .upload_banner_cancel_button { background-color: hsl(204deg 49% 29% / 10%); color: inherit; &:hover { background-color: hsl(204deg 49% 29% / 12%); } &:active { background-color: hsl(204deg 49% 29% / 15%); } } } } .upload_banner { overflow: hidden; &.hidden { display: none; } .moving_bar { position: absolute; width: 0; /* The progress updates seem to come every second or so, so this is the smoothest it can probably get. */ transition: width 1s ease-in-out; background: hsl(204deg 63% 85%); top: 0; bottom: 0; } .upload_msg { flex-grow: 1; } .upload_msg, .main-view-banner-close-button, .upload_banner_cancel_button { z-index: 1; position: relative; } } .composition-area { position: relative; flex: 1; } @keyframes message-limit-flash { 0% { box-shadow: none; } 100% { box-shadow: 0 0 0 1pt hsl(0deg 76% 65%); } } textarea.new_message_textarea { display: table-cell; width: calc(100% - 12px); padding: 5px; height: 1.5em; max-height: 22em; margin-bottom: 0; resize: vertical !important; margin-top: 5px; border-radius: 4px; color: hsl(0deg 0% 33%); background-color: hsl(0deg 0% 100%); &.over_limit, &.over_limit:focus { box-shadow: 0 0 0 1pt hsl(0deg 76% 65%); &.flash { animation: message-limit-flash 0.5s ease-in-out infinite; } } &:read-only, &:disabled { cursor: not-allowed; background-color: hsl(0deg 0% 93%); } &.invalid, &.invalid:focus { border: 1px solid hsl(3deg 57% 33%); box-shadow: 0 0 2px hsl(3deg 57% 33%); } } textarea.new_message_textarea, .compose_table .recipient_box { border: 1px solid hsl(0deg 0% 0% / 20%); box-shadow: none; transition: border 0.2s ease; color: var(--color-text-default); &:focus { outline: 0; border: 1px solid hsl(0deg 0% 67%); box-shadow: none; } } input.recipient_box { margin: 0; padding: 0 6px; height: auto; border-radius: 3px; } #compose_select_recipient_widget { border-radius: 0 4px 4px 0; width: auto; outline: none; &.dropdown-widget-button { padding: 0 6px; } } #stream_message_recipient_topic.recipient_box { width: 100%; /* This width roughly corresponds to how long of a topic can appear in the left sidebar with a single digit unread count without being cut off. */ max-width: 175px; } #private_message_recipient.recipient_box { width: 100%; } #compose-send-button { padding: 3px 12px; margin-bottom: 0; font-weight: 600; font-size: 0.9em; border-radius: 4px 0 0 4px; .loader { display: none; position: relative; top: -6px; } } .enter_sends_choices { .enter_sends_choice { display: flex; gap: 8px; padding-top: 4px; & input[type="radio"] { position: relative; top: 5px; width: auto; cursor: pointer; margin: 4px 0 0; &:focus { outline: 1px dotted hsl(0deg 0% 20%); outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } } &:first-child { padding: 0 0 4px; border-bottom: 1px solid hsl(0deg 0% 0% / 20%); } } .enter_sends_choice_text { display: flex; flex-direction: column; } .enter_sends_minor, .enter_sends_minor kbd { opacity: 0.9; font-size: 11px; color: hsl(0deg 0% 50%); } } .open_enter_sends_dialog { font-size: 12px; height: 14px; padding-left: 4px; opacity: 0.7; margin-bottom: 5px; position: relative; top: -2px; cursor: pointer; @media (width < $mm_min) { font-size: 11px; } & kbd { padding: 0 4px; } &:hover { opacity: 1; } .enter_sends_true, .enter_sends_false { display: none; } & i { padding-left: 3px; font-size: 12px; font-weight: 600; } } #compose-recipient { display: flex; width: 100%; /* Use this containing flex element to establish the minimum height of all its children; the default `align-items: stretch` (which is set on any flexbox without specifying it) ensures that the child flex items will always stretch to fit the height set here; larger heights, such as on group-DM pills, will allow this to grow as needed. Child flex items like chevrons take `align-self: center` to center only themselves, where necessary. */ min-height: var(--compose-recipient-box-min-height); } .compose_control_buttons_container { margin-right: auto; display: flex; gap: 4px; align-items: center; /* We use the selector in this manner to maintain specificity. */ .compose_control_button_container .compose_gif_icon { font-size: 22px; /* Remove top and bottom padding. This is necessary * because `compose_gif_icon` is no longer a flex item. */ padding: 0 5px; } .compose_control_button { padding: 5px; opacity: 0.7; color: inherit; text-decoration: none; font-size: 17px; text-align: center; &:hover { opacity: 1; } } .fa-eye { position: relative; top: -0.7px; } .compose_control_menu { padding: 0 1px; font-size: 18px; } .compose_control_menu_wrapper { opacity: 0.7; padding: 0; margin: 0; &:hover { opacity: 1; } .compose_control_menu { opacity: 1; } } .hide-sm, .hide-lg { display: flex; align-items: center; gap: 4px; padding: 0; margin: 0; } .divider { color: hsl(0deg 0% 75%); font-size: 20px; margin: 0 3px; } .compose_draft_button { font-size: 15px; font-weight: 600; font-family: "Source Sans 3 VF", sans-serif; padding: 0 5px; position: relative; top: 0.7px; } .compose_help_button { font-size: 20px; line-height: 17px; } } .compose_right_float_container { display: flex; flex-direction: row; white-space: nowrap; margin-top: 2px; height: 24px; &.disabled-compose-send-button-container { cursor: not-allowed; & button { pointer-events: none; background-color: hsl(0deg 0% 65%); } } } .drag { display: none; height: 18px; width: 100%; top: 23px; position: relative; cursor: ns-resize; } .preview_message_area { /* minus 5px padding. */ width: calc(100% - 12px); padding: 5px; margin-top: 5px; /* the maximum height the textarea gets to. */ max-height: 308px; /* the minimum height the textarea collapses to. */ min-height: 42px; overflow: auto; border: 1px solid hsl(0deg 0% 67%); border-radius: 4px; background-color: hsl(0deg 0% 98%); cursor: not-allowed; } .markdown_preview_spinner { margin: auto; } #compose_select_recipient_widget_wrapper { display: flex; justify-content: flex-start; height: var(--compose-recipient-box-min-height); .stream_header_colorblock { margin: 0; } .dropdown_widget_value { flex-grow: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--color-text-default); .stream-privacy-type-icon { font-size: 13px; width: 13px; height: 13px; position: relative; top: 2px; } } .fa-chevron-down { padding-left: 5px; color: hsl(0deg 0% 58%); font-weight: lighter; } /* This is the "Select a stream" default message */ .text-warning { color: inherit; } } .dropdown-menu { & ul { list-style: none; margin: 0; background: hsl(0deg 0% 100%); } .typeahead-header { margin: 0; padding-left: 20px; padding-right: 20px; padding-top: 4px; border-top: 1px solid hsl(0deg 0% 0% / 20%); display: flex; align-items: center; } #typeahead-header-text { font-size: 12px; } &.typeahead { background: hsl(0deg 0% 100%); } } .compose_mobile_stream_button i, .compose_mobile_private_button i { margin-right: 4px; } /* `^` icon located next to `Send` / `Scheduled` button which shows options to schedule the message. */ #send_later { display: flex; align-items: center; float: right; color: hsl(0deg 0% 100%); border-radius: 0 4px 4px 0; padding: 0; margin: 0; .zulip-icon { padding: 5px 3px; font-size: 17px; } .separator-line { background-color: hsl(0deg 0% 100% / 65%); height: 70%; width: 1px; } &:hover, &:focus { box-shadow: none; } } @media (width < $xl_min) { #compose-content { margin-right: 7px; } } @media (width < $md_min) { #compose-content { margin-right: 7px; margin-left: 7px; } } @media (width < $mm_min) { #compose-content { margin-right: 5px; margin-left: 5px; } } #compose.compose-fullscreen { z-index: 99; #compose-container { height: 100%; } .message_comp { flex: 1; display: flex !important; flex-flow: column; } #compose-textarea, #preview_message_area { /* Setting height to 0 is necessary to make the flex+Simplebar combination work correctly, without pushing the compose controls offscreen when previewing a very tall message. */ max-height: none !important; height: 0; flex: 1; } } .preview_mode { .preview_mode_disabled { cursor: not-allowed; opacity: 0.3; .compose_control_button { pointer-events: none; } } }