snapshot of https://github.com/zulip/zulip.git @ 48c69911c7dd4e03b20552eb3bd77ad8151c1357 (2026-09-15)
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled

This commit is contained in:
upstream-mirror
2026-09-15 15:05:30 +05:00
commit 64898b2c79
8999 changed files with 1757358 additions and 0 deletions

View File

@@ -0,0 +1,593 @@
.activity-page {
margin: 10px;
}
.activity-head {
background-color: hsl(208deg 100% 97%);
position: sticky;
top: 0;
& th {
border-bottom: 1px solid hsl(0deg 0% 87%);
}
}
.activity-foot {
background-color: hsl(208deg 100% 97%);
font-weight: 700;
position: sticky;
bottom: 0;
}
.table-striped {
& tr.recently_active {
& td {
background-color: hsl(120deg 97% 83%);
}
&:nth-child(odd) td {
background-color: hsl(120deg 70% 76%);
}
}
}
.installation-activity-filter-container {
width: fit-content;
border-radius: 4px;
background-color: hsl(0deg 0% 92%);
border: 1px solid hsl(0deg 0% 68%);
padding: 0 8px;
margin: 8px;
}
.summary-table,
.analytics-table {
border: 1px solid hsl(0deg 0% 87%);
border-collapse: separate;
border-left: 0;
border-radius: 4px;
border-spacing: 0;
margin: 0 10px;
& th,
td {
border-left: 1px solid hsl(0deg 0% 87%);
text-align: left;
&.number {
text-align: right;
}
}
th {
vertical-align: bottom;
padding: 8px;
}
td {
border-top: 1px solid hsl(0deg 0% 87%);
white-space: nowrap;
padding: 2px 8px;
max-width: 320px;
overflow: hidden;
text-overflow: ellipsis;
}
tbody > tr:nth-child(odd) > td {
background-color: hsl(0deg 0% 98%);
}
tbody tr:first-child td {
border-top: 0;
}
thead tr:first-child > th:first-child {
border-top-left-radius: 4px;
}
thead tr:first-child > th:last-child {
border-top-right-radius: 4px;
}
tbody tr:last-child > td:first-child {
border-bottom-left-radius: 4px;
}
tbody tr:last-child > td:last-child {
border-bottom-right-radius: 4px;
}
thead tr:first-child th {
border-top: 0;
}
}
tr.admin td:first-child {
font-weight: bold;
color: hsl(240deg 100% 50%);
font-size: 110%;
}
.good {
font-weight: bold;
color: hsl(120deg 100% 33%);
}
.bad {
font-weight: bold;
color: hsl(0deg 100% 39%);
}
.support-query-result,
.remote-support-query-result {
background-color: hsl(60deg 12% 94%);
padding: 10px;
border-radius: 7px;
box-shadow: 0 10px 7px -6px hsl(0deg 2% 45%);
margin-bottom: 10px;
& select {
height: 30px;
width: 220px;
padding: 0 6px;
font-size: 14px;
color: hsl(0deg 0% 33%);
border-radius: 4px;
border: 1px solid hsl(0deg 0% 80%);
cursor: pointer;
background-color: hsl(0deg 0% 100%);
vertical-align: text-bottom;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
&:focus {
outline: 1px dotted hsl(0deg 0% 20%);
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
}
& input {
width: 206px;
padding: 4px 6px;
border-radius: 4px;
border: 1px solid hsl(0deg 0% 80%);
color: hsl(0deg 0% 33%);
vertical-align: text-bottom;
transition:
border-color linear 0.2s,
box-shadow linear 0.2s;
box-shadow: inset 0 1px 1px hsl(0deg 0% 0% / 7.5%);
&:focus {
border-color: hsl(206deg 80% 62% / 80%);
outline: 0;
box-shadow:
inset 0 1px 1px hsl(0deg 0% 0% / 7.5%),
0 0 8px hsl(206.494deg 80% 62% / 60%);
}
}
.demo-label,
.cloud-label,
.deactivated-label,
.remote-label {
padding: 4px 8px 0;
font-size: 0.9em;
font-weight: bold;
color: hsl(0deg 0% 100%);
text-shadow: 0 -1px 0 hsl(0deg 0% 0% / 25%);
border-radius: 3px;
}
.demo-label {
background-color: hsl(0deg 0% 0%);
}
.cloud-label {
background-color: hsl(280deg 100% 40%);
}
.deactivated-label {
background-color: hsl(2deg 64% 53%);
}
.remote-label {
background-color: hsl(186deg 76% 36%);
}
.current-audit-log {
color: hsl(123deg 46% 34%);
}
.current-plan-data-missing,
.stale-audit-log {
color: hsl(2deg 64% 53%);
}
}
.realm-management-actions {
#new_subdomain {
width: 225px;
}
.support-add-redirect-url-section {
display: block;
padding: 6px 10px;
#add_redirect_url {
width: auto;
}
.support-redirect-url-label {
display: inline;
}
}
}
.reactivate-remote-server-button,
.deactivate-remote-server-button,
.delete-next-fixed-price-plan-button,
.approve-sponsorship-button,
.support-search-button,
.support-submit-button,
.delete-user-button,
.scrub-realm-button {
padding: 6px 12px;
display: inline-block;
margin-bottom: 0;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
font-weight: normal;
line-height: 1.4286;
text-align: center;
white-space: nowrap;
vertical-align: text-bottom;
cursor: pointer;
user-select: none;
background-image: none;
&:hover,
&:focus {
text-decoration: none;
}
&:focus {
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
&:active {
background-image: none;
outline: 0;
}
&[disabled] {
pointer-events: none;
cursor: not-allowed;
opacity: 0.65;
}
}
.deactivate-remote-server-button {
margin-top: 6px;
}
.support-search-form {
margin: 10px;
}
.support-search-button {
vertical-align: middle;
margin: 10px;
}
.approve-sponsorship-button {
vertical-align: middle;
color: hsl(123deg 46% 34%);
background-color: hsl(114deg 25% 85%);
border: 1px solid hsl(123deg 46% 34%);
border-radius: 2px;
&:hover,
&:focus,
&:active {
color: hsl(123deg 50% 30%);
background-color: hsl(114deg 28% 82%);
border: 1px solid hsl(123deg 50% 30%);
}
}
.support-search-button,
.support-submit-button {
color: hsl(0deg 0% 20%);
background-color: hsl(0deg 0% 100%);
border: 1px solid hsl(0deg 0% 83%);
border-radius: 2px;
&:hover,
&:focus,
&:active {
color: hsl(0deg 0% 20%);
background-color: hsl(0deg 0% 92%);
border: 1px solid hsl(0deg 0% 68%);
}
}
.deactivate-remote-server-button,
.delete-next-fixed-price-plan-button,
.delete-user-button,
.scrub-realm-button {
color: hsl(0deg 0% 100%);
background-color: hsl(2deg 64% 58%);
border: 1px solid hsl(2deg 64% 53%);
border-radius: 2px;
&:hover,
&:focus,
&:active {
color: hsl(0deg 0% 100%);
background-color: hsl(2deg 65% 50%);
border: 1px solid hsl(2deg 65% 41%);
}
}
.reactivate-remote-server-button {
color: hsl(0deg 0% 100%);
background-color: hsl(35deg 70% 56%);
border: 1px solid hsl(35deg 70% 50%);
border-radius: 2px;
&:hover,
&:focus,
&:active {
color: hsl(0deg 0% 100%);
background-color: hsl(35deg 82% 40%);
border: 1px solid hsl(35deg 82% 30%);
}
}
.reactivate-remote-server-button,
.deactivate-remote-server-button {
font-size: 15px;
line-height: 1.8;
max-width: 550px;
overflow: hidden;
text-overflow: ellipsis;
}
.user-information-section.user-deactivated,
.user-realm-information-section.realm-deactivated,
.support-query-result.realm-deactivated {
background-color: hsl(22deg 100% 92%);
}
.remote-support-query-result.remote-server-deactivated {
background-color: hsl(2deg 64% 58%);
.remote-server-section {
background-color: hsl(22deg 100% 92%);
}
.remote-realms-section {
background-color: hsl(23deg 100% 95%);
}
}
.delete-next-fixed-price-plan-form,
.delete-user-form {
margin: 8px 0;
}
.installation-activity-header {
text-align: center;
}
.support-section-header {
font-size: 1.2em;
font-weight: bold;
line-height: 20px;
margin: 0 0 8px;
}
.support-realm-icon {
max-width: 25px;
position: relative;
vertical-align: middle;
top: -2px;
}
.reactivate-remote-server-form,
.deactivate-remote-server-form,
.realm-support-information,
.remote-server-information,
.remote-realm-information,
.remote-sponsorship-details,
.support-form,
.next-plan-information,
.current-plan-information {
margin-bottom: 10px;
}
.scrub-realm-form {
padding-top: 10px;
}
.search-query.input-xxlarge {
width: 530px;
padding: 4px 14px;
margin-bottom: 0;
border-radius: 8px;
border: 1px solid hsl(0deg 0% 80%);
box-shadow: inset 0 1px 1px hsl(0deg 0% 0% / 7.5%);
transition:
border-color linear 0.2s,
box-shadow linear 0.2s;
color: hsl(0deg 0% 33%);
&:focus {
border-color: hsl(206deg 80% 62% / 80%);
outline: 0;
box-shadow:
inset 0 1px 1px hsl(0deg 0% 0% / 7.5%),
0 0 8px hsl(206.494deg 80% 62% / 60%);
}
}
@media (width <= 767px) {
.search-query.input-xxlarge {
width: 100%;
}
}
.remote-support-query-result {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: minmax(100px, auto);
grid-template-areas: "server realms";
}
.remote-server-section {
grid-area: server;
}
.remote-realms-section {
grid-area: realms;
}
.user-support-container {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: minmax(100px, auto);
grid-template-areas: "realm user";
}
.user-information-section {
grid-area: user;
}
.user-realm-information-section {
grid-area: realm;
}
.confirmation-container {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: minmax(100px, auto);
grid-template-areas: "confirmation-realm confirmation";
}
.confirmation-information-section {
grid-area: confirmation;
}
.confirmation-realm-section {
grid-area: confirmation-realm;
}
.confirmation-information-section,
.confirmation-realm-section,
.user-information-section,
.user-realm-information-section,
.remote-realms-section,
.remote-server-section {
border: 2px solid hsl(330deg 3% 40%);
border-radius: 4px;
padding: 10px;
}
.confirmation-realm-section,
.user-realm-information-section,
.remote-server-section {
background-color: hsl(60deg 11% 86%);
}
.confirmation-information-section,
.user-information-section,
.remote-realms-section {
background-color: hsl(60deg 12% 90%);
}
.remote-realm-container {
padding-bottom: 25px;
}
.deactivation-information-container,
.activity-header-information,
.push-notification-status,
.realm-management-actions,
.next-plan-container,
.current-plan-container,
.support-sponsorship-container {
border-radius: 4px;
padding: 10px;
margin: 10px 0;
}
.activity-header-information {
border: 2px solid hsl(330deg 3% 40%);
background-color: hsl(60deg 12% 90%);
width: fit-content;
}
.activity-header-entry {
margin: 0;
padding: 2px 0;
}
.push-notification-status,
.realm-management-actions {
border: 2px solid hsl(186deg 76% 36%);
background-color: hsl(188deg 35% 87%);
}
.deactivation-information-container {
border: 2px solid hsl(2deg 64% 58%);
background-color: hsl(23deg 100% 95%);
}
.next-plan-container,
.current-plan-container,
.support-sponsorship-container {
border: 2px solid hsl(33deg 99% 60%);
}
.support-sponsorship-container {
background-color: hsl(30deg 100% 96%);
}
.next-plan-container {
background-color: hsl(31deg 100% 91%);
}
.current-plan-container {
background-color: hsl(31deg 100% 83%);
}
.discounted-price-form {
display: flex;
flex-direction: column;
gap: 5px;
align-items: flex-start;
.support-submit-button {
margin-top: 5px;
}
}
.container {
width: 940px;
margin-right: auto;
margin-left: auto;
@media (width <= 767px) {
width: auto;
}
@media (767px < width <= 979px) {
width: 724px;
}
@media (width >= 1180px) {
width: 1170px;
}
}

View File

@@ -0,0 +1,752 @@
.billing-upgrade-page {
font-family: "Source Sans 3 VF", sans-serif;
background-color: hsl(0deg 0% 98%);
height: 100vh;
.page-content {
padding: 100px 0 30px;
}
.main {
width: 800px;
max-width: 90%;
margin: 0 auto;
}
& h1 {
margin: 30px 0;
font-weight: bold;
}
.nav {
margin-bottom: 0;
}
.support-link {
margin: 10px 20px;
& a,
a:hover,
a:visited {
color: hsl(170deg 47% 33%);
font-weight: 400;
}
}
.license-management,
.payment-schedule {
& label {
display: inline-block;
}
& input[type="radio"] {
display: none;
&:checked {
+ .box {
background-color: hsl(153deg 32% 55%);
color: hsl(0deg 0% 100%);
border-color: hsl(152deg 33% 39%);
}
}
}
.box {
width: 120px;
height: 70px;
background-color: hsl(0deg 0% 94%);
transition: 0.2s ease;
transition-property: background-color, border-color;
display: inline-block;
text-align: center;
cursor: pointer;
position: relative;
border: 1px solid hsl(0deg 0% 91%);
border-radius: 8px;
margin: 0 10px 5px 0;
padding: 30px 20px;
vertical-align: top;
&:hover {
background-color: hsl(0deg 0% 91%);
border-color: hsl(0deg 0% 80%);
}
.schedule-time {
font-weight: bold;
font-size: 1.2em;
margin-top: 10px;
}
.schedule-amount {
margin-top: 5px;
font-size: 1.1em;
height: 50px;
}
.schedule-amount-2 {
font-size: 0.9em;
}
.management-type {
font-weight: bold;
font-size: 1.2em;
margin-top: 10px;
}
.management-type-text {
font-size: 1.1em;
margin-top: 5px;
}
}
}
.stripe-button-el {
padding: 11px 25px;
font-weight: 400;
color: hsl(0deg 0% 100%);
background: linear-gradient(
145deg,
hsl(191deg 56% 55%),
hsl(169deg 65% 42%)
);
box-shadow: 0 3px 10px hsl(0deg 0% 0% / 20%);
border: 0;
height: 40px;
margin: 5px 0 0;
& span {
background: 0;
box-shadow: none;
font-family: "Source Sans 3 VF", sans-serif;
line-height: 20px;
}
}
.stripe-button-el:hover {
background-color: hsl(169deg 65% 42%);
box-shadow: 0 3px 10px hsl(0deg 0% 0% / 30%);
}
.stripe-button-el:active,
.stripe-button-el:enabled:active {
background-color: hsl(169deg 70% 32%);
& span {
background: 0;
box-shadow: none;
}
}
.stripe-button-el:disabled {
& span {
background: none;
}
}
.stripe-button-el:hover:disabled {
box-shadow: none;
background-color: hsl(0deg 0% 78%);
pointer-events: none;
}
.invoice-button {
font-size: 19px;
}
.upgrade-button-container {
display: inline-block;
}
#manual_license_count,
#invoiced_licenses {
width: 50px;
}
#licenses_at_next_renewal_input,
#new_licenses_input {
width: 206px;
}
#error-message-box {
margin-top: 10px;
font-weight: 600;
display: none;
}
#restartsession-loading,
#webhook-loading,
#sponsorship-loading,
#planchange-loading,
#licensechange-loading,
#cardchange-loading,
#invoice-loading,
#autopay-loading {
display: none;
min-height: 55px;
text-align: center;
}
#restartsession-success,
#webhook-success,
#sponsorship-success,
#planchange-success,
#licensechange-success,
#cardchange-success,
#invoice-success,
#autopay-success {
text-align: center;
display: none;
}
#restartsession-error,
#webhook-error,
#sponsorship-error,
#planchange-error,
#licensechange-error,
#cardchange-error,
#invoice-error,
#autopay-error {
text-align: center;
display: none;
}
.zulip-loading-logo {
margin: 0 auto;
width: 30px;
/* Adjusting height moves the loading spinner vertically.
Manually adjusted to align spinner and z-logo. */
height: 23px;
}
.zulip-loading-logo svg circle {
fill: hsl(0deg 0% 27%);
stroke: hsl(0deg 0% 27%);
}
.zulip-loading-logo svg path {
fill: hsl(0deg 0% 100%);
stroke: hsl(0deg 0% 100%);
}
#restartsession_loading_indicator,
#webhook_loading_indicator,
#sponsorship_loading_indicator,
#planchange_loading_indicator,
#licensechange_loading_indicator,
#cardchange_loading_indicator,
#invoice_loading_indicator,
#autopay_loading_indicator {
margin: 10px auto;
}
#restartsession_loading_indicator_box_container,
#webhook_loading_indicator_box_container,
#sponsorship_loading_indicator_box_container,
#planchange_loading_indicator_box_container,
#licensechange_loading_indicator_box_container,
#cardchange_loading_indicator_box_container,
#invoice_loading_indicator_box_container,
#autopay_loading_indicator_box_container {
position: absolute;
left: 50%;
}
#restartsession_loading_indicator_box,
#webhook_loading_indicator_box,
#sponsorship_loading_indicator_box,
#planchange_loading_indicator_box,
#licensechange_loading_indicator_box,
#cardchange_loading_indicator_box,
#invoice_loading_indicator_box,
#autopay_loading_indicator_box {
position: relative;
left: -50%;
top: -41px;
z-index: 10;
border-radius: 6px;
}
#restartsession_loading_indicator .loading_indicator_text,
#webhook_loading_indicator .loading_indicator_text,
#sponsorship_loading_indicator .loading_indicator_text,
#planchange_loading_indicator .loading_indicator_text,
#licensechange_loading_indicator .loading_indicator_text,
#cardchange_loading_indicator .loading_indicator_text,
#invoice_loading_indicator .loading_indicator_text,
#autopay_loading_indicator .loading_indicator_text {
margin-left: -25px;
}
& select,
input,
textarea {
font-family: inherit;
}
}
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
appearance: none;
margin: 0;
}
input[name="licenses"] {
appearance: textfield;
}
#confirm-licenses-modal .dialog_submit_button:active {
/* This is needed to avoid button background changing
when clicking on it due to "button:active" CSS in
legacy_landing_page.css. */
background-color: hsl(240deg 96% 68%);
}
#account-deactivated-success-page .white-box,
#server-deactivate-page .white-box,
#remote-billing-confirm-login-page .white-box,
#remote-billing-confirm-email .white-box,
#server-login-page .white-box,
#upgrade-page .white-box,
#billing-page .white-box,
.sponsorship-page .white-box {
margin: 30px;
}
#account-deactivated-success-page #account-deactivated-success-page-details,
#server-deactivate-page #server-deactivate-details,
#server-login-page #server-login-page-details,
#upgrade-page #upgrade-page-details,
#billing-page #billing-page-details,
.sponsorship-page #sponsorship-form {
margin: 0;
}
#sponsorship-discount-details {
font-weight: normal;
margin: 2px 14px;
padding-top: 0;
text-align: left;
overflow-wrap: break-word;
width: 450px;
}
@media (width < 600px) {
#server-login-page,
#billing-page,
.sponsorship-page {
transform: scale(0.8);
margin: -50px;
}
.sponsorship-status-page {
transform: scale(0.8);
margin: -10px -50px -50px;
}
#upgrade-page {
transform: scale(0.8);
margin: -50px 0;
}
}
@media (width < 460px) {
#upgrade-page,
#billing-page,
.sponsorship-page {
transform: scale(0.6);
margin: -150px -100px;
}
#server-login-page,
.sponsorship-status-page {
transform: scale(0.6);
margin: -50px -150px -100px;
}
#upgrade-page {
transform: scale(0.6);
margin: -150px 0;
}
}
#billing-page .billing-status-page .pitch {
width: 100%;
}
.billing-status-page {
font-weight: 400;
}
.sponsorship-status-page .white-box {
font-weight: 400;
margin: 30px;
padding: 0;
}
.billing-status-page p:last-child,
.sponsorship-status-page p:last-child {
margin-bottom: 0;
}
.remote-billing-confirm-login-form-field-error,
.server-login-form-field-error,
.upgrade-page-error,
.sponsorship-field-error,
.billing-page-error,
.billing-page-success {
text-align: left;
margin-left: 2px;
margin-top: 5px;
}
.header.portico-header {
display: block;
}
#upgrade-page #upgrade-manual-license-count-wrapper,
#billing-page .input-box-number {
text-align: left;
}
#account-deactivated-success-page .pitch,
#server-deactivate-details .pitch,
#remote-billing-confirm-login-page .pitch,
#server-login-page .pitch,
.sponsorship-page .pitch,
.sponsorship-status-page .pitch,
#upgrade-page .pitch,
#billing-page .pitch {
width: 600px;
}
#billing-page .number-input-with-label {
display: flex;
align-items: flex-end;
}
#upgrade-page #manual_license_count,
#billing-page
.white-box
.input-box-number
.number-input-with-label
.short-width-number-input {
width: 100px;
}
#billing-page .number-input-with-label .licence-count-in-use {
padding-left: 10px;
vertical-align: bottom;
position: relative;
bottom: 15px;
}
#billing-page #org-billing-frequency-confirm-button,
#billing-page .license-count-update-button {
margin: 0 auto;
font-size: 1.1rem;
margin-right: 0;
width: 100px;
}
#billing-page #org-billing-frequency-confirm-button.hide,
#billing-page .license-count-update-button.hide {
display: none;
}
#billing-page #org-billing-frequency-confirm-button {
margin: 0;
display: block;
position: absolute;
top: 25px;
right: 0;
}
#billing-page #current-license-change-form,
#billing-page #next-license-change-form {
margin-bottom: 0;
}
.billing-page-success {
display: none;
}
#billing-page-details .input-box.billing-page-field.plan-toggle-action,
#billing-page-details .input-box.billing-page-field.user-stripe-card-update {
margin-top: 10px;
text-align: left;
}
#update-card-button {
position: relative;
.billing-button-loader {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
margin: 0;
}
}
#billing-page-details .plan-toggle-action .plan-toggle-action-button {
margin: 20px auto 0;
background-color: hsl(0deg 70% 40%);
}
#reactivate-subscription
.reactivate-current-plan-button.plan-toggle-action-button {
background-color: hsl(146deg 92% 26%);
}
#server-deactivate-button,
#remote-billing-confirm-login-button,
#remote-billing-confirm-email-button,
#server-login-button,
#org-upgrade-button {
margin: 0;
width: 100%;
}
#upgrade-page-details #payment-schedule-select {
&:disabled {
&:hover {
cursor: not-allowed;
}
}
}
#upgrade-page-details #upgrade-payment-by-invoice-container {
padding-top: 0;
}
#upgrade-page-details #upgrade-payment-method-container {
display: flex;
align-items: center;
gap: 10px;
}
#upgrade-page-details #upgrade-add-card-button,
#billing-page-details .user-stripe-card-update .user-stripe-card-update-button {
margin: 0;
width: auto;
}
#upgrade-page-details #upgrade-cardchange-form {
margin: 0;
}
#server-login-page-details #server-login-form-title .not-editable-realm-field {
font-weight: 500;
padding-top: 0;
}
#server-login-page-details #server-login-form-title,
#billing-page-details .stripe-customer-billing-portal,
#billing-page-details #complimentary-access-end-notice,
#billing-page-details .next-payment-info {
width: 450px;
padding-top: 0;
}
#sponsorship-status-page-details .input-box.sponsorship-form-field:first-child,
#billing-page-details .input-box.billing-page-field:first-child {
margin-top: 10px;
}
.sponsorship-status-page .support-link,
#billing-page .support-link {
text-align: center;
}
.micromodal {
.modal__title {
font-weight: 600;
}
.modal__content {
font-weight: 400;
}
}
#upgrade-page-details #free-trial-top-banner {
margin-top: 10px;
}
#upgrade-page-details .support-link,
#account-deactivated-success-page-details .not-editable-realm-field,
#server-deactivate-details
#server-deactivate-form-top-description
.not-editable-realm-field,
#remote-billing-confirm-email-intro .not-editable-realm-field,
#billing-page-details .billing-frequency-message.not-editable-realm-field,
#free-trial-top-banner .not-editable-realm-field,
#upgrade-page-details .license-management-section .not-editable-realm-field,
#upgrade-page-details #payment-by-invoice-setup .not-editable-realm-field,
#upgrade-page-details .top-of-page-notice .not-editable-realm-field {
padding-top: 0;
}
#free-trial-alert-message,
#free-trial-top-banner {
text-align: left;
}
#upgrade-page-sponsorship-pending-message-top,
#billing-sponsorship-pending-message-top,
#sponsorship-status-success-message-top,
#upgrade-success-message-top,
#billing-success-message-top {
display: block;
text-align: center;
font-weight: 400;
padding: 10px 20px;
width: 600px;
}
.upgrade-page-success {
display: none;
padding: 8px 0;
width: 450px;
text-align: center;
margin: auto;
}
#upgrade-payment-info {
display: grid;
grid-template: auto auto auto 1fr / 1fr auto;
grid-template-areas:
"payment-info add-card"
"stripe-portal stripe-portal"
"alert-message alert-message";
width: 450px;
margin: auto;
}
#update-invoice-billing-info {
display: flex;
flex-direction: column;
width: 450px;
margin: auto;
}
#upgrade-payment-info .alert {
grid-area: alert-message;
}
#upgrade-page-details .stripe-billing-information {
grid-area: stripe-portal;
padding-top: 2px;
}
#upgrade-page-details #upgrade-payment-method-wrapper {
margin-left: 0;
grid-area: payment-info;
width: 100%;
}
/* Used class twice to increase specificity */
#upgrade-payment-info .upgrade-add-card-container.upgrade-add-card-container {
grid-area: add-card;
width: auto;
margin-right: 0;
}
#billing-page-details
.org-billing-frequency-wrapper.input-box
.billing-frequency-select {
width: 150px;
}
#billing-page-details .org-billing-frequency-wrapper.billing-page-field,
#upgrade-page-details .upgrade-add-card-container {
text-align: left;
}
#server-deactivate-error,
#server-login-error,
#autopay-error {
font-weight: 400;
margin-left: 0;
}
#sponsorship-status-page-details .input-box.sponsorship-form-field {
margin: 20px;
}
#sponsorship-form .upgrade-button-container {
display: block;
text-align: center;
}
.billing-page-discount {
opacity: 0.8;
font-weight: 400;
}
.remote-billing-button-loader {
display: none;
vertical-align: top;
position: relative;
height: 30px;
margin-top: -10px;
top: 5px;
}
#server-deactivate-error,
#server-login-error {
text-align: left;
margin: 0 auto;
max-width: 400px;
padding: 10px 25px;
}
#upgrade-page-details #due-today-for-future-update-wrapper {
display: none;
}
#remote-billing-confirm-login-form .text-error {
margin-bottom: 15px;
}
#server-deactivate-details .upgrade-button-container,
#server-login-page-button-container {
width: 450px;
margin: 30px auto 0;
}
#remote-billing-confirm-login-button,
#remote-billing-confirm-email-button,
#billing-page-details #complimentary-access-end-notice-wrapper {
margin-top: 10px;
}
#remote-billing-confirm-email-form #remote-billing-confirm-email-intro {
margin-top: -10px;
}
#remote-billing-confirm-login-form #remote-billing-confirm-login-tos-wrapper {
margin: 0 auto 10px;
}
#account-deactivated-success-page-details
#account-deactivated-success-page-top-message {
margin-top: 10px;
}
.flat-discount-minus-sign {
position: absolute;
left: -10px;
}
.flat-discount-separator {
border-bottom: 1px solid hsl(0deg 0% 0%);
}
.toggle-license-management {
cursor: pointer;
}
#billing-page-details .billing-page-license-management-description {
padding-top: 5px;
}

