Files
deepdrft/DeepDrftPublic.Client/Pages/About.razor.css
T
daniel-c-harvey c7d627b817 feat(about): wire bio portraits, swap images, circular frame, widen pull-quote
Portraits (1365 square) rendered as circles via border-radius:50%; parallax
tamed to fit. Process figure swapped to dd-mixer-2; Home Our Origin split
swapped to dd-pedals. Pull-quote widened 22ch to 44ch.
2026-06-17 21:45:55 -04:00

706 lines
17 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* About.razor scoped styles — "The Liner Notes".
This page diverges from Home by composition, not vocabulary. The backbone is a
persistent left RAIL (a continuous vertical hairline carrying oversized Bodoni
movement numerals + mono marginalia) with the content column offset asymmetrically
to its right. Movement boundaries are rendered as a hand-authored SVG waveform
stroke (the D3 motif folded in). Palette tokens, type stack, the dark Process band,
the feature-card grid, the CTA, and the bw↔colour ParallaxImage crossfade are all
reused from the site's existing vocabulary — only the structure is new.
Home's borrowed primitives that this redesign supersedes (.section-divider /
.divider-line centred rules, the symmetric .section-header-grid 4/8 split, the
.medium-card grid, .section-split) are intentionally NOT re-declared here. */
/* ── Animations (from DeepDrftHero.razor.css) ── */
@keyframes fade-up {
from { opacity: 0; transform: translateY(24px); }
to { opacity: 1; transform: none; }
}
.fade-up {
opacity: 0;
animation: fade-up 0.8s ease forwards;
}
/* ── HERO — the page opener (type scale from Home's .hero-*) ── */
.hero {
min-height: 100vh;
overflow: hidden;
}
.hero-left {
display: flex;
flex-direction: column;
justify-content: center;
padding: 6rem 3rem;
position: relative;
background: var(--deepdrft-white);
height: 100%;
}
.hero-image-pane {
display: flex;
flex-direction: column;
justify-content: center;
background: var(--deepdrft-white);
height: 100%;
}
@media (max-width: 960px) {
.hero { min-height: auto; }
.hero-left { padding: 4rem 1.5rem 3rem; }
}
.hero-eyebrow {
font-family: var(--deepdrft-font-mono);
font-size: 0.65rem;
letter-spacing: 0.28em;
color: var(--deepdrft-green-accent);
text-transform: uppercase;
margin-bottom: 1.8rem;
display: flex;
align-items: center;
gap: 1rem;
animation-delay: 0.1s;
}
.hero-eyebrow::before {
content: '';
display: block;
width: 2.5rem;
height: 1px;
background: var(--deepdrft-green-accent);
}
.hero-title {
font-family: var(--deepdrft-font-display);
font-size: clamp(4.5rem, 8vw, 8.5rem);
font-weight: 300;
line-height: 0.92;
letter-spacing: -0.02em;
color: var(--deepdrft-navy);
margin-bottom: 0.5rem;
animation-delay: 0.22s;
}
.hero-title em {
font-style: italic;
color: var(--deepdrft-green);
}
.hero-desc {
font-family: var(--deepdrft-font-body);
font-size: 0.92rem;
line-height: 1.75;
color: var(--deepdrft-navy);
opacity: 0.7;
max-width: 36ch;
margin-bottom: 3rem;
animation-delay: 0.44s;
}
/* ══════════════════ THE RAIL + SPINE — the signature device ══════════════════
Each movement is a two-column grid: a narrow rail column on the left carrying the
continuous vertical hairline (the narrative spine), the oversized Bodoni numeral,
and the mono marginalia; the content column to its right. The rail column is
~14% of the page on desktop and collapses to an inline header on mobile. */
.movement {
display: grid;
grid-template-columns: minmax(140px, 14%) minmax(0, 1fr);
background: var(--deepdrft-white);
align-items: start;
}
.rail {
position: relative;
align-self: stretch;
padding: 4rem 0 4rem 3rem;
}
/* The continuous vertical hairline — Home's horizontal .divider-line reoriented,
the same --deepdrft-border token, running the length of the movement. */
.rail-line {
position: absolute;
top: 0;
bottom: 0;
left: 3rem;
width: 1px;
background: var(--deepdrft-border);
}
/* Oversized Bodoni movement numeral. Sticks near the top of the viewport as the
movement scrolls, low-opacity navy by default; the active movement lights green
(toggled by the IntersectionObserver — see Interop/about/about-rail.ts). */
.rail-numeral {
position: sticky;
top: 6rem;
font-family: var(--deepdrft-font-display);
font-size: clamp(5rem, 10vw, 9rem);
font-weight: 300;
line-height: 1;
letter-spacing: -0.04em;
color: var(--deepdrft-navy);
opacity: 0.14;
padding-left: 1.4rem;
transition: color 0.5s ease, opacity 0.5s ease;
}
.movement.is-active .rail-numeral {
color: var(--deepdrft-green-accent);
opacity: 0.95;
}
/* Mono marginalia — a rotated caption set against the spine, the way a magazine
annotates a photo. Reuses the mono eyebrow idiom. */
.rail-margin {
position: sticky;
top: 16rem;
margin-top: 2rem;
padding-left: 1.4rem;
font-family: var(--deepdrft-font-mono);
font-size: 0.58rem;
letter-spacing: 0.24em;
text-transform: uppercase;
color: var(--deepdrft-muted);
writing-mode: vertical-rl;
transform: rotate(180deg);
transform-origin: center;
height: 12rem;
}
/* ── The content column — asymmetric, left-anchored prose ── */
.movement-content {
padding: 4rem 3rem 5rem 1rem;
min-width: 0;
}
/* ══════════════════ WAVEFORM MOVEMENT DIVIDER (D3 motif) ══════════════════
A self-contained SVG oscillation stroke with the mono movement tag sitting on it.
Replaces Home's flat .divider-line rule between movements. */
.wave-divider {
display: flex;
align-items: center;
gap: 1.5rem;
margin-bottom: 4rem;
}
.wave-stroke {
flex: 1;
height: 28px;
min-width: 0;
overflow: visible;
}
.wave-stroke path {
fill: none;
stroke: var(--deepdrft-green-accent);
stroke-width: 1.4;
opacity: 0.7;
vector-effect: non-scaling-stroke;
}
.wave-tag {
flex-shrink: 0;
font-family: var(--deepdrft-font-mono);
font-size: 0.62rem;
letter-spacing: 0.28em;
text-transform: uppercase;
color: var(--deepdrft-navy);
white-space: nowrap;
}
/* ── Movement intro — prose hanging at a consistent left edge ── */
.movement-intro {
max-width: 60ch;
margin-bottom: 5rem;
}
.movement-label {
font-family: var(--deepdrft-font-mono);
font-size: 0.62rem;
letter-spacing: 0.28em;
color: var(--deepdrft-green-accent);
text-transform: uppercase;
margin-bottom: 1.4rem;
}
.movement-title {
font-family: var(--deepdrft-font-display);
font-size: clamp(2.6rem, 5vw, 4.2rem);
font-weight: 300;
line-height: 1.02;
color: var(--deepdrft-navy);
margin-bottom: 2rem;
}
.movement-title em {
font-style: italic;
color: var(--deepdrft-green);
}
.movement-prose {
font-family: var(--deepdrft-font-body);
font-size: 0.95rem;
line-height: 1.85;
color: var(--deepdrft-navy);
opacity: 0.72;
max-width: 56ch;
}
/* ── Member bio pair — framed portrait insets with rail-side captions ──
Assembled from the existing type tokens (display serif name, mono caption/role,
body prose). The cards are offset/staggered rather than an even grid. */
.bio-pair {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 3rem;
align-items: start;
}
/* Stagger the second card downward so the pair reads as editorial layout, not a
symmetric grid. */
.bio-card:nth-child(2) {
margin-top: 4rem;
}
.bio-card {
display: flex;
flex-direction: column;
}
.bio-portrait {
width: 100%;
aspect-ratio: 1 / 1;
overflow: hidden;
border: 1px solid var(--deepdrft-border);
border-radius: 50%;
}
/* Graceful-degrade slot shown until a portrait file lands. A flat tonal panel in
the navy family, matching the circular portrait frame. */
.bio-portrait-placeholder {
width: 100%;
aspect-ratio: 1 / 1;
background:
linear-gradient(160deg,
color-mix(in srgb, var(--deepdrft-navy) 8%, var(--deepdrft-white)) 0%,
color-mix(in srgb, var(--deepdrft-navy) 16%, var(--deepdrft-white)) 100%);
}
/* The marginalia caption — mono, sits directly under the framed portrait. */
.bio-caption {
font-family: var(--deepdrft-font-mono);
font-size: 0.56rem;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--deepdrft-muted);
margin-top: 0.9rem;
padding-left: 0.1rem;
}
.bio-meta {
padding-top: 1.4rem;
}
.bio-name {
font-family: var(--deepdrft-font-display);
font-size: 2rem;
font-weight: 300;
line-height: 1.1;
color: var(--deepdrft-navy);
margin-bottom: 1rem;
}
.bio-body {
font-family: var(--deepdrft-font-body);
font-size: 0.85rem;
line-height: 1.8;
color: var(--deepdrft-navy);
opacity: 0.7;
}
/* ── Inset framed figure (gear shot) with rail-side caption ── */
.movement-figure {
margin: 5rem 0 0;
}
.movement-figure ::deep .parallax-window {
border: 1px solid var(--deepdrft-border);
}
.figure-caption {
font-family: var(--deepdrft-font-mono);
font-size: 0.56rem;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--deepdrft-muted);
margin-top: 0.9rem;
}
/* ══════════════════ THE PROCESS — dark band (reused vocabulary) ══════════════════ */
.process-band {
background: var(--deepdrft-navy);
padding: 4.5rem 3rem;
color: var(--deepdrft-white);
}
.process-label {
font-family: var(--deepdrft-font-mono);
font-size: 0.62rem;
letter-spacing: 0.28em;
color: var(--deepdrft-green-accent);
text-transform: uppercase;
margin-bottom: 1.2rem;
}
.process-title {
font-family: var(--deepdrft-font-display);
font-size: clamp(2.4rem, 4.5vw, 3.8rem);
font-weight: 300;
line-height: 1.02;
color: var(--deepdrft-white);
}
.process-title em {
font-style: italic;
color: var(--deepdrft-green-accent);
}
.process-standfirst {
font-family: var(--deepdrft-font-body);
font-size: 0.92rem;
line-height: 1.8;
color: rgba(250, 250, 248, 0.55);
max-width: 56ch;
margin-top: 2rem;
}
.features-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 0;
border: 1px solid rgba(250, 250, 248, 0.08);
margin-top: 3.5rem;
}
.feature-card {
padding: 2.5rem;
border-right: 1px solid rgba(250, 250, 248, 0.08);
border-bottom: 1px solid rgba(250, 250, 248, 0.08);
transition: background 0.3s;
}
/* 2×2 grid: kill the right border on the right column and the bottom border on the
last row so the outer frame stays clean. */
.feature-card:nth-child(2n) { border-right: none; }
.feature-card:nth-child(n + 3) { border-bottom: none; }
.feature-card:hover { background: rgba(250, 250, 248, 0.04); }
.feature-icon {
width: 2.5rem;
height: 2.5rem;
border: 1px solid rgba(250, 250, 248, 0.15);
margin-bottom: 1.8rem;
display: flex;
align-items: center;
justify-content: center;
}
.feature-icon svg {
width: 1rem;
height: 1rem;
stroke: var(--deepdrft-green-accent);
fill: none;
stroke-width: 1.5;
}
.feature-title {
font-family: var(--deepdrft-font-display);
font-size: 1.3rem;
font-weight: 400;
color: var(--deepdrft-white);
margin-bottom: 0.8rem;
line-height: 1.2;
}
.feature-desc {
font-family: var(--deepdrft-font-body);
font-size: 0.8rem;
line-height: 1.7;
color: rgba(250, 250, 248, 0.45);
}
/* ══════════════════ THE PRODUCT — medium list + pull-quote ══════════════════
A stacked editorial definition list, not Home's card grid. */
.medium-list {
list-style: none;
margin: 0 0 5rem;
padding: 0;
border-top: 1px solid var(--deepdrft-border);
max-width: 60ch;
}
.medium-row {
border-bottom: 1px solid var(--deepdrft-border);
}
.medium-row a {
display: flex;
align-items: baseline;
gap: 1.5rem;
padding: 1.6rem 0.4rem;
text-decoration: none;
transition: padding-left 0.25s ease;
}
.medium-row a:hover { padding-left: 1.2rem; }
.medium-row-name {
flex-shrink: 0;
font-family: var(--deepdrft-font-display);
font-size: 1.5rem;
font-weight: 400;
color: var(--deepdrft-navy);
min-width: 7rem;
}
.medium-row a:hover .medium-row-name { color: var(--deepdrft-green-accent); }
.medium-row-desc {
font-family: var(--deepdrft-font-body);
font-size: 0.85rem;
line-height: 1.6;
color: var(--deepdrft-navy);
opacity: 0.6;
}
/* The sharp pull-quote — breaks LEFT into the rail margin at large serif scale. */
.pull-quote {
margin: 0;
margin-left: -7rem;
max-width: 44ch;
}
.pull-eyebrow {
display: block;
font-family: var(--deepdrft-font-mono);
font-size: 0.6rem;
letter-spacing: 0.28em;
text-transform: uppercase;
color: var(--deepdrft-green-accent);
margin-bottom: 1.4rem;
}
.pull-quote p {
font-family: var(--deepdrft-font-display);
font-size: clamp(1.8rem, 3.4vw, 2.9rem);
font-weight: 300;
line-height: 1.15;
color: var(--deepdrft-navy);
}
/* ══════════════════ CLOSING CTA (reused vocabulary) ══════════════════ */
.cta-banner {
background: var(--deepdrft-navy);
padding: 6rem 3rem;
display: flex;
align-items: center;
justify-content: space-between;
gap: 3rem;
position: relative;
overflow: hidden;
}
.cta-banner::before {
content: 'DRFT';
position: absolute;
right: -2rem;
top: 50%;
transform: translateY(-50%);
font-family: var(--deepdrft-font-display);
font-size: 22rem;
font-weight: 300;
color: rgba(250, 250, 248, 0.03);
line-height: 1;
pointer-events: none;
user-select: none;
letter-spacing: -0.05em;
}
.cta-text {
position: relative;
z-index: 1;
}
.cta-headline {
font-family: var(--deepdrft-font-display);
font-size: clamp(2.5rem, 5vw, 5rem);
font-weight: 300;
color: var(--deepdrft-white);
line-height: 1;
margin-bottom: 1rem;
}
.cta-headline em {
font-style: italic;
color: var(--deepdrft-green-accent);
}
.cta-sub {
font-family: var(--deepdrft-font-body);
font-size: 0.88rem;
color: rgba(250, 250, 248, 0.4);
letter-spacing: 0.05em;
}
.cta-actions {
display: flex;
gap: 1rem;
align-items: center;
position: relative;
z-index: 1;
flex-shrink: 0;
flex-wrap: wrap;
}
.btn-white {
font-family: var(--deepdrft-font-mono);
font-size: 0.68rem;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--deepdrft-navy);
background: var(--deepdrft-white);
border: none;
padding: 1rem 2.2rem;
cursor: pointer;
text-decoration: none;
transition: background 0.25s, color 0.25s;
display: inline-block;
}
.btn-white:hover {
background: var(--deepdrft-green-accent);
color: var(--deepdrft-white);
}
.btn-outline-white {
font-family: var(--deepdrft-font-mono);
font-size: 0.68rem;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--deepdrft-white);
background: transparent;
border: 1px solid rgba(250, 250, 248, 0.3);
padding: 1rem 2.2rem;
cursor: pointer;
text-decoration: none;
transition: border-color 0.25s;
display: inline-block;
}
.btn-outline-white:hover { border-color: var(--deepdrft-white); }
/* ══════════════════ RESPONSIVE COLLAPSE ══════════════════
Below 960px the rail collapses: the spine + vertical numeral can't survive a
narrow viewport, so the numeral goes inline above each movement (horizontal,
left-aligned) and the marginalia folds away. Content goes single-column. */
@media (max-width: 960px) {
.movement {
display: block;
}
.rail {
padding: 2.5rem 1.5rem 0;
}
/* Spine becomes a short horizontal accent under the inline numeral. */
.rail-line {
position: static;
width: 3rem;
height: 2px;
margin-top: 1rem;
background: var(--deepdrft-border);
}
.rail-numeral {
position: static;
opacity: 0.18;
padding-left: 0;
font-size: clamp(3.5rem, 16vw, 5.5rem);
}
.movement.is-active .rail-numeral {
opacity: 0.95;
}
/* Marginalia is editorial chrome the narrow column can't host — drop it. */
.rail-margin {
display: none;
}
.movement-content {
padding: 2.5rem 1.5rem 3.5rem;
}
.process-band { padding: 3.5rem 1.5rem; }
/* Pull-quote can't break into a rail that no longer exists. */
.pull-quote {
margin-left: 0;
max-width: 100%;
}
}
@media (max-width: 720px) {
/* Bio pair stacks; drop the stagger so cards align cleanly. */
.bio-pair {
grid-template-columns: 1fr;
gap: 3.5rem;
}
.bio-card:nth-child(2) {
margin-top: 0;
}
}
@media (max-width: 599px) {
.features-grid { grid-template-columns: 1fr; }
.feature-card {
border-right: none;
border-bottom: 1px solid rgba(250, 250, 248, 0.08);
}
.feature-card:last-child { border-bottom: none; }
.medium-row a {
flex-direction: column;
gap: 0.4rem;
}
.cta-banner {
flex-direction: column;
align-items: flex-start;
gap: 2rem;
padding: 4rem 1.5rem;
}
.cta-actions {
width: 100%;
}
.btn-white,
.btn-outline-white {
flex: 1;
text-align: center;
min-width: 140px;
}
.cta-banner::before {
font-size: 8rem;
right: -0.5rem;
}
}