/* Engineering document: the identity is the drawing conventions (title block,
   drawing register, frame, dimension lines, DIN-like type), not a blue canvas.
   Paper and graphite backgrounds keep long reading calm and let screenshots and
   coloured charts sit without clashing. Blue is the ink, red the redline. */

:root {
  --paper: #f7f5ef;
  --sheet: #fdfcf8;
  --ink: #3a5f86;
  --text: #2a2f35;
  --dim: #6b7580;
  --line: #3a5f86;
  /* millimetre paper: 1 mm fine, 5 mm medium, 10 mm bold, in the classic
     orange-brown print colour */
  --mm1: rgba(196, 104, 52, 0.07);
  --mm5: rgba(196, 104, 52, 0.13);
  --mm10: rgba(196, 104, 52, 0.22);
  --redline: #a8493e;
  --code-bg: #efece3;
  /* muted and of one saturation, so no series shouts, but spread in
     lightness so they stay apart without colour */
  --s0: #6f8fb2;
  --s1: #b3bcc5;
  --s2: #b86a5e;
  --s3: #cfae6e;
  --s4: #7c9c84;
  /* builder roles, the same in every post: kaniko orange and grey from the
     logo, softened, and a light blue for BuildKit that stays clear of the ink */
  --ours: #d99a3d;
  --google: #a6adb4;
  --buildkit: #86a7cc;
  --string: #8a6a2e;
  --builtin: #4f7a5b;
  --ring: #8d959d;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper: #16191d;
    --sheet: #1d2126;
    --ink: #9bb5d1;
    --text: #dfe2e6;
    --dim: #98a1ab;
    --line: #9bb5d1;
    --mm1: rgba(214, 140, 90, 0.05);
    --mm5: rgba(214, 140, 90, 0.09);
    --mm10: rgba(214, 140, 90, 0.16);
    --redline: #d58a7f;
    --code-bg: #262b31;
    --s0: #8fadcf;
    --s1: #8d97a2;
    --s2: #d58a7f;
    --s3: #cfb179;
    --s4: #92b59a;
    --ours: #e3ad5c;
    --google: #8a939c;
    --buildkit: #93b3d6;
    --string: #cfb179;
    --builtin: #92b59a;
    --ring: #7a838c;
  }
}

* { box-sizing: border-box; }

/* Millimetre paper behind the sheet. 6px stands in for a millimetre, a real one
   is too dense to read on screen. */
body {
  background-image:
    linear-gradient(var(--mm10) 1px, transparent 1px),
    linear-gradient(90deg, var(--mm10) 1px, transparent 1px),
    linear-gradient(var(--mm5) 1px, transparent 1px),
    linear-gradient(90deg, var(--mm5) 1px, transparent 1px),
    linear-gradient(var(--mm1) 1px, transparent 1px),
    linear-gradient(90deg, var(--mm1) 1px, transparent 1px);
  background-size: 60px 60px, 60px 60px, 30px 30px, 30px 30px, 6px 6px, 6px 6px;
}

body {
  margin: 0;
  color: var(--text);
  background-color: var(--paper);
  font: 17px/1.65 "DIN Next", "DIN 2014", "DIN Pro", Barlow, "Helvetica Neue", Arial, sans-serif;
}

a { color: var(--ink); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--redline); }

code, pre, .titleblock, .register { font-family: ui-monospace, "JetBrains Mono", "DejaVu Sans Mono", monospace; }

.topbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background: var(--sheet);
  border-bottom: 2px solid var(--line);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-size: 14px;
}
.brand { display: flex; align-items: center; gap: 10px; font-weight: 700; color: var(--ink); text-decoration: none; }
.brand img { height: 24px; width: 24px; }

/* The sheet width sets the line length, text fills the sheet. */
.wrap { max-width: 900px; margin: 0 auto; padding: 32px 16px 80px; }

/* Binder: the page is the top sheet of a stack, the edges of two sheets below
   show there is more. Register tabs sit on the top edge. The active tab is cut
   from the top sheet: same paper, no line between them. Inactive tabs sit
   behind in darker paper. The stacked edges replace the double drawing frame. */
.binder .sheet { outline: none; box-shadow: 8px 8px 0 -1px var(--sheet), 8px 8px 0 0 var(--line), 16px 16px 0 -1px var(--sheet), 16px 16px 0 0 var(--line); }
/* Spiral binding down the left edge, one loop every 18px. One pseudo-element
   straddles the sheet edge, which sits 20px into it. Each loop is an ellipse
   centred on the edge. In the air left of the edge the whole loop shows. Over
   the sheet only the upper strand shows, coming over the edge and ending in its
   hole: a strip of sheet colour hides the lower strand, which runs beneath the
   paper. Layers from the top: loop in the air, hole, sheet strip, full loop.
   The wider left padding keeps text clear of the holes. */
