newsletter: site-wide signup modal with 7-day dismiss
Renders on every page via root layout. Behavior: - 5s delay after first paint so it doesn't slam the user. - Animates from a pill into the full card (bb-modal-pop keyframe); respects prefers-reduced-motion. - Heading "Get the latest in broadcast & media", email field, Subscribe + "Not now" + close (X). - Subscribe POSTs to the existing /api/newsletter/subscribe route (native system — newsletter_subscribers table + SMTP welcome via Mailcow/SMTP2GO). Listmonk wasn't installed anywhere on the infra; switching to it later is a one-line URL change. - "Not now" + backdrop click + Escape + X all dismiss for 7 days via localStorage["bb_newsletter_dismissed"]. - On success → "Check your email" panel + auto-close at 4s; subscribed flag stored in localStorage so the modal never re-prompts that visitor. Styling matches the site's dark-navy + electric-blue palette (NOT the neon ticker palette). No layout/page shifts — overlay only.
This commit is contained in:
@@ -1118,4 +1118,246 @@ h1, h2, h3 {
|
||||
|
||||
.bb-browse-item[aria-expanded="true"] .bb-browse-caret {
|
||||
transform: rotate(180deg) translateY(1px);
|
||||
}
|
||||
}
|
||||
/* ─── Newsletter modal (site-wide popup) ──────────────────────────────────── */
|
||||
.bb-modal-backdrop {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(5, 10, 15, 0.62);
|
||||
backdrop-filter: blur(6px);
|
||||
-webkit-backdrop-filter: blur(6px);
|
||||
z-index: 9000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 16px;
|
||||
animation: bb-modal-backdrop-fade 0.35s ease both;
|
||||
}
|
||||
@keyframes bb-modal-backdrop-fade {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
.bb-modal-card {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 440px;
|
||||
background:
|
||||
radial-gradient(120% 70% at 10% -10%, rgba(59,130,246,0.10), transparent 60%),
|
||||
linear-gradient(180deg, #11192a 0%, #0c121e 100%);
|
||||
border: 1px solid rgba(59,130,246,0.22);
|
||||
border-radius: 14px;
|
||||
padding: 28px 28px 24px;
|
||||
box-shadow:
|
||||
0 24px 60px rgba(0,0,0,0.55),
|
||||
0 0 0 1px rgba(255,255,255,0.02) inset;
|
||||
color: #e6ecf3;
|
||||
font-family: var(--font-body);
|
||||
}
|
||||
|
||||
/* Small-to-large open animation — scales the card up from a 65% pill and
|
||||
fades in. Honors prefers-reduced-motion. */
|
||||
.bb-modal-enter {
|
||||
animation: bb-modal-pop 0.42s cubic-bezier(0.22, 1, 0.36, 1) both;
|
||||
transform-origin: center bottom;
|
||||
}
|
||||
@keyframes bb-modal-pop {
|
||||
0% { opacity: 0; transform: translateY(28px) scale(0.62); border-radius: 999px; }
|
||||
55% { opacity: 1; transform: translateY(0) scale(1.02); border-radius: 18px; }
|
||||
100% { opacity: 1; transform: translateY(0) scale(1.00); border-radius: 14px; }
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.bb-modal-enter { animation: bb-modal-fade 0.18s ease both; }
|
||||
}
|
||||
@keyframes bb-modal-fade { from { opacity: 0; } to { opacity: 1; } }
|
||||
|
||||
.bb-modal-close {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 999px;
|
||||
background: rgba(255,255,255,0.04);
|
||||
border: 1px solid rgba(255,255,255,0.06);
|
||||
color: #98a3b3;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
|
||||
}
|
||||
.bb-modal-close:hover {
|
||||
background: rgba(59,130,246,0.18);
|
||||
color: #ffffff;
|
||||
border-color: rgba(59,130,246,0.45);
|
||||
}
|
||||
|
||||
.bb-modal-eyebrow {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.2em;
|
||||
text-transform: uppercase;
|
||||
color: #3b82f6;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.bb-modal-eyebrow-dot {
|
||||
display: inline-block;
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 50%;
|
||||
background: #3b82f6;
|
||||
box-shadow: 0 0 10px rgba(59,130,246,0.65);
|
||||
animation: bb-modal-pulse 2.2s ease-in-out infinite;
|
||||
}
|
||||
@keyframes bb-modal-pulse {
|
||||
0%, 100% { opacity: 1; transform: scale(1); }
|
||||
50% { opacity: 0.55; transform: scale(0.85); }
|
||||
}
|
||||
|
||||
.bb-modal-heading {
|
||||
font-family: var(--font-heading);
|
||||
font-size: 22px;
|
||||
font-weight: 800;
|
||||
line-height: 1.18;
|
||||
margin: 0 0 8px;
|
||||
color: #ffffff;
|
||||
letter-spacing: -0.005em;
|
||||
}
|
||||
.bb-modal-sub {
|
||||
margin: 0 0 18px;
|
||||
font-size: 13.5px;
|
||||
line-height: 1.55;
|
||||
color: #98a3b3;
|
||||
}
|
||||
|
||||
.bb-modal-form { margin: 0; }
|
||||
.bb-modal-label {
|
||||
display: block;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.14em;
|
||||
text-transform: uppercase;
|
||||
color: #6b7585;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.bb-modal-input {
|
||||
width: 100%;
|
||||
background: rgba(255,255,255,0.04);
|
||||
border: 1px solid rgba(255,255,255,0.10);
|
||||
border-radius: 8px;
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
font-family: var(--font-body);
|
||||
padding: 11px 13px;
|
||||
outline: 0;
|
||||
transition: border-color 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
|
||||
}
|
||||
.bb-modal-input:focus {
|
||||
border-color: #3b82f6;
|
||||
background: rgba(59,130,246,0.06);
|
||||
box-shadow: 0 0 0 3px rgba(59,130,246,0.18);
|
||||
}
|
||||
.bb-modal-input::placeholder { color: #4f5763; }
|
||||
.bb-modal-input:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
|
||||
.bb-modal-err {
|
||||
margin-top: 8px;
|
||||
padding: 8px 10px;
|
||||
background: rgba(239,68,68,0.10);
|
||||
border: 1px solid rgba(239,68,68,0.32);
|
||||
border-radius: 6px;
|
||||
color: #fca5a5;
|
||||
font-size: 12.5px;
|
||||
}
|
||||
|
||||
.bb-modal-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
.bb-modal-btn-primary,
|
||||
.bb-modal-btn-secondary {
|
||||
flex: 1;
|
||||
padding: 11px 16px;
|
||||
border-radius: 8px;
|
||||
font-family: var(--font-body);
|
||||
font-size: 13.5px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.01em;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s ease, color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
.bb-modal-btn-primary {
|
||||
background: linear-gradient(180deg, #3b82f6 0%, #2563eb 100%);
|
||||
color: #ffffff;
|
||||
box-shadow: 0 6px 18px rgba(59,130,246,0.28);
|
||||
}
|
||||
.bb-modal-btn-primary:hover:not(:disabled) {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 10px 22px rgba(59,130,246,0.40);
|
||||
}
|
||||
.bb-modal-btn-primary:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
box-shadow: none;
|
||||
}
|
||||
.bb-modal-btn-secondary {
|
||||
background: transparent;
|
||||
color: #98a3b3;
|
||||
border-color: rgba(255,255,255,0.10);
|
||||
}
|
||||
.bb-modal-btn-secondary:hover:not(:disabled) {
|
||||
color: #ffffff;
|
||||
border-color: rgba(255,255,255,0.22);
|
||||
background: rgba(255,255,255,0.04);
|
||||
}
|
||||
.bb-modal-btn-secondary:disabled { opacity: 0.5; cursor: not-allowed; }
|
||||
|
||||
.bb-modal-fineprint {
|
||||
margin: 14px 0 0;
|
||||
font-size: 11px;
|
||||
color: #5a6470;
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
||||
/* Success state */
|
||||
.bb-modal-success {
|
||||
text-align: center;
|
||||
padding: 6px 0 8px;
|
||||
}
|
||||
.bb-modal-success-icon {
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
margin: 0 auto 14px;
|
||||
border-radius: 50%;
|
||||
background: rgba(59,130,246,0.14);
|
||||
border: 1px solid rgba(59,130,246,0.45);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #3b82f6;
|
||||
}
|
||||
.bb-modal-success-title {
|
||||
font-family: var(--font-heading);
|
||||
font-size: 19px;
|
||||
font-weight: 800;
|
||||
color: #ffffff;
|
||||
margin: 0 0 6px;
|
||||
}
|
||||
.bb-modal-success-msg {
|
||||
color: #98a3b3;
|
||||
font-size: 13.5px;
|
||||
line-height: 1.55;
|
||||
margin: 0;
|
||||
}
|
||||
.bb-modal-success-msg strong {
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user