jb-website/src/styles/site.css

168 lines
6.3 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.

/* ============================================================================
Josh Bairstow — shared site chrome
Sits on top of colors_and_type.css. Holds the bits every page repeats:
the warm grounds, near-invisible grain, sprinkled accent marks, the top
bar, link affordances, the signature footer.
Dark ink ground is the default theme; body:not(.dark) is the bone alternate.
========================================================================== */
* { box-sizing: border-box; }
html, body { margin: 0; }
html { -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
body {
font-family: var(--font-body);
background-color: var(--ground-dark);
color: var(--fg-on-dark-1);
min-height: 100vh;
position: relative;
}
body:not(.dark) { background-color: var(--ground); color: var(--fg-1); }
/* ---- page-wide film grain (§5: 38% opacity, no hard edges) ------------- */
body::before {
content: "";
position: fixed; inset: 0;
background-image: url(/assets/texture-grain.svg);
background-size: 240px;
opacity: 0.06;
mix-blend-mode: screen;
pointer-events: none;
z-index: 0;
}
body:not(.dark)::before { opacity: 0.045; mix-blend-mode: normal; }
/* ---- sprinkled accent marks — crisp glyphs, loose placement ------------- */
:root {
--mark-filter-dark: invert(52%) sepia(16%) saturate(340%) brightness(88%);
--mark-filter-light: invert(34%) sepia(18%) saturate(280%) brightness(76%);
--mark-rest: 0.16;
}
.mark {
position: absolute; pointer-events: none; z-index: 0;
filter: var(--mark-filter-dark);
opacity: var(--mark-rest);
transition: opacity var(--dur-slow) var(--ease-out);
}
body:not(.dark) .mark { filter: var(--mark-filter-light); opacity: 0.11; }
/* ---- shared content stage ----------------------------------------------- */
.stage {
position: relative; z-index: 1;
max-width: 1180px;
margin: 0 auto;
padding: clamp(26px, 4.5vh, 52px) clamp(24px, 5vw, 64px) clamp(30px, 5vh, 56px);
min-height: 100vh;
display: flex;
flex-direction: column;
}
/* ---- top bar ------------------------------------------------------------ */
.topbar {
display: flex; align-items: center; justify-content: space-between;
gap: 24px;
padding-bottom: 18px;
border-bottom: 1px solid var(--hairline-on-dark);
}
body:not(.dark) .topbar { border-bottom-color: var(--hairline); }
.wordmark {
font-family: var(--font-display); font-weight: 500;
font-size: 21px; line-height: 1; letter-spacing: 0;
color: var(--fg-on-dark-1); margin: 0;
text-decoration: none; display: inline-flex; align-items: baseline;
}
body:not(.dark) .wordmark { color: var(--fg-1); }
.wordmark .dot { color: var(--accent-deep); }
.topnav { display: flex; align-items: center; gap: 26px; }
.topnav a {
font-family: var(--font-body); font-weight: 500; font-size: 11px;
letter-spacing: 0.2em; text-transform: uppercase; text-decoration: none;
color: var(--fg-on-dark-2);
position: relative; padding-bottom: 2px;
transition: color var(--dur-base) var(--ease-out);
}
body:not(.dark) .topnav a { color: var(--fg-3); }
.topnav a::after {
content: ""; position: absolute; left: 0; bottom: -2px; height: 1px; width: 0;
background: var(--accent); transition: width var(--dur-base) var(--ease-out);
}
.topnav a:hover { color: var(--fg-on-dark-1); }
body:not(.dark) .topnav a:hover { color: var(--fg-1); }
.topnav a:hover::after { width: 100%; }
.topnav a.current { color: var(--fg-on-dark-1); }
body:not(.dark) .topnav a.current { color: var(--fg-1); }
.topnav a.current::after { width: 100%; background: var(--accent-deep); }
.coord {
font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.06em;
color: var(--fg-on-dark-3); font-feature-settings: "onum" 1;
}
body:not(.dark) .coord { color: var(--fg-3); }
/* ---- shared type helpers (on-dark aware) -------------------------------- */
.eyebrow {
font-family: var(--font-body); font-weight: 500; font-size: 11px;
letter-spacing: 0.24em; text-transform: uppercase; color: var(--fg-on-dark-2);
margin: 0; white-space: nowrap;
}
body:not(.dark) .eyebrow { color: var(--fg-3); }
.serif { font-family: var(--font-display); font-weight: 500; letter-spacing: -0.015em; }
/* ---- signature footer --------------------------------------------------- */
.sitefoot {
position: relative; z-index: 1;
margin-top: auto;
padding-top: clamp(22px, 3.5vh, 36px);
border-top: 1px solid var(--hairline-on-dark);
display: flex; align-items: flex-end; justify-content: space-between; gap: 24px;
}
body:not(.dark) .sitefoot { border-top-color: var(--hairline); }
.sitefoot .sig {
width: 74px; opacity: 0.24;
filter: var(--mark-filter-dark);
}
body:not(.dark) .sitefoot .sig { filter: var(--mark-filter-light); }
.sitefoot .copyline {
font-family: var(--font-body); font-size: 12px; color: var(--fg-on-dark-3);
font-feature-settings: "onum" 1; text-align: right; letter-spacing: 0.02em;
}
body:not(.dark) .sitefoot .copyline { color: var(--fg-3); }
.sitefoot .footnav { display: flex; gap: 18px; }
.sitefoot .footnav a {
font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.12em;
text-transform: uppercase; color: var(--fg-on-dark-3); text-decoration: none;
transition: color var(--dur-base) var(--ease-out);
}
.sitefoot .footnav a:hover { color: var(--fg-on-dark-1); }
body:not(.dark) .sitefoot .footnav a { color: var(--fg-3); }
body:not(.dark) .sitefoot .footnav a:hover { color: var(--fg-1); }
/* ---- the latest / arrow link affordance --------------------------------- */
.inkarrow { color: var(--accent-deep); display: inline-block;
transition: transform var(--dur-base) var(--ease-out); }
a:hover .inkarrow { transform: translateX(5px); }
/* ---- warm chiaroscuro image frame (placeholder imagery) ----------------- */
.cutframe {
position: relative; overflow: hidden;
border-radius: var(--radius-cutout);
background: radial-gradient(120% 95% at 68% 16%,
#C9B299 0%, #8A6A47 30%, #4A3826 60%, #221E18 92%);
box-shadow: var(--shadow-2);
}
.cutframe .wm {
position: absolute; right: 7%; bottom: 7%; width: 30%; max-width: 150px;
opacity: 0.10; filter: invert(1); z-index: 4; pointer-events: none;
}
.cutframe .grain {
position: absolute; inset: 0; background-image: url(/assets/texture-grain.svg);
background-size: 220px; opacity: 0.12; mix-blend-mode: overlay;
pointer-events: none; z-index: 3;
}
@media (prefers-reduced-motion: reduce) {
.mark, .inkarrow { transition: none; }
}