View File

@@ -0,0 +1,732 @@
.showing-cloud .self-hosted-comparison,
.showing-self-hosted .cloud-comparison {
display: none;
}
.zulip-plans-comparison {
--color-heading-text: hsl(0deg 0% 100%);
--color-table-text: hsl(223deg 40% 25%);
--color-table-background: hsl(0deg 0% 100% / 80%);
--color-table-link: hsl(210deg 94% 30%);
--color-table-link-hover: hsl(210deg 100% 45%);
--color-table-link-active: hsl(210deg 100% 40%);
--color-table-link-decoration: hsl(210deg 94% 30% / 20%);
--color-table-link-decoration-hover: hsl(210deg 100% 45% / 70%);
--color-table-link-decoration-active: hsl(210deg 100% 40%);
--border-radius-table: 11px;
.icon-cloud {
--icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' viewBox='0 0 16 16'%3e%3cpath fill='%23313F68' d='M4.333 13.333c-1.01 0-1.875-.35-2.591-1.05-.717-.7-1.075-1.555-1.075-2.566 0-.867.26-1.64.783-2.317A3.465 3.465 0 0 1 3.5 6.1a4.525 4.525 0 0 1 1.667-2.483A4.561 4.561 0 0 1 8 2.667c1.3 0 2.403.452 3.308 1.358.906.906 1.359 2.008 1.359 3.308a2.91 2.91 0 0 1 1.908.992c.506.572.758 1.242.758 2.008 0 .834-.291 1.542-.875 2.125a2.893 2.893 0 0 1-2.125.875h-8Z' opacity='.5'/%3e%3c/svg%3e");
}
.icon-self-hosted {
--icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' viewBox='0 0 16 16'%3e%3cpath fill='%23313F68' fill-opacity='.5' d='M11.333 10.667a.98.98 0 0 0 .709-.284.957.957 0 0 0 .291-.716.964.964 0 0 0-.291-.709.965.965 0 0 0-.709-.291.957.957 0 0 0-.716.291.979.979 0 0 0-.284.709.971.971 0 0 0 1 1ZM1.333 6 3.6 3.733c.122-.122.264-.22.425-.291.161-.073.336-.109.525-.109h6.883c.19 0 .364.036.525.109.161.072.303.17.425.291L14.667 6H1.333Zm1.334 6.667a1.29 1.29 0 0 1-.95-.384 1.29 1.29 0 0 1-.384-.95v-4h13.334v4c0 .378-.13.695-.392.95a1.298 1.298 0 0 1-.942.384H2.667Z'/%3e%3c/svg%3e");
}
.icon-infinity {
--icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' viewBox='0 0 24 24'%3e%3cpath fill='black' fill-rule='evenodd' d='M2.464 8.464A5 5 0 0 1 6 7c2.16 0 4.155 1.251 6 3.4C13.845 8.251 15.84 7 18 7a5 5 0 1 1 0 10c-2.16 0-4.155-1.251-6-3.4-1.845 2.149-3.84 3.4-6 3.4a5 5 0 0 1-3.536-8.536ZM10.731 12C8.983 9.857 7.4 9 6 9a3 3 0 1 0 0 6c1.4 0 2.983-.857 4.731-3Zm2.538 0c1.748 2.143 3.331 3 4.731 3a3 3 0 0 0 0-6c-1.4 0-2.983.857-4.731 3Z' clip-rule='evenodd'/%3e%3c/svg%3e");
}
.icon-check {
--icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' viewBox='0 0 24 24'%3e%3cpath fill='black' fill-rule='evenodd' d='M20.707 5.793a1 1 0 0 1 0 1.414l-11 11a1 1 0 0 1-1.414 0l-5-5a1 1 0 1 1 1.414-1.414L9 16.086 19.293 5.793a1 1 0 0 1 1.414 0Z' clip-rule='evenodd'/%3e%3c/svg%3e");
}
.icon-x {
--icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' viewBox='0 0 24 24'%3e%3cpath fill='black' d='M18.707 6.707a1 1 0 0 0-1.414-1.414L12 10.586 6.707 5.293a1 1 0 0 0-1.414 1.414L10.586 12l-5.293 5.293a1 1 0 1 0 1.414 1.414L12 13.414l5.293 5.293a1 1 0 0 0 1.414-1.414L13.414 12l5.293-5.293Z'/%3e%3c/svg%3e");
}
.icon-wrench {
--icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' viewBox='0 0 24 24'%3e%3cpath fill='black' fill-rule='evenodd' d='M16.578 3.36a5.25 5.25 0 0 0-5.866 7.302.75.75 0 0 1-.153.84l-6.91 6.91a1.371 1.371 0 0 0 1.94 1.94l6.91-6.91a.75.75 0 0 1 .839-.154 5.25 5.25 0 0 0 7.301-5.866l-2.915 2.915a1.75 1.75 0 0 1-2.45 0l-.006-.005-1.605-1.606a1.75 1.75 0 0 1 0-2.45l.005-.005 2.91-2.91Zm-2.293-1.503a6.75 6.75 0 0 1 3.993.491.75.75 0 0 1 .22 1.214l-3.766 3.766a.25.25 0 0 0 0 .347l1.593 1.593a.25.25 0 0 0 .347 0L20.438 5.5a.75.75 0 0 1 1.214.221 6.75 6.75 0 0 1-8.445 9.131l-6.557 6.56a2.871 2.871 0 1 1-4.06-4.06l6.558-6.56a6.75 6.75 0 0 1 5.138-8.935Z' clip-rule='evenodd'/%3e%3c/svg%3e");
}
.icon {
vertical-align: middle;
display: inline-block;
flex-shrink: 0;
background-color: currentcolor;
mask-position: center;
mask-repeat: no-repeat;
mask-image: var(--icon);
width: 24px;
height: 24px;
}
.icon-plan {
/* Smaller icons within the table headings. */
width: 16px;
height: 16px;
}
.icon-with-copy {
/* Treat copy and a nearby icon as
a unit when reflowing text for narrower
viewports. */
display: inline-block;
}
.grouped-icons {
display: flex;
justify-content: center;
gap: 4px;
}
h2 {
font-family: var(--font-ss3);
font-weight: 450;
font-size: 44px;
line-height: 120%;
text-align: center;
margin: 64px 0 10px;
color: var(--color-heading-text);
}
.h2-subheader {
font-family: var(--font-ops);
font-weight: 400;
font-size: 16px;
line-height: 145%;
text-align: center;
color: var(--color-heading-text);
/* Let subheader text fill the same area as
text in the comparison table below. */
padding: 0 14px;
a {
color: inherit;
text-decoration: underline;
text-decoration-color: hsl(0deg 0% 100% / 50%);
transition: text-decoration 0.4s ease-out;
&:hover {
text-decoration-color: hsl(0deg 0% 100%);
text-decoration-thickness: 2px;
transition: none;
}
}
}
.comparison-tabs {
width: max-content;
margin: 0 auto;
display: flex;
justify-content: center;
gap: 3px;
background-color: hsl(0deg 0% 100% / 70%);
padding: 3px;
border-radius: 6px;
}
.comparison-tab {
font-family: var(--font-ops);
font-size: 14px;
padding: 4px 16px;
color: hsl(223deg 40% 30%);
font-weight: 600;
border: none;
background-color: hsl(0deg 0% 100% / 0%);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 3px;
cursor: pointer;
transition: background-color 120ms ease-out;
}
.comparison-tab:hover {
transition: none;
background-color: hsl(0deg 0% 100% / 40%);
}
.comparison-tab:active {
background-color: hsl(0deg 0% 100% / 70%);
}
.comparison-tab._selected {
background-color: hsl(0deg 0% 100% / 80%);
cursor: default;
}
.comparison-table {
font-family: var(--font-ss3);
font-size: 16px;
line-height: 18px;
text-align: center;
border-collapse: collapse;
margin: 24px auto 48px;
border-radius: var(--border-radius-table);
color: var(--color-table-text);
background: var(--color-table-background);
}
&.education-features-comparison {
--zulip-cell-background-color: hsl(217deg 71% 78%);
--zulip-cell-foreground-color: hsl(210deg 4% 10%);
--zulip-column-border-width: 8px;
--zulip-column-border-negative-offset: calc(
var(--zulip-column-border-width) * -1
);
padding-bottom: 48px;
.comparison-table {
font-weight: normal;
table-layout: fixed;
width: 100%;
max-width: 800px;
}
.comparison-table-feature {
width: 30%;
}
th.zulip-cell {
padding: 0;
}
th.zulip-cell .label-zulip {
display: block;
/* We make the border larger by 1px to avoid an
occasional rendering bug in Chrome that lets
daylight in between the border here and the
top of the table row. */
border-top: calc(var(--zulip-column-border-width) + 1px) solid
var(--zulip-cell-background-color);
margin: var(--zulip-column-border-negative-offset)
var(--zulip-column-border-negative-offset) 0;
/* The hard-coded numeric values here keep the Zulip
label aligned with other labels in the table-header
row. */
padding: calc(var(--zulip-column-border-width) + 7px)
calc(var(--zulip-column-border-width) + 2px)
calc(var(--zulip-column-border-width) + 5px);
}
.zulip-cell {
color: var(--zulip-cell-foreground-color);
background: var(--zulip-cell-background-color);
border-left: var(--zulip-column-border-width) solid
var(--zulip-cell-background-color);
border-right: var(--zulip-column-border-width) solid
var(--zulip-cell-background-color);
/* Don't display stripes in the Zulip column. */
border-top-color: var(--zulip-cell-background-color);
}
.zulip-cell .bottom-border {
display: block;
width: 100%;
padding: 0 var(--zulip-column-border-width);
border-bottom: var(--zulip-column-border-width) solid
var(--zulip-cell-background-color);
position: absolute;
bottom: var(--zulip-column-border-negative-offset);
left: var(--zulip-column-border-negative-offset);
}
}
.comparison-table a {
color: var(--color-table-link);
text-underline-offset: 4px;
text-decoration-thickness: 1px;
text-decoration-color: var(--color-table-link-decoration);
}
.comparison-table a:hover {
color: var(--color-table-link-hover);
text-decoration-color: var(--color-table-link-decoration-hover);
}
.comparison-table a:active {
color: var(--color-table-link-active);
text-decoration-color: var(--color-table-link-decoration-active);
}
.comparison-table th:first-child {
border-top-left-radius: var(--border-radius-table);
}
.comparison-table th:last-child {
border-top-right-radius: var(--border-radius-table);
}
.comparison-table th,
.comparison-table .subheader {
position: sticky;
font-weight: 700;
color: hsl(223deg 40% 30% / 100%);
background: hsl(209deg 41% 94%);
}
.comparison-table .competitor-cell {
padding: 12px 10px 10px;
font-weight: normal;
/* Use gray color on competitor cells for
checkmarks and warnings (language counts). */
&.comparison-value-positive,
&.comparison-value-warning {
color: hsl(224deg 8% 50% / 100%);
}
/* Use red color on competitor cells for
X marks. */
&.comparison-value-negative {
color: hsl(0deg 36% 58%);
}
}
.comparison-table th .icon {
display: none;
}
.subheader-filler {
background: hsl(209deg 41% 94%);
}
.comparison-table th {
padding: 12px 2px 10px;
top: 60px;
z-index: 1;
}
.comparison-table td.subheader.comparison-table-feature {
font-weight: 600;
color: hsl(223deg 40% 30% / 80%);
top: 64px;
z-index: 2;
padding-top: 8px;
padding-bottom: 8px;
text-transform: uppercase;
font-size: 15px;
letter-spacing: 0.1ch;
}
.comparison-table td {
padding: 8px;
border-top: 1px solid hsl(209deg 40% 40% / 30%);
line-height: 18px;
}
.comparison-table colgroup col:first-child {
width: 340px;
}
.comparison-table colgroup col {
width: 112px;
}
.comparison-table th.comparison-table-feature,
.comparison-table td.comparison-table-feature {
text-align: left;
padding-left: 14px;
}
.comparison-table td.comparison-table-feature {
color: hsl(223deg 40% 16%);
}
.comparison-table-feature-desc {
font-size: 14px;
opacity: 0.7;
margin-top: 4px;
}
.comparison-value-positive {
color: hsl(147deg 80% 29% / 100%);
}
.comparison-value-warning {
color: hsl(42deg 85% 35% / 100%);
}
.comparison-value-negative {
color: hsl(224deg 8% 50% / 100%);
}
.comparison-value-positive,
.comparison-value-warning,
.comparison-value-negative {
/* Set positioning context for use
with tooltip hovers on icons. */
position: relative;
/* Make non-icon text (e.g., "Billed hourly")
less prominent than other text in the table's
rows or columns. */
font-size: 0.9em;
}
&:not(.education-features-comparison) {
.comparison-table tr {
transition: background-color 200ms ease-out;
}
.comparison-table tbody tr:hover {
background-color: hsl(0deg 0% 100% / 30%);
}
.comparison-value-positive::after,
.comparison-value-warning::after,
.comparison-value-negative::after {
content: attr(data-title);
white-space: nowrap;
font-size: 14px;
line-height: 14px;
font-weight: 400;
display: block;
padding: 2px 4px;
border-radius: 5px;
background-color: hsl(208deg 43% 93%);
/* the color of mixed hover row with bg */
position: absolute;
top: calc(50% + 11px);
left: 50%;
/* Keep tooltips over top of other elements,
including the headers within the table. */
z-index: 3;
transform: translateX(-50%);
visibility: hidden;
opacity: 0;
transition:
visibility 301s linear,
opacity 250ms ease-out;
}
.comparison-value-positive:hover::after,
.comparison-value-warning:hover::after,
.comparison-value-negative:hover::after {
transition:
visibility 0s linear,
opacity 250ms ease-out;
transition-delay: 200ms;
visibility: visible;
opacity: 1;
}
}
@media (width <= 940px) {
h1 {
font-size: 40px;
}
.h1-subheader {
font-size: 16px;
}
h2 {
font-size: 32px;
margin-bottom: 4px;
}
.h2-subheader {
font-size: 14px;
}
}
@media (width <= 730px) {
.comparison-table th {
font-size: 14px;
line-height: 18px;
box-sizing: border-box;
height: 44px;
padding: 4px 2px;
}
.comparison-table td {
font-size: 14px;
line-height: 18px;
}
.comparison-table td.subheader.comparison-table-feature {
font-size: 13px;
line-height: 16px;
box-sizing: border-box;
padding-top: 10px;
padding-bottom: 8px;
}
.comparison-table td.comparison-table-feature {
font-size: 14px;
}
.comparison-table-feature-desc {
font-size: 12px;
line-height: 14px;
}
}
@media (width <= 670px) {
.comparison-table .competitor-cell {
padding: 12px 2px 10px;
}
}
@media (width <= 500px) {
.comparison-table th {
font-size: 13px;
line-height: 14px;
}
.comparison-table th.comparison-table-feature,
.comparison-table td.comparison-table-feature {
padding-left: 8px;
}
.comparison-table td {
padding: 4px 2px;
border-top: 1px solid hsl(209deg 40% 40% / 30%);
line-height: 18px;
}
.comparison-table td.comparison-value-positive,
.comparison-table td.comparison-value-warning,
.comparison-table td.comparison-value-negative {
font-size: 13px;
line-height: 14px;
}
.comparison-value-positive::after,
.comparison-value-warning::after,
.comparison-value-negative::after {
display: none;
}
}
}
/* No header to accommodate on self-hosted realms,
so keep sticky headers at the top of the viewport. */
.zulip-plans-comparison.is-self-hosted-realm {
.comparison-table {
th,
td.subheader.comparison-table-feature {
top: 0;
}
}
}
/* Change comparison-table visibility on /plans
based on active plan tab. */
#showing-tab-cloud,
#showing-tab-hosted,
#showing-tab-all {
.comparison-tab-cloud,
.comparison-tab-self-hosted,
.comparison-tab-all {
background-color: hsl(0deg 0% 100% / 0%);
cursor: pointer;
&:hover {
background-color: hsl(0deg 0% 100% / 40%);
}
}
}
.showing-cloud:not(:has(div[id^="showing-tab"])),
#showing-tab-cloud {
.comparison-tab-cloud {
background-color: hsl(0deg 0% 100%);
cursor: default;
&:hover {
background-color: hsl(0deg 0% 100%);
}
}
#self-hosted-plan-comparison,
#all-plan-comparison,
.subheader-open-source,
.subheader-self-hosted-legend,
.self-hosted-feature-only,
.self-hosted-cell {
display: none;
}
#cloud-plan-comparison,
.cloud-cell {
display: revert;
}
/* When only Cloud plans appear in the comparison table,
we need to set the border-radius here that is otherwise
displayed on the table itself.
TODO: Unset this property when the header row is stuck,
so that the little flutter of feature-table lines cannot
be seen by eagle-eyed users. */
th.last-cloud-th {
border-top-right-radius: var(--border-radius-table);
}
}
.showing-self-hosted:not(:has(div[id^="showing-tab"])),
#showing-tab-hosted {
.comparison-tab-self-hosted {
background-color: hsl(0deg 0% 100%);
cursor: default;
&:hover {
background-color: hsl(0deg 0% 100%);
}
}
#cloud-plan-comparison,
#all-plan-comparison,
.cloud-cell {
display: none;
}
#self-hosted-plan-comparison,
.subheader-open-source,
.subheader-self-hosted-legend,
.self-hosted-feature-only,
.self-hosted-cell {
display: revert;
}
th.last-cloud-th {
border-top-right-radius: unset;
}
}
#showing-tab-all {
.comparison-tab-all {
background-color: hsl(0deg 0% 100%);
cursor: default;
&:hover {
background-color: hsl(0deg 0% 100%);
}
}
#cloud-plan-comparison,
#self-hosted-plan-comparison {
display: none;
}
.subheader-open-source,
.subheader-self-hosted-legend,
#all-plan-comparison,
.cloud-cell,
.self-hosted-cell,
.self-hosted-feature-only {
display: revert;
}
th.last-cloud-th {
border-top-right-radius: unset;
}
.comparison-table th .icon {
display: revert;
}
.comparison-table th {
vertical-align: top;
}
.comparison-table th.comparison-table-feature {
padding-top: 28px;
}
.comparison-table td.stuck {
padding-top: 24px;
}
@media (width <= 730px) {
.comparison-table th {
padding: 8px 2px;
}
.comparison-table th.comparison-table-feature {
padding-top: 24px;
padding-left: 14px;
}
.comparison-table td.subheader.comparison-table-feature {
/* Line up features with plan titles. */
line-height: 18px;
}
.comparison-table td.stuck {
padding-top: 20px;
padding-bottom: 6px;
vertical-align: top;
}
}
@media (width <= 684px) {
.comparison-table td.stuck {
height: 60px;
}
}
@media (width <= 500px) {
.comparison-table td.subheader.comparison-table-feature {
/* Line up features with plan titles. */
line-height: 14px;
min-width: auto;
}
.comparison-table td.stuck {
top: 64px;
height: 55px;
}
}
@media (width <= 405px) {
/* For very tiny views, we get rid of the luxury
of any horizontal padding that's left. */
.comparison-table-feature,
.cloud-cell,
.self-hosted-cell {
padding-left: 0;
padding-right: 0;
}
/* Keep the comparison-table features from
colliding with the left screen edge, though. */
.comparison-table-feature {
padding-left: 2px;
}
}
}
@media (width <= 500px) {
.comparison-table td.subheader.comparison-table-feature {
min-width: max-content;
}
}
@media (width <= 460px) {
.zulip-plans-comparison .comparison-tab-all {
display: none;
}
}
@media (width <= 356px) {
.zulip-plans-comparison
.comparison-table
td.subheader.comparison-table-feature {
height: 51px;
top: 60px;
}
.zulip-plans-comparison .comparison-table th {
height: 51px;
}
}
.features-page {
/* Always suppress subheadings on /features */
#cloud-plan-comparison,
#self-hosted-plan-comparison,
#all-plan-comparison {
display: none !important;
}
/* Maintain the margin-top ordinarily set on
the subheadings. */
.comparison-tabs {
margin-top: 64px;
}
}

