- `{contact}` or `{contact: Label}` to add a button on article, additional access on top right corner letter emoji
- Article button styling (with custom shape for Nitro theme)
- Visitor contact panel: live thread over the activity socket, rich composer (formatting,/file uploads), PoW anti-spam gating, contact email reveal after proof
- Admin inbox in the same overlay: thread list, replies, read marking, unread badge; background watch keeps badge and notifications live
- Messaging site settings (button label, email subject, our email) with per-language overrides and auto-translation support
- Browser notifications for new messages on both sides, with click-through to the new content
- Close conversation: archives the thread for admins, starts visitors fresh
Reviewed-on: https://git.zi.fi/LeoVasanko/pagerite/pulls/3
275 lines
8.8 KiB
CSS
275 lines
8.8 KiB
CSS
/* Nitro theme: racing/HUD style — saturated orange + cyan, console/HUD-style
|
||
monospace display type, an orange racing-tab nav with a bezier clip-path,
|
||
matching slanted-parallelogram buttons, and a dark bezier banner. Follows
|
||
prefers-color-scheme: the light scheme
|
||
is a warm light-grey page, the dark scheme a deep violet page; the banner
|
||
and other dark/bright elements carry over unchanged.
|
||
|
||
Color model: the base stylesheet's variables carry the page; nitro adds
|
||
a small set of theme-specific colors below, and everything else in the
|
||
file references variables only, so recoloring happens here. */
|
||
|
||
:root {
|
||
color-scheme: light dark;
|
||
|
||
/* Page palette (base variables) */
|
||
--bg: #eee;
|
||
/* warm light grey page background */
|
||
--surface: #fff;
|
||
--text: #1a1a1a;
|
||
--muted: #655f52;
|
||
/* warm grey secondary text */
|
||
--line: #1a1a1a1f;
|
||
/* hairlines: tables, column rules */
|
||
--accent: #ff6a00;
|
||
/* racing orange: decorations, nav tab, markers */
|
||
--accent2: #008ba3;
|
||
/* deep cyan: h3, blockquote bar, nested markers */
|
||
|
||
/* Nitro-specific colors */
|
||
--orange-deep: #d95a00;
|
||
/* orange dark enough for body text (h2, links) */
|
||
--ink: #000;
|
||
/* pure black details: tab text, brand shadow */
|
||
--neon: #59ecff;
|
||
/* glowing cyan: current page on the orange tab */
|
||
--tab-current: #eee;
|
||
--tab-hover: #fff;
|
||
/* glowing white: nav hover (kept bright: the
|
||
nav glow is text-shadow, which fades dimmer) */
|
||
--tab-muted: #0000008c;
|
||
/* secondary labels on the orange tab */
|
||
|
||
--font-body: var(--font-montserrat);
|
||
--font-heading: var(--font-literata);
|
||
--font-nav: var(--font-heading);
|
||
--nav-weight: 700;
|
||
--code-x-height: 0.517; /* Montserrat's x-height ratio */
|
||
/* Neutral grey selection instead of the accent tint: accent-colored
|
||
text (h2, links, markers) stays readable on it in both schemes. */
|
||
--selection-bg: #6664;
|
||
}
|
||
|
||
/* Dark scheme: same identity, but the page goes deep violet (never muddy
|
||
near-black); the cyan and orange accents brighten to keep their punch. */
|
||
@media (prefers-color-scheme: dark) {
|
||
:root {
|
||
--bg: #17141f;
|
||
--surface: #231f2e;
|
||
--text: #f0ede8;
|
||
--muted: #a89f8f;
|
||
--line: #ffffff22;
|
||
--accent2: #2fc3dd;
|
||
/* brighter cyan, readable on dark */
|
||
--orange-deep: #ff8a3d;
|
||
/* brighter orange, readable on dark */
|
||
--code-bg: #12101b;
|
||
/* code wells join the violet family */
|
||
}
|
||
}
|
||
|
||
/* Any banner used is separated from page by a thick orange line */
|
||
#banner {
|
||
border-bottom: 4px solid var(--accent);
|
||
}
|
||
|
||
/* Oversized outlined brand, spilling off the banner edge: orange stroke,
|
||
solid black fill. */
|
||
#brand {
|
||
/* Scales down proportionally below ~1000px: 10rem at a 62.5rem viewport,
|
||
shrinking with vmin (smaller of viewport width/height) below that. */
|
||
font-size: clamp(2.5rem, 16vmin, 10rem);
|
||
line-height: 1.2;
|
||
font-weight: 700;
|
||
letter-spacing: 0.04em;
|
||
text-transform: uppercase;
|
||
white-space: nowrap;
|
||
color: var(--orange-deep);
|
||
text-shadow: 0 0 0.1em black;
|
||
}
|
||
|
||
#nav {
|
||
font-size: 0.95em;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
/* Racing tab: sitting at the bottom of the banner, with a bezier clip —
|
||
slanted sides that join top and bottom horizontally, and a shallow
|
||
wide notch at the top middle. Generous side padding so the em-based
|
||
slants fit. The border-radius is the fallback for browsers without
|
||
shape(). */
|
||
background: var(--accent);
|
||
width: fit-content;
|
||
padding: 0.3em 2.5em 0;
|
||
border-radius: 1.2em 1.2em 0 0;
|
||
clip-path: shape(
|
||
/* left side */
|
||
from 0% 100%,
|
||
curve to 2.5em 0 with 2em 100% / 1em 0,
|
||
/* notch: ≈ golden-ratio width of the available top edge */
|
||
hline to calc(19.1% + 1.7em),
|
||
line to calc(19.1% + 2.1em) 0.2em,
|
||
hline to calc(80.9% - 2.1em),
|
||
line to calc(80.9% - 1.7em) 0,
|
||
/* right side, bottom */
|
||
hline to calc(100% - 2.5em),
|
||
curve to 100% 100% with calc(100% - 1em) 0 / calc(100% - 2em) 100%,
|
||
close);
|
||
}
|
||
|
||
#nav a {
|
||
color: var(--ink);
|
||
}
|
||
|
||
/* Current page and hover glow on the orange tab; both stay bright colors
|
||
because the glow is text-shadow. */
|
||
#nav .current {
|
||
color: var(--tab-current);
|
||
text-shadow: 0 0 0.1em;
|
||
}
|
||
|
||
#nav a:hover {
|
||
color: var(--tab-hover);
|
||
text-shadow: 0 0 0.1em;
|
||
}
|
||
|
||
#nav span {
|
||
color: var(--tab-muted);
|
||
}
|
||
|
||
/* Buttons in the article flow (the {contact:} trigger and any raw
|
||
<button> in the markup): a racing parallelogram with / slanted sides,
|
||
clipped with the same shape() language as the nav tab. All buttons
|
||
are forced to one fixed 1.7em height (inline-flex centering, nowrap,
|
||
no border — it would be invisible under the clip), so every button
|
||
gets the identical shape and the geometry is exact: a ~62° slant from
|
||
the 0.9em run. The obtuse top-left and bottom-right corners replicate
|
||
the nav tab's top-left corner: a wide bezier sweep with the same
|
||
0.8/0.6 control-handle split along the joining edges (over a 0.5em
|
||
tangent run), mirrored between the two corners. The sharp corners
|
||
keep small arcs, in balance with the wide sweeps (0.22em, arc
|
||
≈ 0.45em — about half the obtuse sweep's, so the sharp corners stay
|
||
subordinate). border-radius is the fallback for browsers without
|
||
shape(). Asymmetric inline padding keeps the text clear of the
|
||
slants (wider on the right: the wide bottom-right sweep cuts deeper
|
||
into the label's end side). Editor chrome (.icon-btn pens, .copy)
|
||
keeps its own styling. The {contact:} envelope's line-height is
|
||
reduced in the base stylesheet so it doesn't outgrow this height. */
|
||
.contact-trigger,
|
||
article button:not(.icon-btn):not(.copy) {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 1.7em;
|
||
padding: 0 1.3em 0 1em;
|
||
white-space: nowrap;
|
||
/* Same typography as the contact trigger (raw <button>s otherwise get
|
||
the small UA font): nav family/weight, article size and leading. */
|
||
font-family: var(--font-nav);
|
||
font-weight: var(--nav-weight);
|
||
font-size: inherit;
|
||
line-height: inherit;
|
||
color: var(--ink);
|
||
background: var(--accent);
|
||
border: none;
|
||
border-radius: 0.2em;
|
||
cursor: pointer;
|
||
clip-path: shape(
|
||
/* bottom edge, left to right */
|
||
from 0.365em 100%,
|
||
hline to calc(100% - 1.4em),
|
||
/* bottom-right corner: nav-style bezier, mirrored from top-left */
|
||
curve to calc(100% - 0.666em) calc(100% - 0.442em)
|
||
with calc(100% - 1.1em) 100% / calc(100% - 0.853em) calc(100% - 0.088em),
|
||
/* right slant */
|
||
line to calc(100% - 0.171em) 0.323em,
|
||
/* top-right corner: sharp, small arc */
|
||
arc to calc(100% - 0.365em) 0% of 0.22em ccw,
|
||
/* top edge, right to left */
|
||
hline to 1.4em,
|
||
/* top-left corner: nav-style bezier */
|
||
curve to 0.666em 0.442em with 1.1em 0 / 0.853em 0.088em,
|
||
/* left slant */
|
||
line to 0.171em calc(100% - 0.323em),
|
||
/* bottom-left corner: sharp, small arc */
|
||
arc to 0.365em 100% of 0.22em ccw,
|
||
close);
|
||
}
|
||
|
||
article button:not(.icon-btn):not(.copy):hover {
|
||
color: var(--tab-hover);
|
||
text-shadow: 0 0 0.1em;
|
||
}
|
||
|
||
/* Console-style headings: uppercase monospace. h1 in the page text color
|
||
with a hazard-stripe underline, h2 deep orange, h3 cyan. */
|
||
article h1 {
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.02em;
|
||
color: var(--text);
|
||
font-weight: 700;
|
||
padding-bottom: 0.5rem;
|
||
/* The hazard-stripe underline breaks out of the page box: the negative
|
||
end margin extends the h1's box (and thus its background) all the
|
||
way to the viewport's edge on that side. */
|
||
margin-inline-end: calc((100% - 100vw) / 2);
|
||
background:
|
||
linear-gradient(-55deg,
|
||
transparent 0 0.2rem,
|
||
var(--accent) 0.2rem 0.9rem,
|
||
transparent 0.9rem 1.4rem) -0.2rem bottom / 1.4rem 4px repeat-x;
|
||
}
|
||
|
||
article h2 {
|
||
color: var(--orange-deep);
|
||
font-weight: 700;
|
||
}
|
||
|
||
article h3 {
|
||
color: var(--accent2);
|
||
font-weight: 700;
|
||
}
|
||
|
||
article a:hover {
|
||
color: var(--accent2);
|
||
text-decoration: none;
|
||
}
|
||
|
||
/* Chevron markers instead of the base emoji diamonds. */
|
||
article ul li::before {
|
||
content: "»";
|
||
color: var(--accent);
|
||
font-weight: 700;
|
||
}
|
||
|
||
article ul ul li::before {
|
||
content: "›";
|
||
color: var(--accent2);
|
||
}
|
||
|
||
article ul ul ul li::before {
|
||
color: var(--muted);
|
||
}
|
||
|
||
blockquote {
|
||
border-inline-start-color: var(--accent2);
|
||
background: color-mix(var(--accent2) 6%, transparent);
|
||
padding: 0.25rem 0.75rem;
|
||
/* Keep the quoted text on the paragraph edge: the tinted box extends
|
||
past it by its own border/padding, like code blocks. */
|
||
margin: 0 0 1rem;
|
||
margin-inline: -1rem -0.75rem;
|
||
}
|
||
|
||
/* Code follows the color scheme; the dark-scheme well joins the violet
|
||
family (--code-bg above). The orange side bar stays in both. */
|
||
pre {
|
||
border-inline-start: 0.25rem solid var(--accent);
|
||
/* Text on the paragraph edge: the box extends by padding + border. */
|
||
margin-inline-start: calc(-0.8rem - 0.25rem);
|
||
border-radius: 3px;
|
||
}
|
||
|
||
img {
|
||
border-radius: 3px;
|
||
}
|