/*
  Minimal black-and-white. One stylesheet for every page.

  The rule the whole sheet is built on: the PAGE has no colour, so the
  screenshots are the only colour on it. That is not an aesthetic preference,
  it is where the eye goes — a monospace grey-scale page puts every pixel of
  attention on the app itself. So nothing here may introduce a hue: no accent,
  no tinted border, no coloured link. Black, white, and two greys.

  Derived from hint-style-mimimal-BW.html — monospace, white ground, black
  rules, underlined links — widened to carry figures, tables and a table of
  contents.
*/

:root {
    --ink: #000;
    --bg: #fff;
    --muted: #333;
    --faint: #6b6b6b;
    --line: #000;
    --hair: #ccc;
    --maxw: 820px;
}

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}
html {
    scroll-behavior: smooth;
}
body {
    background: var(--bg);
    color: var(--ink);
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
        "Liberation Mono", monospace;
    font-size: 15px;
    line-height: 1.62;
    -webkit-font-smoothing: antialiased;
}

/*
  The gutter is 44px, not the 20 a minimal sheet reaches for first. The manual
  puts its contents list in the left column, and at 20 that list sits flush
  against the window edge with nothing to separate it from the browser chrome —
  the one place on the site where text is the leftmost thing on screen.
*/
.wrap {
    max-width: var(--maxw);
    margin: 0 auto;
    padding: 0 44px;
}
.wrap.wide {
    max-width: 1108px; /* 1060 of content plus the two gutters */
}

a {
    color: var(--ink);
    text-decoration: underline;
    text-underline-offset: 3px;
}
/* Inverting on hover is the only "highlight" available without a hue. */
a:hover {
    background: var(--ink);
    color: var(--bg);
    text-decoration: none;
}

img {
    max-width: 100%;
    display: block;
}

hr {
    border: none;
    border-top: 1px solid var(--line);
    margin: 40px 0;
}

/* ------------------------------------------------------------------ header */

header {
    position: sticky;
    top: 0;
    z-index: 10;
    background: var(--bg);
    border-bottom: 1px solid var(--line);
}
header .wrap {
    display: flex;
    /* Baseline for the same reason the footer uses it: brand and nav are two
       type sizes, so centring their boxes puts their text on two lines. The
       boxed controls keep centring against each other inside .header-right. */
    align-items: baseline;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px 20px;
    padding-top: 12px;
    padding-bottom: 12px;
}
.brand {
    font-weight: 700;
    letter-spacing: 0.02em;
    text-decoration: none;
}
.brand:hover {
    background: none;
    color: var(--ink);
    text-decoration: underline;
}
nav ul {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 16px;
    list-style: none;
}
nav a {
    font-size: 0.82rem;
}
nav a[aria-current="page"] {
    font-weight: 700;
}
.header-right {
    display: flex;
    align-items: center;
    gap: 12px;
}
.lang-switch {
    display: flex;
}
.lang-btn {
    font: inherit;
    font-size: 0.75rem;
    background: none;
    color: var(--ink);
    border: 1px solid var(--line);
    padding: 2px 7px;
    cursor: pointer;
}
.lang-btn + .lang-btn {
    border-left: none;
}
.lang-btn.active {
    background: var(--ink);
    color: var(--bg);
}
.nav-cta {
    font-size: 0.82rem;
    border: 1px solid var(--line);
    padding: 4px 10px;
    text-decoration: none;
    white-space: nowrap;
}

/* -------------------------------------------------------------- typography */

h1 {
    font-size: 1.75rem;
    line-height: 1.25;
    letter-spacing: -0.01em;
    margin-bottom: 14px;
}
h1 span {
    text-decoration: underline;
    text-underline-offset: 5px;
}
h2 {
    font-size: 1.15rem;
    margin-bottom: 10px;
}
h3 {
    font-size: 0.98rem;
    margin-bottom: 6px;
}
h4 {
    font-size: 0.92rem;
    margin: 22px 0 6px;
}
p {
    margin-bottom: 14px;
    max-width: 68ch;
}
p:last-child {
    margin-bottom: 0;
}
.eyebrow {
    display: block;
    font-size: 0.72rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--faint);
    margin-bottom: 10px;
}
.lede {
    font-size: 1rem;
    color: var(--muted);
}
.byline {
    font-size: 0.8rem;
    color: var(--faint);
}
code {
    font-family: inherit;
    border: 1px solid var(--hair);
    padding: 0 4px;
}
strong {
    font-weight: 700;
}