View File

@@ -0,0 +1,44 @@
.dev-help-page {
.white-box {
width: 40%;
margin: 0 auto;
}
.dev-help-header {
text-align: center;
margin-bottom: 1em;
}
.invalid-path-error {
color: hsl(1.1deg 44.7% 50.4%);
font-weight: 400;
display: block;
text-align: center;
margin-top: 1em;
}
.dev-help-actions {
margin-top: 1.5em;
display: flex;
justify-content: center;
gap: 5px;
.dev-help-action-button {
display: inline-block;
font-weight: 400;
color: hsl(170deg 41% 52%);
border: 1px solid hsl(170deg 41% 52%);
border-radius: 4px;
padding: 6px 12px;
transition:
color 0.3s ease,
border-color 0.3s ease;
&:hover {
color: hsl(156deg 62% 61%);
border-color: hsl(156deg 62% 61%);
}
}
}
}

View File

@@ -0,0 +1,134 @@
#dev-email-log-container {
.dev-email-log-header {
position: fixed;
font-family: sans-serif;
font-size: 14px;
}
.dev-email-log-header,
.dev-forward-email-alert {
padding: 10px;
border: 1px solid hsl(190deg 65% 84%);
border-radius: 4px;
background-color: hsl(200deg 65% 91%);
color: hsl(200deg 50% 45%);
}
.dev-email-log-actions,
.dev-forward-email-alert {
& a {
color: hsl(200deg 50% 45%);
&:hover {
color: hsl(200deg 56% 33%);
}
}
}
.dev-email-log-actions {
padding-bottom: 5px;
}
.dev-email-log-text-only {
text-align: right;
}
.dev-email-log-content {
padding-top: 100px;
max-width: 1000px;
& h4 {
color: hsl(0deg 0% 20%);
margin: 2px 10px;
}
.email-text,
.email-html {
margin: 10px;
}
.email-text pre {
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
color: hsl(0deg 0% 20%);
display: block;
padding: 9.5px;
margin: 0 0 10px;
font-size: 13px;
line-height: 20px;
word-break: break-all;
overflow-wrap: break-word;
white-space: pre-wrap;
background-color: hsl(0deg 0% 96%);
border: 1px solid hsl(0deg 0% 75%);
border-radius: 4px;
}
}
#smtp_form_status,
.hide {
display: none;
}
#forward_email_modal {
.modal__content label {
font-size: 1rem;
display: block;
cursor: pointer;
}
#forward_address_sections,
.dev-forward-email-alert {
margin: 5px 0;
}
& label.radio {
padding-left: 20px;
}
& input[type="radio"] {
float: left;
width: auto;
cursor: pointer;
margin: -4px 0 0 -20px;
line-height: normal;
&:focus {
outline: 1px dotted hsl(0deg 0% 20%);
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
}
& input[type="text"] {
padding: 4px 6px;
color: hsl(0deg 0% 33%);
border-radius: 4px;
border: 1px solid hsl(0deg 0% 80%);
box-shadow: inset 0 1px 1px hsl(0deg 0% 0% / 7.5%);
transition:
border-color linear 0.2s,
box-shadow linear 0.2s;
margin-bottom: 10px;
width: 206px;
&:focus {
border-color: hsl(206deg 80% 62% / 80%);
outline: 0;
box-shadow:
inset 0 1px 1px hsl(0deg 0% 0% / 7.5%),
0 0 8px hsl(206deg 80% 62% / 60%);
}
}
}
& input[type="checkbox"] {
width: auto;
cursor: pointer;
&:focus {
outline: 1px dotted hsl(0deg 0% 20%);
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
}
}

View File