main.binder .sheet { position: relative; padding-left: 64px; }
.binder .sheet::before {
  content: ""; position: absolute; top: 18px; bottom: 18px; left: -20px; width: 44px; pointer-events: none;
  background:
    radial-gradient(16px 6.5px at 20px 9px, transparent 64%, var(--ring) 68% 100%, transparent 104%) 0 0 / 20px 18px repeat-y,
    radial-gradient(circle at 34px 9px, var(--paper) 2.8px, var(--line) 3.3px 4px, transparent 4.4px) 0 0 / 100% 18px repeat-y,
    linear-gradient(transparent 9px, var(--sheet) 9px) 20px 0 / 24px 18px repeat-y,
    radial-gradient(16px 6.5px at 20px 9px, transparent 64%, var(--ring) 68% 100%, transparent 104%) 0 0 / 100% 18px repeat-y;
}
.tabs { display: flex; gap: 6px; margin-left: 24px; }
.tab { padding: 8px 16px; border: 1px solid var(--line); border-bottom: none; border-radius: 6px 6px 0 0; background: var(--code-bg); color: var(--dim); font: 600 11px ui-monospace, "JetBrains Mono", "DejaVu Sans Mono", monospace; letter-spacing: 0.12em; text-transform: uppercase; text-decoration: none; }
.tab:hover { color: var(--ink); }
.tab.active { position: relative; z-index: 1; margin-bottom: -2px; padding-bottom: 10px; border-width: 2px 2px 0; background: var(--sheet); color: var(--ink); }
/* Phones get no notebook and no grid: plain paper, and the tabs and the topbar
   links move into a menu behind the ☰ in the top left. */
.menu { display: none; }
@media (max-width: 720px) {
  .binder .sheet { box-shadow: none; }
  .binder .sheet::before { display: none; }
  body { background-image: none; background-color: var(--sheet); }
  main.binder .sheet { padding: 0; border: none; }
  .tabs, .topbar > nav { display: none; }
  .topbar { justify-content: flex-start; gap: 14px; }
  .menu { display: block; position: relative; }
  .menu summary { list-style: none; cursor: pointer; color: var(--ink); font-size: 20px; line-height: 1; }
  .menu summary::-webkit-details-marker { display: none; }
  .menu nav { position: absolute; top: calc(100% + 12px); left: -16px; z-index: 2; display: flex; flex-direction: column; min-width: 220px; padding: 6px 0; border: 1px solid var(--line); background: var(--sheet); }
  .menu nav a { padding: 10px 16px; text-decoration: none; }
}

/* The sheet: plain paper in a drawing frame, the grid stays behind it. */
.sheet { background: var(--sheet); border: 2px solid var(--line); outline: 1px solid var(--line); outline-offset: 5px; padding: 32px; }

h1, h2, h3 { color: var(--ink); font-weight: 600; letter-spacing: 0.01em; line-height: 1.25; }
h1 { font-size: 2.1em; margin: 0 0 12px; }

/* Dimension line under section headings: a rule with end ticks. */
.prose h2 {
  margin-top: 2.2em;
  padding-bottom: 6px;
  background:
    linear-gradient(var(--line), var(--line)) left bottom / 100% 1px no-repeat,
    linear-gradient(var(--line), var(--line)) left bottom / 1px 9px no-repeat,
    linear-gradient(var(--line), var(--line)) right bottom / 1px 9px no-repeat;
}

.dim, .back { color: var(--dim); }
.back { display: inline-block; margin-bottom: 12px; font-size: 14px; }
.draft { color: var(--redline); text-transform: uppercase; letter-spacing: 0.1em; }

/* Blockquotes are fine print: methodology and other notes nobody has to read. */
.prose blockquote { margin: 1em 0; padding: 0; border: none; font-size: 0.8em; line-height: 1.5; color: var(--dim); }
.prose blockquote p { margin: 0; }

.lead { font-size: 1.15em; color: var(--dim); }

/* Title block, after DIN EN ISO 7200, across the top of the sheet. */
.titleblock { display: grid; grid-template-columns: repeat(3, 1fr); border: 1px solid var(--line); margin-bottom: 28px; font-size: 13px; }
.titleblock div { border: 1px solid var(--line); margin: -1px 0 0 -1px; padding: 4px 8px; overflow-wrap: anywhere; }
.titleblock .title { grid-column: 1 / -1; }
.titleblock .title strong { display: block; color: var(--ink); font: 600 2em/1.2 "DIN Next", "DIN 2014", Barlow, "Helvetica Neue", Arial, sans-serif; padding: 4px 0 6px; }
.titleblock span, .register th { display: block; font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--dim); }