ul,
ol {
    margin: 0 0 14px 1.25em;
    max-width: 68ch;
}
li {
    margin-bottom: 6px;
}

section {
    padding: 40px 0;
    border-top: 1px solid var(--line);
}
section:first-of-type {
    border-top: none;
}

/* ------------------------------------------------------------------ blocks */

.cta-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin-top: 18px;
}
/* A row can lead with a sentence — the manual hand-off does. It sits on the
   button's line and wraps above it when there is no room for both. */
.cta-row p {
    margin-bottom: 0;
}
.btn-primary,
.btn-secondary {
    font: inherit;
    font-size: 0.88rem;
    padding: 7px 14px;
    border: 1px solid var(--line);
    text-decoration: none;
    cursor: pointer;
    background: none;
    color: var(--ink);
}
.btn-primary {
    background: var(--ink);
    color: var(--bg);
}
.btn-primary:hover {
    background: var(--bg);
    color: var(--ink);
}
.btn-secondary:hover {
    background: var(--ink);
    color: var(--bg);
}

/*
  Numbered blocks — features, steps, views. A plain list with a rule between
  entries, not cards: a card needs a fill or a shadow to read as one, and both
  are colour by another name.
*/
.rows {
    margin: 0;
    list-style: none;
    border-top: 1px solid var(--hair);
}
.rows > li {
    margin: 0;
    padding: 18px 0;
    border-bottom: 1px solid var(--hair);
    display: grid;
    grid-template-columns: 2.5rem 1fr;
    gap: 0 14px;
    align-items: start;
}
.rows .marker {
    font-weight: 700;
    color: var(--faint);
}
.rows h3 {
    margin-bottom: 4px;
}
.rows p {
    margin-bottom: 0;
    color: var(--muted);
}


.note {
    border: 1px solid var(--line);
    padding: 14px 16px;
    margin: 22px 0;
}
.note p {
    margin-bottom: 0;
}

/* ----------------------------------------------------------------- figures */

figure {
    margin: 24px 0;
}
figure img {
    border: 1px solid var(--line);
    width: 100%;
}

/*
  Every screenshot is captured at 1600px and drawn into a column under half
  that, so the figures are all readable-at-full-size and unreadable in place.
  The button is the whole picture: no chrome of its own, the image keeps its
  border, and the only visible affordance is the cursor plus a focus ring for
  anyone not using one.
*/
.zoom-btn {
    display: block;
    width: 100%;
    padding: 0;
    border: none;
    background: none;
    cursor: zoom-in;
}
.zoom-btn:focus-visible {
    outline: 2px solid var(--ink);
    outline-offset: 3px;
}
figcaption {
    font-size: 0.78rem;
    color: var(--faint);
    padding-top: 8px;
}

/* ------------------------------------------------------------------ tables */

.scroll-x {
    overflow-x: auto;
    margin-bottom: 18px;
}
table {
    border-collapse: collapse;
    width: 100%;
    font-size: 0.85rem;
}
th,
td {
    border: 1px solid var(--hair);
    padding: 7px 9px;
    text-align: left;
    vertical-align: top;
}
th {
    border-color: var(--line);
    font-size: 0.72rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

/* ------------------------------------------------------- manual: TOC + body */

/*
  Vertical padding only. `.layout` is also a `.wrap`, and a `padding` shorthand
  here silently zeroed the gutter it inherits — which put the contents list
  flush against the window edge at every width, hidden on a wide screen only
  because the max-width was centring the whole column.
*/
.layout {
    display: grid;
    grid-template-columns: 210px minmax(0, 1fr);
    gap: 48px;
    align-items: start;
    padding-top: 36px;
    padding-bottom: 60px;
}
.toc {
    position: sticky;
    /* The header is 69px and sticky. 72 put the list 3px under it, which
       reads as the two being stuck together; this leaves a clear gap. */
    top: 104px;
    border-right: 1px solid var(--hair);
    padding-right: 16px;
}
.toc h2 {
    font-size: 0.72rem;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--faint);
    margin-bottom: 10px;
}
.toc a {
    display: block;
    font-size: 0.82rem;
    padding: 3px 0;
    text-decoration: none;
}
.toc a:hover {
    text-decoration: underline;
}
.layout main section {
    padding: 0 0 36px;
    border-top: none;
}
.layout main section + section {
    padding-top: 36px;
    border-top: 1px solid var(--line);
}

