
/* GLOBAL */
@import url('https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,200..900;1,400..600&display=swap');
/* ============================================================
SCIENTIFIC SPECIALTIES, INC. | SITE CSS
Brand source: SSIbio Branding Guidelines (2026)
============================================================ */
/* ---------- BRAND TOKENS -------------------------------------
The reds resolve to the Omnia theme's primary / primary-alt as
soon as those are set to SSI Red and Bright Red. The hex values
are only the fallback, so nothing has to be ripped out later.
Maroon and Gray are the two extra brand-gradient stops that the
theme has no slot for. */
/* ==== */
html {
scroll-behavior: smooth;
}
#savecontent {
margin-top: -2px;
}
.anchor {
scroll-margin-top: 100px;
}
h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6 {
color: inherit;
}
h1, .h1 {
font-size: clamp(35px, 4.4vw, 46px);
}
h1.mega, .h1.mega {
font-size: clamp(36px, 4.7vw, 70px);
}
h1.ultra, .h1.ultra {
font-size: clamp(37px, 5.3vw, 95px);
}
h2, .h2 {
font-size: clamp(32px, 4vw, 42px);
}
h3, .h3 {
font-size: clamp(29px, 3.6vw, 37px);
}
h4, .h4 {
font-size: clamp(26px, 3.2vw, 32px);
}
h5, .h5 {
font-size: clamp(23px, 2.8vw, 27px);
}
h6, .h6 {
font-size: clamp(20px, 2.4vw, 22px);
}
body {
font-size: clamp(15px, 2vw, 18px);
}
.btn {
white-space: normal;
}
a:hover img,
a.bg-img:hover a.bg-image:hover {
opacity: .85;
}
#savecontent img {
max-width: 100% !important;
height: auto !important;
}
.rightfloat {
float: right;
margin: 0 0 .5rem 1rem;
width: 40%;
}
@media (max-width: 767px) {
.rightfloat {
float: none;
margin: 0 0 1rem 0;
width: 100%;
}
}
.btn-primary {
color: white !important;
}
.round {
border-radius: 12px;
}
.carousel-control-next-icon,
.carousel-control-prev-icon {
background-color: rgba(0, 0, 0, 0.9);
padding: 1rem;
background-size: 20px;
}
@media(min-width: 1600px) {
.container {
max-width: 1300px;
}
}
@media(min-width: 1600px) {
.container.container-wide {
width: 1500px !important;
max-width: 1500px !important;
}
}
.product-image {
background-size: cover !important;
min-height: auto !important;
padding-bottom: 75%;
}
#savecontent form label {
font-weight: bold;
}
#savecontent form .checkbox-group label,
#savecontent form .radio-group label {
font-weight: normal;
}
.formbuilder-required {
color: red;
}
.text-right.addToCart {
text-align: left !important;
}
.blog-detail-page {
background: var(--light);
}
.blog-detail-page .blog {
border-radius: 12px;
padding: 1.5rem;
background: white;
box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.2);
}
.blog-detail-page .blog h4 {
margin-top: 1rem;
}
form li p {
margin-bottom: 0;
}
form label {
font-weight: bold;
}
form .checkbox-group label,
form .radio-group label {
font-weight: normal;
}
.formbuilder-checkbox,
.formbuilder-radio {
margin-bottom: 4px;
}
.v3-catalog .v3-card-img span:first-of-type, .v3-store .v3-qv-main {
background-size: contain !important;
background-color: white !important;
padding-bottom: 80% !important;
}
.v3-store .v3-qv-thumb {
border: 2px solid #ddd !important;
background-size: contain !important;
background-repeat: no-repeat !important;
background-color: white !important;
}
.v3-pdp .v3-pdp-thumb img {
object-fit: contain !important;
}
.v3-pdp .v3-pdp-stage {
aspect-ratio: 3 / 2 !important;
}
.v3-btn.v3-btn-ghost:hover {
color: inherit !important;
}
.v3-pdp .v3-pdp-rel-img {
aspect-ratio: 5 / 4 !important;
background-size: contain !important;
background-repeat: no-repeat;
background-color: white !important;
}
/* ---------- BRAND TOKENS -------------------------------------
Straight from the CMYK swatches in the SSI branding guidelines.
Deliberately NOT wired to var(--primary): Bootstrap ships its own
--primary (blue) in :root, so anything falling back through it
turns blue. Set the Omnia theme primary to --ssi-red and
primary-alt to --ssi-bright and the two systems agree. */
:root {
--ssi-maroon: #5e1621;
--ssi-red: #ae1e2c;
--ssi-red-dk: #8f1622;
--ssi-bright: #d9232a;
--ssi-gray: #97a0a5;
--ssi-ink: #14171a;
--ssi-body: #4f585e;
--ssi-muted: #79838a;
--ssi-line: #e2e6e9;
--ssi-wash: #f5f6f8;
--ssi-wash-2: #eef0f3;
--ssi-grad: linear-gradient(100deg, #5e1621 0%, var(--ssi-red) 34%, var(--ssi-bright) 62%, var(--ssi-gray) 100%);
--ssi-grad-soft: linear-gradient(120deg, rgba(94, 22, 33, .07) 0%, rgba(174, 30, 44, .06) 45%, rgba(151, 160, 165, .07) 100%);
--ssi-font: 'Mulish', 'Avenir Next', 'Avenir', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
--ssi-r: 10px;
--ssi-r-sm: 6px;
--ssi-shadow: 0 1px 2px rgba(20, 23, 26, .04), 0 10px 34px rgba(20, 23, 26, .07);
--ssi-shadow-lg: 0 2px 6px rgba(20, 23, 26, .05), 0 26px 60px rgba(20, 23, 26, .12);
}
/* ---------- BASE --------------------------------------------- */
html {
scroll-behavior: smooth;
}
body {
font-family: var(--ssi-font);
font-size: clamp(15px, 2vw, 17px);
line-height: 1.68;
color: var(--ssi-body);
-webkit-font-smoothing: antialiased;
}
#savecontent {
margin-top: -2px;
}
#savecontent img {
max-width: 100% !important;
height: auto !important;
}
.anchor {
scroll-margin-top: 140px;
}
/* Guideline says headers are Avenir LIGHT. Base weight is 300 so an
un-bolded heading renders light, and the Omnia editor's bold toggle
still lands at 700 on its own. Never force weight here. */
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
font-family: var(--ssi-font);
font-weight: 300;
color: var(--ssi-ink);
letter-spacing: -.015em;
line-height: 1.14;
}
h1, .h1 { font-size: clamp(34px, 4.4vw, 46px); }
h1.mega, .h1.mega { font-size: clamp(36px, 5vw, 66px); }
h1.ultra, .h1.ultra { font-size: clamp(38px, 5.6vw, 84px); }
h2, .h2 { font-size: clamp(28px, 3.7vw, 40px); }
h3, .h3 { font-size: clamp(25px, 3.2vw, 33px); }
h4, .h4 { font-size: clamp(22px, 2.7vw, 27px); }
h5, .h5 { font-size: clamp(19px, 2.3vw, 22px); }
h6, .h6 { font-size: clamp(17px, 2vw, 19px); }
/* ---------- BUTTONS -------------------------------------------
Bootstrap class names are kept so the Omnia editor still knows
what these are, but the brand colors are asserted here rather
than left to whatever the theme happens to be compiled with. */
.btn {
font-family: var(--ssi-font);
font-weight: 700;
font-size: 15px;
letter-spacing: .015em;
border-radius: var(--ssi-r-sm);
padding: .78rem 1.7rem;
white-space: normal;
border-width: 1px;
transition: background-color .2s ease, border-color .2s ease, color .2s ease, box-shadow .2s ease;
}
.btn-lg {
padding: .95rem 2.1rem;
font-size: 16px;
}
.btn-sm {
padding: .5rem 1.1rem;
font-size: 13px;
}
/* keeps side-by-side buttons on the same baseline and gives a
wrapped pair breathing room on narrow screens */
.btn {
vertical-align: top;
margin-bottom: .5rem;
}
.btn-primary {
background-color: var(--ssi-red);
border-color: var(--ssi-red);
color: #fff !important;
}
.btn-primary:hover,
.btn-primary:focus,
.btn-primary:not(:disabled):not(.disabled):active {
background-color: var(--ssi-red-dk);
border-color: var(--ssi-red-dk);
box-shadow: 0 6px 18px rgba(174, 30, 44, .26);
}
.btn-primary-alt {
background-color: var(--ssi-bright);
border-color: var(--ssi-bright);
color: #fff !important;
}
.btn-primary-alt:hover,
.btn-primary-alt:focus {
background-color: var(--ssi-red);
border-color: var(--ssi-red);
color: #fff !important;
}
.btn-outline-dark {
border-color: #c9d0d5;
color: var(--ssi-ink);
background-color: transparent;
}
.btn-outline-dark:hover,
.btn-outline-dark:focus {
background-color: transparent;
border-color: var(--ssi-red);
color: var(--ssi-red);
}
.btn-light {
background-color: #fff;
border-color: #fff;
color: var(--ssi-maroon);
}
.btn-light:hover,
.btn-light:focus {
background-color: #fff;
border-color: #fff;
color: var(--ssi-red);
}
.btn-outline-light {
border-color: rgba(255, 255, 255, .5);
color: #fff;
background-color: transparent;
}
.btn-outline-light:hover,
.btn-outline-light:focus {
background-color: rgba(255, 255, 255, .12);
border-color: #fff;
color: #fff;
}
.btn:focus,
.btn.focus {
box-shadow: 0 0 0 3px rgba(174, 30, 44, .22);
}
/* trailing arrow inside a button. Keyed to fa-arrow-right rather than
any .fas so a button with a LEADING icon is not affected. Nudges on
hover, same as .ssi-go. */
.btn .fa-arrow-right {
margin-left: .6rem;
font-size: .82em;
transition: transform .22s ease;
}
.btn:hover .fa-arrow-right {
transform: translateX(4px);
}
/* ---------- SHARED TYPE PIECES -------------------------------
.ssi-eyebrow = the guideline sub-header: Avenir Black, uppercase
.ssi-lead = intro paragraph
.ssi-note = the guideline footnote: Book Oblique
.ssi-gt = display text filled with the brand gradient */
.ssi-eyebrow {
font-size: clamp(11px, 1.3vw, 12.5px);
font-weight: 900;
letter-spacing: .19em;
text-transform: uppercase;
color: var(--ssi-red);
margin: 0 0 .85rem;
line-height: 1.4;
}
.ssi-eyebrow-line {
display: inline-flex;
align-items: center;
}
.ssi-eyebrow-line::before {
content: "";
width: 34px;
height: 2px;
margin-right: .85rem;
background: var(--ssi-grad);
flex: 0 0 auto;
}
.ssi-eyebrow-light {
color: #fff;
}
.ssi-eyebrow-light.ssi-eyebrow-line::before {
background: rgba(255, 255, 255, .55);
}
.ssi-lead {
font-size: clamp(16px, 2.1vw, 19px);
line-height: 1.65;
color: var(--ssi-body);
max-width: 62ch;
}
.ssi-lead-c {
margin-left: auto;
margin-right: auto;
}
.ssi-note {
font-size: 13px;
font-style: italic;
color: var(--ssi-muted);
line-height: 1.55;
}
.ssi-gt {
color: var(--ssi-red);
background: var(--ssi-grad);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
}
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
.ssi-gt {
background: none;
-webkit-text-fill-color: currentColor;
}
}
.ssi-rule {
width: 62px;
height: 3px;
border: 0;
margin: 1.35rem 0 1.45rem;
background: var(--ssi-grad);
opacity: 1;
}
.ssi-rule-c {
margin-left: auto;
margin-right: auto;
}
.ssi-wash {
background: var(--ssi-wash);
}
/* an arrow that nudges on hover, only ever inside a link */
.ssi-go {
display: inline-flex;
align-items: center;
font-weight: 700;
font-size: 14px;
letter-spacing: .05em;
text-transform: uppercase;
color: var(--ssi-red);
}
.ssi-go i,
.ssi-go .fas {
margin-left: .55rem;
transition: transform .22s ease;
}
a:hover .ssi-go i,
a:hover .ssi-go .fas,
a.ssi-go:hover i,
a.ssi-go:hover .fas {
transform: translateX(5px);
}
a.ssi-go:hover {
color: var(--ssi-maroon);
text-decoration: none;
}
/* ============================================================
1. HERO
============================================================ */
.ssi-hero {
position: relative;
overflow: hidden;
background: linear-gradient(180deg, #fff 0%, #fff 40%, var(--ssi-wash) 100%);
/* contains the DNA accent's blend to this section's own background
instead of letting it reach through to whatever is behind */
isolation: isolate;
}
/* The DNA helix is the only hero accent, and it runs twice: once
bleeding off the top left corner, once larger off the bottom right,
so the pair frames the hero on a diagonal. The gradient sail arcs
that used to sit top right are gone for good.
welcome-dna.jpg is a white helix on a white plate with no alpha, so
dropping it in as-is would paint an opaque white rectangle over the
hero gradient. mix-blend-mode: multiply fixes that for free: white
multiplies to no change and disappears, and only the soft grey
modelling of the helix survives. Opacity then takes it down to a
whisper, which matters here because the headline sits over it.
aspect-ratio is fine on a div; Omnia's height: auto override only
targets img. */
.ssi-hero-dna {
position: absolute;
aspect-ratio: 660 / 476;
background-image: url(/userfiles/2737/images/welcome-dna.jpg);
background-repeat: no-repeat;
background-size: contain;
mix-blend-mode: multiply;
pointer-events: none;
z-index: 0;
}
/* the smaller of the two. Same opacity as the other one now, so the
pair reads as one accent seen twice rather than a strong one and a
weak one. */
.ssi-hero-dna-tl {
top: -8%;
left: -5%;
width: 38%;
max-width: 500px;
background-position: left top;
opacity: .3;
}
.ssi-hero-dna-br {
bottom: -6%;
right: -5%;
width: 52%;
max-width: 680px;
background-position: right bottom;
opacity: .3;
}
.ssi-hero .container {
position: relative;
z-index: 2;
}
.ssi-hero-copy {
max-width: 640px;
}
.ssi-hero h1 {
margin: 0 0 1.15rem;
font-weight: 200;
line-height: 1.02;
letter-spacing: -.028em;
}
.ssi-hero .ssi-lead {
max-width: 54ch;
}
.ssi-hero-cta {
margin-bottom: .5rem;
}
/* search bar. Not used on the homepage any more (the header owns
the product search) but kept for any page that wants an inline
search block in the body. */
.ssi-search {
display: flex;
align-items: stretch;
background: #fff;
border: 1px solid var(--ssi-line);
border-radius: var(--ssi-r);
box-shadow: var(--ssi-shadow);
overflow: hidden;
max-width: 560px;
transition: border-color .2s ease, box-shadow .2s ease;
}
.ssi-search:focus-within {
border-color: var(--ssi-red);
box-shadow: 0 0 0 4px rgba(174, 30, 44, .09), var(--ssi-shadow);
}
.ssi-search-ico {
display: flex;
align-items: center;
padding: 0 .35rem 0 1.05rem;
color: var(--ssi-muted);
font-size: 15px;
}
.ssi-search input {
flex: 1 1 auto;
min-width: 0;
border: 0;
outline: 0;
background: transparent;
font-family: var(--ssi-font);
font-size: 15px;
color: var(--ssi-ink);
padding: 1rem .75rem;
}
.ssi-search input::placeholder {
color: #9aa4ab;
}
.ssi-search .btn {
border-radius: 0;
flex: 0 0 auto;
padding-left: 1.5rem;
padding-right: 1.5rem;
}
.ssi-chips {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: .5rem;
margin: 1rem 0 0;
font-size: 13px;
}
.ssi-chips-label {
color: var(--ssi-muted);
font-weight: 700;
letter-spacing: .11em;
text-transform: uppercase;
font-size: 11px;
margin-right: .1rem;
}
.ssi-chip {
display: inline-block;
padding: .34rem .82rem;
border: 1px solid var(--ssi-line);
border-radius: 100px;
background: #fff;
color: var(--ssi-body);
font-weight: 600;
font-size: 13px;
line-height: 1.4;
transition: border-color .18s ease, color .18s ease, background-color .18s ease;
}
.ssi-chip:hover {
border-color: var(--ssi-red);
color: var(--ssi-red);
background: #fff;
text-decoration: none;
}
/* rotating product stage. Holds the Best Sellers off the old site. */
.ssi-stage {
position: relative;
max-width: 470px;
margin: 0 auto;
/* room for the badge to straddle the top edge of the circle */
padding-top: 21px;
}
/* the Best Sellers banner. Sits half above the circle and half over
it, so it reads as a label ON the stage rather than a heading
floating above an unrelated graphic. */
.ssi-stage-badge {
position: absolute;
top: 15px;
left: 50%;
transform: translateX(-50%);
z-index: 3;
display: inline-flex;
align-items: center;
gap: .55rem;
white-space: nowrap;
background: linear-gradient(100deg, var(--ssi-maroon) 0%, var(--ssi-red) 55%, var(--ssi-bright) 100%);
color: #fff;
font-size: 11.5px;
font-weight: 900;
letter-spacing: .19em;
text-transform: uppercase;
padding: .62rem 1.5rem;
border-radius: 100px;
box-shadow: 0 10px 24px rgba(94, 22, 33, .26);
}
.ssi-stage-badge .fas {
font-size: 12px;
color: rgba(255, 255, 255, .82);
}
@media (max-width: 575px) {
.ssi-stage-badge {
font-size: 10.5px;
letter-spacing: .16em;
padding: .55rem 1.15rem;
}
}
.ssi-stage-frame {
position: relative;
width: 100%;
aspect-ratio: 1 / 1;
border-radius: 50%;
background: radial-gradient(circle at 50% 44%, #fff 0%, #fff 52%, #eef0f3 74%, rgba(238, 240, 243, 0) 75%);
}
.ssi-stage-frame::before {
content: "";
position: absolute;
inset: 4%;
border-radius: 50%;
border: 1px solid rgba(174, 30, 44, .16);
}
.ssi-stage-frame::after {
content: "";
position: absolute;
inset: 14%;
border-radius: 50%;
border: 1px dashed rgba(151, 160, 165, .38);
}
.ssi-stage-slide {
position: absolute;
inset: 9%;
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
transform: scale(.965);
transition: opacity .7s ease, transform .7s ease;
}
.ssi-stage-slide.is-on {
opacity: 1;
transform: scale(1);
}
.ssi-stage-slide img {
max-width: 100%;
max-height: 100%;
width: auto;
object-fit: contain;
filter: drop-shadow(0 24px 34px rgba(20, 23, 26, .16));
}
.ssi-stage-caps {
position: relative;
margin-top: .75rem;
text-align: center;
min-height: 58px;
}
.ssi-stage-cap {
position: absolute;
left: 0;
right: 0;
top: 0;
opacity: 0;
transition: opacity .5s ease;
}
.ssi-stage-cap.is-on {
opacity: 1;
}
/* ---- BEST SELLERS ARE LINKS ----
Both the render and the caption under it go to that SKU's product
page. Two links to the same place on purpose: the photo is the
thing people aim at, the caption is the thing that reads as a link.
POINTER-EVENTS IS THE WHOLE TRICK HERE. All four slides and all
four captions are stacked on top of each other, three of them
invisible at opacity 0. Invisible is not intangible, so without
this the top of the pile swallows every click and you always land
on the last product in the markup, whatever is on screen. */
.ssi-stage-slide,
.ssi-stage-cap {
pointer-events: none;
}
.ssi-stage-slide.is-on,
.ssi-stage-cap.is-on {
pointer-events: auto;
}
/* AND THE DECORATION ON TOP OF THEM MUST NOT TAKE CLICKS EITHER.
The two rings are pseudo elements of the frame, so the dashed one
is the frame's last child and paints over every slide. Its box
covers everything from 14% in, while the slide sits at 9%, which
left only that thin outer band of the render catching a click.
None of these three is interactive. */
.ssi-stage-frame::before,
.ssi-stage-frame::after,
.ssi-stage-badge {
pointer-events: none;
}
/* The anchor fills the slide rather than shrink-wrapping the render,
so the img's max-height still has a definite height to resolve
against and nothing about the existing sizing changes. */
.ssi-stage-slide > a {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
/* No zoom on the render, per the house rule. The global
a:hover img rule already fades it, which is enough. The caption
warms to brand red, the same signal the category circles use. */
.ssi-stage-cap:hover {
text-decoration: none;
}
.ssi-stage-cap:hover .ssi-stage-name {
color: var(--ssi-red);
}
.ssi-stage-cap .ssi-stage-brand {
display: block;
font-weight: 900;
text-transform: uppercase;
letter-spacing: .17em;
font-size: 11.5px;
color: var(--ssi-red);
}
.ssi-stage-cap .ssi-stage-name {
display: block;
font-size: 16px;
color: var(--ssi-ink);
font-weight: 500;
}
.ssi-stage-dots {
display: flex;
justify-content: center;
gap: .55rem;
margin-top: .35rem;
}
.ssi-stage-dots button {
width: 26px;
height: 4px;
padding: 0;
border: 0;
border-radius: 100px;
background: #cfd5d9;
cursor: pointer;
transition: background-color .25s ease;
}
.ssi-stage-dots button.is-on {
background: var(--ssi-red);
}
.ssi-stage-dots button:hover {
background: var(--ssi-bright);
}
@media (max-width: 991px) {
/* Stacked columns, so both helixes go bigger and reposition, but
they do NOT get any fainter. Opacity is set once and holds from
320px to 4K, so the accent has the same weight everywhere. */
.ssi-hero-dna-tl {
top: -3%;
left: -18%;
width: 72%;
max-width: none;
}
.ssi-hero-dna-br {
bottom: -4%;
right: -14%;
width: 92%;
max-width: none;
}
.ssi-stage {
max-width: 400px;
}
}
/* ============================================================
2. CREDENTIAL BAR
============================================================ */
.ssi-creds {
background: var(--ssi-wash);
border-top: 1px solid var(--ssi-line);
border-bottom: 1px solid var(--ssi-line);
}
.ssi-cred {
display: flex;
align-items: flex-start;
gap: .8rem;
padding: .4rem 0;
}
.ssi-cred i {
color: var(--ssi-red);
font-size: 21px;
line-height: 1.35;
flex: 0 0 auto;
}
.ssi-cred-t {
display: block;
font-weight: 800;
color: var(--ssi-ink);
font-size: 15px;
line-height: 1.3;
}
.ssi-cred-s {
display: block;
font-size: 12.5px;
color: var(--ssi-muted);
line-height: 1.45;
}
/* The one photograph on the page with people in it, in the header of
the category section. Same construction as .ssi-oem-img: width plus
height auto plus aspect-ratio, which survives Omnia's base
img { height: auto !important } because auto is exactly what
aspect-ratio needs in order to compute the height itself. A fixed
pixel height here would be thrown away.
5/2 rather than 16/10: a hard letterbox crops out the ceiling racks
and the floor and leaves only the three figures and the bench, and it
keeps the photo from out-weighing the heading it sits beside. */
.ssi-labshot {
width: 100%;
height: auto;
aspect-ratio: 5 / 2;
object-fit: cover;
border-radius: var(--ssi-r);
box-shadow: var(--ssi-shadow);
}
/* ============================================================
3. CATEGORY CIRCLES
Six across on desktop, three on tablet, two on a phone. The card
version of this section is gone; these replaced it.
The character is all in the ring. At rest it is a soft brand
wash behind a hairline, so the circle reads as a quiet framed
portrait. On hover the wash becomes the full brand gradient, the
hairline gets out of the way and the whole thing picks up a
maroon shadow. The photo itself never moves and never zooms.
============================================================ */
.ssi-circ {
display: block;
text-align: center;
}
.ssi-circ:hover {
text-decoration: none;
}
.ssi-circ-ring {
display: block;
position: relative;
width: 100%;
max-width: 172px;
margin: 0 auto 1rem;
padding: 7px;
border-radius: 50%;
background: var(--ssi-grad-soft);
transition: background .3s ease, box-shadow .3s ease;
}
/* the hairline. Without it the soft wash just fades into the page
and the circle loses its edge. */
.ssi-circ-ring::before {
content: "";
position: absolute;
inset: 0;
border-radius: 50%;
border: 1px solid var(--ssi-line);
transition: border-color .3s ease;
}
.ssi-circ-img {
display: block;
position: relative;
width: 100%;
padding-bottom: 100%;
border-radius: 50%;
background-color: #fff;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
box-shadow: inset 0 0 0 1px rgba(20, 23, 26, .06);
}
.ssi-circ:hover .ssi-circ-ring {
background: var(--ssi-grad);
box-shadow: 0 14px 30px rgba(94, 22, 33, .2);
}
.ssi-circ:hover .ssi-circ-ring::before {
border-color: transparent;
}
.ssi-circ-brand {
display: block;
font-size: 10px;
font-weight: 900;
letter-spacing: .17em;
text-transform: uppercase;
color: var(--ssi-gray);
margin-bottom: .22rem;
transition: color .22s ease;
}
.ssi-circ:hover .ssi-circ-brand {
color: var(--ssi-muted);
}
.ssi-circ-name {
display: block;
/* two lines' worth, so "High Throughput" wrapping does not knock
the other five labels out of alignment */
min-height: 2.6em;
font-size: clamp(15px, 1.6vw, 17px);
font-weight: 700;
color: var(--ssi-ink);
line-height: 1.3;
letter-spacing: -.005em;
transition: color .22s ease;
}
.ssi-circ:hover .ssi-circ-name {
color: var(--ssi-red);
}
/* ============================================================
4 + 9. SWIPE RAILS (shared engine)
Native overflow scrolling, snap points, plus pointer drag for
mouse users. Works with zero JS if the script never runs.
============================================================ */
.ssi-rail-wrap {
position: relative;
}
.ssi-rail {
display: flex;
gap: 1rem;
overflow-x: auto;
overflow-y: hidden;
scroll-snap-type: x mandatory;
-webkit-overflow-scrolling: touch;
scrollbar-width: none;
-ms-overflow-style: none;
padding: .35rem .25rem 1.35rem;
margin: 0 -.25rem;
cursor: grab;
}
.ssi-rail::-webkit-scrollbar {
display: none;
}
.ssi-rail.is-dragging {
cursor: grabbing;
scroll-snap-type: none;
scroll-behavior: auto;
}
.ssi-rail.is-dragging a {
pointer-events: none;
}
.ssi-rail > * {
scroll-snap-align: start;
flex: 0 0 auto;
}
/* arrows live in the section header, never on top of a card */
.ssi-rail-nav {
display: none;
width: 46px;
height: 46px;
border-radius: 50%;
border: 1px solid var(--ssi-line);
background: #fff;
color: var(--ssi-ink);
align-items: center;
justify-content: center;
padding: 0;
margin-left: .5rem;
cursor: pointer;
transition: color .2s ease, border-color .2s ease, opacity .2s ease;
}
.ssi-rail-nav:hover {
color: var(--ssi-red);
border-color: rgba(174, 30, 44, .45);
}
.ssi-rail-nav:focus {
outline: 0;
border-color: var(--ssi-red);
box-shadow: 0 0 0 3px rgba(174, 30, 44, .18);
}
.ssi-rail-nav[disabled] {
opacity: .28;
cursor: default;
color: var(--ssi-ink);
border-color: var(--ssi-line);
}
@media (min-width: 992px) {
.ssi-rail-nav {
display: inline-flex;
}
}
.ssi-rail-hint {
display: inline-flex;
align-items: center;
gap: .5rem;
font-size: 11.5px;
font-weight: 800;
letter-spacing: .13em;
text-transform: uppercase;
color: var(--ssi-muted);
}
.ssi-rail-hint .fas {
color: var(--ssi-red);
font-size: 13px;
}
@media (min-width: 992px) {
.ssi-rail-hint {
display: none;
}
}
/* Edge fade so a cut-off card reads as "there is more over there".
It has to overshoot this wrapper. The rail inside is pulled .25rem
wider than the wrapper on each side, and in an overflow-x container
the content scrolls THROUGH the padding, so cards stay visible for
4px past the wrapper's right edge. A fade that stopped at the
wrapper (right: -1px) left a hard 3px sliver of white card showing
just past where the fade finished. Now it runs out to the container
gutter, and the gutter is the same wash colour so the overshoot is
invisible. The solid end also starts earlier, so there is real
coverage rather than 7px of it. */
.ssi-rail-wrap::after {
content: "";
position: absolute;
top: 0;
right: -15px;
bottom: 18px;
width: 78px;
pointer-events: none;
z-index: 2;
background: linear-gradient(90deg, rgba(245, 246, 248, 0) 0%, var(--ssi-wash) 70%);
transition: opacity .25s ease;
}
.ssi-rail-wrap.is-end::after {
opacity: 0;
}
/* An auto-scrolling rail also bleeds off the LEFT, since it is never
parked at scroll position zero. Mirror of the fade above. */
.ssi-rail-wrap.is-marquee::before {
content: "";
position: absolute;
top: 0;
left: -15px;
bottom: 18px;
width: 78px;
pointer-events: none;
z-index: 2;
background: linear-gradient(270deg, rgba(245, 246, 248, 0) 0%, var(--ssi-wash) 70%);
}
.ssi-rail-wrap.is-marquee::after {
opacity: 1;
}
/* Snap has to come off for the marquee. Mandatory snap fights a
frame-by-frame scrollLeft animation and turns the drift into a
stutter. The class is added by JS, so with the script blocked the
rail keeps its snap points and behaves like any other rail. */
.ssi-rail.is-marquee {
scroll-snap-type: none;
}
/* ---- 4. BRAND FAMILY CARDS ---- */
.ssi-brand {
width: 232px;
display: flex;
flex-direction: column;
background: #fff;
border: 1px solid var(--ssi-line);
border-radius: var(--ssi-r);
padding: 1.5rem 1.35rem 1.35rem;
transition: border-color .22s ease, box-shadow .22s ease;
}
.ssi-brand:hover {
text-decoration: none;
border-color: rgba(174, 30, 44, .45);
box-shadow: var(--ssi-shadow);
}
/* Background image on a fixed 2.5:1 box, not an .
The eight sub-brand marks run from 2.06:1 (UltraFlux) all the way
to 3.93:1 (IsoFreeze). Sized by width in a min-height box, the two
tall ones overflowed and set the height for the whole rail while
the wide ones floated in dead space. A fixed box fixes that: every
card reserves the same slot.
cover is deliberate, do not "fix" it to contain. cover fills the box
by height, which does trim the sides off the widest marks, and that
is the look Jared wants on both the homepage rail and the About page
grid. contain was tried and rejected.
padding-bottom rather than aspect-ratio because Omnia's base CSS
forces height: auto on anything image-shaped. */
.ssi-brand-logo {
display: block;
width: 100%;
padding-bottom: 40%;
margin-bottom: 1.1rem;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}
.ssi-brand-desc {
display: block;
font-size: 14px;
line-height: 1.5;
color: var(--ssi-body);
text-align: center;
margin-bottom: .9rem;
}
.ssi-brand-go {
display: block;
text-align: center;
font-size: 11px;
font-weight: 800;
letter-spacing: .15em;
text-transform: uppercase;
color: var(--ssi-red);
margin-top: auto;
}
/* Section 5 was three big alternating spotlights for Vertex,
UltraFlux and SureSeal (.ssi-spot, .ssi-feats). Removed with the
sections. */
/* ============================================================
6. MADE IN USA
============================================================ */
.ssi-usa {
position: relative;
background-color: #2a0b12;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
color: rgba(255, 255, 255, .82);
}
.ssi-usa-veil {
position: absolute;
inset: 0;
background: linear-gradient(104deg, rgba(30, 6, 11, .96) 0%, rgba(94, 22, 33, .93) 46%, rgba(174, 30, 44, .78) 100%);
}
.ssi-usa .container {
position: relative;
z-index: 2;
}
.ssi-usa h2,
.ssi-usa h3 {
color: #fff;
}
.ssi-usa .ssi-lead {
color: rgba(255, 255, 255, .84);
}
.ssi-usa-flag {
width: 46px;
height: auto;
}
.ssi-stat {
border-top: 2px solid rgba(255, 255, 255, .28);
padding-top: 1.1rem;
height: 100%;
}
.ssi-stat-n {
display: block;
font-size: clamp(28px, 3.6vw, 40px);
font-weight: 200;
color: #fff;
line-height: 1.05;
letter-spacing: -.02em;
margin-bottom: .4rem;
}
.ssi-stat-n small {
font-size: .48em;
font-weight: 600;
letter-spacing: .02em;
}
.ssi-stat-l {
display: block;
font-size: 13.5px;
line-height: 1.5;
color: rgba(255, 255, 255, .74);
}
.ssi-usa .btn-light {
color: var(--ssi-maroon);
}
/* ============================================================
7. CUSTOM AND OEM
============================================================ */
.ssi-oem-img {
width: 100%;
height: auto;
aspect-ratio: 1 / 1;
object-fit: cover;
border-radius: var(--ssi-r);
box-shadow: var(--ssi-shadow);
}
.ssi-oem-stack {
position: relative;
}
.ssi-oem-badge {
position: absolute;
right: 6%;
bottom: -26px;
background: #fff;
border: 1px solid var(--ssi-line);
border-radius: var(--ssi-r);
box-shadow: var(--ssi-shadow-lg);
padding: 1rem 1.3rem;
max-width: 230px;
}
.ssi-oem-badge .ssi-stat-n {
color: var(--ssi-ink);
}
.ssi-oem-badge .ssi-stat-l {
color: var(--ssi-muted);
}
.ssi-caps {
display: flex;
flex-wrap: wrap;
gap: .55rem;
margin: 1.4rem 0 1.8rem;
}
.ssi-cap {
display: inline-flex;
align-items: center;
gap: .5rem;
padding: .5rem 1rem;
background: #fff;
border: 1px solid var(--ssi-line);
border-radius: 100px;
font-size: 13.5px;
font-weight: 600;
color: var(--ssi-body);
}
.ssi-cap i {
color: var(--ssi-red);
font-size: 13px;
}
/* ============================================================
8. RESOURCES
============================================================ */
.ssi-res {
display: block;
height: 100%;
position: relative;
overflow: hidden;
border: 1px solid var(--ssi-line);
border-radius: var(--ssi-r);
background: #fff;
padding: 1.7rem 1.6rem 1.6rem;
transition: border-color .22s ease, box-shadow .22s ease;
}
/* BLOOM, and it has a source.
This started as a decorative blob in the empty bottom right corner,
which is the problem with it: nothing on the card explains why the
colour is there. So it moved. The icon is the strongest thing on the
card and it is already a disc of the brand gradient, so the bloom is
now centred exactly behind it and the card reads as being lit BY the
icon rather than as having a shape parked in one corner.
520px across on a card about 300px wide, so what lands on the card
is the wide soft part of the falloff and never an edge. The
centring is not a guess: the icon is 46px inside 1.6rem / 1.7rem of
padding, so its middle sits at roughly 50px, 50px, and the offsets
are that minus half the bloom.
Light red over white lands as a pale blush, warm enough to belong to
the brand and faint enough that the heading still sits on it
comfortably. */
.ssi-res::after {
content: "";
position: absolute;
top: -210px;
left: -210px;
width: 520px;
height: 520px;
opacity: .85;
background: radial-gradient(circle at center,
rgba(217, 35, 42, .15) 0%,
rgba(217, 35, 42, .085) 22%,
rgba(211, 38, 52, .038) 44%,
rgba(205, 40, 58, .012) 62%,
rgba(205, 40, 58, 0) 78%);
transition: opacity .3s ease;
}
/* the light comes up with the card. These are links, so the whole
panel is a legitimate hover target. */
.ssi-res:hover::after {
opacity: 1;
}
.ssi-res:hover {
text-decoration: none;
border-color: rgba(174, 30, 44, .45);
box-shadow: var(--ssi-shadow);
}
.ssi-res > * {
position: relative;
z-index: 2;
}
.ssi-res-ico {
display: flex;
align-items: center;
justify-content: center;
width: 46px;
height: 46px;
border-radius: 50%;
background: var(--ssi-grad);
color: #fff;
font-size: 17px;
margin-bottom: 1.1rem;
}
.ssi-res-t {
display: block;
font-size: 19px;
font-weight: 500;
color: var(--ssi-ink);
line-height: 1.25;
margin-bottom: .5rem;
transition: color .22s ease;
}
.ssi-res:hover .ssi-res-t {
color: var(--ssi-red);
}
.ssi-res-d {
display: block;
font-size: 14px;
line-height: 1.55;
color: var(--ssi-body);
margin-bottom: 1rem;
}
.ssi-res-go {
display: inline-flex;
align-items: center;
font-size: 11px;
font-weight: 800;
letter-spacing: .15em;
text-transform: uppercase;
color: var(--ssi-red);
}
.ssi-res-go .fas {
margin-left: .55rem;
font-size: 10px;
transition: transform .22s ease;
}
.ssi-res:hover .ssi-res-go .fas {
transform: translateX(5px);
}
/* Section 9 was the testimonials rail (.ssi-quote). Removed with
the section. */
/* ============================================================
10. DISTRIBUTION SPLIT
Both cards get the same brand gradient now. The only thing
telling them apart is the watermark: an oversized Font Awesome
glyph bled off the bottom right corner and clipped by the card's
own overflow, at an opacity where it reads as texture rather
than as a second icon competing with the heading.
============================================================ */
.ssi-split {
position: relative;
overflow: hidden;
border-radius: var(--ssi-r);
height: 100%;
padding: 2.8rem 2.2rem;
background: linear-gradient(120deg, #260810 0%, var(--ssi-maroon) 42%, var(--ssi-red) 100%);
color: rgba(255, 255, 255, .84);
transition: box-shadow .3s ease;
}
/* HOVER. The card holds its position: it is not itself a link, the
button inside it is, so moving the whole panel would be moving
something that is not the target. What changes instead is the light.
A gradient cannot be transitioned, so the brighter version is a
second full-bleed layer underneath the content that fades up, and
the panel picks up a deep maroon shadow at the same time. */
.ssi-split::before {
content: "";
position: absolute;
inset: 0;
z-index: 0;
background: linear-gradient(120deg, #3a0f18 0%, #7a1c2b 42%, var(--ssi-bright) 100%);
opacity: 0;
transition: opacity .3s ease;
pointer-events: none;
}
.ssi-split:hover::before {
opacity: 1;
}
.ssi-split:hover {
box-shadow: 0 18px 44px rgba(94, 22, 33, .34);
}
/* the watermark comes up with it, so the texture reads a little
stronger on the lit card */
.ssi-split-mark {
transition: opacity .3s ease;
}
.ssi-split:hover .ssi-split-mark {
opacity: .13;
}
.ssi-split h3 {
color: #fff;
}
.ssi-split-mark {
position: absolute;
right: -1.4rem;
bottom: -2.6rem;
z-index: 1;
font-size: clamp(150px, 22vw, 215px);
line-height: 1;
color: #fff;
opacity: .08;
pointer-events: none;
}
.ssi-split > *:not(.ssi-split-mark) {
position: relative;
z-index: 2;
}
/* Section 11 was the news teaser row (.ssi-post). Removed with the
section. */
/* Section 12 was the closing "Talk to a person" CTA (.ssi-close,
.ssi-touch). The section came off the homepage, so its CSS went
with it. */
/* ============================================================
INTERIOR PAGES
Everything below here is shared by the subpages, not by the
homepage. First used on About.
============================================================ */
/* ---- PAGE HERO ----
The standard band at the top of every interior page: a photograph,
a brand veil, an eyebrow, one heading and one line of subheading.
ONE PHOTOGRAPH, SITE WIDE. It lives here rather than inline on each
page, so changing it later is one edit instead of one per subpage,
and a new subpage needs nothing but the class. A page that ever
does want its own can still set background-image inline and win.
PLACEHOLDER: hotlinked off the Unsplash CDN, so no upload and a
third party dependency. Swap this one URL for real SSI facility
photography at /userfiles/2737/images/ before launch and every
interior page changes at once.
Deliberately NOT reusing .ssi-usa-veil. That one sits at .96
because it carries a paragraph and four stats and the photo under
it is only texture. This band is shallow and holds three lines, so
the veil is heaviest on the left where the type is and thins out
to the right, which leaves the laboratory visible instead of
painting over it. */
.ssi-phero {
position: relative;
overflow: hidden;
background-color: #2a0b12;
background-image: url(https://images.unsplash.com/photo-1579154204601-01588f351e67?w=2400&h=900&fit=crop&q=80);
background-size: cover;
background-position: center;
background-repeat: no-repeat;
color: rgba(255, 255, 255, .82);
}
.ssi-phero-veil {
position: absolute;
inset: 0;
background: linear-gradient(96deg, rgba(16, 4, 7, .95) 0%, rgba(48, 11, 18, .9) 34%, rgba(94, 22, 33, .72) 66%, rgba(140, 26, 38, .55) 100%);
}
/* Echo of the 2px brand rule along the bottom of the header, so the
hero closes the same way the header does. */
.ssi-phero::after {
content: "";
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 3px;
background: var(--ssi-grad);
z-index: 3;
}
.ssi-phero .container {
position: relative;
z-index: 2;
}
.ssi-phero h1,
.ssi-phero h2 {
color: #fff;
}
.ssi-phero-sub {
font-size: clamp(16px, 2.1vw, 19px);
line-height: 1.6;
color: rgba(255, 255, 255, .82);
max-width: 58ch;
}
/* ---- FILM BAND ----
The dark field the corporate video sits on. Same maroon family as
the page hero, without the photograph under it, so the two read as
related without competing.
The video itself carries preload="none" and a poster in the markup,
which is what keeps a 22.5 MB file off the page load. aspect-ratio
is safe here: Omnia's height: auto !important is scoped to img and
never touches a video element. */
.ssi-film {
background: linear-gradient(104deg, #1a0509 0%, #4a1119 52%, #6d1926 100%);
color: rgba(255, 255, 255, .78);
}
.ssi-film h2 {
color: #fff;
}
/* auto margins so the 62ch cap still sits centred inside a
text-center column, instead of hugging the left of it */
.ssi-film-lead {
font-size: clamp(16px, 2.1vw, 19px);
line-height: 1.6;
color: rgba(255, 255, 255, .8);
max-width: 62ch;
margin-left: auto;
margin-right: auto;
}
.ssi-film-v {
display: block;
width: 100%;
max-width: 100%;
height: auto;
aspect-ratio: 16 / 9;
background: #000;
border-radius: var(--ssi-r);
box-shadow: var(--ssi-shadow-lg);
}
/* ---- AT A GLANCE CARD ----
Key and value on one line, wrapping to two lines under 400px,
where a right aligned value on its own row would read as a
mistake. */
.ssi-facts {
background: #fff;
border: 1px solid var(--ssi-line);
border-radius: var(--ssi-r);
box-shadow: var(--ssi-shadow);
padding: 1.6rem 1.7rem 1.2rem;
}
.ssi-facts-h {
font-size: 11.5px;
font-weight: 900;
letter-spacing: .19em;
text-transform: uppercase;
color: var(--ssi-muted);
margin: 0 0 1.1rem;
}
.ssi-facts-row {
display: flex;
flex-wrap: wrap;
align-items: baseline;
gap: .1rem 1rem;
justify-content: space-between;
padding: .72rem 0;
border-top: 1px solid var(--ssi-line);
}
.ssi-facts-k {
flex: 0 0 auto;
font-size: 12.5px;
font-weight: 800;
letter-spacing: .07em;
text-transform: uppercase;
color: var(--ssi-muted);
}
.ssi-facts-v {
flex: 1 1 auto;
font-size: 15px;
font-weight: 600;
line-height: 1.4;
color: var(--ssi-ink);
text-align: right;
}
/* ---- TRUST MARKS ----
The client's own four symbols. Sized by width because Omnia's base
CSS forces img height to auto, and the four source PNGs are all
300 square canvases with the artwork floating inside at different
scales, so a shared box width is the only thing that lines them
up. */
.ssi-badge {
text-align: center;
}
.ssi-badge-img {
display: block;
width: 112px;
max-width: 100%;
height: auto;
margin: 0 auto .8rem;
}
.ssi-badge-t {
display: block;
font-size: 16px;
font-weight: 800;
color: var(--ssi-ink);
margin-bottom: .35rem;
}
.ssi-badge-d {
display: block;
max-width: 27ch;
margin: 0 auto;
font-size: 13.5px;
line-height: 1.5;
color: var(--ssi-body);
}
/* ---- PILLAR CARDS ----
Not links, so nothing here reacts to hover. */
.ssi-pillar {
background: #fff;
border: 1px solid var(--ssi-line);
border-radius: var(--ssi-r);
padding: 1.8rem 1.7rem;
font-size: 15px;
line-height: 1.62;
}
.ssi-pillar-ico {
display: inline-flex;
align-items: center;
justify-content: center;
width: 52px;
height: 52px;
border-radius: 50%;
background: var(--ssi-grad);
color: #fff;
font-size: 20px;
margin-bottom: 1.15rem;
}
.ssi-pillar-t {
font-size: clamp(21px, 2.4vw, 25px);
margin-bottom: .7rem;
}
/* ---- IMAGE PLATE ----
The four Ab_*.png composites off the old About page are white
plates with red hairline frames drawn into the artwork, built for
a white page. On any tinted section they show up as a white box,
so they get a real white card instead and the box becomes the
point. line-height 0 kills the inline descender gap under the
image. */
.ssi-plate {
background: #fff;
border: 1px solid var(--ssi-line);
border-radius: var(--ssi-r);
box-shadow: var(--ssi-shadow);
padding: 1.1rem;
line-height: 0;
}
.ssi-plate img {
display: block;
width: 100%;
max-width: 100%;
height: auto;
}
/* Rule between stacked image and copy rows. It sits on the .row, so
it runs the full content width through the gutter rather than
stopping at the first column. */
.ssi-proc + .ssi-proc {
margin-top: 2.6rem;
padding-top: 2.6rem;
border-top: 1px solid var(--ssi-line);
}
/* ---- TICK LIST ---- */
.ssi-ticks {
list-style: none;
padding: 0;
margin: 0 0 1.6rem;
}
.ssi-ticks li {
display: flex;
align-items: flex-start;
gap: .7rem;
padding: .42rem 0;
font-size: 15.5px;
line-height: 1.55;
}
.ssi-ticks li > .fas {
flex: 0 0 auto;
margin-top: .3em;
font-size: 13px;
color: var(--ssi-red);
}
/* ---- FORMS ----
FOR THE OMNIA FORM BUILDER. Verified against the real rendered
output of CUSTFORM_VH4L8BKJ on the live careers page, not guessed
at. What it emits, for anyone styling another form later:
div.fs2-wrap.fs2-labels-top outer wrapper
div.form-row.fs2-row one row of fields
div.col-12.col-md-6 the column, sized in the
form builder per field
div.formbuilder-text.form-group.field-FIRSTNAME
label.formbuilder-text-label
span.formbuilder-required the star
input.form-control
Field wrappers are .formbuilder-text / -select / -textarea / -file
/ -checkbox-group, each also carrying .form-group and a
.field-NAME built out of the question. Labels are real label
elements with a matching -label class. Checkbox groups nest
div.checkbox-group > div.formbuilder-checkbox > input + label.
NO fieldsets and NO legends, so .ssi-form-legend below only ever
applies to markup we write ourselves.
Scoped to .ssi-form throughout. Nothing here may leak out to the
navbar search or the footer, which is the same trap the global
.btn rule fell into during the header build. */
.ssi-form {
background: #fff;
border: 1px solid var(--ssi-line);
border-radius: var(--ssi-r);
box-shadow: var(--ssi-shadow);
padding: 1.9rem 1.8rem 1.7rem;
}
/* The form builder wraps its fields in a ul. Strip the list styling
without caring whether it is there. */
.ssi-form ul,
.ssi-form ol {
list-style: none;
padding-left: 0;
margin: 0;
}
.ssi-form label {
display: block;
font-size: 13.5px;
font-weight: 700;
line-height: 1.4;
color: var(--ssi-ink);
margin-bottom: .42rem;
}
.ssi-form .formbuilder-required {
color: var(--ssi-red);
font-weight: 700;
margin-left: .1rem;
}
.ssi-form .form-control {
height: auto;
padding: .72rem .9rem;
font-size: 15px;
font-family: var(--ssi-font);
color: var(--ssi-ink);
background-color: #fff;
border: 1px solid #d5dbe0;
border-radius: var(--ssi-r-sm);
box-shadow: none;
transition: border-color .18s ease, box-shadow .18s ease;
}
.ssi-form .form-control::placeholder {
color: #9aa4ab;
}
.ssi-form .form-control:focus {
border-color: var(--ssi-red);
box-shadow: 0 0 0 3px rgba(174, 30, 44, .15);
}
.ssi-form select.form-control {
cursor: pointer;
}
.ssi-form textarea.form-control {
min-height: 8rem;
line-height: 1.55;
}
/* The upload reads as a dropzone rather than as another text box.
Two class names deep because the form builder puts .form-control on
the file input as well, and a 0,1,1 selector would lose the border
to it. */
.ssi-form input[type="file"],
.ssi-form .form-control[type="file"] {
display: block;
width: 100%;
height: auto;
font-size: 14px;
padding: .7rem .9rem;
border: 1px dashed #c8d0d6;
border-radius: var(--ssi-r-sm);
background: var(--ssi-wash);
cursor: pointer;
}
.ssi-form .form-group {
margin-bottom: 1.15rem;
}
/* Side by side fields whose labels wrap to a different number of
lines would otherwise start their inputs at different heights.
Letting the label absorb the slack drops every control in the row
onto the same baseline, without anything having to know how long
any given label is.
Two shapes, because the form builder puts a column div between the
row and the field wrapper and hand written markup does not. */
.ssi-form .form-row > [class*="col-"] {
display: flex;
flex-direction: column;
}
.ssi-form .form-row > [class*="col-"] > .form-group,
.ssi-form .form-row > .form-group {
display: flex;
flex-direction: column;
flex: 1 1 auto;
}
.ssi-form .form-row > [class*="col-"] > .form-group > label,
.ssi-form .form-row > .form-group > label {
margin-bottom: auto;
padding-bottom: .42rem;
}
/* Group heading. .ssi-form-legend on a p in the mockup, and a real
legend element if the form builder emits fieldsets. */
.ssi-form-legend,
.ssi-form legend {
width: auto;
float: none;
font-size: 11.5px;
font-weight: 900;
letter-spacing: .19em;
text-transform: uppercase;
color: var(--ssi-red);
margin: 2rem 0 1.1rem;
padding-bottom: .7rem;
border-bottom: 1px solid var(--ssi-line);
}
.ssi-form-legend:first-child,
.ssi-form legend:first-child,
.ssi-form form > *:first-child.ssi-form-legend {
margin-top: 0;
}
/* Checkbox and radio rows. The label rule above turns every label
into a block, which is right for a field label and wrong for the
text beside a tick box, so it is undone here. */
.ssi-form .checkbox-group,
.ssi-form .radio-group {
margin-top: .1rem;
}
.ssi-form .formbuilder-checkbox,
.ssi-form .formbuilder-radio {
display: flex;
align-items: flex-start;
gap: .55rem;
margin-bottom: .45rem;
break-inside: avoid;
page-break-inside: avoid;
}
.ssi-form .formbuilder-checkbox input,
.ssi-form .formbuilder-radio input {
flex: 0 0 auto;
width: 16px;
height: 16px;
margin: .22em 0 0;
accent-color: var(--ssi-red);
cursor: pointer;
}
.ssi-form .formbuilder-checkbox label,
.ssi-form .formbuilder-radio label,
.ssi-form .form-check-label {
display: inline;
margin-bottom: 0;
font-size: 15px;
font-weight: 400;
color: var(--ssi-body);
cursor: pointer;
}
/* LONG TICK BOX LISTS GO INTO COLUMNS BY THEMSELVES.
Ten options in one column is a long scroll for no reason, and it
looks worse now the form runs full container width. Three or four
options, like a shift question, must NOT be split, or Day / Swing /
Graveyard end up spread across a row reading as three separate
things.
:has(> :nth-child(7)) is what tells those two cases apart: it only
matches a group that actually has a seventh item in it. That means
this works on any form on the site without knowing the field's name
or how many options it has, which matters because the form builder
gives no way to put a class on a field. Its only hook is
.field-NAME, generated from the question text, so anything keyed to
that breaks silently the moment somebody rewords the question.
CSS columns rather than a grid, because a column count works on
whatever container the form builder produces without knowing what
is inside it, and it balances the items across the columns.
IN ITS OWN BLOCK, NOT MERGED WITH .ssi-cols BELOW. One selector a
browser cannot parse invalidates the whole selector list, so an
old browser meeting :has() here would take .ssi-cols down with it.
Kept apart, an old browser simply gets one column and nothing else
is affected. */
@media (min-width: 576px) {
.ssi-form .checkbox-group:has(> :nth-child(7)),
.ssi-form .radio-group:has(> :nth-child(7)) {
column-count: 2;
column-gap: 1.6rem;
}
}
@media (min-width: 768px) {
.ssi-form .checkbox-group:has(> :nth-child(7)),
.ssi-form .radio-group:has(> :nth-child(7)) {
column-count: 3;
}
}
/* Same thing for markup we write by hand, where a class is possible. */
@media (min-width: 576px) {
.ssi-form .ssi-cols {
column-count: 2;
column-gap: 1.6rem;
}
}
@media (min-width: 768px) {
.ssi-form .ssi-cols {
column-count: 3;
}
}
/* Conditional block, the one the old form hides until you answer yes.
Marked rather than hidden so the mockup shows the whole form. */
.ssi-form-cond {
border-left: 3px solid var(--ssi-line);
padding: 1.1rem 0 .1rem 1.1rem;
margin: 0 0 1.15rem;
}
.ssi-form-condnote {
font-size: 12.5px;
font-style: italic;
color: var(--ssi-muted);
margin-bottom: .9rem;
}
.ssi-form-condnote .fas {
margin-right: .35rem;
}
/* ---- BRAND CARDS IN A GRID ----
Same card as the homepage rail, minus the fixed rail width. Two
class names deep on purpose: the plain .ssi-brand width is reset
again inside the small screen media queries further down, and a
0,2,0 selector wins there without having to duplicate this in
every one of them. */
.ssi-brand.ssi-brand-g {
width: auto;
height: 100%;
}
/* ---- PHOTO CARD ----
A photograph across the top of a card with copy underneath. Built
for Vision and Mission on Our Purpose, generic enough for any pair
or trio of statements that each deserve an image.
Not links, so nothing here reacts to hover and the photo never
zooms.
overflow hidden on the card plus a plain border-radius is what
rounds the top of the photo. The image needs no radius of its own,
which means the same card works whatever sits at the top of it. */
.ssi-pcard {
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
background: #fff;
border: 1px solid var(--ssi-line);
border-radius: var(--ssi-r);
box-shadow: var(--ssi-shadow);
}
/* width + height auto + aspect-ratio, the one crop that survives
Omnia's img { height: auto !important }, because auto is exactly
what aspect-ratio needs to compute the height itself. A fixed
pixel height here would be thrown away. */
.ssi-pcard-img {
display: block;
width: 100%;
height: auto;
aspect-ratio: 16 / 10;
object-fit: cover;
}
.ssi-pcard-body {
flex: 1 1 auto;
padding: 1.7rem 1.7rem 1.6rem;
font-size: 15px;
line-height: 1.62;
}
@media (max-width: 575px) {
.ssi-pcard-body {
padding: 1.4rem 1.3rem 1.35rem;
}
}
/* A letterbox variant of the same card image, for the four OEM
photographs on Custom Capabilities. They are 550x225, which is
exactly 22:9, so this ratio crops nothing off them and they all
land the same height whatever the card body does. Declared rather
than left to the file's own ratio so a future replacement photo
is forced into line instead of breaking the row. */
.ssi-pcard-img.ssi-pcard-wide {
aspect-ratio: 22 / 9;
}
/* ---- NUMBERED LIST INSIDE A CARD ----
The six core values, in the third .ssi-pcard on Our Purpose.
They are an ordered list on the client's page, so the numbering is
theirs and is kept.
THE NUMERAL IS A CSS COUNTER, not typed into the markup, so
reordering the list or adding a seventh value renumbers itself.
The browser's own list marker is turned off and the counter is
drawn in the ::before instead, which is what lets it be coloured
and positioned. */
.ssi-values {
list-style: none;
counter-reset: ssi-value;
padding-left: 0;
margin: 0;
}
.ssi-values li {
counter-increment: ssi-value;
position: relative;
padding-left: 1.9rem;
margin-bottom: .55rem;
line-height: 1.45;
}
.ssi-values li:last-child {
margin-bottom: 0;
}
.ssi-values li::before {
content: counter(ssi-value);
position: absolute;
left: 0;
top: 0;
width: 1.35rem;
text-align: right;
font-size: 15px;
font-weight: 800;
line-height: inherit;
color: var(--ssi-red);
}
/* ---- STATEMENT BAND ----
A dark brand field carrying nothing but words. Built for the
closing statement on Our Purpose and deliberately generic, so any
page that needs a full width pull quote can use it.
Same gradient family as .ssi-phero and .ssi-film so the three read
as one system, with no photograph and no icon competing with the
type. */
.ssi-band {
background: linear-gradient(104deg, #1a0509 0%, #4a1119 52%, #6d1926 100%);
color: rgba(255, 255, 255, .82);
}
/* A statement, not a heading, so it is a p. Sized between the lead
and an h2, in the same light weight the headings use, because at
this length a full heading weight would shout. */
.ssi-band-t {
font-size: clamp(18px, 2.6vw, 25px);
font-weight: 300;
line-height: 1.5;
letter-spacing: -.01em;
color: #fff;
max-width: 68ch;
margin-left: auto;
margin-right: auto;
}
/* The eyebrow is inline-flex so its leading rule sits on the same
line as the text. That makes it a flex container, so centring it
inside a text-center column needs justify-content, which the
Bootstrap utility in the markup supplies. This just stops the
block from hugging the left. */
.ssi-band .ssi-eyebrow {
display: flex;
margin-bottom: 1.1rem;
}
/* ---- LITERATURE CARDS ----
The download grid on Product Literature. Sixteen documents, so the
card is deliberately small and quiet: a cover, a title, a PDF tag.
Same hover language as .ssi-cert and .ssi-res, which is the border
warming and a shadow lifting. The cover never zooms.
A tighter version of .ssi-cert rather than a reuse of it, because
that one is built for three items with descriptions and this one
is a dense index. */
.ssi-lit {
display: flex;
flex-direction: column;
height: 100%;
background: #fff;
border: 1px solid var(--ssi-line);
border-radius: var(--ssi-r);
padding: .9rem .9rem .8rem;
text-align: center;
transition: border-color .22s ease, box-shadow .22s ease;
}
.ssi-lit:hover,
.ssi-lit:focus {
text-decoration: none;
border-color: rgba(174, 30, 44, .45);
box-shadow: var(--ssi-shadow);
}
/* MIXED SHAPES IN ONE ROW. The brochure and flyer covers are all
portrait at about 0.78, the three compatibility charts are
landscape at about 1.29. A fixed ratio box with the cover scaled
to fit INSIDE it means a chart and a brochure sitting side by side
still put their titles on the same line, and nothing is stretched.
Ratio on the span, not the img, because Omnia forces
height: auto !important on images; max-height still applies and
resolves against the definite height the ratio gives the parent. */
.ssi-lit-shot {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
aspect-ratio: 3 / 4;
margin-bottom: .75rem;
}
.ssi-lit-shot img {
width: auto;
max-width: 100%;
max-height: 100%;
}
.ssi-lit-t {
display: block;
font-size: 13.5px;
font-weight: 700;
line-height: 1.35;
color: var(--ssi-ink);
margin-bottom: .6rem;
transition: color .22s ease;
}
.ssi-lit:hover .ssi-lit-t {
color: var(--ssi-red);
}
/* margin-top auto pins the tag to the bottom, so a one line title and
a three line title still line their tags up across the row. */
.ssi-lit-go {
display: block;
margin-top: auto;
font-size: 10.5px;
font-weight: 800;
letter-spacing: .15em;
text-transform: uppercase;
color: var(--ssi-red);
}
/* Group heading. Small and ruled rather than a 40px h2, because
there are three of them on one page and they are labels on a grid,
not section titles. */
.ssi-lit-cat {
font-size: 12px;
font-weight: 900;
letter-spacing: .19em;
text-transform: uppercase;
color: var(--ssi-muted);
padding-bottom: .7rem;
margin: 0 0 1.2rem;
border-bottom: 1px solid var(--ssi-line);
}
.row + .ssi-lit-cat {
margin-top: 1.4rem;
}
/* The catalog cover in its own feature row. A link wrapping a single
image, so no span gymnastics needed. */
.ssi-lit-feat-img {
display: block;
transition: opacity .22s ease;
}
.ssi-lit-feat-img img {
display: block;
width: 100%;
max-width: 100%;
height: auto;
filter: drop-shadow(0 10px 22px rgba(20, 23, 26, .16));
}
/* ---- CERTIFICATE CARDS ----
A scan of a certificate on a white card, linking to the PDF. Used
on Quality, and built to take any certificate SSI add later.
The whole card is the link, so hover is legitimate here. Same
language as .ssi-res and .ssi-brand: the border warms and a shadow
comes up. Nothing moves and the scan never zooms. */
.ssi-cert {
display: flex;
flex-direction: column;
height: 100%;
background: #fff;
border: 1px solid var(--ssi-line);
border-radius: var(--ssi-r);
padding: 1.4rem 1.3rem 1.25rem;
text-align: center;
transition: border-color .22s ease, box-shadow .22s ease;
}
.ssi-cert:hover,
.ssi-cert:focus {
text-decoration: none;
border-color: rgba(174, 30, 44, .45);
box-shadow: var(--ssi-shadow);
}
/* THE SCANS ARE NOT ALL THE SAME SHAPE. 320x443 for the two ISO
certificates and 320x406 for the 11137 declaration. Stretching
them to a shared box would distort a legal document, so the box is
a fixed ratio and the scan is scaled to fit INSIDE it, bottom
aligned so the three sit on one line.
aspect-ratio on the span, not the img: Omnia's base CSS forces
height: auto !important on images. max-height still applies to the
img, and resolves against the definite height the ratio gives the
parent. */
.ssi-cert-shot {
display: flex;
align-items: flex-end;
justify-content: center;
width: 100%;
aspect-ratio: 4 / 5;
margin-bottom: 1.1rem;
}
.ssi-cert-shot img {
width: auto;
max-width: 100%;
max-height: 100%;
}
.ssi-cert-t {
display: block;
font-size: 16px;
font-weight: 800;
color: var(--ssi-ink);
line-height: 1.3;
margin-bottom: .3rem;
transition: color .22s ease;
}
.ssi-cert:hover .ssi-cert-t {
color: var(--ssi-red);
}
.ssi-cert-d {
display: block;
font-size: 13.5px;
line-height: 1.5;
color: var(--ssi-body);
margin-bottom: 1rem;
}
/* margin-top auto pins this to the bottom, so the three cards line
their footers up however long the description above runs. */
.ssi-cert-go {
display: block;
margin-top: auto;
font-size: 11px;
font-weight: 800;
letter-spacing: .15em;
text-transform: uppercase;
color: var(--ssi-red);
}
.ssi-cert-go .fas {
margin-right: .4rem;
}
/* ---- LEGAL PAGES ----
Long form policy copy. Privacy policy now, terms of use and any
other document the lawyers hand over later.
The whole job here is legibility. So: real space above each
numbered heading, and a hairline rule instead of the the old
page put between every section.
MEASURE. NO max-width here, deliberately. The line length is set
by the container instead: the page uses .container-narrow, which
caps at 900px and comes back to about 100 characters a line at
this font size. If this block is ever dropped into a plain
.container it will run the full 1300px, which is too long to read
comfortably, so keep it in the narrow one. */
.ssi-legal {
color: var(--ssi-body);
}
.ssi-legal p {
font-size: 15.5px;
line-height: 1.75;
margin-bottom: 1.05rem;
}
/* The rule and the space live on the heading rather than on a
separator element, so a section can be added or removed without
anyone remembering to move an with it. */
.ssi-legal h2 {
font-size: clamp(19px, 2.5vw, 24px);
line-height: 1.3;
color: var(--ssi-ink);
margin: 2.9rem 0 1.1rem;
padding-top: 2.5rem;
border-top: 1px solid var(--ssi-line);
/* The platform header is fixed, so an anchor jump would otherwise
park the heading underneath it. 130 clears the 109 to 111px the
header measures from 401px up, with air to spare. Under 401 the
search box drops onto its own row and the header grows to 165,
which is what the override further down is for. */
scroll-margin-top: 130px;
}
.ssi-legal > h2:first-child {
margin-top: 0;
padding-top: 0;
border-top: 0;
}
/* Terms of Use has one h3, the arbitration and class action waiver
subhead inside section 11. Base h3 on this site is larger than base
h2, so without this it would outrank the numbered heading above it.
Sits between the h2 and the h5, with no rule, because it is a
subhead within a section rather than a new one. */
.ssi-legal h3 {
font-size: clamp(17px, 2.1vw, 19px);
font-weight: 800;
line-height: 1.35;
color: var(--ssi-ink);
margin: 2.4rem 0 .9rem;
}
.ssi-legal h5 {
font-size: 15px;
font-weight: 900;
color: var(--ssi-ink);
margin: 2rem 0 .7rem;
}
.ssi-legal ul {
list-style: none;
padding-left: 0;
margin: 0 0 1.4rem;
}
.ssi-legal ul li {
position: relative;
padding-left: 1.3rem;
font-size: 15.5px;
line-height: 1.7;
margin-bottom: .35rem;
}
.ssi-legal ul li::before {
content: "";
position: absolute;
left: .2rem;
top: .66em;
width: 5px;
height: 5px;
border-radius: 50%;
background: var(--ssi-red);
}
.ssi-legal strong {
color: var(--ssi-ink);
}
/* break-word rather than a wrapper: section 9 prints a full URL as
its own link text, and on a 340px phone that string is wider than
the column. */
.ssi-legal a {
color: var(--ssi-red);
text-decoration: underline;
word-break: break-word;
}
.ssi-legal a:hover {
color: var(--ssi-maroon);
}
.ssi-legal-contact {
background: var(--ssi-wash);
border: 1px solid var(--ssi-line);
border-radius: var(--ssi-r);
padding: 1.35rem 1.5rem;
margin-bottom: 1.4rem;
}
.ssi-legal-contact p {
margin-bottom: 0;
line-height: 1.85;
}
/* The header is taller under 401 because the search box wraps onto
its own row, so a deep link into a section needs more clearance. */
@media (max-width: 400px) {
.ssi-legal h2 {
scroll-margin-top: 185px;
}
}
/* ---- CONTACT DETAILS LIST ----
Address, phone, email and hours beside the form on Contact Us.
Same icon-then-content shape as the footer's contact column, in
the light palette, so the two read as the same information
twice rather than as two different components.
The rules are drawn with border-top on every item except the
first, which is what lets an item be added or removed without
leaving a stray line at either end. */
.ssi-cinfo {
list-style: none;
margin: 0;
padding: 0;
}
.ssi-cinfo li {
display: flex;
gap: .85rem;
padding: .95rem 0;
border-top: 1px solid var(--ssi-line);
font-size: 15px;
line-height: 1.55;
color: var(--ssi-body);
}
.ssi-cinfo li:first-child {
border-top: 0;
padding-top: 0;
}
.ssi-cinfo li:last-child {
padding-bottom: 0;
}
.ssi-cinfo .fas {
flex: 0 0 auto;
margin-top: .25em;
font-size: 14px;
color: var(--ssi-red);
}
/* Red rather than ink, because these four lines are mostly links
sitting next to four lines that are not, and the icon alone is
not enough to tell them apart. */
.ssi-cinfo a {
color: var(--ssi-red);
font-weight: 600;
}
.ssi-cinfo a:hover {
color: var(--ssi-maroon);
text-decoration: underline;
}
.ssi-cinfo-k {
display: block;
font-size: 11.5px;
font-weight: 900;
letter-spacing: .16em;
text-transform: uppercase;
color: var(--ssi-muted);
margin-bottom: .15rem;
}
/* ---- HIGHLIGHTED NOTE ----
The client set their "contact sales directly" line in yellow
highlighter in the CMS editor. That is an editor's way of saying
read this first, not a design, so it is a brand edged panel here
instead. Generic enough for any page that needs one line to sit
above the rest. */
.ssi-cnote {
background: var(--ssi-wash);
border: 1px solid var(--ssi-line);
border-left: 4px solid var(--ssi-red);
border-radius: var(--ssi-r-sm);
padding: 1.1rem 1.3rem;
font-size: 15px;
line-height: 1.6;
color: var(--ssi-ink);
}
.ssi-cnote p:last-child {
margin-bottom: 0;
}
.ssi-cnote a {
color: var(--ssi-red);
font-weight: 700;
text-decoration: underline;
}
.ssi-cnote a:hover {
color: var(--ssi-maroon);
}
/* ---- CONTACT MAP ----
Fills whatever height is left in the details column once the note
and the details card have taken theirs, so the column finishes
level with the form beside it instead of leaving a white gap.
HOW THE HEIGHT WORKS, because an iframe will not just stretch:
the column is d-flex flex-column and a Bootstrap row already
stretches its columns to the tallest one, so this wrapper's
flex: 1 1 auto hands it the leftover. The iframe is then a flex
item of the wrapper, which is what stretches it, rather than a
height: 100% that has nothing definite to resolve against.
min-height is the mobile case: stacked, there is no leftover to
claim, so the map falls back to a fixed band. Kept modest because
on a phone this sits above the form, and a tall map there is just
something to scroll past. */
.ssi-cmap {
display: flex;
flex: 1 1 auto;
min-height: 240px;
overflow: hidden;
border: 1px solid var(--ssi-line);
border-radius: var(--ssi-r);
box-shadow: var(--ssi-shadow);
background: var(--ssi-wash);
}
.ssi-cmap iframe {
display: block;
flex: 1 1 auto;
width: 100%;
min-height: 240px;
border: 0;
}
@media (min-width: 992px) {
.ssi-cmap {
min-height: 220px;
}
}
@media (min-width: 992px) {
.ssi-proc + .ssi-proc {
margin-top: 3.6rem;
padding-top: 3.6rem;
}
}
/* On a phone the hero photo is cropped hard and the type lands over
the middle of it, so the sideways veil stops helping and turns
into a flat, heavy one. */
@media (max-width: 767px) {
.ssi-phero-veil {
background: linear-gradient(180deg, rgba(16, 4, 7, .93) 0%, rgba(60, 14, 22, .9) 55%, rgba(110, 24, 34, .86) 100%);
}
}
@media (max-width: 575px) {
.ssi-brand.ssi-brand-g {
padding: 1.15rem .85rem 1.05rem;
}
.ssi-brand-g .ssi-brand-desc {
font-size: 12.5px;
}
.ssi-badge-img {
width: 88px;
}
.ssi-pillar {
padding: 1.5rem 1.3rem;
}
}
@media (max-width: 400px) {
.ssi-facts-v {
flex-basis: 100%;
text-align: left;
}
}
/* ============================================================
SMALL SCREEN TUNING
============================================================ */
@media (max-width: 767px) {
.ssi-search {
flex-wrap: wrap;
}
.ssi-search input {
padding: .9rem .6rem;
}
.ssi-search .btn {
width: 100%;
border-radius: 0;
}
.ssi-search-ico {
padding-left: .95rem;
}
.ssi-oem-badge {
position: static;
max-width: none;
margin-top: 1rem;
box-shadow: var(--ssi-shadow);
}
.ssi-brand {
width: 200px;
}
.ssi-stat {
padding-top: .9rem;
}
}
@media (max-width: 575px) {
/* Full-width stacked buttons, but ONLY inside page content. Scoped to
#savecontent on purpose: unscoped, this also blew out the search
button in the navbar and the signup button in the footer. */
#savecontent .btn.ml-2 {
margin-left: 0 !important;
}
#savecontent .btn {
width: 100%;
}
.ssi-caps {
gap: .5rem;
}
}
@media (max-width: 359px) {
.ssi-brand {
width: 172px;
}
}
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
.ssi-stage-slide,
.ssi-stage-cap {
transition: none;
}
.ssi-res-go i,
.ssi-go i,
.btn .fa-arrow-right {
transition: none;
}
.ssi-circ-ring {
transition: none;
}
.ssi-drawer,
.ssi-nav {
transition: none;
}
}
/* ############################################################
TEMP: BUILD NOTES SECTION DELETE BEFORE LAUNCH
############################################################
Everything below this banner belongs to the build notes section at
the BOTTOM of htm.htm and to nothing else. Delete that section and
its script, delete this block, and the site is unchanged.
Same dark field and neutral top-left bloom as the footer, so it
reads as deliberate rather than broken.
############################################################ */
.ssi-tmp {
position: relative;
overflow: hidden;
background: #12161a;
color: rgba(255, 255, 255, .68);
/* one amber, used by the alert border and the // separators both, so
tuning it is a single edit */
--tmp-amber: #ffc848;
}
.ssi-tmp::before {
content: "";
position: absolute;
top: -150px;
left: -170px;
width: min(1200px, 125%);
aspect-ratio: 1 / 1;
background: radial-gradient(circle at 34% 30%,
rgba(236, 240, 244, .11) 0%,
rgba(228, 233, 238, .075) 24%,
rgba(214, 221, 227, .04) 44%,
rgba(200, 208, 215, .015) 60%,
rgba(200, 208, 215, 0) 72%);
pointer-events: none;
z-index: 0;
}
.ssi-tmp > * {
position: relative;
z-index: 1;
}
/* The alert, muted the way a dark theme does it: the colour lives in a
low alpha wash and a hairline, never in a solid fill, because a
saturated red panel on a near-black field vibrates.
Media object, so the icon holds its own column and any amount of
text typed in beside it stays hung off that column rather than
wrapping back underneath the glyph. */
.ssi-tmp-alert {
display: flex;
align-items: flex-start;
gap: .7rem;
border: 1px solid var(--tmp-amber);
border-radius: var(--ssi-r-sm);
background: rgba(217, 35, 42, .09);
padding: .85rem 1.1rem;
/* Courier, so the block reads as a terminal note rather than as
page copy. It is the cheapest possible signal that this is not
part of the site, and it costs nothing to delete with the rest.
The Font Awesome icon inside is unaffected, .fas asserts its own
family. */
font-family: "Courier New", Courier, monospace;
font-size: 14.7px;
/* tight, because this is a scannable run of notes rather than
prose. Loose leading here just made it longer to get through. */
line-height: 1.25;
color: rgba(255, 255, 255, .72);
}
/* not pure --ssi-bright: full saturation red on near-black is hard to
read at this size, so it is lifted toward pink */
.ssi-tmp-alert > .fas {
flex: 0 0 auto;
margin-top: .2em;
font-size: 15px;
color: #ff8a90;
}
/* the title reads as the title on brightness alone. Courier bold is
heavy and clotted, and it was fight ing the yellow separators for
attention, so the weight comes back off and only the white stays. */
.ssi-tmp-alert strong,
.ssi-tmp-alert b {
font-weight: 400;
color: #fff;
}
/* The // separators, in amber. In a single run-on paragraph of notes
the eye needs somewhere to break, and a coloured token does that
without adding any vertical space, which is the whole point of
keeping this block one tight paragraph. Applied by the small script
in the section itself, so nothing has to be typed by hand. */
.ssi-tmp-sep {
color: var(--tmp-amber);
font-weight: 700;
padding: 0 .12rem;
}
/* no font-family here, the whole block is already Courier. This is
just the highlight plate. */
.ssi-tmp-alert code {
font-size: inherit;
padding: .1rem .34rem;
border-radius: 3px;
background: rgba(255, 255, 255, .09);
color: #ffb3b7;
}
/* ############ END TEMP BLOCK ############################### */
.job-image .d-flex.h-100 {
background-size: contain !important;
background-repeat: no-repeat !important;
}
.v3-caret {
color: var(--primary) !important;
}
/* PAGE SPECIFIC */
/* FOOTER */
