/* The one theme. Monochrome, flush left, two navigation layouts. */

:root {
  --ink: #000;
  --paper: #fff;
  --muted: color-mix(in srgb, var(--ink) 50%, var(--paper));
  --rule: color-mix(in srgb, var(--ink) 20%, var(--paper));
  /* Named here so a customer's choice has one property to override. The
     stack is the one this theme has always used: Archivo is not shipped and
     has never been, so in practice this resolves to the system UI face. */
  --font: Archivo, system-ui, -apple-system, "Segoe UI", sans-serif;

  /* The type scale. Five styles for the whole site and no more.

     These numbers were moved deliberately away from the site this theme was
     derived from (spec section 7 carries the new figures and says so). They
     are not a drift to be corrected back: 42/26/17/17/13 is the scale, and
     "restoring" 44/24/16/16/12 to match the source would undo a decision.

     A customer's two size settings are multipliers on this scale rather than
     a size per heading, so the proportions between the five styles hold at
     every step and one property moves a whole family. Both default to 1, so
     a site that has never touched them renders the scale exactly as written
     here. See sites/style.py. */
  --heading-scale: 1;
  --text-scale: 1;
  --display: calc(42px * var(--heading-scale));
  --display-narrow: calc(31px * var(--heading-scale));
  --section: calc(26px * var(--heading-scale));
  --body: calc(17px * var(--text-scale));
  --small: calc(13px * var(--text-scale));

  /* margins and gutters scale with the viewport rather than snapping */
  --margin: calc(34 * 100vw / 1600);
  --gutter: var(--margin);
  --measure: 672px;
}

/* No `prefers-color-scheme: dark` block, deliberately, and it is not an
   omission to be tidied up later.

   This theme used to invert for a visitor whose system asks for dark. That
   cannot coexist with letting a customer choose their own two colours. A
   customer who picks black on white and is shown white on black has not been
   given a choice; and the 4.5:1 we guarantee between their two colours would
   be measured against a background we then replaced, so the guarantee would
   be about a page nobody sees. Their choice is the choice.

   The panel keeps its dark scheme. That one is our interface, nobody is
   choosing colours for it, and the two questions are unrelated. See
   docs/known-issues.md. */

@media (max-width: 900px) {
  :root { --margin: 16px; --gutter: 16px; }
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  padding: var(--margin);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--body);
  line-height: 1.44;
  -webkit-text-size-adjust: 100%;
}

/* Five type styles for the whole site, and no more. Every size comes from
   the scale above; none is written here as a number. */
.site-title, h1, blockquote p {
  font-size: var(--display); font-weight: 800; letter-spacing: -0.02em; line-height: 1.04;
  margin: 0 0 24px;
}
h2 { font-size: var(--section); font-weight: 800; letter-spacing: -0.012em; line-height: 1.22; margin: 0 0 24px; }
h3, .site-nav a, footer a { font-size: var(--body); font-weight: 700; line-height: 1.44; }
p, ul, ol, table { font-size: var(--body); font-weight: 400; line-height: 1.44; }
figcaption { font-size: var(--small); letter-spacing: 0.015em; line-height: 1.24; color: var(--muted); }

@media (max-width: 900px) {
  .site-title, h1, blockquote p { font-size: var(--display-narrow); line-height: 1.1; }
}

main { max-width: var(--measure); }
p, ul, ol, blockquote, figure { max-width: var(--measure); margin: 0 0 24px; }

/* A pasted URL breaks mid-word rather than pushing past the measure; the
   page body never scrolls sideways. */
p, ul, ol, li, blockquote, figcaption, h1, h2, h3, .site-title,
.site-nav a, footer a {
  overflow-wrap: anywhere;
}

/* Irregular rhythm: little air inside a section, a lot between them. Three
   steps and nothing in between: 24px within a section, 64px around a break
   in one, 176px between sections.

   `:first-child`, not `:first-of-type`. The reduced top margin is for a
   heading that genuinely opens the page, sitting just under the title.
   `:first-of-type` matched the first h2 whatever came before it, so a page
   with an intro paragraph got 80px at the first heading and 176px at every
   later one, and the rhythm read as a mistake rather than a rule. */
