Files
ferrix/docs/sass/site.scss
T
Rayhaan JaufeerallyandClaude Opus 5.5 9ce81a873e Docs: show the front page photograph in its own colours
The blue two-colour treatment is replaced by the photograph's own
colours, slightly darkened, under a neutral shade that keeps the text
legible.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 21:35:36 +02:00

1079 lines
27 KiB
SCSS
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.
// The site's one stylesheet, in the manner of the International
// Typographic Style: a neo-grotesque, a strict grid, hairline rules, flush
// left, no ornament, and one colour, blue, used for what matters.
//
// Colours are tokens on :root, redefined for the dark theme, which follows
// the system unless the reader picked one.
// Inter, variable in weight and optical size, and JetBrains Mono; served
// from the site itself (see static/fonts/README.md).
@font-face {
font-family: "Inter";
src: url("fonts/InterVariable.woff2") format("woff2");
font-weight: 100 900;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "JetBrains Mono";
src: url("fonts/JetBrainsMono-Regular.woff2") format("woff2");
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "JetBrains Mono";
src: url("fonts/JetBrainsMono-Medium.woff2") format("woff2");
font-weight: 500 700;
font-style: normal;
font-display: swap;
}
:root {
color-scheme: light;
--bg: #ffffff;
--bg-tint: #f3f6fb; // code, the panels
--bg-hover: #eef2f9;
--ink: #0a1b33; // headings, the strong rules
--text: #26354d;
--muted: #687891;
--rule: #dce3ee;
--rule-strong: #0a1b33;
--blue: #1f45e0; // links, marks, the one colour
--blue-deep: #0b2fa8; // International Klein Blue, near enough
--blue-tint: #e9eefc;
--on-blue: #ffffff;
--signal: #d4372c; // caution, used once in a while
// Code.
--tok-comment: #8794a8;
--tok-string: #0b2fa8;
--tok-constant: #1f45e0;
--tok-tag: #0a1b33;
--tok-field: #43577a;
--tok-keyword: #0b2fa8;
--display: "Inter", "Helvetica Neue", Helvetica, Arial, sans-serif;
--sans: "Inter", "Helvetica Neue", Helvetica, Arial, sans-serif;
--mono: "JetBrains Mono", "SF Mono", ui-monospace, Menlo, Consolas, monospace;
--topbar: 56px;
--gutter: 32px;
}
@mixin dark {
color-scheme: dark;
--bg: #06101e;
--bg-tint: #0b1729;
--bg-hover: #0f1d33;
--ink: #f1f5fc;
--text: #c8d2e2;
--muted: #8291a9;
--rule: #18263b;
--rule-strong: #c8d2e2;
--blue: #7095ff;
--blue-deep: #2a4fe0;
--blue-tint: #0f2142;
--on-blue: #ffffff;
--signal: #ff6b5e;
--tok-comment: #5f6f88;
--tok-string: #9fb6ff;
--tok-constant: #7095ff;
--tok-tag: #f1f5fc;
--tok-field: #b4c1d6;
--tok-keyword: #9fb6ff;
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) { @include dark; }
}
:root[data-theme="dark"] { @include dark; }
// ---------------------------------------------------------------------------
// Base
*, *::before, *::after { box-sizing: border-box; }
html {
-webkit-text-size-adjust: 100%;
text-size-adjust: 100%;
scroll-padding-top: calc(var(--topbar) + 24px);
}
body {
margin: 0;
min-height: 100vh;
display: flex;
flex-direction: column;
background: var(--bg);
color: var(--text);
font: 15.5px/1.65 var(--sans);
font-feature-settings: "cv11", "ss01";
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
a { color: inherit; text-decoration: none; }
img, svg { display: block; }
.icon { flex: none; }
code, kbd, pre { font-family: var(--mono); }
button { font: inherit; color: inherit; }
::selection { background: var(--blue); color: var(--on-blue); }
:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.skip {
position: absolute;
left: 12px;
top: -48px;
z-index: 100;
padding: 8px 14px;
background: var(--blue);
color: var(--on-blue);
&:focus { top: 12px; }
}
kbd {
display: inline-flex;
align-items: center;
font-size: 11px;
line-height: 1;
padding: 3px 5px;
border: 1px solid var(--rule);
color: var(--muted);
}
// A small label in the monospace: section numbers and the like.
.eyebrow {
display: block;
margin: 0 0 12px;
font: 500 12px/1.4 var(--mono);
color: var(--blue);
}
// ---------------------------------------------------------------------------
// Top bar
.topbar {
position: sticky;
top: 0;
z-index: 40;
height: var(--topbar);
background: var(--bg);
border-bottom: 1px solid var(--rule-strong);
}
.topbar-inner {
height: 100%;
padding: 0 var(--gutter);
display: flex;
align-items: center;
gap: 40px;
}
.brand {
display: flex;
align-items: center;
gap: 10px;
font: 600 18px/1 var(--display);
letter-spacing: -0.02em;
color: var(--ink);
}
.brand-mark { width: 12px; height: 12px; background: var(--blue); }
.brand-version { font: 400 12px var(--mono); letter-spacing: 0; color: var(--muted); }
.topnav {
display: flex;
gap: 28px;
a {
font-size: 14px;
color: var(--muted);
&:hover { color: var(--ink); }
&[aria-current="page"] { color: var(--ink); }
}
}
.topbar-actions {
margin-left: auto;
display: flex;
align-items: center;
gap: 4px;
}
.search-button {
display: flex;
align-items: center;
gap: 10px;
width: 220px;
height: 34px;
padding: 0 8px 0 10px;
margin-right: 12px;
border: 1px solid var(--rule);
background: transparent;
color: var(--muted);
font-size: 13.5px;
cursor: pointer;
&:hover { border-color: var(--muted); }
.search-button-key { margin-left: auto; }
}
.icon-button {
display: inline-grid;
place-items: center;
width: 34px;
height: 34px;
border: 0;
background: transparent;
color: var(--muted);
cursor: pointer;
&:hover { color: var(--ink); }
}
.menu-button { display: none; margin-left: -8px; }
// The icon for the theme one would switch to.
.theme-icon-light { display: none; }
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) .theme-icon-light { display: block; }
:root:not([data-theme="light"]) .theme-icon-dark { display: none; }
}
:root[data-theme="dark"] .theme-icon-light { display: block; }
:root[data-theme="dark"] .theme-icon-dark { display: none; }
// ---------------------------------------------------------------------------
// Buttons and links
.button {
display: inline-flex;
align-items: center;
gap: 10px;
height: 46px;
padding: 0 22px;
font-size: 15px;
font-weight: 500;
border: 1px solid transparent;
cursor: pointer;
.icon { width: 16px; height: 16px; transition: transform 0.15s; }
&:hover .icon { transform: translateX(3px); }
}
.button-primary {
background: var(--blue-deep);
color: var(--on-blue);
&:hover { background: var(--ink); color: var(--bg); }
}
.button-ghost {
color: var(--ink);
border-color: var(--rule-strong);
background: transparent;
&:hover { background: var(--ink); color: var(--bg); }
}
.text-link {
display: inline-flex;
align-items: center;
gap: 6px;
font-weight: 500;
color: var(--blue);
.icon { width: 15px; height: 15px; transition: transform 0.15s; }
&:hover .icon { transform: translateX(3px); }
}
// ---------------------------------------------------------------------------
// The front page: a poster, then a datasheet, then numbered sections.
.layout-home main { flex: 1; }
.home-section {
padding: 0 var(--gutter);
border-top: 1px solid var(--rule-strong);
}
// A section's number and name on the left, its content on a grid to the
// right: the same two columns all the way down the page.
.home-grid {
display: grid;
grid-template-columns: 3fr 9fr;
gap: var(--gutter);
padding: 28px 0 96px;
}
.home-label {
font: 600 13px/1.4 var(--display);
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--ink);
.eyebrow { margin-bottom: 4px; }
}
.hero {
position: relative;
min-height: min(calc(100vh - var(--topbar)), 760px);
display: flex;
flex-direction: column;
color: #ffffff;
background: #0a0c10;
overflow: hidden;
}
// The photograph in its own colours, a little darker and calmer, with a
// shade on the left that keeps the text legible.
.hero-photo {
position: absolute;
inset: 0;
img {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
object-position: 60% 50%;
filter: saturate(0.85) brightness(0.8);
}
}
.hero-shade {
position: absolute;
inset: 0;
background: linear-gradient(90deg,
rgba(10, 12, 16, 0.92) 0%,
rgba(10, 12, 16, 0.78) 35%,
rgba(10, 12, 16, 0.35) 65%,
rgba(10, 12, 16, 0.05) 100%);
}
.hero-copy {
position: relative;
flex: 1;
display: flex;
flex-direction: column;
max-width: 820px;
padding: 96px var(--gutter) 40px;
.eyebrow { color: #c9d4ff; }
}
.hero-title {
margin: 0 0 32px;
font: 700 clamp(52px, 7vw, 100px)/0.96 var(--display);
letter-spacing: -0.05em;
color: #ffffff;
}
.hero-text {
max-width: 33em;
margin: 0 0 40px;
font-size: 19px;
line-height: 1.6;
color: #e3e9ff;
code { color: #ffffff; }
}
.hero-actions { display: flex; flex-wrap: wrap; gap: 12px; }
.hero-foot {
margin-top: auto;
padding-top: 48px;
font: 13px var(--mono);
color: #b8c7ff;
.prompt { color: #ffffff; margin-right: 8px; user-select: none; }
}
.hero-credit {
position: relative;
margin: 0;
padding: 0 var(--gutter) 20px;
text-align: right;
font: 11.5px var(--mono);
color: rgba(255, 255, 255, 0.7);
a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
a:hover { color: #ffffff; }
}
.button-light {
background: #ffffff;
color: var(--blue-deep);
&:hover { background: #dfe6ff; }
}
.button-outline-light {
color: #ffffff;
border-color: rgba(255, 255, 255, 0.75);
&:hover { background: #ffffff; color: #0a1b33; }
}
.spec {
margin: 0;
display: grid;
grid-template-columns: 1fr 1fr;
column-gap: var(--gutter);
div {
display: grid;
grid-template-columns: 11em 1fr;
gap: 16px;
padding: 13px 0;
border-bottom: 1px solid var(--rule);
font-size: 14.5px;
}
dt { color: var(--muted); }
dd { margin: 0; color: var(--ink); }
}
.features {
display: grid;
grid-template-columns: repeat(4, 1fr);
column-gap: var(--gutter);
row-gap: 48px;
}
.feature {
display: block;
padding-top: 14px;
border-top: 1px solid var(--rule-strong);
h3 {
margin: 10px 0 8px;
font: 600 17px/1.3 var(--display);
letter-spacing: -0.015em;
color: var(--ink);
}
p { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--muted); }
code { font-size: 0.9em; color: var(--text); }
.eyebrow { margin: 0; }
&:hover h3 { color: var(--blue); }
}
.phases, .checks {
list-style: none;
margin: 0 0 28px;
padding: 0;
display: grid;
grid-template-columns: repeat(4, 1fr);
column-gap: var(--gutter);
li {
display: flex;
gap: 14px;
padding: 10px 0;
border-bottom: 1px solid var(--rule);
font: 14px var(--mono);
color: var(--ink);
}
span { color: var(--muted); }
}
.home-note { max-width: 44em; margin: 0 0 20px; color: var(--text); }
.checks {
grid-template-columns: repeat(3, 1fr);
li { font-family: var(--sans); font-size: 15px; }
span { font: 13px var(--mono); color: var(--blue); }
}
.start {
display: grid;
grid-template-columns: 4fr 7fr;
gap: var(--gutter);
align-items: start;
pre {
margin: 0;
padding: 22px 24px;
background: var(--bg-tint);
font-size: 13px;
line-height: 1.8;
color: var(--ink);
overflow-x: auto;
}
.prompt { color: var(--blue); user-select: none; }
.comment { color: var(--tok-comment); }
p { margin: 0 0 24px; font-size: 17px; max-width: 30em; }
}
.not-found {
flex: 1;
padding: 120px var(--gutter);
h1 { margin: 0 0 16px; font: 700 64px/1 var(--display); letter-spacing: -0.045em; color: var(--ink); }
p { margin: 0 0 32px; font-size: 18px; max-width: 30em; }
}
// ---------------------------------------------------------------------------
// The documentation: contents, page, and what is on the page
.docs-layout {
flex: 1;
width: 100%;
display: grid;
grid-template-columns: 264px minmax(0, 1fr) 236px;
}
.sidebar {
position: sticky;
top: var(--topbar);
height: calc(100vh - var(--topbar));
overflow-y: auto;
padding: 32px 24px 48px var(--gutter);
border-right: 1px solid var(--rule);
scrollbar-width: thin;
}
.nav-group {
margin-bottom: 28px;
ul { list-style: none; margin: 0; padding: 0; }
li a {
position: relative;
display: block;
padding: 4px 0;
font-size: 14px;
color: var(--muted);
&:hover { color: var(--ink); }
&[aria-current="page"] {
color: var(--ink);
font-weight: 500;
&::before {
content: "";
position: absolute;
left: -16px;
top: 50%;
width: 7px;
height: 7px;
margin-top: -3.5px;
background: var(--blue);
}
}
}
}
.nav-group-title {
display: flex;
gap: 10px;
margin-bottom: 8px;
font: 600 12px/1.4 var(--display);
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--ink);
span { font: 500 11.5px var(--mono); letter-spacing: 0; color: var(--blue); }
&:hover, &[aria-current="page"] { color: var(--blue); }
}
.docs-main {
min-width: 0;
padding: 44px 64px 96px;
}
.toc-column { padding: 44px var(--gutter) 48px 0; }
.toc {
position: sticky;
top: calc(var(--topbar) + 44px);
max-height: calc(100vh - var(--topbar) - 88px);
overflow-y: auto;
font-size: 13px;
counter-reset: toc;
ul { list-style: none; margin: 0; padding: 0; }
ul ul { padding-left: 26px; }
> ul > li > a::before {
counter-increment: toc;
content: counter(toc, decimal-leading-zero);
display: inline-block;
width: 26px;
font: 11.5px var(--mono);
color: var(--muted);
}
a {
display: block;
padding: 4px 0;
color: var(--muted);
line-height: 1.45;
&:hover { color: var(--ink); }
&.active { color: var(--ink); }
&.active::before { color: var(--blue) !important; }
}
}
.toc-title {
margin: 0 0 12px;
font: 600 12px var(--display);
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--ink);
}
.page-header {
margin-bottom: 40px;
padding-bottom: 32px;
border-bottom: 1px solid var(--rule);
h1 {
margin: 0;
color: var(--ink);
font: 680 48px/1.02 var(--display);
letter-spacing: -0.04em;
}
.lead {
margin: 18px 0 0;
font-size: 19px;
line-height: 1.55;
color: var(--muted);
text-wrap: pretty;
}
}
// Text written in Markdown. Its second-level headings are numbered, as the
// contents beside them are.
.prose {
max-width: 760px;
font-size: 16px;
line-height: 1.72;
color: var(--text);
counter-reset: h2;
> :first-child { margin-top: 0; }
p, ul, ol, table, pre, blockquote, figure, details { margin: 0 0 1.3em; }
h2, h3, h4 {
color: var(--ink);
font-family: var(--display);
font-weight: 600;
text-wrap: balance;
a { color: inherit; text-decoration: none; }
}
h2 {
margin: 2.6em 0 0.8em;
padding-top: 14px;
border-top: 1px solid var(--rule-strong);
font-size: 26px;
line-height: 1.2;
letter-spacing: -0.03em;
&::before {
counter-increment: h2;
content: counter(h2, decimal-leading-zero);
display: block;
margin-bottom: 10px;
font: 500 12px var(--mono);
letter-spacing: 0;
color: var(--blue);
}
}
.page-header + h2 { margin-top: 0; }
h3 { margin: 2em 0 0.6em; font-size: 19px; letter-spacing: -0.02em; }
h4 { margin: 1.6em 0 0.5em; font-size: 16px; }
a:not(.card) {
color: var(--blue);
text-decoration: underline;
text-decoration-color: color-mix(in srgb, var(--blue) 35%, transparent);
text-decoration-thickness: 1px;
text-underline-offset: 3px;
&:hover { text-decoration-color: currentColor; }
}
// A heading is a link to itself, and looks like a heading.
:is(h2, h3, h4) a { color: inherit !important; text-decoration: none !important; }
strong { color: var(--ink); font-weight: 600; }
ul, ol { padding-left: 1.25em; }
li { margin: 0.35em 0; padding-left: 0.2em; }
ul > li::marker { content: "– "; color: var(--muted); }
ol > li::marker { font: 500 0.85em var(--mono); color: var(--blue); }
li > ul, li > ol { margin: 0.35em 0; }
hr { border: 0; border-top: 1px solid var(--rule); margin: 3em 0; }
:not(pre) > code {
padding: 0.12em 0.35em;
font-size: 0.85em;
color: var(--ink);
background: var(--bg-tint);
white-space: nowrap;
}
a code { color: inherit; }
blockquote {
padding: 0 0 0 20px;
border-left: 1px solid var(--rule-strong);
color: var(--muted);
}
table {
display: block;
width: max-content;
max-width: 100%;
overflow-x: auto;
border-collapse: collapse;
font-size: 14.5px;
line-height: 1.55;
}
th, td {
padding: 10px 20px 10px 0;
text-align: left;
vertical-align: top;
border-bottom: 1px solid var(--rule);
}
th {
padding-top: 0;
font: 600 11.5px/1.4 var(--display);
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--ink);
border-bottom-color: var(--rule-strong);
white-space: nowrap;
}
td code { white-space: normal; overflow-wrap: anywhere; }
td:first-child code { white-space: nowrap; overflow-wrap: normal; }
// The type of a configuration field, under its name.
td .type {
display: block;
margin-top: 4px;
font-size: 12.5px;
color: var(--muted);
white-space: nowrap;
}
details {
border-top: 1px solid var(--rule-strong);
padding: 12px 0;
summary { cursor: pointer; font-weight: 600; color: var(--ink); }
}
// A whole configuration file, with its name above it.
figure.example {
margin: 0 0 1.5em;
figcaption {
padding: 8px 0;
font: 12px var(--mono);
color: var(--muted);
border-top: 1px solid var(--rule-strong);
}
.code-block, pre { margin: 0 !important; }
}
figure.diagram {
padding: 0 0 8px;
border-top: 1px solid var(--rule-strong);
overflow-x: auto;
svg { margin: 24px 0 0; max-width: 100%; height: auto; }
figcaption { margin-top: 16px; font-size: 14px; color: var(--muted); max-width: 40em; }
.box { fill: var(--bg); stroke: var(--rule-strong); stroke-width: 1; }
.box-accent { fill: var(--blue-deep); stroke: var(--blue-deep); }
.t { fill: var(--ink); font: 600 14px var(--display); }
.s { fill: var(--muted); font: 12px var(--sans); }
.t.on-accent, .s.on-accent { fill: var(--on-blue); }
.edge { fill: none; stroke: var(--ink); stroke-width: 1; }
.edge-back { stroke: var(--blue); stroke-dasharray: 4 4; }
.head { fill: var(--ink); }
}
}
// Code blocks. The highlighter names each token; the colours are ours.
.prose pre {
position: relative;
padding: 18px 22px;
font-size: 13.5px;
line-height: 1.7;
color: var(--ink);
background: var(--bg-tint);
overflow-x: auto;
tab-size: 4;
scrollbar-width: thin;
code { display: block; min-width: max-content; }
}
.z-comment { color: var(--tok-comment); }
.z-string { color: var(--tok-string); }
.z-constant { color: var(--tok-constant); }
.z-keyword, .z-storage { color: var(--tok-keyword); font-weight: 500; }
.z-entity.z-name.z-tag, .z-entity.z-name { color: var(--tok-tag); font-weight: 500; }
.z-support, .z-variable { color: var(--tok-field); }
.z-punctuation.z-definition.z-comment { color: var(--tok-comment); }
.code-block {
position: relative;
margin: 0 0 1.3em;
pre { margin: 0 !important; }
&:hover .copy-button { opacity: 1; }
}
.copy-button {
position: absolute;
top: 8px;
right: 8px;
display: grid;
place-items: center;
width: 30px;
height: 30px;
border: 1px solid var(--rule);
background: var(--bg);
color: var(--muted);
cursor: pointer;
opacity: 0;
transition: opacity 0.15s;
&:hover { color: var(--ink); border-color: var(--muted); }
&:focus-visible { opacity: 1; }
&.copied { color: var(--blue); opacity: 1; }
.icon { width: 14px; height: 14px; }
}
@media (hover: none) { .copy-button { opacity: 1; } }
// > [!NOTE] and the like, which Zola writes as a blockquote with a class
// and no title: a rule above, the kind in capitals, the text.
.prose blockquote[class^="markdown-alert-"] {
--alert: var(--blue);
--alert-title: "Note";
padding: 12px 0 2px;
border: 0;
border-top: 2px solid var(--alert);
color: var(--text);
font-size: 15px;
> :last-child { margin-bottom: 0.6em; }
&::before {
content: var(--alert-title);
display: block;
margin-bottom: 4px;
font: 600 11.5px var(--display);
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--alert);
}
}
.prose blockquote.markdown-alert-tip { --alert-title: "Tip"; }
.prose blockquote.markdown-alert-important { --alert: var(--ink); --alert-title: "Important"; }
.prose blockquote.markdown-alert-warning { --alert: var(--signal); --alert-title: "Warning"; }
.prose blockquote.markdown-alert-caution { --alert: var(--signal); --alert-title: "Caution"; }
// The pages of a group, as a list with rules between.
.cards {
max-width: 760px;
margin-bottom: 48px;
border-top: 1px solid var(--rule-strong);
}
.card {
display: grid;
grid-template-columns: 3.6em 1fr;
gap: 4px 0;
padding: 16px 0;
border-bottom: 1px solid var(--rule);
&:hover .card-title { color: var(--blue); }
}
.card-number { font: 500 12px/1.9 var(--mono); color: var(--blue); grid-row: span 2; }
.card-title {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
font: 600 17px var(--display);
letter-spacing: -0.015em;
color: var(--ink);
.icon { width: 16px; height: 16px; color: var(--muted); }
}
.card-text { font-size: 14.5px; line-height: 1.55; color: var(--muted); }
.group-overview {
max-width: 760px;
margin-bottom: 24px;
h2 {
display: flex;
gap: 14px;
align-items: baseline;
margin: 0 0 6px;
font: 600 24px var(--display);
letter-spacing: -0.03em;
color: var(--ink);
span { font: 500 12px var(--mono); color: var(--blue); letter-spacing: 0; }
a:hover { color: var(--blue); }
}
> p { margin: 0 0 16px; color: var(--muted); }
}
.pager {
max-width: 760px;
margin-top: 72px;
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--gutter);
}
.pager-link {
display: flex;
flex-direction: column;
gap: 4px;
padding-top: 12px;
border-top: 1px solid var(--rule-strong);
&:hover .pager-title { color: var(--blue); }
}
.pager-next { text-align: right; grid-column: 2; }
.pager-label { font: 12px var(--mono); color: var(--muted); }
.pager-title { font: 600 18px var(--display); letter-spacing: -0.02em; color: var(--ink); }
.page-source {
max-width: 760px;
margin: 32px 0 0;
font-size: 13px;
a {
display: inline-flex;
align-items: center;
gap: 6px;
color: var(--muted);
&:hover { color: var(--ink); }
}
.icon { width: 14px; height: 14px; }
}
// ---------------------------------------------------------------------------
// Footer
.footer { border-top: 1px solid var(--rule-strong); }
.footer-inner {
padding: 24px var(--gutter);
display: grid;
grid-template-columns: 3fr 9fr;
gap: var(--gutter);
font-size: 13.5px;
color: var(--muted);
}
.footer-brand { display: flex; align-items: center; gap: 10px; color: var(--ink); font-weight: 500; }
.footer-links { display: flex; flex-wrap: wrap; gap: 28px; a:hover { color: var(--ink); } }
.footer-links span { margin-left: auto; }
// ---------------------------------------------------------------------------
// Search
.search {
position: fixed;
inset: 0;
z-index: 60;
display: flex;
justify-content: center;
align-items: flex-start;
padding: 12vh 16px 16px;
&[hidden] { display: none; }
}
.search-backdrop {
position: absolute;
inset: 0;
background: color-mix(in srgb, var(--ink) 30%, transparent);
animation: fade-in 0.12s ease;
}
.search-dialog {
position: relative;
width: 100%;
max-width: 640px;
max-height: 70vh;
display: flex;
flex-direction: column;
background: var(--bg);
border: 1px solid var(--rule-strong);
overflow: hidden;
animation: fade-in 0.12s ease;
}
.search-field {
display: flex;
align-items: center;
gap: 12px;
padding: 0 16px;
border-bottom: 1px solid var(--rule-strong);
color: var(--muted);
input {
flex: 1;
height: 56px;
border: 0;
outline: 0;
background: transparent;
color: var(--ink);
font: 17px var(--sans);
&::placeholder { color: var(--muted); }
&::-webkit-search-cancel-button { display: none; }
}
kbd { cursor: pointer; }
}
.search-results {
list-style: none;
margin: 0;
padding: 0;
overflow-y: auto;
&:empty { display: none; }
li { border-bottom: 1px solid var(--rule); }
a {
display: block;
padding: 12px 16px 12px 18px;
border-left: 3px solid transparent;
&:hover { background: var(--bg-hover); }
&[aria-selected="true"] { border-left-color: var(--blue); background: var(--blue-tint); }
&[aria-selected="true"] .search-result-title { color: var(--blue); }
}
}
.search-result-section { display: block; font: 11.5px var(--mono); color: var(--muted); margin-bottom: 2px; }
.search-result-title { display: block; font: 600 15.5px var(--display); color: var(--ink); }
.search-result-text {
display: -webkit-box;
margin-top: 3px;
font-size: 13.5px;
line-height: 1.5;
color: var(--muted);
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
mark { background: transparent; color: var(--ink); font-weight: 600; }
}
.search-empty { margin: 0; padding: 28px 18px; color: var(--muted); }
@keyframes fade-in { from { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after { animation: none !important; transition: none !important; }
}
// ---------------------------------------------------------------------------
// Narrower screens
@media (max-width: 1240px) {
.docs-layout { grid-template-columns: 248px minmax(0, 1fr); }
.toc-column { display: none; }
.docs-main { padding: 40px 48px 80px; }
.features { grid-template-columns: repeat(2, 1fr); }
.phases { grid-template-columns: repeat(3, 1fr); }
.checks { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 960px) {
:root { --gutter: 24px; }
.topnav { display: none; }
.menu-button { display: inline-grid; }
.search-button { width: auto; border: 0; margin-right: 0; }
.search-button-label, .search-button-key { display: none; }
.docs-layout { grid-template-columns: minmax(0, 1fr); }
.sidebar {
position: fixed;
top: var(--topbar);
left: 0;
bottom: 0;
z-index: 30;
width: min(320px, 86vw);
height: auto;
padding-left: 40px;
background: var(--bg);
border-right: 1px solid var(--rule-strong);
transform: translateX(-102%);
transition: transform 0.2s ease;
visibility: hidden;
}
body.menu-open .sidebar { transform: none; visibility: visible; }
body.menu-open::after {
content: "";
position: fixed;
inset: var(--topbar) 0 0 0;
z-index: 20;
background: color-mix(in srgb, var(--ink) 25%, transparent);
}
.docs-main { padding: 32px var(--gutter) 64px; }
.hero { min-height: 0; }
.hero-copy { padding: 64px var(--gutter) 32px; }
.hero-shade { background: linear-gradient(180deg, rgba(10, 12, 16, 0.7), rgba(10, 12, 16, 0.9)); }
.hero-credit { text-align: left; }
.home-grid { grid-template-columns: minmax(0, 1fr); gap: 20px; padding-bottom: 72px; }
.spec { grid-template-columns: minmax(0, 1fr); }
.start { grid-template-columns: minmax(0, 1fr); }
.footer-inner { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 640px) {
:root { --gutter: 16px; }
.topbar-inner { gap: 16px; }
.brand-version { display: none; }
.page-header h1 { font-size: 36px; }
.page-header .lead { font-size: 17px; }
.prose { font-size: 15.5px; }
.prose h2 { font-size: 22px; }
.prose pre { font-size: 12.5px; padding: 14px 16px; }
.hero-text { font-size: 17px; }
.spec div { grid-template-columns: 9em 1fr; }
.features { grid-template-columns: minmax(0, 1fr); row-gap: 32px; }
.phases { grid-template-columns: repeat(2, 1fr); }
.checks { grid-template-columns: minmax(0, 1fr); }
.pager { grid-template-columns: minmax(0, 1fr); }
.pager-next { grid-column: 1; }
}