diff --git a/_assets/styles/_docs.scss b/_assets/styles/_docs.scss index 3474e545c..745eee199 100644 --- a/_assets/styles/_docs.scss +++ b/_assets/styles/_docs.scss @@ -14,10 +14,6 @@ $docs-primary-tint: tint-color($primary, 30%); $docs-muted: #4b433c; $docs-hairline: rgb(167 151 139 / 55%); -// 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` 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. @@ -40,8 +36,10 @@ $docs-flag-text: shade-color($quaternary, 25%); // Ink, so it carries on from the navbar rather than leaving a pale band // between the two. .docs-head { + position: relative; padding-top: calc(#{$navbar-height} + clamp(2rem, 5vw, 3.5rem)); padding-bottom: clamp(2.25rem, 5vw, 3.5rem); + overflow: hidden; color: $body-bg; background-color: $body-color; } @@ -50,7 +48,30 @@ $docs-flag-text: shade-color($quaternary, 25%); outline-color: $body-bg; } +// The ring off the logogram, the same drawing home's masthead and the news +// head use, tuned for the glance panel it sits behind here. +.docs-head-ring { + position: absolute; + inset-block-start: 0; + inset-inline-end: 0; + z-index: 0; + width: min(48vw, 360px); + aspect-ratio: 1; + color: $docs-primary-tint; + pointer-events: none; + opacity: 0.12; + transform: translate(22%, -30%); +} + +.docs-head-ring svg { + display: block; + width: 100%; + height: auto; +} + .docs-head-grid { + position: relative; + z-index: 1; display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 0.85fr); gap: clamp(2rem, 5vw, 4rem); @@ -79,18 +100,20 @@ $docs-flag-text: shade-color($quaternary, 25%); color: rgb(231 231 214 / 76%); } -/* --- Head: the invite ----------------------------------------------- - 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. +/* --- Head: at a glance --------------------------------------------------- + The shape `.join` has on the home page and `.hb-stat` gives the handbook: + an eyebrow, a headline number, and a row that leads on. Here the number + is every page this index gathers, so the two children read as one family + rather than the handbook having copied the parent. */ -.invite { +.docs-glance { padding: 1.25rem 1.375rem; background-color: rgb(231 231 214 / 4%); border: 1px solid rgb(231 231 214 / 20%); } -.invite-eyebrow { +.docs-glance-eyebrow { font-family: $font-family-monospace; font-size: 0.6875rem; color: $tertiary; @@ -98,7 +121,7 @@ $docs-flag-text: shade-color($quaternary, 25%); letter-spacing: 0.08em; } -.invite-title { +.docs-glance-title { display: flex; flex-wrap: wrap; gap: 0.5rem; @@ -110,34 +133,29 @@ $docs-flag-text: shade-color($quaternary, 25%); color: $body-bg; } -.invite-num { +.docs-glance-num { font-family: $font-family-monospace; font-size: clamp(2.25rem, 5vw, 2.75rem); line-height: 0.9; color: $docs-primary-tint; } -.invite-what { +.docs-glance-what { margin-top: 0.75rem !important; font-size: 0.9375rem; line-height: 1.6; color: rgb(231 231 214 / 70%); } -.invite-row { +.docs-glance-row { padding-top: 0.875rem; margin-top: 1rem !important; border-top: 1px solid rgb(231 231 214 / 16%); } -// Links on the ink. `.docs main a` is (0,1,2), so a band rule needs `main` -// to reach them. -.docs-index main .docs-head a { - color: $body-bg; -} - -// The treatment `.join-row a` gives the home page's equivalent link. -.docs-index main .invite-row a { +// The treatment `.join-row a` gives the home page's equivalent link. Scoped +// to the head, where the ink is: parchment on a band would be invisible. +.docs-index main .docs-head .docs-glance-row a { font-family: $font-family-monospace; font-weight: 700; color: $body-bg; @@ -176,6 +194,17 @@ $docs-flag-text: shade-color($quaternary, 25%); border-bottom: 1px solid $docs-hairline; } +// The numbered voice `.area-num` gives the home page's SDK areas and +// `.rule-card-num` gives the handbook's grid, so a reader who has seen either +// already knows this is one entry in a counted set. +.docs-index .part-num { + display: block; + margin-bottom: 0.375rem; + font-family: $font-family-monospace; + font-size: 0.75rem; + color: $docs-link; +} + .docs-index .part-name { font-size: 1.0625rem; font-weight: 700; @@ -188,9 +217,10 @@ $docs-flag-text: shade-color($quaternary, 25%); color: $docs-muted; } -/* --- The handbook ------------------------------------------------------- - 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. +/* --- The handbook -------------------------------------------------------- + The rules live at their own page now; this is the teaser that sends a + reader there, styled as the arrow-link `.featured-link` gives the news + page's lead story. */ .docs-index .handbook-lede { @@ -201,70 +231,27 @@ $docs-flag-text: shade-color($quaternary, 25%); color: $docs-muted; } -.docs-index .rule-list { - margin-top: 1.75rem !important; -} - -.docs-index .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-index .rule:first-child { - border-top: 1px solid rgb(167 151 139 / 35%); +.docs-index .handbook-more { + margin-top: 1.25rem !important; } -// A grid, so the numeral keeps its own column and stays beside the first -// line of a title long enough to wrap. -.docs-index .rule-name { - display: grid; - grid-template-columns: 1.375rem minmax(0, 1fr); - gap: 0.5rem; - align-items: baseline; - font-size: 0.9375rem; +.docs-index .handbook-link { + display: inline-flex; + gap: 0.375rem; + align-items: center; font-weight: 700; -} - -.docs-index .rule-num { - font-family: $font-family-monospace; - font-size: 0.75rem; - font-weight: 400; color: $docs-link; + text-decoration: none; + border-bottom: 2px solid currentcolor; } -.docs-index .rule-heading { - display: flex; - flex-wrap: wrap; - gap: 0.5rem; - align-items: baseline; +.docs-index .handbook-link-arrow { + display: inline-block; + transition: transform 0.15s ease; } -.docs-index .rule-point { - font-size: 0.9375rem; - line-height: 1.6; -} - -// The chip carries the state in text, so it does not rest on color alone. -.docs-index .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-index .handbook-gap { - max-width: 60ch; - margin-top: 1.5rem !important; - font-size: 0.9375rem; - line-height: 1.65; - color: $docs-muted; +.docs-index .handbook-link:hover .handbook-link-arrow { + transform: translateX(3px); } /* --- Not here yet -------------------------------------------------------- @@ -305,10 +292,10 @@ $docs-flag-text: shade-color($quaternary, 25%); .docs-index .part-list { grid-template-columns: minmax(0, 1fr); } +} - // The name column stops earning its width once the point beside it wraps. - .docs-index .rule { - grid-template-columns: minmax(0, 1fr); - gap: 0.375rem; +@media (prefers-reduced-motion: reduce) { + .docs-index .handbook-link-arrow { + transition: none; } } diff --git a/_assets/styles/_handbook.scss b/_assets/styles/_handbook.scss new file mode 100644 index 000000000..0df6d5af8 --- /dev/null +++ b/_assets/styles/_handbook.scss @@ -0,0 +1,326 @@ +@use 'sass:color'; + +// The handbook index: the front door to the nine rules. It shares the +// two-column hero and the count `_docs.scss` gives the rest of the site's +// index pages, but the rules themselves are the point of this one page, so +// they get the room a plain list does not: a grid of cards, drawn the way +// the SDK areas are drawn on the home page — hairline dividers between cells +// that share the section's own ground, not a border around each one. + +// Colors come from _sublime-theme.scss and reuse the exact tones +// _docs.scss, _about.scss, and _news.scss give a hero band and a quiet +// section, so this page agrees with the rest of the site on what a link, a +// muted caption, and a wash look like. + +$hb-wrap: 1200px; +$hb-gutter: clamp(1rem, 4vw, 3rem); +$hb-link: shade-color($primary, 25%); +$hb-primary-tint: tint-color($primary, 30%); +$hb-muted: #4b433c; +$hb-hairline: rgb(167 151 139 / 55%); + +// A pale wash with deep-shade text, so the flag clears AA at this size. +$hb-flag-bg: tint-color($quaternary, 88%); +$hb-flag-text: shade-color($quaternary, 25%); + +// The wash `_docs.scss` gives its own quiet section, reused here as the +// ground the rule grid sits on. +$hb-quiet: color.mix($tertiary, $body-bg, 12%); + +// 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. +.handbook-index main h1, +.handbook-index main h2, +.handbook-index main p, +.handbook-index main dl, +.handbook-index main dd, +.handbook-index main ol, +.handbook-index main ul { + margin: 0; +} + +.handbook-index main ol, +.handbook-index main ul { + padding: 0; + list-style: none; +} + +/* --- Head --------------------------------------------------------------- + The same hero shape `.docs-head` and `.about-head` use: ink, the ring off + the logogram bleeding from the corner, a lede on one side and a stat on the + other. Its own classes, because the content beside the ring — a live count + of rules, not a link out — is what makes this page a destination rather + than a repeat of the index it is reached from. +*/ + +.hb-head { + position: relative; + padding-top: calc(#{$navbar-height} + clamp(2rem, 5vw, 3.5rem)); + padding-bottom: clamp(2.25rem, 5vw, 3.5rem); + overflow: hidden; + color: $body-bg; + background-color: $body-color; +} + +.hb-head :focus-visible { + outline-color: $body-bg; +} + +// The ring off the logogram, the same drawing the home masthead and the news +// head use, tuned for this band: lower and further into the corner than +// home's, since it sits behind a narrower second column here. +.hb-ring { + position: absolute; + inset-block-start: 0; + inset-inline-end: 0; + z-index: 0; + width: min(52vw, 400px); + aspect-ratio: 1; + color: $hb-primary-tint; + pointer-events: none; + opacity: 0.12; + transform: translate(24%, -26%); +} + +.hb-ring svg { + display: block; + width: 100%; + height: auto; +} + +.hb-head-grid { + position: relative; + z-index: 1; + display: grid; + grid-template-columns: minmax(0, 1.4fr) minmax(0, 0.85fr); + gap: clamp(2rem, 5vw, 4rem); + align-items: start; +} + +// _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. +.hb-title { + display: block; + font-size: clamp(1.875rem, 4.5vw, 2.75rem); + font-weight: 700; + line-height: 1.08; + letter-spacing: -0.02em; +} + +.hb-title::after { + content: none; +} + +.hb-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 stat ------------------------------------------------------- + How much of the handbook is written, read at a glance, with the same + progress a reader would otherwise have to count from the grid below. +*/ + +.hb-stat { + padding: 1.25rem 1.375rem 1.375rem; + background-color: rgb(231 231 214 / 4%); + border: 1px solid rgb(231 231 214 / 20%); +} + +.hb-stat-eyebrow { + font-family: $font-family-monospace; + font-size: 0.6875rem; + color: $tertiary; + text-transform: uppercase; + letter-spacing: 0.08em; +} + +.hb-stat-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; +} + +.hb-stat-num { + font-family: $font-family-monospace; + font-size: clamp(2.25rem, 5vw, 2.75rem); + line-height: 0.9; + color: $hb-primary-tint; +} + +.hb-stat-what { + margin-top: 0.75rem !important; + font-size: 0.9375rem; + line-height: 1.6; + color: rgb(231 231 214 / 70%); +} + +// One square a rule, filled once it is written. The same information the +// numeral above states in words, read a second way. +.hb-progress { + display: flex; + flex-wrap: wrap; + gap: 0.25rem; + margin-top: 0.875rem !important; +} + +.hb-progress-cell { + width: 0.625rem; + height: 0.625rem; + background-color: $hb-primary-tint; + border: 1px solid $hb-primary-tint; +} + +.hb-progress-cell-open { + background-color: transparent; + border-color: rgb(231 231 214 / 30%); +} + +.hb-stat-row { + padding-top: 0.875rem; + margin-top: 1rem !important; + border-top: 1px solid rgb(231 231 214 / 16%); +} + +// Links on the ink. `.handbook-index main a` is (0,1,2), so a band rule needs +// `main` to reach them. +.handbook-index main .hb-head .hb-stat-row a { + font-family: $font-family-monospace; + font-weight: 700; + color: $body-bg; +} + +/* --- Shared section furniture ------------------------------------------ */ + +.handbook-index .band-quiet { + background-color: $hb-quiet; + border-block: 1px solid $hb-hairline; +} + +.handbook-index .section-count { + font-family: $font-family-monospace; + font-size: 0.8125rem; + color: $hb-muted; + text-transform: uppercase; + letter-spacing: 0.06em; +} + +/* --- The rules: a grid, not a list --------------------------------------- + Nine rules divide evenly into three columns of three, so the grid is + counted rather than fitted: the same reasoning `_home.scss` gives the SDK + areas. The 1px gap over the hairline background is what draws the lines + between cells; each cell's own background matches the section's, so the + grid reads as one drawn surface rather than nine boxes set on top of it. +*/ + +.rule-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 1px; + margin-top: 1.75rem !important; + background-color: $hb-hairline; + border: 1px solid $hb-hairline; +} + +.rule-card { + position: relative; + display: flex; + flex-direction: column; + gap: 0.625rem; + height: 100%; + padding: 1.375rem 1.5rem 1.5rem; + color: inherit; + text-decoration: none; + background-color: $hb-quiet; + transition: background-color 150ms ease; +} + +// Lighter than the wash it sits on, so the card the pointer is over reads as +// lifted rather than tinted; this is what keeps the title's contrast well +// clear of AA rather than trading it away for a coloured hover. +.rule-card:hover, +.rule-card:focus-visible { + background-color: $body-bg; +} + +.rule-card-num { + display: block; + font-family: $font-family-monospace; + font-size: 0.75rem; + color: $hb-link; +} + +.rule-card-heading { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + align-items: baseline; +} + +.rule-card-title { + font-size: 1.0625rem; + font-weight: 700; + line-height: 1.3; + color: $hb-link; +} + +.rule-card:hover .rule-card-title, +.rule-card:focus-visible .rule-card-title { + text-decoration: underline; +} + +// The flag carries the state in text, so it does not rest on color alone. +.rule-card-flag { + padding: 0.0625rem 0.4375rem; + font-family: $font-family-monospace; + font-size: 0.6875rem; + font-weight: 400; + color: $hb-flag-text; + text-transform: uppercase; + letter-spacing: 0.06em; + background-color: $hb-flag-bg; +} + +.rule-card-point { + font-size: 0.9375rem; + line-height: 1.6; + color: $hb-muted; +} + +.hb-gap { + max-width: 60ch; + margin-top: 1.5rem !important; + font-size: 0.9375rem; + line-height: 1.65; + color: $hb-muted; +} + +/* --- Narrow -------------------------------------------------------------- */ + +@media (width < 960px) { + .hb-head-grid { + grid-template-columns: minmax(0, 1fr); + } +} + +@media (width < 760px) { + .rule-grid { + grid-template-columns: minmax(0, 1fr); + } +} + +@media (prefers-reduced-motion: reduce) { + .rule-card { + transition: none; + } +} diff --git a/_assets/styles/main.scss b/_assets/styles/main.scss index 13a2c130e..8876f0899 100644 --- a/_assets/styles/main.scss +++ b/_assets/styles/main.scss @@ -22,6 +22,7 @@ @import 'docs'; @import 'docs-page'; @import 'error'; +@import 'handbook'; @import 'home'; @import 'nav'; @import 'news'; diff --git a/_data/sections.json b/_data/sections.json index 8b19302eb..0967ef424 100644 --- a/_data/sections.json +++ b/_data/sections.json @@ -1,6 +1 @@ -{ - "handbook": { - "name": "Style handbook", - "url": "/docs/#handbook" - } -} +{} diff --git a/collections/_pages/about.html b/collections/_pages/about.html index 8b9281aac..26921a25e 100644 --- a/collections/_pages/about.html +++ b/collections/_pages/about.html @@ -48,8 +48,9 @@

