From 9faaa2c9fed04f1c5fce25b143631c44c92fa9cf Mon Sep 17 00:00:00 2001
From: Derek Lewis
Date: Fri, 21 Aug 2026 02:03:42 +0000
Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=93=96=E2=9C=A8=EF=BC=9Agive=20the=20?=
=?UTF-8?q?docs=20an=20index?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The page at /docs/ was five paragraphs of Latin, and the home page
links to it. Thirteen real pages already published underneath it,
reachable only by knowing the URL.
Every handbook page carries a `key_point`: one sentence stating the
rule it makes. Nothing rendered it. The include that would have,
`key-point.liquid`, is called from a layout no page uses. So the index
puts each rule beside its name and most lookups end here rather than a
page in.
Five of the nine handbook pages are placeholders. The index says which,
and how many, because on a community site a gap that is named is a job
somebody can pick up. The count and the flags are read from the same
collection the list is built from, so they cannot disagree with it.
Both groups come from collections rather than a typed list. A doc
appears by existing, and the four mirrored from OpenINF/.github carry
their summaries in the task that generates them, so a regeneration does
not drop them.
The Edit link on every page under /docs/ pointed at OpenINF/open.inf.is,
which does not exist. Pages can now also set their own `description`,
which the whole site had been filling with one site-wide sentence.
Signed-off-by: Derek Lewis
Assisted-by: Claude-Code:claude-opus-5
Assisted-by: Claude-Code:claude-fable-5
---
_assets/styles/_custom.scss | 6 +
_assets/styles/_docs.scss | 409 ++++++++++++++++++
_assets/styles/main.scss | 1 +
_includes/head.liquid | 2 +-
_layouts/docs.liquid | 2 +-
build/tasks/compile/siteify-health-files.mts | 12 +
collections/_docs/code-of-conduct.md | 4 +
collections/_docs/contributing.md | 4 +
.../_docs/handbook/style/capitalization.md | 1 +
.../_docs/handbook/style/code-in-text.md | 1 +
.../_docs/handbook/style/code-samples.md | 1 +
collections/_docs/handbook/style/dashes.md | 1 +
collections/_docs/handbook/style/lists.md | 1 +
.../style/people-person-first-language.md | 8 +
collections/_docs/security.md | 2 +
collections/_docs/support.md | 2 +
collections/_pages/docs.html | 208 ++++++---
collections/_pages/home.html | 3 +-
eleventy.config.mjs | 18 +
19 files changed, 627 insertions(+), 59 deletions(-)
create mode 100644 _assets/styles/_docs.scss
diff --git a/_assets/styles/_custom.scss b/_assets/styles/_custom.scss
index 8a086d7d2..3f172d146 100644
--- a/_assets/styles/_custom.scss
+++ b/_assets/styles/_custom.scss
@@ -1,5 +1,11 @@
// Custom Styles
+// The navbar is fixed, so an anchor lands behind it without this. The extra
+// room keeps the target clear of the bar rather than flush against it.
+html {
+ scroll-padding-top: calc(#{$navbar-height} + 1rem);
+}
+
main {
min-height: 100%;
}
diff --git a/_assets/styles/_docs.scss b/_assets/styles/_docs.scss
new file mode 100644
index 000000000..c1d99b9f3
--- /dev/null
+++ b/_assets/styles/_docs.scss
@@ -0,0 +1,409 @@
+@use 'sass:color';
+
+// The docs index: what is written, and what is still open.
+
+// Family resemblance with _home.scss is deliberate throughout: the same
+// $docs-wrap/$docs-gutter proportions, the same ink band offset under the
+// fixed navbar, the same translucent-on-ink aside box for the page's one
+// call to act. This page still reads a size class quieter than the home
+// page -- it is the second door, not the front one -- and spends its one
+// bold gesture on a single computed number rather than on a graphic.
+
+// Colours come from the Sass variables in _sublime-theme.scss rather than
+// from custom properties scoped to `.home`, matching this file's own prior
+// convention. $docs-muted reuses the literal tone _home.scss repeats for
+// secondary copy (#4b433c) rather than re-deriving a slightly different one
+// from $tertiary, so the two pages read as the same ink at a glance.
+
+// Every contrast pair below is a foreground/background this file actually
+// paints, verified against the true composited colour (translucent ink
+// overlays included), not the nominal one:
+// ink / parchment 13.97:1
+// ink / band-quiet 12.77:1
+// $docs-link / parchment 5.34:1
+// $docs-link / band-quiet 4.88:1
+// $docs-muted / parchment 7.75:1
+// $docs-muted / band-quiet 7.09:1
+// $docs-flag-text / $docs-flag-bg 6.91:1
+// parchment (solid) / ink 13.97:1
+// $docs-primary-tint / ink 6.57:1
+// $docs-primary-tint / .invite's own bg 6.01:1
+// tertiary (solid) / ink 6.19:1
+// parchment @70% / ink 7.37:1
+
+$docs-wrap: 1200px;
+$docs-gutter: clamp(1rem, 4vw, 3rem);
+$docs-link: shade-color($primary, 25%);
+$docs-primary-tint: tint-color($primary, 30%);
+$docs-muted: #4b433c;
+$docs-hairline: rgb(167 151 139 / 55%);
+
+// A pale wash of $quaternary with its own deep-shade text, rather than
+// $quaternary as a solid fill: solid $quaternary under $body-bg text (what
+// `.tag-soon` uses on the home page) measures 4.33:1, under the 4.5:1 floor
+// for text this size. This pairing keeps the same "not yet" hue and clears
+// AA with room to spare.
+$docs-flag-bg: tint-color($quaternary, 88%);
+$docs-flag-text: shade-color($quaternary, 25%);
+
+// Scoped to `main` so the page's resets stay inside the page and leave the
+// navbar and footer to the rest of the site. `.docs a` or `.docs
+// :focus-visible` would also match the navbar -- it is `main`'s sibling
+// under the same body class -- which is exactly how the navbar went teal
+// and lost its focus ring before. The footer's negative top margin is
+// absorbed elsewhere by the padding on `main > .container`; there is no
+// such container here, so the room is taken directly.
+.docs main {
+ padding-bottom: 104px;
+}
+
+.docs main h1,
+.docs main h2,
+.docs main p,
+.docs main dl,
+.docs main dd,
+.docs main ul {
+ margin: 0;
+}
+
+.docs main ul {
+ padding: 0;
+ list-style: none;
+}
+
+.docs main a {
+ color: $docs-link;
+}
+
+.docs main :focus-visible {
+ outline: 2px solid $body-color;
+ outline-offset: 2px;
+}
+
+.docs .wrap {
+ max-width: $docs-wrap;
+ padding-inline: $docs-gutter;
+ margin-inline: auto;
+}
+
+/* --- Head -------------------------------------------------------------- */
+
+// Ink, so it carries on from the navbar above it rather than letting the
+// body's parchment show as a pale band between the two. Shorter than the
+// home page's masthead and without its ring graphic -- this is the second
+// door, not the front one -- so the one flourish here is the numeral in
+// `.invite`, not a second motif competing with it.
+.docs-head {
+ padding-top: calc(#{$navbar-height} + clamp(2rem, 5vw, 3.5rem));
+ padding-bottom: clamp(2.25rem, 5vw, 3.5rem);
+ color: $body-bg;
+ background-color: $body-color;
+}
+
+.docs-head :focus-visible {
+ outline-color: $body-bg;
+}
+
+.docs-head-grid {
+ display: grid;
+ grid-template-columns: minmax(0, 1.4fr) minmax(0, 0.85fr);
+ gap: clamp(2rem, 5vw, 4rem);
+ align-items: start;
+}
+
+// _custom.scss makes every h1 a flex row and draws a rule after it, which
+// suits a plain page heading (see every handbook page's title) and is
+// wrong beside a two-column grid: the rule would run only to this column's
+// edge, reading as an accidental underline against `.invite` rather than a
+// deliberate one.
+.docs-title {
+ display: block;
+ font-size: clamp(1.875rem, 4.5vw, 2.75rem);
+ font-weight: 700;
+ line-height: 1.08;
+ letter-spacing: -0.02em;
+}
+
+.docs-title::after {
+ content: none;
+}
+
+.docs-lede {
+ max-width: 42ch;
+ margin-top: 1rem !important;
+ font-size: clamp(1rem, 1.6vw, 1.0625rem);
+ line-height: 1.6;
+ color: rgb(231 231 214 / 76%);
+}
+
+/* --- Head: the invite -----------------------------------------------
+ Same shape as `.join` on the home page -- a labelled box, a headline
+ statement, a closing line with a link -- carrying this page's own content
+ instead: the handbook's own gap, not a repeat of the home page's Discord
+ invite. A visitor who wants Discord already saw it one click back; a
+ visitor reading the docs is closer to being able to act on this one. Both
+ branches below read from the same count the full list further down is
+ built from, so the two can never disagree.
+*/
+
+.invite {
+ padding: 1.25rem 1.375rem;
+ background-color: rgb(231 231 214 / 4%);
+ border: 1px solid rgb(231 231 214 / 20%);
+}
+
+.invite-eyebrow {
+ font-family: $font-family-monospace;
+ font-size: 0.6875rem;
+ color: $tertiary;
+ text-transform: uppercase;
+ letter-spacing: 0.08em;
+}
+
+.invite-title {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+ align-items: baseline;
+ margin-top: 0.625rem !important;
+ font-size: 1.1875rem;
+ font-weight: 700;
+ line-height: 1.3;
+ color: $body-bg;
+}
+
+.invite-num {
+ font-family: $font-family-monospace;
+ font-size: clamp(2.25rem, 5vw, 2.75rem);
+ line-height: 0.9;
+ color: $docs-primary-tint;
+}
+
+.invite-what {
+ margin-top: 0.75rem !important;
+ font-size: 0.9375rem;
+ line-height: 1.6;
+ color: rgb(231 231 214 / 70%);
+}
+
+.invite-row {
+ padding-top: 0.875rem;
+ margin-top: 1rem !important;
+ border-top: 1px solid rgb(231 231 214 / 16%);
+}
+
+.invite-row a {
+ font-weight: 700;
+ color: $docs-primary-tint;
+}
+
+/* --- Shared section furniture ------------------------------------------ */
+
+.docs .band {
+ padding-block: clamp(2.5rem, 6vw, 4rem);
+}
+
+// The handbook is the substance of this page, so it sits on its own
+// ground.
+.docs .band-quiet {
+ background-color: color.mix($tertiary, $body-bg, 12%);
+ border-block: 1px solid $docs-hairline;
+}
+
+.docs .section-head {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem 1rem;
+ align-items: baseline;
+ justify-content: space-between;
+ padding-bottom: 0.75rem;
+ border-bottom: 2px solid $body-color;
+}
+
+.docs .section-title {
+ font-size: 1.125rem;
+ font-weight: 700;
+ letter-spacing: -0.01em;
+}
+
+.docs .section-more {
+ font-family: $font-family-monospace;
+ font-size: 0.8125rem;
+}
+
+.docs .section-count {
+ font-family: $font-family-monospace;
+ font-size: 0.8125rem;
+ color: $docs-muted;
+ text-transform: uppercase;
+ letter-spacing: 0.06em;
+}
+
+/* --- Taking part --------------------------------------------------------
+ A plain divided list, not a numbered tile grid: these four are process
+ and community links, the same kind of thing as the home page's own
+ "How we work" list, not a catalogue of product areas. The numbered-tile
+ treatment stays reserved for the SDK's package areas on the home page,
+ so the two forms keep meaning something different from each other.
+*/
+
+.docs .part-list {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 0 clamp(1.5rem, 4vw, 3rem);
+ margin-top: 1.75rem !important;
+}
+
+.docs .part-item {
+ padding-block: 1.375rem;
+ border-bottom: 1px solid $docs-hairline;
+}
+
+.docs .part-name {
+ font-size: 1.0625rem;
+ font-weight: 700;
+}
+
+.docs .part-what {
+ margin-top: 0.375rem !important;
+ font-size: 0.9375rem;
+ line-height: 1.6;
+ color: $docs-muted;
+}
+
+/* --- The handbook -------------------------------------------------------
+ Alphabetical, one row per rule, name and point side by side so the column
+ of names reads as an index and the point sits where the eye lands after
+ it. The index numeral borrows `.area-num`'s exact recipe from the home
+ page (mono, small, the same teal); a reference list earns the numbering a
+ catalogue-style tile grid would not, because unlike "Taking part" this
+ one really is consulted the way an index is: by looking something up.
+*/
+
+.docs .handbook-lede {
+ max-width: 60ch;
+ margin-top: 1.25rem !important;
+ font-size: 0.9375rem;
+ line-height: 1.65;
+ color: $docs-muted;
+}
+
+.docs .rule-list {
+ margin-top: 1.75rem !important;
+}
+
+.docs .rule {
+ display: grid;
+ grid-template-columns: minmax(0, 19rem) minmax(0, 1fr);
+ gap: 0.25rem 2rem;
+ padding-block: 0.875rem;
+ border-bottom: 1px solid rgb(167 151 139 / 35%);
+}
+
+.docs .rule:first-child {
+ border-top: 1px solid rgb(167 151 139 / 35%);
+}
+
+// A grid, not one flex-wrap row: the numeral has to stay in its own
+// column so it stays pinned beside the first line of the title rather
+// than wrapping away with it. "Documenting Command-Line Syntax" and
+// "Prefer People/Person-First Language When Appropriate" are long enough
+// to wrap on their own regardless -- the numeral should not follow them.
+.docs .rule-name {
+ display: grid;
+ grid-template-columns: 1.375rem minmax(0, 1fr);
+ gap: 0.5rem;
+ align-items: baseline;
+ font-size: 0.9375rem;
+ font-weight: 700;
+}
+
+.docs .rule-num {
+ font-family: $font-family-monospace;
+ font-size: 0.75rem;
+ font-weight: 400;
+ color: $docs-link;
+}
+
+.docs .rule-heading {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+ align-items: baseline;
+}
+
+.docs .rule-point {
+ font-size: 0.9375rem;
+ line-height: 1.6;
+}
+
+// Unwritten pages are marked by this chip alone -- text, not colour alone,
+// so the state does not rest on the wash of colour behind it. The point
+// beside it stays at full weight and full contrast in every row: the rule
+// is exactly as real on a page that is not written yet.
+.docs .rule-flag {
+ padding: 0.0625rem 0.4375rem;
+ font-family: $font-family-monospace;
+ font-size: 0.6875rem;
+ font-weight: 400;
+ color: $docs-flag-text;
+ text-transform: uppercase;
+ letter-spacing: 0.06em;
+ background-color: $docs-flag-bg;
+}
+
+.docs .handbook-gap {
+ max-width: 60ch;
+ margin-top: 1.5rem !important;
+ font-size: 0.9375rem;
+ line-height: 1.65;
+ color: $docs-muted;
+}
+
+/* --- Not here yet --------------------------------------------------------
+ Quieter than the two sections above on purpose: its whole point is that
+ there is not much to say yet, and a heading the same size as "Taking
+ part" would promise a third pillar this page does not have.
+*/
+
+.docs .band-tail {
+ padding-block: clamp(1.5rem, 3vw, 2rem);
+}
+
+.docs .tail-title {
+ font-family: $font-family-monospace;
+ font-size: 0.75rem;
+ font-weight: 700;
+ color: $docs-muted;
+ text-transform: uppercase;
+ letter-spacing: 0.08em;
+}
+
+.docs .tail-what {
+ max-width: 60ch;
+ margin-top: 0.625rem !important;
+ font-size: 0.9375rem;
+ line-height: 1.65;
+ color: $docs-muted;
+}
+
+/* --- Narrow -------------------------------------------------------------- */
+
+@media (width < 960px) {
+ .docs-head-grid {
+ grid-template-columns: minmax(0, 1fr);
+ }
+}
+
+@media (width < 760px) {
+ .docs .part-list {
+ grid-template-columns: minmax(0, 1fr);
+ }
+
+ // The name column stops earning its width once the point beside it
+ // wraps to three or four lines.
+ .docs .rule {
+ grid-template-columns: minmax(0, 1fr);
+ gap: 0.375rem;
+ }
+}
diff --git a/_assets/styles/main.scss b/_assets/styles/main.scss
index 820029fcd..dcb19855f 100644
--- a/_assets/styles/main.scss
+++ b/_assets/styles/main.scss
@@ -16,6 +16,7 @@
@import '../../node_modules/bootstrap/scss/nav';
@import '../../node_modules/bootstrap/scss/navbar';
@import '../../node_modules/bootstrap/scss/pagination';
+@import 'docs';
@import 'error';
@import 'home';
@import 'nav';
diff --git a/_includes/head.liquid b/_includes/head.liquid
index c2c99f717..95756fbbe 100644
--- a/_includes/head.liquid
+++ b/_includes/head.liquid
@@ -14,7 +14,7 @@
>
{% if status == 'unpublished' %}
diff --git a/_layouts/docs.liquid b/_layouts/docs.liquid
index f302652c0..48b01246c 100644
--- a/_layouts/docs.liquid
+++ b/_layouts/docs.liquid
@@ -9,7 +9,7 @@ body_classes:
{% if editable != false %}
diff --git a/build/tasks/compile/siteify-health-files.mts b/build/tasks/compile/siteify-health-files.mts
index c9b5f4c71..7e3701e29 100644
--- a/build/tasks/compile/siteify-health-files.mts
+++ b/build/tasks/compile/siteify-health-files.mts
@@ -114,18 +114,28 @@ for (const value of healthFiles) {
case 'CODE_OF_CONDUCT.md':
siteifyFile(value, 'collections/_docs', {
title: 'OpenINF Code of Conduct',
+ description:
+ 'Respect people, their identities, their culture, and their work. ' +
+ 'Listen before responding.',
+ order: 2,
editable: false,
});
break;
case 'CONTRIBUTING.md':
siteifyFile(value, 'collections/_docs', {
title: 'Contributing to OpenINF',
+ description:
+ 'How issues get claimed, what makes a pull request easy to merge, ' +
+ 'and the sign-off every contribution carries.',
+ order: 1,
permalink: '/docs/dev/internals/contributing/',
});
break;
case 'SECURITY.md': {
siteifyFile(value, 'collections/_docs', {
title: 'OpenINF Security Policies',
+ description: 'How to report a vulnerability privately.',
+ order: 4,
permalink: '/docs/dev/internals/security/',
});
break;
@@ -133,6 +143,8 @@ for (const value of healthFiles) {
case 'SUPPORT.md':
siteifyFile(value, 'collections/_docs', {
title: 'Support • Frequently Asked Questions',
+ description: 'Where to ask, in the order worth trying.',
+ order: 3,
permalink: '/docs/dev/faq/support/',
});
break;
diff --git a/collections/_docs/code-of-conduct.md b/collections/_docs/code-of-conduct.md
index 56b8ce0c2..15f9c155c 100644
--- a/collections/_docs/code-of-conduct.md
+++ b/collections/_docs/code-of-conduct.md
@@ -2,6 +2,10 @@
title: OpenINF Code of Conduct
permalink: /docs/code-of-conduct/
note: This file is autogenerated. Edit CODE_OF_CONDUCT.md instead.
+description: >-
+ Respect people, their identities, their culture, and their work. Listen before
+ responding.
+order: 2
editable: false
---
diff --git a/collections/_docs/contributing.md b/collections/_docs/contributing.md
index 0849b20fb..efca54e02 100644
--- a/collections/_docs/contributing.md
+++ b/collections/_docs/contributing.md
@@ -2,6 +2,10 @@
title: Contributing to OpenINF
permalink: /docs/dev/internals/contributing/
note: This file is autogenerated. Edit CONTRIBUTING.md instead.
+description: >-
+ How issues get claimed, what makes a pull request easy to merge, and the
+ sign-off every contribution carries.
+order: 1
---
Want to contribute? Great! First, read this document, which is a set of
diff --git a/collections/_docs/handbook/style/capitalization.md b/collections/_docs/handbook/style/capitalization.md
index e243bf858..0a5d60fff 100644
--- a/collections/_docs/handbook/style/capitalization.md
+++ b/collections/_docs/handbook/style/capitalization.md
@@ -1,6 +1,7 @@
---
title: Capitalization
key_point: When to capitalize, and when to leave a word lowercase.
+stub: true
---
> [!NOTE]\
diff --git a/collections/_docs/handbook/style/code-in-text.md b/collections/_docs/handbook/style/code-in-text.md
index 4511d7d90..3f9268546 100644
--- a/collections/_docs/handbook/style/code-in-text.md
+++ b/collections/_docs/handbook/style/code-in-text.md
@@ -1,6 +1,7 @@
---
title: Code in Text
key_point: What to set in code font, and how to explain placeholders.
+stub: true
---
> [!NOTE]\
diff --git a/collections/_docs/handbook/style/code-samples.md b/collections/_docs/handbook/style/code-samples.md
index 5c5070dd6..d4b0449dc 100644
--- a/collections/_docs/handbook/style/code-samples.md
+++ b/collections/_docs/handbook/style/code-samples.md
@@ -1,6 +1,7 @@
---
title: Code Samples
key_point: How to introduce and present a code sample.
+stub: true
---
> [!NOTE]\
diff --git a/collections/_docs/handbook/style/dashes.md b/collections/_docs/handbook/style/dashes.md
index fc21dd634..3cb6664bf 100644
--- a/collections/_docs/handbook/style/dashes.md
+++ b/collections/_docs/handbook/style/dashes.md
@@ -1,6 +1,7 @@
---
title: Dashes
key_point: Which dash to use, and how it differs from a colon.
+stub: true
---
> [!NOTE]\
diff --git a/collections/_docs/handbook/style/lists.md b/collections/_docs/handbook/style/lists.md
index 6e6fd0f75..2817ff974 100644
--- a/collections/_docs/handbook/style/lists.md
+++ b/collections/_docs/handbook/style/lists.md
@@ -1,6 +1,7 @@
---
title: Lists
key_point: How to introduce and punctuate lists.
+stub: true
---
> [!NOTE]\
diff --git a/collections/_docs/handbook/style/people-person-first-language.md b/collections/_docs/handbook/style/people-person-first-language.md
index bd88d4ad2..536c80c82 100644
--- a/collections/_docs/handbook/style/people-person-first-language.md
+++ b/collections/_docs/handbook/style/people-person-first-language.md
@@ -1,7 +1,15 @@
---
title: Prefer People/Person-First Language When Appropriate
+key_point:
+ Follow the community's own preference between person-first and identity-first
+ language.
+stub: true
---
+> [!NOTE]\
+> This page is a placeholder. The rule below stands; the guidance that would
+> follow it is yet to be written.
+
As linguistic prescription: prefer person-first language when the community
prefers referring to themselves as person-first.
diff --git a/collections/_docs/security.md b/collections/_docs/security.md
index da68bc48b..8fbb6784d 100644
--- a/collections/_docs/security.md
+++ b/collections/_docs/security.md
@@ -2,6 +2,8 @@
title: OpenINF Security Policies
permalink: /docs/dev/internals/security/
note: This file is autogenerated. Edit SECURITY.md instead.
+description: How to report a vulnerability privately.
+order: 4
---
The OpenINF SDK team, now benefitting from [dual Maintainership][], takes the
diff --git a/collections/_docs/support.md b/collections/_docs/support.md
index c8b4cbbb7..869b33fb5 100644
--- a/collections/_docs/support.md
+++ b/collections/_docs/support.md
@@ -2,6 +2,8 @@
title: Support • Frequently Asked Questions
permalink: /docs/dev/faq/support/
note: This file is autogenerated. Edit SUPPORT.md instead.
+description: Where to ask, in the order worth trying.
+order: 3
---
Having trouble? Please consult these official resources in order of appearance.
diff --git a/collections/_pages/docs.html b/collections/_pages/docs.html
index 418d46442..fe9667626 100644
--- a/collections/_pages/docs.html
+++ b/collections/_pages/docs.html
@@ -1,60 +1,158 @@
---
title: Docs
-body_classes:
- - docs
+layout: default
permalink: /docs/
-custom_css:
+description:
+ How to take part in OpenINF, and the house style the work is written in.
+body_classes:
- docs
+eleventyImport:
+ collections: ['handbook', 'communityDocs']
---
-
- Lorem ipsum odor amet, consectetuer adipiscing elit. Leo vestibulum sagittis
- ornare ante himenaeos integer urna. Etiam ullamcorper malesuada nisl tortor
- ligula nulla habitasse hendrerit porta. Integer elit facilisi lacus;
- adipiscing rutrum metus praesent. Dapibus montes convallis sed blandit
- pharetra, tortor tellus commodo. Dis augue quisque et, ante aenean nisl.
- Habitasse morbi interdum leo netus finibus ad maximus dignissim sociosqu?
- Ullamcorper augue facilisi sapien class quam; eget commodo quisque. Porta
- ligula porttitor cubilia nulla sem at posuere praesent et. Ex morbi curabitur
- nisi consequat natoque.
-
-
-
- Venenatis efficitur ullamcorper cubilia; gravida fermentum placerat. Eu
- suscipit accumsan lacus; orci hac posuere nisi netus per. Fames fames
- porttitor inceptos sit congue placerat mollis egestas ornare. Eros odio semper
- maecenas habitasse senectus arcu. Cubilia nostra rhoncus aliquam viverra
- mollis interdum? Auctor velit mus et ullamcorper ligula phasellus. Himenaeos
- fringilla tempor porta sem pharetra. Adipiscing cras laoreet hac adipiscing
- cras integer at mus orci.
-
-
-
- Tortor sociosqu purus adipiscing lectus lacus lacus libero nisl. Primis proin
- vehicula sapien massa, commodo sociosqu massa quam. Tempus non ornare ad
- euismod maximus, tincidunt eu augue. Sodales nostra habitant himenaeos cubilia
- mauris nec donec in. Nisi dictum risus rhoncus convallis pharetra commodo
- porta cubilia. Aa eleifend sagittis dolor duis. Venenatis dolor ornare felis
- mus finibus interdum sagittis. Egestas semper dictum risus pellentesque
- litora? Potenti ac augue morbi natoque sem nam elementum vel.
-
-
-
- Eu gravida aptent laoreet bibendum vulputate aliquam ad massa maximus. Ac
- mauris blandit fermentum nibh integer vehicula. Sapien turpis per tempus
- hendrerit fusce nascetur egestas risus. Interdum fames pretium; viverra
- parturient elit dui. Odio praesent parturient eu odio potenti, ad hac ad. Sem
- ultrices neque donec a nullam nibh! Malesuada primis nec urna cras netus elit
- litora elementum eu. Hac vivamus ultrices ridiculus; dictum magnis donec enim.
- Cubilia fermentum in condimentum torquent integer iaculis. Arcu nulla lobortis
- massa tempus metus nullam.
-
-
-
- Placerat venenatis nullam consectetur orci nunc mus. Penatibus nibh ornare,
- lobortis quam et dui inceptos nec. Donec litora id quis cras montes.
- Condimentum tortor vestibulum id hendrerit lectus cubilia eros pretium sit.
- Nullam odio netus nostra integer integer? Phasellus sociosqu morbi consequat
- cubilia urna erat velit dis ad. Arcu tincidunt condimentum pellentesque
- dapibus sagittis magnis suspendisse dignissim urna. Mus duis non vitae mus
- libero bibendum.
-
+ {{ written_count }} of {{ handbook_total }} written
+
+
+
+
+ The house style our documentation and commit messages follow. One rule
+ to a page, and the rule is below, so most of the time you need not open
+ the page at all.
+
+ The unwritten pages hold a title and the rule they mean to make, and
+ nothing else yet. Each is a small, self-contained thing to pick up.
+ How to contribute.
+
+ {%- endif %}
+
+
+
+
+
+
+
Not here yet
+
+ The OpenINF SDK arrives in Q4 2026, and its reference documentation
+ arrives with it.
+ Progress shows up in the news.
+
The house style our documentation and commit messages follow.
diff --git a/eleventy.config.mjs b/eleventy.config.mjs
index 8c0057c55..97a446bd1 100644
--- a/eleventy.config.mjs
+++ b/eleventy.config.mjs
@@ -129,6 +129,24 @@ export default async function (eleventyConfig) {
);
});
+ // The index at /docs/ shows these two groups, so they arrive as two
+ // collections rather than one the template has to sort back out. Reference
+ // is read by looking things up, so the handbook goes alphabetical; the
+ // community docs keep the reading order their `order` sets, and a doc
+ // without one stays off the index until somebody places it.
+ eleventyConfig.addCollection('handbook', (collectionApi) => {
+ return collectionApi
+ .getFilteredByGlob('collections/_docs/handbook/**/*.md')
+ .sort((a, b) => a.data.title.localeCompare(b.data.title));
+ });
+
+ eleventyConfig.addCollection('communityDocs', (collectionApi) => {
+ return collectionApi
+ .getFilteredByGlob('collections/_docs/*.md')
+ .filter((doc) => typeof doc.data.order === 'number')
+ .sort((a, b) => a.data.order - b.data.order);
+ });
+
eleventyConfig.addPlugin(EleventyI18nPlugin, {
// Any valid BCP 47-compatible language tag is supported.
defaultLanguage: 'en', // required
From a10c29cd1715b4fec3857f1b476834372d163100 Mon Sep 17 00:00:00 2001
From: Derek Lewis
Date: Fri, 21 Aug 2026 02:30:42 +0000
Subject: [PATCH 2/2] =?UTF-8?q?=E2=99=BF=F0=9F=94=A7=EF=BC=9Alift=20the=20?=
=?UTF-8?q?links=20on=20the=20ink=20bands=20off=20the=20ink?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The masthead's own rules had the right colours all along: parchment for
the GitHub row, parchment at 82% for the line about the Code of Conduct.
Neither reached the page. `.home main a` is (0,1,2) and carries the deep
teal meant for links on parchment; a rule naming only the row it styles
is (0,1,1) and loses to it. On the ink that teal reads 2.62:1, the same
number and the same cause as the navbar links.
The band now sets a legible colour for any link inside it, and the rules
that differ from it carry `main` too, so a link added to the masthead
later starts readable rather than starting at 2.62:1.
The docs page had it in `.invite`, where the link now takes the mono and
the parchment `.join-row` gives the home page's equivalent link, both
boxes being the same box. 13.97:1, 9.72:1, and 12.78:1.
Signed-off-by: Derek Lewis
Assisted-by: Claude-Code:claude-opus-5
---
_assets/styles/_docs.scss | 121 ++++++++++-------------------------
_assets/styles/_home.scss | 11 +++-
collections/_pages/docs.html | 28 +++-----
eleventy.config.mjs | 8 +--
4 files changed, 57 insertions(+), 111 deletions(-)
diff --git a/_assets/styles/_docs.scss b/_assets/styles/_docs.scss
index c1d99b9f3..abe00f8f6 100644
--- a/_assets/styles/_docs.scss
+++ b/_assets/styles/_docs.scss
@@ -2,34 +2,10 @@
// The docs index: what is written, and what is still open.
-// Family resemblance with _home.scss is deliberate throughout: the same
-// $docs-wrap/$docs-gutter proportions, the same ink band offset under the
-// fixed navbar, the same translucent-on-ink aside box for the page's one
-// call to act. This page still reads a size class quieter than the home
-// page -- it is the second door, not the front one -- and spends its one
-// bold gesture on a single computed number rather than on a graphic.
-
-// Colours come from the Sass variables in _sublime-theme.scss rather than
-// from custom properties scoped to `.home`, matching this file's own prior
-// convention. $docs-muted reuses the literal tone _home.scss repeats for
-// secondary copy (#4b433c) rather than re-deriving a slightly different one
-// from $tertiary, so the two pages read as the same ink at a glance.
-
-// Every contrast pair below is a foreground/background this file actually
-// paints, verified against the true composited colour (translucent ink
-// overlays included), not the nominal one:
-// ink / parchment 13.97:1
-// ink / band-quiet 12.77:1
-// $docs-link / parchment 5.34:1
-// $docs-link / band-quiet 4.88:1
-// $docs-muted / parchment 7.75:1
-// $docs-muted / band-quiet 7.09:1
-// $docs-flag-text / $docs-flag-bg 6.91:1
-// parchment (solid) / ink 13.97:1
-// $docs-primary-tint / ink 6.57:1
-// $docs-primary-tint / .invite's own bg 6.01:1
-// tertiary (solid) / ink 6.19:1
-// parchment @70% / ink 7.37:1
+// This page reads wider than the 48ch column the rest of the site uses, so it
+// sets its own width and its own offset under the fixed navbar. Colours come
+// from _sublime-theme.scss; $docs-muted is the tone _home.scss gives secondary
+// copy, so the two pages read alike.
$docs-wrap: 1200px;
$docs-gutter: clamp(1rem, 4vw, 3rem);
@@ -38,21 +14,13 @@ $docs-primary-tint: tint-color($primary, 30%);
$docs-muted: #4b433c;
$docs-hairline: rgb(167 151 139 / 55%);
-// A pale wash of $quaternary with its own deep-shade text, rather than
-// $quaternary as a solid fill: solid $quaternary under $body-bg text (what
-// `.tag-soon` uses on the home page) measures 4.33:1, under the 4.5:1 floor
-// for text this size. This pairing keeps the same "not yet" hue and clears
-// AA with room to spare.
+// A pale wash with deep-shade text, so the chip clears AA at this size.
$docs-flag-bg: tint-color($quaternary, 88%);
$docs-flag-text: shade-color($quaternary, 25%);
-// Scoped to `main` so the page's resets stay inside the page and leave the
-// navbar and footer to the rest of the site. `.docs a` or `.docs
-// :focus-visible` would also match the navbar -- it is `main`'s sibling
-// under the same body class -- which is exactly how the navbar went teal
-// and lost its focus ring before. The footer's negative top margin is
-// absorbed elsewhere by the padding on `main > .container`; there is no
-// such container here, so the room is taken directly.
+// Scoped to `main` to keep the resets off the navbar and footer, which are
+// its siblings under the same body class. The padding replaces what
+// `main > .container` gives the footer elsewhere.
.docs main {
padding-bottom: 104px;
}
@@ -88,11 +56,8 @@ $docs-flag-text: shade-color($quaternary, 25%);
/* --- Head -------------------------------------------------------------- */
-// Ink, so it carries on from the navbar above it rather than letting the
-// body's parchment show as a pale band between the two. Shorter than the
-// home page's masthead and without its ring graphic -- this is the second
-// door, not the front one -- so the one flourish here is the numeral in
-// `.invite`, not a second motif competing with it.
+// Ink, so it carries on from the navbar rather than leaving a pale band
+// between the two.
.docs-head {
padding-top: calc(#{$navbar-height} + clamp(2rem, 5vw, 3.5rem));
padding-bottom: clamp(2.25rem, 5vw, 3.5rem);
@@ -111,11 +76,8 @@ $docs-flag-text: shade-color($quaternary, 25%);
align-items: start;
}
-// _custom.scss makes every h1 a flex row and draws a rule after it, which
-// suits a plain page heading (see every handbook page's title) and is
-// wrong beside a two-column grid: the rule would run only to this column's
-// edge, reading as an accidental underline against `.invite` rather than a
-// deliberate one.
+// _custom.scss draws a rule after every h1. Beside a two-column grid it
+// would stop at this column's edge, so it is off here.
.docs-title {
display: block;
font-size: clamp(1.875rem, 4.5vw, 2.75rem);
@@ -137,13 +99,8 @@ $docs-flag-text: shade-color($quaternary, 25%);
}
/* --- Head: the invite -----------------------------------------------
- Same shape as `.join` on the home page -- a labelled box, a headline
- statement, a closing line with a link -- carrying this page's own content
- instead: the handbook's own gap, not a repeat of the home page's Discord
- invite. A visitor who wants Discord already saw it one click back; a
- visitor reading the docs is closer to being able to act on this one. Both
- branches below read from the same count the full list further down is
- built from, so the two can never disagree.
+ The shape `.join` has on the home page, carrying the handbook's own gap.
+ Both branches read the count the list further down is built from.
*/
.invite {
@@ -192,9 +149,17 @@ $docs-flag-text: shade-color($quaternary, 25%);
border-top: 1px solid rgb(231 231 214 / 16%);
}
-.invite-row a {
+// Links on the ink. `.docs main a` is (0,1,2), so a band rule needs `main`
+// to reach them.
+.docs main .docs-head a {
+ color: $body-bg;
+}
+
+// The treatment `.join-row a` gives the home page's equivalent link.
+.docs main .invite-row a {
+ font-family: $font-family-monospace;
font-weight: 700;
- color: $docs-primary-tint;
+ color: $body-bg;
}
/* --- Shared section furniture ------------------------------------------ */
@@ -203,8 +168,7 @@ $docs-flag-text: shade-color($quaternary, 25%);
padding-block: clamp(2.5rem, 6vw, 4rem);
}
-// The handbook is the substance of this page, so it sits on its own
-// ground.
+// The handbook is the substance of this page, so it sits on its own ground.
.docs .band-quiet {
background-color: color.mix($tertiary, $body-bg, 12%);
border-block: 1px solid $docs-hairline;
@@ -240,11 +204,8 @@ $docs-flag-text: shade-color($quaternary, 25%);
}
/* --- Taking part --------------------------------------------------------
- A plain divided list, not a numbered tile grid: these four are process
- and community links, the same kind of thing as the home page's own
- "How we work" list, not a catalogue of product areas. The numbered-tile
- treatment stays reserved for the SDK's package areas on the home page,
- so the two forms keep meaning something different from each other.
+ A plain divided list: process and community links, the same kind of thing
+ as the home page's "How we work".
*/
.docs .part-list {
@@ -272,12 +233,8 @@ $docs-flag-text: shade-color($quaternary, 25%);
}
/* --- The handbook -------------------------------------------------------
- Alphabetical, one row per rule, name and point side by side so the column
- of names reads as an index and the point sits where the eye lands after
- it. The index numeral borrows `.area-num`'s exact recipe from the home
- page (mono, small, the same teal); a reference list earns the numbering a
- catalogue-style tile grid would not, because unlike "Taking part" this
- one really is consulted the way an index is: by looking something up.
+ Alphabetical, one row per rule, name and point side by side so the names
+ read as an index. The numeral uses `.area-num`'s recipe from the home page.
*/
.docs .handbook-lede {
@@ -304,11 +261,8 @@ $docs-flag-text: shade-color($quaternary, 25%);
border-top: 1px solid rgb(167 151 139 / 35%);
}
-// A grid, not one flex-wrap row: the numeral has to stay in its own
-// column so it stays pinned beside the first line of the title rather
-// than wrapping away with it. "Documenting Command-Line Syntax" and
-// "Prefer People/Person-First Language When Appropriate" are long enough
-// to wrap on their own regardless -- the numeral should not follow them.
+// A grid, so the numeral keeps its own column and stays beside the first
+// line of a title long enough to wrap.
.docs .rule-name {
display: grid;
grid-template-columns: 1.375rem minmax(0, 1fr);
@@ -337,10 +291,7 @@ $docs-flag-text: shade-color($quaternary, 25%);
line-height: 1.6;
}
-// Unwritten pages are marked by this chip alone -- text, not colour alone,
-// so the state does not rest on the wash of colour behind it. The point
-// beside it stays at full weight and full contrast in every row: the rule
-// is exactly as real on a page that is not written yet.
+// The chip carries the state in text, so it does not rest on colour alone.
.docs .rule-flag {
padding: 0.0625rem 0.4375rem;
font-family: $font-family-monospace;
@@ -361,9 +312,8 @@ $docs-flag-text: shade-color($quaternary, 25%);
}
/* --- Not here yet --------------------------------------------------------
- Quieter than the two sections above on purpose: its whole point is that
- there is not much to say yet, and a heading the same size as "Taking
- part" would promise a third pillar this page does not have.
+ Quieter than the sections above: a heading at their size would promise a
+ third pillar the page does not have.
*/
.docs .band-tail {
@@ -400,8 +350,7 @@ $docs-flag-text: shade-color($quaternary, 25%);
grid-template-columns: minmax(0, 1fr);
}
- // The name column stops earning its width once the point beside it
- // wraps to three or four lines.
+ // The name column stops earning its width once the point beside it wraps.
.docs .rule {
grid-template-columns: minmax(0, 1fr);
gap: 0.375rem;
diff --git a/_assets/styles/_home.scss b/_assets/styles/_home.scss
index 492b2ee26..066da7382 100644
--- a/_assets/styles/_home.scss
+++ b/_assets/styles/_home.scss
@@ -270,7 +270,13 @@
color: rgb(231 231 214 / 70%);
}
-.join-row a {
+// Links on the ink. `.home main a` is (0,1,2), so a band rule needs `main`
+// to reach them.
+.home main .masthead a {
+ color: var(--parchment);
+}
+
+.home main .join-row a {
font-family: var(--mono);
font-weight: 700;
color: var(--parchment);
@@ -282,7 +288,8 @@
color: rgb(231 231 214 / 58%);
}
-.join-coc a {
+// Same weight as the rule above it, so this stays below it in the file.
+.home main .join-coc a {
color: rgb(231 231 214 / 82%);
}
diff --git a/collections/_pages/docs.html b/collections/_pages/docs.html
index fe9667626..a5eaae3c2 100644
--- a/collections/_pages/docs.html
+++ b/collections/_pages/docs.html
@@ -31,11 +31,7 @@