/* Drawing register as the index. */
.register { width: 100%; border-collapse: collapse; font-size: 14px; }
.register th, .register td { border: 1px solid var(--line); padding: 6px 10px; text-align: left; vertical-align: top; }
.register th { display: table-cell; }
.register td.title { font-family: "DIN Next", "DIN 2014", Barlow, "Helvetica Neue", Arial, sans-serif; font-size: 16px; }

.prose code { background: var(--code-bg); padding: 0.1em 0.3em; }
.prose pre { background: var(--code-bg); border-left: 3px solid var(--line); padding: 12px; overflow-x: auto; }
.prose pre code { background: none; padding: 0; }
.prose table { display: block; width: max-content; max-width: 100%; margin: 1.5em auto; overflow-x: auto; border-collapse: collapse; font-size: 15px; }
.prose th, .prose td { border: 1px solid var(--line); padding: 4px 10px; text-align: left; }
/* The register is page structure, not a figure: full width, unlike data tables. */
.prose table.register { display: table; width: 100%; margin: 1em 0; font-size: 14px; }
.register td:not(.title) { white-space: nowrap; }
@media (max-width: 720px) { .register th:last-child, .register td:last-child { display: none; } }
.prose img { max-width: 100%; border: 1px solid var(--line); }

/* Homepage: not a drawing, so no title block and no double frame. The intro
   reads larger, features sit in a grid of framed cards. */
.sheet.plain { border: 1px solid var(--line); outline: none; padding: 40px 40px 32px; }
.sheet.plain h1 { font-size: 2em; margin: 0 0 10px; }
.cards { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin: 1.5em 0; }
.card { border: 1px solid var(--line); padding: 14px 16px; background: var(--sheet); }
.card h3 { margin: 0 0 6px; font-size: 1.05em; }
.card p { margin: 0; color: var(--text); font-size: 0.95em; }
.card { display: flex; flex-direction: column; }
.card h3 a { text-decoration: none; }
.card h3 img { height: 1.5em; border: none; vertical-align: -0.35em; margin-right: 8px; }
@media (max-width: 720px) { .cards { grid-template-columns: 1fr; } }

/* Sponsors and maintainers, centred rows of pictures. Corporate logos sit in
   framed cells of a fixed width, so another sponsor does not stretch the rest.
   Sponsor portraits carry no text, names are in the tooltips. Maintainers get
   their handle under the portrait, they are who a visitor would talk to. */
.home p:has(> a > img[src$="-logo.svg"]) { display: flex; flex-wrap: wrap; justify-content: center; gap: 16px; }
.home p > a:has(> img[src$="-logo.svg"]) { display: flex; align-items: center; justify-content: center; width: 240px; height: 104px; padding: 24px; border: 1px solid var(--line); background: var(--sheet); }
.home a > img[src$="-logo.svg"] { max-height: 40px; max-width: 100%; border: none; }
.home p:has(> a > img[src^="data/sponsors/"]:not([src$="-logo.svg"])),
.home p:has(> a > img[src^="data/maintainers/"]) { display: flex; flex-wrap: wrap; justify-content: center; gap: 14px 28px; }
.home a > img[src^="data/sponsors/"]:not([src$="-logo.svg"]),
.home a > img[src^="data/maintainers/"] { display: block; width: 64px; height: 64px; border-radius: 50%; border: 1px solid var(--line); }
.home p > a:has(> img[src^="data/maintainers/"]) { display: flex; flex-direction: column; align-items: center; gap: 6px; text-decoration: none; font: 12px ui-monospace, "JetBrains Mono", "DejaVu Sans Mono", monospace; }

/* Timeline: a year axis like a dimension line, eras in the builder colours,
   callout leaders down to the labels. */
.timeline { margin: 2em 0 1em; }
.timeline svg { width: 100%; height: auto; display: block; }
.timeline text { fill: var(--text); font: 13px "DIN Next", "DIN 2014", Barlow, "Helvetica Neue", Arial, sans-serif; }
.timeline .year { fill: var(--dim); font: 11px ui-monospace, "DejaVu Sans Mono", monospace; }
.timeline .year.marked { fill: var(--ink); font-weight: 700; }
.timeline .date { fill: var(--ink); font: 700 11px ui-monospace, "DejaVu Sans Mono", monospace; }
.timeline .axis, .timeline .leader { stroke: var(--line); stroke-width: 1; fill: none; }
.timeline .event { fill: var(--sheet); stroke: var(--ink); stroke-width: 2; }
.timeline .track { fill: var(--dim); font: 10px ui-monospace, "DejaVu Sans Mono", monospace; letter-spacing: 0.08em; text-transform: uppercase; }
.timeline .ours { fill: var(--ours); }
.timeline .google { fill: var(--google); }
.topbar nav a { margin-left: 18px; text-decoration: none; }