@@ -0,0 +1,228 @@
:root {
--color-footer-background: hsl(238deg 28% 27%);
--color-links: hsl(238deg 100% 82%);
@media (prefers-color-scheme: dark) {
--color-footer-background: hsl(238deg 28% 21%);
}
}
/* These need to be here so that other pages don't need to import a different library for these icons to work */
.footer-social-icon-mastodon {
--footer-social-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' fill='none' viewBox='0 0 28 28'%3e%3cg fill='%23A3A5F8'%3e%3cpath d='M18.42 16.43h2.38v-6.02c0-1.23-.3-2.2-.94-2.93a3.27 3.27 0 0 0-2.55-1.1c-1.22 0-2.15.47-2.76 1.41l-.6 1-.58-1a3.07 3.07 0 0 0-2.76-1.4c-1.05 0-1.9.37-2.55 1.1a4.3 4.3 0 0 0-.94 2.92v6.02H9.5v-5.84c0-1.23.52-1.86 1.55-1.86 1.15 0 1.72.74 1.72 2.2v3.2h2.38v-3.2c0-1.46.57-2.2 1.71-2.2 1.04 0 1.56.63 1.56 1.86v5.84Z'/%3e%3cpath fill-rule='evenodd' d='M3 0a3 3 0 0 0-3 3v22a3 3 0 0 0 3 3h22a3 3 0 0 0 3-3V3a3 3 0 0 0-3-3H3Zm18.39 3.6s3.26 1.45 3.26 6.43c0 0 .04 3.66-.46 6.2-.31 1.63-2.81 3.4-5.69 3.74-1.5.18-2.97.34-4.54.27-2.57-.12-4.6-.62-4.6-.62 0 .24.02.48.05.72.33 2.53 2.51 2.68 4.58 2.76 2.09.07 3.94-.52 3.94-.52l.09 1.89s-1.46.78-4.06.92c-1.43.08-3.21-.03-5.28-.58-4.5-1.19-5.27-5.98-5.39-10.84a100.6 100.6 0 0 1-.02-3v-.94c0-4.97 3.27-6.43 3.27-6.43 1.64-.76 4.46-1.07 7.39-1.1H14c2.93.03 5.75.34 7.39 1.1Z' clip-rule='evenodd'/%3e%3c/g%3e%3c/svg%3e");
}
.footer-social-icon-bluesky {
--footer-social-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 568 501' fill='none'%3e%3cpath fill='%23A3A5F8' d='M123.121 33.664C188.241 82.553 257.473 181.247 284 234.247c26.527-53 95.759-151.694 160.879-200.583C491.866-1.595 568-26.713 568 60.142c0 17.34-9.945 145.713-15.778 166.555-20.275 72.453-94.155 90.933-159.875 79.706C507.222 326.108 536.444 388.731 473.333 451.355c-119.86 118.875-172.205-29.838-185.624-67.928-2.46-6.984-3.61-10.252-3.61-7.474 0-2.778-1.149.49-3.609 7.474-13.42 38.09-65.764 186.803-185.624 67.928-63.111-62.624-33.89-125.247 64.985-145.345-65.72 11.227-139.6-7.253-159.875-79.706C9.945 205.855 0 77.482 0 60.142 0-26.713 76.134-1.595 123.121 33.664Z'/%3e%3c/svg%3e");
}
.footer-social-icon-linkedin {
--footer-social-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' fill='none' viewBox='0 0 28 28'%3e%3cg clip-path='url(%23a)'%3e%3cpath fill='%23A3A5F8' d='M28 3a3 3 0 0 0-3-3H3a3 3 0 0 0-3 3v22a3 3 0 0 0 3 3h22a3 3 0 0 0 3-3V3ZM8.27 23.9H4.19V10.5h4.18v13.4h-.1ZM6.17 8.7A2.42 2.42 0 0 1 3.8 6.3c0-1.3 1.1-2.4 2.39-2.4 1.3 0 2.39 1.1 2.39 2.4 0 1.3-1 2.4-2.4 2.4Zm17.65 15.2h-4.09v-6.5c0-1.5 0-3.5-2.2-3.5-2.18 0-2.48 1.7-2.48 3.4v6.6h-4.09V10.5h3.99v1.8h.1c.6-1 1.89-2.2 3.88-2.2 4.19 0 4.98 2.8 4.98 6.4v7.4h-.1Z'/%3e%3c/g%3e%3cdefs%3e%3cclipPath id='a'%3e%3cpath fill='white' d='M0 0h28v28H0z'/%3e%3c/clipPath%3e%3c/defs%3e%3c/svg%3e");
}
#footer {
background: var(--color-footer-background);
box-sizing: border-box;
& ul {
/* Override bootstrap defaults */
list-style: none;
margin: 0;
}
.footer__container {
max-width: 1132px;
padding: 52px 52px 0;
display: flex;
justify-content: space-between;
gap: 40px;
flex-flow: row wrap;
margin: 0 auto;
}
.footer__section {
flex-shrink: 0;
}
.footer__section-title {
display: block;
font-style: normal;
font-weight: 700;
font-size: 18px;
line-height: 133%;
letter-spacing: 0.1em;
color: hsl(0deg 0% 100%);
opacity: 0.8;
text-transform: uppercase;
border-bottom: 0;
margin-bottom: 0;
margin-block: 0;
}
.footer__section ul {
margin: 20px 0 28px;
padding-left: 0;
display: flex;
flex-direction: column;
align-items: flex-start;
& li {
margin-bottom: 10px;
}
}
& li {
font-style: normal;
font-weight: 400;
font-size: 16px;
line-height: 20px;
color: var(--color-links);
border-bottom: 1px solid var(--color-footer-background);
}
& a,
a:visited {
font-weight: 400;
font-size: 16px;
color: var(--color-links);
text-decoration: none;
}
& a:hover,
a:focus {
color: var(--color-links);
border-bottom: 1px solid var(--color-links);
transition: none;
text-decoration: none;
outline: none;
}
.footer__legal {
margin: 12px 0 0;
padding: 0 52px;
border-top: 1px solid hsl(0deg 0% 100% / 10%);
& a {
border-bottom: 1px solid var(--color-footer-background);
&:hover {
border-bottom: 1px solid var(--color-links);
}
}
&.footer__legal_not_corporate {
margin-top: 0;
}
}
.footer__legal-container {
max-width: 1132px;
padding: 15px 0;
display: flex;
place-content: center space-between;
flex-flow: row wrap;
margin: 0 auto;
box-sizing: border-box;
font-style: normal;
font-weight: 400;
font-size: 14px;
line-height: 18px;
}
.footer__legal-spacer {
flex-grow: 1;
}
.footer__legal-container .copyright {
color: hsl(0deg 0% 100% / 50%);
@media screen and (width <= 600px) {
/* Maintain space between copyright
and legal links when flex-wrapping
at narrower viewports. */
margin-bottom: 8px;
}
}
.footer__legal-container a {
font-size: 14px;
line-height: 18px;
}
.footer__legal-container a:not(:last-child) {
margin-right: 2em;
}
.footer__section .extra_margin {
margin-bottom: 40px;
}
.footer-social-links {
margin: -25px 0 20px;
display: flex;
gap: 8px;
}
.footer-social-icon {
width: 28px;
height: 28px;
display: inline-block;
flex-shrink: 0;
background-color: hsl(238.59deg 85.86% 80.59%);
mask-position: center;
mask-repeat: no-repeat;
mask-image: var(--footer-social-icon);
transition: background-color 150ms ease-out;
&:hover {
background-color: hsl(238.6deg 84.31% 90%);
}
&:active {
background-color: hsl(240deg 86.67% 97.06%);
}
}
/* #footer responsivity and global fixes */
@media (width <= 1280px) {
.footer__container {
justify-content: flex-start;
row-gap: 0;
}
.footer__legal-container {
justify-content: flex-end;
}
}
@media (width <= 600px) {
.footer__legal {
padding: 0 10px;
}
.footer__legal-spacer {
width: 100%;
}
.footer__legal-container {
column-gap: 20px;
justify-content: center;
& a:not(:last-child) {
margin-right: 0;
}
}
}
@media (width <= 400px) {
.footer__container {
gap: 0;
flex-direction: column;
}
.footer__section .extra_margin {
margin-bottom: 36px;
}
}
}

