, not the the two rules below (1196-1197) assume -- so submitted/draft there always fell through to this rule's one fixed color, unable to tell the two states apart (MonthlyReportList's own rows really are s, so it never hit this gap). Same colors as the button-based rules, just re-declared at matching structure. */ .report-cards article > header em.submitted { color: #28784f; background: #e5f5ec; } .report-cards article > header em.draft { color: #ad6c11; background: #fff2dd; } .report-cards article p { display: -webkit-box; margin: 0.8rem 0; overflow: hidden; line-height: 1.55; -webkit-box-orient: vertical; -webkit-line-clamp: 3; } .report-cards article > footer { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; padding-top: 0.65rem; border-top: 1px solid #eceef1; } .report-cards article > footer span { display: flex; align-items: center; min-width: 0; color: #7e8690; font-size: 0.78rem; } .report-cards article > footer span .material-icons { margin-right: 0.25rem; font-size: 1rem; } .report-cards article > footer button { display: flex; align-items: center; flex: none; min-height: 2.2rem; margin: 0; padding: 0 0.1rem 0 0.6rem; border: 0; box-shadow: none; color: #347bd7; background: transparent; } .report-cards article > footer button .material-icons { font-size: 1.15rem; } .report-cards > button { display: grid; grid-template-columns: 3.2rem minmax(0, 1fr) auto 1.5rem; align-items: center; gap: 0.65rem; width: 100%; min-height: 5.2rem; margin: 0 0 0.7rem; padding: 0.7rem; border: 1px solid #e6e9ec; border-radius: 0.4rem; box-shadow: none; color: #30353c; background: #fff; text-align: left; } .report-month { display: grid; place-items: center; width: 3.2rem; height: 3.2rem; border-radius: 0.35rem; color: #fff; background: #5577b9; } .report-cards > button > span:nth-child(2), .report-cards > button strong, .report-cards > button small { display: block; min-width: 0; } .report-cards > button small { margin-top: 0.25rem; color: #858d97; } .report-cards > button em { padding: 0.25rem 0.4rem; border-radius: 0.25rem; font-size: 0.72rem; font-style: normal; } .report-cards > button em.submitted { color: #28784f; background: #e5f5ec; } .report-cards > button em.draft { color: #ad6c11; background: #fff2dd; } .report-statistics { margin-bottom: 0.7rem; padding: 1rem; background: #fff; } .report-statistics > header { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; margin-bottom: 1rem; } .report-statistics > header span, .report-statistics > header strong, .report-statistics > header small { display: block; } .report-statistics > header small { margin-bottom: 0.2rem; color: #808892; } .report-statistics > header button, .report-statistics > button { min-height: 2.4rem; margin: 0; padding: 0 0.7rem; border: 1px solid #dce0e5; border-radius: 0.3rem; box-shadow: none; color: #347bd7; background: #fff; } .report-statistics > button { display: flex; align-items: center; justify-content: center; width: 100%; margin-top: 1rem; } .report-statistics > button .material-icons { margin-right: 0.35rem; font-size: 1.15rem; } .report-detail { padding-bottom: 1.5rem; } .report-detail > section { margin-bottom: 0.65rem; padding: 1rem; background: #fff; } .report-author { display: grid; /* Same dead-avatar-column issue .report-cards article > header had (see its comment) and was fixed for -- DailyReportDetail/MonthlyReportDetail (the only two renderers of this class) never render an here either, just the name+badge span and the status . The unused leading 3rem column squeezed the name into a column narrow enough to wrap "员工" onto its own line, while the status badge landed in what should've been the name's share of the row. */ grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 0.7rem; } .report-author img { width: 3rem; height: 3rem; border-radius: 50%; object-fit: cover; } .report-author span, .report-author strong, .report-author small { display: block; min-width: 0; } .report-author small { margin-top: 0.2rem; color: #858d96; } .report-author em { font-style: normal; } /* Was one fixed color (green) regardless of report.status's actual value -- a "未提交" (not yet submitted) badge showing the same green as "已提交" reads backwards. */ .report-author em.submitted { color: #28784f; } .report-author em.draft { color: #ad6c11; } .report-detail h2, .report-detail h3, .report-detail p { margin: 0; } .report-detail h2 { font-size: 1.05rem; } .report-detail h2 + small { display: block; margin-top: 0.4rem; color: #89919b; } .report-detail h3 { margin-bottom: 0.6rem; font-size: 0.98rem; } .report-detail section p { line-height: 1.7; white-space: pre-wrap; } .report-file { display: grid; grid-template-columns: 2.5rem minmax(0, 1fr) 2rem; align-items: center; gap: 0.6rem; } .report-file > .material-icons:first-child { color: #4f74ad; font-size: 2rem; } .report-file span, .report-file strong, .report-file small { display: block; } .report-file small { margin-top: 0.2rem; color: #8b929b; } .report-updated { display: flex; align-items: center; justify-content: center; color: #8a929c; font-size: 0.78rem; } .report-updated .material-icons { margin-right: 0.25rem; font-size: 1rem; } .mailbox-page > main { padding: 0.8rem 1rem 1.5rem; background: #fff; } .mailbox-page label { display: block; position: relative; margin-top: 1rem; } .mailbox-page label > span:first-child { display: block; margin-bottom: 0.55rem; font-weight: 600; } .mailbox-page input[type='text'], .mailbox-page label > input:not([type]), .mailbox-page label > textarea { width: 100%; margin: 0; border: 1px solid #dfe3e7; border-radius: 0.3rem; box-shadow: none; background: #fff; } .mailbox-page label > input:not([type]) { height: 3rem; padding: 0 0.75rem; } .mailbox-page label > textarea { height: 12rem; padding: 0.75rem 0.75rem 2rem; resize: vertical; line-height: 1.5; } .mailbox-content > small { position: absolute; right: 0.75rem; bottom: 0.65rem; color: #9ca3ac; } .mailbox-notice, .mailbox-upload { display: grid; grid-template-columns: 2.5rem minmax(0, 1fr) 1.5rem; align-items: center; gap: 0.5rem; width: 100%; min-height: 4.2rem; margin: 0; padding: 0.65rem 0.75rem; border: 1px solid #dfe4e9; border-radius: 0.35rem; box-shadow: none; color: #343a42; background: #f7f9fb; text-align: left; } .mailbox-notice > .material-icons:first-child { color: #2e7954; } .mailbox-notice span, .mailbox-notice strong, .mailbox-notice small { display: block; min-width: 0; } .mailbox-notice small { margin-top: 0.2rem; color: #78818b; } .mailbox-upload { grid-template-columns: 2.5rem minmax(0, 1fr) auto; margin-top: 1rem; border-style: dashed; } .mailbox-upload > .material-icons { color: #347bd7; } .mailbox-upload small { color: #888f99; } .mailbox-anonymous { display: grid !important; grid-template-columns: 2rem minmax(0, 1fr); align-items: center; gap: 0.5rem; margin: 1rem 0 !important; padding: 0.8rem; border: 1px solid #e4e7ea; border-radius: 0.35rem; } .mailbox-anonymous input { width: 1.25rem; height: 1.25rem; margin: 0; } .mailbox-anonymous span, .mailbox-anonymous strong, .mailbox-anonymous small { display: block; min-width: 0; } .mailbox-anonymous small { margin-top: 0.2rem; color: #858d96; } .mailbox-notice-backdrop { display: grid; position: absolute; z-index: 60; inset: 0; place-items: center; padding: 1rem; background: rgba(20,24,29,0.52); } .mailbox-notice-dialog { width: min(100%, 25rem); padding: 1.25rem; border-radius: 0.5rem; background: #fff; text-align: center; } .mailbox-notice-dialog > .material-icons { color: #2f7854; font-size: 2.7rem; } .mailbox-notice-dialog h2 { margin: 0.6rem 0 0.8rem; font-size: 1.15rem; } .mailbox-notice-dialog p { margin: 0.65rem 0; color: #555d67; line-height: 1.65; text-align: left; } .mailbox-notice-dialog small { display: block; margin: 0.8rem 0; color: #898f98; } .mailbox-notice-dialog button { width: 100%; min-height: 2.9rem; margin: 0.5rem 0 0; padding: 0 1rem; border: 0; border-radius: 0.35rem; box-shadow: none; color: #fff; background: #347bd7; } /* Ch.9 additions: real data needs an arbitrary-depth org tree, repeatable daily-report time blocks, meeting detail/create screens, and a couple of small mailbox extras that the original demo (fixed 2-level tree, single-shot report form) didn't need. */ .organization-loading { padding: 2rem 1rem; color: #8b929c; text-align: center; } .organization-department { display: flex; align-items: center; gap: 0.6rem; width: 100%; min-height: 3.4rem; margin: 0; padding: 0 1rem; border: 0; border-bottom: 1px solid #eceef1; border-radius: 0; box-shadow: none; color: #30353c; background: #fff; text-align: left; text-transform: none; } .organization-department > .material-icons:first-child { color: #8b929c; font-size: 1.3rem; } .organization-department.expanded { color: #2094f3; } .organization-department.expanded > .material-icons:first-child { color: #2094f3; } .organization-department > span { flex: 1 1 auto; min-width: 0; } .organization-department > span strong { display: block; overflow: hidden; font-weight: 500; text-overflow: ellipsis; white-space: nowrap; } .organization-department > .material-icons:last-child { color: #b0b6bd; } .organization-person { display: flex; align-items: center; gap: 0.6rem; width: 100%; min-height: 3.2rem; margin: 0; padding: 0 1rem; border: 0; border-bottom: 1px solid #eceef1; border-radius: 0; box-shadow: none; color: #30353c; background: #fafbfc; text-align: left; text-transform: none; } .organization-person > .material-icons:first-child { color: #b0b6bd; font-size: 1.1rem; } .organization-person > span { flex: 1 1 auto; min-width: 0; } .organization-person > span strong { overflow: hidden; font-weight: 400; text-overflow: ellipsis; white-space: nowrap; } .organization-person.me { color: #2094f3; } .organization-person.me > span strong { color: #2094f3; font-weight: 500; } .organization-person > .material-icons:last-child { color: #b0b6bd; } .meeting-more { display: flex; align-items: center; flex: none; margin: 0; padding: 0; border: 0; box-shadow: none; color: #b0b6bd; background: transparent; font-size: 0.85rem; } .meeting-attendees { color: #347bd7; } .meeting-responded { width: 100%; min-height: 2.4rem; margin: 0; padding: 0 1rem; border: 0; border-radius: 0.3rem; box-shadow: none; color: #8b929c; background: #f2f3f5; } .meeting-participant-list { margin: 0.8rem 0 0; padding: 0.6rem 0 0; border-top: 1px solid #eceef1; list-style: none; } .meeting-participant-list li { display: flex; align-items: center; justify-content: space-between; min-height: 2.3rem; } .meeting-participant-list em { padding: 0.15rem 0.5rem; border-radius: 0.25rem; color: #8b929c; background: #f2f3f5; font-size: 0.72rem; font-style: normal; } .meeting-participant-list em.accepted { color: #28784f; background: #e5f5ec; } .meeting-participant-list em.declined { color: #ad3d45; background: #fbe9eb; } .meeting-participant-list em.tentative { color: #ad6c11; background: #fff2dd; } .meeting-status footer { display: flex; gap: 0.6rem; margin-top: 0.8rem; } .meeting-status footer button { flex: 1 1 auto; min-height: 2.6rem; margin: 0; border: 0; border-radius: 0.3rem; box-shadow: none; color: #347bd7; background: #eaf2fc; } .meeting-status footer button.danger { color: #ad3d45; background: #fbe9eb; } .meeting-time-range { display: flex; align-items: center; gap: 0.5rem; } .meeting-time-range .report-field { flex: 1 1 0; } .meeting-time-range span { color: #8b929c; } .meeting-selected-attendees { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: -0.4rem 0 0.8rem; } .meeting-selected-attendees span { display: flex; align-items: center; gap: 0.25rem; padding: 0.3rem 0.5rem; border-radius: 999px; background: #eaf2fc; color: #347bd7; font-size: 0.82rem; } .meeting-selected-attendees .material-icons { font-size: 0.9rem; cursor: pointer; } .daily-report-block { margin-bottom: 1rem; padding-bottom: 1rem; border-bottom: 1px solid #eceef1; } .daily-report-block-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.6rem; } .daily-report-block-header .material-icons { color: #8b929c; cursor: pointer; } .daily-report-date { display: block; margin: -0.3rem 0 0.5rem; color: #8b929c; } .daily-report-add-block { display: flex; align-items: center; justify-content: center; gap: 0.3rem; width: 100%; min-height: 2.6rem; margin: 0 0 1rem; border: 1px dashed #d5d9dd; border-radius: 0.3rem; box-shadow: none; color: #347bd7; background: #fff; } .report-draft-status { margin: 0; color: #8b929c; font-size: 0.82rem; text-align: right; } .report-cards article > header .role-badge, .report-author .role-badge { display: inline-block; flex-shrink: 0; margin-left: 0.4rem; padding: 0.1rem 0.4rem; border-radius: 0.25rem; color: #347bd7; background: #eaf2fc; font-size: 0.72rem; white-space: nowrap; } /* The name before this badge has no length cap of its own (falls back to the raw account id when no nickname is set, which can run much longer than a real name) -- let it truncate instead of squeezing the fixed-width badge next to it into wrapping onto its own line. */ .report-cards article > header > span > strong, .report-author > span > strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .workplace-error { padding: 0.8rem 1rem; color: #ad3d45; text-align: center; } /* Specificity needs to beat `.workbench-profile span` (base.css, above) -- that rule's `display: block` is meant for the plain text-label spans in this same row, but a bare `.workbench-avatar- fallback` alone is one class vs. that rule's class+element, so it lost and fell back to block, silently discarding this rule's own centering and leaving the icon glyph sitting in normal block flow (top-left of the circle) instead of centered. */ .workbench-profile .workbench-avatar-fallback { display: flex; align-items: center; justify-content: center; width: 3rem; height: 3rem; border-radius: 50%; color: #fff; background: #b0b6bd; } .mailbox-anonymous-choice { display: flex; gap: 1.2rem; justify-content: center; margin-top: 0.8rem; } .mailbox-anonymous-choice label { display: flex; align-items: center; gap: 0.35rem; color: #58606b; font-size: 0.88rem; } .mailbox-attachment-list { margin: 0.5rem 0 0; padding: 0; list-style: none; } .mailbox-attachment-list li { display: flex; align-items: center; justify-content: space-between; min-height: 2.2rem; color: #58606b; } .mailbox-attachment-list .material-icons { color: #8b929c; cursor: pointer; font-size: 1.1rem; } @media screen and (max-width: 480px) { .workbench-apps { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1.2rem 0.35rem; } .workbench-banner { grid-template-columns: minmax(0, 1fr) 4rem; padding: 1rem; } .workbench-banner > .material-icons { font-size: 3.8rem; } .meeting-card dl > div { grid-template-columns: 5.8rem minmax(0, 1fr); } .report-cards > button { grid-template-columns: 3.2rem minmax(0, 1fr) auto 1.2rem; gap: 0.45rem; } } * { box-sizing: border-box; padding: 0; margin: 0; font-family: Roboto, Arial, sans-serif; text-rendering: optimizeLegibility; scrollbar-width: thin; scrollbar-color: var(--clr-scrollbar-thumb) var(--clr-scrollbar-track); } /* Basic elements defined */ html, body { height: 100%; width: 100%; height: 100dvh; width: 100dvw; font-size: 10pt; /* 13.33 px/rem */ color: var(--clr-text-primary); overflow: hidden; background-color: var(--clr-body-background); box-shadow: inset 0 10rem var(--clr-header-stripe-bg); /* the deep-plue stripe accross the top */ } tt { font-family: 'Roboto Mono', Courier, monospace; } a { color: var(--clr-primary-accent); text-decoration: none; } a:hover, a:focus { color: var(--clr-primary-accent-hover); text-decoration: underline; } a.danger { color: var(--clr-danger-text); } a.danger:hover, a.danger:focus { color: var(--clr-danger-text-hover); } a.gray:hover, a.gray:focus { color: var(--clr-text-tertiary); } form { font-size: 1.1rem; padding: 0.5rem 0.75rem; line-height: 1.5; } label { font-size: 1.1rem; margin-right: auto; } label.small { color: var(--clr-primary-action); font-size: 0.95rem; } label.large { color: var(--clr-primary-action); font-size: 1.1rem; } label.invalid { color: var(--clr-danger-text); } img.avatar { width: 100%; height: 100%; border-radius: 50%; } img.avatar.self { padding: 7%; } /* Input fields and buttons */ button { display: inline-block; font-family: inherit; font-size: 1.05rem; height: 2.2rem; line-height: 2.2rem; font-weight: normal; text-align: center; vertical-align: middle; touch-action: manipulation; cursor: pointer; border: 1px solid var(--clr-transparent); white-space: nowrap; padding-left: 1.2rem; padding-right: 1.2rem; border-radius: 4px; box-shadow: 0 1px 3px 0 var(--clr-shadow-button); text-transform: uppercase; min-width: 5rem; margin: 0 0.35rem 0 0.35rem; } button[disabled], html input[disabled] { cursor: default; opacity: 0.65; box-shadow: none; filter: grayscale(50%); } button.round { border-radius: 50%; width: 3rem; height: 3rem; padding: 0; margin: 0; line-height: 3.5rem; outline: none; /* otherwise a square outline is shown */ box-shadow: 0 2px 0.5rem 0 var(--clr-shadow-button); z-index: 2; } button.round.small { width: 2rem; height: 2rem; line-height: 2rem; box-shadow: 0 2px 0.35rem 0 var(--clr-shadow-button); } /* Scoped to the variants whose *default* text is already white (.primary/.danger/.positive below) -- for them this is a no-op safety net. It used to apply to every unconditionally, which silently turned any plain button's text/icon white on hover or press. Most buttons in this app are bare elements with a light or unchanged hover background (confirmed: no bare button in this file switches to a dark hover background), so that white-out made the label or icon vanish against the still-light background -- reported independently on the personal-settings rows, the secondary button, and again on the messages home's icon buttons and avatar/list rows in the two-pane desktop layout. Do not restore the bare `button:hover` form of this rule. */ button.primary:hover:not([disabled]), button.primary:active:not([disabled]), button.danger:hover:not([disabled]), button.danger:active:not([disabled]), button.positive:hover:not([disabled]), button.positive:active:not([disabled]) { color: var(--clr-bright); } button:active { box-shadow: inset 0 3px 0.5rem var(--clr-shadow-button-inset-active); } button:active.round.small { box-shadow: inset 0 2px 0.35rem var(--clr-shadow-button-inset-active); } button.primary { background-color: var(--clr-button-primary-bg); color: var(--clr-button-primary-text); } button.primary:hover:not([disabled]), button.primary:active:not([disabled]) { background-color: var(--clr-button-primary-hover-bg); } button.secondary { background-color: var(--clr-button-secondary-bg); color: var(--clr-button-secondary-text); } button.secondary:hover:not([disabled]), button.secondary:active:not([disabled]) { /* Restate the (non-white) text color: the generic button:hover rule forces white text, which disappears against this light hover background -- same class of bug as .personal-menu-row. */ color: var(--clr-button-secondary-text); background-color: var(--clr-button-secondary-hover-bg); } button.outline { background-color: var(--clr-transparent); color: var(--clr-button-outline-text); border: 1px solid var(--clr-button-outline-border); box-shadow: none; } button.outline:hover:not([disabled]), button.outline:active:not([disabled]) { color: var(--clr-button-outline-text); background-color: var(--clr-button-outline-hover-bg); } button.danger { background-color: var(--clr-button-danger-bg); color: var(--clr-button-danger-text); } button.danger:hover:not([disabled]), button.danger:active:not([disabled]) { background-color: var(--clr-button-danger-hover-bg); } button.positive { background-color: var(--clr-button-positive-bg); color: var(--clr-button-positive-text); } button.positive:hover:not([disabled]), button.positive:active:not([disabled]) { background-color: var(--clr-button-positive-hover-bg); } textarea, input { font-family: inherit; font-size: 1.1rem; background: var(--clr-transparent); border: none; margin: 0.25rem 0; padding: 0 0.125rem; outline: none; color: var(--clr-input-text); } input[type="text"], input[type="email"], input[type="password"], input[type="search"], input[type="tel"], input[type="date"], input[type="time"], textarea { height: 2.5rem; border-bottom: 1px solid var(--clr-input-border); box-shadow: 0 1px 0 var(--clr-input-shadow); transition: all 0.1s ease-in-out, height 0s; } input[type="text"], input[type="email"], input[type="password"], input[type="tel"], input[type="date"], input[type="time"], textarea { width: 100%; } textarea:focus, input[type="text"]:focus, input[type="email"]:focus, input[type="password"]:focus, input[type="search"]:focus, input[type="tel"]:focus, input[type="date"]:focus, input[type="time"]:focus { border-bottom: 1px solid var(--clr-input-border-focus); box-shadow: 0 1px 0 var(--clr-input-shadow-focus); } textarea.invalid, input[type="text"].invalid, input[type="email"].invalid, input[type="password"].invalid, input[type="search"].invalid, input[type="tel"].invalid { border-bottom: 1px solid var(--clr-input-invalid-border); box-shadow: 0 1px 0 var(--clr-input-invalid-shadow); } input[type="text"]::placeholder, input[type="email"]::placeholder, input[type="password"]::placeholder, input[type="search"]::placeholder, input[type="tel"]::placeholder, textarea::placeholder { color: var(--clr-input-placeholder-text); font-weight: lighter; } input[type="text"].with-icon-right, input[type="password"].with-icon-right { margin-right:-2rem; padding-right:2rem; } input[type="text"].with-icon-left, input[type="password"].with-icon-left { margin-left:-1.45rem; padding-left:1.75rem; } textarea { resize: none; padding-top: 0.45rem; } input[type="range"] { width: 90%; } option { padding: 0; } datalist { display: flex; flex-direction: row; justify-content: space-between; width: 100%; } /* END of input and buttons */ /* BEGIN scrollbar styling. */ /* Chrome & other webkit browsers */ ::-webkit-scrollbar { width: 0.6rem; } ::-webkit-scrollbar-track { -webkit-box-shadow: inset 0 0 6px var(--clr-shadow-scrollbar-track-webkit); box-shadow: inset 0 0 6px var(--clr-shadow-scrollbar-track-webkit); background-color: var(--clr-scrollbar-track); } ::-webkit-scrollbar-thumb { background-color: var(--clr-scrollbar-thumb); } /* END of Scrollbar styling. */ /* BEGIN Popup/dropdown menu */ ul.menu { position: absolute; list-style: none; width: 12rem; border-radius: 0.2rem; padding-top: 0.35rem; padding-bottom: 0.35rem; box-shadow: 0 1px 6px var(--clr-shadow-dialog); background-color: var(--clr-bright); z-index: 4; } ul.menu > li { padding: 0.75rem 0.75rem 0.75rem 1.25rem; cursor: pointer; } ul.menu > li:hover { background-color: var(--clr-menu-item-hover-bg); } ul.menu > li.separator { padding: 0; margin: 2px; height: 1px; background-color: var(--clr-border-light); } ul.menu > li.separator:hover { background-color: var(--clr-border-light); } ul.menu > li.disabled { pointer-events: none; opacity: 0.6; } /* The down arrow head - trigger for context menu */ .menuTrigger { position: absolute; right: 0.25rem; width: 1.4rem; height: 1.4rem; line-height: 1.4rem; border-radius: 0.7rem; text-align: center; opacity: 0; background-color: inherit; user-select: none; } .menuTrigger a { color: var(--clr-text-secondary); } li .menuTrigger { top: 0.25rem; } li:hover .menuTrigger { opacity: 0.9; } li:hover .menuTrigger a { color: var(--clr-text-secondary); } /* END popup/dropdown menu */ /* Begin Alert: modal window with message and buttons. */ div.alert-container { position: absolute; display: flex; padding: 1rem; justify-content: center; align-items: center; width: 100%; height: 100%; overflow: hidden; background: var(--clr-alert-overlay-bg); z-index: 3; } div.alert { position: relative; background-color: var(--clr-bright); box-shadow: 0.15rem 0.15rem 1.5rem var(--clr-shadow-dialog); padding: 1rem; border-radius: 0.3rem; margin: auto 2rem auto 2rem; width: fit-content; height: min-content; min-width: 16rem; max-width: 24rem; max-height: 40rem; overflow: hidden; } div.alert-container .title { position: relative; color: var(--clr-primary-accent); font-size: 1.2rem; font-weight: 500; width: 100%; padding: 0 0 0.35rem 0; } div.alert-container .title.with-control { position: relative; display: flex; padding: 0.5rem 0.5rem 0 0.5rem; align-items: center; flex: none; justify-content: space-between; } div.alert-container .content { position: relative; padding: 0.5rem 0 0.5rem 0; } /* END Alert */ /* BEGIN trusted badges with legend */ div.trusted-badge { margin: 0.25rem 0; } /* END trusted badges */ /* Generic text colors */ .blue { color: var(--clr-primary-accent)!important; /* blue 500 */ } .lt-blue { color: var(--clr-lt-fg-1)!important; /* blue 300, using lt-fg-1 which is #90caf9 */ } .orange { color: var(--clr-std-orange)!important; } .verified-color { color: var(--clr-verified-accent)!important; /* lt-blue 500 */ } .staff-color { color: var(--clr-staff-accent)!important; /* light green 700 */ } .danger-color { color: var(--clr-warning-accent)!important; /* amber 500 */ } .green { color: light-dark(#388e3c, #1a9a1d); /* green 700 */ } .white { color: var(--clr-bright)!important; /* 100% white */ } .red { color: var(--clr-danger-text)!important; /* red 700 */ } /* Color of an inverted icon badges */ .badge-inv { color: var(--clr-badge-inv)!important; } .gray { color: var(--clr-text-secondary)!important; } .light-gray { color: var(--clr-text-placeholder)!important; } .large { font-size: 120%; } /* Other universal style components */ .small { font-size: 90%; } .float-right { position: absolute; right: 0.5rem; } .hr { display: block; width: 100%; height: 0.45rem; min-height: 0.3rem; background-color: var(--clr-background-light-gray); box-shadow: inset 0 0.25rem 0.25rem -0.25rem var(--clr-shadow-hr-inset), inset 0 -0.25rem 0.25rem -0.25rem var(--clr-shadow-hr-inset); } .hr.thin { height: 0.015rem; } /* Vertical divider line */ .divider { display: inline-block; width: 1px; margin: 0 0.25rem; border-left: var(--clr-border-muted) 1.5px groove; } .ellipsized { overflow-x: hidden; white-space: nowrap; text-overflow: ellipsis; } .flat-button { display: flex; align-items: center; margin: 0.15rem 0.35rem; height: 2em; line-height: 2em; font-weight: normal; text-align: center; vertical-align: middle; touch-action: manipulation; white-space: nowrap; text-transform: uppercase; background-color: var(--clr-bright); z-index: 1; } .flat-button:hover, .flat-button:focus { text-decoration: none; } .flat-button.disabled, .flat-button.disabled:hover, .flat-button.disabled:focus { color: var(--clr-primary-accent); cursor: default; opacity: 0.75; filter: grayscale(75%); } .flat-button.faux { display: inline-block; height: 1.4em; line-height: 1.4em; text-transform: none; padding: 0 .35rem; margin: 0.15rem; border: 1px solid var(--clr-text-tertiary); border-radius: 3px; background-color: var(--clr-background-extra-light-gray); } .action-button { display: block; position: absolute; color: var(--clr-text-secondary); font-size: 1.8rem; background-color: var(--clr-background-off-white); border-radius: 50%; width: 3.25rem; height: 3.25rem; min-width: unset; min-height: unset; padding: 0; margin: 0; outline: none; /* otherwise a square outline is shown */ box-shadow: 0 2px 0.5rem 0 var(--clr-shadow-button); transition: all 150ms; z-index: 2; } .action-button:focus, .action-button:hover, .action-button:hover:not([disabled]), .action-button:active:not([disabled]) { color: var(--clr-text-tertiary-activated); background-color: var(--clr-primary-action-hover); } .action-button:active { color: var(--clr-text-tertiary-activated); background-color: var(--clr-primary-action); } .action-button.hidden { width: 1px; height: 1px; font-size: 1px; line-height: 1px; right: 2.625rem; bottom: 2.625rem; opacity: 0; } /* Element which can take focus but shows no outline */ .group-focus { outline: none; } /* END generic text colors */ /* END of basic elements */ #mountPoint { height: 100%; padding-top: 1rem; padding-bottom: 1rem; } /* Top-level application layout style: sidepanel + main view */ #noscript-message { position: relative; display: flex; flex-direction: column; max-width: 30rem; overflow: hidden; margin-top: 5rem; margin-left: auto; margin-right: auto; border-radius: 0.25rem; box-shadow: 1px 2px 0.3rem var(--clr-shadow-gray-strong); background-color: var(--clr-bright); } #noscript-title { padding: 1rem; font-size: 120%; font-weight: bolder; background-color: var(--clr-primary-accent); /* blue 500 */ color: var(--clr-primary-light-blue); /* light-blue 100 */ } #noscript-content { padding: 1rem; } #app-container { position: relative; display: flex; height: 100%; max-width: 84rem; overflow: hidden; margin-left: auto; margin-right: auto; border-radius: 0.25rem; box-shadow: 1px 2px 0.3rem var(--clr-shadow-gray-strong); background-color: var(--clr-bright); } #sidepanel { position: relative; display: flex; flex-direction: column; flex-grow: 0; flex-shrink: 0.3; width: 24rem; min-width: 18rem; height: 100%; } #topic-view { position: relative; display: flex; overflow-x: hidden; flex-direction: column; width: 100%; height: 100%; } #info-view { position: relative; display: flex; flex-direction: column; flex-grow: 0; flex-shrink: 0.3; width: 24rem; min-width: 18rem; height: 100%; } /* Generic announcement text, centered vertically and horizontally */ .center-medium-text { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; text-align: center; font-size: 1.4rem; } /* Class to alternatively hide sidepanel/topic-view/info-view */ .nodisplay { display: none!important; } /* Quoted div */ .quoted { margin-left: 1rem; } /* Extra space on the right */ .space-right { margin-right: 0.25rem; } /* Container with whitish background and rounded corners */ .rounded-container { position: relative; background-color: var(--clr-background-off-white); border-radius: 0.1rem; padding: 0.25rem; margin: 0.25rem; } /* BEGIN InPlaceEdit styles */ span.in-place-edit, div.in-place-edit { display: inline-block; font-family: inherit; font-size: 1rem; margin: 0.25rem 0.125rem 0 0.125rem; width: 100%; vertical-align: baseline; border-bottom: 1px dashed var(--clr-border-muted); cursor: pointer; } .in-place-edit.short { display: inline-flex; align-items: center; font-size: 1.1rem; height: 2.5rem; line-height: 2.25; white-space: nowrap; } .in-place-edit.disabled { border-bottom: none; cursor: default; color: var(--clr-text-disabled); } .in-place-edit.placeholder { color: var(--clr-text-placeholder); } .in-place-edit span { display: inline-block; } .in-place-edit.short span { white-space: nowrap; text-overflow: ellipsis; overflow-x: hidden; width: 100%; } .in-place-edit .material-icons { display: inline-block; } .material-icons.invalid { color: var(--clr-error-text-muted); } textarea.in-place-edit { height: unset; font-size: unset; } input.in-place-edit.invalid { color: var(--clr-error-text-muted); } /* END of InPlaceEdit styles */ table.permission-editor { width: 100%; } table.permission-editor td { margin: 0.35rem 0; font-size: 1.1rem; vertical-align: middle; } table.permission-editor td.checkbox { text-align: center; color: var(--clr-text-tertiary); } .permission-editor .material-icons { font-size: 1.3rem; line-height: 1.3rem; } .material-icons.clickable { cursor: pointer; border-bottom: none; } .clickable { border-bottom: 1px dashed var(--clr-border-muted); cursor: pointer; } .image-clickable { cursor: pointer; } .clean-clickable { cursor: pointer; } /* END of top-level layout */ /* Sidepanel styles */ .panel-title { font-size: 1.4rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .panel-title.deleted { text-decoration: line-through; } .caption-panel { display: flex; align-items: center; flex: none; padding: 0.5rem; height: var(--caption-panel-height); white-space: nowrap; box-shadow: 0 1px 2px var(--clr-shadow-gray-strong); overflow-x: hidden; z-index: 1; /* otherwise the shadow becomes invisible */ } .dialog-buttons { display: flex; padding: 0.5rem; justify-content: flex-end; align-items: center; } .dialog-buttons button { margin: 0 0.5rem; } .avatar-box { position: relative; flex-grow: 0; flex-shrink: 0; } .bot-form { display: flex; flex-direction: column; overflow: hidden; min-width: 8rem; line-height: 2rem; } .bot-form div { min-height: 2rem; vertical-align: middle; } .bot-form button { display: inline-block; margin: 0.15rem; background-color: var(--clr-blue-wash-light); color: var(--clr-primary-accent); /* blue 500 */ font-size: inherit; text-transform: none; height: 2rem; line-height: 2rem; } .bot-form > div > button { width: auto; } .bot-form button:focus, .bot-form button:hover, .bot-form button:active { outline: 0; color: var(--clr-dk-fg-5); /* #1565C0, a darker blue */ background-color: var(--clr-primary-wash); } #side-caption-panel { background-color: var(--clr-primary-accent); /* blue 500 */ color: var(--clr-primary-light-blue); /* light-blue 100 */ } #side-caption-panel a { color: var(--clr-primary-light-blue); /* blue 100 */ padding-left: 0.5rem; line-height: 1; } #side-caption-panel :hover { color: var(--clr-bright); } #sidepanel-title { margin-right: auto; margin-left: 0.5rem; } #self-avatar { width: 3rem; min-width: 3rem; height: 3rem; flex: none; border-radius: 50%; } #self-avatar.avatar-box { font-size: 1.8rem; } /* Application settings */ #settings-form ul { list-style: none; } #settings-form li { vertical-align: middle; } #settings-form label { display: inline-block; padding-left: 0.5rem; } input#host-name { width: 100%; } /* Input with a search icon on the left */ input.search { text-indent: 1.4rem; } i.search { position: absolute; left: .6rem; } /* Area which displays an error message */ .info-box { position: relative; display: none; overflow: hidden; padding: 1rem 1.5rem 0.75rem 0.5rem; } .info-box > span { line-height: 1.35rem; } .info-box .cancel { position: absolute; right: 0.25rem; top: 0.5rem; } .info-box.error { display: flex; background-color: var(--clr-error-bg-light); border-bottom: 1px solid var(--clr-error-border-light); color: var(--clr-error-text-dark); } .info-box.warning { display: flex; background-color: var(--clr-warning-bg-light); border-bottom: 1px solid var(--clr-warning-border-light); color: var(--clr-warning-text-dark); } .info-box.info { display: flex; background-color: var(--clr-info-bg-light); border-bottom: 1px solid var(--clr-info-border-light); color: var(--clr-info-text-dark); } .info-box .cancel .material-icons { font-size: 1rem; color: var(--clr-text-secondary); } .info-box.error .cancel .material-icons { color: var(--clr-error-text-dark); } .info-box .icon { display: block; margin-right: 0.5rem; } .info-box .icon .material-icons { font-size: 1.5rem; } .info-box.warning .icon .material-icons { color: var(--clr-warning-icon); } .info-box.error .icon .material-icons { color: var(--clr-error-icon); } .info-box.info .icon .material-icons { color: var(--clr-info-text-dark); } /* List of contacts */ .flex-column { display: flex; flex-direction: column; height: 100%; overflow-x: hidden; } .flex-column.narrow { height: auto; } .scrollable-panel { overflow-x: hidden; overflow-y: auto; margin-top: 0.25rem; margin-bottom: auto; height: 100%; scroll-behavior: smooth; } .contact-box { list-style: none; overflow-x: hidden; } .contact-box > li { position: relative; display: flex; padding: 0.35rem 0.25rem 0.5rem 0.35rem; min-height: 3.75rem; flex-grow: 0; flex-shrink: 0; /* partial bottom border */ background: linear-gradient(to right, var(--clr-transparent) 3.5rem, var(--clr-background-extra-light-gray) 1px, var(--clr-background-extra-light-gray) 100%) 0 100% / 100% 1px no-repeat, var(--clr-bright); overflow-x: hidden; cursor: pointer; } .contact-box.small > li { padding: 0.25rem 0.25rem 0.35rem 0.35rem; min-height: 2.5rem; } .contact-box > li:last-child { /* remove border from the last contact */ background: var(--clr-bright); } .contact-box > li:hover { background-color: var(--clr-background-blue-gray-50); /* blue-gray 50 highlight */ } .contact-box > li.selected { background-color: var(--clr-background-blue-gray-100); /* blue-gray 100 highlight */ } .contact-box > li.tpinned { border-right: 1.5px solid var(--clr-secondary-accent); background-color: var(--clr-background-blue-gray-75); /* blue-gray 75 highlight */ } .contact-box > li.action { min-height: 2.5rem; border-bottom: none; } .contact-box .text-box { overflow-x: hidden; } .contact-box .contact-title { font-size: 1.05rem; text-overflow: ellipsis; overflow-x: hidden; white-space: nowrap; } .contact-box .contact-title.deleted { opacity: 0.66; text-decoration: line-through; text-decoration-thickness: 0.5px; } .contact-box .contact-comment { text-overflow: ellipsis; overflow-x: hidden; white-space: nowrap; font-weight: lighter; } .contact-box .contact-comment > span { overflow-x: hidden; white-space: nowrap; text-overflow: ellipsis; } .contact-box .contact-comment b { font-weight: bolder; } .contact-box .contact-comment .material-icons { margin-bottom: 0.2rem; color: light-dark(#777, #666); /* #777 */ } /* Avatar and online-offline indicator */ .contact-box .avatar-box { position: relative; margin-right: 0.35rem; width: 3rem; min-width: 3rem; height: 3rem; min-height: 3rem; font-size: 1.8rem; overflow: hidden; padding: 0; } .contact-box .avatar { width: 3rem; height: 3rem; border-radius: 50%; } .contact-box.small .avatar-box { width: 2rem; min-width: 2rem; height: 2rem; min-height: 2rem; font-size: 1.2rem; } .contact-box.small .avatar { width: 2rem; height: 2rem; } .avatar.deleted { opacity: 0.75; filter: grayscale(1); } .contact-box .avatar-box > .material-icons { display: flex; flex-direction: column; justify-content: space-around; font-size: 2.4rem; line-height: 3rem; } .contact-box .avatar-box > .checkmark.material-icons { line-height: unset; } .contact-box.small .avatar-box > .material-icons { font-size: 1.6rem; line-height: 2rem; } .contact-box .text-box { display: flex; flex-direction: column; justify-content: space-around; } .contact-box .text-box > div { display: flex; flex-direction: row; align-items: center; } .contact-box .action-text { text-align: center; font-size: 0.95rem; line-height: 2.5rem; margin: 0 auto 0 auto; cursor: pointer; } img.channel { width: 1.25rem; height: 1.25rem; vertical-align: middle; margin-left: 0.3rem; } .large img.channel { width: 1.45rem; height: 1.45rem; margin-left: 0.5rem; margin-bottom: 0.15rem; } /* Online-offline indicator positioned inside avatar-box */ .avatar-box .online, .avatar-box .offline { position: absolute; width: 0.75rem; min-width: 0.75rem; height: 0.75rem; min-height: 0.75rem; flex-shrink: 0; border-radius: 50%; right: 0; bottom: 0.1rem; } .avatar-box .online { background-color: var(--clr-online); /* Specific green for online status */ } .avatar-box .offline { background-color: var(--clr-offline); /* #C0C0C0 (silver) or #ccc */ } /* Typing indicator: animation of the online dot */ .online.typing { animation: typing 0.5s infinite; } @keyframes typing { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(-0.3rem); } } .contact-box .checkmark.material-icons { width: 1.5rem; height: 1.5rem; font-size: 1.5rem; color: var(--clr-secondary-accent); position: absolute; right: 0; bottom: 0; background-color: var(--clr-bright); overflow: visible; border: 0.0px solid var(--clr-transparent); padding-left: 0.5px; } .contact-box .deleted.material-icons { width: 1.5rem; height: 1.5rem; font-size: 1.5rem; color: var(--clr-text-tertiary); position: absolute; right: 0; bottom: 0; background-color: var(--clr-bright); } /* END of avatar box */ #add-topic { position: absolute; right: 1rem; bottom: 1rem; } /* Various forms inside a panel (signup form, new topic form) */ .panel-form { display: flex; position: relative; flex-direction: column; padding: 0; } .panel-form-row { display: flex; position: relative; align-items: center; padding: 0.5rem 0.75rem; line-height: 1.5; flex-grow: 0; flex-shrink: 0; } .panel-form-column { display: flex; position: relative; flex-direction: column; flex-grow: 0; padding: 0.5rem 0.75rem; line-height: 1.5; overflow-x: clip; } /* Make sure padding is only applied at the top level panel */ .panel-form-row > .panel-form-column, .panel-form-column > .panel-form-column { padding: 0!important; flex-grow: 1; } .panel-form-column > .panel-form-row, .panel-form-row > .panel-form-row { padding: 0!important; } .panel-form-column > .group { margin-top: 0.25rem; margin-bottom: 0.25rem; } /* Styling of avatar upload control */ .avatar-upload { position: relative; display: flex; flex-direction: column; flex-shrink: 0; width: 10rem; height: 10.5rem; font-size: 4.5rem; padding: 0; margin: 0.25rem; } .avatar-upload.read-only { height: auto; } .avatar-upload .clear-avatar { position: absolute; font-size: 1rem; top: 0; right: 0; opacity: 0; background-image: radial-gradient(var(--clr-bright) 40%, var(--clr-transparent) 75%); } .avatar-upload:hover .clear-avatar { opacity: 1; } .avatar-upload .avatar-box { position: relative; width: 10rem; height: 10rem; } .avatar-upload .avatar-box > .material-icons { position: relative; font-size: 4rem; line-height: 10rem; vertical-align: middle; } /* Clearfix */ .avatar-upload:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } .avatar-upload .blank { text-align: center; vertical-align: middle; border: 1px dashed var(--clr-text-tertiary); font-size: 1rem; flex-shrink: 0; width: 10rem; height: 10rem; overflow: hidden; color: var(--clr-text-tertiary); line-height: 10rem; border-radius: 50%; } .avatar-upload img.preview { width: 10rem; height: 10rem; overflow: hidden; border-radius: 50%; } .avatar-upload img.preview::before { position: absolute; content: " "; display: flex; font-size: 0.9rem; font-weight: lighter; color: var(--clr-text-primary); top: 0; left: 0; width: 10rem; height: 10rem; justify-content: center; background: center no-repeat url("../img/broken_image.png"); border-radius: 50%; } .avatar-upload .inputfile.hidden { width: 0.1px; height: 0.1px; opacity: 0; overflow: hidden; position: absolute; } .avatar-upload .inputfile + label.round { display: flex; position: absolute; align-items: center; justify-content: center; cursor: pointer; width: 3rem; height: 3rem; line-height: 3rem; border-radius: 50%; box-shadow: 0 1px 4px var(--clr-shadow-dialog); /* rgba(0,0,0,0.4) similar to menu */ bottom: 0; right: 0; background-color: var(--clr-background-off-white); z-index: 1; } .avatar-upload .inputfile:focus + label.round { outline: none; } .avatar-upload .inputfile:focus + label, .avatar-upload .inputfile + label:hover { background-color: var(--clr-primary-wash); color: var(--clr-primary-accent); } /* END of avatar upload */ /* END of new account panel */ /* END of sidepanel styles */ /* Topic/messages view */ #topic-caption-panel { background-color: var(--clr-background-blue-gray-300); } #topic-caption-panel a { color: var(--clr-text-secondary); text-decoration: none; } #topic-caption-panel :hover { color: var(--clr-dark); } #topic-caption-panel .avatar-box { position: relative; width: 3rem; min-width: 3rem; height: 3rem; font-size: 1.8rem; margin-right: 0.35rem; } #topic-caption-panel .avatar-box > .material-icons { font-size: 2.4rem; line-height: 3rem; } #topic-title-group { overflow-x: hidden; } #hide-message-view { display: block; margin-right: 0.35rem; } #topic-users { margin-left: auto; margin-right: 1rem; width: min-content; } #topic-users .avatar-box { display: inline-block; width: 1.8rem; min-width: 1.8rem; height: 1.8rem; min-height: 1.8rem; font-size: 1rem; margin-right: 0.2rem; } #topic-users .avatar-box > .material-icons { font-size: 1.4rem; line-height: 1.8rem; } /* Overflow span "+18 more" */ #topic-users > span { line-height: 2rem; vertical-align: top; } /* Div holding QR code */ .qr-code { align-self: center; } #messages-container { position: relative; overflow-y: hidden; height: 100%; } #messages-container::before { content: ""; position: absolute; top: 0; left: 0; height: 100%; width: 100%; background-color: var(--clr-background-blue-gray-50); background-image: var(--wallpaper-url); background-repeat: var(--wallpaper-repeat); background-size: var(--wallpaper-size); background-position: var(--wallpaper-position); filter: blur(var(--wallpaper-blur)) invert(var(--wallpaper-invert)) brightness(var(--wallpaper-brightness)); pointer-events: none; z-index: 0; } /* Dark mode wallpaper adjustments: image wallpaper * #messages-container.dark.wpimg::before { filter: brightness(50%); } /* Dark mode wallpaper adjustments: pattern wallpaper * #messages-container.dark.wppatt::before { filter: invert(1); } */ /* Scrollable panel where the messages are shown */ #messages-panel { position: relative; padding: 0.75rem; overflow-y: scroll; height: 100%; } #write-only-background { position: absolute; top: 0; left: 0; height: 100%; width: 100%; background-image: repeating-linear-gradient(45deg, rgba(255,255,255,0.5), rgba(255,255,255,.5) 0.5rem, rgba(255,255,255,.8) 0.5rem, rgba(255,255,255,.8) 1rem); /* Specific gradient, keep as is or break down further if these opacities are common */ } #write-only-note { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: var(--clr-bright); color: var(--clr-text-primary); height: auto; width: auto; line-height: 2rem; text-align: center; padding: 0.75rem 1.25rem 0.75rem 1.25rem; border-radius: 0.5rem; box-shadow: 0 1px 0.5px var(--clr-shadow-button-inset-active); /* rgba(0, 0, 0, 0.12) */ } #peer-messaging-disabled-note { position: absolute; left: 50%; bottom: 4.3rem; transform: translate(-50%); background-color: var(--clr-bright); color: var(--clr-text-primary); width: fit-content; line-height: 2rem; text-align: center; padding: 0.75rem 1.25rem 0.75rem 1.25rem; border-radius: 0.5rem; box-shadow: 0 1px 0.5px var(--clr-shadow-button-inset-active); /* rgba(0, 0, 0, 0.12) */ } /* Relationship-state advisory, e.g. pending friend request. Plain centered caption, matching docs/images/个人对话框(对方的状态).png rather than the heavier card style above. */ #relationship-status-note { text-align: center; color: var(--clr-text-secondary); font-size: 0.85rem; padding: 0.5rem 1.25rem; flex: none; } #relationship-status-note a { color: var(--clr-primary-accent); } /* Group role badge next to a sender's name, docs/images/群标识.png -- gold for the owner, green for admins. Regular members get no badge (senderRole prop is 'member' or absent, neither case renders one). */ .chat-box .author .role-badge { display: inline-block; font-style: normal; font-size: 0.7rem; line-height: 1.3; padding: 0 0.4em; border-radius: 0.25rem; margin-left: 0.35em; color: #fff; vertical-align: middle; } .chat-box .author .role-badge.owner { background-color: #e0a82e; } .chat-box .author .role-badge.admin { background-color: #3ba55c; } /* Group chat top banners: announcement (docs/images/群公告状态.png) and pending join requests (docs/images/新邀请进群申请.png). Both can be visible at once, announcement first. */ #group-announcement-banner, #group-join-request-banner { display: flex; align-items: center; gap: 0.5rem; padding: 0.6rem 1rem; background-color: var(--clr-bright); border-bottom: 1px solid var(--clr-divider); color: var(--clr-text-primary); flex: none; } #group-announcement-banner i:first-child { color: var(--clr-warning-text, #e0a82e); } #group-join-request-banner i:first-child { color: var(--clr-warning-text, #e0a82e); } #group-announcement-banner span, #group-join-request-banner span { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.9rem; } #group-announcement-banner i:last-child, #group-join-request-banner i:last-child { color: var(--clr-text-secondary); } /* Red failure icon to the left of a failed outgoing bubble, and the reason caption below it. */ .message-fail-icon { align-self: flex-end; margin: 0 0.25rem 0.6rem 0; } .message-fail-reason { font-size: 0.8rem; color: var(--clr-text-secondary); text-align: right; margin-top: 0.25rem; } .message-fail-reason a { color: var(--clr-primary-accent); } /* Multi-select mode (Ch.4 4.15-4.16). */ .select-checkbox { align-self: center; margin: 0 0.5rem 0 0.25rem; color: var(--clr-text-secondary); cursor: pointer; flex: none; } .select-checkbox.blue { color: var(--clr-primary-accent); } /* Flexbox auto-margin trick: pins the checkbox to the far left of the row for sent (.right) messages, where it would otherwise cluster next to the bubble at the row's right edge along with everything else justify-content:flex-end pulls there. Scoped to .right only -- applying it unconditionally (as this rule originally did) claims 100% of the row's remaining space for the auto margin regardless of alignment, which on a received (.left) message drags the avatar+bubble that follow the checkbox all the way to the row's right edge instead of leaving them where justify-content's default flex-start already puts them: immediately after the checkbox, at the row's left edge (docs/images/多选-选中对话框.png). */ .chat-box li.right .select-checkbox { margin-right: auto; } /* Reuses the existing (previously-unused) div.toast/.show animation for 收藏成功 etc. -- positioned higher than its 2rem default so it clears the batch-action-bar below it. */ #messages-container { position: relative; } #messages-container div.toast { bottom: 0.75rem; } #batch-action-bar { display: flex; flex-direction: column; flex: none; background-color: var(--clr-background-blue-gray-50); padding: 0.5rem 0.6rem; } #batch-action-count { text-align: center; color: var(--clr-text-secondary); font-size: 0.85rem; padding-bottom: 0.4rem; } #batch-action-buttons { display: flex; justify-content: space-around; } #batch-action-buttons a { display: flex; flex-direction: column; align-items: center; font-size: 0.75rem; color: var(--clr-text-primary); } #batch-action-buttons a.disabled { color: var(--clr-text-secondary); opacity: 0.5; pointer-events: none; } #batch-action-cancel { text-align: center; margin-top: 0.5rem; color: var(--clr-text-secondary); font-size: 0.85rem; } /* Batch-forward confirm sheet (docs/images/转发—逐条转发.png). */ .batch-forward-confirm { max-width: 24rem; } /* Also carries .forward-dialog for its base sheet chrome, but that class's own height:80% (right for forward-dialog.jsx's long contact list) leaves this content-sized confirm sheet mostly empty space below its buttons. Same (single-class) specificity as .forward-dialog itself, so a bare .batch-forward-confirm{height:auto} would depend on which rule happens to come later in this file to win -- the compound selector here beats it unconditionally instead. */ .forward-dialog.batch-forward-confirm { height: auto; } .batch-forward-target { display: flex; align-items: center; justify-content: space-between; padding: 0.6rem 0; } /* .contact-box > li (2969 above) is more specific than the bare .batch-forward-target class above, so its padding and its avatar-reserving divider (the gradient's gap starts at 3.5rem, assuming an avatar occupies that space) win by default -- this row has no avatar, so the divider ends up looking like it starts partway across the row. Reasserted here at matching specificity with a full-width divider instead. */ .contact-box > li.batch-forward-target { padding: 0.6rem 0; background: linear-gradient(to right, var(--clr-background-extra-light-gray), var(--clr-background-extra-light-gray)) 0 100% / 100% 1px no-repeat, var(--clr-bright); } /* 从只读 div 改成可输入的留言框后,要显式清掉 input 的原生边框/宽度,否则会缩成一个小方框。 */ .batch-forward-comment { box-sizing: border-box; width: 100%; margin: 0.5rem 0; padding: 0.6rem; border: 0; border-radius: 0.4rem; color: var(--clr-text-primary); background-color: var(--clr-background-blue-gray-50); font: inherit; } .batch-forward-comment::placeholder { color: var(--clr-text-secondary); } .batch-forward-actions { display: flex; gap: 0.5rem; margin-top: 0.5rem; } .batch-forward-actions button { flex: 1; padding: 0.6rem; border-radius: 0.4rem; border: none; background-color: var(--clr-background-blue-gray-50); color: var(--clr-text-primary); } .batch-forward-actions button.primary { background-color: var(--clr-primary-accent); color: var(--clr-bright); } /* Footer-panel with the input for the new message */ #send-message-panel { display: flex; align-items: center; flex: none; padding: 0.4rem 0.4rem 0.4rem 0.6rem; background-color: var(--clr-background-blue-gray-50); z-index: 2; min-height: 4rem; } #send-message-panel #writing-disabled { width: 100%; text-align: center; font-size: 1.2rem; } #send-message-wrapper { position: relative; background-color: var(--clr-background-blue-gray-50); box-shadow: 0px -2px 3px -1px var(--clr-shadow-panel-divider); /* Faint shadow above panel */ z-index: 2; } #mention-picker { position: absolute; left: 0.5rem; right: 0.5rem; bottom: 100%; margin-bottom: 0.3rem; max-height: 12rem; overflow-y: auto; background: #fff; border-radius: 0.4rem; box-shadow: 0 -0.2rem 0.6rem rgba(0,0,0,0.15); z-index: 3; } .mention-picker-row { padding: 0.6rem 0.9rem; cursor: pointer; } .mention-picker-row.active, .mention-picker-row:hover { background: var(--clr-background-blue-gray-50); } .mention-picker-empty { padding: 0.6rem 0.9rem; color: var(--clr-text-tertiary); } #emoji-panel, #attach-panel { flex: none; background: #fff; border-top: 1px solid var(--clr-shadow-panel-divider); max-height: 12rem; overflow-y: auto; } #emoji-panel-tabs { display: flex; padding: 0.4rem 0.6rem 0; } #emoji-panel-tabs a { padding: 0.3rem 0.8rem; font-size: 1.3rem; border-bottom: 2px solid transparent; text-decoration: none; } #emoji-panel-tabs a.active { border-bottom-color: var(--clr-primary-accent); } #emoji-panel-grid { display: flex; flex-wrap: wrap; padding: 0.4rem; } #emoji-panel-grid a { width: 2.4rem; height: 2.4rem; display: flex; align-items: center; justify-content: center; font-size: 1.4rem; text-decoration: none; } #emoji-panel-footer { display: flex; align-items: center; justify-content: space-between; padding: 0.4rem 0.8rem 0.6rem; border-top: 1px solid var(--clr-shadow-panel-divider); } #emoji-panel-footer a { display: flex; align-items: center; justify-content: center; width: 2.4rem; height: 2.4rem; text-decoration: none; color: var(--clr-text-tertiary); } /* 同一色相、不同深浅区分"发不出去"和"能发"两态,不是灰色/彩色那种对比——跟本项目其它地方 记录过的"发送按钮禁用态浅蓝、启用态深蓝"是同一条设计判断。 */ #emoji-panel-footer a.emoji-panel-send { color: light-dark(#90caf9, #4a7ba6); } #emoji-panel-footer a.emoji-panel-send.active { color: var(--clr-primary-accent); } .emoji-panel-empty { width: 100%; padding: 1rem; text-align: center; color: var(--clr-text-tertiary); } #attach-panel { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.6rem; padding: 1rem 0.6rem; } #attach-panel a { display: flex; flex-direction: column; align-items: center; gap: 0.3rem; font-size: 0.8rem; color: var(--clr-text-primary); text-decoration: none; } #attach-panel a .material-icons { width: 3rem; height: 3rem; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--clr-background-blue-gray-50); font-size: 1.5rem; } #attach-panel a.disabled { opacity: 0.4; pointer-events: none; } .send-message-picker-backdrop { position: fixed; inset: 0; z-index: 20; display: flex; align-items: flex-end; background: rgba(0,0,0,0.35); } .send-message-picker-backdrop > section { width: 100%; max-height: 70vh; display: flex; flex-direction: column; background: #fff; border-radius: 0.6rem 0.6rem 0 0; } .send-message-picker-backdrop header { display: flex; align-items: center; justify-content: space-between; padding: 0.9rem 1rem; font-weight: 600; border-bottom: 1px solid var(--clr-shadow-panel-divider); } .send-message-picker-backdrop header a { color: var(--clr-text-tertiary); } .send-message-picker-list { overflow-y: auto; padding: 0.4rem 0; } .send-message-picker-list a { display: block; padding: 0.75rem 1rem; color: var(--clr-text-primary); text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .send-message-picker-empty { padding: 1.5rem; text-align: center; color: var(--clr-text-tertiary); } #sendMessage { overflow: hidden; overflow-wrap: break-word; } #send-message-panel .material-icons { min-width: 2rem; font-size: 1.6rem; } #send-message-panel .material-icons.secondary { color: var(--clr-text-tertiary)!important; } /* Split out from the rule above -- it was originally a second, unscoped clause on it (a copy-paste slip, matching the same .avatar-box .online/.offline mistake elsewhere in this file), which in practice is the only rule greying out letter-tile.jsx's generic (no-letter) deleted-topic icon (``, no wrapper class of its own to hang a scoped rule off of) -- letter-tile.jsx's *other* deleted-avatar case (.lettertile.disabled) has its own real rule and was never affected. Kept as an explicit, separately-scoped rule instead of silently dropping a behavior nothing else provides. */ i.material-icons.disabled { color: var(--clr-text-tertiary)!important; } #send-message-panel .material-icons.secondary:hover { color: var(--clr-primary-accent)!important; } /* The textarea where the message is entered. */ #send-message-input { overflow: hidden auto; min-height: 2.5rem; max-height: 6rem; } /* New chat invitation panel */ .accept-invite-panel { background-color: var(--clr-background-blue-gray-50); box-shadow: 0px -2px 3px -1px var(--clr-shadow-panel-divider); /* Faint shadow above panel */ width: 100%; z-index: 1; } .accept-invite-panel .title { font-size: 1.2rem; padding: 0.75rem; } .accept-invite-panel .footer { background-color: var(--clr-background-off-white); white-space: nowrap; padding-bottom: 0.35rem; text-align: center; } .accept-invite-panel button { font-size: 1rem; height: 2em; line-height: 2em; border: 1px solid var(--clr-transparent); margin: 0.25rem; box-shadow: 0 1px 2px 0 var(--clr-shadow-button); } /* END of chat invitation panel */ /* A static panel shown when no topic is selected */ #dummy-view { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; background-color: var(--clr-cyan-50); text-align: center; } #dummy-view-icon { display: grid; place-items: center; width: 6.5rem; height: 6.5rem; margin: 0 auto 0.8rem; border-radius: 1.2rem; color: #fff; background: #2878d6; } #dummy-view-icon .material-icons { font-size: 4.2rem; } #dummy-view h2 { margin: 0; font-size: 1.25rem; } #dummy-view p { margin: 0.25rem 0 0; color: #777f89; } #image-preview { position: absolute; display: flex; flex-direction: column; top: 0; left: 0; width: 100%; height: 100%; z-index: 2; background-color: var(--clr-overlay-white-strong); } #preview-caption-panel { display: flex; justify-content: space-between; background-color: var(--clr-background-blue-gray-50); box-shadow: 0 1px 2px var(--clr-shadow-silver-subtle); /* Faint shadow under the panel */ line-height: 2rem; flex-shrink: 0; flex-grow: 0; height: var(--caption-panel-height); padding: 1rem 0.75rem 0 0.75rem; font-size: 120%; z-index: 3; } #preview-caption-panel a { color: var(--clr-text-secondary); text-decoration: none; } #preview-caption-panel a:hover { color: var(--clr-dark); } #image-preview-container { display: flex; justify-content: space-around; align-items: center; overflow: hidden; background-color: var(--clr-gray-medium-bg); width: 100%; height: 100%; } #image-preview-footer { display: flex; justify-content: space-around; height: 3.2rem; line-height: 1.5rem; background-color: var(--clr-background-blue-gray-50); box-shadow: 0px -2px 3px -1px var(--clr-shadow-panel-divider); /* Faint shadow above panel */ flex-grow: 0; flex-shrink: 0; z-index: 1; } #image-preview-container .material-icons { font-size: 6rem; } #image-preview-container .doc-card { display: flex; flex-direction: column; overflow-x: hidden; background-color: var(--clr-std-ltgray); padding: 1rem; border-radius: 0.5rem; max-width: 30rem; } .doc-card .avatar-box { width: 10rem; height: 10rem; font-size: 4.5rem; } .doc-card .avatar-box .material-icons { line-height: 10rem; } /* Video-call related styles */ #video-container { position: absolute; display: flex; flex-direction: column; justify-content: space-between; top: 0; left: 0; width: 100%; height: 100%; background-color: var(--clr-overlay-white-strong); /* Must clear every other in-app overlay (headers/toasts go up to z-index:100) so a call always covers the screen. */ z-index: 200; } #video-container.minimized { left: auto; top: 1rem; right: 1rem; width: 18rem; height: 18rem; background-color: unset; user-select: none; cursor: grab; box-shadow: 0.15rem 0.15rem 1.5rem var(--clr-shadow-dialog); border-radius: 0.5rem; } #video-container.audio-minimized { width: auto; height: auto; background-color: unset; box-shadow: none; } .call-pill { display: flex; align-items: center; gap: 0.5rem; background-color: var(--clr-bright); border-radius: 999px; padding: 0.5rem 0.75rem 0.5rem 1rem; box-shadow: 0.15rem 0.15rem 1.5rem var(--clr-shadow-dialog); cursor: grab; } .call-pill > .material-icons { color: var(--clr-badge-green-text); font-size: 1.3rem; } .call-pill-duration { color: var(--clr-text-primary); font-variant-numeric: tabular-nums; font-size: 0.9rem; white-space: nowrap; } .call-pill-row { /* Wraps .call-pill and its restore button as plain flex siblings (row, shrink-to-content) so the button can sit right next to the pill using ordinary flow instead of position:absolute -- #video-container is already an absolute-positioned flex column (base rule, for the fullscreen video layout) and fighting that from a descendant with more absolute positioning turned out to size unpredictably (a container with a mix of flex/absolute descendants doesn't reliably shrink-wrap the way a single plain flex child does). This wrapper is that one simple child. */ display: flex; align-items: center; gap: 0.5rem; } .audio-minimized button.full-screen { position: static; width: 1.5rem; height: 1.5rem; } .audio-minimized button.full-screen .material-icons { font-size: 1.1rem; } .call-duration { position: absolute; top: 1.5rem; left: 50%; transform: translateX(-50%); z-index: 2; color: #fff; background-color: var(--clr-shadow-dialog); padding: 0.3rem 1rem; border-radius: 999px; font-variant-numeric: tabular-nums; font-size: 0.95rem; } #controls { position: absolute; display: flex; column-gap: 1rem; align-items: center; align-self: center; justify-content: center; bottom: 2.5rem; z-index: 1; } #controls.minimized { column-gap: 0.5rem; bottom: 1.75rem; } #controls button { position: relative; display: flex; align-items: center; justify-content: center; border-radius: 50%; width: 4rem; height: 4rem; min-width: initial; box-shadow: 0 3px 6px 0 var(--clr-shadow-button); } #controls.minimized button { width: 2.75rem; height: 2.75rem; box-shadow: 0 2px 4px 0 var(--clr-shadow-button); } #controls button .material-icons { font-size: 1.8rem; } #controls.minimized button .material-icons { font-size: 1.4rem; } #controls button.off { background-color: rgba(0, 0, 0, 0.55); color: #fff; } #controls button.off:hover:not([disabled]), #controls button.off:active:not([disabled]) { background-color: rgba(0, 0, 0, 0.7); } button.full-screen { position: absolute; top: 2rem; left: 2rem; z-index: 1; width: 2.5rem; height: 2.5rem; border-radius: 0.5rem; padding: 0; box-shadow: none; background-color: transparent; min-width: unset; } .minimized:not(.audio-minimized) button.full-screen { top: 1rem; left: 1rem; width: 2rem; height: 2rem; } button.full-screen:hover:not([disabled]), button:active:not([disabled]) { color: var(--clr-text-secondary); } button.full-screen .material-icons { font-size: x-large; } .minimized:not(.audio-minimized) button.full-screen .material-icons { font-size: large; } #video-container-panel { position: relative; height: 100%; width: 100%; } .call-party { background-color: var(--clr-background-extra-light-gray); border-radius: 0.5rem; border: 2px solid var(--clr-border-light); overflow: hidden; } .call-party:hover { border-color: var(--clr-primary-accent); } .minimized .call-party { border-width: 1px; } .call-party.peer { position: absolute; top: 1rem; left: 1rem; right: 1rem; bottom: 1rem; z-index: 1; } .minimized .call-party.peer { top: 0; left: 0; right: 0; bottom: 0; } .call-party.self { position: absolute; right: 0.5rem; bottom: 0.5rem; width: 10rem; height: 10rem; z-index: 2; } .call-party.self[disabled] { display: none; } video { width: 100%; height: 100%; object-fit: contain; } .call-party.self video { transform: scaleX(-1); } .call-party[disabled] video { display: none; } .caller-card { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; flex-direction: column; } .caller-card .avatar-box { width: 10rem; height: 10rem; font-size: 6rem; } .caller-card.pulse img.avatar, .caller-card.pulse .lettertile { animation: active-call 1.5s linear infinite; } .caller-card .avatar-box .material-icons { font-size: 6rem; line-height: 1.6; } .minimized .caller-card .avatar-box { width: 6rem; height: 6rem; font-size: 3.6rem; } /* Badge with "You" for current user or peer's name. */ .call-party .caller-name { max-width: 12rem; padding: 0.15rem 0.5rem; border-radius: 0.35rem; z-index: 1; text-shadow: 0 0 1px var(--clr-bright); background-color: var(--clr-background-off-white); text-overflow: ellipsis; overflow-x: hidden; white-space: nowrap; } .call-party.self .caller-name.inactive { position: absolute; bottom: 0.25rem; right: 0.25rem; } .caller-card .caller-name { font-size: larger; margin-top: 0.5rem; } .caller-card .trusted-badge, .call-peer-card h1 .trusted-badge { display: inline-block; } /* Plain status line under the name badge (not another pill) -- matches how call-experience-view.jsx's own demo renders the same "正在等待对方接受邀请…" copy. */ .caller-card .caller-status { margin-top: 0.5rem; color: var(--clr-bright); font-size: 0.9rem; opacity: 0.8; } .call-party.peer .caller-name.inactive { position: absolute; font-size: larger; left: 1rem; bottom: 0.5rem; margin: 0 auto; } .minimized .caller-name { padding: 0.1rem 0.35rem; border-radius: 0.25rem; font-weight: lighter; } .call-message { display: flex; flex-direction: row; } .call-message .duration { font-weight: lighter; } #go-to-latest { right: 1.5rem; bottom: 1rem; } @keyframes active-call { 0% { box-shadow: 0 0 0 0.1rem var(--clr-primary-accent-transparent-medium), 0 0 0 0.3rem var(--clr-primary-accent-transparent-medium), 0 0 0 0.5rem var(--clr-primary-accent-transparent-medium); } 100% { box-shadow: 0 0 0 0.4rem var(--clr-primary-accent-transparent-medium), 0 0 0 2rem rgba(33, 150, 243, 0), /* End with transparent */ 0 0 0 3rem rgba(33, 150, 243, 0); /* End with transparent */ } } /* Talk bubbles */ .chat-box { list-style: none; padding: 0 0 3.5rem 0; margin: 0 0.5rem; scroll-behavior: smooth; } /* Group chats have avatars on the left. Make left margin smaller */ .chat-box.group { margin-left: -0.4rem; } .chat-box li { display: flex; margin: 0; padding: 0; align-items: flex-end; } .chat-box .right { justify-content: flex-end; } .voice-unread-dot { position: absolute; top: -0.15rem; right: -0.15rem; width: 0.55rem; height: 0.55rem; border-radius: 50%; background: #e3444d; border: 1.5px solid var(--clr-background-primary, #fff); z-index: 1; } .bubble { position: relative; display: flex; max-width: 36rem; min-width: 9rem; height: auto; padding: 0.75rem 0.5rem 0.75rem 0.5rem; margin: 0; text-align: left; color: var(--clr-bubble-text); border-radius: 0.5rem; transition: ease-out background-color 0.5s; transition-delay: 0.3s; filter: drop-shadow(0.5px 0.5px 0.7px var(--clr-shadow-bubble-drop)); } .chat-box li.single { margin-top: 0.25rem; margin-bottom: 0.75rem; } .chat-box li.first { margin-top: 0.25rem; margin-bottom: 0.15rem; } .chat-box li.middle { margin-top: 0.15rem; margin-bottom: 0.15rem; } .chat-box li.last { margin-top: 0.15rem; margin-bottom: 0.75rem; } .left .bubble { background-color: var(--clr-bubble-left-bg); margin-right: 0.5rem; } .left.flash .bubble { background-color: var(--clr-bubble-left-bg-flash); } .left .bubble.tip { border-bottom-left-radius: 0; } .right .bubble { background-color: var(--clr-bubble-right-bg); margin-left: 1.75rem; } .right.flash .bubble { background-color: var(--clr-bubble-right-bg-flash); } .right .bubble.tip { border-bottom-right-radius: 0; } .chat-box .meta { justify-content: center; margin-top: 0.5rem; margin-bottom: 0.5rem; } .chat-box .meta .bubble { color: var(--clr-bubble-meta-text); min-width: unset; } .meta .bubble.deleted { background-color: var(--clr-bubble-meta-deleted-bg); padding: 0.75rem 0.75rem 0.5rem 0.75rem; } .meta .bubble.date { font-size: smaller; padding: 0.5rem 0.5rem 0.5rem 0.5rem; background-color: var(--clr-bubble-meta-date-bg); text-transform: uppercase; user-select: none; } /* Left triangle placed bottom left flush. */ .left .bubble.tip::before { content: ''; position: absolute; width: 0.85rem; height: 0.85rem; left: -0.8rem; bottom: 0; background-color: var(--clr-bubble-left-bg); clip-path: polygon(100% 0, 0 110%, 100% 110%); -webkit-clip-path: polygon(100% 0, 0 110%, 100% 110%); border-bottom-left-radius: 0.3rem; transition: ease-out background-color 0.5s; transition-delay: 0.3s; } .left.flash .bubble.tip::before { background-color: var(--clr-bubble-left-bg-flash); } /* Right triangle placed bottom right flush. */ .right .bubble.tip::before { content: ''; position: absolute; width: 0.85rem; height: 0.85rem; left: 99.8%; bottom: 0; background-color: var(--clr-bubble-right-bg); clip-path: polygon(0 0, 100% 110%, 0 110%); -webkit-clip-path: polygon(0 0, 100% 110%, 0 110%); border-bottom-right-radius: 0.3rem; transition: ease-out background-color 0.5s; transition-delay: 0.3s; } .right.flash .bubble.tip::before { background-color: var(--clr-bubble-right-bg-flash); } .chat-box .avatar-box { position: relative; width: 1.4rem; min-width: 1.4rem; height: 1.4rem; min-height: 1.4rem; font-size: 0.8rem; margin-bottom: 0.8rem; margin-right: 0.8rem; } /* Message text + timestamp and delivery marker */ .bubble div.content-meta { width: 100%; } .bubble div.message-content { position: relative; margin: 0; width: 100%; max-width: 36rem; overflow-wrap: anywhere; padding: 0 0.75rem 0 0.75rem; font-size: var(--message-text-size); } /* Increase font size when the message contains only emojis. Font from 3x to almost normal, from 1 to 5 emojis in a message */ .bubble div.message-content.emoji-1 { font-size: 300%; } .bubble div.message-content.emoji-2 { font-size: 241%; } .bubble div.message-content.emoji-3 { font-size: 193%; } .bubble div.message-content.emoji-4 { font-size: 155%; } .bubble div.message-content.emoji-5 { font-size: 125%; } /* The timestamp is a floating element. Need to ensure div.message-content is expanded * to accomodate it. It's usually called clearfix. */ .bubble div.message-content:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } .chat-box .timestamp-padding { display: inline-block; width: 4rem; height: 0; } .chat-box .timestamp { position: relative; font-size: 80%; color: var(--clr-bubble-timestamp-text); top: 0.35rem; float: right; white-space: nowrap; user-select: none; } /* The name of the person who sent the message * (group chat only) */ .chat-box .author { font-size: 80%; color:var(--clr-bubble-author-text); max-width: 12em; text-overflow: ellipsis; white-space: nowrap; overflow-x: hidden; } /* Inline and preview image styles */ .inline-image, .image-preview { position: relative; overflow: hidden; border-radius: 0.1rem; } .inline-image { max-width: 36rem; max-height: 24rem; } /* Container with upload progress */ .inline-image > .rounded-container { position: relative; margin: 0.25rem auto; bottom: 2rem; /* Imitating minimum margins on the left and right */ border-left: 0.25rem solid var(--clr-transparent); border-right: 0.25rem solid var(--clr-transparent); } /* Broken image graphics which replaces the stock graphics. */ img.inline-image::before, img.image-preview::before { position: absolute; display: flex; font-size: 0.9rem; font-weight: lighter; color: var(--clr-text-primary); top: 0; left: 0; width: 100%; height: 100%; justify-content: center; background: center no-repeat var(--clr-border-light) url("../img/broken_image.png"); } img.inline-image::before { content: attr(alt); background-size: 3rem 3rem; } img.image-preview::before { content: " "; background-size: 10rem 10rem; } .inline-image.video > img.inline-image::before, img.image-preview.video::before { background: center no-repeat var(--clr-border-light) url("../img/broken_video.png"); } .inline-image.video > img.inline-image::before { background-size: 3rem 3rem; } .inline-video { display: flex; position: relative; align-items: center; justify-content: center; } .inline-video > img.inline-image::before { background: var(--clr-border-light); } .inline-video .duration { padding: 0.25rem 0.5rem; color: var(--clr-toast-bg); /* #333 */ background-color: rgba(255, 255, 255, 0.5); /* Specific rgba */ position: absolute; bottom: 0.25rem; left: 0.25rem; font-size: 80%; border-radius: 0.3rem; } .inline-video .play-control { display: flex; position: absolute; align-items: center; justify-content: center; width: 4rem; height: 4rem; background-color: rgba(0, 0, 0, 0.4); /* Specific rgba */ border-radius: 50%; pointer-events: none; cursor: pointer; } /* Attachment styles */ .attachment { display: flex; } .attachment:last-of-type { margin-bottom: -0.45rem; } /* END of talk bubbles */ /* END of topic/mesages view */ /* InfoView styles */ #info-caption-panel { background-color: var(--clr-background-blue-gray-300); } #info-caption-panel a { color: var(--clr-text-secondary); line-height: 1; text-decoration: none; } #info-caption-panel :hover { color: var(--clr-dark); } #info-title { margin-right: auto; } #group-manager { position: relative; display: flex; flex-direction: column; height: 100%; overflow-y: hidden; } #group-manager-buttons { display: flex; background-color: var(--clr-background-blue-gray-50); box-shadow: 0 -1px var(--clr-shadow-panel-divider); /* Faint shadow above panel */ z-index: 2; justify-content: space-around; padding: 0.4rem; height: 4rem; border-left: 1px solid var(--clr-border-light); } /* END of InfoView */ /* BEGIN Tabs */ ul.tabbar { display: flex; flex-grow: 0; flex-shrink: 0; background: var(--clr-tabbar-bg); list-style:none; margin: 0; width: 100%; overflow: hidden; padding: 0; padding-left: 1rem; } ul.tabbar > li { position: relative; height: 2.4rem; box-shadow: inset 0 -2px 2.5px -1px var(--clr-shadow-button); /* rgba(0,0,0,0.25) */ } ul.tabbar li.active { background: var(--clr-bright); } ul.tabbar li:after { height: 0.10rem; width: 100%; content: ""; bottom: 0; left: 0; position: absolute; background: var(--clr-tabbar-inactive-border); } ul.tabbar li.active:after { height: 0.15rem; content: ""; bottom: 0; left: 0; position: absolute; background: var(--clr-tabbar-active-border); animation: tabbar-border-expand 0.2s cubic-bezier(0.4, 0.0, 0.4, 1) 0s alternate forwards; } @keyframes tabbar-border-expand { 0% { opacity: 0; width: 0; } 100% { opacity: 1; width: 100%; } } ul.tabbar > li > a { position: relative; padding-left: 1rem; padding-right: 1rem; text-align: center; line-height: 2.4rem; font-weight: 400; font-size: 1.3rem; font-variant: small-caps; text-decoration: none; color: var(--clr-tabbar-inactive-text); overflow: hidden; } ul.tabbar li.active > a { color: var(--clr-tabbar-active-text); } /* END Tabs */ /* Miscellaneous */ /* Badge with the number of unread messages */ .unread { display: inline-block; font-size: 0.75rem; font-weight: bolder; background-color: var(--clr-secondary-accent); color: var(--clr-bright); border-radius: 50%; width: 1.35rem; height: 1.35rem; margin-left: 0.5rem; line-height: 1.45rem; text-align: center; vertical-align: middle; } .material-icons.as-badge { padding-left: 0.2rem; font-size: 1.15rem; color: var(--clr-chip-remove-icon-bg); /* #aaa */ } /* Badge with a label, like [you], [muted], etc */ .badge { font-family: 'Roboto Mono', Courier, monospace, sans-serif; font-size: 0.8rem; border: 1px solid var(--clr-badge-default-border); background-color: var(--clr-badge-default-bg); color: var(--clr-badge-default-text); padding: 0.05rem 0.25rem 0.05rem 0.25rem; margin: 0.05rem 0.1rem 0.05rem 0.1rem; border-radius: 0.2rem; display: inline-block; align-self: flex-start; } .badge.green { border-color: var(--clr-badge-green-border); background-color: var(--clr-badge-green-bg); color: var(--clr-badge-green-text); } .badge.yellow { border-color: var(--clr-badge-yellow-border); background-color: var(--clr-badge-yellow-bg); color: var(--clr-badge-yellow-text); } .badge.blue { border-color: var(--clr-badge-blue-border); background-color: var(--clr-badge-blue-bg); color: var(--clr-badge-blue-text); } .badge.red { border-color: var(--clr-badge-red-border); background-color: var(--clr-badge-red-bg); color: var(--clr-badge-red-text); } .badge.magenta { border-color: var(--clr-badge-magenta-border); background-color: var(--clr-badge-magenta-bg); color: var(--clr-badge-magenta-text); } /* Letter tile base style, responsive square box */ .lettertile { width: 100%; padding-bottom: 100%; border-radius: 50%; user-select: none; } /* Div with letter tile content */ .lettertile > div { position: absolute; display: flex; flex-shrink: 0; flex-grow: 0; top: 0; bottom: 0; left: 0; right: 0; text-transform: uppercase; align-items: center; justify-content: center; text-align: center; border-radius: 50%; line-height: 1; padding-top: 0.1em; color: var(--clr-lettertile-default-text); /* default text color #FAFAFA, gray 50 */ } .lettertile:hover { color: var(--clr-lettertile-hover-text); } .lettertile.disabled { opacity: 0.5; } /* Colors of letter tiles */ .lt-bg-0 { background-color: var(--clr-lt-bg-0); } .lt-bg-1 { background-color: var(--clr-lt-bg-1); } .lt-bg-2 { background-color: var(--clr-lt-bg-2); } .lt-bg-3 { background-color: var(--clr-lt-bg-3); } .lt-bg-4 { background-color: var(--clr-lt-bg-4); } .lt-bg-5 { background-color: var(--clr-lt-bg-5); } .lt-bg-6 { background-color: var(--clr-lt-bg-6); } .lt-bg-7 { background-color: var(--clr-lt-bg-7); } .lt-bg-8 { background-color: var(--clr-lt-bg-8); } .lt-bg-9 { background-color: var(--clr-lt-bg-9); } .lt-bg-10 { background-color: var(--clr-lt-bg-10); } .lt-bg-11 { background-color: var(--clr-lt-bg-11); } .lt-bg-12 { background-color: var(--clr-lt-bg-12); } .lt-bg-13 { background-color: var(--clr-lt-bg-13); } .lt-bg-14 { background-color: var(--clr-lt-bg-14); } .lt-bg-15 { background-color: var(--clr-lt-bg-15); } /* Darker version of letter tile colors */ .dk-bg-0 { background-color: var(--clr-dk-bg-0); } .dk-bg-1 { background-color: var(--clr-dk-bg-1); } .dk-bg-2 { background-color: var(--clr-dk-bg-2); } .dk-bg-3 { background-color: var(--clr-dk-bg-3); } .dk-bg-4 { background-color: var(--clr-dk-bg-4); } .dk-bg-5 { background-color: var(--clr-dk-bg-5); } .dk-bg-6 { background-color: var(--clr-dk-bg-6); } .dk-bg-7 { background-color: var(--clr-dk-bg-7); } .dk-bg-8 { background-color: var(--clr-dk-bg-8); } .dk-bg-9 { background-color: var(--clr-dk-bg-9); } .dk-bg-10 { background-color: var(--clr-dk-bg-10); } .dk-bg-11 { background-color: var(--clr-dk-bg-11); } .dk-bg-12 { background-color: var(--clr-dk-bg-12); } .dk-bg-13 { background-color: var(--clr-dk-bg-13); } .dk-bg-14 { background-color: var(--clr-dk-bg-14); } .dk-bg-15 { background-color: var(--clr-dk-bg-15); } /* Same colors as above but for text as opposite to background */ .lt-fg-0 { color: var(--clr-lt-fg-0)!important; } .lt-fg-1 { color: var(--clr-lt-fg-1)!important; } .lt-fg-2 { color: var(--clr-lt-fg-2)!important; } .lt-fg-3 { color: var(--clr-lt-fg-3)!important; } .lt-fg-4 { color: var(--clr-lt-fg-4)!important; } .lt-fg-5 { color: var(--clr-lt-fg-5)!important; } .lt-fg-6 { color: var(--clr-lt-fg-6)!important; } .lt-fg-7 { color: var(--clr-lt-fg-7)!important; } .lt-fg-8 { color: var(--clr-lt-fg-8)!important; } .lt-fg-9 { color: var(--clr-lt-fg-9)!important; } .lt-fg-10 { color: var(--clr-lt-fg-10)!important; } .lt-fg-11 { color: var(--clr-lt-fg-11)!important; } .lt-fg-12 { color: var(--clr-lt-fg-12)!important; } .lt-fg-13 { color: var(--clr-lt-fg-13)!important; } .lt-fg-14 { color: var(--clr-lt-fg-14)!important; } .lt-fg-15 { color: var(--clr-lt-fg-15)!important; } .dk-fg-0 { color: var(--clr-dk-fg-0)!important; } .dk-fg-1 { color: var(--clr-dk-fg-1)!important; } .dk-fg-2 { color: var(--clr-dk-fg-2)!important; } .dk-fg-3 { color: var(--clr-dk-fg-3)!important; } .dk-fg-4 { color: var(--clr-dk-fg-4)!important; } .dk-fg-5 { color: var(--clr-dk-fg-5)!important; } .dk-fg-6 { color: var(--clr-dk-fg-6)!important; } .dk-fg-7 { color: var(--clr-dk-fg-7)!important; } .dk-fg-8 { color: var(--clr-dk-fg-8)!important; } .dk-fg-9 { color: var(--clr-dk-fg-9)!important; } .dk-fg-10 { color: var(--clr-dk-fg-10)!important; } .dk-fg-11 { color: var(--clr-dk-fg-11)!important; } .dk-fg-12 { color: var(--clr-dk-fg-12)!important; } .dk-fg-13 { color: var(--clr-dk-fg-13)!important; } .dk-fg-14 { color: var(--clr-dk-fg-14)!important; } .dk-fg-15 { color: var(--clr-dk-fg-15)!important; } /* Material icons resized from the default 24pt */ .material-icons { font-size: 1.4rem; line-height: 1; vertical-align: middle; text-align: center; user-select: none; } .material-icons.small { font-size: 1rem; } .material-icons.medium { font-size: 1.2rem; } .material-icons.large { font-size: 1.6rem; } .material-icons.big { font-size: 2.2rem; } .material-icons.x-big { font-size: 3rem; } .material-icons.huge { font-size: 4rem; } .composed-material { display: inline-block; position: relative; } .composed-material .second { position: absolute; font-size: 85%; top: 7%; left: 39%; font-weight: bold; } .composed-material .second-small { position: absolute; font-size: 62%; top: 14%; left: 30%; font-weight: bold; } /* White outline */ .material-icons.outline { position: relative; text-shadow: -1px 1px var(--clr-bright), 1px 1px var(--clr-bright), 1px -1px var(--clr-bright), -1px -1px var(--clr-bright); } #self-avatar .material-icons { font-size: 2.4rem; line-height: 3rem; } .avatar-box .material-icons { color: var(--clr-lettertile-default-text); /* #fafafa, gray 50 */ border-radius: 50%; width: inherit; height: inherit; } .chip-input { display: flex; flex-wrap: wrap; flex-grow: 1; cursor: text; font-size: 1.1rem; font-weight: normal; background: var(--clr-transparent); border-bottom: 1px solid var(--clr-input-border); box-shadow: 0 1px 0 var(--clr-input-shadow); transition: all 0.1s ease-in-out; max-height: 10rem; min-height: 4rem; overflow-y: scroll; margin: 0.25rem 0 0.25rem 0; outline: none; color: var(--clr-input-text); align-items: center; justify-content: flex-start; text-align: center; } .chip-input.focused { border-bottom: 1px solid var(--clr-input-border-focus); box-shadow: 0 1px 0 var(--clr-input-shadow-focus); } .chip-input > input[type="text"] { display: inline-block; width: auto; border: none; line-height: 1.8; box-shadow: none; min-width: 4rem; flex: 1 0 auto; height: 1.8rem; margin: 0.125rem; } .chip { display: flex; flex: 0 0 auto; align-items: center; height: 1.8rem; line-height: 1.8; border-radius: 0.9rem; margin: 0.125rem; background-color: var(--clr-chip-bg); white-space: nowrap; font-size: 90%; max-width: 12rem; overflow: hidden; text-overflow: ellipsis; } .chip > span { white-space: nowrap; overflow-x: hidden; text-overflow: ellipsis; } .chip.invalid { color: var(--clr-chip-invalid-text); background-color: var(--clr-chip-invalid-bg); } .chip > a { display: inline-block; color: var(--clr-chip-remove-icon-text); background-color: var(--clr-chip-remove-icon-bg); border-radius: 50%; margin: 0.3rem; width: 1.175rem; min-width: 1.175rem; height: 1.175rem; line-height: 1.15; text-decoration: none; } .chip > a:focus, .chip > a:hover { text-decoration: none; color: var(--clr-chip-remove-icon-hover-text); background-color: var(--clr-chip-remove-icon-hover-bg); } .chip .avatar-box { position: relative; width: 1.8rem; min-width: 1.8rem; height: 1.8rem; min-height: 1.8rem; font-size: 1rem; margin-right: 0.2rem; } .chip .avatar-box .material-icons { font-size: 1.4rem; line-height: 1.8rem; } .chip .spacer { display: inline-block; margin: 0.3rem; width: 0.25rem; height: 1.175rem; } .load-spinner-box { --size-small: 2.5rem; --size-large: 4rem; position: absolute; box-shadow: 0.1rem 0.1rem 0.15rem 1px var(--clr-shadow-button); border-radius: 50%; padding: 0.25rem; width: var(--size-small); height: var(--size-small); left: 0; right: 0; top: 5rem; margin-left: auto; margin-right: auto; background-color: var(--clr-bright); z-index: 2; } .load-spinner-box.large { width: var(--size-large); height: var(--size-large); } .load-spinner-box.clear { box-shadow: 0.1rem 0.1rem 0.15rem 1px var(--clr-shadow-button-inset-active); /* rgba(0,0,0,0.12) */ background-color: rgba(255,255,255,0.5); /* Specific rgba */ } .load-spinner-box.centered { top: calc(var(--size-small)/2 - 0.25rem); } .load-spinner-box.large.centered { top: calc(var(--size-large)/2 - 0.25rem); } .loader-spinner { border: 0.35rem solid var(--clr-spinner-track); border-radius: 50%; border-top: 0.35rem solid var(--clr-spinner-active); width: 2rem; height: 2rem; animation: spin 1.5s linear infinite; } .load-spinner-box.large .loader-spinner { width: 3.5rem; height: 3.5rem; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } /* File upload styles */ .uploader { display: flex; } /* Gray uploader bar of fixed length (background) */ .uploader > div { position: relative; height: 0.6rem; padding: 0.15rem; margin: 0.35rem; width: 6rem; line-height: 0; border-radius: 0.1rem; background-color: var(--clr-background-blue-gray-100); } /* Colored uploader progress bar of variable length */ .uploader > div > span { display: inline-block; height: 0.3rem; background-color: var(--clr-primary-action); border-radius: 0.08rem; } /* Highlighted text */ .highlight { color: var(--clr-highlight-text); font-weight: bolder; } .highlight .preview { color: var(--clr-highlight-preview-text); font-weight: inherit; } /* Image cropping widget */ .cropper { position: relative; width: 18rem; height: 21rem; margin: auto; margin-top: 1rem; align-self: center; transform: translateZ(0); border-radius: 0.25rem; } .cropper .bounding-box { position: relative; width: 18rem; height: 18rem; overflow: hidden; z-index: 1; border-radius: 0.25rem; border: solid 2px var(--clr-cropper-bounding-box-border); box-shadow: 1px 1px 3px var(--clr-shadow-cropper-gray); background-color: var(--clr-cropper-bounding-box-bg); } .cropper .preview { position: absolute; max-height: none; max-width: none; z-index: -1; } .cropper .cutout { position: absolute; width: 17.8rem; height: 17.8rem; border: 1px dashed var(--clr-cropper-cutout-border); margin: auto; top: 0; bottom: 0; right: 0; left: 0; box-shadow: 0 0 150rem 150rem var(--clr-cropper-cutout-shadow); z-index: 0; } .cropper .cutout.circle { border-radius: 50%; } .cropper .overlay { position: absolute; cursor: move; touch-action: none; z-index: 1; } .cropper .zoom-wrapper { height: 2rem; width: 80%; margin: 1rem auto; text-align: center; } .cropper .zoom { box-shadow: none; pointer-events: none; z-index: 2; } .cropper .zoom:focus { outline: none; } /* Quoted (cited) content */ .reply-quote { position: relative; padding: 0.15rem 0.5rem 0.25rem 0.5rem; border-left: 0.25rem solid var(--clr-reply-quote-border); line-height: 1.5em; font-weight: lighter; border-radius: 0.25rem; color: var(--clr-reply-quote-text); cursor: pointer; } .chat-box .bubble .reply-quote { margin: 0.15rem -0.75rem 0.3rem -0.75rem; } .chat-box .bubble .reply-quote:first-child { margin-top: -0.25rem; } .chat-box .left .reply-quote { background-color: var(--clr-reply-quote-left-bg); } .chat-box .right .reply-quote { background-color: var(--clr-reply-quote-right-bg); } .reply-quote .inline-image { vertical-align: middle; margin-bottom: 0.1rem; } .reply-quote img.inline-image::before { content: ''; } #reply-quote-preview { display: flex; align-items: center; } #reply-quote-preview .reply-quote { width: 100%; background-color: var(--clr-reply-quote-preview-bg); margin: 0.35rem 0.5rem 0 0; cursor: initial; } #reply-quote-preview .cancel { min-width: 2.4rem; text-align: center; } #reply-quote-preview .inline-image { background-color: var(--clr-border-light); } #reply-quote-preview img.inline-image::before { content: ''; } #send-message-panel #reply-quote-preview { width: 100%; } #send-message-panel #reply-quote-preview .reply-quote { margin-bottom: 0.35rem; } .forwarding-quote { font-size: 200%; line-height: 200%; } .mention { font-weight: 500; } /* Message forwarding. */ .forward-dialog { position: relative; overflow: hidden; background-color: var(--clr-bright); box-shadow: 0.15rem 0.15rem 1.5rem var(--clr-shadow-dialog); padding: 0.5rem; border-radius: 0.3rem; margin: auto 1rem auto 1rem; width: 24rem; height: 80%; } .forward-dialog .scrollable-panel { height: 80%; } .audio { display: flex; margin-left: auto; align-items: center; flex: none; background-color: var(--clr-audio-bg); height: 3rem; border-radius: 1.5rem; } .audio canvas { width: 14rem; height: 2.6rem; margin-right: 2rem; } .audio canvas.playback { margin-right: 0; } /* .compose-record-overlay (8588 below) replaced this holdMode presentation -- see audio-recorder.jsx's holdMode render for why. */ .compose-record-overlay canvas { width: 6rem; height: 1.8rem; margin-top: 0.4rem; } .audio .duration { font-size: large; } .audio-player { display: flex; align-items: center; } .audio-player .material-icons.large { font-size: 2.4rem; color: var(--clr-audio-icon); } .audio-player .material-icons.disabled { color: var(--clr-audio-icon-disabled); cursor: default; } .audio-player .playback { width: 14rem; height: 2.6rem; } .audio-player canvas.playback { display: block; } /* Targets the wrapper div around canvas.playback + .timer (audio-player.jsx's non-short render) -- was accidentally written as div.playback, but "playback" is the canvas's own class, not this wrapper's (which had no class at all), so this never matched anything; canvas+timer fell back to block-level stacking (timer on its own line below the waveform) instead of sitting side by side. */ .audio-player .playback-row { display: flex; align-items: center; justify-content: center; color: var(--clr-audio-icon); font-size: small; } .audio-player .timer { font-size: smaller; color: var(--clr-audio-timer-text); } /* Pinned messages */ #pinned-wrapper { position: relative; display: flex; align-items: center; height: 100%; margin-right: 0.5rem; } .pinned { position: relative; display: flex; align-items: center; padding: 0.15rem 0.5rem 0.25rem 0.5rem; background-color: var(--clr-background-off-white); background-position: center; font-weight: lighter; border-radius: 0 0.25rem 0.25rem 0; color: var(--clr-text-primary); height: 100%; width: 24rem; min-width: 0; cursor: pointer; transition: background 0.4s; } .pinned > p { overflow-x: hidden; text-overflow: ellipsis; white-space: nowrap; } .pinned:hover { background-color: var(--clr-bright); /* #fafdff is very close to white */ } .pinned:active { background-color: var(--clr-blue-wash-medium); transition: background 0s; } .pinned-scroll { position: relative; display: flex; flex-direction: column; align-items: center; border-radius: 0.25rem 0 0 0.25rem; background-color: var(--clr-background-extra-light-gray); justify-content: space-evenly; height: 100%; padding: 0.2rem; margin-left: 0.35rem; user-select: none; } .pinned-scroll .dot { width: 0.3rem; height: 0.3rem; border-radius: 50%; background-color: var(--clr-text-tertiary); user-select: none; } .pinned-scroll .adot { width: 0.45rem; height: 0.45rem; border-radius: 50%; background-color: var(--clr-light-blue-accent); user-select: none; } #pinned-wrapper:hover .menuTrigger { opacity: 0.9; } #pinned-wrapper:hover .menuTrigger a { color: var(--clr-text-secondary); } .pinned-menu { position: absolute; display: flex; flex-direction: column; background-color: var(--clr-pinned-menu-bg); border-radius: 0 0.25rem 0.25rem 0; justify-content: space-evenly; top: 0; bottom: 0; right: 0; } .pinned-menu .menuTrigger { position: relative; right: 0; } /* END of pinned messages */ /* Contact attachments */ .contact-card { position: relative; background-color: var(--clr-background-off-white); border-radius: 0.5rem; display: flex; flex-direction: column; min-width: 14rem; } .contact-card .avatar-box { position: relative; width: 1.8rem; height: 1.8rem; font-size: 1rem; margin-right: 0.75rem; margin-bottom: 0; } .contact-card .contact-body { align-items: center; background-color: var(--clr-background-blue-gray-50); display: flex; padding: 0.75rem; border-radius: 0.5rem 0.5rem 0 0; border-bottom: none; } .contact-card .contact-body .name-box { display: flex; flex-direction: column; overflow: hidden; } .contact-card .contact-body .name-box .name { color: var(--clr-text-primary); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .contact-card .contact-body .name-box .org { color: var(--clr-text-secondary); font-size: 90%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 300; } .contact-card .contact-actions { display: flex; justify-content: space-evenly; align-items: center; padding: 0 0.5rem; border-radius: 0 0 0.5rem 0.5rem; border-top: none; background-color: var(--clr-bright); } .contact-card .contact-actions a { cursor: pointer; } .contact-card .contact-actions .divider { height: 1.8rem; opacity: 0.5; } /* END of contact attachments */ /* Drag-and-drop area. */ .drag-n-drop { display: flex; border: dashed var(--clr-drag-n-drop-border) 0.15rem; border-radius: 1rem; background-color: var(--clr-drag-n-drop-bg); position: absolute; top: 1.5rem; bottom: 1.5rem; left: 1.5rem; right: 1.5rem; z-index: 3; justify-content: center; align-items: center; font-size: 2rem; color: var(--clr-drag-n-drop-text); outline: 0.5rem solid var(--clr-drag-n-drop-outline); } .country-flag { display: inline-block; font-size: larger; } .dial-code { white-space: nowrap; display: inline-block; cursor: pointer; vertical-align: middle; margin-bottom: 0.15rem; } ul.phone-country-selector { list-style: none; overflow-x: hidden; } ul.phone-country-selector > li { position: relative; font-weight: lighter; padding: 0.25rem 0.5rem 0.15rem 0.5rem; cursor: pointer; width: 100%; } ul.phone-country-selector > li:hover { background-color: var(--clr-background-blue-gray-50); /* blue-gray 50 highlight */ } ul.phone-country-selector > li.selected { background-color: var(--clr-background-blue-gray-100); /* blue-gray 100 highlight */ } ul.phone-country-selector .dial-code { position: absolute; right: 0.5rem; color: var(--clr-primary-action); font-weight: normal; } ul.phone-country-selector span { display: inline-block; } ul.phone-country-selector span.country { text-overflow: ellipsis; overflow-x: hidden; } .image-grid { position: relative; display: grid; grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr)); gap: 0.35rem; padding: 0.25rem; } .image-grid-cell { padding: 0; margin: 0; width: 100%; height: 7rem; overflow: hidden; border-radius: 0.25rem; border: 1.5px solid transparent; cursor: pointer; box-shadow: 0 0 0.2rem var( --clr-shadow-hr-inset); /* gray */ } .image-grid-cell img { object-fit: cover; } .image-grid-cell.selected { border: 1.5px solid var(--clr-secondary-accent); } img.inverted { filter: invert(1); } div.toast { visibility: hidden; display: flex; align-items: center; justify-content: center; position: absolute; min-width: 10rem; padding: 0.5rem 1rem; height: 3rem; z-index: 3; font-weight: lighter; color: var(--clr-toast-text); background-color: var(--clr-toast-bg); border-radius: 0.5rem; box-shadow: 1px 2px 0.3rem var(--clr-shadow-gray-strong); /* gray */ bottom: 2rem; left: 50%; translate: -50%; } div.toast.show { visibility: visible; animation: fadein 0.5s, fadeout 0.5s 2.5s; } /* Tenant entry, authentication, and identity security. */ #sidepanel.auth-onboarding-panel { width: 100%; min-width: 0; flex: 1 1 auto; color-scheme: light; background: #f7f9fc; color: #20242c; } .auth-onboarding-panel * { box-sizing: border-box; letter-spacing: 0; } .auth-page, .auth-landing { position: relative; width: 100%; min-height: 100%; overflow-x: hidden; overflow-y: auto; background: #fff; } .auth-soft-bg { background: #f6f7f9; } .auth-landing { display: flex; flex-direction: column; align-items: center; padding: max(1.5rem, env(safe-area-inset-top)) 2rem max(1.5rem, env(safe-area-inset-bottom)); background: radial-gradient(ellipse 40% 25% at 90% 0%, rgba(68, 151, 255, 0.14), transparent 72%), #fff; } .auth-landing-form { width: min(100%, 28rem); margin: auto 0; } .auth-brand { display: flex; flex-direction: column; align-items: center; margin-bottom: 4rem; } .auth-logo { display: grid; place-items: center; width: 5.5rem; height: 5.5rem; border-radius: 0.75rem; background: #fff; box-shadow: 0 0.75rem 2rem rgba(35, 74, 125, 0.14); } .auth-logo span { display: grid; place-items: center; width: 3.75rem; height: 3.75rem; border-radius: 50% 50% 50% 18%; color: #fff; background: #1677ff; font-size: 2.2rem; font-weight: 700; transform: rotate(-18deg); } .auth-brand h1 { margin: 1.3rem 0 0; color: #14171c; font-size: 2rem; font-weight: 700; } .auth-top-link, .auth-bottom-link, .auth-back-link, .auth-text-button, .auth-switch button, .auth-remove-file { width: auto; min-width: 0; height: auto; min-height: 0; padding: 0; border: 0; box-shadow: none; color: #1677ff; background: transparent; font-size: 0.95rem; text-transform: none; } .auth-top-link { position: absolute; top: max(1.5rem, env(safe-area-inset-top)); right: 2rem; } .auth-bottom-link { margin-top: auto; padding-top: 2rem; } .auth-back-link { position: absolute; top: max(1.5rem, env(safe-area-inset-top)); left: 2rem; display: flex; align-items: center; color: #616975; } .auth-back-link .material-icons { margin-right: 0.15rem; font-size: 1rem; } .auth-field-wrap { margin-bottom: 1rem; } .auth-field { display: flex; align-items: center; min-height: 3.8rem; border: 1px solid transparent; border-radius: 0.5rem; background: #f2f4f7; transition: border-color 150ms, box-shadow 150ms; } .auth-field:focus-within { border-color: #4091ff; box-shadow: 0 0 0 3px rgba(22, 119, 255, 0.1); } .auth-field.invalid { border-color: #d94b4b; } .auth-field input { min-width: 0; width: 100%; height: 3.7rem; margin: 0; padding: 0 1rem; border: 0; box-shadow: none; color: #252931; background: transparent; font-size: 1rem; } .auth-field input:focus { box-shadow: none; } .auth-field input::placeholder, .auth-list-form input::placeholder, .auth-realname-content input::placeholder, .auth-form textarea::placeholder { color: #b2b7bf; } .auth-field-icon { flex: none; margin-left: 1rem; color: #4091ff; font-size: 1.35rem; } /* Same left-side position/color as the plain (non-clickable) .auth-field-icon above -- this is just that icon made clickable (企业注册's credit-code scan icon), so it shouldn't look any different at rest, only respond to a tap. */ .auth-field-icon-button { flex: none; display: flex; margin: 0 0 0 1rem; padding: 0; border: 0; background: transparent; color: #4091ff; } .auth-field-icon-button .material-icons { font-size: 1.35rem; } .auth-inline-icon, .auth-icon-button { display: grid; place-items: center; flex: none; width: 3.25rem; min-width: 3.25rem; height: 3.25rem; min-height: 3.25rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #a7adb6; background: transparent; } .auth-inline-icon .material-icons { font-size: 1.25rem; } .auth-field-error { margin-top: 0.4rem; color: #cf3f3f; font-size: 0.82rem; } .auth-primary { width: 100%; height: 3.8rem; margin: 1rem 0 0; border: 0; border-radius: 0.5rem; color: #fff; background: #368bfa; box-shadow: 0 0.4rem 1rem rgba(54, 139, 250, 0.2); font-size: 1.08rem; font-weight: 500; text-transform: none; } .auth-primary:hover:not([disabled]), .auth-primary:focus:not([disabled]) { background: #1677e8; } .auth-primary[disabled] { color: #fff; background: #b8d5fa; box-shadow: none; cursor: default; } .auth-row { display: flex; align-items: center; } .auth-row-end { justify-content: flex-end; min-height: 1.5rem; margin-top: -0.35rem; } .auth-switch { margin: 1.3rem 0 0; color: #4a4f57; text-align: center; } .auth-agreement { display: flex; align-items: flex-start; max-width: 32rem; margin-top: auto; color: #454b54; font-size: 0.9rem; line-height: 1.5; } .auth-agreement input { width: 1.1rem; height: 1.1rem; margin: 0.12rem 0.55rem 0 0; accent-color: #368bfa; } .auth-agreement a { color: #1677ff; } .auth-form-alert { display: flex; align-items: center; margin: 0 0 1rem; padding: 0.75rem 0.9rem; border-radius: 0.4rem; color: #bd3434; background: #fff1f1; font-size: 0.9rem; } .auth-form-alert .material-icons { margin-right: 0.45rem; font-size: 1.15rem; } .auth-header { position: sticky; top: 0; z-index: 2; display: grid; grid-template-columns: 3.5rem 1fr 3.5rem; align-items: center; height: 4.25rem; padding-top: env(safe-area-inset-top); border-bottom: 1px solid #edf0f4; background: rgba(255,255,255,0.96); } .auth-header h1 { margin: 0; color: #252931; font-size: 1.2rem; text-align: center; } .auth-header .auth-icon-button { color: #252931; } .auth-header .material-icons { font-size: 1.25rem; } .auth-content { width: 100%; min-height: calc(100% - 4.25rem); margin: 0 auto; padding: 2rem; } .auth-content-narrow { max-width: 40rem; } .auth-steps { display: grid; grid-template-columns: repeat(3, 1fr); margin: 0 0 2.25rem; padding: 0; list-style: none; } .auth-steps li { position: relative; display: flex; flex-direction: column; align-items: center; color: #b4b9c1; text-align: center; } .auth-steps li:not(:last-child)::after { content: ''; position: absolute; top: 1rem; left: calc(50% + 1.25rem); width: calc(100% - 2.5rem); height: 2px; background: #d9dde3; } .auth-steps li.active:not(:last-child)::after { background: #4091ff; } .auth-steps span { display: grid; place-items: center; width: 2rem; height: 2rem; border: 1px solid #aeb4bd; border-radius: 50%; background: #fff; } .auth-steps b { margin-top: 0.55rem; font-size: 0.86rem; font-weight: 500; } .auth-steps .active { color: #368bfa; } .auth-steps .active span { border-color: #368bfa; color: #fff; background: #368bfa; } .auth-label { display: block; margin: 1.25rem 0 0.55rem; color: #292d34; font-size: 1rem; font-weight: 500; } .auth-label span { margin-left: 0.35rem; color: #87909c; font-size: 0.78rem; font-weight: 400; } .auth-help, .auth-review-time { margin: -0.45rem 0 0; color: #9ba1aa; font-size: 0.84rem; } .auth-upload { display: flex; position: relative; flex-direction: column; align-items: center; justify-content: center; min-height: 12rem; overflow: hidden; border: 1px dashed #c7ccd4; border-radius: 0.5rem; background: #fafafa; cursor: pointer; } .auth-upload.invalid { border-color: #d94b4b; } .auth-upload input, .auth-add-screenshot input { display: none; } .auth-upload .material-icons { color: #4091ff; font-size: 3.4rem; } .auth-upload img { width: 100%; height: 8rem; object-fit: contain; } .auth-upload strong { max-width: 90%; margin-top: 0.65rem; overflow: hidden; color: #252931; font-size: 0.95rem; text-overflow: ellipsis; white-space: nowrap; } .auth-upload small { margin-top: 0.35rem; color: #a4aab2; } .auth-remove-file { margin-top: 0.5rem; color: #cf3f3f; } .auth-review-time { display: flex; align-items: center; justify-content: center; margin-top: 0.85rem; } .auth-review-time .material-icons { margin-right: 0.35rem; font-size: 1rem; } .auth-form textarea { width: 100%; min-height: 10rem; resize: vertical; padding: 1rem; border: 1px solid #e1e4e9; border-radius: 0.5rem; box-shadow: none; color: #252931; background: #fff; font: inherit; line-height: 1.6; } .auth-form textarea:focus { border-color: #4091ff; outline: none; box-shadow: 0 0 0 3px rgba(22, 119, 255, 0.1); } .auth-form textarea.invalid { border-color: #d94b4b; } .auth-counter { margin: -1.7rem 0.75rem 0.8rem 0; color: #a0a6af; font-size: 0.8rem; text-align: right; } .auth-screenshot-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.75rem; } .auth-screenshot, .auth-add-screenshot { position: relative; aspect-ratio: 1; overflow: hidden; border: 1px solid #dce0e5; border-radius: 0.4rem; background: #fff; } .auth-screenshot img { width: 100%; height: 100%; object-fit: cover; } .auth-screenshot button { position: absolute; top: 0.2rem; right: 0.2rem; display: grid; place-items: center; width: 1.4rem; min-width: 1.4rem; height: 1.4rem; min-height: 1.4rem; margin: 0; padding: 0; border: 0; border-radius: 50%; color: #fff; background: rgba(0,0,0,0.58); } .auth-screenshot button .material-icons { font-size: 0.9rem; } .auth-add-screenshot { display: grid; place-items: center; color: #87909c; cursor: pointer; } .auth-code-button { flex: none; width: auto; min-width: 6.8rem; height: 2.7rem; min-height: 2.7rem; margin: 0 0.55rem 0 0; padding: 0 0.8rem; border: 0; border-radius: 0.4rem; box-shadow: none; color: #1677ff; background: transparent; font-size: 0.9rem; text-transform: none; } .auth-code-button[disabled] { color: #a7adb6; } .auth-register-form .auth-brand { margin-bottom: 2rem; } .auth-register-page .auth-agreement { margin-top: 2rem; } .auth-list-form { display: flex; flex-direction: column; min-height: calc(100vh - 8.25rem); } .auth-list-form label { /* `.auth-list-form` is `display:flex` with no explicit `align-items`, so it defaults to `normal` -- which does not stretch a `display:grid` child to the flex container's full width the way it would a plain block child, leaving each label sized to fit its own grid content instead. The "手机号" row (2 populated grid columns: label + input, nothing in the 3rd) ends up visibly narrower than "验证码" (3 populated columns, the extra width of the code-request button), so the stacked white row backgrounds end at different edges instead of lining up. Explicit `width: 100%` sidesteps the stretch behavior entirely instead of depending on it. */ display: grid; grid-template-columns: 7rem 1fr auto; align-items: center; width: 100%; min-height: 4.5rem; padding: 0 1rem; border-bottom: 1px solid #e4e7eb; background: #fff; box-sizing: border-box; } .auth-list-form label span { color: #30343b; font-size: 1rem; } .auth-list-form input { min-width: 0; width: 100%; height: 4rem; margin: 0; border: 0; box-shadow: none; color: #252931; background: transparent; font-size: 1rem; } .auth-list-form input:focus { box-shadow: none; } .auth-list-gap { height: 1rem; background: #f6f7f9; } .auth-sticky-action { margin-top: auto; } /* docs/images/身份验证(安卓).png shows "确定" sitting a fixed distance below this page's own short 2-field form, not pinned to the very bottom of the screen -- `.auth-sticky-action`'s `margin-top: auto` (shared with PasswordReset below, a 4-field form long enough that "anchor to the bottom" and "sit right after the content" look about the same) pushes it the rest of the way down an otherwise mostly-empty page instead, which is the "why is there a huge gap" of it. Scoped to just this page so PasswordReset's own sticky-bottom placement (correct for its longer form) is untouched. */ .auth-identity-check-page .auth-sticky-action { margin-top: 2.5rem; } .auth-realname-page { background: #f5f6f8; } .auth-realname-hero { display: flex; align-items: center; justify-content: space-between; min-height: 14rem; padding: 2rem max(2rem, calc((100% - 44rem) / 2)); color: #12357b; background: #cfe1fa; } .auth-realname-hero div { display: flex; flex-direction: column; } .auth-realname-hero strong { font-size: 2.5rem; font-weight: 800; } .auth-realname-hero span { margin-top: 0.75rem; color: #53799c; font-size: 1.2rem; } .auth-realname-hero > .material-icons { color: #4a82ee; font-size: 9rem; opacity: 0.9; } .auth-realname-content { width: min(calc(100% - 2rem), 44rem); margin: -1.5rem auto 0; padding: 0 0 2rem; } .auth-realname-content h2 { position: relative; z-index: 1; margin: 0; padding: 1.5rem 2rem; border: 1px solid #fff; border-radius: 0.5rem 0.5rem 0 0; background: #e8f1fd; font-size: 1.15rem; } .auth-realname-content form { padding: 2rem; background: #fff; } .auth-realname-content label { display: grid; grid-template-columns: 8rem 1fr; align-items: center; min-height: 4.5rem; margin-bottom: 1rem; padding: 0 1rem; border-radius: 0.5rem; background: #f6f6f7; } .auth-realname-content input { min-width: 0; width: 100%; height: 3.8rem; margin: 0; border: 0; box-shadow: none; color: #30343b; background: transparent; font-size: 1rem; } .auth-privacy-note { display: flex; margin: 1rem 0 0; padding: 1rem; border-radius: 0.4rem; color: #a0a6af; background: #fff; line-height: 1.5; } .auth-privacy-note .material-icons { margin-right: 0.5rem; font-size: 1.15rem; } .auth-reminder-demo { overflow: hidden; background: #f5f6f8; } .auth-demo-chat { width: min(100%, 42rem); margin: 0 auto; padding: 2rem; } .auth-demo-chat h1 { text-align: center; } .auth-demo-search { display: flex; align-items: center; justify-content: center; height: 2.8rem; margin-bottom: 1rem; border-radius: 0.5rem; color: #969ca5; background: #e9ecf0; } .auth-demo-row { display: flex; align-items: center; min-height: 4.8rem; border-bottom: 1px solid #e3e6ea; } .auth-demo-row > span { display: grid; place-items: center; width: 3.2rem; height: 3.2rem; margin-right: 0.8rem; border-radius: 0.5rem; color: #fff; background: #368bfa; } .auth-demo-row div { display: flex; flex-direction: column; } .auth-demo-row small { margin-top: 0.3rem; color: #969ca5; } .auth-modal-backdrop { position: absolute; inset: 0; z-index: 3; display: grid; place-items: center; padding: 1.5rem; background: rgba(0,0,0,0.38); } .auth-modal { width: min(100%, 30rem); padding: 2rem; border-radius: 0.5rem; background: #fff; box-shadow: 0 1rem 3rem rgba(0,0,0,0.18); text-align: center; } .auth-modal { position: relative; } .auth-modal-close { position: absolute; top: 0.6rem; right: 0.6rem; min-width: 0; height: auto; margin: 0; padding: 0.25rem; color: #9aa1ab; background: none; border: 0; box-shadow: none; } .auth-modal h2 { margin: 0 0 1rem; font-size: 1.45rem; } .auth-modal p { color: #858c96; line-height: 1.6; text-align: left; } .auth-modal .auth-text-button { margin-top: 1rem; color: #7c838d; } .auth-pin-content { display: flex; position: relative; flex-direction: column; align-items: center; width: min(100%, 32rem); margin: 0 auto; padding: 6rem 2rem 2rem; } .auth-pin-content h1 { margin: 0 0 3.5rem; font-size: 1.8rem; } /* 青少年模式的 PIN 页复用了下面的 .auth-pin-boxes / .auth-pin-input / .auth-primary, 但它自己的容器类 .youth-password-gate 原来在整个 base.css 里一条规则都没有。缺的正是 .auth-pin-content 提供的两件事:position:relative(.auth-pin-input 是 position:absolute + top:11rem,没有定位祖先就会跑到更外层去,点 PIN 框重新聚焦会点空)和 align-items:center (.auth-pin-boxes 是 grid,父级的 text-align:center 对它无效,不会居中)。 */ .youth-password-gate { display: flex; position: relative; flex-direction: column; align-items: center; width: min(100%, 32rem); margin: 0 auto; padding: 3rem 2rem 2rem; } .youth-password-gate .auth-primary { width: min(100%, 24rem); margin-top: 3rem; } .youth-password-gate .auth-text-button { margin-top: 1.2rem; } /* .auth-pin-input used to be sized/positioned with hardcoded top/width/height values guessed to match wherever .auth-pin-boxes happened to render on each page -- .auth-pin-content's and .youth-password-gate's shorter top padding push the boxes to two different heights, so one shared guessed `top` could only ever be right for one of them (confirmed live twice: the two pages' real box positions differ by ~9.25rem, and a value tuned for one left the other's boxes only ~32% overlapping the real input, still mostly unclickable). Wrapping both in their own tightly-fitting, positioned container instead -- inset:0 on the input then always matches .auth-pin-boxes' actual rendered box exactly, on any page, with no measured constant to keep in sync. */ .auth-pin-wrap { position: relative; display: inline-block; } .auth-pin-boxes { display: grid; grid-template-columns: repeat(4, 4rem); gap: 0.8rem; } .auth-pin-boxes span { display: grid; place-items: center; aspect-ratio: 1; border-radius: 0.35rem; color: #30343b; background: #f2f3f5; } .auth-pin-input { position: absolute; inset: 0; margin: 0; opacity: 0; } /* input[type="text"]'s global reset (2131 above) sets a fixed height:2.5rem at higher specificity (0,1,1) than a bare .auth-pin-input's (0,1,0) -- it was winning and pinning this input to 2.5rem tall regardless of the boxes' actual height, undoing the inset:0 fix above for the vertical axis (width happened to still come out right only because the reset's own width:100% agrees with this element's actual need). Selector bumped to definitively outrank it, not just happen to. */ .auth-pin-wrap .auth-pin-input { width: 100%; height: 100%; } .auth-pin-content .auth-primary { width: min(100%, 24rem); margin-top: 3rem; } .auth-toast { position: fixed; z-index: 20; bottom: max(2rem, env(safe-area-inset-bottom)); left: 50%; display: flex; align-items: center; max-width: calc(100% - 2rem); padding: 0.8rem 1.1rem; border-radius: 0.4rem; color: #fff; background: rgba(31, 35, 42, 0.92); box-shadow: 0 0.5rem 1.5rem rgba(0,0,0,0.18); transform: translateX(-50%); animation: auth-toast-in 180ms ease-out; } .auth-toast .material-icons { margin-right: 0.5rem; color: #63d68b; font-size: 1.15rem; } .security-product-links button.flat-button { display: grid; grid-template-columns: 2rem 1fr 2rem; align-items: center; width: 100%; margin: 0; color: var(--clr-text-primary); text-align: left; text-transform: none; } .security-product-links .trailing { color: var(--clr-text-tertiary); } @keyframes auth-toast-in { from { opacity: 0; transform: translate(-50%, 0.5rem); } to { opacity: 1; transform: translate(-50%, 0); } } /* Message center, quick navigation, and system notices. */ #sidepanel.message-center-panel { width: 24rem; min-width: 20rem; flex: 0 0 24rem; color-scheme: light; background: #fff; color: #242830; } #sidepanel.message-center-panel.full-page { width: 100%; min-width: 0; flex: 1 1 auto; } .message-center-panel * { box-sizing: border-box; letter-spacing: 0; } .messages-product-page, .message-actions-page, .system-messages-page { position: relative; display: flex; flex-direction: column; width: 100%; min-height: 100%; overflow: hidden; background: #fff; } .messages-home-header, .messages-sub-header { display: grid; position: relative; z-index: 5; grid-template-columns: 3.5rem 1fr 3.5rem; align-items: center; flex: none; min-height: 4.25rem; padding-top: env(safe-area-inset-top); border-bottom: 1px solid #f0f1f3; background: #fff; } .messages-home-header h1, .messages-sub-header h1 { grid-column: 2; margin: 0; overflow: hidden; color: #22262d; font-size: 1.25rem; font-weight: 600; text-align: center; text-overflow: ellipsis; white-space: nowrap; } .messages-menu-button, .messages-sub-header button { display: grid; place-items: center; width: 3.25rem; min-width: 3.25rem; height: 3.25rem; min-height: 3.25rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #272b32; background: transparent; } .messages-menu-button { grid-column: 3; } .messages-menu-button .material-icons { font-size: 1.75rem; } .messages-sub-header button .material-icons { font-size: 1.2rem; } .messages-connection { grid-column: 2; display: flex; align-items: center; justify-content: center; font-size: 1.2rem; font-weight: 600; } .messages-spinner { width: 1.25rem; height: 1.25rem; margin-right: 0.55rem; border: 3px dotted #aab0b8; border-radius: 50%; animation: messages-spin 850ms linear infinite; } @keyframes messages-spin { to { transform: rotate(360deg); } } .messages-home-content { width: 100%; min-height: 0; overflow-x: hidden; overflow-y: auto; flex: 1 1 auto; padding-bottom: 1rem; } .message-center-panel.full-page .messages-home-content, .message-center-panel.full-page .messages-home-header > * { --messages-content-width: 52rem; } .messages-search { display: flex; align-items: center; height: 2.8rem; margin: 0.75rem; border: 1px solid transparent; border-radius: 0.5rem; color: #a5abb4; background: #f1f2f4; } .message-center-panel.full-page .messages-search, .message-center-panel.full-page .messages-frequent, .message-center-panel.full-page .messages-conversations { width: min(calc(100% - 2rem), 52rem); margin-right: auto; margin-left: auto; } .messages-search:focus-within { border-color: #4091ff; box-shadow: 0 0 0 3px rgba(22,119,255,0.08); } .messages-search .material-icons { margin-left: 0.9rem; font-size: 1.35rem; } .messages-search input { min-width: 0; width: 100%; height: 2.7rem; margin: 0; padding: 0 0.85rem; border: 0; box-shadow: none; color: #252931; background: transparent; font-size: 0.95rem; } .messages-search input:focus { box-shadow: none; } .messages-search input::placeholder { color: #a5abb4; } .messages-frequent { padding: 0.3rem 0 0.8rem; } .messages-frequent h2 { margin: 0 0.75rem 0.65rem; color: #9399a2; font-size: 0.88rem; font-weight: 400; } .messages-frequent-scroll { display: flex; gap: 0.75rem; overflow-x: auto; padding: 0 0.75rem 0.3rem; scrollbar-width: none; } .messages-frequent-scroll::-webkit-scrollbar { display: none; } .messages-frequent-scroll button { display: flex; /* 3.75rem(50px) 装不下用户名这类较长的名字(实测 "kcg051307" 需要 52px),会被截成 "kcg0513...";参考图 docs/images/消息.png 里这一栏的名字是完整显示的。放宽到 4.4rem。 */ flex: 0 0 4.4rem; flex-direction: column; align-items: center; width: 4.4rem; min-width: 4.4rem; height: auto; min-height: 0; margin: 0; padding: 0; border: 0; box-shadow: none; color: #656b74; background: transparent; text-transform: none; } .messages-frequent-scroll button > span { width: 100%; margin-top: 0.4rem; overflow: hidden; font-size: 0.78rem; line-height: 1.3; text-overflow: ellipsis; white-space: nowrap; } .messages-conversations { display: flex; flex-direction: column; } .messages-conversation { display: grid; grid-template-columns: 3.4rem minmax(0, 1fr) auto; align-items: center; width: 100%; min-width: 0; min-height: 4.55rem; margin: 0; padding: 0.45rem 0.75rem; border: 0; border-radius: 0; border-bottom: 1px solid #f1f2f4; box-shadow: none; color: #252931; background: #fff; text-align: left; text-transform: none; } .messages-conversation:hover, .messages-conversation:focus { background: #f6f8fb; } .messages-conversation.pinned { background: #f4f6f8; } .messages-avatar { display: grid; position: relative; place-items: center; width: 3rem; height: 3rem; overflow: visible; border-radius: 0.55rem; color: #fff; background: #3c8df6; } .messages-avatar.small { width: 3.2rem; height: 3.2rem; border-radius: 0.65rem; } .messages-avatar.tone-orange { color: #ff951c; background: #fff5e5; } .messages-avatar.tone-green { color: #16ae54; background: #eefaf3; } .messages-avatar img { width: 100%; height: 100%; border-radius: inherit; object-fit: cover; } .messages-avatar > .material-icons { font-size: 1.8rem; } .messages-avatar .online, .messages-avatar .offline { position: absolute; right: -0.18rem; bottom: -0.12rem; width: 0.72rem; min-width: 0.72rem; height: 0.72rem; min-height: 0.72rem; border: 2px solid #fff; border-radius: 50%; background: #1fb36a; } .messages-avatar .offline { background: #aeb4bd; } .messages-conversation-copy { display: flex; min-width: 0; flex-direction: column; justify-content: center; padding: 0 0.55rem; } .messages-conversation-copy strong, .messages-conversation-copy small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .messages-conversation-copy strong { color: #272b31; font-size: 1rem; font-weight: 500; /* .messages-conversation is a , and the generic `button { line-height: 2.2rem }` rule (sized for a single line of button label) is inherited all the way down to this line -- with a ~1rem font that leaves a huge box of invisible padding above/below the actual glyphs, which reads as "too much gap in the middle, too little room overall" even though the real text is tiny. */ line-height: 1.3; } .messages-conversation-copy small { margin-top: 0.2rem; color: #969ca5; font-size: 0.84rem; font-weight: 400; line-height: 1.3; } .messages-conversation-meta { display: flex; align-self: stretch; min-width: 3.4rem; flex-direction: column; align-items: flex-end; justify-content: space-around; } .messages-conversation-meta time { color: #9ca2aa; font-size: 0.72rem; white-space: nowrap; } .messages-conversation-meta b { display: grid; place-items: center; min-width: 1.25rem; height: 1.25rem; padding: 0 0.3rem; border-radius: 0.7rem; color: #fff; background: #f34b46; font-size: 0.7rem; font-weight: 500; /* Same class of bug as .messages-conversation-copy strong/small just above: inherits the generic `button { line-height: 2.2rem }` rule from the enclosing row button, whose line box (~29px) is taller than this badge's own 1.25rem (20px) height, pushing the digit off-center inside the circle instead of the intended dead-center placement `place-items: center` implies. */ line-height: 1; } .messages-conversation-meta .material-icons { color: #a5abb3; font-size: 1.1rem; } .messages-empty { display: flex; flex-direction: column; align-items: center; padding: 4rem 1rem; color: #9ca2aa; } .messages-empty .material-icons { font-size: 2.4rem; } .messages-bottom-nav { display: grid; grid-template-columns: repeat(2, 1fr); flex: none; min-height: 4.8rem; padding-bottom: env(safe-area-inset-bottom); border-top: 1px solid #eceef1; background: #fff; } .messages-bottom-nav button { display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; height: 4.8rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #9ca2ab; background: transparent; text-transform: none; } .messages-bottom-nav button.active { color: #297fea; } .messages-bottom-nav .material-icons { font-size: 1.55rem; } .messages-bottom-nav span { margin-top: 0.25rem; font-size: 0.76rem; } .messages-menu-backdrop, .message-action-backdrop { position: absolute; inset: 0; z-index: 10; background: rgba(0,0,0,0.43); } .messages-quick-menu { position: absolute; top: calc(3.6rem + env(safe-area-inset-top)); right: 0.65rem; width: 12rem; overflow: hidden; border-radius: 0.4rem; background: #4b4c4f; box-shadow: 0 0.8rem 2rem rgba(0,0,0,0.24); } .messages-quick-menu::before { content: ''; position: absolute; top: -0.45rem; right: 1rem; width: 0.9rem; height: 0.9rem; background: #4b4c4f; transform: rotate(45deg); } .messages-quick-menu button { display: grid; position: relative; grid-template-columns: 2.2rem 1fr; align-items: center; width: 100%; min-height: 3.2rem; margin: 0; padding: 0 1rem; border: 0; border-radius: 0; box-shadow: none; color: #fff; background: transparent; text-align: left; text-transform: none; } .messages-quick-menu button:hover, .messages-quick-menu button:focus { background: rgba(255,255,255,0.09); } .messages-quick-menu .material-icons { font-size: 1.35rem; } .messages-quick-menu span { font-size: 0.98rem; } .messages-toast { position: fixed; z-index: 30; bottom: max(1.5rem, env(safe-area-inset-bottom)); left: 50%; max-width: calc(100% - 2rem); padding: 0.75rem 1.1rem; border-radius: 0.4rem; color: #fff; background: rgba(34,38,45,0.94); box-shadow: 0 0.5rem 1.5rem rgba(0,0,0,0.18); text-align: center; transform: translateX(-50%); } .message-actions-page { background: #e8eaee; } .message-actions-chat { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 1.5rem max(1rem, calc((100% - 50rem) / 2)); background: #edf0f3 url('../img/bkg/a00.png') repeat; } .message-time { margin: 0 0 1.5rem; color: #8d949d; font-size: 0.78rem; text-align: center; } .message-demo-row { display: flex; align-items: flex-start; gap: 0.65rem; margin-bottom: 1rem; } .message-demo-row.mine { justify-content: flex-end; } .message-demo-row .messages-avatar { width: 2.7rem; height: 2.7rem; flex: 0 0 2.7rem; } .message-demo-bubble { width: auto; max-width: min(72%, 28rem); min-height: 2.7rem; height: auto; margin: 0; padding: 0.75rem 0.9rem; border: 0; border-radius: 0.35rem; box-shadow: 0 1px 2px rgba(0,0,0,0.08); color: #252931; background: #fff; font-size: 0.95rem; font-weight: 400; line-height: 1.5; text-align: left; text-transform: none; } .message-demo-bubble.mine { background: #b9eb8f; } .message-operation-result { color: #777f89; font-size: 0.8rem; text-align: center; } .message-demo-composer { display: grid; grid-template-columns: 2.5rem minmax(0,1fr) 2.5rem 2.5rem; align-items: center; flex: none; min-height: 4rem; padding: 0.5rem max(0.75rem, calc((100% - 52rem) / 2)); background: #f7f8fa; } .message-demo-composer span { min-width: 0; height: 2.7rem; padding: 0 0.8rem; overflow: hidden; border-radius: 0.35rem; color: #a2a8b0; background: #fff; line-height: 2.7rem; white-space: nowrap; } .message-demo-composer .material-icons { color: #555c65; font-size: 1.45rem; text-align: center; } .message-action-backdrop { display: grid; place-items: center; } .message-action-menu { width: min(calc(100% - 3rem), 23rem); overflow: hidden; border-radius: 0.5rem; background: #4b4c4f; box-shadow: 0 1rem 3rem rgba(0,0,0,0.24); } .message-action-menu button { display: grid; grid-template-columns: 1fr 2rem; align-items: center; width: calc(100% - 2rem); min-height: 3.1rem; margin: 0 1rem; padding: 0; border: 0; border-radius: 0; border-bottom: 1px solid rgba(255,255,255,0.1); box-shadow: none; color: #fff; background: transparent; text-align: left; text-transform: none; } .message-action-menu button:last-child { border-bottom: 0; } .message-action-menu button:hover, .message-action-menu button:focus { background: rgba(255,255,255,0.08); } .message-action-menu span { font-size: 0.98rem; } .message-action-menu .material-icons { font-size: 1.3rem; } .system-messages-page { background: #f4f5f7; } .system-notification-list { width: 100%; max-width: 52rem; margin: 0 auto; overflow-y: auto; padding: 1.5rem; } .system-notification-list article { margin-bottom: 1.5rem; } .system-notification-list article > time { display: block; margin-bottom: 0.75rem; color: #a2a8b0; font-size: 0.82rem; text-align: center; } .system-notification-card { padding: 1.3rem; border: 1px solid #eceef1; border-radius: 0.5rem; background: #fff; box-shadow: 0 0.2rem 0.8rem rgba(37,49,65,0.04); } .system-notification-load-more { display: block; width: 100%; margin: 0; padding: 0.7rem; border: 1px solid #eceef1; border-radius: 0.5rem; box-shadow: none; color: #567; background: #fff; font-size: 0.85rem; text-transform: none; } .system-notification-list article.read .system-notification-card { opacity: 0.82; } .system-notification-card header { display: flex; align-items: center; justify-content: space-between; } .system-notification-card h2 { margin: 0; color: #20242b; font-size: 1.05rem; } .system-notification-card header > span { padding: 0.15rem 0.4rem; border-radius: 0.25rem; color: #fff; background: #f34b46; font-size: 0.7rem; } .system-notification-card p { margin: 0.85rem 0; color: #555c66; line-height: 1.55; } .system-notification-card dl { margin: 0; } .system-notification-card dl div { display: flex; margin: 0.35rem 0; } .system-notification-card dt { color: #242830; font-weight: 600; } .system-notification-card dd { margin: 0; color: #555c66; } .system-security-link { display: flex; align-items: center; width: auto; min-width: 0; height: auto; min-height: 0; margin: 0.6rem 0 0; padding: 0; border: 0; box-shadow: none; color: #1683f8; background: transparent; font-size: 0.9rem; text-transform: none; } .system-security-link .material-icons { font-size: 1.1rem; } .system-notification-card footer { margin-top: 1.1rem; color: #767e88; line-height: 1.6; } /* Direct-message relationship states and structured message cards. */ #sidepanel.direct-message-panel { width: 100%; min-width: 0; flex: 1 1 auto; color-scheme: light; background: #f4f6f8; color: #252931; } .direct-message-panel * { box-sizing: border-box; letter-spacing: 0; } .chat-product-page { display: flex; position: relative; flex-direction: column; width: 100%; min-height: 100%; overflow: hidden; background: #f4f6f8; } .chat-product-header { display: grid; position: relative; z-index: 4; grid-template-columns: 3.5rem minmax(0,1fr) 3.5rem; align-items: center; flex: none; min-height: 4.5rem; padding-top: env(safe-area-inset-top); border-bottom: 1px solid #eceef1; background: #fff; } .chat-product-header > button { display: grid; place-items: center; width: 3.25rem; min-width: 3.25rem; height: 3.25rem; min-height: 3.25rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #292d34; background: transparent; } .chat-product-header > button .material-icons { font-size: 1.25rem; } .chat-product-header > div { min-width: 0; text-align: center; } .chat-product-header h1 { margin: 0; overflow: hidden; color: #23272e; font-size: 1.2rem; text-overflow: ellipsis; white-space: nowrap; } .chat-product-header span { display: flex; align-items: center; justify-content: center; margin-top: 0.15rem; color: #7d848e; font-size: 0.78rem; } .chat-product-header span i { width: 0.55rem; height: 0.55rem; margin-right: 0.3rem; border-radius: 50%; background: #16bf78; } .chat-product-timeline { width: 100%; min-height: 0; overflow-x: hidden; overflow-y: auto; flex: 1 1 auto; padding: 1.5rem max(1rem, calc((100% - 54rem) / 2)); scroll-behavior: smooth; } .chat-time { margin: 0.3rem 0 1.4rem; color: #9299a2; font-size: 0.8rem; text-align: center; } .chat-message-row { display: flex; align-items: flex-start; gap: 0.65rem; margin: 0 0 1rem; } .chat-message-row.mine { justify-content: flex-end; } .chat-avatar { width: 2.8rem; height: 2.8rem; overflow: hidden; flex: 0 0 2.8rem; border-radius: 0.5rem; background: #dfe3e8; } .chat-avatar img { width: 100%; height: 100%; object-fit: cover; } .chat-message-stack { display: flex; min-width: 0; max-width: min(72%, 32rem); flex-direction: column; } .chat-message-row.mine .chat-message-stack { align-items: flex-end; } .chat-bubble { position: relative; min-width: 2.8rem; min-height: 2.8rem; padding: 0.72rem 0.9rem; border-radius: 0.45rem; color: #282c33; background: #fff; box-shadow: 0 1px 2px rgba(31,39,50,0.06); font-size: 0.98rem; line-height: 1.5; overflow-wrap: anywhere; } .chat-bubble::before { content: ''; position: absolute; top: 0.85rem; left: -0.35rem; width: 0.7rem; height: 0.7rem; background: inherit; transform: rotate(45deg); } .chat-bubble.mine { color: #fff; background: #398afa; } .chat-bubble.mine::before { right: -0.35rem; left: auto; } .chat-bubble.image, .chat-bubble.voice { padding: 0; background: transparent; box-shadow: none; } .chat-bubble.image::before, .chat-bubble.voice::before { display: none; } .chat-message-status { display: flex; align-items: center; justify-content: flex-end; min-height: 1.2rem; margin-top: 0.25rem; color: #8d949e; font-size: 0.72rem; } .chat-message-status.failed { color: #df3838; } .chat-message-status .material-icons { margin-right: 0.25rem; font-size: 1.15rem; } .chat-relation-notice { display: flex; align-items: center; justify-content: center; min-height: 1.8rem; margin: 0.4rem auto 1.5rem; color: #939aa3; font-size: 0.82rem; line-height: 1.5; text-align: center; } .chat-relation-notice button { width: auto; min-width: 0; height: auto; min-height: 0; margin: 0 0 0 0.5rem; padding: 0; border: 0; box-shadow: none; color: #2683f5; background: transparent; font-size: inherit; text-transform: none; } .chat-request-actions { display: flex; justify-content: center; gap: 0.75rem; margin: 2rem auto; } .chat-request-actions button { width: auto; min-width: 6rem; height: 2.7rem; min-height: 2.7rem; margin: 0; padding: 0 1.2rem; border: 1px solid #d9dde3; border-radius: 0.4rem; box-shadow: none; color: #5d646e; background: #fff; font-size: 0.9rem; text-transform: none; } .chat-request-actions button.primary { border-color: #398afa; color: #fff; background: #398afa; } .chat-image-message { position: relative; width: 10rem; aspect-ratio: 3 / 4; overflow: hidden; border-radius: 0.5rem; background: #e2e5e9; } .chat-image-message > img { width: 100%; height: 100%; object-fit: cover; } .chat-upload-progress { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; color: #fff; background: rgba(20,24,30,0.4); } .chat-upload-progress progress { width: 4rem; height: 0.35rem; border: 0; accent-color: #fff; } .chat-upload-progress strong { margin-top: 0.5rem; font-size: 0.85rem; } .chat-voice-message { display: grid; grid-template-columns: 1.5rem auto 2.2rem; align-items: center; min-width: 8rem; min-height: 3rem; padding: 0 0.85rem; border-radius: 0.45rem; color: #30343b; background: #fff; box-shadow: 0 1px 2px rgba(31,39,50,0.06); } .chat-message-row.mine .chat-voice-message { color: #fff; background: #398afa; } .chat-voice-message .material-icons { font-size: 1.3rem; } .chat-voice-message strong { font-size: 1rem; font-weight: 500; } .chat-voice-message span { height: 1rem; background: repeating-linear-gradient(90deg, currentColor 0 2px, transparent 2px 5px); opacity: 0.55; } .chat-file-card { display: grid; grid-template-columns: minmax(0,1fr) 3.4rem; gap: 1rem; width: min(100%, 24rem); min-width: 17rem; padding: 1rem; border-radius: 0.5rem; background: #fff; box-shadow: 0 1px 2px rgba(31,39,50,0.06); } .chat-file-card > div { display: flex; min-width: 0; flex-direction: column; } .chat-file-card strong { overflow: hidden; color: #30343b; line-height: 1.45; text-overflow: ellipsis; } .chat-file-card small { margin-top: auto; color: #a1a7af; } .chat-file-icon { display: grid; place-items: center; width: 3.4rem; height: 3.4rem; border-radius: 0.35rem; color: #fff; background: #f13e67; font-size: 2rem; font-weight: 600; } .chat-contact-card { display: flex; width: min(100%, 22rem); min-width: 16rem; height: auto; min-height: 0; margin: 0; padding: 0; overflow: hidden; flex-direction: column; border: 0; border-radius: 0.5rem; box-shadow: 0 1px 2px rgba(31,39,50,0.06); color: #30343b; background: #fff; text-align: left; text-transform: none; } .chat-contact-card > span { display: flex; align-items: center; width: 100%; padding: 0.85rem; } .chat-contact-card img { width: 3rem; height: 3rem; margin-right: 0.75rem; border-radius: 0.45rem; object-fit: cover; } .chat-contact-card strong { overflow: hidden; font-size: 1rem; text-overflow: ellipsis; white-space: nowrap; } .chat-contact-card small { width: calc(100% - 1.7rem); margin: 0 0.85rem; padding: 0.65rem 0; border-top: 1px solid #eceef1; color: #9da3ac; } .chat-permission-banner { display: flex; align-items: center; justify-content: center; flex: none; min-height: 2.5rem; padding: 0.55rem 1rem; color: #7e858e; background: #fff7e8; font-size: 0.82rem; text-align: center; } .chat-permission-banner .material-icons { margin-right: 0.4rem; color: #dc9221; font-size: 1.05rem; } .chat-composer { display: grid; grid-template-columns: 2.7rem minmax(0,1fr) 2.7rem auto; align-items: center; flex: none; min-height: 4.2rem; padding: 0.55rem max(0.75rem, calc((100% - 54rem) / 2)); border-top: 1px solid #e8eaee; background: #f8f9fa; } .chat-composer > button { display: grid; place-items: center; width: 2.5rem; min-width: 2.5rem; height: 2.5rem; min-height: 2.5rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #555c65; background: transparent; } .chat-composer > button[disabled] { color: #b7bcc3; } .chat-composer > button .material-icons { font-size: 1.45rem; } .chat-composer input { min-width: 0; width: 100%; height: 2.8rem; margin: 0; padding: 0 0.8rem; border: 1px solid #eceef1; border-radius: 0.4rem; box-shadow: none; color: #252931; background: #fff; font-size: 0.93rem; } .chat-composer input:focus { border-color: #4091ff; box-shadow: 0 0 0 3px rgba(22,119,255,0.08); } .chat-composer input[disabled] { color: #9da3ab; background: #f1f2f4; } .chat-composer .chat-send-button { width: auto; min-width: 3.8rem; margin-left: 0.25rem; padding: 0 0.75rem; border-radius: 0.35rem; color: #fff; background: #398afa; font-size: 0.82rem; text-transform: none; } .chat-attachment-panel { display: grid; grid-template-columns: repeat(4, minmax(4rem, 1fr)); gap: 1rem; flex: none; min-height: 13rem; padding: 1rem max(1rem, calc((100% - 48rem) / 2)) max(1rem, env(safe-area-inset-bottom)); border-top: 1px solid #e3e6ea; background: #f1f2f4; } .chat-attachment-panel button { display: flex; flex-direction: column; align-items: center; justify-content: flex-start; width: 100%; height: auto; min-height: 5.2rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #6d747e; background: transparent; text-transform: none; } .chat-attachment-panel button > span { display: grid; place-items: center; width: 3.8rem; height: 3.8rem; border-radius: 0.5rem; color: #4d535b; background: #fff; } .chat-attachment-panel .material-icons { font-size: 1.55rem; } .chat-attachment-panel small { margin-top: 0.45rem; font-size: 0.78rem; } .chat-toast { position: fixed; z-index: 30; bottom: max(1.5rem, env(safe-area-inset-bottom)); left: 50%; max-width: calc(100% - 2rem); padding: 0.75rem 1.1rem; border-radius: 0.4rem; color: #fff; background: rgba(34,38,45,0.94); box-shadow: 0 0.5rem 1.5rem rgba(0,0,0,0.18); text-align: center; transform: translateX(-50%); } /* Message composer, media tasks, selection, favorites, and forwarding. */ #sidepanel.message-composer-panel { width: 100%; min-width: 0; flex: 1 1 auto; color-scheme: light; color: #252931; background: #f4f6f8; } .message-composer-panel * { box-sizing: border-box; letter-spacing: 0; } .message-composer-page .chat-product-header span { margin-top: 0.1rem; } .compose-timeline { padding-bottom: 2rem; } .compose-avatar { display: grid; place-items: center; width: 2.7rem; height: 2.7rem; overflow: hidden; flex: 0 0 2.7rem; border-radius: 0.45rem; color: #fff; background: #4789dc; } .compose-avatar img { width: 100%; height: 100%; object-fit: cover; } .compose-avatar .material-icons { font-size: 1.35rem; } .compose-message-row { display: flex; align-items: flex-start; gap: 0.65rem; width: 100%; margin-bottom: 1rem; } .compose-message-row.mine { justify-content: flex-end; } .compose-text-bubble { position: relative; max-width: min(70%, 32rem); min-height: 2.7rem; padding: 0.7rem 0.9rem; border-radius: 0.45rem; background: #fff; box-shadow: 0 1px 2px rgba(31,39,50,0.06); line-height: 1.5; overflow-wrap: anywhere; } .compose-text-bubble.mine { color: #fff; background: #398afa; } .compose-mention { color: #1976d2; font-weight: 500; } .compose-voice-bubble { display: grid; grid-template-columns: 1.5rem minmax(3rem, 8rem) auto; align-items: center; gap: 0.4rem; width: auto; min-width: 10rem; height: 3rem; min-height: 3rem; margin: 0; padding: 0 0.85rem; border: 0; border-radius: 0.45rem; box-shadow: 0 1px 2px rgba(31,39,50,0.06); color: #30343b; background: #fff; } .compose-voice-bubble.mine { color: #fff; background: #398afa; } .compose-voice-bubble > i:last-child { position: absolute; width: 0.45rem; height: 0.45rem; margin-left: 10.3rem; border-radius: 50%; background: #ef3f4d; } .compose-wave { height: 1rem; opacity: 0.55; background: repeating-linear-gradient(90deg, currentColor 0 2px, transparent 2px 5px); } .compose-media-card, .compose-video-card { position: relative; width: 11rem; aspect-ratio: 4 / 3; overflow: hidden; border: 0; border-radius: 0.45rem; background: #dfe3e8; } .compose-video-card { height: auto; min-height: 0; margin: 0; padding: 0; box-shadow: none; } .compose-media-card > img, .compose-video-card > img { width: 100%; height: 100%; object-fit: cover; } .compose-video-card > .material-icons { position: absolute; top: 50%; left: 50%; color: #fff; font-size: 2.8rem; filter: drop-shadow(0 2px 5px rgba(0,0,0,0.3)); transform: translate(-50%, -50%); } .compose-video-card > small { position: absolute; right: 0.45rem; bottom: 0.35rem; padding: 0.1rem 0.3rem; border-radius: 0.2rem; color: #fff; background: rgba(0,0,0,0.55); } .compose-media-state { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; flex-direction: column; color: #fff; background: rgba(25,29,35,0.52); } .compose-media-state .material-icons { font-size: 1.7rem; } .compose-media-state strong { margin: 0.3rem 0; font-size: 0.75rem; } .compose-media-state progress { width: 5rem; height: 0.3rem; accent-color: #fff; } .compose-file-card { display: grid; grid-template-columns: 3rem minmax(0, 1fr) 1.7rem; align-items: center; gap: 0.8rem; width: min(25rem, calc(100vw - 8rem)); min-height: 5rem; padding: 0.8rem; border-radius: 0.45rem; background: #fff; box-shadow: 0 1px 2px rgba(31,39,50,0.06); } .compose-file-type { display: grid; place-items: center; width: 3rem; height: 3.4rem; border-radius: 0.3rem; color: #fff; background: #e74664; font-size: 0.72rem; font-weight: 700; } .compose-file-card > div, .compose-upload-list > div > div { display: flex; min-width: 0; flex-direction: column; } .compose-file-card strong, .compose-upload-list strong { overflow: hidden; color: #30343b; text-overflow: ellipsis; white-space: nowrap; } .compose-file-card small, .compose-upload-list small { margin-top: 0.35rem; color: #9097a0; } .compose-file-card progress, .compose-upload-list progress { width: 100%; height: 0.3rem; margin-top: 0.35rem; accent-color: #398afa; } .compose-toolbar { display: grid; grid-template-columns: 2.8rem minmax(0, 1fr) 2.8rem auto; align-items: center; min-height: 4.2rem; padding: 0.55rem max(0.6rem, calc((100% - 54rem) / 2)); border-top: 1px solid #e4e7eb; background: #f8f9fa; } .compose-toolbar > button { display: grid; place-items: center; width: 2.6rem; min-width: 2.6rem; height: 2.6rem; min-height: 2.6rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #555c65; background: transparent; } .compose-toolbar input { width: 100%; min-width: 0; height: 2.8rem; margin: 0; padding: 0 0.8rem; border: 1px solid #e4e7eb; border-radius: 0.35rem; box-shadow: none; color: #252931; background: #fff; } .compose-toolbar .compose-send, .compose-upload-page footer button, .compose-target-footer button, .compose-confirm-send { width: auto; min-width: 3.8rem; padding: 0 0.85rem; border: 0; border-radius: 0.35rem; color: #fff; background: #398afa; text-transform: none; } .compose-toolbar .compose-hold-button { width: 100%; color: #30343b; border: 1px solid #e1e4e8; background: #fff; font-size: 0.92rem; } .compose-emoji-panel { position: relative; flex: none; min-height: 14rem; padding: 0 1rem max(1rem, env(safe-area-inset-bottom)); border-top: 1px solid #e2e5e9; background: #f4f5f7; } .compose-emoji-panel nav { display: flex; gap: 0.25rem; height: 3rem; border-bottom: 1px solid #e1e4e8; } .compose-emoji-panel nav button, .compose-emoji-delete { width: 3rem; min-width: 3rem; height: 3rem; min-height: 3rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #7d848d; background: transparent; } .compose-emoji-panel nav button.active { color: #398afa; border-bottom: 2px solid #398afa; } .compose-emoji-panel > div { display: grid; grid-template-columns: repeat(9, minmax(2.5rem, 1fr)); gap: 0.35rem; max-width: 52rem; padding: 0.8rem 0; margin: auto; } .compose-emoji-panel > div button { display: grid; place-items: center; width: 100%; min-width: 2.5rem; height: 2.5rem; min-height: 2.5rem; margin: 0; padding: 0; border: 0; box-shadow: none; background: transparent; font-size: 1.4rem; } .compose-emoji-delete { position: absolute; right: 1rem; bottom: max(0.5rem, env(safe-area-inset-bottom)); border-radius: 0.3rem; background: #fff; } .compose-record-overlay { position: fixed; z-index: 20; top: 50%; left: 50%; display: flex; align-items: center; justify-content: center; width: 12rem; min-height: 11rem; padding: 1.2rem; border-radius: 0.5rem; color: #fff; background: rgba(34,39,47,0.9); box-shadow: 0 1rem 3rem rgba(0,0,0,0.24); flex-direction: column; transform: translate(-50%, -50%); } .compose-record-overlay.cancel { background: rgba(204,55,62,0.94); } .compose-record-overlay > .material-icons { font-size: 3rem; } .compose-record-overlay strong { margin-top: 0.65rem; font-size: 0.8rem; } .compose-record-overlay small { margin-top: 0.35rem; opacity: 0.8; } .compose-meter { display: flex; align-items: center; gap: 0.18rem; height: 1.8rem; margin-top: 0.4rem; } .compose-meter i { width: 0.18rem; border-radius: 0.1rem; background: #fff; } .compose-picker-page, .compose-forward-page, .compose-upload-page { display: flex; width: 100%; min-height: 100%; flex-direction: column; color: #252931; background: #f6f7f9; } .compose-picker-header { display: grid; grid-template-columns: 4.5rem minmax(0, 1fr) 4.5rem; align-items: center; min-height: 4.5rem; padding-top: env(safe-area-inset-top); border-bottom: 1px solid #ebedf0; background: #fff; } .compose-picker-header h1 { margin: 0; font-size: 1.12rem; text-align: center; } .compose-picker-header button { width: 100%; min-width: 0; height: 3.2rem; min-height: 3.2rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #30343b; background: transparent; } .compose-picker-header button.text { color: #287fe5; font-size: 0.88rem; text-transform: none; } .compose-picker-header button[disabled] { color: #b4bac1; } .compose-search { display: flex; align-items: center; height: 2.8rem; margin: 0.8rem max(1rem, calc((100% - 48rem) / 2)); padding: 0 0.75rem; border-radius: 0.35rem; color: #949ba4; background: #fff; } .compose-search .material-icons { font-size: 1.25rem; } .compose-search input { width: 100%; min-width: 0; height: 100%; margin: 0; padding: 0 0.55rem; border: 0; box-shadow: none; background: transparent; } .compose-section-title { width: min(100%, 48rem); margin: 0 auto; padding: 0.5rem 1rem; color: #8d949d; font-size: 0.78rem; } .compose-picker-list { width: min(100%, 48rem); margin: 0 auto; background: #fff; } .compose-picker-list > button { display: grid; grid-template-columns: 3rem minmax(0, 1fr) 2rem; align-items: center; gap: 0.75rem; width: 100%; min-width: 0; min-height: 4.4rem; margin: 0; padding: 0.55rem 1rem; border: 0; border-bottom: 1px solid #eef0f2; border-radius: 0; box-shadow: none; color: #252931; background: #fff; text-align: left; text-transform: none; } .compose-picker-list > button > span:nth-child(2) { display: flex; min-width: 0; flex-direction: column; } .compose-picker-list strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .compose-picker-list small { margin-top: 0.2rem; color: #969da6; font-size: 0.76rem; } .compose-checkbox, .compose-check { display: grid; place-items: center; width: 1.4rem; height: 1.4rem; border: 1px solid #c9ced4; border-radius: 50%; color: #fff; background: #fff; } .compose-checkbox.checked, .compose-check.checked { border-color: #398afa; background: #398afa; } .compose-checkbox .material-icons, .compose-check .material-icons { font-size: 0.95rem; } .compose-select-row { display: flex; align-items: flex-start; width: 100%; } .compose-select-row.selectable { gap: 0.7rem; } .compose-select-row.selectable .compose-message-row { width: calc(100% - 2.2rem); } .compose-check { flex: 0 0 1.4rem; min-width: 1.4rem; min-height: 1.4rem; margin: 0.65rem 0 0; padding: 0; box-shadow: none; } .compose-selection-bar { display: grid; grid-template-columns: 4rem 1fr 5rem; align-items: center; min-height: 3.2rem; border-bottom: 1px solid #e6e9ed; background: #fff; text-align: center; } .compose-selection-bar button { width: 100%; min-width: 0; min-height: 2.8rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #398afa; background: transparent; font-size: 0.78rem; text-transform: none; } .compose-batch-actions { display: grid; grid-template-columns: repeat(3, 1fr); flex: none; min-height: 4.6rem; padding-bottom: env(safe-area-inset-bottom); border-top: 1px solid #e3e6ea; background: #fff; } .compose-batch-actions button { display: flex; align-items: center; justify-content: center; width: 100%; min-width: 0; min-height: 4.2rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #515862; background: transparent; flex-direction: column; text-transform: none; } .compose-batch-actions button[disabled] { color: #b8bdc4; } .compose-batch-actions span { margin-top: 0.25rem; font-size: 0.72rem; } .compose-upload-page > main { width: min(100%, 48rem); min-height: 0; margin: 0 auto; padding: 1.2rem; overflow-y: auto; flex: 1 1 auto; } .compose-upload-drop { display: flex; align-items: center; justify-content: center; min-height: 11rem; border: 1px dashed #b9c4d1; border-radius: 0.45rem; color: #4f5863; background: #fff; cursor: pointer; flex-direction: column; } .compose-upload-drop input { position: absolute; width: 1px; height: 1px; opacity: 0; } .compose-upload-drop .material-icons { margin-bottom: 0.5rem; color: #398afa; font-size: 2.6rem; } .compose-upload-drop small { margin-top: 0.35rem; color: #9299a2; } .compose-upload-list h2, .compose-forward-confirm h2 { margin: 1.4rem 0 0.7rem; font-size: 0.92rem; } .compose-upload-list > div { display: grid; grid-template-columns: 3rem minmax(0, 1fr) 2rem; align-items: center; gap: 0.8rem; padding: 0.8rem; border-bottom: 1px solid #eceef1; background: #fff; } .compose-upload-list button { width: 2rem; min-width: 2rem; height: 2rem; min-height: 2rem; margin: 0; padding: 0; border: 0; box-shadow: none; background: transparent; } .compose-upload-page > footer, .compose-target-footer { display: flex; align-items: center; justify-content: flex-end; min-height: 4.5rem; padding: 0.6rem max(1rem, calc((100% - 48rem) / 2)); border-top: 1px solid #e3e6ea; background: #fff; } .compose-upload-page footer button, .compose-target-footer button { height: 2.8rem; min-height: 2.8rem; margin: 0; } /* Contact relationships and group governance. */ #sidepanel.contact-management-panel, #sidepanel.group-management-panel { width: 100%; min-width: 0; flex: 1 1 auto; color-scheme: light; color: #252931; background: #f5f6f8; } .contact-management-panel *, .group-management-panel * { box-sizing: border-box; letter-spacing: 0; } .people-page, .group-page { display: flex; position: relative; width: 100%; min-height: 100%; overflow: hidden; flex-direction: column; background: #f5f6f8; } .people-header, .group-header, .group-chat-header { display: grid; z-index: 3; grid-template-columns: 4.5rem minmax(0, 1fr) 4.5rem; align-items: center; flex: none; min-height: 4.5rem; padding-top: env(safe-area-inset-top); border-bottom: 1px solid #e9ebee; background: #fff; } .people-header h1, .group-header h1, .group-chat-header h1 { margin: 0; overflow: hidden; font-size: 1.15rem; text-align: center; text-overflow: ellipsis; white-space: nowrap; } .people-header > button, .group-header > button, .group-chat-header > button { display: grid; place-items: center; width: 100%; min-width: 0; height: 3.2rem; min-height: 3.2rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #2e333a; background: transparent; } .people-header > button.text, .group-header > button.text { color: #247ee6; font-size: 0.86rem; text-transform: none; } .people-search, .group-search { display: flex; align-items: center; flex: none; height: 2.8rem; margin: 0.8rem max(1rem, calc((100% - 50rem) / 2)); padding: 0 0.75rem; border-radius: 0.35rem; color: #9299a2; background: #fff; } .people-search .material-icons, .group-search .material-icons { font-size: 1.2rem; } .people-search input, .group-search input { width: 100%; min-width: 0; height: 100%; margin: 0; padding: 0 0.5rem; border: 0; box-shadow: none; background: transparent; } .people-avatar, .group-avatar { display: grid; /* place-items 只在 grid 下同时管住两个方向;一旦外层规则把它改成 flex,就只剩交叉轴生效。 补上 justify/align-content,让这里在 grid 和 flex 两种情况下都保持居中。 */ place-items: center; align-content: center; justify-content: center; width: 3rem; height: 3rem; overflow: hidden; flex: 0 0 3rem; border-radius: 0.45rem; color: #fff; background: #4389df; } .people-avatar img, .group-avatar img { width: 100%; height: 100%; object-fit: cover; } .people-avatar .material-icons, .group-avatar .material-icons { font-size: 1.45rem; } .people-scroll, .people-page > main, .group-page > main { min-height: 0; overflow-y: auto; flex: 1 1 auto; } .people-entry-list, .people-group, .people-add-actions, .people-settings > section, .group-settings > section, .group-governance > section { width: min(100%, 50rem); margin: 0 auto 0.8rem; background: #fff; } .people-entry-list > button { display: grid; grid-template-columns: 3rem minmax(0, 1fr) auto 1.5rem; align-items: center; gap: 0.75rem; width: 100%; min-height: 4.3rem; margin: 0; padding: 0.55rem 1rem; border: 0; border-bottom: 1px solid #eef0f2; border-radius: 0; box-shadow: none; color: #2d3239; background: #fff; text-align: left; text-transform: none; } /* The 4th column is reserved for the trailing chevron, but the badge before it only renders when item.badge is truthy (most of these rows never have one) -- grid auto-placement fills columns left-to-right in DOM order regardless, so with no badge the chevron auto-lands in column 3 instead of 4, leaving column 4 empty and the icon sitting well short of the row's right edge. Pinned to column 4 explicitly so its position doesn't depend on how many siblings happened to render before it. */ .people-entry-list > button > .material-icons:last-child { grid-column: 4; } .people-entry-list em { display: grid; place-items: center; min-width: 1.2rem; height: 1.2rem; padding: 0 0.35rem; border-radius: 0.6rem; color: #fff; background: #ef4653; font-size: 0.7rem; font-style: normal; } .people-group h2 { margin: 0; padding: 0.45rem 1rem; color: #868d97; background: #f5f6f8; font-size: 0.78rem; } .people-group > button { display: flex; align-items: center; gap: 0.8rem; width: 100%; min-height: 4.2rem; margin: 0; padding: 0.55rem 1rem; border: 0; border-bottom: 1px solid #eef0f2; border-radius: 0; box-shadow: none; color: #2d3239; background: #fff; text-align: left; text-transform: none; } /* Each of these rows renders an Avatar (also a bare ``, `.people-avatar`/`.group-avatar`) followed by this text column, both direct children of the same `button`/`article` -- a selector scoped only by tag+ancestor (no `:nth-child`) matches the avatar too, and since it comes first in source order and ties this rule's specificity, it wins and overrides the avatar's own real `flex: 0 0 ` with `flex: 1 1 auto`. The avatar was rendered as a plain flex item with no basis to hold onto, so it grew to fill the row instead of staying a fixed-size square -- the "stretched-into-a-bar" avatar. `.people-add-actions button > span` and the two `> div` selectors are naturally exempt (their first child is an /, not a same-tag sibling), which is why only some rows in this shared rule needed `:nth-child(2)` and others didn't. */ .people-group > button > span:nth-child(2), .people-request-list article > div, .people-block-list article > span:nth-child(2), .people-search-result button > span:nth-child(2), .people-add-actions button > span, .group-list button > span:nth-child(2), .group-request-list article > div, .group-admin-page article > span:nth-child(2), .group-muted-list article > span:nth-child(2), .group-member-picker > button > span:nth-child(2) { display: flex; min-width: 0; flex-direction: column; flex: 1 1 auto; } /* Same class of bug as .messages-conversation-copy (base.css, message list rows): these rows are all elements, and neither `strong` nor `small` here override the generic `button { line-height: 2.2rem }` -- meaning a ~0.75-1rem line of text sits in a ~35px-tall box, reading as "way too much gap between the title and subtitle" even though the actual margin-top below is tiny. */ .people-group strong, .people-request-list strong, .people-block-list strong, .people-search-result strong, .people-add-actions strong, .group-list strong, .group-request-list strong, .group-admin-page strong, .group-muted-list strong, .group-member-picker strong { line-height: 1.3; } .people-group small, .people-request-list small, .people-block-list small, .people-search-result small, .people-add-actions small, .group-list small, .group-request-list small, .group-admin-page small, .group-muted-list small, .group-member-picker small { margin-top: 0.2rem; color: #9299a2; font-size: 0.75rem; line-height: 1.3; } .people-index { position: absolute; z-index: 2; top: 13rem; right: 0.35rem; display: flex; gap: 0.2rem; flex-direction: column; } .people-index a { color: #6a727d; font-size: 0.68rem; text-decoration: none; } .people-request-list, .people-block-list, .group-request-list, .group-muted-list, .group-admin-page { width: min(100%, 50rem); margin: 0 auto; background: #fff; } .people-request-list article, .people-block-list article, .group-request-list article, .group-admin-page article, .group-muted-list article { display: flex; align-items: center; gap: 0.75rem; min-height: 5.2rem; padding: 0.7rem 1rem; border-bottom: 1px solid #eceef1; } .people-request-list p, .group-request-list p { max-width: 24rem; margin: 0.2rem 0; overflow: hidden; color: #69717b; font-size: 0.8rem; text-overflow: ellipsis; white-space: nowrap; } .people-request-list article > span, .group-request-list article > span { display: flex; gap: 0.4rem; } .people-request-list button, .people-block-list button, .group-request-list button, .group-admin-page article button, .group-muted-list button { width: auto; min-width: 3.3rem; height: 2.1rem; min-height: 2.1rem; margin: 0; padding: 0 0.65rem; border: 1px solid #d8dce1; border-radius: 0.3rem; box-shadow: none; color: #69717b; background: #fff; font-size: 0.76rem; text-transform: none; } .people-request-list button.primary, .group-request-list button.primary { border-color: #398afa; color: #fff; background: #398afa; } .people-request-list em, .group-request-list em { color: #969da5; font-size: 0.78rem; font-style: normal; } .people-add-actions { margin-top: 0.5rem; } .people-add-actions button { display: grid; grid-template-columns: 2.7rem minmax(0, 1fr) 1.5rem; align-items: center; gap: 0.7rem; width: 100%; min-height: 4.4rem; margin: 0; padding: 0.65rem 1rem; border: 0; border-bottom: 1px solid #eceef1; border-radius: 0; box-shadow: none; color: #2d3239; background: #fff; text-align: left; text-transform: none; } .people-add-actions button > .material-icons:first-child { color: #398afa; font-size: 1.7rem; } .people-my-account { color: #9299a2; font-size: 0.8rem; text-align: center; } .people-search-result { width: min(100%, 50rem); margin: 0 auto; } .people-search-result h2 { padding: 0 1rem; color: #8b929b; font-size: 0.78rem; } .people-search-result button { display: flex; align-items: center; gap: 0.8rem; width: 100%; min-height: 4.7rem; margin: 0; padding: 0.7rem 1rem; border: 0; box-shadow: none; color: #2d3239; background: #fff; text-align: left; text-transform: none; } .people-qr-page main, .group-qr-page main { display: flex; align-items: center; justify-content: center; padding: 2rem 1rem; flex-direction: column; } .people-qr-card, .group-qr-card { width: min(100%, 23rem); padding: 1.4rem; border-radius: 0.45rem; background: #fff; box-shadow: 0 0.8rem 2.2rem rgba(35,43,54,0.1); text-align: center; } .people-qr-profile, .group-qr-card > div:first-child { display: flex; align-items: center; gap: 0.75rem; text-align: left; } .people-qr-profile > span:nth-child(2), .group-qr-card > div:first-child > span:nth-child(2) { display: flex; flex-direction: column; } .people-qr-profile small, .group-qr-card small { margin-top: 0.2rem; color: #8f969f; } .people-qrcode, .group-qrcode { width: 190px; height: 190px; margin: 1.5rem auto 1rem; } .people-qrcode img, .group-qrcode img { width: 100%; height: 100%; } .people-qr-card p, .group-qr-card p { margin: 0.6rem 0 0; } .people-qr-actions, .group-qr-actions { display: flex; gap: 1rem; margin-top: 1.5rem; } .people-qr-actions button, .group-qr-actions button { display: flex; align-items: center; justify-content: center; width: 8.5rem; min-width: 0; min-height: 2.8rem; margin: 0; border: 0; border-radius: 0.35rem; box-shadow: none; color: #3b424b; background: #fff; text-transform: none; } .people-qr-actions .material-icons, .group-qr-actions .material-icons { margin-right: 0.4rem; font-size: 1.2rem; } .people-verify, .people-profile { width: min(100%, 42rem); margin: 0 auto; padding: 2rem 1rem; text-align: center; } .people-verify > .people-avatar { width: 4.5rem; height: 4.5rem; margin: 0 auto; } .people-verify h2 { margin: 0.8rem 0 1.8rem; } .people-verify label { display: flex; padding: 1rem; background: #fff; text-align: left; flex-direction: column; } .people-verify textarea { min-height: 7rem; margin: 0.7rem 0; padding: 0.7rem; border: 1px solid #e3e6ea; border-radius: 0.35rem; box-shadow: none; resize: vertical; } .people-verify label small { color: #989fa7; text-align: right; } .people-verify-actions { display: flex; gap: 0.6rem; margin-top: 1.2rem; } .people-verify-actions button { flex: 1; min-height: 3rem; border: 0; border-radius: 0.35rem; box-shadow: none; background: var(--clr-background-blue-gray-50); text-transform: none; } .people-verify-actions .people-primary { margin: 0; } .people-section-title { margin: 0.6rem 1rem 0; color: var(--clr-text-secondary); font-size: 0.85rem; font-weight: normal; } .people-empty-hint { padding: 1.5rem 1rem; text-align: center; color: var(--clr-text-secondary); } .people-remark-edit { display: flex; gap: 0.5rem; padding: 0.6rem 1rem; } .people-remark-edit input { flex: 1; border: 1px solid #e3e6ea; border-radius: 0.35rem; padding: 0.4rem 0.6rem; } .people-profile dd.muted { color: var(--clr-text-secondary); } .people-search-result em { flex: none; padding: 0.35rem 0.9rem; border-radius: 1rem; font-style: normal; font-size: 0.85rem; color: var(--clr-text-secondary); background: var(--clr-background-blue-gray-50); } .people-search-result em.people-add-cta { color: var(--clr-primary-accent); } .people-primary { display: flex; align-items: center; justify-content: center; width: 100%; min-height: 3rem; margin: 1.2rem 0 0; border: 0; border-radius: 0.35rem; box-shadow: none; color: #fff; background: #398afa; text-transform: none; } .people-primary .material-icons { margin-right: 0.4rem; } .people-profile > section:first-child { display: grid; grid-template-columns: 4.5rem minmax(0, 1fr) 2rem; align-items: center; gap: 1rem; padding: 1.2rem; background: #fff; text-align: left; } .people-profile > section:first-child .people-avatar { width: 4.5rem; height: 4.5rem; } .people-profile h2, .people-profile p { margin: 0.2rem 0; } .people-profile p { color: #858c95; font-size: 0.82rem; } .people-profile dl { margin: 0.8rem 0; padding: 0 1rem; background: #fff; text-align: left; } .people-profile dl > div { display: grid; grid-template-columns: 6rem 1fr; padding: 0.9rem 0; border-bottom: 1px solid #eef0f2; } .people-profile dt, .people-profile dd { margin: 0; } .people-profile dd { color: #707883; } .people-profile-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 0.8rem; } .people-profile-actions button { min-height: 3rem; margin: 0; border: 1px solid #dce0e5; border-radius: 0.35rem; box-shadow: none; color: #398afa; background: #fff; text-transform: none; } .people-profile-actions button.people-primary { border-color: #398afa; color: #fff; background: #398afa; } .people-settings, .group-settings, .group-governance { padding: 0.8rem 0 2rem; } .people-settings-profile { display: flex; align-items: center; gap: 0.8rem; padding: 0.8rem 1rem; } .people-settings section > button, .people-settings section > div, .group-settings section > button, .group-settings section > div, .group-governance section > button, .group-governance section > div, .group-profile > button, .group-profile > label, .people-profile-qr-row { display: flex; align-items: center; width: 100%; min-height: 3.7rem; margin: 0; padding: 0.65rem 1rem; border: 0; border-bottom: 1px solid #eceef1; border-radius: 0; box-shadow: none; color: #30353c; background: #fff; text-align: left; text-transform: none; } .people-settings section > button > span, .people-settings section > div > span, .group-settings section > button > span, .group-settings section > div > span, .group-governance section > button > span { flex: 1 1 auto; } .people-settings section small, .group-settings section small { min-width: 0; margin-left: auto; overflow: hidden; color: #949ba4; text-overflow: ellipsis; white-space: nowrap; } .people-switch, .group-switch { position: relative; width: 2.8rem; min-width: 2.8rem; height: 1.55rem; min-height: 1.55rem; margin: 0; padding: 0; border: 0; border-radius: 0.8rem; box-shadow: none; background: #c7ccd2; } .people-switch i, .group-switch i { position: absolute; top: 0.15rem; left: 0.15rem; width: 1.25rem; height: 1.25rem; border-radius: 50%; background: #fff; transition: transform 0.18s ease; } .people-switch.checked, .group-switch.checked { background: #398afa; } .people-switch.checked i, .group-switch.checked i { transform: translateX(1.25rem); } .people-danger, .group-danger { display: block; width: min(calc(100% - 2rem), 48rem); min-height: 3rem; margin: 1rem auto; border: 0; border-radius: 0.35rem; box-shadow: none; color: #df3f48; background: #fff; text-transform: none; } .people-empty, .group-empty { display: flex; align-items: center; justify-content: center; min-height: 23rem; color: #8d949d; flex-direction: column; text-align: center; } .people-empty .material-icons, .group-empty > .material-icons { margin-bottom: 0.8rem; color: #b3bac2; font-size: 4rem; } .people-sheet-backdrop, .group-sheet-backdrop, .group-modal-backdrop { position: absolute; z-index: 20; inset: 0; display: flex; align-items: flex-end; justify-content: center; background: rgba(28,33,40,0.44); } .people-confirm-sheet, .group-source-sheet, .group-confirm-sheet { width: min(100%, 36rem); padding: 1.2rem; border-radius: 0.5rem 0.5rem 0 0; background: #fff; text-align: center; } .people-confirm-sheet > i { display: block; width: 2.5rem; height: 0.25rem; margin: 0 auto 1rem; border-radius: 0.2rem; background: #d6dae0; } .people-confirm-sheet h2, .group-source-sheet h2, .group-confirm-sheet h2 { margin: 0.2rem 0 0.8rem; font-size: 1.08rem; } .people-confirm-sheet p, .group-confirm-sheet p { color: #757d87; line-height: 1.6; } .group-password-input { width: 100%; height: 2.75rem; margin-top: 0.6rem; padding: 0 0.9rem; border: 1px solid #dde1e6; border-radius: 0.35rem; font-size: 1rem; text-align: left; } .people-confirm-sheet button, .group-source-sheet button, .group-confirm-sheet button { width: 100%; min-height: 3rem; margin: 0.45rem 0 0; border: 0; border-radius: 0.35rem; box-shadow: none; color: #31363d; background: #f2f3f5; text-transform: none; } .people-confirm-sheet button.danger, .group-confirm-sheet button.danger { color: #fff; background: #e3444d; } .group-source-sheet button { display: flex; align-items: center; justify-content: center; } .group-source-sheet button .material-icons { margin-right: 0.5rem; } .group-tabs { display: grid; grid-template-columns: repeat(3, 1fr); width: min(100%, 50rem); margin: 0 auto; border-bottom: 1px solid #e4e7eb; background: #fff; } .group-tabs button { min-height: 2.8rem; margin: 0; padding: 0; border: 0; border-bottom: 2px solid transparent; border-radius: 0; box-shadow: none; color: #747c86; background: transparent; font-size: 0.8rem; text-transform: none; } .group-tabs button.active { border-bottom-color: #398afa; color: #247ee6; } .group-list { width: min(100%, 50rem); margin: 0 auto; background: #fff; } /* Group identity header atop 群聊设置 (docs/images/群聊设置.png) -- avatar + name + description, tap through to 群资料. Same row shape as .group-list > button, just with a larger avatar and two-line text. */ .group-settings-header { display: grid; grid-template-columns: 3.6rem minmax(0, 1fr) 1.5rem; align-items: center; gap: 0.8rem; width: 100%; min-height: 5rem; margin: 0; padding: 0.8rem 1rem; border: 0; border-bottom: 1px solid #eceef1; border-radius: 0; box-shadow: none; color: #30353c; background: #fff; text-align: left; text-transform: none; } .group-settings-header .group-avatar { width: 3.6rem; height: 3.6rem; } /* 必须排除 .group-avatar:它本身也是个 span,被这条规则改成 flex-direction:column 之后, 自己的 place-items:center 就只剩交叉轴(水平)生效,主轴(垂直)退回 flex-start, 里面的图标会贴着方块顶部而不是居中。 */ .group-settings-header > span:not(.group-avatar) { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; } /* Same generic `button { line-height: 2.2rem }` leak as .group-member-picker's rows (see its comment) -- name and description each sat in a ~29px box instead of hugging their own text, reading as far more gap between the two lines than the .15rem `gap` above actually specifies. */ .group-settings-header strong { line-height: 1.3; } .group-settings-header small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #9299a2; line-height: 1.3; } .group-list > button { display: grid; grid-template-columns: 3.2rem minmax(0, 1fr) 1.5rem; align-items: center; gap: 0.8rem; width: 100%; min-height: 4.7rem; margin: 0; padding: 0.7rem 1rem; border: 0; border-bottom: 1px solid #eceef1; border-radius: 0; box-shadow: none; color: #30353c; background: #fff; text-align: left; text-transform: none; } .group-empty p { max-width: 19rem; margin: 0.5rem auto 1rem; line-height: 1.5; } .group-empty button { width: auto; min-height: 2.7rem; margin: 0; padding: 0 1rem; border: 0; border-radius: 0.35rem; box-shadow: none; color: #fff; background: #398afa; text-transform: none; } .group-modal-backdrop { align-items: center; } .group-modal { width: min(calc(100% - 2rem), 28rem); padding: 1.2rem; border-radius: 0.5rem; background: #fff; } .group-modal h2 { margin: 0 0 1rem; font-size: 1.1rem; } .group-modal label { display: flex; flex-direction: column; } .group-modal input { height: 2.8rem; margin: 0.5rem 0; padding: 0 0.7rem; border: 1px solid #dce0e5; border-radius: 0.35rem; box-shadow: none; } .group-modal p { color: #858c96; font-size: 0.78rem; } .group-modal footer { display: flex; justify-content: flex-end; gap: 0.6rem; } .group-modal footer button { width: auto; min-width: 4.5rem; min-height: 2.6rem; margin: 0; border: 0; border-radius: 0.3rem; box-shadow: none; color: #59616b; background: #eef0f2; text-transform: none; } .group-modal footer button.primary { color: #fff; background: #398afa; } .group-chat-header { grid-template-columns: 3.5rem minmax(0, 1fr) 3.5rem; } .group-chat-header > div { text-align: center; } .group-chat-header small { color: #8c939c; } .group-top-notice { display: grid; grid-template-columns: 2.5rem minmax(0, 1fr) 1.5rem; align-items: center; gap: 0.6rem; width: min(100%, 54rem); min-height: 3.7rem; margin: 0 auto; padding: 0.5rem 1rem; border: 0; border-bottom: 1px solid #e8eaed; border-radius: 0; box-shadow: none; color: #30353c; background: #fff; text-align: left; text-transform: none; } .group-top-notice > .material-icons:first-child { color: #398afa; } .group-top-notice.announcement > .material-icons:first-child { color: #f29b38; } .group-top-notice span { display: flex; min-width: 0; flex-direction: column; } .group-top-notice small { margin-top: 0.15rem; overflow: hidden; color: #8d949d; font-size: 0.75rem; text-overflow: ellipsis; white-space: nowrap; } .group-chat-timeline { width: 100%; min-height: 0; padding: 1.5rem max(1rem, calc((100% - 54rem) / 2)); overflow-y: auto; flex: 1 1 auto; } .group-system-event { width: fit-content; max-width: 80%; margin: 0.8rem auto; padding: 0.35rem 0.6rem; border-radius: 0.3rem; color: #878e97; background: #e8eaed; font-size: 0.75rem; text-align: center; } .group-chat-message { display: flex; gap: 0.7rem; margin-top: 1rem; } .group-chat-message > div { max-width: 70%; } .group-chat-message > div > span { color: #7d858f; font-size: 0.75rem; } .group-chat-message em { margin-left: 0.35rem; padding: 0.08rem 0.3rem; border-radius: 0.2rem; color: #247ee6; background: #eaf3ff; font-size: 0.65rem; font-style: normal; } .group-chat-message.owner em { color: #d57b17; background: #fff1df; } .group-chat-message p { margin: 0.3rem 0 0; padding: 0.7rem 0.9rem; border-radius: 0.4rem; background: #fff; line-height: 1.5; } .group-chat-composer { display: grid; grid-template-columns: 2.6rem minmax(0, 1fr) 2.6rem 2.6rem; align-items: center; flex: none; min-height: 4rem; padding: 0.5rem max(0.5rem, calc((100% - 54rem) / 2)); border-top: 1px solid #e2e5e9; background: #f8f9fa; } .group-chat-composer button { width: 2.5rem; min-width: 2.5rem; height: 2.5rem; min-height: 2.5rem; margin: 0; padding: 0; border: 0; box-shadow: none; background: transparent; } .group-chat-composer input { height: 2.7rem; margin: 0; padding: 0 0.7rem; border: 1px solid #e1e4e8; border-radius: 0.35rem; box-shadow: none; background: #fff; } .group-invite-card { width: min(100%, 23rem); margin: 3rem auto; padding: 1rem; border-radius: 0.45rem; background: #fff; box-shadow: 0 0.5rem 1.5rem rgba(34,42,52,0.08); } .group-invite-card > div { display: flex; align-items: center; gap: 0.8rem; } .group-invite-card > div > span { display: flex; flex-direction: column; } .group-invite-card small, .group-invite-card p { color: #858c95; } .group-invite-card button { width: 100%; min-height: 2.8rem; margin: 0.8rem 0 0; border: 0; border-radius: 0.35rem; box-shadow: none; color: #fff; background: #398afa; text-transform: none; } .group-invite-card button[disabled] { color: #7e858e; background: #e8eaed; } .group-announcement-detail { width: min(100%, 42rem); margin: 0 auto; padding: 2rem 1.2rem; background: #fff; } .group-announcement-detail > .material-icons { color: #f19b38; font-size: 2.5rem; } .group-announcement-detail h2 { margin: 0.7rem 0 1.2rem; } .group-announcement-detail > p { color: #555d67; line-height: 1.8; } .group-announcement-detail > small { display: block; margin-top: 1rem; color: #3a8aec; } /* 群聊设置页的成员预览网格(参考 docs/images/群聊设置.png)。这里必须用比 ".group-settings section > div" 更高的特异性覆盖那套列表项样式(flex + min-height + border-bottom + padding),否则网格容器会被当成一行普通设置项渲染,出现整行下划线; 同理成员格子刻意放在 grid 容器内部,避免成为 section 的直接子元素而命中同一套样式。 */ .group-settings section > .group-member-section-title { min-height: 2.8rem; padding: 0.75rem 1rem 0.35rem; border-bottom: 0; gap: 0.5rem; } .group-member-section-title > strong { color: #30353c; font-size: 1rem; line-height: 1.3; } .group-member-section-title > small { margin-left: auto; color: #949ba4; line-height: 1.3; } .group-settings section > .group-member-grid { display: flex; flex-wrap: wrap; align-items: flex-start; /* 不用 5 等分栅格:成员少的时候每个格子仍占满 1/5 宽度,头像被各自居中在很宽的格子里, 相邻两个头像之间会空出约头像宽度的间隙,看着很散。改成固定格子宽 + 固定间距靠左排。 尺寸按 docs/images/群聊设置.png 的比例反推:那张图里头像约占格子宽的 70%、相邻头像间隙 约为头像宽的 40%,且五个字的昵称能完整显示不截断——所以格子要比头像明显宽出一截, 光把格子缩到和头像等宽会让昵称被截成"测试..."。 */ gap: 0.9rem 0.5rem; min-height: 0; padding: 0.25rem 1rem 1rem; border-bottom: 0; } /* 全局 button 规则(css/base.css 约 1999 行)写死了 height: 2.2rem 和同值的 line-height, 不显式覆盖的话这里的格子会被压到 29px 高——头像溢出、下面的名字被压成 0 高度直接看不见。 */ .group-member-grid > button { display: flex; flex-direction: column; align-items: center; gap: 0.35rem; width: 4.4rem; min-width: 0; height: auto; min-height: 0; margin: 0; padding: 0; border: 0; box-shadow: none; color: #68707a; background: transparent; line-height: 1.3; text-transform: none; } .group-member-grid > button > small { width: 100%; overflow: hidden; color: #68707a; text-align: center; text-overflow: ellipsis; white-space: nowrap; } /* 成员格子里的头像比默认 3rem 略大,才能撑起参考图里"头像占格子七成、间隙约头像四成"的比例; 与之配套,"添加"格也用同一尺寸。 */ .group-member-grid .group-avatar, .group-member-tile-action { width: 3.6rem; height: 3.6rem; flex: 0 0 3.6rem; } /* "添加"格:跟成员头像同样尺寸的浅色方块,视觉上与真实成员头像区分开。宽高本该跟上面那条规则 一致(3.6rem)——之前这里写成了3rem,两条规则特异性相同、这条排在后面,字面覆盖了 width/ height,但没盖到上面那条的 flex:0 0 3.6rem(这条完全没提 flex),容器又是 flex-direction: column,主轴尺寸吃 flex-basis 不吃 height,实际渲成了 3rem 宽、3.6rem 高的长方形。 */ .group-member-tile-action { display: grid; place-items: center; width: 3.6rem; height: 3.6rem; border-radius: 0.45rem; color: #98a0aa; background: #f0f2f5; } .group-member-tile-action > .material-icons { font-size: 1.5rem; } .group-profile { width: min(100%, 50rem); margin: 0 auto; padding-top: 0.8rem; } .group-profile > button, .group-profile > label { gap: 0.7rem; } /* :not(.group-avatar) exclusion needed for the same reason as .group-settings-header's own (see its comment): this selector is scoped only by tag+ancestor, so without it also matches .group-profile-avatar's leading Avatar span and forces it to the label column's 6rem min-width -- stretching what should be a small square avatar into an 80px-wide rectangle. */ .group-profile > button > span:not(.group-avatar), .group-profile > label > span { min-width: 6rem; } .group-profile > button > small, .group-profile > label > input { min-width: 0; margin-left: auto; overflow: hidden; color: #818892; text-overflow: ellipsis; white-space: nowrap; } .group-profile > label > input { width: 100%; height: 2.5rem; margin: 0; padding: 0 0.5rem; border: 0; box-shadow: none; text-align: right; } .group-profile-avatar .group-avatar { width: 3.5rem; height: 3.5rem; } /* 群头像/群二维码这两行没有其它行都有的 (本身靠 margin-left:auto 把末尾图标推到 最右)——原来两行的图标紧贴在文字标签后面,跟其它行对不齐,列表右侧参差不齐。直接把 auto margin 放到"最右边这一组图标"里最靠前的那一个身上,这是更明确的写法,不依赖前面 兄弟元素的间接推挤:群头像只有末尾箭头一个图标,加在它自己身上;群二维码是"二维码小图标 +箭头"两个连续图标要整组贴右,auto margin 只能放在这一组的第一个(二维码图标)身上—— 放在箭头身上只会把箭头自己推到最右,二维码图标依然留在文字标签后面,两个图标就分家了。 */ .group-profile-avatar > i:last-child, .group-profile-qr > i:first-of-type { margin-left: auto; } .group-edit-text { width: min(100%, 42rem); margin: 0 auto; padding: 1rem; } .group-edit-text input, .group-edit-text textarea { width: 100%; margin: 0; padding: 0.8rem; border: 1px solid #e1e4e8; border-radius: 0.35rem; box-shadow: none; background: #fff; } .group-edit-text input { height: 3rem; } .group-edit-text textarea { min-height: 10rem; resize: vertical; } .group-edit-text > small { display: block; margin-top: 0.4rem; color: #969da6; text-align: right; } .group-edit-text p { color: #878e98; font-size: 0.78rem; } .group-governance section > div > span { display: flex; flex-direction: column; flex: 1 1 auto; } .group-governance section > div > span small { margin-top: 0.2rem; color: #9299a2; font-size: 0.72rem; } .group-admin-page { padding-bottom: 1rem; } .group-admin-page aside { display: flex; gap: 0.6rem; margin: 0; padding: 0.8rem 1rem; color: #7a828c; background: #eef5ff; font-size: 0.78rem; line-height: 1.5; } .group-admin-page aside .material-icons { color: #398afa; font-size: 1.2rem; } .group-admin-page aside p { margin: 0; } .group-admin-page h2 { margin: 0; padding: 0.7rem 1rem; color: #8a929b; background: #f5f6f8; font-size: 0.78rem; } .group-inline-empty { padding: 2rem; color: #969da5; text-align: center; } /* 列表下方的常驻灰色注脚(禁言页的"以上成员不允许发言"),区别于上面的空状态文案。 */ .group-inline-note { margin: 0; padding: 0.9rem 1rem 1.4rem; color: #969da5; font-size: 0.85rem; text-align: center; } /* Alphabet-group section header inside MemberPicker/OwnerSelect, same treatment as .group-admin-page h2. */ .group-section-title { margin: 0; padding: 0.7rem 1rem; color: #8a929b; background: #f5f6f8; font-size: 0.78rem; } /* Small muted caption under a list/header, e.g. member count or "仅群主及群管理员可编辑". */ .group-inline-hint { padding: 0.3rem 1rem 0.7rem; color: #969da5; font-size: 0.78rem; } /* Centered "设置成功" overlay confirmation, docs/images/添加管理员-设置成功.png -- distinct from the bottom-anchored .chat-toast used for lighter feedback elsewhere in this file. */ .group-toast-center { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 30; display: flex; flex-direction: column; align-items: center; gap: 0.4rem; padding: 1.2rem 1.6rem; border-radius: 0.6rem; color: #fff; background: rgba(34,38,45,0.94); box-shadow: 0 0.5rem 1.5rem rgba(0,0,0,0.18); } .group-toast-center .material-icons { font-size: 2rem; } /* Dropdown menu anchored under group-files' header "+" button, docs/images/群文件-上传状态.png -- unlike .group-upload-sources (a full-width bottom bar used elsewhere), this is a small popover. */ .group-upload-menu { position: absolute; top: 3.4rem; right: max(1rem, calc((100% - 50rem) / 2 + 1rem)); z-index: 20; display: flex; flex-direction: column; min-width: 9rem; padding: 0.4rem 0; border-radius: 0.5rem; background: rgba(34,38,45,0.94); box-shadow: 0 0.5rem 1.5rem rgba(0,0,0,0.18); } .group-upload-menu button { display: flex; align-items: center; gap: 0.6rem; padding: 0.6rem 1rem; border: 0; border-radius: 0; box-shadow: none; color: #fff; background: transparent; text-align: left; text-transform: none; font-size: 0.85rem; } .group-upload-menu .material-icons { font-size: 1.1rem; } .group-member-picker { width: min(100%, 50rem); margin: 0 auto; background: #fff; } .group-member-picker > button { display: grid; grid-template-columns: 3rem minmax(0, 1fr) 1.5rem; align-items: center; gap: 0.8rem; width: 100%; min-height: 4.5rem; margin: 0; padding: 0.6rem 1rem; border: 0; border-bottom: 1px solid #eceef1; border-radius: 0; box-shadow: none; color: #30353c; background: #fff; text-align: left; text-transform: none; } .group-check { display: grid; place-items: center; width: 1.4rem; height: 1.4rem; border: 1px solid #c8cdd3; border-radius: 50%; color: #fff; } .group-check.checked { border-color: #398afa; background: #398afa; } .group-check .material-icons { font-size: 0.95rem; } .group-file-list { width: min(100%, 54rem); margin: 0 auto; background: #fff; } .group-file-list article { display: grid; grid-template-columns: 3rem minmax(0, 1fr) 2.5rem; align-items: center; gap: 0.8rem; min-height: 5rem; padding: 0.7rem 1rem; border-bottom: 1px solid #eceef1; } .group-file-type { display: grid; place-items: center; width: 3rem; height: 3.4rem; border-radius: 0.3rem; color: #fff; background: #e54b68; font-size: 0.7rem; font-weight: 700; } .group-file-list article > div { display: flex; min-width: 0; flex-direction: column; } .group-file-list strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .group-file-list small { margin-top: 0.3rem; color: #9299a2; font-size: 0.74rem; } .group-file-list progress { width: 100%; height: 0.3rem; margin-top: 0.4rem; accent-color: #398afa; } .group-file-list button { width: 2.5rem; min-width: 2.5rem; height: 2.5rem; min-height: 2.5rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #5f6872; background: transparent; } .group-upload-sources { display: grid; grid-template-columns: repeat(3, 1fr); flex: none; min-height: 6rem; padding: 0.7rem max(1rem, calc((100% - 36rem) / 2)) max(0.7rem, env(safe-area-inset-bottom)); border-top: 1px solid #e2e5e9; background: #fff; } .group-upload-sources button { display: flex; align-items: center; justify-content: center; width: 100%; min-width: 0; margin: 0; padding: 0; border: 0; box-shadow: none; color: #5c6570; background: transparent; flex-direction: column; text-transform: none; } .group-upload-sources .material-icons { margin-bottom: 0.35rem; color: #398afa; font-size: 1.7rem; } /* Content library, secure downloads, and conversation search. */ #sidepanel.content-library-panel { width: 100%; min-width: 0; flex: 1 1 auto; color-scheme: light; color: #292e35; background: #f5f6f8; } .content-library-panel * { box-sizing: border-box; letter-spacing: 0; } .library-page { display: flex; position: relative; width: 100%; min-height: 100%; overflow: hidden; flex-direction: column; background: #f5f6f8; } .library-header { display: grid; z-index: 3; grid-template-columns: 4.5rem minmax(0, 1fr) 4.5rem; align-items: center; flex: none; min-height: 4.5rem; padding-top: env(safe-area-inset-top); border-bottom: 1px solid #e9ebee; background: #fff; } .library-header h1 { margin: 0; overflow: hidden; font-size: 1.15rem; text-align: center; text-overflow: ellipsis; white-space: nowrap; } .library-header > button { display: grid; place-items: center; width: 100%; min-width: 0; height: 3.2rem; min-height: 3.2rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #2e333a; background: transparent; } .library-header > button.text { color: #247ee6; font-size: 0.86rem; text-transform: none; } .library-search { display: flex; align-items: center; flex: none; height: 2.8rem; margin: 0.8rem max(1rem, calc((100% - 52rem) / 2)); padding: 0 0.75rem; border-radius: 0.35rem; color: #9299a2; background: #fff; } .library-search .material-icons { font-size: 1.2rem; } .library-search input { width: 100%; min-width: 0; height: 100%; margin: 0; padding: 0 0.5rem; border: 0; box-shadow: none; background: transparent; } .library-avatar { display: grid; place-items: center; width: 3rem; height: 3rem; overflow: hidden; flex: 0 0 3rem; border-radius: 0.45rem; color: #fff; background: #4389df; } .library-avatar img { width: 100%; height: 100%; object-fit: cover; } .library-type-tabs, .library-history-tabs { display: flex; width: min(100%, 52rem); min-height: 2.9rem; margin: 0 auto; overflow-x: auto; flex: none; border-bottom: 1px solid #e4e7eb; background: #fff; scrollbar-width: none; } .library-type-tabs button, .library-history-tabs button { min-width: 4.3rem; min-height: 2.9rem; margin: 0; padding: 0 0.8rem; border: 0; border-bottom: 2px solid transparent; border-radius: 0; box-shadow: none; color: #747c86; background: transparent; font-size: 0.8rem; text-transform: none; } .library-type-tabs button.active, .library-history-tabs button.active { border-bottom-color: #398afa; color: #247ee6; } .library-favorite-list, .library-history-content { width: min(100%, 52rem); min-height: 0; margin: 0 auto; overflow-y: auto; flex: 1 1 auto; } /* Favorites/History/DownloadPage's loading/error placeholder text and Favorites/History's "加载 更多" pagination button -- both had zero rules anywhere in this file, falling back to a bare 's default margins and a plain 's default outline respectively. */ .library-empty-hint { padding: 1.5rem 1rem; color: #9299a2; font-size: 0.85rem; text-align: center; } .library-load-more { display: block; width: min(100%, 52rem); margin: 0 auto; padding: 0.8rem; border: 1px solid #eceef1; border-radius: 0.4rem; box-shadow: none; color: #567; background: #fff; font-size: 0.85rem; text-transform: none; } .library-favorite-item { display: flex; gap: 0.7rem; padding: 0.9rem 1rem; border-bottom: 1px solid #eceef1; background: #fff; } .library-favorite-item.selecting { align-items: center; } .library-favorite-content { min-width: 0; flex: 1 1 auto; } .library-favorite-content > footer { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 0.5rem; margin-top: 0.65rem; color: #9299a2; font-size: 0.72rem; } .library-favorite-content > footer span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .library-favorite-content > footer button { width: 2rem; min-width: 2rem; height: 2rem; min-height: 2rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #7d858e; background: transparent; } .library-text-content { margin: 0; color: #343941; font-size: 0.94rem; line-height: 1.65; } .library-file-card { display: grid; grid-template-columns: 3rem minmax(0, 1fr) auto; align-items: center; gap: 0.8rem; width: 100%; min-height: 4.8rem; margin: 0; padding: 0.7rem; border: 1px solid #eceef1; border-radius: 0.4rem; box-shadow: none; color: #30353c; background: #fafbfc; text-align: left; text-transform: none; } .library-file-card > span, .library-download-icon { display: grid; place-items: center; width: 3rem; height: 3.4rem; border-radius: 0.3rem; color: #fff; background: #e54b68; font-size: 0.7rem; font-weight: 700; } .library-file-card > div { display: flex; min-width: 0; flex-direction: column; } .library-file-card strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .library-file-card small { margin-top: 0.3rem; color: #9299a2; font-size: 0.74rem; } .library-file-card.removed { opacity: 0.65; } .library-file-card em { color: #d74a53; font-size: 0.74rem; font-style: normal; } .library-link-text { display: flex; align-items: center; gap: 0.6rem; width: 100%; min-width: 0; height: auto; min-height: 2.8rem; margin: 0; padding: 0.6rem 0.8rem; border: 1px solid #eceef1; border-radius: 0.4rem; box-shadow: none; color: var(--clr-primary-accent); background: #fafbfc; text-align: left; text-transform: none; line-height: 1.3; } .library-link-text span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* Shared by VoiceCard/LinkText/MediaThumb's "removed" state (content-library-view.jsx) -- same opacity + red label language as .library-file-card.removed/em above, but these three don't share its grid layout (voice/media assume an icon+waveform or an image backdrop that isn't there once the source message is gone), so the removed state uses a simple centered flex row instead. */ .library-voice-card.removed, .library-link-text.removed, .library-media-thumb.removed { display: flex; align-items: center; justify-content: center; gap: 0.4rem; opacity: 0.65; } .library-voice-card.removed em, .library-link-text.removed em, .library-media-thumb.removed em { color: #d74a53; font-size: 0.74rem; font-style: normal; } .library-voice-card { display: flex; align-items: center; gap: 0.6rem; width: min(100%, 20rem); min-height: 3.2rem; margin: 0; padding: 0 0.8rem; border: 0; border-radius: 0.4rem; box-shadow: none; color: #343a42; background: #eef5ff; } .library-voice-card.playing { color: #fff; background: #398afa; } .library-voice-card .material-icons { font-size: 1.6rem; } .library-wave { height: 1rem; opacity: 0.55; background: repeating-linear-gradient(90deg, currentColor 0 2px, transparent 2px 5px); } .library-link-card { display: grid; grid-template-columns: 5.2rem minmax(0, 1fr); gap: 0.8rem; width: 100%; min-height: 5.8rem; margin: 0; padding: 0.7rem; border: 1px solid #eceef1; border-radius: 0.4rem; box-shadow: none; color: #30353c; background: #fafbfc; text-align: left; text-transform: none; } .library-link-card > img { width: 5.2rem; height: 4.5rem; border-radius: 0.3rem; object-fit: cover; } .library-link-card > div { min-width: 0; } .library-link-card strong, .library-link-card p { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .library-link-card p { margin: 0.35rem 0; color: #7e858f; font-size: 0.76rem; } .library-link-card small { display: flex; align-items: center; color: #9aa0a8; } .library-link-card small .material-icons { margin-right: 0.25rem; font-size: 0.95rem; } .library-media-thumb { position: relative; width: 11rem; height: auto; aspect-ratio: 4 / 3; min-height: 0; margin: 0; padding: 0; overflow: hidden; border: 0; border-radius: 0.4rem; box-shadow: none; background: #dfe3e8; } .library-media-thumb img { width: 100%; height: 100%; object-fit: cover; } .library-media-thumb .material-icons { position: absolute; top: 50%; left: 50%; color: #fff; font-size: 2.5rem; filter: drop-shadow(0 2px 4px rgba(0,0,0,0.35)); transform: translate(-50%, -50%); } .library-media-thumb small { position: absolute; right: 0.4rem; bottom: 0.3rem; color: #fff; } .library-check { display: grid; place-items: center; width: 1.4rem; min-width: 1.4rem; height: 1.4rem; min-height: 1.4rem; margin: 0; padding: 0; border: 1px solid #c8cdd3; border-radius: 50%; box-shadow: none; color: #fff; background: #fff; } .library-check.checked { border-color: #398afa; background: #398afa; } .library-check .material-icons { font-size: 0.95rem; } .library-empty { display: flex; align-items: center; justify-content: center; min-height: 20rem; color: #969da6; flex-direction: column; } .library-empty .material-icons { margin-bottom: 0.7rem; color: #b5bbc2; font-size: 3.5rem; } .library-batch-bar { display: grid; grid-template-columns: repeat(2, 1fr); flex: none; min-height: 4.5rem; padding-bottom: env(safe-area-inset-bottom); border-top: 1px solid #e2e5e9; background: #fff; } .library-batch-bar button { display: flex; align-items: center; justify-content: center; min-height: 4.2rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #555e68; background: transparent; flex-direction: column; text-transform: none; } .library-batch-bar button[disabled] { color: #b6bbc2; } .library-batch-bar span { margin-top: 0.2rem; font-size: 0.72rem; } .library-section-title { width: min(100%, 52rem); margin: 0 auto; padding: 0.55rem 1rem; color: #8a929b; font-size: 0.78rem; } .library-target-list { width: min(100%, 52rem); min-height: 0; margin: 0 auto; overflow-y: auto; flex: 1 1 auto; background: #fff; } .library-target-list > button { display: grid; grid-template-columns: 3rem minmax(0, 1fr) 1.5rem; align-items: center; gap: 0.8rem; width: 100%; min-height: 4.5rem; margin: 0; padding: 0.6rem 1rem; border: 0; border-bottom: 1px solid #eceef1; border-radius: 0; box-shadow: none; color: #30353c; background: #fff; text-align: left; text-transform: none; } .library-target-list > button > span:nth-child(2) { display: flex; min-width: 0; flex-direction: column; } .library-target-list small { margin-top: 0.2rem; color: #9299a2; } .library-next-bar { display: flex; align-items: center; justify-content: space-between; flex: none; min-height: 4.3rem; padding: 0.6rem max(1rem, calc((100% - 50rem) / 2)); border-top: 1px solid #e2e5e9; color: #777f89; background: #fff; } .library-next-bar button, .library-share-confirm > button, .library-primary { width: auto; min-width: 5rem; min-height: 2.8rem; margin: 0; padding: 0 1rem; border: 0; border-radius: 0.35rem; box-shadow: none; color: #fff; background: #398afa; text-transform: none; } .library-next-bar button[disabled] { background: #b7c9df; } .library-share-confirm { width: min(100%, 42rem); margin: 0 auto; padding: 1.2rem; } .library-share-confirm h2 { margin: 0 0 0.8rem; font-size: 0.92rem; } .library-target-summary { display: flex; gap: 1rem; padding: 1rem; overflow-x: auto; background: #fff; } .library-target-summary > span { display: flex; align-items: center; width: 4rem; flex: 0 0 4rem; flex-direction: column; } .library-target-summary small { width: 100%; margin-top: 0.3rem; overflow: hidden; text-align: center; text-overflow: ellipsis; white-space: nowrap; } .library-share-confirm > section { margin-top: 1rem; padding: 1rem; background: #fff; } .library-share-confirm > section p { margin-bottom: 0; color: #858d96; font-size: 0.76rem; line-height: 1.5; } .library-share-confirm textarea { width: 100%; min-height: 5rem; margin: 1rem 0; padding: 0.8rem; border: 0; border-radius: 0.35rem; box-shadow: none; background: #fff; resize: vertical; } .library-share-confirm > button { width: 100%; } .library-download { width: min(100%, 36rem); margin: 0 auto; padding: 2.5rem 1.2rem; text-align: center; } .library-download-icon { width: 5rem; height: 5.8rem; margin: 0 auto 1rem; font-size: 1rem; } .library-download h2 { margin: 0; overflow-wrap: anywhere; font-size: 1.1rem; } .library-download > p { color: #8a929b; } .library-download dl { margin: 1.5rem 0; padding: 0 1rem; background: #fff; text-align: left; } .library-download dl > div { display: flex; justify-content: space-between; padding: 0.8rem 0; border-bottom: 1px solid #eceef1; } .library-download dt, .library-download dd { margin: 0; } .library-download dd { color: #777f89; } .library-primary { display: flex; align-items: center; justify-content: center; width: 100%; } .library-primary .material-icons { margin-right: 0.4rem; } .library-download-progress { margin: 1.5rem 0; padding: 1rem; background: #fff; text-align: left; } .library-download-progress > div { display: flex; justify-content: space-between; } .library-download-progress progress { width: 100%; height: 0.45rem; margin: 0.8rem 0 0.4rem; accent-color: #398afa; } .library-download-progress small { color: #9299a2; } /* DownloadPage's loading ("取消") and done ("用其他应用打开") states each render exactly one button here -- never two side by side -- so the 2nd 1fr column sat permanently empty, pinning the button to the left half with the right half dead space. */ .library-download-actions { display: grid; grid-template-columns: 1fr; gap: 0.8rem; } .library-download-actions button { min-height: 2.9rem; margin: 0; border: 1px solid #dce0e5; border-radius: 0.35rem; box-shadow: none; color: #555e68; background: #fff; text-transform: none; } .library-download-actions button.primary { border-color: #398afa; color: #fff; background: #398afa; } .library-download-actions .material-icons { margin-right: 0.35rem; font-size: 1.1rem; vertical-align: middle; } .library-complete { display: flex; align-items: center; gap: 0.7rem; margin: 1.5rem 0; padding: 1rem; color: #257c58; background: #eaf8f1; text-align: left; } .library-complete > .material-icons { font-size: 2rem; } .library-complete > span { display: flex; flex-direction: column; } .library-complete small { margin-top: 0.2rem; color: #65917d; } .library-message-results > button { display: grid; grid-template-columns: 3rem minmax(0, 1fr) 1.5rem; align-items: start; gap: 0.8rem; width: 100%; min-height: 5.5rem; margin: 0; padding: 0.8rem 1rem; border: 0; border-bottom: 1px solid #eceef1; border-radius: 0; box-shadow: none; color: #30353c; background: #fff; text-align: left; text-transform: none; } .library-message-results > button > span { min-width: 0; } .library-message-results p { margin: 0.3rem 0; color: #666e78; line-height: 1.5; } .library-message-results mark { padding: 0 0.08rem; color: #1f66b8; background: #dcecff; } .library-message-results small { color: #969da5; } .library-record-files, .library-record-links { padding: 0.8rem; background: #fff; } .library-record-header { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; width: 100%; min-width: 0; height: auto; margin: 0 0 0.4rem; padding: 0; border: 0; box-shadow: none; color: inherit; background: transparent; text-align: left; text-transform: none; } .library-record-header strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; } .library-record-header small { flex: none; color: #9299a2; font-size: 0.74rem; } .library-record-files .library-file-card, .library-record-links .library-link-text { margin-bottom: 0.7rem; } .library-date-title { margin: 0; padding: 0.7rem 0.8rem; color: #828a94; font-size: 0.8rem; } .library-media-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.35rem; padding: 0 0.8rem 1rem; } .library-media-grid button { position: relative; width: 100%; height: auto; min-height: 0; aspect-ratio: 1; margin: 0; padding: 0; overflow: hidden; border: 0; border-radius: 0.25rem; box-shadow: none; background: #dfe3e8; } .library-media-grid img { width: 100%; height: 100%; object-fit: cover; } .library-media-grid .material-icons { position: absolute; top: 50%; left: 50%; color: #fff; font-size: 2.2rem; filter: drop-shadow(0 2px 4px rgba(0,0,0,0.35)); transform: translate(-50%, -50%); } .library-media-grid small { position: absolute; right: 0.3rem; bottom: 0.2rem; color: #fff; font-size: 0.65rem; } /* Android call experience and call records. */ #sidepanel.call-experience-panel { width: 100%; min-width: 0; flex: 1 1 auto; color-scheme: light; background: #11151a; } .call-experience-panel * { box-sizing: border-box; letter-spacing: 0; } .call-history-page, .call-minimized-page { display: flex; position: relative; width: 100%; min-height: 100%; overflow: hidden; color: #252a31; background: #f5f6f8; flex-direction: column; } .call-history-page > header, .call-chat-preview-header { display: grid; grid-template-columns: 3.8rem minmax(0, 1fr) 3.8rem; align-items: center; flex: none; min-height: 4.5rem; padding-top: env(safe-area-inset-top); border-bottom: 1px solid #e8eaed; background: #fff; } .call-history-page > header h1 { margin: 0; font-size: 1.15rem; text-align: center; } .call-history-page > header button, .call-chat-preview-header button { display: grid; place-items: center; width: 100%; min-width: 0; height: 3.2rem; min-height: 3.2rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #30353c; background: transparent; } .call-history-page > main { width: min(100%, 48rem); min-height: 0; margin: 0 auto; overflow-y: auto; flex: 1 1 auto; background: #fff; } .call-record { display: grid; grid-template-columns: 2.5rem minmax(0, 1fr) auto 1.5rem; align-items: center; gap: 0.7rem; width: 100%; min-height: 4.5rem; margin: 0; padding: 0.65rem 1rem; border: 0; border-bottom: 1px solid #eceef1; border-radius: 0; box-shadow: none; color: #30353c; background: #fff; text-align: left; text-transform: none; } .call-record > .material-icons:first-child { display: grid; place-items: center; width: 2.5rem; height: 2.5rem; border-radius: 50%; color: #257a58; background: #e9f7f0; } .call-record.missed > .material-icons:first-child, .call-record.declined > .material-icons:first-child, .call-record.busy > .material-icons:first-child { color: #d84850; background: #fdecee; } .call-record > span { display: flex; min-width: 0; flex-direction: column; } .call-record small { margin-top: 0.2rem; color: #858d96; } .call-record.missed small, .call-record.declined small, .call-record.busy small { color: #d84850; } .call-record time { color: #969da5; font-size: 0.72rem; } .call-record > .material-icons:last-child { color: #8d949d; font-size: 1rem; } .call-history-page > footer { display: grid; grid-template-columns: 1fr 1fr; gap: 0.8rem; width: min(100%, 48rem); min-height: 4.8rem; margin: 0 auto; padding: 0.7rem 1rem max(0.7rem, env(safe-area-inset-bottom)); border-top: 1px solid #e2e5e9; background: #fff; } .call-history-page > footer button { display: flex; align-items: center; justify-content: center; min-height: 3rem; margin: 0; border: 0; border-radius: 0.35rem; box-shadow: none; color: #fff; background: #277f5a; text-transform: none; } .call-history-page > footer button:last-child { background: #347fd7; } .call-history-page > footer .material-icons { margin-right: 0.4rem; font-size: 1.2rem; } .call-fullscreen { display: flex; position: relative; width: 100%; min-height: 100%; overflow: hidden; color: #fff; background: #171c22; flex-direction: column; isolation: isolate; } .call-audio-surface { background: #26323b; } .call-ambient { position: absolute; z-index: -2; inset: -2rem; background: linear-gradient(160deg, #34444f 0%, #202931 52%, #151a20 100%); } .call-audio-surface::after { content: ''; position: absolute; z-index: -1; inset: 0; opacity: 0.12; background-image: url('../img/bkg/p09.jpg'); background-position: center; background-size: cover; filter: blur(24px); transform: scale(1.12); } .call-fullscreen.incoming-call-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; /* Must clear every other in-app overlay (headers/toasts go up to z-index:100) so a call always covers the screen. */ z-index: 200; } .incoming-call-photo-blur { position: absolute; z-index: -1; inset: 0; opacity: 0.12; background-image: var(--incoming-call-photo); background-position: center; background-size: cover; filter: blur(24px); transform: scale(1.12); } .call-product-header { display: grid; z-index: 4; grid-template-columns: 4rem minmax(0, 1fr) 4rem; align-items: center; flex: none; min-height: 4.8rem; padding-top: env(safe-area-inset-top); } .call-product-header > button { display: grid; place-items: center; width: 100%; min-width: 0; height: 3.4rem; min-height: 3.4rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: rgba(255,255,255,0.92); background: transparent; } .call-product-header > span { color: rgba(255,255,255,0.7); font-size: 0.74rem; text-align: center; } .call-peer-card { display: flex; z-index: 2; align-items: center; justify-content: center; min-height: 0; padding: 1rem; flex: 1 1 auto; flex-direction: column; } .call-product-avatar { display: block; width: 7.5rem; height: 7.5rem; overflow: hidden; border: 2px solid rgba(255,255,255,0.4); border-radius: 50%; box-shadow: 0 1rem 2.5rem rgba(0,0,0,0.25); } .call-product-avatar.small { width: 3rem; height: 3rem; } .call-product-avatar img { width: 100%; height: 100%; object-fit: cover; } /* Name + trusted badge used to share one nowrap/ellipsis box -- when the name alone was long enough to need truncating, the badge (last in source order) got truncated away with it, entirely outside the visible area instead of just following a shortened name. Name now truncates in its own flex child; the badge is a non-shrinking sibling so it always stays on-screen right after whatever of the name fit. */ .call-peer-card h1 { display: flex; align-items: center; margin: 1.3rem 0 0.45rem; max-width: 100%; color: #fff; font-size: 1.55rem; } .call-peer-card h1 > span { min-width: 0; overflow-x: hidden; text-overflow: ellipsis; white-space: nowrap; } .call-peer-card h1 .trusted-badge { flex: none; } .call-peer-card p { margin: 0; color: rgba(255,255,255,0.78); font-size: 0.92rem; } .call-peer-card .call-network { display: flex; align-items: center; margin-top: 0.65rem; color: rgba(255,255,255,0.62); } .call-network i { width: 0.45rem; height: 0.45rem; margin-right: 0.35rem; border-radius: 50%; background: #43d38c; } .call-ringing-dots { display: flex; gap: 0.35rem; margin-top: 1rem; } .call-ringing-dots i { width: 0.4rem; height: 0.4rem; border-radius: 50%; background: rgba(255,255,255,0.65); animation: call-dot 1.2s infinite ease-in-out; } .call-ringing-dots i:nth-child(2) { animation-delay: 0.15s; } .call-ringing-dots i:nth-child(3) { animation-delay: 0.3s; } @keyframes call-dot { 0%, 70%, 100% { transform: translateY(0); opacity: 0.45; } 35% { transform: translateY(-0.35rem); opacity: 1; } } .call-incoming-actions, .call-active-controls, .call-single-action, .call-video-controls { display: flex; z-index: 4; align-items: flex-start; justify-content: space-evenly; flex: none; min-height: 8rem; padding: 1rem max(1rem, calc((100% - 34rem) / 2)) max(1.5rem, env(safe-area-inset-bottom)); } .call-single-action { justify-content: center; } .call-control { display: flex; align-items: center; width: 5rem; min-width: 5rem; height: auto; min-height: 0; margin: 0; padding: 0; border: 0; box-shadow: none; color: rgba(255,255,255,0.78); background: transparent; flex-direction: column; text-transform: none; } .call-control > span { display: grid; place-items: center; width: 3.7rem; height: 3.7rem; border-radius: 50%; color: #fff; background: rgba(255,255,255,0.16); backdrop-filter: blur(8px); } .call-control.active > span { color: #22272d; background: #fff; } .call-control.danger > span { color: #fff; background: #e3464f; } .call-control .material-icons { font-size: 1.55rem; } .call-control small { width: 100%; margin-top: 0.5rem; color: inherit; font-size: 0.7rem; line-height: 1.2; text-align: center; } .call-incoming-actions .call-control:last-child > span { background: #2ab56f; } .call-video-surface { background: #11151a; } .call-video-backdrop, .call-video-off { position: absolute; z-index: -2; inset: 0; width: 100%; height: 100%; } .call-video-backdrop { object-fit: cover; } .call-video-off { display: flex; align-items: center; justify-content: center; background: #252f37; flex-direction: column; } .call-video-off .call-product-avatar { width: 7rem; height: 7rem; } .call-video-off strong { margin-top: 1.2rem; } .call-video-off small { margin-top: 0.35rem; color: rgba(255,255,255,0.68); } .call-video-off.local { background: #20272e; } .call-video-shade { position: absolute; z-index: -1; inset: 0; background: linear-gradient(180deg, rgba(0,0,0,0.42), transparent 30%, transparent 62%, rgba(0,0,0,0.58)); } .call-video-status { z-index: 2; text-align: center; } .call-video-status h1 { margin: 0.4rem 0 0.25rem; color: #fff; font-size: 1.25rem; } .call-video-status p { margin: 0; color: rgba(255,255,255,0.8); } .call-video-controls { margin-top: auto; } .call-local-preview { position: absolute; z-index: 3; top: max(6.2rem, calc(env(safe-area-inset-top) + 5rem)); right: 1rem; width: 7rem; min-width: 7rem; height: auto; min-height: 0; aspect-ratio: 3 / 4; margin: 0; padding: 0; overflow: hidden; border: 1px solid rgba(255,255,255,0.35); border-radius: 0.4rem; box-shadow: 0 0.5rem 1.2rem rgba(0,0,0,0.3); background: #252c33; } .call-local-preview img { width: 100%; height: 100%; object-fit: cover; } .call-local-preview .material-icons { position: absolute; top: 50%; left: 50%; color: #fff; transform: translate(-50%, -50%); } .call-toast { position: fixed; z-index: 50; bottom: max(1.5rem, env(safe-area-inset-bottom)); left: 50%; max-width: calc(100% - 2rem); padding: 0.7rem 1rem; border-radius: 0.3rem; color: #fff; background: rgba(24,28,34,0.94); text-align: center; transform: translateX(-50%); } .call-chat-preview-header > div { display: flex; align-items: center; justify-content: center; flex-direction: column; } .call-chat-preview-header small { margin-top: 0.15rem; color: #37a66d; } .call-minimized-page > main { min-height: 0; padding: 1.5rem max(1rem, calc((100% - 52rem) / 2)); overflow-y: auto; flex: 1 1 auto; } .call-chat-preview-message { width: fit-content; max-width: 70%; padding: 0.7rem 0.9rem; border-radius: 0.4rem; background: #fff; line-height: 1.5; } .call-chat-composer { display: grid; grid-template-columns: minmax(0, 1fr) 3rem; align-items: center; flex: none; min-height: 4rem; padding: 0.5rem max(0.7rem, calc((100% - 52rem) / 2)); border-top: 1px solid #e2e5e9; background: #fff; } .call-chat-composer input { height: 2.7rem; margin: 0; padding: 0 0.7rem; border: 1px solid #e1e4e8; border-radius: 0.35rem; box-shadow: none; background: #f7f8f9; } .call-chat-composer button { width: 3rem; min-width: 3rem; height: 2.7rem; min-height: 2.7rem; margin: 0; padding: 0; border: 0; box-shadow: none; background: transparent; } .call-floating-window { position: fixed; z-index: 20; top: 0; left: 0; width: 7.4rem; min-width: 7.4rem; height: auto; min-height: 0; aspect-ratio: 3 / 4; margin: 0; padding: 0; overflow: hidden; touch-action: none; border: 1px solid rgba(255,255,255,0.6); border-radius: 0.45rem; box-shadow: 0 0.5rem 1.5rem rgba(0,0,0,0.28); background: #20262c; } .call-floating-window img { width: 100%; height: 100%; pointer-events: none; object-fit: cover; } .call-floating-window span { position: absolute; right: 0.4rem; bottom: 0.35rem; display: flex; align-items: center; color: #fff; font-size: 0.68rem; text-shadow: 0 1px 2px rgba(0,0,0,0.8); } .call-floating-window span i { width: 0.4rem; height: 0.4rem; margin-right: 0.25rem; border-radius: 50%; background: #41d48d; } .call-mini-hangup { position: fixed; z-index: 21; right: 1rem; bottom: 5.2rem; display: grid; place-items: center; width: 3rem; min-width: 3rem; height: 3rem; min-height: 3rem; margin: 0; padding: 0; border: 0; border-radius: 50%; box-shadow: 0 0.4rem 1rem rgba(0,0,0,0.2); color: #fff; background: #e3464f; } .compose-target-footer { justify-content: space-between; margin-top: auto; color: #757d87; font-size: 0.82rem; } .compose-forward-confirm { width: min(100%, 40rem); margin: 0 auto; padding: 1.2rem; } .compose-forward-confirm > section, .compose-forward-confirm textarea { width: 100%; margin-bottom: 1rem; padding: 1rem; border: 0; border-radius: 0.45rem; background: #fff; } .compose-target-summary { display: flex; gap: 1rem; overflow-x: auto; } .compose-target-summary > span { display: flex; align-items: center; width: 4rem; flex: 0 0 4rem; flex-direction: column; } .compose-target-summary small { width: 100%; margin-top: 0.35rem; overflow: hidden; text-align: center; text-overflow: ellipsis; white-space: nowrap; } .compose-forward-preview h2 { margin-top: 0; } .compose-forward-preview p { margin: 0.45rem 0; overflow: hidden; color: #757c85; font-size: 0.82rem; text-overflow: ellipsis; white-space: nowrap; } .compose-forward-confirm textarea { min-height: 5rem; resize: vertical; } .compose-forward-mode { display: grid; grid-template-columns: 1fr 1fr; gap: 0.7rem; margin-bottom: 1rem; } .compose-forward-mode button { min-height: 2.8rem; margin: 0; border: 1px solid #dce0e5; border-radius: 0.35rem; box-shadow: none; color: #646c76; background: #fff; text-transform: none; } .compose-forward-mode button.active { border-color: #398afa; color: #287fe5; background: #eef6ff; } .compose-confirm-send { width: 100%; min-height: 3rem; margin: 0; } @keyframes fadein { from { bottom: 0; opacity: 0; } to { bottom: 2rem; opacity: 1; } } @keyframes fadeout { from { bottom: 2rem; opacity: 1; } to { bottom: 0; opacity: 0; } } /* Very wide monitor. */ @media (min-width: 1440px){ #app-container { max-width: 114rem; } } /* Mobile styles. */ @media (max-width: 960px) { #mountPoint { padding: 0; } .pinned { width: 16rem; } } @media (max-width: 640px) { #app-container { width: 100%; border-radius: 0; box-shadow: none; } #sidepanel { width: 100%; } #sidepanel.message-center-panel, #sidepanel.message-center-panel.full-page { width: 100%; min-width: 0; flex-basis: 100%; } #sidepanel.direct-message-panel { width: 100%; min-width: 0; } #sidepanel.message-composer-panel { width: 100%; min-width: 0; } #sidepanel.contact-management-panel, #sidepanel.group-management-panel { width: 100%; min-width: 0; } #sidepanel.content-library-panel { width: 100%; min-width: 0; } #sidepanel.call-experience-panel { width: 100%; min-width: 0; } .call-active-controls, .call-video-controls { padding-right: 0.35rem; padding-left: 0.35rem; } .call-control { width: 4.5rem; min-width: 4.5rem; } .call-control > span { width: 3.4rem; height: 3.4rem; } .library-media-grid { grid-template-columns: repeat(3, 1fr); } .library-link-card { grid-template-columns: 4.3rem minmax(0, 1fr); } .library-link-card > img { width: 4.3rem; height: 4.3rem; } .people-request-list article, .group-request-list article { align-items: flex-start; } .people-request-list article > span, .group-request-list article > span { flex-direction: column; } .people-profile-actions { grid-template-columns: 1fr; } .compose-emoji-panel > div { grid-template-columns: repeat(7, 1fr); } .compose-picker-header { grid-template-columns: 4rem minmax(0, 1fr) 4.5rem; } .compose-upload-page > main, .compose-forward-confirm { padding: 1rem; } .chat-product-timeline { padding: 1.25rem 1rem; } .chat-message-stack { max-width: calc(100% - 4rem); } .chat-bubble { font-size: 0.94rem; } .chat-file-card { min-width: min(17rem, calc(100vw - 6rem)); } .chat-contact-card { min-width: min(16rem, calc(100vw - 6rem)); } .chat-composer { padding-right: 0.4rem; padding-left: 0.4rem; } .chat-attachment-panel { grid-template-columns: repeat(4, 1fr); gap: 0.7rem; padding: 1rem 0.75rem max(1rem, env(safe-area-inset-bottom)); } .chat-attachment-panel button > span { width: 3.3rem; height: 3.3rem; } .messages-conversation { grid-template-columns: 3.55rem minmax(0, 1fr) auto; min-height: 4.8rem; padding-right: 1rem; padding-left: 1rem; } .messages-frequent-scroll { gap: 1rem; padding-right: 1rem; padding-left: 1rem; } .messages-frequent h2 { margin-left: 1rem; } .messages-search { margin-right: 1rem; margin-left: 1rem; } .system-notification-list { padding: 1rem; } .auth-landing { padding-right: 1.25rem; padding-left: 1.25rem; } .auth-brand { margin-bottom: 3rem; } .auth-content { padding: 1.25rem; } .auth-reset-content { padding: 1rem 0; } .auth-list-form { min-height: calc(100vh - 6.25rem); } .auth-list-form label { grid-template-columns: 6.4rem 1fr auto; } .auth-code-button { min-width: 5.8rem; padding: 0 0.4rem; } .auth-realname-hero { min-height: 12rem; padding: 1.5rem; } .auth-realname-hero strong { font-size: 2rem; } .auth-realname-hero > .material-icons { font-size: 6rem; } .auth-realname-content form { padding: 1.25rem; } .auth-realname-content label { grid-template-columns: 6.2rem 1fr; } .auth-screenshot-grid { grid-template-columns: repeat(3, 1fr); } #info-view { width: 100%; } /* Bottom sheet rather than a dialog */ .forward-dialog { border-radius: 0.3rem 0.3rem 0 0; margin: auto 0 0 0; width: 100%; } /* Must make it a bit visible on mobile because there is no :hover */ .menuTrigger { opacity: 0.3; } #send-message-input { /* Just an indicator that the screen is in mobile mode */ transition-property: -tinode-mobile; } #pinned-wrapper { height: 3.5rem; margin: 0.25rem; } .pinned { width: unset; } /* :not(.audio-minimized) -- same specificity (1,1,0) as #video-container.audio-minimized (4149 above), and this rule comes later in the file so it was winning even for a voice call's pill, stretching it into the same full-width box meant for the video floating window. */ #video-container.minimized:not(.audio-minimized) { flex-direction: row; left: 0; right: auto; top: var(--caption-panel-height); width: 100%; height: 11rem; border-radius: unset; box-shadow: 0 0 0.5rem var(--clr-shadow-gray-strong); } #controls.minimized { flex-direction: column; row-gap: 0.5rem; bottom: auto; column-gap: unset; right: 1rem; } .minimized .call-party { border-radius: unset; box-shadow: unset; } } /* .call-party.self's fullscreen self-preview (bottom-right corner) overlaps #controls' centered button row somewhere around 641px-750px: narrower than this and the row above already switches to the cramped mobile layout (with its own bottom:8.5rem clearance built in below); wider and #controls has enough room to stay clear of the preview on its own. 768px is comfortably past where the overlap was verified to stop, and is a common breakpoint already used elsewhere in this file. Kept as its own query (rather than folded into the 640px block above) since the rest of that block also restructures #video-container/#controls into an entirely different mobile layout that shouldn't kick in this early. */ @media (max-width: 768px) { .call-party.self { bottom: 8.5rem; border-radius: unset; } } /* Android personal profile, settings, privacy, youth mode and permissions. */ #sidepanel.personal-settings-panel { width: 100%; min-width: 0; flex: 1 1 auto; color-scheme: light; background: #f5f6f8; } .personal-settings-panel * { box-sizing: border-box; letter-spacing: 0; } .personal-page { display: flex; position: relative; width: 100%; min-height: 100%; overflow: hidden; color: #262b31; background: #f5f6f8; flex-direction: column; } .personal-page > .personal-page { min-height: 0; flex: 1 1 auto; } .personal-page button, .personal-page input, .personal-page textarea { font: inherit; letter-spacing: 0; } .personal-page button { text-transform: none; } .personal-page > main { min-height: 0; overflow-y: auto; flex: 1 1 auto; } .personal-header { display: grid; grid-template-columns: 3.7rem minmax(0, 1fr) 3.7rem; align-items: center; min-height: 4.5rem; padding-top: env(safe-area-inset-top); border-bottom: 1px solid #e7e9ec; background: #fff; flex: none; } .personal-header h1 { min-width: 0; margin: 0; overflow: hidden; font-size: 1.15rem; font-weight: 650; text-align: center; text-overflow: ellipsis; white-space: nowrap; } .personal-header button { display: grid; place-items: center; width: 3.7rem; min-width: 3.7rem; height: 3.7rem; min-height: 3.7rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #252a30; background: transparent; } .personal-header button.text { color: #2873d0; font-size: 0.9rem; } .personal-header .material-icons { font-size: 1.55rem; } .personal-toast { position: fixed; z-index: 90; bottom: max(1.5rem, env(safe-area-inset-bottom)); left: 50%; max-width: calc(100% - 2rem); padding: 0.7rem 1rem; border-radius: 0.3rem; color: #fff; background: rgba(25,29,34,0.94); text-align: center; transform: translateX(-50%); } .personal-center-page > main { padding: 0.85rem 0; } .personal-center-page section, .personal-menu-section, .android-settings-list section, .privacy-list section { margin-bottom: 0.75rem; background: #fff; } .personal-identity { display: grid; grid-template-columns: 4.5rem minmax(0, 1fr) 1.5rem; align-items: center; gap: 0.8rem; width: calc(100% - 1.6rem); min-height: 7rem; margin: 0 0.8rem 0.8rem; padding: 0.9rem; border: 0; border-radius: 0.45rem; box-shadow: none; color: #2e3339; background: #fff; text-align: left; } .personal-identity img { width: 4.5rem; height: 4.5rem; border-radius: 0.55rem; object-fit: cover; } /* No-avatar fallback: docs/images/我的.png only shows the real-photo state, so this is sized/shaped to match `.personal-identity img` above rather than copied from a reference. Specificity has to beat `.personal-identity span` below (class+element vs. this rule's two classes) or that rule's `display: block` wins and silently drops the centering, leaving a tiny uncentered icon glyph -- same bug, and same fix, as .workbench-avatar-fallback. */ .personal-identity .personal-avatar-fallback { display: flex; align-items: center; justify-content: center; width: 4.5rem; height: 4.5rem; border-radius: 0.55rem; color: #fff; background: #b0b6bd; } .personal-identity .personal-avatar-fallback .material-icons { font-size: 2rem; } .personal-identity span, .personal-identity strong, .personal-identity small { display: block; min-width: 0; } .personal-identity strong { margin-bottom: 0.35rem; overflow: hidden; font-size: 1.25rem; text-overflow: ellipsis; white-space: nowrap; } .personal-identity small { margin-top: 0.15rem; color: #8a919a; } .personal-menu-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 0.65rem; width: 100%; min-height: 4rem; margin: 0; padding: 0.65rem 1rem; border: 0; border-bottom: 1px solid #eceef1; border-radius: 0; box-shadow: none; color: #30353b; background: #fff; text-align: left; } .personal-menu-row:has(> .material-icons:first-child) { grid-template-columns: 2.3rem minmax(0, 1fr) auto; } .personal-menu-row:last-child { border-bottom: 0; } /* The generic button:hover/button:active rule (base.css ~2027) forces color to --clr-bright (white) on every , assuming a dark hover background -- true for .primary/.danger/.positive (already white text) but not for a plain white row like this one, where it silently turns the label invisible (white text on the still-white/light-gray hover background). Restate the row's own text color on hover/active, and add a visible (if subtle) background shift so hovering isn't a no-op. */ .personal-menu-row:hover:not([disabled]), .personal-menu-row:active:not([disabled]) { color: #30353b; background: var(--clr-menu-item-hover-bg); } /* Overrides the generic button.danger (solid red background, meant for standalone confirm/cancel buttons) that this row would otherwise inherit just for reusing the "danger" class as a semantic marker -- the design calls for a plain row (same background as every other row) with only the icon and label tinted red, not an alarming solid-red block. */ .personal-menu-row.danger, .personal-menu-row.danger:hover:not([disabled]), .personal-menu-row.danger:active:not([disabled]) { color: #d93f48; background: #fff; } .personal-menu-row.danger:hover:not([disabled]), .personal-menu-row.danger:active:not([disabled]) { background: var(--clr-menu-item-hover-bg); } .personal-menu-row.danger > .material-icons:first-child { color: #d93f48; } .personal-menu-row > .material-icons:first-child { color: #59636e; font-size: 1.55rem; } .personal-menu-row > .material-icons:last-child { color: #a8aeb5; } .personal-menu-row span { display: flex; align-items: center; justify-content: space-between; gap: 0.7rem; min-width: 0; } .personal-menu-row strong { min-width: 0; font-weight: 500; } .personal-menu-row small { max-width: 62%; overflow: hidden; color: #969da5; text-align: right; text-overflow: ellipsis; white-space: nowrap; } .personal-profile-list { padding-top: 0.7rem; background: #fff; } .personal-profile-list > button:first-child { display: grid; grid-template-columns: minmax(0, 1fr) 3.8rem 1.5rem; align-items: center; width: 100%; min-height: 5rem; margin: 0; padding: 0.6rem 1rem; border: 0; border-bottom: 1px solid #eceef1; border-radius: 0; box-shadow: none; color: #30353b; background: #fff; text-align: left; } .personal-profile-list > button:first-child img { width: 3.5rem; height: 3.5rem; border-radius: 0.45rem; object-fit: cover; } .gender-option-list { padding-top: 0.7rem; background: #fff; } .gender-option-list button { display: grid; grid-template-columns: minmax(0, 1fr) 1.5rem; align-items: center; width: 100%; min-height: 3.6rem; margin: 0; padding: 0.6rem 1rem; border: 0; border-bottom: 1px solid #eceef1; border-radius: 0; box-shadow: none; color: #30353b; background: #fff; text-align: left; } .gender-option-list button strong { font-weight: 400; } .gender-option-list button .material-icons { color: var(--clr-primary, #3b82f6); } .profile-editor-page > main { padding: 1rem; } .profile-editor-page > main > label { display: block; position: relative; } .profile-editor-page label input, .profile-editor-page label textarea { width: 100%; margin: 0; padding: 0.75rem 3rem 0.75rem 0.75rem; border: 1px solid #dbe0e5; border-radius: 0.35rem; box-shadow: none; background: #fff; } .profile-editor-page label input:not([type='date']) { height: 3.2rem; } .profile-editor-page label textarea { height: 11rem; padding-bottom: 2rem; resize: vertical; line-height: 1.5; } .profile-editor-page > main > label > small { position: absolute; right: 0.75rem; bottom: 0.65rem; color: #9ba2aa; } .profile-editor-page > main > label > button { position: absolute; top: 0.1rem; right: 2.7rem; display: grid; place-items: center; width: 2.8rem; min-width: 2.8rem; height: 3rem; min-height: 3rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #a3a9b0; background: transparent; } .profile-editor-page > main > p { margin: 0.65rem 0 0; color: #8a929b; font-size: 0.8rem; } .birth-date-editor { display: flex; align-items: center; padding-top: 4rem !important; flex-direction: column; } .birth-date-editor > .material-icons { color: #d66372; font-size: 4rem; } .birth-date-editor label { width: min(100%, 26rem); margin-top: 1.5rem; } .birth-date-editor label span { display: block; margin-bottom: 0.5rem; font-weight: 600; } .birth-date-editor label input { height: 3.2rem; padding: 0 0.75rem; } .personal-qr-page > main { padding: 1rem; } .personal-qr-page main > section { width: min(100%, 27rem); margin: 0 auto; padding: 1.2rem; border-radius: 0.45rem; background: #fff; text-align: center; } .personal-qr-profile { display: flex; align-items: center; gap: 0.7rem; text-align: left; } .personal-qr-profile img { width: 3.3rem; height: 3.3rem; border-radius: 0.4rem; object-fit: cover; } .personal-qr-profile span, .personal-qr-profile strong, .personal-qr-profile small { display: block; } .personal-qr-profile small { margin-top: 0.2rem; color: #858d96; } .personal-qrcode { display: inline-block; width: 226px; height: 226px; margin: 1.5rem auto 0.8rem; padding: 8px; border: 1px solid #eceef1; background: #fff; } .personal-qrcode img, .personal-qrcode canvas { width: 210px !important; height: 210px !important; } .personal-qr-page section > p { margin: 0.5rem 0; } .personal-qr-page section > small { color: #8d949d; } .personal-qr-actions { display: grid; grid-template-columns: repeat(2, 1fr); width: min(100%, 27rem); margin: 0.8rem auto 0; background: #fff; } .personal-qr-actions button { display: flex; align-items: center; justify-content: center; min-height: 3.4rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #3476cd; background: transparent; } .personal-qr-actions button + button { border-left: 1px solid #eceef1; } .personal-qr-actions .material-icons { margin-right: 0.3rem; } .android-settings-list { padding: 0.75rem 0 1.5rem; } .personal-logout { width: 100%; min-height: 3.8rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #d93f48; background: #fff; } .personal-sheet-backdrop, .update-backdrop, .permission-overlay { display: grid; position: absolute; z-index: 70; inset: 0; place-items: center; padding: 1rem; background: rgba(22,26,31,0.52); } .personal-confirm-sheet { width: min(100%, 25rem); padding: 1.25rem; border-radius: 0.5rem; background: #fff; text-align: center; } .personal-confirm-sheet > .material-icons { color: #4d73aa; font-size: 2.8rem; } .personal-confirm-sheet h2 { margin: 0.65rem 0; font-size: 1.15rem; } .personal-confirm-sheet p { margin: 0.7rem 0 1rem; color: #5c646e; line-height: 1.6; text-align: left; } .personal-confirm-sheet input { width: 100%; height: 3rem; margin: 0 0 0.8rem; padding: 0 0.75rem; border: 1px solid #dce0e5; border-radius: 0.35rem; box-shadow: none; text-align: center; } .personal-confirm-sheet button { width: 100%; min-height: 2.9rem; margin: 0.45rem 0 0; padding: 0 1rem; border: 0; border-radius: 0.35rem; box-shadow: none; color: #4d5660; background: #f0f2f4; } .personal-confirm-sheet button.primary { color: #fff; background: #347bd7; } .personal-confirm-sheet button.danger { color: #fff; background: #d84950; } .app-version-page > main { padding: 2rem 1rem; } .app-brand { margin-bottom: 2rem; text-align: center; } .app-brand > span { display: grid; place-items: center; width: 6.5rem; height: 6.5rem; margin: 0 auto 0.8rem; border-radius: 1.2rem; color: #fff; background: #2878d6; } .app-brand .material-icons { font-size: 4.2rem; } .app-brand h2, .app-brand p { margin: 0; } .app-brand h2 { font-size: 1.25rem; } .app-brand p { margin-top: 0.25rem; color: #777f89; } .update-dialog { width: min(100%, 25rem); padding: 1.3rem; border-radius: 0.55rem; background: #fff; text-align: center; } .update-dialog > span { display: grid; place-items: center; width: 5rem; height: 5rem; margin: 0 auto 0.8rem; border-radius: 50%; color: #fff; background: #4e74b7; } .update-dialog > span .material-icons { font-size: 3.2rem; } .update-dialog h2 { margin: 0; font-size: 1.35rem; } .update-dialog > strong { display: block; margin-top: 0.25rem; color: #69717b; } .update-dialog ul { margin: 1rem 0; padding-left: 1.25rem; color: #4e5660; line-height: 1.65; text-align: left; } .update-dialog button { width: 100%; min-height: 3rem; margin: 0.45rem 0 0; padding: 0 1rem; border: 0; border-radius: 0.35rem; box-shadow: none; color: #777f88; background: transparent; } .update-dialog button:first-of-type { color: #fff; background: #347bd7; } .privacy-list { padding-top: 0.75rem; } .privacy-list section > div { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 0.8rem; min-height: 4.6rem; padding: 0.7rem 1rem; border-bottom: 1px solid #eceef1; } .privacy-list section > div:last-child { border-bottom: 0; } .privacy-list section > div span, .privacy-list section > div strong, .privacy-list section > div small { display: block; min-width: 0; } .privacy-list section > div small { margin-top: 0.25rem; color: #8b929b; line-height: 1.35; } .personal-switch { position: relative; width: 3.25rem; min-width: 3.25rem; height: 1.9rem; min-height: 1.9rem; margin: 0; padding: 0; border: 0; border-radius: 1rem; box-shadow: none; background: #d8dce1; } /* 企业强制策略锁死的项(后端 privacy.editable 里为 false)要看得出是不可改的, 否则用户只会觉得开关点不动。 */ .personal-switch:disabled { opacity: 0.45; cursor: not-allowed; } .personal-switch i { position: absolute; top: 0.15rem; left: 0.15rem; width: 1.6rem; height: 1.6rem; border-radius: 50%; background: #fff; box-shadow: 0 1px 4px rgba(0,0,0,0.2); transition: transform 160ms ease; } .personal-switch.checked { background: #347bd7; } .personal-switch.checked i { transform: translateX(1.35rem); } .privacy-note { margin: 0; padding: 0 1rem 0.75rem; color: #7e8690; font-size: 0.82rem; line-height: 1.5; } .youth-mode-page { background: #fff; } .youth-mode-page > main { padding: 3.2rem 1.5rem 1rem; text-align: center; } .youth-mode-page > main > .material-icons { color: #347bd7; font-size: 5rem; } .youth-mode-page h2 { margin: 1rem 0 1.5rem; font-size: 1.45rem; } .youth-mode-page ul { margin: 0; padding: 0; list-style: none; text-align: left; } .youth-mode-page li { position: relative; margin-bottom: 1.2rem; padding-left: 1.7rem; line-height: 1.55; } .youth-mode-page li::before { position: absolute; top: 0.55rem; left: 0.2rem; width: 0.55rem; height: 0.55rem; border-radius: 50%; background: #347bd7; content: ''; } .youth-usage { margin-top: 1.8rem; color: #868e97; } .youth-mode-page > footer { padding: 0.8rem 1rem max(1rem, env(safe-area-inset-bottom)); background: #fff; text-align: center; flex: none; } .youth-mode-page > footer button { width: 100%; min-height: 3.2rem; margin: 0; padding: 0 1rem; border: 0; border-radius: 0.35rem; box-shadow: none; color: #fff; background: #347bd7; } .youth-mode-page > footer button.outline { border: 1px solid #347bd7; color: #347bd7; background: #fff; } .youth-mode-page > footer small { display: block; margin-top: 0.65rem; color: #9aa1a9; } .permission-guide-page { background: #fff; } .permission-preview { padding: 1.2rem 1rem; opacity: 0.72; } .permission-preview > header { display: flex; align-items: center; justify-content: space-between; } .permission-preview h1 { margin: 0; font-size: 1.35rem; } .permission-preview > label { display: flex; align-items: center; justify-content: center; min-height: 3rem; margin: 1rem 0; border-radius: 0.35rem; color: #8d949c; background: #f0f2f4; } .permission-preview > label .material-icons { margin-right: 0.35rem; } .permission-preview > div { display: grid; grid-template-columns: 3.4rem minmax(0, 1fr); align-items: center; gap: 0.7rem; min-height: 4.6rem; border-bottom: 1px solid #eceef1; } .permission-preview > div > span:last-child, .permission-preview > div strong, .permission-preview > div small { display: block; min-width: 0; } .permission-preview > div small { margin-top: 0.2rem; color: #8b929b; } .permission-avatar { display: grid; place-items: center; width: 3.1rem; height: 3.1rem; border-radius: 0.45rem; color: #fff; background: #5a77a9; } .permission-avatar.tone-0 { background: #d18128; } .permission-avatar.tone-1 { background: #4673bd; } .permission-avatar.tone-2 { background: #398258; } .permission-avatar.tone-3 { background: #9c5f7a; } .permission-overlay section { width: min(100%, 24rem); padding: 1.3rem; border-radius: 0.5rem; background: #fff; text-align: center; } .permission-overlay section > span { display: grid; place-items: center; width: 4.6rem; height: 4.6rem; margin: 0 auto 0.8rem; border-radius: 50%; color: #fff; background: #347bd7; } .permission-overlay section > span .material-icons { font-size: 2.7rem; } .permission-overlay h2 { margin: 0; font-size: 1.2rem; } .permission-overlay p { margin: 0.8rem 0 1rem; color: #555d67; line-height: 1.6; text-align: left; } .permission-overlay button { width: 100%; min-height: 3rem; margin: 0.4rem 0 0; padding: 0 1rem; border: 0; border-radius: 0.35rem; box-shadow: none; color: #8a919a; background: transparent; } .permission-overlay button:first-of-type { color: #fff; background: #347bd7; } @media screen and (max-width: 480px) { .personal-menu-row { min-height: 3.8rem; } .personal-menu-row small { max-width: 55%; } .personal-qrcode { margin-top: 1rem; } .youth-mode-page > main { padding-top: 2rem; } } /* Android anti-fraud warnings, abuse reports and user feedback. */ #sidepanel.security-support-panel { width: 100%; min-width: 0; flex: 1 1 auto; color-scheme: light; background: #f5f6f8; } .security-support-panel * { box-sizing: border-box; letter-spacing: 0; } .support-page { display: flex; position: relative; width: 100%; min-height: 100%; overflow: hidden; color: #272c32; background: #f5f6f8; flex-direction: column; } .support-page button, .support-page input, .support-page textarea { font: inherit; letter-spacing: 0; } .support-page button { text-transform: none; } .support-page > main { min-height: 0; overflow-y: auto; flex: 1 1 auto; } .support-header { display: grid; grid-template-columns: 3.7rem minmax(0, 1fr) 3.7rem; align-items: center; min-height: 4.5rem; padding-top: env(safe-area-inset-top); border-bottom: 1px solid #e6e9ec; background: #fff; flex: none; } .support-header h1 { min-width: 0; margin: 0; overflow: hidden; font-size: 1.15rem; font-weight: 650; text-align: center; text-overflow: ellipsis; white-space: nowrap; } .support-header button { display: grid; place-items: center; width: 3.7rem; min-width: 3.7rem; height: 3.7rem; min-height: 3.7rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #272c32; background: transparent; } .support-toast { position: fixed; z-index: 100; bottom: max(1.5rem, env(safe-area-inset-bottom)); left: 50%; max-width: calc(100% - 2rem); padding: 0.7rem 1rem; border-radius: 0.3rem; color: #fff; background: rgba(25,29,34,0.94); text-align: center; transform: translateX(-50%); } .risk-warning-page { background: #fff; } .risk-conversation-preview { min-height: 100%; opacity: 0.78; } .risk-conversation-preview > header { display: grid; grid-template-columns: 3.5rem minmax(0, 1fr) 3.5rem; align-items: center; min-height: 4.5rem; padding-top: env(safe-area-inset-top); border-bottom: 1px solid #e7e9ec; background: #fff; text-align: center; } .risk-conversation-preview > header button { display: grid; place-items: center; width: 3.5rem; height: 3.5rem; margin: 0; padding: 0; border: 0; box-shadow: none; background: transparent; } .risk-conversation-preview > header span, .risk-conversation-preview > header strong, .risk-conversation-preview > header small { display: block; } .risk-conversation-preview > header small { margin-top: 0.15rem; color: #3d9a68; } .risk-conversation-preview > main { min-height: calc(100vh - 8.8rem); padding: 1rem; background: #eef0f3; } .risk-conversation-preview > main > p { margin: 0 0 1rem; color: #8b929b; font-size: 0.75rem; text-align: center; } .risk-conversation-preview main > div { width: fit-content; max-width: 78%; margin-bottom: 0.65rem; padding: 0.7rem 0.85rem; border-radius: 0.35rem; background: #fff; line-height: 1.5; } .risk-conversation-preview main > div.mine { margin-left: auto; background: #bde7a9; } .risk-conversation-preview > footer { display: flex; align-items: center; justify-content: space-between; min-height: 4.3rem; padding: 0.6rem 1rem max(0.6rem, env(safe-area-inset-bottom)); border-top: 1px solid #e0e3e7; color: #959ca5; background: #fff; } .risk-conversation-preview > footer span { width: calc(100% - 2.7rem); padding: 0.65rem 0.75rem; border: 1px solid #e0e3e7; border-radius: 0.3rem; background: #f7f8f9; } .risk-overlay { display: grid; position: absolute; z-index: 70; inset: 0; place-items: center; padding: 1rem; background: rgba(19,23,28,0.55); } .risk-dialog { width: min(100%, 25rem); max-height: calc(100% - 2rem); padding: 1.15rem; overflow-y: auto; border-radius: 0.55rem; background: #fff; text-align: center; } /* .risk-dialog was designed as a modal card, centered by .risk-overlay's place-items:center wrapper (RiskConfirmDialog). FraudAwareness reuses the same class directly as .support-page's (no overlay wrapper, no explicit height on the page unlike a modal) to pick up its ul/li/aside/button styling -- but .support-page is a plain flex column with no centering of its own, so the capped width left the whole page pinned to the left edge on anything wider than ~25rem instead of centered like every other support-page/group-page/people-page in the app. */ .risk-info-page { margin: 0 auto; } .risk-symbol { display: grid; place-items: center; width: 5rem; height: 5rem; margin: 0 auto 0.6rem; border-radius: 50%; color: #fff; background: #3979cd; } .risk-dialog.secondary .risk-symbol { color: #9b5e08; background: #fff0d5; } .risk-symbol .material-icons { font-size: 3.2rem; } .risk-dialog h2 { margin: 0; font-size: 1.35rem; } .risk-dialog > p { margin: 0.75rem 0; color: #4d555e; line-height: 1.65; text-align: left; } .risk-dialog > p.risk-emphasis { color: #b1363f; font-weight: 650; text-align: center; } .risk-dialog ul { margin: 0.9rem 0; padding: 0.25rem 0.75rem; border: 1px solid #d9e5f4; border-radius: 0.4rem; list-style: none; } .risk-dialog li { display: flex; align-items: center; min-height: 2.7rem; border-bottom: 1px solid #e7edf4; line-height: 1.35; text-align: left; } .risk-dialog li:last-child { border-bottom: 0; } .risk-dialog li .material-icons { margin-right: 0.55rem; color: #347bd7; font-size: 1.35rem; } .risk-dialog aside { display: flex; align-items: flex-start; gap: 0.5rem; margin: 0.8rem 0; padding: 0.7rem; border-radius: 0.35rem; color: #9e333b; background: #fff0f1; line-height: 1.45; text-align: left; } .risk-dialog button { width: 100%; min-height: 3rem; margin: 0.45rem 0 0; padding: 0 0.75rem; border: 0; border-radius: 0.35rem; box-shadow: none; color: #7f8790; background: transparent; } .risk-dialog button.primary { color: #fff; background: #347bd7; } .risk-dialog button.danger { color: #fff; background: #cc3d46; } .report-reasons { padding-bottom: 1rem; } .report-target { display: grid; grid-template-columns: 3.5rem minmax(0, 1fr) 2rem; align-items: center; gap: 0.75rem; min-height: 5.3rem; padding: 0.8rem 1rem; background: #fff; } .report-target img { width: 3.5rem; height: 3.5rem; border-radius: 0.45rem; object-fit: cover; } .report-target span, .report-target strong, .report-target small { display: block; min-width: 0; } .report-target small { margin-top: 0.25rem; color: #818a94; } .report-target > .material-icons { color: #3b8661; } .report-reasons > h2 { margin: 0; padding: 1rem; color: #6e7781; font-size: 0.85rem; font-weight: 500; } .report-loading { margin: 0; padding: 1rem; color: #6e7781; font-size: 0.85rem; } .report-reason-list { background: #fff; } .report-reason-list button { display: grid; grid-template-columns: 2.8rem minmax(0, 1fr) 1.5rem; align-items: center; gap: 0.55rem; width: 100%; min-height: 4.3rem; margin: 0; padding: 0.65rem 1rem; border: 0; border-bottom: 1px solid #eceef1; border-radius: 0; box-shadow: none; color: #30353c; background: #fff; text-align: left; } .report-reason-list button > span:first-child { display: grid; place-items: center; width: 2.5rem; height: 2.5rem; border-radius: 0.4rem; color: #fff; background: #4d70a8; } .report-reason-list button > span:nth-child(2), .report-reason-list strong, .report-reason-list small { display: block; min-width: 0; } .report-reason-list small { margin-top: 0.2rem; overflow: hidden; color: #858d97; font-size: 0.76rem; text-overflow: ellipsis; white-space: nowrap; } .report-reason-list button > .material-icons:last-child { color: #a8aeb5; } .report-details, .feedback-page > main { padding-bottom: 1rem; } .report-selected-reason { display: grid; grid-template-columns: 2.7rem minmax(0, 1fr) auto; align-items: center; gap: 0.7rem; padding: 0.9rem 1rem; background: #fff; } .report-selected-reason > .material-icons { color: #b14650; font-size: 2rem; } .report-selected-reason span, .report-selected-reason strong, .report-selected-reason small { display: block; min-width: 0; } .report-selected-reason small { margin-bottom: 0.2rem; color: #858d96; } .report-selected-reason button { min-height: 2.5rem; margin: 0; padding: 0 0.5rem; border: 0; box-shadow: none; color: #3476ce; background: transparent; } .support-textarea { display: block; position: relative; margin-top: 0.7rem; padding: 1rem; background: #fff; } .support-textarea > span { display: block; margin-bottom: 0.6rem; font-weight: 600; } .support-textarea b { margin-left: 0.2rem; color: #d6424b; } .support-textarea textarea { display: block; width: 100%; height: 10.5rem; margin: 0; padding: 0.75rem 0.8rem 2rem; resize: vertical; border: 1px solid #dfe3e7; border-radius: 0.35rem; box-shadow: none; background: #fff; line-height: 1.5; } .support-textarea > small { position: absolute; right: 1.8rem; bottom: 1.6rem; color: #9ba2ab; } .evidence-section, .feedback-upload { margin-top: 0.7rem; padding: 1rem; background: #fff; } .evidence-section > header, .feedback-upload > header { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; margin-bottom: 0.8rem; } .evidence-section header span, .evidence-section header strong, .evidence-section header small, .feedback-upload header span, .feedback-upload header strong, .feedback-upload header small { display: block; min-width: 0; } .evidence-section header small, .feedback-upload header small { margin-top: 0.2rem; color: #858d96; } .evidence-section header em, .feedback-upload header em { color: #858d96; font-style: normal; } .evidence-section article { display: grid; grid-template-columns: 2.5rem minmax(0, 1fr) 2.5rem; align-items: center; min-height: 3.5rem; border-bottom: 1px solid #eceef1; } .evidence-section article > .material-icons { color: #5273a8; } .evidence-section article > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .evidence-section article button { display: grid; place-items: center; width: 2.5rem; height: 2.5rem; margin: 0; padding: 0; border: 0; box-shadow: none; color: #989fa7; background: transparent; } .evidence-upload, .feedback-upload > button { display: flex; align-items: center; justify-content: center; width: 100%; min-height: 4.5rem; margin: 0; padding: 0.7rem; border: 1px dashed #cbd1d8; border-radius: 0.35rem; box-shadow: none; color: #3476ce; background: #f8f9fa; flex-direction: column; } .evidence-upload .material-icons, .feedback-upload > button .material-icons { margin-bottom: 0.25rem; font-size: 1.8rem; } .report-privacy-note { display: flex; align-items: flex-start; gap: 0.5rem; margin: 0.8rem 1rem 0; color: #74808b; font-size: 0.78rem; line-height: 1.45; } .report-privacy-note .material-icons { color: #4b8065; font-size: 1.05rem; } .support-submit-bar { padding: 0.75rem 1rem max(0.8rem, env(safe-area-inset-bottom)); border-top: 1px solid #e1e4e8; background: #fff; flex: none; } .support-submit-bar button, .support-success > button { width: 100%; min-height: 3.1rem; margin: 0; padding: 0 1rem; border: 0; border-radius: 0.35rem; box-shadow: none; color: #fff; background: #347bd7; font-weight: 600; } .support-success { display: flex; align-items: center; padding: 4rem 1.2rem 1.5rem; text-align: center; flex-direction: column; } .support-success > .material-icons { color: #3a9365; font-size: 5rem; } .support-success h2 { margin: 1rem 0 0.55rem; font-size: 1.35rem; } .support-success > p { max-width: 26rem; margin: 0; color: #66707a; line-height: 1.6; } .support-success dl { width: min(100%, 26rem); margin: 1.5rem 0; padding: 0.5rem 1rem; border: 1px solid #e0e4e8; border-radius: 0.4rem; background: #fff; } .support-success dl > div { display: flex; align-items: center; justify-content: space-between; min-height: 3rem; border-bottom: 1px solid #eceef1; } .support-success dl > div:last-child { border-bottom: 0; } .support-success dt, .support-success dd { margin: 0; } .support-success dt { color: #7c858f; } .support-success > button { width: min(100%, 26rem); } .feedback-categories { padding: 1rem; background: #fff; } .feedback-categories h2 { margin: 0 0 0.8rem; font-size: 1rem; } .feedback-categories > div { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.55rem; } .feedback-categories button { /* docs/images/意见反馈.png has no category selector at all (server/im_http.go's `category` field is real and required, but the design was never drawn for it -- same "no reference, add the simplest reasonable UI" call as Ch.6's own-group-nickname editor). This card layout (flex column, tall min-height) was carried over from an icon-above-label grid pattern used elsewhere, but this button only ever renders a single line of plain text -- with no `justify-content` set, `column` direction defaults the main axis to `flex-start`, pinning that one line to the top of a much taller box instead of centering it, which is the "why does this look off" of it. Simplified to a plain centered pill sized for the text it actually holds. */ display: flex; align-items: center; justify-content: center; min-width: 0; min-height: 2.75rem; margin: 0; padding: 0.45rem; border: 1px solid #e0e4e8; border-radius: 0.35rem; box-shadow: none; color: #666f79; background: #fff; } .feedback-categories button.active { border-color: #347bd7; color: #2f70c7; background: #eef5ff; } .feedback-categories .material-icons { margin-bottom: 0.25rem; font-size: 1.45rem; } .feedback-categories button span { width: 100%; overflow-wrap: anywhere; font-size: 0.76rem; line-height: 1.25; text-align: center; } .feedback-contact { display: block; padding: 1rem; background: #fff; } .feedback-contact > span { display: block; margin-bottom: 0.55rem; font-weight: 600; } .feedback-contact input { width: 100%; height: 3rem; margin: 0; padding: 0 0.75rem; border: 1px solid #dfe3e7; border-radius: 0.35rem; box-shadow: none; background: #fff; } .diagnostics-consent { display: grid; grid-template-columns: 1.8rem minmax(0, 1fr); align-items: flex-start; gap: 0.5rem; margin-top: 0.7rem; padding: 1rem; background: #fff; } .diagnostics-consent input { width: 1.25rem; height: 1.25rem; margin: 0.1rem 0 0; } .diagnostics-consent span, .diagnostics-consent strong, .diagnostics-consent small { display: block; min-width: 0; } .diagnostics-consent small { margin-top: 0.3rem; color: #7e8791; line-height: 1.45; } @media screen and (max-width: 480px) { .risk-dialog { padding: 1rem; } .risk-symbol { width: 4.3rem; height: 4.3rem; } .risk-symbol .material-icons { font-size: 2.8rem; } .feedback-categories > div { gap: 0.35rem; } } /* QR scanning ("扫一扫"): full-screen camera view + the post-scan group-join confirm sheet. No reference screenshot covers the scanning viewfinder itself (docs/images/ only has the generate-a-code screens) -- z-index 200 matches the call overlays (widgets/call-panel.jsx), the only other feature that also needs to sit above every other full-screen surface. */ .qr-scan-view { position: fixed; z-index: 200; inset: 0; overflow: hidden; background: #000; } .qr-scan-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; } .qr-scan-mask { position: absolute; inset: 0; display: grid; place-items: center; } .qr-scan-frame { position: relative; width: 62vw; max-width: 17rem; aspect-ratio: 1; border-radius: 0.5rem; box-shadow: 0 0 0 999rem rgba(0,0,0,0.5); } .qr-scan-corner { position: absolute; width: 1.6rem; height: 1.6rem; border: 0.22rem solid #4d8dff; font-style: normal; } .qr-scan-corner-tl { top: -0.11rem; left: -0.11rem; border-right: 0; border-bottom: 0; border-radius: 0.4rem 0 0 0; } .qr-scan-corner-tr { top: -0.11rem; right: -0.11rem; border-left: 0; border-bottom: 0; border-radius: 0 0.4rem 0 0; } .qr-scan-corner-bl { bottom: -0.11rem; left: -0.11rem; border-right: 0; border-top: 0; border-radius: 0 0 0 0.4rem; } .qr-scan-corner-br { bottom: -0.11rem; right: -0.11rem; border-left: 0; border-top: 0; border-radius: 0 0 0.4rem 0; } .qr-scan-header { position: absolute; z-index: 2; top: 0; left: 0; right: 0; display: flex; align-items: center; justify-content: space-between; padding: 0.9rem 0.5rem; background: linear-gradient(rgba(0,0,0,0.45), transparent); } .qr-scan-header button { width: 2.6rem; height: 2.6rem; border: 0; box-shadow: none; color: #fff; background: transparent; } .qr-scan-header h1 { margin: 0; color: #fff; font-size: 1.05rem; font-weight: 500; } .qr-scan-header span { width: 2.6rem; } .qr-scan-hint { position: absolute; left: 0; right: 0; bottom: 14%; margin: 0; color: #e7ebf0; font-size: 0.9rem; text-align: center; } .qr-scan-error { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.6rem; padding: 0 2rem; color: #fff; text-align: center; } .qr-scan-error .material-icons { font-size: 2.6rem; color: #f2b53d; } .qr-scan-error button { margin-top: 0.6rem; padding: 0 1.4rem; min-height: 2.6rem; border: 0; border-radius: 1.4rem; box-shadow: none; color: #fff; background: #347bd7; } .qr-join-backdrop { position: fixed; z-index: 200; inset: 0; display: grid; place-items: center; padding: 1rem; background: rgba(22,26,31,0.52); } .qr-join-sheet { width: min(100%, 25rem); padding: 1.4rem 1.25rem 1.25rem; border-radius: 0.5rem; background: #fff; text-align: center; } .qr-join-avatar { display: grid; place-items: center; width: 4rem; height: 4rem; margin: 0 auto 0.6rem; border-radius: 50%; overflow: hidden; color: #9aa3ad; background: #eef1f4; } .qr-join-avatar img { width: 100%; height: 100%; object-fit: cover; } .qr-join-avatar .material-icons { font-size: 1.9rem; } .qr-join-sheet h2 { margin: 0.2rem 0; font-size: 1.1rem; } .qr-join-sheet > p { margin: 0 0 0.9rem; color: #757d87; } .qr-join-sheet input { width: 100%; height: 2.9rem; margin: 0 0 0.8rem; padding: 0 0.75rem; border: 1px solid #dce0e5; border-radius: 0.35rem; box-shadow: none; text-align: center; } .qr-join-sheet button { width: 100%; min-height: 2.9rem; margin: 0.45rem 0 0; border: 0; border-radius: 0.35rem; box-shadow: none; color: #4d5660; background: #f0f2f4; } .qr-join-sheet button.primary { color: #fff; background: #347bd7; } /* 合并转发卡片(widgets/forward-bundle.jsx,第4章 4.20)。 服务端 mode="bundle" 生成的消息不是 Drafty,单独渲染成一张可展开的"聊天记录"卡片。 */ .forward-bundle { min-width: 11rem; max-width: 18rem; } .forward-bundle-title { margin-bottom: 0.35rem; font-weight: 500; } .forward-bundle-lines { margin: 0; padding: 0; list-style: none; } .forward-bundle-lines li { overflow: hidden; margin: 0.15rem 0; color: var(--clr-text-secondary); font-size: 0.85rem; line-height: 1.35; text-overflow: ellipsis; white-space: nowrap; } .forward-bundle-lines li b { font-weight: 500; } .forward-bundle-more, .forward-bundle-count { display: block; width: 100%; margin: 0.4rem 0 0; padding: 0.35rem 0 0; border: 0; border-top: 1px solid var(--clr-divider, #e7e9ec); border-radius: 0; box-shadow: none; background: none; color: var(--clr-text-secondary); font-size: 0.8rem; line-height: 1.3; text-align: left; text-transform: none; } .forward-bundle-more { color: #347bd7; cursor: pointer; } .forward-bundle-comment { margin-top: 0.4rem; color: var(--clr-text-primary); font-size: 0.85rem; }