771 lines
20 KiB
CSS
771 lines
20 KiB
CSS
/* The landing page: flat Sticknife chrome framing the pantheon.
|
|
Everything is scoped to body.landing so the rest of the app keeps styles.css as it was.
|
|
|
|
The identity is the logo's construction — content banded between hard rules, sitting on a
|
|
baseline — plus one discipline: gold belongs to the art and to status, never to the chrome.
|
|
That is what lets thirteen gilt seals be the only rich thing on the page. */
|
|
|
|
body.landing {
|
|
--ink: #0c0b0a;
|
|
--wall: #141210;
|
|
--rule: #2b2622;
|
|
--rule-2: #3a342d;
|
|
--cream: #f2ece1;
|
|
--muted: #8e8579;
|
|
--dim: #5f584f;
|
|
--gold: #b5976e;
|
|
--hot: #e1812b;
|
|
|
|
--chrome: "Oswald", "Archivo Narrow", "Barlow Condensed", "Roboto Condensed",
|
|
"Helvetica Neue Condensed", "Arial Narrow", system-ui, sans-serif;
|
|
--plaque: "Cinzel", "Trajan Pro", "Palatino Linotype", Palatino, "Book Antiqua",
|
|
Georgia, serif;
|
|
--data: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
|
|
|
--gutter: clamp(16px, 3vw, 28px);
|
|
--col: 1180px;
|
|
/* roughly the width of the Sign in button: how far right of the content column the fixed
|
|
nav sits, so the sign-up card passes underneath it rather than through it */
|
|
--nav-clear: 104px;
|
|
|
|
background: var(--ink);
|
|
color: var(--cream);
|
|
font-family: var(--chrome);
|
|
font-stretch: 85%;
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
/* a faint warm cast from above, so the black isn't flat vinyl */
|
|
body.landing::before {
|
|
content: "";
|
|
position: fixed;
|
|
inset: 0;
|
|
z-index: 0;
|
|
pointer-events: none;
|
|
background: radial-gradient(120% 70% at 50% -10%, rgba(181, 151, 110, .07), transparent 60%);
|
|
}
|
|
|
|
body.landing .page { position: relative; z-index: 1; display: block; }
|
|
|
|
body.landing .landing-shell {
|
|
width: 100%;
|
|
margin: 0;
|
|
padding: 0;
|
|
border: 0;
|
|
background: none;
|
|
box-shadow: none;
|
|
}
|
|
|
|
.sn-page {
|
|
width: min(var(--col), 100%);
|
|
margin: 0 auto;
|
|
padding: 0 var(--gutter);
|
|
}
|
|
|
|
/* The auth nav lives in the shared topbar. It used to line up with the content column's right
|
|
edge, which is exactly where the sign-up card is, so scrolling dragged the card straight
|
|
under it. Sitting it a button's width further right puts it in the margin instead — and on
|
|
viewports too narrow to have a margin to spare, the floor keeps it on the page. */
|
|
body.landing .topbar {
|
|
top: 34px;
|
|
right: max(10px, calc(50vw - var(--col) / 2 + var(--gutter) - var(--nav-clear)));
|
|
gap: 8px;
|
|
}
|
|
|
|
body.landing .nav-button {
|
|
min-height: 36px;
|
|
border: 2px solid var(--cream);
|
|
border-radius: 0;
|
|
background: transparent;
|
|
color: var(--cream);
|
|
font-family: var(--chrome);
|
|
font-size: .78rem;
|
|
font-stretch: 85%;
|
|
font-weight: 600;
|
|
letter-spacing: .11em;
|
|
text-transform: uppercase;
|
|
transition: background .16s, color .16s;
|
|
}
|
|
|
|
body.landing .nav-button:hover { background: var(--cream); color: var(--ink); }
|
|
body.landing .navlinks form { margin: 0; }
|
|
|
|
/* ---------------------------------------------------------------- brand and structure */
|
|
|
|
.sn-head { padding: 30px 0 22px; }
|
|
.sn-brand { display: inline-block; }
|
|
|
|
.sn-brand img {
|
|
display: block;
|
|
width: clamp(150px, 17vw, 200px);
|
|
height: auto;
|
|
}
|
|
|
|
.sn-baseline { height: 3px; background: var(--cream); }
|
|
.sn-hair { height: 1px; background: var(--rule); }
|
|
|
|
/* ------------------------------------------------------------------------------- gate */
|
|
|
|
.sn-gate {
|
|
display: grid;
|
|
grid-template-columns: minmax(0, 1.3fr) minmax(320px, .7fr);
|
|
gap: clamp(28px, 5vw, 60px);
|
|
align-items: start;
|
|
padding: clamp(38px, 6vw, 62px) 0 clamp(34px, 5vw, 52px);
|
|
}
|
|
|
|
.sn-eyebrow {
|
|
margin: 0 0 18px;
|
|
color: var(--muted);
|
|
font-size: .72rem;
|
|
font-weight: 600;
|
|
letter-spacing: .3em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
body.landing .sn-gate-copy h1 {
|
|
margin: 0 0 20px;
|
|
color: var(--cream);
|
|
font-family: var(--chrome);
|
|
font-size: clamp(2.3rem, 5.4vw, 4.2rem);
|
|
font-weight: 600;
|
|
line-height: .94;
|
|
letter-spacing: .012em;
|
|
text-transform: uppercase;
|
|
text-wrap: balance;
|
|
}
|
|
|
|
body.landing .sn-lede {
|
|
max-width: 46ch;
|
|
margin: 0;
|
|
color: var(--muted);
|
|
font-family: var(--plaque);
|
|
font-size: clamp(1rem, 1.5vw, 1.12rem);
|
|
line-height: 1.6;
|
|
}
|
|
|
|
.sn-lede em { color: var(--cream); font-style: normal; }
|
|
|
|
.sn-gate-card {
|
|
padding: clamp(20px, 2.4vw, 28px);
|
|
border: 1px solid var(--rule-2);
|
|
background: var(--wall);
|
|
}
|
|
|
|
body.landing .sn-gate-card h2 {
|
|
margin: 0 0 18px;
|
|
color: var(--muted);
|
|
font-family: var(--chrome);
|
|
font-size: .74rem;
|
|
font-weight: 600;
|
|
letter-spacing: .26em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
body.landing .sn-gate-card label {
|
|
display: grid;
|
|
gap: 7px;
|
|
color: var(--muted);
|
|
font-family: var(--chrome);
|
|
font-size: .72rem;
|
|
font-weight: 600;
|
|
letter-spacing: .16em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
body.landing .sn-gate-card .stack { display: grid; gap: 14px; }
|
|
|
|
body.landing .sn-gate-card input {
|
|
width: 100%;
|
|
height: 42px;
|
|
padding: 0 12px;
|
|
border: 1px solid var(--rule-2);
|
|
border-radius: 0;
|
|
background: #0a0908;
|
|
color: var(--cream);
|
|
font-family: var(--data);
|
|
font-size: .92rem;
|
|
letter-spacing: 0;
|
|
text-transform: none;
|
|
}
|
|
|
|
body.landing .sn-gate-card input:focus-visible { border-color: var(--gold); }
|
|
|
|
body.landing .sn-gate-card button {
|
|
width: 100%;
|
|
min-height: 42px;
|
|
margin-top: 4px;
|
|
border: 2px solid var(--cream);
|
|
border-radius: 0;
|
|
background: var(--cream);
|
|
color: var(--ink);
|
|
font-family: var(--chrome);
|
|
font-size: .8rem;
|
|
font-weight: 600;
|
|
font-stretch: 85%;
|
|
letter-spacing: .11em;
|
|
text-transform: uppercase;
|
|
cursor: pointer;
|
|
transition: background .16s;
|
|
}
|
|
|
|
body.landing .sn-gate-card button:hover { background: #fff; }
|
|
|
|
body.landing .sn-fineprint {
|
|
margin: 16px 0 0;
|
|
color: var(--dim);
|
|
font-family: var(--data);
|
|
font-size: .74rem;
|
|
line-height: 1.55;
|
|
}
|
|
|
|
.sn-fineprint b { color: var(--muted); font-weight: 400; }
|
|
|
|
/* the global link colour belongs to the other pages' palette; at this size the underline is
|
|
doing most of the work anyway */
|
|
body.landing .sn-fineprint a {
|
|
color: var(--muted);
|
|
text-decoration: underline;
|
|
text-underline-offset: 2px;
|
|
text-decoration-color: var(--rule-2);
|
|
}
|
|
|
|
body.landing .sn-fineprint a:hover { color: var(--gold); text-decoration-color: var(--gold); }
|
|
|
|
body.landing ul.sn-fineprint {
|
|
display: grid;
|
|
gap: 9px;
|
|
padding: 0;
|
|
list-style: none; /* separated by space alone — no marker, no indent */
|
|
}
|
|
|
|
body.landing .sn-gate-card .notice {
|
|
margin-bottom: 16px;
|
|
border-radius: 0;
|
|
font-family: var(--plaque);
|
|
font-size: .88rem;
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ section band */
|
|
|
|
.sn-band {
|
|
display: flex;
|
|
align-items: baseline;
|
|
justify-content: center;
|
|
gap: 20px;
|
|
padding: 28px 0 2px;
|
|
}
|
|
|
|
.sn-band-label {
|
|
color: var(--gold);
|
|
font-family: var(--plaque);
|
|
font-size: .96rem;
|
|
letter-spacing: .34em;
|
|
text-indent: .34em; /* offset the trailing letter-space so it centres optically */
|
|
text-transform: lowercase;
|
|
}
|
|
|
|
/* ----------------------------------------------------------------------------- the field */
|
|
|
|
.sn-field {
|
|
position: relative;
|
|
width: 100vw;
|
|
margin-left: calc(50% - 50vw);
|
|
/* Taller than the ring needs. geometry() spends the surplus on margin rather than on a
|
|
bigger ring, which is what keeps the tenants pushed outside the ring — Nanshe at the top
|
|
of it especially — from running off the top edge. */
|
|
height: clamp(900px, 105vh, 1140px);
|
|
overflow: hidden;
|
|
}
|
|
|
|
.sn-graph { position: absolute; inset: 0; width: 100%; height: 100%; }
|
|
|
|
/* houses are invisible until you go looking for one */
|
|
.sn-links g { opacity: 0; transition: opacity .3s ease; }
|
|
.sn-links g.on { opacity: 1; }
|
|
.sn-links line { stroke: var(--gold); stroke-width: 1; }
|
|
|
|
/* The cluster keeps its edges drawn rather than surfacing them on hover — it is small enough
|
|
to read at a glance, and the lines are what make it hang off the one at the top. Faint,
|
|
though: they are there to be inferred, not read. */
|
|
.sn-side-graph .sn-links line { stroke-opacity: .18; transition: stroke-opacity .3s ease; }
|
|
.sn-side-graph .sn-links.on line { stroke-opacity: .5; }
|
|
|
|
.sn-node { cursor: pointer; }
|
|
.sn-node image { transition: transform .3s ease; transform-box: fill-box; transform-origin: center; }
|
|
.sn-node .sn-halo { opacity: 0; transition: opacity .3s ease; }
|
|
.sn-node.lit .sn-halo, .sn-node.sel .sn-halo { opacity: 1; }
|
|
.sn-node.lit image, .sn-node.sel image { transform: scale(1.07); }
|
|
|
|
.sn-niche-ring { fill: #100e0c; stroke: var(--rule-2); stroke-width: 1; }
|
|
|
|
.sn-monogram {
|
|
fill: var(--rule-2);
|
|
font-family: var(--plaque);
|
|
font-size: 1.5rem;
|
|
letter-spacing: .08em;
|
|
text-anchor: middle;
|
|
}
|
|
|
|
.sn-label {
|
|
fill: var(--muted);
|
|
font-family: var(--plaque);
|
|
font-size: .68rem;
|
|
letter-spacing: .17em;
|
|
text-anchor: middle;
|
|
text-transform: uppercase;
|
|
opacity: .5;
|
|
transition: opacity .25s, fill .25s;
|
|
}
|
|
|
|
.sn-node.lit .sn-label, .sn-node.sel .sn-label { fill: var(--cream); opacity: 1; }
|
|
.sn-node[data-state="planned"] .sn-label, .sn-node[data-state="machine"] .sn-label { opacity: .34; }
|
|
|
|
.sn-graph.busy .sn-node:not(.lit):not(.sel) { opacity: .26; }
|
|
.sn-node { transition: opacity .3s ease; }
|
|
|
|
/* House names are authored lowercase — that is the control string. Every place one is shown
|
|
title-cases it in CSS, so the data stays plain and the page stays capitalised. */
|
|
.sn-house-tag {
|
|
fill: var(--gold);
|
|
font-family: var(--plaque);
|
|
font-size: .68rem;
|
|
letter-spacing: .22em;
|
|
text-anchor: middle;
|
|
text-transform: capitalize;
|
|
opacity: 0;
|
|
transition: opacity .3s ease;
|
|
}
|
|
|
|
.sn-house-tag.on { opacity: 1; }
|
|
|
|
.sn-node:focus { outline: none; }
|
|
.sn-node:focus-visible .sn-focus-ring { stroke: var(--hot); stroke-width: 2; }
|
|
.sn-focus-ring { fill: none; stroke: none; }
|
|
|
|
/* ------------------------------------------------------------------- the side drawers */
|
|
|
|
/* A rail of tabs pinned to the right edge, and one parked panel per tab behind it. The tabs
|
|
live on the rail rather than on the panels so that opening one never buries another's
|
|
handle underneath it. */
|
|
.sn-drawers {
|
|
position: absolute;
|
|
inset: 0;
|
|
z-index: 6;
|
|
pointer-events: none; /* the field underneath stays reachable */
|
|
--rail-w: 36px; /* keep in step with RAIL in pantheon.js */
|
|
}
|
|
|
|
.sn-drawers[hidden] { display: none; }
|
|
|
|
.sn-rail {
|
|
position: absolute;
|
|
z-index: 2;
|
|
top: 0;
|
|
bottom: 0;
|
|
right: 0;
|
|
width: var(--rail-w);
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 10px;
|
|
padding-top: 72px;
|
|
border-left: 1px solid var(--rule-2);
|
|
background: rgba(11, 10, 9, .95);
|
|
pointer-events: auto;
|
|
}
|
|
|
|
.sn-side-tab {
|
|
flex: none;
|
|
padding: 20px 0;
|
|
border: 0;
|
|
background: transparent;
|
|
color: var(--muted);
|
|
cursor: pointer;
|
|
font-family: var(--plaque);
|
|
font-size: .7rem;
|
|
letter-spacing: .22em;
|
|
text-transform: capitalize;
|
|
transition: color .2s;
|
|
}
|
|
|
|
.sn-side-tab span {
|
|
display: block;
|
|
writing-mode: vertical-rl;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.sn-side-tab:hover { color: var(--cream); }
|
|
.sn-side-tab.on { color: var(--gold); }
|
|
.sn-side-tab:focus-visible { outline: 1px solid var(--hot); outline-offset: -3px; }
|
|
|
|
.sn-side-body {
|
|
position: absolute;
|
|
z-index: 1;
|
|
top: 0;
|
|
bottom: 0;
|
|
right: var(--rail-w);
|
|
width: clamp(260px, 24vw, 360px);
|
|
border-left: 1px solid var(--rule-2);
|
|
background: rgba(11, 10, 9, .97);
|
|
transform: translateX(calc(100% + var(--rail-w)));
|
|
pointer-events: none;
|
|
transition: transform .42s cubic-bezier(.22, .61, .36, 1);
|
|
}
|
|
|
|
.sn-side-body.open { transform: none; pointer-events: auto; }
|
|
|
|
.sn-side-graph { display: block; width: 100%; height: 100%; }
|
|
|
|
.sn-hint {
|
|
position: absolute;
|
|
z-index: 2;
|
|
bottom: 14px;
|
|
left: 50%;
|
|
margin: 0;
|
|
color: var(--dim);
|
|
font-family: var(--data);
|
|
font-size: .7rem;
|
|
transform: translateX(-50%);
|
|
transition: opacity .3s;
|
|
}
|
|
|
|
.sn-hint.away { opacity: 0; }
|
|
|
|
/* ------------------------------------------------------------- no-script / no-d3 listing */
|
|
|
|
/* The listing ships hidden and is only revealed when the graph cannot run — either by the
|
|
noscript rule in the page or by pantheon.js giving up. This [hidden] rule has to be here:
|
|
the display below would otherwise outrank the browser's own [hidden] { display: none }. */
|
|
.sn-fallback[hidden] { display: none; }
|
|
|
|
/* The stacked view: one block per family, each member a card that opens in place. It is the
|
|
no-JavaScript fallback and the whole layout on a narrow screen, where a ring of thirty-two
|
|
seals is unreadable and a list of families is not. */
|
|
.sn-fallback {
|
|
position: relative;
|
|
z-index: 1;
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
|
gap: 30px 40px;
|
|
width: min(var(--col), 100%);
|
|
margin: 0 auto;
|
|
padding: 34px var(--gutter);
|
|
}
|
|
|
|
body.landing .sn-fallback h2 {
|
|
margin: 0 0 14px;
|
|
padding-bottom: 8px;
|
|
border-bottom: 1px solid var(--rule);
|
|
color: var(--gold);
|
|
font-family: var(--plaque);
|
|
font-size: .8rem;
|
|
letter-spacing: .2em;
|
|
text-transform: capitalize;
|
|
}
|
|
|
|
.sn-fallback ul { margin: 0; padding: 0; list-style: none; }
|
|
.sn-fallback li { margin: 0 0 10px; }
|
|
|
|
.sn-card { border: 1px solid var(--rule); background: rgba(20, 18, 16, .5); }
|
|
.sn-card[open] { border-color: var(--rule-2); background: var(--wall); }
|
|
|
|
.sn-card summary {
|
|
display: flex;
|
|
gap: 14px;
|
|
align-items: center;
|
|
padding: 12px;
|
|
cursor: pointer;
|
|
list-style: none;
|
|
}
|
|
|
|
.sn-card summary::-webkit-details-marker { display: none; }
|
|
.sn-card summary::marker { content: ""; }
|
|
.sn-card summary:focus-visible { outline: 1px solid var(--hot); outline-offset: -2px; }
|
|
|
|
.sn-card-face {
|
|
flex: none;
|
|
display: grid;
|
|
place-items: center;
|
|
width: 58px;
|
|
height: 58px;
|
|
}
|
|
|
|
.sn-card-face img { display: block; width: 100%; height: auto; }
|
|
|
|
.sn-card-face .sn-empty {
|
|
display: grid;
|
|
place-items: center;
|
|
width: 46px;
|
|
height: 46px;
|
|
border: 1px solid var(--rule-2);
|
|
border-radius: 50%;
|
|
color: var(--dim);
|
|
font-family: var(--plaque);
|
|
font-size: 1rem;
|
|
}
|
|
|
|
.sn-card-head { display: grid; gap: 2px; min-width: 0; }
|
|
|
|
.sn-fallback b {
|
|
color: var(--cream);
|
|
font-family: var(--plaque);
|
|
font-size: .84rem;
|
|
font-weight: 600;
|
|
letter-spacing: .13em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.sn-card-domain {
|
|
color: var(--gold);
|
|
font-family: var(--data);
|
|
font-size: .66rem;
|
|
letter-spacing: .12em;
|
|
text-transform: lowercase;
|
|
}
|
|
|
|
.sn-card-does {
|
|
color: var(--muted);
|
|
font-family: var(--plaque);
|
|
font-size: .82rem;
|
|
line-height: 1.45;
|
|
}
|
|
|
|
.sn-card-body { padding: 0 12px 14px; border-top: 1px solid var(--rule); }
|
|
|
|
.sn-card-body p {
|
|
margin: 12px 0 0;
|
|
color: var(--muted);
|
|
font-family: var(--plaque);
|
|
font-size: .88rem;
|
|
line-height: 1.6;
|
|
}
|
|
|
|
.sn-card-body .sn-spec { margin: 14px 0 16px; }
|
|
.sn-card[data-state="machine"] .sn-card-body .sn-actions { display: none; }
|
|
|
|
|
|
.sn-fallback a { color: var(--gold); font-family: var(--data); font-size: .78rem; }
|
|
.sn-fallback span { color: var(--dim); font-family: var(--data); font-size: .78rem; }
|
|
|
|
/* --------------------------------------------------------------------------- the drawer */
|
|
|
|
/* The detail panel rides in from the left edge of the field; the graph re-centres into the
|
|
space that is left, which the simulation animates on its own. */
|
|
.sn-drawer {
|
|
position: absolute;
|
|
z-index: 7;
|
|
top: 0;
|
|
bottom: 0;
|
|
left: 0;
|
|
width: clamp(320px, 33vw, 452px);
|
|
overflow-y: auto;
|
|
border-right: 1px solid var(--rule-2);
|
|
background: rgba(11, 10, 9, .97);
|
|
transform: translateX(-101%);
|
|
pointer-events: none;
|
|
transition: transform .42s cubic-bezier(.22, .61, .36, 1);
|
|
}
|
|
|
|
.sn-drawer.open {
|
|
transform: none;
|
|
pointer-events: auto;
|
|
}
|
|
|
|
.sn-drawer-in {
|
|
display: block;
|
|
padding: clamp(22px, 2.4vw, 34px);
|
|
}
|
|
|
|
.sn-drawer-art {
|
|
width: min(200px, 54%);
|
|
margin-bottom: clamp(18px, 2vw, 26px);
|
|
}
|
|
|
|
.sn-drawer-art img { display: block; width: 100%; height: auto; }
|
|
|
|
.sn-drawer-art .sn-empty {
|
|
display: grid;
|
|
place-items: center;
|
|
aspect-ratio: 1;
|
|
border: 1px solid var(--rule-2);
|
|
border-radius: 50%;
|
|
background: radial-gradient(circle at 50% 36%, #171512, #0e0c0b 72%);
|
|
color: var(--rule-2);
|
|
font-family: var(--plaque);
|
|
font-size: 3rem;
|
|
}
|
|
|
|
.sn-drawer-body { position: relative; }
|
|
|
|
body.landing .sn-drawer-body h3 {
|
|
margin: 0 44px 6px 0; /* clear of the close button */
|
|
color: var(--cream);
|
|
font-family: var(--plaque);
|
|
font-size: clamp(1.5rem, 3vw, 2rem);
|
|
font-weight: 600;
|
|
letter-spacing: .13em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.sn-drawer-domain {
|
|
margin: 0 0 20px;
|
|
color: var(--gold);
|
|
font-size: .78rem;
|
|
font-weight: 600;
|
|
letter-spacing: .22em;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
body.landing .sn-long {
|
|
max-width: 58ch;
|
|
margin: 0 0 22px;
|
|
color: var(--muted);
|
|
font-family: var(--plaque);
|
|
font-size: 1rem;
|
|
line-height: 1.65;
|
|
}
|
|
|
|
.sn-spec {
|
|
display: grid;
|
|
grid-template-columns: max-content minmax(0, 1fr);
|
|
gap: 9px 18px;
|
|
margin: 0 0 24px;
|
|
padding: 18px 0 0;
|
|
border-top: 1px solid var(--rule);
|
|
font-family: var(--data);
|
|
font-size: .78rem;
|
|
}
|
|
|
|
.sn-spec dt { color: var(--dim); }
|
|
.sn-spec dd { margin: 0; color: var(--cream); }
|
|
.sn-spec .sn-house-name { text-transform: capitalize; }
|
|
|
|
.sn-actions { display: flex; flex-wrap: wrap; gap: 10px; }
|
|
|
|
.sn-btn {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-height: 38px;
|
|
padding: 0 16px;
|
|
border: 2px solid var(--cream);
|
|
background: transparent;
|
|
color: var(--cream);
|
|
font-family: var(--chrome);
|
|
font-size: .78rem;
|
|
font-weight: 600;
|
|
font-stretch: 85%;
|
|
letter-spacing: .11em;
|
|
text-transform: uppercase;
|
|
text-decoration: none;
|
|
cursor: pointer;
|
|
transition: background .16s, color .16s;
|
|
}
|
|
|
|
.sn-btn:hover { background: var(--cream); color: var(--ink); }
|
|
.sn-btn-quiet { border-color: var(--rule-2); color: var(--muted); }
|
|
.sn-btn-quiet:hover { border-color: var(--cream); background: transparent; color: var(--cream); }
|
|
|
|
.sn-close {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
z-index: 2;
|
|
display: grid;
|
|
place-items: center;
|
|
width: 34px;
|
|
height: 34px;
|
|
border: 1px solid var(--rule-2);
|
|
background: transparent;
|
|
color: var(--muted);
|
|
font-size: 1.1rem;
|
|
line-height: 1;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.sn-close:hover { border-color: var(--cream); color: var(--cream); }
|
|
|
|
/* ------------------------------------------------------------------------------- footer */
|
|
|
|
.sn-maker {
|
|
display: flex;
|
|
align-items: flex-end;
|
|
justify-content: space-between;
|
|
gap: 28px;
|
|
min-height: 128px;
|
|
}
|
|
|
|
.sn-maker img { display: block; width: 60px; height: auto; opacity: .16; }
|
|
|
|
body.landing .sn-thesis {
|
|
padding-bottom: 22px;
|
|
color: var(--muted);
|
|
font-family: var(--plaque);
|
|
font-size: 1rem;
|
|
letter-spacing: .04em;
|
|
}
|
|
|
|
.sn-colophon {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
justify-content: space-between;
|
|
gap: 14px;
|
|
padding: 14px 0 44px;
|
|
color: var(--dim);
|
|
font-family: var(--data);
|
|
font-size: .72rem;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------- responsive */
|
|
|
|
@media (max-width: 900px) {
|
|
.sn-gate { grid-template-columns: minmax(0, 1fr); }
|
|
}
|
|
|
|
/* no room to slide the graph aside: the panel simply covers it */
|
|
@media (max-width: 700px) {
|
|
.sn-drawer { width: 100%; border-right: 0; }
|
|
}
|
|
|
|
/* Below this the ring stops being readable: thirty-two seals want more width than a phone
|
|
has, and shrinking them to fit turns the whole thing into gravel. So the field gives way
|
|
to the stacked families, which need no script and no physics — the [hidden] attribute is
|
|
overridden here rather than removed, so this works with JavaScript switched off. */
|
|
@media (max-width: 820px) {
|
|
.sn-field {
|
|
height: auto;
|
|
overflow: visible;
|
|
}
|
|
|
|
.sn-graph,
|
|
.sn-hint,
|
|
.sn-drawers,
|
|
.sn-drawer { display: none; }
|
|
|
|
.sn-fallback[hidden] { display: grid; }
|
|
.sn-fallback { padding-top: 8px; }
|
|
|
|
/* Reading order down the column, set by STACK_ORDER in pantheon.py. Scoped to this query on
|
|
purpose: the custom property is inert everywhere else, so the desktop listing keeps the
|
|
order the markup is in and the ring is untouched. */
|
|
.sn-family { order: var(--stack, 0); }
|
|
}
|
|
|
|
@media (max-width: 560px) {
|
|
body.landing .topbar {
|
|
top: auto;
|
|
right: var(--gutter);
|
|
bottom: max(16px, env(safe-area-inset-bottom));
|
|
}
|
|
|
|
/* the field is already stacked by here — nothing left to size */
|
|
.sn-fallback { grid-template-columns: minmax(0, 1fr); gap: 26px; }
|
|
}
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
body.landing *, body.landing *::before, body.landing *::after {
|
|
animation-duration: .01ms !important;
|
|
transition-duration: .01ms !important;
|
|
}
|
|
}
|