h2 { margin-top: 176px; }
main > h2:first-child { margin-top: 80px; }

/* A pull quote is set at display size, so the 24px that suits a paragraph
   leaves it jammed against the body text above and below it. It is a break
   within a section rather than a new one, which is the middle step. The
   figure owns the whole gap: the spacing used to be split between the
   blockquote and its paragraph, which is why it was hard to reason about. */
figure.quote { margin: 64px 0; }
figure.quote blockquote { margin: 0; }
figure.quote figcaption { margin-top: 8px; }
footer { margin-top: 240px; padding-top: 24px; border-top: 1px solid var(--rule); }
footer a { margin-right: 24px; }
.hosted-on { font-size: var(--small); color: var(--muted); margin: 24px 0 0; }
/* The whole phrase sits inside the anchor, so `footer a` matches it directly
   and would otherwise win over .hosted-on's inherited size and weight. */
.hosted-on a { font-size: inherit; font-weight: inherit; margin-right: 0; }

/* Two navigation layouts, and the customer picks between them. One <nav>,
   one set of links, one modifier class; see sites/style.py NAV_CLASSES.
   Neither layout is a header bar. */
/* The measure belongs to reading, so it belongs to the title and not to the
   header around it. Capping the header capped the horizontal navigation too,
   which is a row of short labels rather than prose: it wrapped onto a second
   line while two thirds of the page sat empty beside it. The nav now runs to
   the content width, which is the viewport less the body padding. */
.site-head > .site-title { max-width: var(--measure); }

/* Under the title. The default, including for sites that predate the
   choice. A row of links directly below the site title, borrowing the
   footer's shape: the same type style (see `h3, .site-nav a, footer a`
   above) and the same 24px between one link and the next. */
.site-nav--title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 24px;
  margin: 0 0 24px;
}

/* In the margin. The fixed corner stack this theme shipped with: the
   navigation *is* the empty right margin, which is why there is no header.
   Out of flow, so its place in the document does not matter. */
.site-nav--margin {
  position: fixed;
  top: 40px;
  right: var(--margin);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  pointer-events: none;
  z-index: 10;
}
.site-nav--margin a { pointer-events: auto; }

/* Two kinds of destination share this nav: places on the page you are
   reading, and other pages. Undivided they read as one list, so a section
   and a page that share a name look like a repeat rather than two
   different things. The German marketing site has "Loslegen" as both.
   A hairline and a little air say "the rest of the site starts here"
   without adding a word or a heading to a nav that has neither.

   It has to work in both layouts, so it turns with them: a short horizontal
   rule between two stacked links, a short vertical one between two links
   side by side. Same element, same markup, same job. */
.nav-rule { background: var(--rule); }
.site-nav--margin .nav-rule { width: 24px; height: 1px; margin: 10px 0; }
.site-nav--title .nav-rule { width: 1px; height: 24px; margin: 0; }

@media (max-width: 900px) {
  /* Below 900px there is no empty right margin to put anything in, so the
     margin layout falls back to the flow. It keeps its own vertical
     hairline shape: it is still a stack, just not a fixed one. */
  .site-nav--margin { position: static; align-items: flex-start; margin-bottom: 64px; }
}

/* A link in prose is a plain underline. It has to wrap mid-word and sit on
   the text baseline, and an inline-block with hidden overflow does neither:
   it cannot break, and it takes its baseline from its bottom margin edge. */
a { color: inherit; text-decoration: underline; }

/* Wipe underline: the old rule leaves right as the new one enters left.
   Only in the nav and the footer, where the links are short by design. */