/* The post is the only page whose content ends in a bare paragraph — every
   other one closes on a section, a figure or a CTA band, all of which carry
   their own bottom padding. Without this the last line sits on the footer
   rule. */
article {
    padding-bottom: 64px;
}
article h2 {
    margin-top: 34px;
}
article h2:first-child {
    margin-top: 0;
}
.standfirst {
    font-size: 1rem;
}

/* ------------------------------------------------------------------- modal */

.modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 40px 20px;
    overflow-y: auto;
    z-index: 50;
}
.modal-backdrop[hidden] {
    display: none;
}
.modal {
    position: relative;
    background: var(--bg);
    border: 1px solid var(--line);
    max-width: 720px;
    width: 100%;
    padding: 28px 26px 32px;
}
.modal-close {
    position: absolute;
    top: 8px;
    right: 10px;
    font: inherit;
    font-size: 1.2rem;
    line-height: 1;
    background: none;
    border: none;
    color: var(--ink);
    cursor: pointer;
    padding: 4px 8px;
}
/*
  The two pictures in the runway explainer are the only colour in a wall of
  prose. At 64 and 180 they read as decoration stuck to a corner, and at 160
  and 420 they still read as illustration beside the text. Both are 16:9, so
  the full content width makes the first one a splash the essay opens on and
  the second a plate the essay breaks for — which is the job they are here to
  do.
*/
.modal-logo {
    display: block;
    width: 100%;
    margin: 0 auto 26px;
}
.modal-body .formula {
    border: 1px solid var(--line);
    padding: 12px 14px;
    margin: 18px 0;
    text-align: center;
}
.modal-figure {
    display: block;
    width: 100%;
    margin: 32px auto;
}

/* ------------------------------------------------------- hero / cta / foot */

.hero {
    padding: 48px 0 40px;
}
.hero-art {
    margin-top: 26px;
    max-width: 260px;
}
/*
  A button, not a bare clickable image: the logo opens full size, and a thing
  that opens something has to be reachable by keyboard and announce itself.
*/
.hero-art-btn {
    display: block;
    padding: 0;
    border: none;
    background: none;
    cursor: zoom-in;
    width: 100%;
}
.hero-art-btn img {
    border: 1px solid var(--line);
}
.hero-art-btn:focus-visible {
    outline: 2px solid var(--ink);
    outline-offset: 3px;
}

/*
  The lightbox is the one place the page goes dark. Black is in the palette,
  and a full-size image needs ground that is not competing with it.
*/
.lightbox {
    position: fixed;
    inset: 0;
    z-index: 60;
    background: rgba(0, 0, 0, 0.88);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 14px;
    padding: 56px 24px 32px;
    cursor: zoom-out;
}
.lightbox[hidden] {
    display: none;
}
.lightbox img {
    max-width: min(100%, 1100px);
    max-height: 82vh;
    width: auto;
    cursor: default;
}
.lightbox-caption {
    color: #fff;
    font-size: 0.78rem;
    margin: 0;
    text-align: center;
}
.lightbox-close {
    position: absolute;
    top: 12px;
    right: 16px;
    font: inherit;
    font-size: 1.1rem;
    line-height: 1;
    background: none;
    border: 1px solid #fff;
    color: #fff;
    padding: 5px 10px;
    cursor: pointer;
}

.cta-band {
    border: 1px solid var(--line);
    padding: 26px 24px;
}

footer {
    border-top: 1px solid var(--line);
    /* Even with every other section rule: 40 above the line, 40 below. */
    padding: 40px 0;
}
footer .wrap {
    display: flex;
    flex-wrap: wrap;
    /* Baseline, not centre: brand, nav and the meta line are three type sizes
       and centring their boxes puts their baselines at three heights. */
    align-items: baseline;
    justify-content: space-between;
    gap: 12px 20px;
}
footer p {
    font-size: 0.78rem;
    color: var(--faint);
    margin-bottom: 0;
}

/* --------------------------------------------------------------- narrow */

@media (max-width: 820px) {
    .layout {
        grid-template-columns: 1fr;
        gap: 28px;
    }
    .toc {
        position: static;
        border-right: none;
        border-bottom: 1px solid var(--hair);
        padding: 0 0 16px;
    }
    header .wrap {
        justify-content: flex-start;
    }
}
@media (max-width: 560px) {
    .wrap {
        padding: 0 22px;
    }
    .rows > li {
        grid-template-columns: 1fr;
        gap: 4px;
    }
    h1 {
        font-size: 1.4rem;
    }
}
