Template:UI/hero/styles.css
From Miniscope
/* TemplateStyles for {{UI/hero}}.
*
* Two layout variants share the same DOM:
* * .wiki-hero--background — full-bleed image with overlay, centered
* text. Lab-wiki style. Pairs with theme=dark by default.
* * .wiki-hero--product — light gradient with image floated right
* and text on the left. Miniscope.org style. Pairs with theme=light.
*
* Stacking inside the hero box (z-index from back to front):
* 0. .wiki-hero background — fallback gradient (visible if no image
* or if the image fails to load)
* 1. .wiki-hero__media — the [[File:...]] image, object-fit: cover
* 2. .wiki-hero::before — readability overlay (variant-specific)
* 3. .wiki-hero__content — text and actions
*
* Theme tokens via var(--labki-*, literal). Geometry stays literal —
* MW 1.44.5 / css-sanitizer 5.5.0 accepts var() in `background`,
* `color`, and `border` shorthand, but rejects it in `border-radius`,
* `box-shadow`, `padding`, `margin`, `transition`, `transform`,
* `inset`, `top/right/bottom/left`, `width`, `height`, `z-index`, and
* most other numeric properties. The hero's geometry rarely needs to
* vary by theme anyway.
*
* Page-shell concerns DO NOT live here — TemplateStyles auto-scopes
* selectors under .mw-parser-output, so body- and html-scoped rules
* can't migrate into this file. The wiki's MediaWiki:Common.css must
* still carry:
* * body.page-Main_Page / body.mainpage padding neutralizers (so
* the negative horizontal margins reach the content card edge)
* * .hero-btn-anon / .hero-btn-user visibility against
* body.tweeki-user-anon
* See Template:UI/hero docstring for the exact CSS to keep on the wiki.
*/
/* ============================================================
BASE
============================================================ */
.wiki-hero {
position: relative;
overflow: hidden;
margin: -32px -40px 32px;
padding: 72px 40px 60px;
border-radius: 8px 8px 0 0;
z-index: 0;
}
.wiki-hero__media {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1;
}
.wiki-hero__media img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
/* Readability overlay sits above the image, below the content. The
actual gradient stack is set per variant below.
No `pointer-events: none` even though the overlay covers the hero —
the css-sanitizer 5.5.0 used by TemplateStyles rejects that property
(templatestyles-error-unrecognized-property). It's not needed here
anyway: the overlay has no event handler, the image below it
renders without an <a> wrapper (link= empty), and content sits
above on z-index 3, so nothing interactive is being intercepted. */
.wiki-hero::before {
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 2;
}
.wiki-hero__content {
position: relative;
z-index: 3;
max-width: 720px;
}
.wiki-hero__eyebrow {
font-size: 0.85rem;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.18em;
margin: 0 0 12px;
}
.wiki-hero__title {
font-size: 3.25rem;
font-weight: 800;
line-height: 1.05;
margin: 0 0 18px;
letter-spacing: -0.02em;
}
.wiki-hero__tagline {
font-size: 1.1rem;
line-height: 1.55;
margin: 0 0 24px;
max-width: 580px;
}
.wiki-hero__actions {
margin-top: 8px;
display: flex;
flex-wrap: wrap;
gap: 12px;
}
/* ============================================================
THEME: dark
White text on a dimmed image. The fallback gradient on
.wiki-hero shows through if no image is provided. The overlay
on ::before guarantees text contrast on any image.
============================================================ */
.wiki-hero--dark {
color: #ffffff;
background: linear-gradient(135deg, #000000 0%, #0e1c2e 50%, var(--labki-primary, #003B5C) 100%);
}
.wiki-hero--dark::before {
background:
radial-gradient(ellipse 640px 280px at center,
rgba(0, 0, 0, 0.55) 0%,
rgba(0, 0, 0, 0.20) 70%,
rgba(0, 0, 0, 0) 100%),
linear-gradient(rgba(0, 0, 0, 0.35), rgba(0, 0, 0, 0.50));
}
.wiki-hero--dark .wiki-hero__eyebrow {
color: rgba(255, 255, 255, 0.85);
text-shadow: 0 1px 8px rgba(0, 0, 0, 0.6);
}
.wiki-hero--dark .wiki-hero__title {
color: #ffffff;
}
.wiki-hero--dark .wiki-hero__tagline {
color: rgba(255, 255, 255, 0.82);
}
/* The platform's labki-tweeki.css recolors links inside
.mw-parser-output; the hero sits on dark and needs to override
that with !important. Same pattern the pre-template Common.css
used.
Plain `text-decoration: underline` only — the css-sanitizer 5.5.0
used by TemplateStyles rejects the CSS Text Decoration Level 4
properties (`text-underline-offset`, `text-decoration-thickness`,
`text-decoration-color` as a transition target) with
templatestyles-error-unrecognized-property. Default browser
underline placement and weight are acceptable. */
.wiki-hero--dark .wiki-hero__tagline a,
.wiki-hero--dark .wiki-hero__tagline a:visited {
color: #ffffff !important;
text-decoration: underline;
transition: color 0.15s;
}
.wiki-hero--dark .wiki-hero__tagline a:hover {
color: rgba(255, 255, 255, 0.78) !important;
}
/* ============================================================
THEME: light
Dark text on a light gradient. Used by the product variant
most often, but theme is independent of variant.
============================================================ */
.wiki-hero--light {
color: var(--labki-heading, #003B5C);
background:
linear-gradient(90deg,
rgba(246, 248, 250, 1) 0%,
rgba(248, 249, 250, 0.95) 38%,
rgba(238, 241, 244, 1) 100%);
}
.wiki-hero--light .wiki-hero__eyebrow {
color: var(--labki-accent, #2774AE);
}
.wiki-hero--light .wiki-hero__title {
color: var(--labki-heading, #003B5C);
}
.wiki-hero--light .wiki-hero__tagline {
color: var(--labki-text-muted, #5a6a7a);
}
/* ============================================================
VARIANT: product
Image anchored right; readability fade gives the left half a
safe text zone. Pairs naturally with align=left.
============================================================ */
.wiki-hero--product .wiki-hero__media img {
object-position: right center;
}
/* The fade ends at 70% of the hero's width so the rightmost ~30%
shows the image untouched — that's the product showcase zone.
Stops at 0/25/45/70% give a soft curve that keeps the text
readable in the left half without abruptly cutting off. */
.wiki-hero--product.wiki-hero--light::before {
background:
linear-gradient(90deg,
rgba(248, 249, 250, 0.96) 0%,
rgba(248, 249, 250, 0.82) 25%,
rgba(248, 249, 250, 0.20) 45%,
rgba(248, 249, 250, 0.00) 70%);
}
/* Dark counterpart — same stop positions for a consistent curve,
black instead of off-white. Without this, .wiki-hero--dark::before
(the centered spotlight from the background variant) would apply
to product+dark and dim the image globally, defeating the
right-side showcase. Higher specificity than .wiki-hero--dark::before
so this one wins for the product+dark combination. */
.wiki-hero--product.wiki-hero--dark::before {
background:
linear-gradient(90deg,
rgba(0, 0, 0, 0.92) 0%,
rgba(0, 0, 0, 0.78) 25%,
rgba(0, 0, 0, 0.18) 45%,
rgba(0, 0, 0, 0.00) 70%);
}
/* ============================================================
ALIGNMENT
Drives content block position, text-align, and action-row
justification together so a single param flips all three.
============================================================ */
.wiki-hero--align-center .wiki-hero__content {
margin-left: auto;
margin-right: auto;
text-align: center;
}
.wiki-hero--align-center .wiki-hero__tagline {
margin-left: auto;
margin-right: auto;
}
.wiki-hero--align-center .wiki-hero__actions {
justify-content: center;
}
.wiki-hero--align-left .wiki-hero__content {
margin-left: 0;
margin-right: auto;
text-align: left;
}
.wiki-hero--align-left .wiki-hero__actions {
justify-content: flex-start;
}
.wiki-hero--align-right .wiki-hero__content {
margin-left: auto;
margin-right: 0;
text-align: right;
}
.wiki-hero--align-right .wiki-hero__actions {
justify-content: flex-end;
}
/* ============================================================
RESPONSIVE
Tighter padding and smaller type below 768px. Border radius
drops to 0 because on narrow screens the content card is
already edge-to-edge and rounded corners look broken.
============================================================ */
@media (max-width: 768px) {
.wiki-hero {
margin: -20px -18px 24px;
padding: 48px 20px 44px;
border-radius: 0;
}
.wiki-hero__title {
font-size: 2.25rem;
}
.wiki-hero__tagline {
font-size: 1rem;
}
}