1127
web/styles/portico/hello.css Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,911 @@
/* Override `width: 100vw` from marketing_page.css, which makes
html wider than the visible content area when a classic scrollbar
is present — the CSS `vw` unit always includes the scrollbar's
width. That shifts every centered element rightward by half the
scrollbar width, producing asymmetric side margins on the gradient.
`scrollbar-gutter: stable` reserves gutter space even when no
scrollbar is shown, preventing layout jiggle when switching between
categories whose heights differ enough to add or remove the
vertical scrollbar. */
html:has(.portico-landing.integrations) {
width: auto;
scrollbar-gutter: stable;
}
.portico-landing.integrations {
--color-integrations-category-text: hsl(223deg 6% 35%);
/* Card-style border used for `.integration-lozenge` tiles on the
catalog and `.eligible_realm` rows on /communities. */
--color-integrations-card-border: hsl(0deg 0% 88%);
--color-integrations-card-border-hover: hsl(0deg 0% 73%);
color: hsl(0deg 0% 27%);
font-weight: normal;
/* Extra gradient space below the main card before the footer.
This is padding-bottom on .portico-landing (not margin-bottom
on .main), so the blue gradient background fills the space
instead of margin-collapsing through to an invisible external
gap. */
padding-bottom: 60px;
/* Modern blue gradient background, matching /plans and the homepage.
This replaces the complex multi-layer gradient system from
zerver/gradients.html (which is no longer included on these pages). */
background: linear-gradient(
180deg,
var(--color-background-gradient-start) 0%,
var(--color-background-gradient-end) 100%
);
& h1,
h2,
h3 {
&:hover::after {
content: none;
}
}
.markdown {
font-size: 1.1rem;
}
.main {
width: calc(100% - 100px);
max-width: 1170px;
margin: 0 auto;
border-radius: 10px;
background-color: hsl(0deg 0% 100%);
/* The catalog page gets a gray content area so the white
integration cards stand out. Specific integration doc pages
keep the default white content background. */
&:has(.catalog) {
background-color: hsl(0deg 0% 96%);
}
& img {
/* Replace the Bootstrap image reset that the new
integrations_bundle no longer provides. Without these,
images embedded in integration instructions render at
their natural size and overflow the content column. */
max-width: 100%;
height: auto;
vertical-align: middle;
box-shadow: none;
border: none;
}
/* Below 1000px the sidebar is hidden, so narrow the main's
own side margins at the same breakpoint. This keeps the
"blue gradient strip" on each side of the main card
consistently sized across the two primary layouts. */
@media (width <= 1000px) {
width: calc(100% - 50px);
}
@media (width <= 450px) {
width: 100%;
}
}
.padded-content {
/* `.integration-request` already supplies 20px of bottom
padding, so we only need a small bottom gap here to give
the buttons breathing room inside the gray card. */
padding: 50px 0 20px;
.inner-content {
min-height: 870px;
}
@media (width <= 450px) {
padding: 40px 0 20px;
}
/* On doc pages at narrow widths the header is a compact
logo + name + back row, so it needs less top breathing
room than the catalog page's tall heading block. */
&:has(#integration-instructions-group) {
@media (width <= 1000px) {
padding-top: 25px;
}
}
}
& ol li {
list-style: none;
& ul li {
list-style: inherit;
}
}
/* Left-align the header block with the cards column, so the title,
subtitle, and search box don't spill into the sidebar area. The
sidebar column below takes 230 px (200 sidebar + 30 gutter),
and the first visible `.integration-lozenge` sits another 5 px
further right due to its own horizontal margin, so we pad the
header block to start at 265 px from the main card's left edge
to land on the card's visible left edge. At narrow widths, the
sidebar is hidden and the header reverts to its original
near-full-width layout. */
.integration-main-text {
padding: 0 30px 0 265px;
@media (width <= 1000px) {
padding: 0 30px;
}
}
.portico-page-heading {
font-size: 2.5em;
font-weight: 300;
line-height: 1.2;
text-align: center;
/* When the heading wraps to multiple lines at narrow widths,
balance the line widths so the top line doesn't end up much
longer than the bottom (which makes a centered title look
visually off-center). */
text-wrap: balance;
/* At widths where the sidebar is visible, left-align the
title so its left edge matches the left edge of the cards
column below. */
@media (width > 1000px) {
text-align: left;
}
}
.portico-page-subheading {
font-weight: 400;
font-size: 1.1em;
color: hsl(0deg 0% 40%);
line-height: 1.2;
text-align: center;
@media (width > 1000px) {
text-align: left;
}
}
/* Markdown-style blue links used in the page subheading and in
content areas that render user-facing text. */
.portico-page-subheading a,
.integration-instructions a,
.eligible_realm_end_notice a {
color: var(--color-link);
text-decoration: underline;
text-decoration-color: var(--color-link-underline);
text-underline-offset: 0.1176em;
&:hover {
color: var(--color-link-hover);
text-decoration-color: var(--color-link-underline-hover);
}
}
#integration-search {
margin-bottom: 30px;
padding: 0 30px 0 265px;
@media (width <= 1000px) {
padding: 0 30px;
margin-bottom: 10px;
}
.searchbar {
display: flex;
justify-content: center;
margin: 30px auto 0;
/* At widths where the sidebar is visible, left-align the
search box so its left edge matches the left edge of
the cards column below. */
@media (width > 1000px) {
justify-content: flex-start;
}
.searchbar-reset {
position: relative;
width: 100%;
max-width: 500px;
.search_input {
/* border-box so width:100% includes the 70px of
horizontal padding; otherwise the search box
overflows its 500px cap by padding width. */
box-sizing: border-box;
font-size: 1em;
font-family: inherit;
width: 100%;
height: 45px;
padding: 0 20px 0 50px;
border-radius: 5px;
border: 1px solid hsl(0deg 0% 80%);
display: block;
color: hsl(0deg 0% 33%);
margin-bottom: 10px;
transition: border-color linear 0.2s;
&:focus {
border-color: var(--color-link);
outline: 0;
}
}
& .zulip-icon-search {
position: absolute;
left: 18px;
top: 13px;
font-size: 18px;
color: hsl(0deg 0% 53%);
pointer-events: none;
}
}
}
}
.catalog {
/* `flow-root` makes .catalog a new block formatting context
that contains the floated sidebar, so when a category has
few cards the sidebar doesn't overflow past .catalog's
bottom into the page background below. */
display: flow-root;
margin-top: 20px;
padding: 0 30px;
min-height: 500px;
.integration-categories-sidebar {
float: left;
width: 200px;
padding: 0 30px 0 0;
margin: 0;
&.sticky {
position: sticky;
top: 40px;
margin: auto;
height: 490px;
z-index: 10;
}
& h3 {
font-weight: 700;
font-size: 1.1em;
margin: 0 0 5px;
color: var(--color-integrations-category-text);
}
/* Visually separate "Custom integrations" (the second h3)
from the last category pill above it. */
& h3 ~ h3 {
margin-top: 20px;
}
& a {
display: block;
text-decoration: none;
font-weight: 400;
font-size: 0.95em;
padding: 6px 10px;
margin: 2px 0;
border-radius: 5px;
color: var(--color-integrations-category-text);
cursor: pointer;
&:hover {
color: hsl(223deg 6% 15%);
}
&.selected {
background-color: hsl(0deg 0% 100%);
color: hsl(223deg 6% 25%);
/* !important is needed to override the
`.portico-landing a:not(.button) {
font-weight: inherit !important }` rule
in marketing_page.css. */
font-weight: 600 !important;
}
}
@media (width <= 1000px) {
display: none;
}
}
}
.integration-categories-dropdown {
display: none;
/* Match the search box at narrow widths: the outer container
takes 30px horizontal padding, and the inner elements
(toggle + list) cap at 500px and center within the content
area — mirroring the `#integration-search { padding: 0 30px }`
+ `.searchbar-reset { max-width: 500px }` structure. */
@media (width <= 1000px) {
display: block;
margin: 0;
padding: 0 30px;
& h3 {
font-weight: 400;
font-size: 1.1em;
text-align: left;
margin: 0;
padding: 12px 20px;
&.heading {
font-weight: 600;
}
}
.integration-toggle-categories-dropdown,
.dropdown-list {
/* border-box so the 1px border is included in the
500px cap, matching the search input's dimensions
exactly. */
box-sizing: border-box;
width: 100%;
max-width: 500px;
margin-left: auto;
margin-right: auto;
}
.integration-toggle-categories-dropdown {
cursor: pointer;
display: flex;
position: relative;
padding: 0;
align-items: center;
justify-content: space-between;
/* White background so the toggle button stands out
from the gray catalog content area, matching the
white-highlight selected pill in the wide-window
sidebar. */
background-color: hsl(0deg 0% 100%);
border: 1px solid hsl(0deg 0% 80%);
/* Match the rounded corners of the search input. */
border-radius: 5px;
}
& i {
margin-right: 10px;
font-size: 24px;
}
/* The outer box is on the list container, so the items
inside have no borders and no dividers between them.
`border-top: 0` lets the list visually continue the
toggle's bottom edge without a double line. Only the
bottom corners are rounded; `overflow: hidden` clips
the selected item's white background so it doesn't
extend past the rounded border at the bottom. */
.dropdown-list {
display: none;
cursor: pointer;
padding: 0;
border: 1px solid hsl(0deg 0% 80%);
border-top: 0;
border-radius: 0 0 5px 5px;
overflow: hidden;
& a {
display: block;
text-decoration: none;
font-weight: 400;
font-size: 1em;
padding: 12px 20px;
color: var(--color-integrations-category-text);
&:hover {
color: hsl(223deg 6% 15%);
}
&.selected {
background-color: hsl(0deg 0% 100%);
color: hsl(223deg 6% 25%);
font-weight: 600 !important;
}
}
}
}
/* While the dropdown list is open, square the toggle's
bottom corners so they meet the list's straight top edge
cleanly instead of showing a rounded-to-straight seam.
jQuery's `slideToggle` sets `style="display: block"` inline
on the list when open, which we detect via :has(). */
&:has(.dropdown-list[style*="display: block"])
.integration-toggle-categories-dropdown {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
}
.integration-lozenges {
overflow: hidden;
text-align: left;
@media (width <= 1000px) {
text-align: center;
}
/* The lozenge cards are wrapped in bare <a> tags, which
inherit the browser-default underline. Suppress it so
the underline doesn't peek through the whitespace gaps
between inline-block cards as visible dashes. */
& > a {
text-decoration: none;
}
}
.integration-lozenge {
vertical-align: top;
width: 153px;
height: 200px;
padding: 0 4px;
margin: 7px 5px;
border-radius: 5px;
border: 1px solid var(--color-integrations-card-border);
background-color: hsl(0deg 0% 100%);
color: var(--color-integrations-category-text);
text-align: center;
transition: 0.3s ease;
transition-property: border-color;
&:not([hidden]) {
display: inline-block;
}
&:hover {
border-color: var(--color-integrations-card-border-hover);
}
.integration-secondary-line-text {
margin: 0;
line-height: 10px;
font-size: 0.65em;
font-weight: 400;
}
.integration-category,
.realm-category {
font-size: 0.85em;
margin-top: 5px;
font-weight: 400;
color: hsl(216deg 23% 13% / 50%);
}
&.without-category {
height: 180px;
}
.integration-logo {
margin: 34px auto 20px;
height: 60px;
}
.fa-plus {
font-size: 59px;
}
.integration-name {
font-size: 1.2em;
font-weight: 400;
margin: 10px 4px 0;
&.with-secondary {
font-size: 1.1em;
margin-top: 4px;
}
}
@media (width <= 830px) {
width: 134px;
height: 180px;
.integration-logo {
margin: 34px auto 15px;
height: 45px;
}
.fa-plus {
font-size: 45px;
}
.integration-name {
font-size: 1em;
}
.integration-category,
.realm-category {
font-size: 0.8em;
}
}
@media (width <= 375px) {
width: 120px;
}
@media (width <= 357px) {
width: 108px;
height: 160px;
&.without-category {
height: 140px;
}
.integration-logo {
margin: 28px auto 10px;
height: 45px;
}
.integration-name {
font-size: 0.9em;
}
.integration-category,
.realm-category {
font-size: 0.77em;
}
}
}
.integration-request {
font-size: 1em;
/* Generous top/bottom padding so the "Don't see an integration
you need?" section has visible breathing room between the
last row of cards above and the section content below. */
padding: 40px 0 20px;
/* At widths where the header is left-aligned, left-align
the bottom section to match. The 5px left padding lines
up the text with the visible card edges, since each
`.integration-lozenge` has a 5px horizontal margin. */
@media (width > 1000px) {
text-align: left;
padding-left: 5px;
}
& p {
margin: 0 0 20px;
}
/* Lay out the /why-zulip-style hero-buttons as a flex row,
since the flex rule in marketing_page.css is scoped to
.why-page and its siblings. Centered at narrow widths,
left-aligned at wide widths to match the header. */
.hero-buttons {
display: flex;
flex-flow: row wrap;
justify-content: center;
@media (width > 1000px) {
justify-content: flex-start;
/* Each .button has 10px margin from marketing_page.css,
which pushes its visible border right of the text
above. Pull the flex container left to compensate. */
margin-left: -10px;
}
}
}
/* -- integration instructions -- */
#integration-instructions-group {
padding: 0 50px;
display: flex;
.integration-instruction-block {
display: flex;
flex-direction: column;
/* Let the left column size to its widest child (the logo
box, or a long category pill) plus a right-padding
gutter. The instructions column uses `flex: 1` to fill
the remaining space. */
flex-shrink: 0;
padding-right: 30px;
.integration-lozenge {
width: 125px;
height: auto;
padding: 0 5px 20px;
/* Align the top of the logo card with the visible
cap-height of the title's first character. This
`margin-top` is tuned so that the card's top edge
sits on the same horizontal line as the top of
the "Z" (or equivalent cap-height glyph) in the
h1 title, not on its typographic ascender line.
The value balances the 15px top margin the shared
markdown rules give h1 plus the half-leading and
ascender offset that sit above the visible glyph
in Source Sans 3 VF at the h1's font-size. */
margin: 25px 21px 20px;
order: 1;
.integration-category,
.realm-category {
display: none;
}
@media (width <= 1000px) {
border: none;
display: flex !important;
align-items: center;
justify-content: space-between;
height: auto;
width: auto;
margin: unset;
padding: unset;
.integration-logo {
/* Override the shared catalog-card rule at
`@media (width <= 830px)` that shrinks logos
to 45px — the doc-page header should keep the
full-size logo at every width. */
height: 60px;
margin: 0;
}
.integration-name {
font-size: 1.2em !important;
margin: 0 0 0 20px;
}
}
}
.name {
display: none;
font-size: 1.4em;
font-weight: 400;
margin: 0;
padding-bottom: 35px;
}
.categories {
order: 2;
/* Left-align the pills with the logo box above, which
has `margin: 0 21px 20px` on `.integration-lozenge`. */
margin-left: 21px;
/* Each category is its own <a> wrapping an <h3>. Lay
them out as a vertical flex column so the pills are
sized to their content (like in-app pills) instead
of stretching to a fixed width. */
display: flex;
flex-direction: column;
align-items: flex-start;
& a {
text-decoration: none;
}
.integration-category,
.realm-category {
font-size: 0.95em;
font-weight: 400;
padding: 5px 14px;
margin: 0 0 6px;
border-radius: 14px;
background-color: hsl(210deg 94% 42% / 10%);
color: hsl(210deg 70% 35%);
&:hover {
background-color: hsl(210deg 94% 42% / 17%);
color: hsl(210deg 70% 28%);
}
}
}
#integration-list-link {
margin-left: 30px;
order: 3;
color: var(--color-integrations-category-text);
text-decoration: none;
display: flex;
align-items: center;
.zulip-icon-arrow-left {
font-size: 16px;
margin-right: 5px;
}
/* Show "Back to list" on wide screens, "Back" on
narrow where space is limited. */
.integrations-back-label-short {
display: none;
}
@media (width <= 1000px) {
.integrations-back-label-long {
display: none;
}
.integrations-back-label-short {
display: inline;
}
}
&:hover {
color: hsl(223deg 6% 15%);
}
@media (width >= 1000px) {
margin-top: 15px;
}
}
@media (width <= 1000px) {
flex-direction: row;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
/* Drop the column-gutter padding on the right so
the back-link reaches the card's right edge
instead of sitting 30 px inside it. */
padding: 0 0 12px;
border-bottom: 1px solid hsl(0deg 0% 88%);
}
@media (width <= 1000px) {
.name {
display: block;
}
.categories {
display: none;
}
}
}
.integration-instructions {
.logos_disclaimer {
font-size: 14px;
font-style: italic;
}
@media (width >= 1000px) {
/* Fill whatever space the left column leaves after
sizing to its widest child. min-width: 0 lets the
column shrink below its intrinsic content size when
the viewport is narrow. */
flex: 1;
min-width: 0;
}
@media (width <= 1000px) {
margin-left: 0;
& h1:first-child {
margin-top: 0;
}
}
}
@media (width <= 1000px) {
flex-direction: column;
}
@media (width <= 768px) {
padding: 0 25px;
}
@media (width <= 450px) {
padding: 0 12px;
}
}
}
.portico-landing.integrations.communities {
.main {
max-width: 900px;
}
/* `.eligible_realm` has no horizontal margin, unlike
`.integration-lozenge` which has a 5 px left/right margin, so
the communities heading needs 5 px less left padding than the
integrations heading to line up with the first realm's visible
left edge. */
.integration-main-text {
padding-left: 260px;
@media (width <= 1000px) {
padding-left: 30px;
}
}
.portico-page-heading {
color: hsl(0deg 0% 0%);
font-size: 44px;
}
.portico-page-subheading {
font-weight: 300;
color: hsl(0deg 0% 20%);
max-width: 800px;
line-height: 150%;
margin: auto;
}
.integration-categories-sidebar h3 {
color: hsl(0deg 0% 0%);
font-size: 20px;
font-weight: 600;
}
.catalog {
margin-top: 50px;
}
.eligible_realms {
display: flex;
flex-direction: column;
.eligible_realm {
display: flex;
margin-bottom: 12px;
padding: 15px 20px;
border: 1px solid var(--color-integrations-card-border);
border-radius: 6px;
transition: border-color 0.3s ease;
background-color: hsl(0deg 0% 100%);
/* The card itself is an <a>, which would otherwise inherit
the underline from `.portico-landing a:not(.button)` in
marketing_page.css and visibly underline the name and
description text inside it. */
text-decoration: none;
&:hover {
border-color: var(--color-integrations-card-border-hover);
}
.eligible_realm_logo {
display: flex;
margin-right: 20px;
width: 60px;
height: 60px;
}
.eligible_realm_details {
display: flex;
flex-direction: column;
justify-content: center;
.eligible_realm_name {
font-weight: 400;
font-size: 21px;
color: hsl(220.6deg 20% 33.3%);
line-height: 23px;
margin: 0 0 2px;
}
.eligible_realm_description {
font-weight: 400;
font-size: 15px;
color: hsl(220deg 2.7% 56.5%);
line-height: 19px;
margin: 0;
/* For restricting text to only two lines.
See https://caniuse.com/?search=display%3A%20-webkit-box for support. */
overflow: hidden;
display: -webkit-box; /* stylelint-disable-line value-no-vendor-prefix */
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
}
}
& hr {
margin: 10px 0;
border: 0;
border-top: 1px solid hsl(0deg 0% 93%);
}
.eligible_realm_end_notice {
text-align: center;
font-size: 18px;
}
}
}

View File

@@ -0,0 +1,183 @@
#custom_http_headers {
width: 100%;
height: 60px;
resize: vertical;
}
#dev-panel {
margin-left: 3%;
margin-right: 3%;
padding: 20px 10px 15px;
background-color: hsl(0deg 0% 100% / 48%);
box-shadow: 0 0 40px hsl(0deg 0% 0% / 6%);
& textarea {
color: hsl(0deg 0% 33%);
background-color: hsl(0deg 0% 100%);
border-radius: 4px;
vertical-align: middle;
border: 1px solid hsl(0deg 0% 80%);
padding: 4px 6px;
margin-bottom: 10px;
font-size: 14px;
box-shadow: inset 0 1px 1px hsl(0deg 0% 0% / 7.5%);
transition:
border-color linear 0.2s,
box-shadow linear 0.2s;
&:focus {
border-color: hsl(206.5deg 80% 62% / 80%);
outline: 0;
box-shadow:
inset 0 1px 1px hsl(0deg 0% 0% / 7.5%),
0 0 8px hsl(206.5deg 80% 62% / 60%);
}
&:read-only {
cursor: not-allowed;
}
}
& select,
textarea,
input {
font-family: inherit;
}
& select {
height: 30px;
padding: 0 6px;
width: 220px;
font-size: 14px;
color: hsl(0deg 0% 33%);
border-radius: 4px;
border: 1px solid hsl(0deg 0% 80%);
margin-bottom: 10px;
cursor: pointer;
background-color: hsl(0deg 0% 100%);
vertical-align: middle;
}
& input {
padding: 4px 6px;
color: hsl(0deg 0% 33%);
border-radius: 4px;
border: 1px solid hsl(0deg 0% 80%);
box-shadow: inset 0 1px 1px hsl(0deg 0% 0% / 7.5%);
transition:
border-color linear 0.2s,
box-shadow linear 0.2s;
margin-bottom: 10px;
&:focus {
border-color: hsl(206deg 80% 62% / 80%);
outline: 0;
box-shadow:
inset 0 1px 1px hsl(0deg 0% 0% / 7.5%),
0 0 8px hsl(206deg 80% 62% / 60%);
}
}
}
#fixture_body {
width: 90%;
height: 500px;
resize: vertical;
}
#idp-results {
width: 100%;
height: 500px;
resize: vertical;
background-color: hsl(0deg 0% 100%);
}
.top-navbar {
display: grid;
grid-template-columns: 1fr 5fr 1fr;
}
#URL {
width: 100%;
}
#stream_name,
#topic_name {
width: 206px;
}
.buttons {
display: flex;
justify-content: space-between;
width: 92%;
margin-right: 2%;
button {
padding: 6px 12px;
color: hsl(0deg 0% 100%);
background-color: hsl(208deg 56% 53%);
border: 1px solid hsl(208deg 56% 47%);
&:hover,
&:active,
&:focus {
background-color: hsl(208deg 56% 45%);
border-color: hsl(208deg 56% 36%);
}
}
}
.centerpiece {
font-size: 30px;
text-align: center;
}
.inline {
display: flex;
flex-wrap: nowrap;
justify-content: space-between;
margin-right: 10%;
}
.optional {
color: hsl(0deg 0% 50%);
}
.pad-small {
height: 100px;
width: 100%;
}
.row1 {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin-left: 2%;
margin-right: 2%;
}
.row2 {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
margin-left: 2%;
margin-right: 2%;
}
.row3 {
display: flex;
flex-flow: column wrap;
justify-content: flex-start;
margin-left: 2%;
margin-right: 2%;
}
.row4 {
display: grid;
grid-template-columns: 1fr 1fr;
margin-left: 2%;
margin-right: 2%;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
@import url("../components.css");
@import url("portico_variables.css");
@import url("legacy_portico.css");
@import url("portico_modals.css");
@import url("portico_signin.css");
@import url("markdown.css");
@import url("navbar.css");
@import url("footer.css");

View File

@@ -0,0 +1,596 @@
.markdown {
/* Copied from app_variables.css to be used in portico pages. */
--color-copy-button: color-mix(
in oklch,
hsl(229deg 9% 36%) 70%,
transparent
);
--color-copy-button-hover: hsl(229deg 9% 36%);
--color-copy-button-active: color-mix(
in oklch,
hsl(229deg 9% 36%) 70%,
transparent
);
--color-copy-button-success: hsl(146deg 90% 27%);
/* User circles */
/* stylelint-disable color-no-hex */
--color-user-circle-active: light-dark(#43a35e, #4cdc75);
--color-user-circle-idle: light-dark(#f5b266, #ae640a);
--color-user-circle-offline: light-dark(#c1c6d7, #454854);
--color-user-circle-deactivated: hsl(0deg 0% 50%);
--gradient-user-circle-idle: linear-gradient(
to right,
var(--color-user-circle-idle) 5%,
light-dark(
color-mix(
in srgb,
var(--color-user-circle-idle) 78.9%,
transparent
),
var(--color-user-circle-idle)
)
25%,
transparent 100%
);
/* stylelint-enable color-no-hex */
font-weight: 400;
font-size: 1rem;
line-height: 1.5;
& h1[id],
h2[id],
h3[id],
h4[id] {
&::before {
display: block;
content: " ";
visibility: hidden;
}
}
& h2[id],
h3[id],
h4[id] {
&::before {
margin-top: -10px;
height: 10px;
}
}
& h1 {
border-bottom: 1px solid hsl(0deg 0% 93%);
padding-bottom: 10px;
margin-bottom: 15px;
&[id] {
&::before {
margin-top: -30px;
height: 30px;
}
}
&#zulip-administration {
font-size: 1.75em;
padding: 10px 0;
margin-bottom: 0;
line-height: 100%;
}
}
& h2 {
font-size: 1.5em;
line-height: 1.25;
margin: 20px 0 5px;
}
& h3 {
font-size: 1.25em;
line-height: 1.25;
opacity: 1;
margin: 20px 0 5px;
}
& h1,
h2,
h3 {
font-weight: 700;
user-select: none;
&:hover {
cursor: pointer;
&::after {
display: inline-block;
font: normal normal normal 16px/1 FontAwesome;
cursor: pointer;
content: "\f0c1";
margin-left: 5px;
vertical-align: middle;
}
}
}
& h5,
h6 {
margin: 10px 0;
line-height: 20px;
}
/* Since markdown doesn't make it easy to put an HTML element around a
markdown table, we instead have a model of putting an empty div
before it to configure a specific table's styling. */
& div.centered_table + table td:not(:first-child),
div.centered_table + table th {
text-align: center;
}
.legend_symbol {
position: absolute;
left: calc(340px);
transform: translateX(-50%);
/* Adjust for 50px closed left sidebar state */
@media (width <= 800px) {
left: calc(5% + 50px);
}
}
.legend_label {
position: relative;
left: calc(30px);
}
& li {
line-height: 150%;
}
& ol {
counter-reset: item;
list-style: none;
& > li {
position: relative;
vertical-align: top;
/* This needs to be wide enough for 2-digit numbers. */
padding-left: 33px;
top: -2px;
counter-increment: item;
&::before {
position: absolute;
top: 0;
left: 0;
content: counter(item);
display: inline-block;
vertical-align: top;
padding: 3px 6.5px 3px 7.5px;
margin-right: 5px;
background-color: var(--color-link);
color: hsl(0deg 0% 100%);
border-radius: 100%;
font-size: 0.9em;
line-height: 1.1;
text-align: center;
}
.codehilite {
background-color: hsl(0deg 0% 100%);
& pre {
white-space: pre;
overflow-x: auto;
}
}
& > ul {
margin-bottom: 5px;
}
}
@media (width <= 500px) {
margin-left: 0;
}
}
& ul {
margin: 0 10px 15px 25px;
/* Avoid extra whitespace after nested bulleted lists. */
& ul {
margin: 0 20px;
}
& > li {
margin: 5px 0 10px;
& > p {
margin: 0 0 5px;
}
& > p:first-child {
margin: 0;
}
}
}
.content {
padding: 30px;
max-width: 700px;
background-color: hsl(0deg 0% 100%);
& ol li p:not(:first-child) {
display: block;
}
& > ol {
margin: 15px 10px;
& > li {
margin: 2.5px 0;
}
}
& i.icon-collapsed-state {
transform: rotate(270deg);
}
@media (width <= 500px) {
padding: 10px;
}
}
& i.zulip-icon {
margin: 0 2px 2px;
vertical-align: middle;
}
& i.zulip-icon.mobile-help {
color: hsl(244deg 69% 62%);
}
& a {
color: hsl(176deg 46% 41%);
font-weight: 600;
& code {
color: hsl(176deg 46% 41%);
}
}
& strong {
font-weight: 600;
}
& img {
vertical-align: top;
box-shadow: 0 0 4px hsl(0deg 0% 0% / 5%);
border: 1px solid hsl(0deg 0% 87%);
border-radius: 4px;
&.inline {
height: 1.4em;
box-shadow: none;
}
}
.warn,
.tip,
.keyboard_tip {
position: relative;
display: block;
background-color: hsl(210deg 22% 96%);
border: 1px solid hsl(210deg 22% 90%);
border-radius: 4px;
padding: 10px;
margin: 5px 0;
& p {
margin-bottom: 0;
}
& p:first-of-type {
display: inline;
}
}
.tip,
.keyboard_tip {
background-color: hsl(46deg 63% 95%);
border: 1px solid hsl(46deg 63% 84%);
}
.tip::before {
display: inline;
content: "\f0eb Tip: ";
font-family: FontAwesome, "Source Sans 3 VF", sans-serif;
font-weight: 600;
}
.keyboard_tip::before {
display: inline;
content: "\f11c Keyboard shortcut: ";
font-family: FontAwesome, "Source Sans 3 VF", sans-serif;
font-weight: 600;
}
.user-circle {
/* We make the circles slightly larger than in the
sidebar UI, so they look good next to the copy. */
font-size: 0.7em;
display: inline-block;
/* 1.5px at 11.2px/1em */
vertical-align: 0.1339em;
}
.user-circle-active {
color: var(--color-user-circle-active);
}
.user-circle-idle {
background: var(--gradient-user-circle-idle);
background-clip: text;
-webkit-text-fill-color: transparent;
}
.with_avatar .user-circle-idle {
background: var(--gradient-user-circle-idle-avatar);
}
.user-circle-offline {
color: var(--color-user-circle-offline);
}
.user-circle-deactivated {
color: var(--color-user-circle-deactivated);
}
& kbd {
/* Same as kbd in app_components.css */
display: inline-block;
border: 1px solid hsl(0deg 0% 80%);
border-radius: 4px;
font-weight: 600;
white-space: nowrap;
background-color: hsl(0deg 0% 98%);
color: hsl(0deg 0% 20%);
text-shadow: 0 1px 0 hsl(0deg 0% 100%);
/* Different from app_components.css */
/* Removed margin setting */
font-size: 0.85em;
padding: 0 0.4em;
&.arrow-key {
/* Same as in informational_overlays.css */
line-height: 1;
padding: 0 0.2em 0.2em;
/* Different from informational_overlays.css */
font-size: 1.2em;
}
}
& code {
/* Same font-family as zulip.css */
font-family: "Source Code Pro", monospace;
/* Same as base rules for code elements in rendered_markdown.css */
font-size: 0.825em;
unicode-bidi: embed;
direction: ltr;
color: hsl(0deg 0% 0%);
border-radius: 3px;
/* Different from base rules for code elements in rendered_markdown.css */
white-space: initial;
padding: 0 4px;
background-color: hsl(0deg 0% 93%);
overflow-wrap: break-word;
}
.codehilite {
/* Relative positioning is used to place the copy-to-clipboard button
in the top-right corner. */
position: relative;
}
& pre {
& code {
font-size: 14px;
white-space: pre-wrap;
padding: 0;
color: inherit;
background-color: transparent;
border: 0;
}
}
.copy-codeblock {
cursor: pointer;
/* Invisible default button */
background: none;
border: none;
padding: 0;
position: absolute;
/* Position the button in the top-right corner */
top: 10px;
right: 10px;
line-height: 3px;
&:focus {
outline-offset: -1px;
outline-color: hsl(176deg 46% 41%);
}
}
.copy-button {
display: flex;
border-radius: 4px;
color: var(--color-copy-button);
/* 2px at 16px/1em */
padding: 0.125em;
cursor: pointer;
&:hover,
&:focus-visible {
color: var(--color-copy-button-hover);
}
&:active {
color: var(--color-copy-button-active);
}
&.copy-button-success {
color: var(--color-copy-button-success);
}
}
.tabbed-section {
& ol {
margin-left: 15px;
margin-top: 10px;
}
& ul.nav {
margin: 0;
& li {
display: inline-block;
padding: 5px 14px;
margin: 0;
cursor: pointer;
&.active {
color: var(--color-link);
margin-bottom: -1px;
border: 1px solid hsl(0deg 0% 87%);
border-bottom: 1px solid hsl(0deg 0% 100%);
border-radius: 4px 4px 0 0;
}
}
}
&.no-tabs ul.nav {
display: none;
}
.blocks {
padding: 10px;
margin-bottom: 10px;
border: 1px solid hsl(0deg 0% 87%);
.tab-content {
display: none;
}
}
&.has-tabs .blocks {
border-radius: 0 6px 6px;
}
/* A "no-tabs" section is a degenerate zero-tabs wrapper that
just holds flowing markdown content. The border and radius
on `.blocks` exist to visually group a tab bar with the
content below it, which is meaningless when there's no tab
bar — it just draws a random frame around a subset of the
content. Drop the frame in that case.
Reset padding to 0 and use `margin-block` instead so that
the top/bottom margins collapse with adjacent paragraphs,
the first list item's margin, etc. — that gives a natural,
single breathing-room gap of ~20 px instead of stacking
the preceding paragraph's 10 px margin on top of the
block's own space. */
&.no-tabs .blocks {
padding: 0;
margin-block: 20px;
border: 0;
border-radius: 0;
}
&.no-tabs .blocks > .tab-content,
&.has-tabs .blocks > .active {
display: block;
}
}
& blockquote {
padding: 0 0 0 15px;
margin: 0 0 20px;
border-left: 5px solid hsl(0deg 0% 93%);
& p {
font-size: 17.5px;
font-weight: 300;
line-height: 1.25;
margin-bottom: 0;
}
}
}
/* Shared element-level styling for pages that render markdown as
content documentation: /help and /api pages (under `.help .markdown`)
and integration doc pages (under `.integration-instructions`).
Keeping these rules in one place lets both the help bundle and the
integrations bundle depend on a single source of truth — markdown.css
is already loaded by both. Marketing pages (which also load this
file but don't match either selector) are intentionally unaffected,
because their layouts rely on different defaults for lists,
paragraph margins, and so on. */
.help .markdown,
.integration-instructions {
& p {
margin: 0 0 10px;
}
& p:empty {
margin: 0;
}
& h1 {
margin-top: 15px;
}
& h4 {
margin: 15px 0 5px;
}
& hr {
margin: 20px 0;
border: 0;
border-top: 1px solid hsl(0deg 0% 93%);
}
/* Reset the browser-default left padding on lists so numbered
items and bullets align with surrounding paragraphs. */
& ul,
& ol {
padding: 0;
}
/* Fenced code blocks: light gray card with a subtle border and
rounded corners. The 15px vertical margins give surrounding
paragraphs visible breathing room around the code card, which
a tighter 10px bottom margin (and 0 top) was not providing.
The explicit font-size matches the `pre code` rule in .markdown
above and ensures code blocks render at the same size whether
the codehilite wraps content in <code> or not (some integration
pages generate bare <pre> without a <code> child). */
& pre {
padding: 9.5px;
margin: 15px 0;
font-family: "Source Code Pro", monospace;
font-size: 14px;
color: hsl(0deg 0% 0%);
word-break: break-all;
line-height: 20px;
background-color: hsl(0deg 0% 96%);
border: 1px solid hsl(0deg 0% 0% / 15%);
border-radius: 4px;
}
/* Inline `<code>` inside a link inherits the link color. */
& a code {
color: var(--color-link);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,763 @@
:root {
/* Actual navbar height is determined by label padding
(16px top/bottom) and line-height (28px): 16 + 28 + 16 = 60px.
Keep this variable in sync with those values. */
--navbar-height: 60px;
--announcement-banner-background: hsl(216deg 90% 82%);
--announcement-banner-foreground: hsl(240deg 100% 5.9%);
--announcement-banner-border: hsl(240deg 100% 5.9% / 12%);
--announcement-banner-link-underline: hsl(240deg 100% 5.9% / 80%);
}
/* Suppress rubber-band overscroll on marketing pages: the banner is
sticky and in-flow while .top-menu is fixed, so during overscroll
above scroll: 0 the banner briefly drifts down with the document
while the navbar stays pinned, exposing a gap and visually
overlapping the navbar's top edge. */
html {
overscroll-behavior-y: none;
}
/* Announcement banner above the marketing nav, shown when
LANDING_PAGE_NAVBAR_MESSAGE is configured. Lives in navbar.css
(loaded by every marketing-page bundle, including landing-page-hello)
so /hello renders it identically to /plans, /why-zulip, etc.
position: sticky keeps the banner in flow — so .top-menu's
`position: fixed; top: auto` still resolves to "just below this
banner" — while pinning the banner to the viewport top on scroll.
z-index 11 sits above .top-menu (z-index 10) so the two sit
flush during scroll without flicker. */
#navbar-custom-message {
position: sticky;
top: 0;
z-index: 11;
padding: 10px;
text-align: center;
font-size: 1.125rem; /* 18px at 16px/1rem */
font-weight: 450;
letter-spacing: 0.01em;
background: var(--announcement-banner-background);
color: var(--announcement-banner-foreground);
border-bottom: 1px solid var(--announcement-banner-border);
& a {
color: var(--announcement-banner-foreground);
text-decoration: underline;
text-decoration-color: var(--announcement-banner-link-underline);
text-decoration-thickness: 2px;
text-underline-offset: 2px;
transition: text-decoration-color 0.2s;
}
& a:hover {
text-decoration-color: var(--announcement-banner-foreground);
}
}
details summary::-webkit-details-marker {
/* Hide the default arrow on Safari. */
display: none;
}
.top-menu :focus-visible {
/* Show white outline by default */
/* This overrides outline-style: auto which
renders a double outline of white and dark blue */
outline: 1px solid hsl(0deg 0% 100%);
&.top-menu-item,
&.nav-menu-label {
outline-offset: -2px;
}
}
.nav-zulip-logo {
background-image: url("data:image/svg+xml,%3Csvg width='108' height='28' viewBox='0 0 108 28' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23clip0_555_12341234)'%3E%3Cpath d='M25.0534 4.18667C25.0534 5.59714 24.4217 6.85034 23.4589 7.6106L14.1128 15.9802C13.9392 16.1294 13.7136 15.8888 13.8388 15.688L17.267 8.80536C17.3631 8.61266 17.2385 8.37582 17.0414 8.37582H3.7444C1.68498 8.37582 0 6.49104 0 4.18791C0 1.88416 1.68498 6.14715e-07 3.7444 6.14715e-07H21.309C23.3684 -0.00124264 25.0534 1.88353 25.0534 4.18667ZM3.7444 28H21.309C23.3684 28 25.0534 26.1152 25.0534 23.8121C25.0534 21.5083 23.3684 19.6242 21.309 19.6242H8.01203C7.81489 19.6242 7.69029 19.3873 7.78638 19.1946L11.2146 12.312C11.3398 12.1112 11.1142 11.8706 10.9406 12.0198L1.59447 20.3882C0.631713 21.1478 0 22.4016 0 23.8121C0 26.1152 1.68498 28 3.7444 28ZM36.136 20.2825L43.8715 9.11804V9.02107H36.8588V5.97633H48.6431V8.10292L41.0762 19.1225V19.2195H48.764V22.2642H36.136V20.2825V20.2825ZM57.1505 5.97633V15.353C57.1505 18.1559 58.2106 19.5819 60.0909 19.5819C62.0189 19.5819 63.0789 18.2286 63.0789 15.353V5.97633H66.7421V15.1105C66.7421 20.137 64.2116 22.5291 59.97 22.5291C55.8728 22.5291 53.4631 20.2576 53.4631 15.0621V5.97633H57.1505V5.97633ZM72.3333 5.97633H76.0207V19.1704H82.4792V22.2636H72.3333V5.97633ZM90.7454 5.97633V22.2636H87.058V5.97633H90.7454ZM96.3359 6.1939C97.4686 6.00058 99.0593 5.85574 101.3 5.85574C103.566 5.85574 105.181 6.29088 106.265 7.16054C107.301 7.98233 108 9.33561 108 10.9301C108 12.5252 107.47 13.8785 106.506 14.7966C105.253 15.9808 103.397 16.5123 101.228 16.5123C100.747 16.5123 100.313 16.4881 99.9756 16.4396V22.2636H96.3366V6.1939H96.3359ZM99.975 13.5888C100.288 13.6615 100.674 13.6851 101.204 13.6851C103.156 13.6851 104.361 12.6943 104.361 11.0271C104.361 9.52894 103.324 8.63442 101.493 8.63442C100.746 8.63442 100.24 8.70715 99.975 8.77926V13.5888V13.5888Z' fill='white'%3E%3C/path%3E%3C/g%3E%3Cdefs%3E%3CclipPath id='clip0_555_12341234'%3E%3Crect width='108' height='28' fill='white'%3E%3C/rect%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E");
background-repeat: no-repeat;
width: 108px;
}
.top-menu {
position: fixed;
width: 100%;
background: hsl(240deg 100% 10% / 60%);
backdrop-filter: blur(10px);
color: hsl(0deg 0% 100%);
z-index: 10;
overflow: hidden;
transition: background-color 0.3s ease-out;
&:hover {
background: hsl(240deg 100% 10% / 85%);
}
}
.top-menu-container {
/* 1280px + 32px for paddings on the edges */
max-width: 1312px;
margin: 0 auto;
display: flex;
align-items: center;
}
.top-menu-logo {
overflow: hidden;
opacity: 0.85;
/* 14*2 = 28px = height of logo svg */
padding: 14px;
margin: 0 16px;
flex-shrink: 0;
}
.top-menu-items-group-1,
.top-menu-items-group-2 {
display: flex;
}
.top-menu-items-group-1 {
margin-right: 16px;
}
.top-menu-mobile a {
&,
&:hover,
&:focus,
&:visited {
color: hsl(0deg 0% 100% / 80%);
}
}
.top-menu-item {
display: flex;
align-items: center;
flex-shrink: 0;
font-style: normal;
font-weight: 400;
font-size: 20px;
line-height: 28px;
padding: 14px;
user-select: none;
cursor: pointer;
transition-property: background, color;
transition-duration: 0.05s;
transition-timing-function: ease-out;
&,
&:visited {
color: hsl(0deg 0% 100% / 80%);
text-decoration: none;
}
}
.top-menu-item:hover {
color: hsl(0deg 0% 100%);
background: hsl(240deg 100% 10% / 10%);
transition-duration: 0.05s;
}
.top-menu-item:active {
color: hsl(0deg 0% 100%);
background: hsl(240deg 100% 10% / 20%);
}
.top-menu-item.top-menu-tab,
.top-menu-item.top-menu-tab:hover,
.top-menu-item.top-menu-tab:active {
opacity: 1;
background: none;
}
.top-menu-item-spacer {
flex-shrink: 1;
flex-grow: 1;
}
.top-menu-item input[type="radio"],
.top-menu-tab-input-unselect {
display: none;
}
.top-menu-item.top-menu-tab {
padding: 0;
position: relative;
cursor: auto;
}
.top-menu-tab-unselect {
position: absolute;
inset: 0;
z-index: 0;
cursor: pointer;
}
.top-menu-tab-input:checked + label {
transition:
background,
color 0.2s;
background: hsl(240deg 100% 10% / 60%);
color: hsl(0deg 0% 100%);
pointer-events: none;
user-select: none;
}
.top-menu-tab label {
padding: 16px;
cursor: pointer;
transition-property: background, color;
transition-duration: 0.1s;
transition-timing-function: ease-out;
z-index: 5;
color: hsl(0deg 0% 100% / 80%);
/* Override bootstrap */
margin-bottom: 0;
font-size: inherit;
line-height: inherit;
}
.top-menu-tab label::after {
pointer-events: none;
content: " ";
display: inline-block;
vertical-align: middle;
width: 16px;
height: 16px;
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgba(255%2c255%2c255%2c0.8)' stroke-width='3' stroke-linecap='round' stroke-linejoin='round' class='feather feather-chevron-down'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
background-size: 16px;
margin-left: 2px;
margin-right: -8px;
background-repeat: no-repeat;
}
.top-menu-tab .top-menu-tab-input:checked + label::after {
transform: rotate(-180deg);
}
.top-menu-tab .top-menu-tab-input:not(:checked) + label:hover {
background: hsl(240deg 100% 10% / 10%);
color: hsl(0deg 0% 100%);
transition-duration: 0.1s;
}
.top-menu-tab .top-menu-tab-input:not(:checked) + label:active {
background: hsl(240deg 100% 10% / 20%);
color: hsl(0deg 0% 100%);
}
.top-menu-tab label.top-menu-tab-user-label::after {
display: block;
position: absolute;
right: 16px;
top: 50%;
transform: translateY(-45%);
}
.top-menu-tab
.top-menu-tab-input:checked
+ label.top-menu-tab-user-label::after {
transform: translateY(-45%) rotate(-180deg);
}
.top-menu-submenu-backdrop {
background: hsl(240deg 100% 10% / 60%);
opacity: 0;
height: 0;
width: 100%;
transition: 0.05s;
transition-property:
height, opacity; /* stylelint-disable-line plugin/no-low-performance-animation-properties */
}
.top-menu-tab-input-unselect:not(:checked) + .top-menu-submenu-backdrop {
height: 334px;
opacity: 1;
}
.top-menu-tab-label-unselect {
position: absolute;
display: none;
/* To account for scrollbar if any present. */
right: 15px;
top: var(--navbar-height);
width: 44px;
height: 44px;
background-size: 32px;
background-repeat: no-repeat;
/* Close menu icon */
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgba(255,255,255,1)' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3e%3cline x1='18' y1='6' x2='6' y2='18'%3e%3c/line%3e%3cline x1='6' y1='6' x2='18' y2='18'%3e%3c/line%3e%3c/svg%3e");
background-position: center;
cursor: pointer;
opacity: 0.5;
}
.top-menu-tab-label-unselect:hover {
opacity: 0.8;
}
.top-menu-tab-label-unselect:active {
opacity: 1;
}
.top-menu-tab-input-unselect:not(:checked) ~ .top-menu-tab-label-unselect {
display: block;
}
.top-menu-submenu {
position: absolute;
top: var(--navbar-height);
display: flex;
gap: 16px;
opacity: 0;
visibility: hidden;
transition: 0.2s;
transition-property: opacity, visibility;
}
#case-studies-submenu {
width: 100vw;
position: fixed;
left: 0;
justify-content: center;
@media (width <= 1300px) {
flex-wrap: wrap;
place-content: baseline flex-start;
height: calc(100vh - var(--navbar-height));
overflow-y: auto;
width: 100vw;
padding-left: 10px;
}
& > .top-menu-submenu-column:last-child {
/* Bottom padding provides space for the scroll fade
indicator so no content is obscured at end of scroll. */
padding-bottom: 50px;
}
/* Fade bottom edge to hint at scrollable content. */
mask-image: linear-gradient(
to bottom,
hsl(0deg 0% 0%) calc(100% - 50px),
transparent 100%
);
}
/* Prevent background scrolling when the case studies dropdown
covers the full viewport height on narrower desktop screens.
Lower bound excludes widths where the desktop navbar is hidden. */
@media (width > 1100px) and (width <= 1300px) {
body:has(#top-menu-tab-case-studies:checked) {
overflow: hidden;
}
}
.top-menu-tab .top-menu-tab-user-label {
max-width: 140px;
padding-right: 28px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.top-menu-tab-user-img {
width: 24px;
height: 24px;
display: inline;
vertical-align: middle;
border-radius: 3px;
margin-right: 4px;
}
.top-menu-mobile-user-img {
width: 28px;
height: 28px;
display: inline;
vertical-align: text-top;
border-radius: 3px;
margin-right: 4px;
}
@media (width <= 1400px) {
.top-menu-submenu.signup-column {
justify-content: flex-end;
right: 55px;
}
}
@media (width <= 1024px) {
.top-menu-tab .top-menu-tab-user-label {
max-width: 40px;
}
.top-menu-tab .top-menu-tab-user-label .top-menu-tab-user-name {
display: none;
}
}
.top-menu-tab-input:checked ~ .top-menu-submenu {
opacity: 1;
visibility: visible;
}
.top-menu-submenu-column {
display: flex;
flex-direction: column;
padding-top: 16px;
flex-shrink: 0;
max-width: 420px;
.top-menu-submenu-list {
margin: 0;
padding-left: 0;
list-style: none;
.top-menu-submenu-list-item {
font-size: 17px;
font-weight: 400;
color: hsl(0deg 0% 100% / 90%);
border-radius: 2px;
cursor: pointer;
&:hover {
background: hsl(0deg 0% 100% / 10%);
}
&:active {
background: hsl(0deg 0% 100% / 20%);
}
& a {
display: block;
padding: 6px 16px;
text-decoration: none;
line-height: 125%;
color: hsl(0deg 0% 100% / 90%);
}
}
}
}
.top-menu-mobile .top-menu-mobile-item a {
padding: 10px 10px 10px 53px;
border-radius: 2px;
cursor: pointer;
text-decoration: none;
display: block;
&:hover {
background: hsl(0deg 0% 100% / 10%);
}
&:active {
background: hsl(0deg 0% 100% / 20%);
}
}
.top-menu-submenu-section {
padding-left: 16px;
font-size: 17px;
opacity: 0.6;
margin-bottom: 4px;
letter-spacing: 2px;
}
.top-menu-mobile {
display: none;
background: hsl(240deg 100% 10% / 40%);
backdrop-filter: blur(10px);
z-index: 20;
/* No `top` — defaults to auto, which resolves to the static
position (just below the sticky banner when one is present,
or at the viewport top otherwise). Same trick as .top-menu
above. The [open] state below pins to top: 0 so the expanded
panel covers the full viewport. */
position: fixed;
left: 0;
right: 0;
height: var(--navbar-height);
overflow: auto;
font-style: normal;
font-weight: 500;
font-size: 20px;
line-height: 28px;
letter-spacing: 0.02em;
font-feature-settings:
"pnum" on,
"lnum" on;
color: hsl(0deg 0% 100% / 80%);
overscroll-behavior: contain;
}
.top-menu-mobile[open] {
top: 0;
bottom: 0;
height: 100%;
background: hsl(240deg 100% 5.9% / 80%);
backdrop-filter: blur(20px);
}
/* When a banner is present, keep it visible above the open menu by
pushing the panel down by the banner's actual rendered height.
--announcement-banner-height is set by header.ts only while the menu is open
(via a ResizeObserver scoped to that interval), so the offset
stays accurate when the announcement wraps onto multiple lines on
narrow viewports without paying for an observer the rest of the
time. The 42px fallback covers the first frame before JS runs. */
:has(#navbar-custom-message) .top-menu-mobile[open] {
top: var(--announcement-banner-height, 42px);
height: calc(100% - var(--announcement-banner-height, 42px));
}
.top-menu-mobile-items-group-1,
.top-menu-mobile-items-group-2 {
display: flex;
flex-direction: column;
margin-bottom: 24px;
}
.top-menu-mobile-items-group-1 summary,
.top-menu-mobile-items-group-1 a,
.top-menu-mobile-items-group-2 summary,
.top-menu-mobile-items-group-2 a {
cursor: pointer;
transition: background 0.4s ease-out;
}
.top-menu-mobile-items-group-1 summary,
.top-menu-mobile-items-group-2 summary {
padding: 10px 10px 10px 23px;
user-select: none;
}
.top-menu-mobile-items-group-1 a,
.top-menu-mobile-items-group-2 a {
padding-left: 53px;
}
@media (hover: hover) and (pointer: fine) {
.top-menu-mobile-items-group-1 summary:hover,
.top-menu-mobile-items-group-2 summary:hover {
background: hsl(0deg 0% 100% / 10%);
transition: none;
}
}
.top-menu-mobile-items-group-1 summary:active,
.top-menu-mobile-items-group-2 summary:active {
background: hsl(0deg 0% 100% / 10%);
}
/* We display: block here instead of the default
display: list-item largely for the sake of Safari,
which as of early 2026 still ignores the ::marker
line below. Because we're overriding the default
markers on all browsers, this display mode doesn't
impact other browsers, either. */
.top-menu-mobile-item-summary {
display: block;
}
.top-menu-mobile-item-summary::marker {
content: "";
}
.top-menu-mobile-item-summary::before {
content: "";
display: inline-block;
vertical-align: middle;
margin-top: -4px;
margin-right: 4px;
width: 24px;
height: 24px;
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgba(255%2c255%2c255%2c0.7)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-chevron-down'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
transition: transform 0.12s ease-out;
transform: rotate(-90deg);
}
.top-menu-mobile details[open] > summary::before {
transform: rotate(0deg);
}
.top-menu-mobile-submenu {
display: flex;
flex-direction: column;
font-size: 18px;
margin-bottom: 18px;
.top-menu-submenu-list {
margin: 0;
list-style: none;
.top-menu-submenu-list-item {
font-size: 17px;
font-weight: 400;
line-height: 26px;
color: hsl(0deg 0% 100% / 90%);
border-radius: 2px;
cursor: pointer;
&:hover {
background: hsl(0deg 0% 100% / 10%);
}
&:active {
background: hsl(0deg 0% 100% / 20%);
}
& a {
text-decoration: none;
padding: 5px 0 5px 53px;
display: block;
}
}
}
}
.top-menu-mobile-submenu-section {
letter-spacing: 0.1em;
color: hsl(0deg 0% 100% / 40%);
text-transform: uppercase;
margin-top: 8px;
font-size: 17px;
padding-left: 53px;
user-select: none;
pointer-events: none;
}
.top-menu-mobile-summary {
cursor: pointer;
position: sticky;
top: 0;
z-index: 1;
transition: 0.3s;
transition-property: background, backdrop-filter;
height: var(--navbar-height);
overflow: hidden;
display: flex;
justify-content: space-between;
align-items: center;
}
.top-menu-mobile-summary:active {
background: hsl(229deg 47% 17% / 80%);
backdrop-filter: blur(10px);
}
.top-menu-mobile[open] > .top-menu-mobile-summary {
background: hsl(229deg 47% 17% / 80%);
backdrop-filter: blur(10px);
}
/* For browsers which don't support blur */
@supports not (
(backdrop-filter: blur(10px)) or (-webkit-backdrop-filter: blur(10px))
) {
.top-menu {
background: hsl(240deg 100% 10% / 80%);
}
.top-menu-mobile {
background: hsl(240deg 100% 10% / 80%);
}
.top-menu-mobile[open] {
background: hsl(240deg 100% 5.9% / 100%);
}
.top-menu-mobile-summary:active {
background: hsl(229deg 47% 17% / 95%);
}
.top-menu-mobile[open] > .top-menu-mobile-summary {
background: hsl(229deg 47% 17% / 95%);
}
}
.top-menu-mobile[open] > .top-menu-mobile-summary:active {
background: hsl(229deg 47% 20% / 100%);
}
.top-menu-mobile-summary::marker {
content: "";
display: none;
}
.top-menu-mobile-summary::after {
display: block;
height: 32px;
float: right;
content: "MENU";
line-height: 32px;
color: hsl(0deg 0% 100% / 80%);
padding-right: 38px;
font-size: 20px;
font-weight: 400;
letter-spacing: 2px;
margin-right: 16px;
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgba(255,255,255,0.9)' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3e%3cline x1='3' y1='12' x2='21' y2='12'%3e%3c/line%3e%3cline x1='3' y1='6' x2='21' y2='6'%3e%3c/line%3e%3cline x1='3' y1='18' x2='21' y2='18'%3e%3c/line%3e%3c/svg%3e");
background-repeat: no-repeat;
background-size: 32px;
background-position: right;
transition:
background,
letter-spacing 0.2s; /* stylelint-disable-line plugin/no-low-performance-animation-properties */
}
.top-menu-mobile-summary:active::after {
letter-spacing: 2px;
}
.top-menu-mobile[open] > summary::after {
content: "Close";
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgba(255,255,255,0.9)' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3e%3cline x1='18' y1='6' x2='6' y2='18'%3e%3c/line%3e%3cline x1='6' y1='6' x2='18' y2='18'%3e%3c/line%3e%3c/svg%3e");
}
@media (hover: hover) and (pointer: fine) {
.top-menu-mobile-summary:hover {
background: hsl(229deg 47% 18% / 100%);
}
.top-menu-mobile[open] > .top-menu-mobile-summary:hover {
background: hsl(229deg 47% 18% / 100%);
}
.top-menu-mobile-summary:hover::after {
letter-spacing: 4px;
}
}
/* menu responsivity */
@media (width <= 1311px) {
.top-menu {
background: hsl(240deg 100% 10% / 50%);
}
.top-menu-logo {
margin-right: 0;
}
.top-menu-item {
padding: 16px 12px;
font-size: 18px;
font-weight: 500;
}
}
@media (width <= 1100px) {
.top-menu {
display: none;
}
.top-menu-logo {
margin-right: unset;
display: inline-block;
}
.top-menu-mobile {
display: block;
}
}

View File

@@ -0,0 +1,14 @@
/* While the portico pages design is in flux,
we need to limit globally scoped CSS like this
to its own file.
The bulk of styles as well as CSS variables are
in `pricing_plans.css`, which gets shared on
non-plans pages such as /for/business/ */
html {
/* Set the background on HTML to the starting
color for the plans-page gradient, so that the
top overscroll is undetectable. */
background: var(--color-background-gradient-start);
}

View File

@@ -0,0 +1,50 @@
/* This file contains the required variables and styles for the modals
to work properly in the portico, billing, upgrade and dev email log pages. */
:root {
/* This is a copy of the neutral icon button variables defined
in app_variables.css required for the modal close button styling. */
--color-text-neutral-icon-button: light-dark(
color-mix(in oklch, hsl(229deg 9% 36%) 70%, transparent),
color-mix(in oklch, hsl(229deg 10% 70%) 70%, transparent)
);
--color-text-neutral-icon-button-hover: light-dark(
hsl(229deg 9% 36%),
hsl(229deg 10% 70%)
);
--color-text-neutral-icon-button-active: light-dark(
color-mix(in oklch, hsl(229deg 9% 36%) 70%, transparent),
color-mix(in oklch, hsl(229deg 10% 70%) 70%, transparent)
);
}
.modal__container {
--base-font-size-px: 16px;
font-size: var(--base-font-size-px);
font-weight: 400;
}
.modal__close {
/* This is a subset of the styling defined for the icon button
component in web/styles/buttons.css. */
display: flex;
justify-content: center;
align-items: center;
aspect-ratio: 1;
font-size: var(--base-font-size-px);
background-color: transparent; /* Override button default background color */
cursor: pointer;
border: none;
border-radius: 4px;
color: var(--color-text-neutral-icon-button);
&:hover,
&:focus-visible {
color: var(--color-text-neutral-icon-button-hover);
}
&:active {
color: var(--color-text-neutral-icon-button-active);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,40 @@
:root {
--color-background-gradient-start: hsl(209deg 40% 50%);
--color-background-gradient-end: hsl(210deg 48% 69%);
/* This is the same color as set on `--color-table-background` in
comparison_table.css. */
--color-background-marketing-page: hsl(0deg 0% 100% / 80%);
/* This is a legacy color previously set on .why-page divs. */
--color-text-marketing-page: hsl(223deg 6% 25%);
--color-background-solid-hero: var(--color-background-gradient-start);
--color-text-hero: hsl(0deg 0% 100%);
--font-ss3: "Source Sans 3 VF", sans-serif;
--font-ops: "Open Sans Variable", sans-serif;
--color-background-box: hsl(210deg 44% 92%);
--color-background-box-muted: hsl(0deg 0% 100% / 50%);
--color-background-box-muted-hover: hsl(0deg 0% 100% / 60%);
--color-plan-tab-header: hsl(223deg 40% 30%);
--color-plan-tab-copy: hsl(223deg 40% 25% / 70%);
--color-box-header: hsl(223deg 43% 25%);
--color-box-copy: hsl(223deg 43% 25%);
--color-box-copy-fine-print: hsl(223deg 43% 55%);
--color-link: hsl(210deg 94% 42%);
--color-link-hover: hsl(210deg 100% 50%);
--color-link-portico-auth: hsl(200deg 100% 40%);
--color-link-portico-auth-hover: hsl(200deg 100% 25%);
--color-link-underline: hsl(210deg 94% 42% / 30%);
--color-link-underline-hover: hsl(210deg 100% 50%);
--color-link-underline-alternate: hsl(210deg 94% 100% / 40%);
--color-link-underline-alternate-hover: hsl(210deg 94% 100% / 80%);
--color-prominent-border: var(--color-link);
--color-action-button: hsl(240deg 66% 60%);
--color-action-button-hover: hsl(240deg 66% 55%);
--color-action-button-active: hsl(240deg 66% 50%);
--color-action-button-subtle-hover: hsl(240deg 66% 97%);
--color-action-button-subtle-active: hsl(240deg 66% 94%);
@media (prefers-color-scheme: dark) {
--color-background-gradient-start: hsl(209deg 63% 40%);
--color-background-gradient-end: hsl(238deg 28% 50%);
}
}

View File

@@ -0,0 +1,874 @@
.portico-pricing {
--icon-left-outward-tab-curve: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' viewBox='0 0 16 16'%3e%3cpath fill='white' d='M0 16h16V0c0 8.837-7.163 16-16 16Z'/%3e%3c/svg%3e");
--icon-right-outward-tab-curve: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' viewBox='0 0 16 16'%3e%3cpath fill='white' d='M16 16H0V0c0 8.837 7.163 16 16 16Z'/%3e%3c/svg%3e");
--icon-question-header-swoosh: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='33' height='56' fill='none' viewBox='0 0 33 56'%3e%3cpath fill='%23E2EBF4' d='M33 37 1 56C1 35-3.5 0 33 0 7.5 3 7.776 37 33 37Z'/%3e%3c/svg%3e");
--icon-current-plan-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' fill='none' viewBox='0 0 22 22'%3e%3cg fill='%230F8544'%3e%3cpath d='M14.396 9.813a.914.914 0 1 0-1.293-1.293l-3.02 3.02-1.186-1.186a.914.914 0 1 0-1.294 1.293l1.834 1.833a.914.914 0 0 0 1.293 0l3.666-3.667Z'/%3e%3cpath fill-rule='evenodd' d='M11 .923a4.58 4.58 0 0 0-3.495 1.62 4.581 4.581 0 0 0-4.961 4.949 4.58 4.58 0 0 0 0 7.016 4.58 4.58 0 0 0 4.96 4.949 4.583 4.583 0 0 0 7.003-.001 4.582 4.582 0 0 0 4.95-4.96 4.583 4.583 0 0 0 0-6.991 4.58 4.58 0 0 0-4.962-4.962A4.581 4.581 0 0 0 11 .923ZM9.678 3.09a2.752 2.752 0 0 1 3.64.932.914.914 0 0 0 .972.4 2.752 2.752 0 0 1 3.289 3.288.914.914 0 0 0 .4.971 2.753 2.753 0 0 1 0 4.638.914.914 0 0 0-.4.97 2.752 2.752 0 0 1-3.283 3.29.914.914 0 0 0-.97.401 2.75 2.75 0 0 1-4.644 0 .914.914 0 0 0-.971-.401 2.752 2.752 0 0 1-3.29-3.283.914.914 0 0 0-.403-.97 2.753 2.753 0 0 1 0-4.652.914.914 0 0 0 .404-.97A2.752 2.752 0 0 1 7.71 4.42a.914.914 0 0 0 .97-.4c.25-.389.592-.709.997-.93Z' clip-rule='evenodd'/%3e%3c/g%3e%3c/svg%3e");
--icon-discount-tooltip-curve: url("data:image/svg+xml,%3Csvg width='35' height='14' viewBox='0 0 35 14' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M17.4814 14C16.3229 6.40469 8.98604 0 0.5 0L34.5 0C26.0153 0 18.4853 6.40469 17.4814 14Z' fill='%23F4F9FE'/%3E%3C/svg%3E");
--width-price-box-min: 240px;
--width-price-box-max: 355px;
--height-discounted-price-box: 98px;
--height-price-details-min: 53px;
padding: 102px 0 58px;
background: linear-gradient(
180deg,
var(--color-background-gradient-start) 0%,
var(--color-background-gradient-end) 100%
);
@media (prefers-color-scheme: dark) {
--color-background-box: hsl(221deg 35% 89%);
background: linear-gradient(
180deg,
var(--color-background-gradient-start) 30%,
var(--color-background-gradient-end) 100%
);
}
ul {
padding: 0;
margin: 0;
}
h1 {
font-weight: 500;
font-size: 58px;
line-height: 110%;
text-align: center;
color: hsl(0deg 0% 100%);
margin: 10px;
}
.h1-subheader {
font-family: var(--font-ops);
font-weight: 400;
font-size: 20px;
line-height: 145%;
text-align: center;
font-feature-settings:
"pnum" on,
"lnum" on;
color: hsl(0deg 0% 100%);
max-width: 560px;
padding: 0 10px;
margin: 0 auto;
/* There's never a button instance here, but we need
this to correct for specificity against the overall
marketing-page link styles.
TODO: Integrate this link style so as to not add a
:not() selector here. */
& a:not(.button) {
color: inherit;
text-decoration: underline;
text-decoration-color: hsl(0deg 0% 100% / 50%);
text-decoration-thickness: 1px;
text-underline-offset: 2px;
transition: text-decoration 0.4s ease-out;
&:hover {
text-decoration-color: hsl(0deg 0% 100%);
text-decoration-thickness: 2px;
color: inherit;
transition: none;
}
}
}
li {
list-style-type: none;
display: flex;
align-items: flex-start;
/* Prevent flexbox from collapsing
whitespace around links and other
inline elements. */
gap: 0.3em;
&::before {
content: "";
height: 6px;
width: 6px;
border-radius: 16px;
/* 0.5333em, roughly 8px given the
15px font-size on list items, will
keep the bullet vertically centered
with the first line of a list item
as the page's text scales. */
margin: 0.5333em 4px 0 0;
/* Prevent "bullets" from being distorted
on a multiline bullet point. */
flex: 0 0 auto;
background: currentcolor;
opacity: 0.3;
}
}
.unlimited-push-notifications {
padding-bottom: 21px;
}
.support-note {
margin-top: 15px;
font-size: 17px;
font-weight: 550;
&::before {
/* Hide the bullet on the support note,
but still keep its width to maintain
lefthand alignment. */
background: transparent;
}
}
a {
color: var(--color-link);
text-decoration: underline;
text-decoration-color: var(--color-link-underline);
text-underline-offset: 4px;
&:hover {
color: var(--color-link-hover);
text-decoration: underline;
text-decoration-color: var(--color-link-underline-hover);
}
}
/* Remove padding introduced in legacy_landing_page.css */
.padded-content {
padding: 0;
}
@media (width <= 768px) {
.pricing-model .padded-content {
padding: 0;
}
}
.pricing-container {
display: grid;
grid-template:
". . cloud-title self-hosted-title . . " auto
"pricing pricing pricing pricing pricing pricing" auto / 56px 1fr minmax(
0,
420px
)
minmax(0, 420px) 1fr 56px;
column-gap: 2px;
margin: 50px auto 38px;
/* We use the plan count on the respective `.showing-` class
to determine a maximum width, beyond which the plans will
grow no wider. */
max-width: calc(
(var(--count-plans) * var(--width-price-box-max)) + 40px
);
@media screen and (width <= 700px) {
grid-template-columns:
40px 1fr minmax(0, 420px)
minmax(0, 420px) 1fr 40px;
}
}
.request-sponsorship {
margin-bottom: 10px;
}
.pricing-pane-scroll-container {
grid-area: pricing;
overflow-x: auto;
scrollbar-width: none;
}
.cloud-plan-title {
grid-area: cloud-title;
}
.self-hosted-plan-title {
grid-area: self-hosted-title;
}
.pricing-tab,
.inactive-pricing-tab {
cursor: pointer;
background: var(--color-background-box);
padding: 12px 12px 0;
border-radius: 16px 16px 0 0;
min-height: 40px;
h2 {
color: var(--color-plan-tab-header);
font-family: var(--font-ops);
font-weight: 550;
font-size: 30px;
line-height: 32px;
margin: 0;
margin-bottom: 8px;
text-align: center;
}
p {
color: var(--color-plan-tab-copy);
font-weight: 400;
font-size: 16px;
line-height: 125%;
margin: 0;
text-align: center;
padding-bottom: 14px;
@media screen and (width <= 700px) {
display: none;
}
}
/* Shared styles to handle tab curvature. */
&::before {
display: none;
width: 16px;
height: 16px;
content: "";
position: absolute;
bottom: 0;
left: -16px;
background-color: var(--color-background-box);
mask-position: center;
mask-repeat: no-repeat;
mask-image: var(--icon-left-outward-tab-curve);
}
&::after {
display: none;
width: 16px;
height: 16px;
content: "";
position: absolute;
bottom: 0;
right: -16px;
background-color: var(--color-background-box);
mask-position: center;
mask-repeat: no-repeat;
mask-image: var(--icon-right-outward-tab-curve);
}
}
.inactive-pricing-tab {
cursor: default;
}
.pricing-pane {
display: grid;
grid-template-columns: repeat(
auto-fit,
minmax(var(--width-price-box-min), 1fr)
);
grid-template-rows: auto;
/* We use the plan count on the respective `.showing-` class
to determine a minimum width, at which point the plans scroll. */
min-width: calc(var(--count-plans) * var(--width-price-box-min));
padding: 20px 5px;
border-radius: 16px;
color: var(--color-box-copy);
background: var(--color-background-box);
margin: 0 16px;
@media screen and (width <= 700px) {
margin: 0 8px;
}
h2 {
font-weight: 550;
font-size: 28px;
line-height: 28px;
padding-left: 14px;
margin: 8px 0 16px;
&.with-fine-print {
display: flex;
/* Keep fine-print to same distance from
the dashed border to the right as the
heading text is to the left. */
padding: 0 14px;
small {
flex: 0 1 min-content;
margin-left: auto;
font-weight: 350;
font-size: 14px;
line-height: 14px;
text-align: right;
color: var(--color-box-copy-fine-print);
}
}
}
ul {
font-family: var(--font-ops);
font-weight: 400;
font-size: 15px;
}
li {
margin-bottom: 10px;
line-height: 21px;
}
.price-box {
height: 100%;
display: flex;
flex-direction: column;
border-right: 1px dashed hsl(223deg 40% 25% / 20%);
&:last-child {
border-right: 0;
}
/* Make sure flexing text-content boxes
occupy their full with, but account
for padding with border-box sizing. */
.text-content {
box-sizing: border-box;
width: 100%;
margin: 0 auto;
}
/* Set right and left padding on the
bottom box so that buttons align
to the text column above. */
.bottom {
padding: 0 16px;
.text-content {
/* But allow buttons and price info
a bit more breathing room. */
padding: 0;
}
}
}
.text-content {
padding: 0 16px;
}
.bottom {
/* Push to the bottom of the price box. */
margin-top: auto;
}
.standard-price-box {
display: flex;
/* Handle a discount line, when
needed. */
flex-wrap: wrap;
align-items: flex-start;
gap: 4px;
margin: 24px 0 6px;
font-weight: 400;
/* For supporting browsers, constrain the height
of the standard price box when it includes a
discount. This keeps discount tooltips on the
same horizontal line, while also maintaining
alignment of non-discounted price box prices. */
&:has(.discount) {
height: var(--height-discounted-price-box);
}
.price {
font-size: 38px;
font-weight: 400;
line-height: 1;
letter-spacing: -1px;
}
.currency-symbol {
opacity: 0.5;
}
.details {
flex: 1 0 0;
p {
margin: 2px 0 0;
font-size: 15px;
line-height: 17px;
}
}
.discount {
/* Keep the discount to its own
line in the wrapping flexbox. */
flex: 0 0 100%;
/* But move it to the top of the
flex area. */
order: -1;
text-align: center;
padding: 9px 0 10px;
margin-bottom: 9px;
border-radius: 30px;
background-color: hsl(210deg 83% 98%);
position: relative;
font-family: var(--font-ops);
font-size: 15px;
/* Use padding to better position
text within its single line. */
line-height: 1;
@media screen and (width <= 1240px) {
/* Pad the discount balloon... */
padding: 8px 5px 9px;
/* But pull out the margins an equal
amount so it can breathe. */
margin: 0 -5px 9px;
}
& b {
font-weight: 650;
}
&::after {
content: "";
background-image: var(--icon-discount-tooltip-curve);
display: block;
width: 35px;
height: 14px;
bottom: -14px;
left: calc(50% - 17.5px);
position: absolute;
}
}
.price,
.details {
/* Preserve a height for allowing
price details to wrap as many
as three lines. */
min-height: var(--height-price-details-min);
}
}
}
.additional-pricing-information {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
grid-template-rows: auto;
column-gap: 32px;
max-width: 912px;
margin: 0 auto;
@media screen and (width <= 810px) {
grid-template-columns: minmax(0, 456px);
justify-content: center;
row-gap: 32px;
}
header {
position: relative;
padding: 0 16px 0 32px;
&::before {
display: block;
content: "";
width: 32px;
height: 56px;
position: absolute;
background-color: var(--color-background-box);
top: 30px;
left: -0.5px;
mask-position: center;
mask-repeat: no-repeat;
mask-image: var(--icon-question-header-swoosh);
}
h2 {
font-family: var(--font-ops);
font-weight: 500;
font-size: 30px;
line-height: 38px;
margin: 0;
}
p {
font-weight: 400;
font-size: 16px;
margin: 0;
margin-bottom: 6px;
}
a {
color: inherit;
text-decoration-color: var(--color-link-underline-alternate);
&:hover {
text-decoration: underline;
text-decoration-color: var(
--color-link-underline-alternate-hover
);
}
}
}
.text-content {
color: var(--color-box-copy);
background: var(--color-background-box);
padding: 20px 32px;
border-radius: 16px;
b {
font-weight: 600;
}
}
h3 {
margin: 0 0 6px;
font-weight: 500;
font-size: 22px;
line-height: 28px;
}
ul {
margin-bottom: 12px;
}
li {
font-size: 15px;
margin-bottom: 4px;
}
p {
margin: 0;
}
.sponsorship-button {
display: block;
font-weight: 550;
font-size: 15px;
line-height: 20px;
text-align: center;
padding: 8px 10px;
margin-bottom: 6px;
}
.contact-note {
font-weight: 400;
font-size: 14px;
}
}
@media screen and (width <= 500px) {
.additional-pricing-information {
margin: 0 8px;
header {
padding-bottom: 29px;
}
p {
display: none;
}
}
}
.button {
display: block;
font-family: var(--font-ss3);
font-weight: 550;
font-size: 15px;
text-align: center;
text-decoration: none;
letter-spacing: 0.06ch;
padding: 8px 10px;
border-radius: 4px;
/* Position relatively for discount tab */
position: relative;
z-index: 5;
}
.button-placeholder {
/* Empty element for maintaining the
layout on plans that otherwise have
no button. */
height: 37.5px;
visibility: hidden;
}
.get-started-button {
color: hsl(0deg 0% 100%);
background-color: hsl(146deg 92% 26%);
&:hover {
text-decoration: none;
color: hsl(0deg 0% 100%);
background-color: hsl(146deg 92% 24%);
}
}
.upgrade-button {
color: hsl(0deg 0% 100%);
background-color: hsl(219deg 62% 54%);
&:hover {
text-decoration: none;
color: hsl(0deg 0% 100%);
background-color: hsl(219deg 62% 50%);
}
}
.current-plan-button,
.current-plan-descriptor {
display: flex;
align-items: center;
justify-content: center;
gap: 0.5ch;
color: hsl(147deg 57% 25%);
background-color: hsl(152deg 79% 24% / 5%);
.current-plan-icon {
width: 22px;
height: 22px;
display: block;
background-color: currentcolor;
mask-position: center;
mask-repeat: no-repeat;
mask-image: var(--icon-current-plan-icon);
}
}
.current-plan-descriptor {
/* Pad and lead the descriptor
to better match other buttons */
padding: 1.75px 0;
line-height: 16px;
background-color: transparent;
border: 1px solid hsl(152deg 79% 24% / 10%);
font-weight: normal;
}
.current-plan-button:hover {
text-decoration: none;
color: hsl(147deg 57% 25%);
background-color: hsl(152deg 79% 24% / 14%);
}
.sponsorship-button {
color: hsl(147deg 57% 25%);
background-color: hsl(152deg 79% 24% / 10%);
&:hover {
text-decoration: none;
color: hsl(147deg 57% 25%);
background-color: hsl(146deg 92% 24% / 15%);
}
}
&.showing-cloud {
--count-plans: 3;
.self-hosted-scroll,
.self-hosted-plan-pricing,
.self-hosted-additional-pricing {
display: none;
}
.cloud-plan-title {
position: relative;
/* Show curvature on cloud tab. */
&::before {
display: block;
}
&::after {
display: block;
}
p {
border-bottom: 1px dashed hsl(223deg 40% 25% / 20%);
margin: 0 10px;
}
@media screen and (width <= 700px) {
h2 {
border-bottom: 1px dashed hsl(223deg 40% 25% / 20%);
height: 100%;
margin: 0 10px;
}
}
@media screen and (width <= 500px) {
h2 {
margin: 0;
}
}
}
.self-hosted-plan-title {
border-radius: 16px 16px 0 14px;
margin-bottom: 2px;
background-color: var(--color-background-box-muted);
&:hover {
background-color: var(--color-background-box-muted-hover);
}
}
}
&.showing-self-hosted {
--count-plans: 4;
.cloud-scroll,
.cloud-plan-pricing,
.cloud-additional-pricing {
display: none;
}
.cloud-plan-title {
border-radius: 16px 16px 14px 0;
margin-bottom: 2px;
background-color: var(--color-background-box-muted);
&:hover {
background-color: var(--color-background-box-muted-hover);
}
}
.self-hosted-plan-title {
position: relative;
/* Show curvature on self-hosted tab. */
&::before {
display: block;
}
&::after {
display: block;
}
p {
border-bottom: 1px dashed hsl(223deg 40% 25% / 20%);
margin: 0 10px;
}
@media screen and (width <= 700px) {
h2 {
border-bottom: 1px dashed hsl(223deg 40% 25% / 20%);
height: 100%;
margin: 0 10px;
}
}
@media screen and (width <= 500px) {
h2 {
margin: 0;
}
}
}
}
.is-self-hosted-realm {
/* Don't display buttons on cloud plans
when viewed by self-hosters. */
.cloud-plan-pricing .bottom .text-content {
display: none;
}
}
@media screen and (width <= 1140px) {
.self-hosted-plan-pricing {
ul {
font-size: 14px;
}
.standard-price-box {
--height-price-details-min: 48px;
--height-discounted-price-box: 91px;
.price {
font-size: 32px;
}
.details {
p {
font-size: 13px;
line-height: 16px;
}
}
.discount {
font-size: 13px;
}
}
}
}
@media screen and (width <= 940px) {
/* This block of styles duplicates the adjustments
to .self-hosted-plan-pricing above; because of the
fewer number of Cloud plans, we don't need these
adjustments until this breakpoint. */
.cloud-plan-pricing {
ul {
font-size: 14px;
}
.standard-price-box {
--height-price-details-min: 48px;
--height-discounted-price-box: 91px;
.price {
font-size: 32px;
}
.details {
p {
font-size: 13px;
line-height: 16px;
}
}
.discount {
font-size: 13px;
}
}
}
h1 {
font-size: 40px;
}
.h1-subheader {
font-size: 16px;
}
.pricing-tab {
h2 {
font-size: 24px;
line-height: 26px;
margin-bottom: 5px;
}
p {
font-size: 14px;
padding-bottom: 10px;
}
}
.pricing-pane {
h2 {
font-size: 22px;
margin: 4px 0 12px;
}
}
}
@media screen and (width <= 920px) {
.additional-pricing-information header h2 {
font-size: 24px;
}
}
@media screen and (width <= 500px) {
.pricing-tab h2 {
font-size: 20px;
}
}
}

View File

@@ -0,0 +1,143 @@
:root.dark-theme {
color-scheme: dark;
}
body {
--base-font-size-px: 16px;
width: 100%;
margin: 0;
padding: 0;
font-size: var(--base-font-size-px);
/* The line-height used in most of the UI should be at least
its legacy value, but should expand with larger base
line-height values. */
line-height: max(
var(--legacy-body-line-height-unitless),
var(--base-line-height-unitless)
);
font-family: "Source Sans 3 VF", sans-serif;
font-weight: unset; /* override value in legacy_portico.css */
color: var(--color-text-default);
background-color: var(--color-background);
}
.showroom-wrapper {
display: flex;
flex-flow: column;
gap: 20px;
padding: 40px 20px;
}
.showroom-controls-section {
display: grid;
grid-template-columns: [control-name-start] max-content [control-name-end control-input-start] 1fr [control-input-end];
gap: 10px;
margin-top: 50px;
width: min(100%, 500px);
}
.showroom-controls {
display: grid;
grid-template-columns: subgrid;
grid-column: control-name-start / control-input-end;
grid-auto-rows: 1fr;
gap: 10px;
background-color: var(--color-background);
border: solid 1px;
padding: 10px;
width: 100%;
}
.showroom-control {
display: grid;
grid-template-columns: subgrid;
grid-column: control-name-start / control-input-end;
gap: 10px;
}
.showroom-control-element {
font-size: inherit;
font-family: inherit;
}
.showroom-control-label {
cursor: pointer;
grid-column: control-name-start / control-name-end;
align-self: center;
}
.showroom-control-setting {
grid-column: control-input-start / control-input-end;
}
.showroom-control-setting-multiple {
display: flex;
align-items: center;
gap: 10px;
}
.hidden {
display: none !important;
}
.showroom-controls-label {
grid-column: control-name-start / control-input-end;
margin-top: 10px;
font-size: 1.4em;
font-weight: 600;
}
.showroom-button-grid {
display: grid;
grid-template-areas: "showroom-component-button-intent-label showroom-component-action-button-group showroom-component-icon-button-group";
grid-template-columns: repeat(3, max-content);
gap: 15px 30px;
}
.showroom-component-button-intent-group {
display: grid;
grid-template-columns: subgrid;
grid-column: 1 / -1;
place-items: center start;
}
.showroom-component-button-intent-label {
grid-area: showroom-component-button-intent-label;
}
.showroom-component-action-button-group,
.showroom-component-action-button-label {
grid-area: showroom-component-action-button-group;
}
.showroom-component-icon-button-group,
.showroom-component-icon-button-label {
grid-area: showroom-component-icon-button-group;
}
.showroom-component-action-button-group,
.showroom-component-icon-button-group {
display: flex;
flex-flow: row wrap;
gap: 15px;
}
.showroom-component-button-intent-label,
.showroom-component-action-button-label,
.showroom-component-icon-button-label {
font-size: 1.1em;
font-weight: 500;
}
#showroom_component_banner_select_intent {
text-transform: capitalize;
}
#showroom_component_banner_default_wrapper {
width: min(100%, 800px);
margin: 0 auto;
}
.showroom-filter-input-container {
width: clamp(200px, 100%, 400px);
}

View File

@@ -0,0 +1,201 @@
body {
font-family: "Source Sans 3 VF", sans-serif !important;
background-color: hsl(0deg 0% 98%);
}
p {
margin-bottom: 0;
}
.app-main {
padding: 0;
width: auto;
max-width: none;
}
.svg-container {
margin: 20px;
}
.center-charts {
margin: 30px;
}
.stats-page .alert,
.analytics-page-header {
text-align: center;
}
.stats-page h1 {
font-weight: 300;
}
.summary-stats {
vertical-align: top;
margin: 0 auto;
padding: 20px;
border: 2px solid hsl(0deg 0% 93%);
background-color: hsl(0deg 0% 100%);
width: 395px;
& h1 {
margin-top: 0;
font-size: 1.5em;
}
}
.flex-container {
display: flex;
flex-flow: wrap;
justify-content: space-around;
}
.chart-container {
vertical-align: top;
margin: 10px 0;
padding: 20px;
border: 2px solid hsl(0deg 0% 93%);
background-color: hsl(0deg 0% 100%);
& button {
position: relative;
z-index: 1;
}
& h1 {
margin-top: 0;
font-size: 1.5em;
}
.button-container {
position: relative;
z-index: 1;
margin-bottom: 5px;
}
}
.analytics-page-header {
margin-left: 10px;
}
.rangeslider-container {
user-select: none;
}
.rangeselector text {
font-weight: 400;
}
.buttons button {
background-color: hsl(0deg 0% 94%);
&.selected {
background-color: hsl(0deg 0% 85%);
}
}
.button {
font-family: "Source Sans 3 VF", sans-serif !important;
border: none;
border-radius: 4px;
outline: none;
padding: 2px 6px;
&:hover {
background-color: hsl(0deg 0% 84%) !important;
}
}
.docs_link a {
font-weight: 300;
color: inherit;
text-decoration: none;
}
.last-update {
margin: 0 0 30px;
font-size: 0.8em;
font-weight: 400;
text-align: center;
color: hsl(0deg 0% 67%);
}
#users_hover_humans,
#read_hover_everyone,
#hover_human {
margin-left: 10px;
}
#id_messages_sent_by_client {
min-height: 100px;
width: 750px;
position: relative;
}
#id_messages_sent_by_message_type {
height: 300px;
width: 750px;
position: relative;
}
#id_messages_sent_over_time,
#id_messages_read_over_time {
height: 400px;
width: 750px;
position: relative;
&[last_value_is_partial="true"] .points path:last-of-type {
opacity: 0.5;
}
}
#id_number_of_users {
height: 370px;
width: 750px;
position: relative;
}
#id_stats_errors {
display: none;
}
#users_hover_info,
#read_hover_info,
#hoverinfo,
#pie_messages_sent_by_type_total {
float: right;
font-size: 0.8em;
font-weight: 400;
}
#users_hover_info,
#read_hover_info,
#hoverinfo {
display: none;
position: relative;
height: 0;
top: -25px;
}
.spinner::before {
content: "";
box-sizing: border-box;
position: absolute;
top: 50%;
left: 50%;
width: 30px;
height: 30px;
margin-top: -15px;
margin-left: -15px;
border-radius: 50%;
border: 1px solid hsl(0deg 0% 80%);
border-top-color: hsl(155deg 93% 42%);
animation: spinner 1s linear infinite;
}
@keyframes spinner {
to {
transform: rotate(360deg);
}
}

File diff suppressed because one or more lines are too long