mirror of
https://github.com/simplex-chat/simplexmq.git
synced 2026-03-30 18:35:59 +00:00
* web: extract shared web module from smp-server
Move web serving infrastructure (warp, static files, HTML templating)
from apps/smp-server/web/Static.hs into library modules:
- Simplex.Messaging.Server.Web (generic web infra + templating)
- Simplex.Messaging.Server.Web.Embedded (TH-embedded assets)
Move static assets from apps/smp-server/static/ to
src/Simplex/Messaging/Server/Web/.
Move EmbeddedWebParams/WebHttpsParams from Server.Main to Server.Web.
Keep SMP-specific rendering (serverInformation) in apps/smp-server/SMP/Web.hs.
generateSite is now generic: takes pre-rendered HTML + link page paths,
enabling reuse by XFTP and NTF servers.
* web: add tests for templating engine
Tests for render, section_, item_, and timedTTLText functions
in Simplex.Messaging.Server.Web module.
* web: add serverInfoSubsts, serveStaticPageH2, safe port parsing
* web: rename SMP.Web to SMPWeb, remove SMP subdirectory
* fix(web): section_ collapsing sections with Just "" content
Commit e48bedea ("servers: fix server pages when source code is not
specified") changed section_ to treat Just "" the same as Nothing -
collapsing the section. The intent was to handle the sourceCode case
(empty string when not specified), but the guard
`not (B.null content)` also broke operator, admin, complaints, and
hosting - all of which legitimately use Just "" as a
section-present marker.
Before (correct):
Nothing -> before <> next
Just content -> before <> item_ label content inside <> ...
After (broken):
Just content | not (B.null content) -> ...
_ -> before <> next
Restore the original behavior: only Nothing collapses a section.
* refactor
---------
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
414 lines
6.8 KiB
CSS
414 lines
6.8 KiB
CSS
@font-face {
|
|
font-family: Gilroy;
|
|
src: url("GilroyRegular.woff2") format("woff2");
|
|
font-weight: 400;
|
|
font-style: normal;
|
|
}
|
|
|
|
@font-face {
|
|
font-family: Gilroy;
|
|
src: url("GilroyLight.woff2") format("woff2");
|
|
font-weight: 300;
|
|
font-style: normal;
|
|
}
|
|
|
|
@font-face {
|
|
font-family: Gilroy;
|
|
src: url("GilroyMedium.woff2") format("woff2");
|
|
font-weight: 500;
|
|
font-style: normal;
|
|
}
|
|
|
|
@font-face {
|
|
font-family: Gilroy;
|
|
src: url("GilroyBold.woff2") format("woff2");
|
|
font-weight: 700;
|
|
font-style: normal;
|
|
}
|
|
|
|
@font-face {
|
|
font-family: Gilroy;
|
|
src: url("GilroyRegularItalic.woff2") format("woff2");
|
|
font-weight: 400;
|
|
font-style: italic;
|
|
}
|
|
|
|
html {
|
|
scroll-behavior: smooth;
|
|
font-family: Gilroy, Helvetica, sans-serif;
|
|
;
|
|
letter-spacing: 0.003em;
|
|
}
|
|
|
|
img {
|
|
user-select: none;
|
|
-webkit-user-select: none;
|
|
/* For Safari and older Chrome versions */
|
|
-moz-user-select: none;
|
|
/* For Firefox */
|
|
-ms-user-select: none;
|
|
/* For Internet Explorer and Edge */
|
|
}
|
|
|
|
a{
|
|
word-wrap: break-word;
|
|
}
|
|
|
|
/* NEW SITE */
|
|
.container,
|
|
.container-fluid,
|
|
.container-xxl,
|
|
.container-xl,
|
|
.container-lg,
|
|
.container-md,
|
|
.container-sm {
|
|
width: 100%;
|
|
/* padding: 0 20px; */
|
|
margin-right: auto;
|
|
margin-left: auto;
|
|
}
|
|
|
|
@media (min-width: 576px) {
|
|
|
|
.container-sm,
|
|
.container {
|
|
max-width: 540px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 768px) {
|
|
|
|
.container-md,
|
|
.container-sm,
|
|
.container {
|
|
max-width: 720px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 992px) {
|
|
|
|
.container-lg,
|
|
.container-md,
|
|
.container-sm,
|
|
.container {
|
|
max-width: 960px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1200px) {
|
|
|
|
.container-xl,
|
|
.container-lg,
|
|
.container-md,
|
|
.container-sm,
|
|
.container {
|
|
max-width: 1140px;
|
|
}
|
|
}
|
|
|
|
@media (min-width: 1400px) {
|
|
|
|
.container-xxl,
|
|
.container-xl,
|
|
.container-lg,
|
|
.container-md,
|
|
.container-sm,
|
|
.container {
|
|
max-width: 1320px;
|
|
}
|
|
}
|
|
|
|
.gradient-text {
|
|
background: -webkit-linear-gradient(to bottom, #53C1FF -50%, #0053D0 160%);
|
|
background: linear-gradient(to bottom, #53C1FF -50%, #0053D0 160%);
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
background-clip: text;
|
|
text-fill-color: transparent;
|
|
}
|
|
|
|
.dark .border-gradient {
|
|
background:
|
|
linear-gradient(#11182F, #11182F) padding-box,
|
|
linear-gradient(to bottom, transparent, #01F1FF 58%) border-box;
|
|
border: 1px solid transparent;
|
|
}
|
|
|
|
.dark .only-light {
|
|
display: none;
|
|
}
|
|
|
|
.only-dark {
|
|
display: none;
|
|
}
|
|
|
|
.dark .only-dark {
|
|
display: inherit;
|
|
}
|
|
|
|
.menu-link {
|
|
font-size: 16px;
|
|
line-height: 33.42px;
|
|
color: #0D0E12;
|
|
}
|
|
|
|
.dark .menu-link {
|
|
color: #fff;
|
|
}
|
|
|
|
.nav-link ul li a.active {
|
|
color: #0053D0;
|
|
|
|
}
|
|
|
|
.dark .nav-link ul li a.active {
|
|
color: #66D9E2;
|
|
}
|
|
|
|
@media (min-width:1024px) {
|
|
|
|
.nav-link-text,
|
|
.menu-link {
|
|
display: inline-block;
|
|
position: relative;
|
|
color: #0D0E12;
|
|
}
|
|
|
|
.nav-link-text::before,
|
|
.active .nav-link-text::before,
|
|
.menu-link::before {
|
|
content: "";
|
|
position: absolute;
|
|
width: 0;
|
|
height: 1px;
|
|
bottom: 0;
|
|
right: 0;
|
|
/* background-color: initial; */
|
|
transition: width 0.25s ease-out;
|
|
}
|
|
|
|
.menu-link::before {
|
|
background-color: #0D0E12;
|
|
}
|
|
|
|
.dark .menu-link::before {
|
|
background-color: #fff;
|
|
}
|
|
|
|
.active .nav-link-text::before {
|
|
width: 100%;
|
|
}
|
|
|
|
.nav-link:hover .nav-link-text::before,
|
|
.menu-link:hover::before {
|
|
width: 100%;
|
|
left: 0;
|
|
right: auto;
|
|
}
|
|
}
|
|
|
|
|
|
.sub-menu {
|
|
visibility: hidden;
|
|
opacity: 0;
|
|
color: #505158;
|
|
}
|
|
|
|
.sub-menu .no-hover {
|
|
color: #505158 !important;
|
|
}
|
|
|
|
.dark .sub-menu,
|
|
.dark .sub-menu .no-hover {
|
|
color: #fff !important;
|
|
}
|
|
|
|
.dark .sub-menu li:hover {
|
|
color: #66D9E2;
|
|
}
|
|
|
|
.sub-menu li:hover {
|
|
color: #0053D0;
|
|
}
|
|
|
|
.sub-menu {
|
|
transition: all .3s ease !important;
|
|
}
|
|
|
|
.nav-link span svg,
|
|
header nav {
|
|
transition: all 0.5s ease;
|
|
}
|
|
|
|
.nav-link:hover span svg {
|
|
transform: rotate(180deg);
|
|
}
|
|
|
|
@media (min-width:1024px) {
|
|
|
|
.nav-link:hover .sub-menu,
|
|
.nav-link:focus-within .sub-menu {
|
|
visibility: visible;
|
|
opacity: 1;
|
|
margin-top: 0;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 1024px) {
|
|
.sub-menu {
|
|
max-height: 0;
|
|
transform: translateY(-10px);
|
|
transition: all .7s ease !important;
|
|
}
|
|
|
|
.active .sub-menu {
|
|
max-height: 600px;
|
|
transform: translateY(0px);
|
|
opacity: 1;
|
|
visibility: visible;
|
|
margin-top: 0;
|
|
}
|
|
|
|
header nav {
|
|
visibility: hidden;
|
|
opacity: 0;
|
|
transform: translateX(100%);
|
|
}
|
|
|
|
header nav.open {
|
|
visibility: visible;
|
|
opacity: 1;
|
|
transform: translateX(0);
|
|
}
|
|
}
|
|
|
|
.lock-scroll {
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* hero */
|
|
header {
|
|
transition: all .7s ease;
|
|
}
|
|
|
|
.primary-header {
|
|
background: linear-gradient(270deg, #0053D0 35.85%, #0197FF 94.78%);
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
background-clip: text;
|
|
text-shadow: 0px 4px 74px #e9e7e2;
|
|
}
|
|
|
|
.dark .primary-header {
|
|
background: linear-gradient(270deg, #70F0F9 100%, #70F0F9 100%);
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
background-clip: text;
|
|
text-shadow: none;
|
|
}
|
|
|
|
.secondary-header {
|
|
color: #606c71;
|
|
text-shadow: 0px 4px 74px #e9e7e2;
|
|
}
|
|
|
|
.dark .secondary-header {
|
|
color: #fff;
|
|
text-shadow: none;
|
|
}
|
|
|
|
.description {
|
|
width: 31rem;
|
|
}
|
|
|
|
p a {
|
|
color: #0053D0;
|
|
text-decoration: underline;
|
|
text-underline-offset: 2px;
|
|
}
|
|
|
|
.dark p a {
|
|
color: #70F0F9;
|
|
}
|
|
|
|
/* For Contact & Invitation Page */
|
|
.primary-header-contact {
|
|
background: linear-gradient(251.16deg, #53c1ff 1.1%, #0053d0 100.82%);
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
background-clip: text;
|
|
text-shadow: 0px 4px 74px #e9e7e2;
|
|
}
|
|
|
|
.dark .primary-header-contact {
|
|
background: linear-gradient(270deg, #70F0F9 100%, #70F0F9 100%);
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
background-clip: text;
|
|
text-shadow: none;
|
|
}
|
|
|
|
.secondary-header-contact {
|
|
text-shadow: 0px 4px 74px #e9e7e2;
|
|
}
|
|
|
|
.dark .secondary-header-contact {
|
|
text-shadow: none;
|
|
}
|
|
|
|
.content_copy_with_tooltip {
|
|
background-color: #f8f8f6;
|
|
border-radius: 50px;
|
|
padding-bottom: 4px;
|
|
padding-top: 8px;
|
|
margin-top: 16px;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.content_copy_with_tooltip .tooltip {
|
|
vertical-align: -6px;
|
|
}
|
|
|
|
.content_copy_with_tooltip .content {
|
|
font-size: 15px;
|
|
}
|
|
|
|
.contact-tab>.contact-tab-content,
|
|
.job-tab>.job-tab-content {
|
|
opacity: 0;
|
|
max-height: 0;
|
|
transition: all 0.5s ease;
|
|
visibility: hidden;
|
|
transform: translateY(10px);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.contact-tab svg,
|
|
.job-tab svg {
|
|
transform: rotate(-180deg);
|
|
transition: all .5s ease;
|
|
}
|
|
|
|
.contact-tab.active>.contact-tab-content,
|
|
.job-tab.active>.job-tab-content {
|
|
opacity: 1;
|
|
max-height: 300px;
|
|
visibility: visible;
|
|
transform: translateY(0px);
|
|
}
|
|
|
|
.for-tablet .contact-tab.active>.contact-tab-content,
|
|
.for-tablet .job-tab.active>.job-tab-content {
|
|
min-height: 450px;
|
|
}
|
|
|
|
.contact-tab.active svg,
|
|
.contact-tab:hover svg,
|
|
.job-tab.active svg,
|
|
.job-tab:hover svg {
|
|
transform: rotate(0deg);
|
|
}
|
|
|
|
.d-none-if-js-disabled {
|
|
display: none !important;
|
|
} |