.site-nav a, footer a {
  text-decoration: none;
  position: relative;
  display: inline-block;
  overflow: hidden;
}
.site-nav a::before, .site-nav a::after,
footer a::before, footer a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 1px;
  width: 100%; height: 1px;
  background: currentColor;
  /* no resting underline: both rules wait off to the left */
  transform: translateX(-101%);
  transition: transform 1s cubic-bezier(0.19, 1, 0.22, 1);
}
.site-nav a:hover::before, .site-nav a:focus-visible::before,
footer a:hover::before, footer a:focus-visible::before { transform: translateX(101%); }
.site-nav a:hover::after, .site-nav a:focus-visible::after,
footer a:hover::after, footer a:focus-visible::after { transform: translateX(0); }

/* A keyboard user tabbing the nav would otherwise start a one-second
   animation per link. WCAG 2.3.3. */
@media (prefers-reduced-motion: reduce) {
  .site-nav a::before, .site-nav a::after,
  footer a::before, footer a::after { transition: none; }
}

/* Wide content scrolls inside its own box; the page body never does. */
.table-wrap { overflow-x: auto; max-width: 100%; margin: 0 0 24px; }
table { border-collapse: collapse; }
th, td { text-align: left; padding: 4px 24px 4px 0; border-bottom: 1px solid var(--rule); }
th { font-weight: 700; }

img { max-width: 100%; height: auto; display: block; }
blockquote { margin: 0 0 8px; }
hr.delimiter { border: 0; height: 64px; margin: 0; }

/* The ring has to contrast with what is behind it, which is the page, not
   with the element's own text. `currentColor` on a filled button is the
   button's white label, and `outline-offset` then draws that white ring on
   the white page: invisible, exactly where a keyboard user needs it most.
   `--ink` is guaranteed to contrast with `--paper` -- on a tenant site the
   contrast nudge enforces it -- so the ring reads on filled and unfilled
   controls alike. */
:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }



/* The one control the theme carries that a visitor never sees. Fixed in the
   top right so it does not move with the page, and drawn in the site's own
   colours so a customer previewing a dark site is not handed a white box.
   templates/site/base.html renders it only when sites/views.py says this is
   a preview. */
.preview-exit {
  position: fixed;
  top: 16px;
  right: 16px;
  z-index: 20;
  padding: 8px 14px;
  background: var(--ink);
  color: var(--paper);
  font-size: var(--small);
  font-weight: 700;
  text-decoration: none;
  border: 1px solid var(--ink);
}
.preview-exit:hover, .preview-exit:focus-visible {
  background: var(--paper);
  color: var(--ink);
}
/* The margin navigation lives in the same corner, but only a preview has
   anything to make room for. Unscoped, this moved the nav down on every
   published page. */
.is-preview .site-nav--margin { top: 64px; }


/* The one control a published page carries. It closes the page, so it takes
   the between-sections step above it and nothing below: the footer's own
   240px follows. Drawn in the site's colours, like the preview exit. */
.call-to-action {
  margin: 176px 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
/* When the shuffle precedes it, that gap has already been spent. */
.shuffle + .call-to-action { margin-top: 24px; }
.call-to-action a {
  display: inline-block;
  padding: 14px 28px;
  background: var(--ink);
  color: var(--paper);
  font-size: var(--body);
  font-weight: 700;
  text-decoration: none;
  border: 1px solid var(--ink);
}
.call-to-action a:hover, .call-to-action a:focus-visible {
  background: var(--paper);
  color: var(--ink);
}
/* The wipe underline belongs to nav and footer links, not to a filled
   button; it would animate a bar across the label. */
.call-to-action a::before, .call-to-action a::after { content: none; }


/* The shuffle control sits with the closing button but reads as secondary:
   one thing to press, one thing to notice. */
.shuffle { margin: 96px 0 0; }
.shuffle a {
  font-size: var(--small);
  font-weight: 700;
  color: var(--muted);
  text-decoration: underline;
  margin-right: 24px;
}
.shuffle a:hover, .shuffle a:focus-visible { color: var(--ink); }
.shuffle a::before, .shuffle a::after { content: none; }