/* Colour dot for a series role, the same colours as the charts. */
.dot { display: inline-block; width: 0.6em; height: 0.6em; border-radius: 50%; margin-right: 0.45em; vertical-align: 0.05em; }
.dot.ours { background: var(--ours); }
.dot.google { background: var(--google); }
.dot.buildkit { background: var(--buildkit); }
/* Two code blocks next to each other, stacked on narrow screens. */
.side-by-side { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; align-items: start; }
.side-by-side pre { margin: 0; font-size: 13px; }
@media (max-width: 720px) { .side-by-side { grid-template-columns: 1fr; } }

/* Syntax highlighting, chroma classes, in the palette's muted tones. */
.chroma .k, .chroma .kd, .chroma .kn, .chroma .kr { color: var(--ink); font-weight: 600; }
.chroma .s, .chroma .s1, .chroma .s2, .chroma .se, .chroma .sb, .chroma .sd { color: var(--string); }
.chroma .c, .chroma .c1, .chroma .cm, .chroma .cp { color: var(--dim); font-style: italic; }
.chroma .nb, .chroma .nv, .chroma .na, .chroma .nf { color: var(--builtin); }
.chroma .m, .chroma .mi, .chroma .mf { color: var(--string); }
.chroma .o, .chroma .p { color: var(--dim); }

.chart { margin: 1.8em 0; border: 1px solid var(--line); padding: 12px; }
.chart svg { width: 100%; height: auto; display: block; }
.chart text { fill: var(--text); font: 12px ui-monospace, "DejaVu Sans Mono", monospace; }
.chart .value, .chart .legend { fill: var(--dim); }
.chart .group { font-weight: 600; fill: var(--ink); }
.chart .icon-archived { fill: var(--google); }
.chart .s0 { fill: var(--s0); }
.chart .s1 { fill: var(--s1); }
.chart .s2 { fill: var(--s2); }
.chart .s3 { fill: var(--s3); }
.chart .s4 { fill: var(--s4); }
.chart .ours { fill: var(--ours); }
.chart .google { fill: var(--google); }
.chart .buildkit { fill: var(--buildkit); }
/* Print: A4 on white. The light palette always, whatever the screen uses. The
   page margin stands in for the sheet frame. Code wraps instead of being clipped,
   and blocks that make no sense split stay on one page. */
@page { size: A4; margin: 16mm 15mm; }
@media print {
  :root {
    --paper: #fff; --sheet: #fff; --ink: #3a5f86; --text: #2a2f35; --dim: #6b7580; --line: #3a5f86;
    --redline: #a8493e; --code-bg: #f3f1ea;
    --ours: #d99a3d; --google: #a6adb4; --buildkit: #86a7cc; --string: #8a6a2e; --builtin: #4f7a5b;
  }
  * { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
  body { background: #fff; font-size: 10.5pt; line-height: 1.5; }
  .topbar, .back, .tabs { display: none; }
  .binder { padding: 0; }
  main.binder .sheet { padding: 0; box-shadow: none; }
  .binder .sheet::before { display: none; }
  .wrap { max-width: none; padding: 0; }
  .sheet { border: none; outline: none; padding: 0; }
  .titleblock { grid-template-columns: repeat(3, 1fr); font-size: 8pt; }
  .titleblock .title strong { font-size: 1.8em; }
  a { color: inherit; text-decoration: none; }
  .prose pre { white-space: pre-wrap; overflow-wrap: anywhere; font-size: 8pt; }
  .side-by-side { grid-template-columns: 1fr 1fr; }
  .side-by-side pre { font-size: 6.4pt; }
  .cards { grid-template-columns: 1fr 1fr; }
  h2, h3 { break-after: avoid; }
  pre, table, .chart, .titleblock, .side-by-side, .card, blockquote { break-inside: avoid; }
  p { orphans: 3; widows: 3; }
}

@media (max-width: 720px) {
  .sheet { padding: 16px; }
  .titleblock { grid-template-columns: 1fr 1fr; }
  .titleblock .title strong { font-size: 1.5em; }
}