In practice

The rules are written down
How prose is styled, how a commit is worded, how a change gets - reviewed. It lives in the handbook, - not in the head of whoever reviews you. + reviewed. It lives in the + handbook, not in the head of + whoever reviews you.
diff --git a/collections/_pages/docs.html b/collections/_pages/docs.html index 0c0ef1365..89e24ad4a 100644 --- a/collections/_pages/docs.html +++ b/collections/_pages/docs.html @@ -16,6 +16,8 @@ -%} {%- assign written_count = written | size -%} {%- assign open_count = handbook_total | minus: written_count -%} +{%- assign community_count = collections.communityDocs | size -%} +{%- assign total_pages = community_count | plus: handbook_total -%} {%- assign rule_word = 'rules' -%} {%- if open_count == 1 -%} {%- assign rule_word = 'rule' -%} @@ -23,6 +25,10 @@
+ +

Docs

@@ -32,33 +38,19 @@

Docs

- -
@@ -75,6 +67,10 @@

Taking part

    {%- for doc in collections.communityDocs %}
  • +

    {{ doc.data.title }}

    @@ -87,8 +83,8 @@

    Taking part

    Taking part

    The style handbook

    -

    - {{ written_count }} of {{ handbook_total }} written -

    + {%- if open_count > 0 %} +

    + {{ written_count }} of {{ handbook_total }} written +

    + {%- endif %}

    The house style our documentation and commit messages follow, one rule - to a page. Each rule is stated below, so you can find the one you need. + to a page, so a question about how something is written has one place to + be answered.

    -
    - {%- for doc in collections.handbook %} -
    -
    - - - {{ doc.data.title }} - {%- if doc.data.stub %} - Unwritten - {%- endif %} - -
    -
    {{ doc.data.key_point }}
    -
    - {%- endfor %} -
    - - {%- if open_count > 0 %} -

    - The rules marked unwritten have their line here but no page yet. Any - one of them is a contained piece of work. - How to contribute. -

    - {%- endif %} +

    + + Read the handbook + + +

    diff --git a/collections/_pages/handbook.html b/collections/_pages/handbook.html new file mode 100644 index 000000000..3b35d1e3b --- /dev/null +++ b/collections/_pages/handbook.html @@ -0,0 +1,116 @@ +--- +title: Style Handbook +layout: default +permalink: /docs/handbook/style/ +description: + The house style OpenINF documentation and commit messages follow, one rule + to a page. +body_classes: + - docs + - handbook-index +eleventyImport: + collections: ['handbook'] +--- +{%- assign handbook_total = collections.handbook | size -%} +{%- assign written = collections.handbook + | where_exp: 'doc', 'doc.data.stub != true' +-%} +{%- assign written_count = written | size -%} +{%- assign open_count = handbook_total | minus: written_count -%} +
    + +
    + + +
    +
    +

    Style Handbook

    +

    + The house style our documentation and commit messages follow, one rule + to a page. Each rule is stated below, so you can find the one you need + without reading the rest. +

    +
    + + +
    +
    + + +
    +
    +
    +

    Every rule

    + {%- if open_count > 0 %} +

    + {{ written_count }} of {{ handbook_total }} written +

    + {%- endif %} +
    + +
      + {%- for doc in collections.handbook %} +
    1. + + + + {{ doc.data.title }} + {%- if doc.data.stub %} + Unwritten + {%- endif %} + + {{ doc.data.key_point }} + +
    2. + {%- endfor %} +
    + + {%- if open_count > 0 %} +

    + A rule marked unwritten has its page; the page states the rule and + stops. Any one of them is a contained piece of work. + How to contribute. +

    + {%- endif %} +
    +
    +
    diff --git a/collections/_pages/home.html b/collections/_pages/home.html index 18cab6f87..13fd470ab 100644 --- a/collections/_pages/home.html +++ b/collections/_pages/home.html @@ -235,7 +235,7 @@

    How we work

  • - Style handbook + Style handbook

    The house style our documentation and commit messages follow. diff --git a/collections/_pages/license.html b/collections/_pages/license.html index 04da2ebd8..c56b92e95 100644 --- a/collections/_pages/license.html +++ b/collections/_pages/license.html @@ -44,7 +44,7 @@

    Everything else

    Written material carries its own terms, stated at the foot of the page it is on: the - style handbook under + style handbook under