/* The homepage's and the blog's look: Pixelify Sans for headings and labels, a serif for prose,
   on the palette and stepped corners in tokens.css. The docs have their own, docs/docs.css. */
* { box-sizing: border-box; }
/* Four type sizes, no more: the title, headings, reading text, and small print (code, labels,
   captions, metadata). */
:root { --fs-xl: 64px; --fs-l: 24px; --fs-m: 17px; --fs-s: 14px; }
@media (max-width: 600px) { :root { --fs-xl: 48px; --fs-l: 22px; --fs-s: 13px; } }
html { background: var(--bg); }
body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: var(--fs-m)/1.65 ui-serif, "New York", Georgia, serif;
  -webkit-font-smoothing: antialiased;
}
a { color: var(--accent); text-underline-offset: 3px; }
code {
  font: var(--fs-s) var(--mono);
  background: var(--chip);
  padding: 1px 5px;
  border-radius: 2px;
}

/* The scene sits behind the top of the page. Under the text column it dissolves into mist
   where the lede begins; in the margins the meadow runs on down the page. The header's height
   is where the text starts, and scene.js reads it. */
body { overflow-x: clip; }
h1, h2, h3, .headline, .meta, .note .label, .lede em, .threads, .kinds, .ladder b, .soon { font-variant-ligatures: none; } /* Pixelify draws "fi" as a broken glyph */
/* overflow-x: the canvas is a whole number of scene pixels wide, so it can be half a pixel wider
   than the window; clipped here it can't scroll the page sideways, and still runs on down. */
.scene { position: relative; height: 420px; overflow-x: clip; }
.scene canvas {
  position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: min(100%, 2400px); height: 900px;
  image-rendering: pixelated;
}
.scene .title {
  position: relative; max-width: 760px; margin: 0 auto; padding: 64px 16px 0;
}
h1 {
  font: 700 var(--fs-xl)/1 var(--pixel);
  margin: 0;
  color: #f3efff;
  letter-spacing: 0.02em;
  text-shadow: 3px 3px 0 #2b2d6a;
}


main, footer { position: relative; }
main { max-width: 760px; margin: 0 auto; padding: 8px 16px 64px; }
.headline { font: 600 var(--fs-l)/1.2 var(--pixel); color: #f3efff; margin: 0 0 16px; max-width: 24em; text-wrap: balance; }
.lede { margin: 0; max-width: 32em; }
.lede em { font-style: normal; font: 600 1em var(--pixel); color: var(--accent); }

h2 {
  font: 600 var(--fs-l)/1.2 var(--pixel);
  color: var(--ink);
  margin: 72px 0 18px;
  display: flex; align-items: center; gap: 12px;
}
h2 { color: var(--fg); position: relative; }
/* A strip of turf and flowers at the far right of each heading (scene.js). */
h2 canvas.sprig { position: absolute; right: 0; bottom: 0; width: 138px; height: 42px; image-rendering: pixelated; pointer-events: none; }

h2::before {
  content: ""; width: 20px; height: 20px; flex: none;
  background: url("/icon.svg") center / contain no-repeat;
  image-rendering: pixelated;
}
p { margin: 0 0 14px; }

/* A framed video: an outline and a stepped panel. scene.js gives the box a margin and draws
   a thin frame in it, leaving an empty gap around the picture. */
.frame { position: relative; margin: 0; }
.frame .box { background: var(--ink); padding: var(--px); }
.frame video, .frame img { display: block; width: 100%; height: auto; background: var(--panel); }
.frame canvas.stones { position: absolute; pointer-events: none; image-rendering: pixelated; }
.frame figcaption { font-size: var(--fs-s); color: var(--muted); margin-top: 6px; }

/* A note card: a panel with stepped corners and a gold label, for asides the reader
   shouldn't miss. */
.note { margin: 40px 0; filter: drop-shadow(var(--px) var(--px) 0 var(--shadow)); }
.note .card { --s: var(--px); background: var(--panel); padding: 20px 24px 22px; box-shadow: inset 0 0 0 var(--px) var(--chip); }
.note .label { font: 600 var(--fs-s)/1 var(--pixel); color: var(--gold); letter-spacing: 0.04em; margin: 0 0 10px; display: flex; align-items: center; gap: 8px; }
.note .label img { width: 16px; height: 16px; image-rendering: pixelated; }
.note p { margin: 0; }
.note p + p { margin-top: 10px; }
.meta {
  font: var(--fs-s)/1.4 var(--pixel); color: var(--muted);
  display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 8px;
}
.meta .date { color: var(--gold); }
.meta .commit { font: 1em var(--mono); align-self: center; } /* a hash mixes letters and digits; all of it in mono */
/* The homepage's text sits on a sheet of page colour laid on the meadow, so it never runs over
   the scene; the meadow carries on either side and fades into mist behind it (scene.js). */
main.sheet { max-width: 808px; margin-top: 124px; padding: 40px 40px 64px; background: var(--bg); }

/* The architecture figure (web/lib/architecture.ts): three threads as swimlanes, laid out by CSS
   alone so nothing moves when threads.js adds its overlay. A narrow figure has the lanes as columns
   with time running down; a wide one (it steps out of the column, like the claim above) has them as
   rows with time running right. Each lane is a subgrid, so a moment (--t, or --r as a row) lines up
   across all three. One ink; the accent marks what is proved, gold the frame being made. */
figure.threads { container-type: inline-size; margin: 32px auto 8px; max-width: 640px; }
.threads .lanes { position: relative; display: grid; gap: 22px 8px;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1.2fr) minmax(0, 0.65fr); grid-template-rows: auto repeat(4, auto); }
.threads .lane { --s: var(--px); display: grid; grid-row: 1 / -1; grid-template-rows: subgrid; align-items: start;
  padding: 10px 6px 12px; background: var(--panel); }
.threads .lane.main { grid-column: 1; }
.threads .lane.lean { grid-column: 2; background: color-mix(in srgb, var(--accent) 9%, var(--panel)); box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent) 45%, transparent); }
.threads .lane.render { grid-column: 3; }
.threads .head { grid-row: 1; margin: 0; padding: 0 2px; font-size: var(--fs-s); line-height: 1.35; }
.threads .head > span { display: block; }
.threads .nm { font: 600 var(--fs-s)/1.25 var(--pixel); letter-spacing: 0.06em; text-transform: uppercase; }
.threads .sub, .threads .step i, .threads .tag i { font-style: italic; color: var(--muted); }
.threads .tag { margin-top: 6px; font: 600 var(--fs-s)/1.25 var(--pixel); color: var(--muted); }
.threads .tag i { display: block; font: italic var(--fs-s)/1.35 ui-serif, "New York", Georgia, serif; }
.threads .lean .tag { color: var(--accent); }
/* Steps and chips are outlined in 2px that follows the stepped corners: the box is the line's
   colour, and a copy of its shape 2px in is the fill. */
.threads .step, .threads .chip { --s: 3px; --line: var(--fg); --fill: var(--bg); position: relative; isolation: isolate;
  background: var(--line); transition: background-color 0.6s; }
.threads .step::before, .threads .chip::before { content: ""; position: absolute; inset: 2px; z-index: -1; clip-path: inherit;
  background: var(--fill); transition: background-color 0.6s; }
.threads .step { grid-row: var(--r); display: flex; flex-direction: column; padding: 7px 9px 8px; line-height: 1.3; font-size: var(--fs-s); }
.threads .step b { font-weight: normal; }
.threads .n { display: inline-block; min-width: 2ch; font: var(--fs-s) var(--mono); font-style: normal; color: var(--fg); }
.threads .ask { --line: var(--muted); }
.threads .work { gap: 8px; }
.threads .chips { display: flex; flex-direction: column; align-items: stretch; gap: 2px; }
.threads .chip { --line: var(--muted); --fill: var(--panel); padding: 3px 8px 4px; text-align: center; }
.threads .chev { display: block; width: 8px; height: 12px; margin: 0 auto; transform: rotate(90deg); fill: none; stroke: var(--muted); stroke-width: 2; shape-rendering: crispEdges; }
.threads .ticks { grid-row: 2 / -1; align-self: stretch; display: flex; flex-direction: column; justify-content: space-between; padding: 0 2px; }
.threads .tk { display: flex; align-items: center; gap: 6px; font: var(--fs-s)/1 var(--mono); color: var(--muted); transition: color 0.6s, opacity 0.6s; }
.threads .tk.ahead { opacity: 0.4; }
.threads .tk::before { content: ""; flex: none; width: 10px; height: 2px; background: currentColor; }
.threads .tk .n { color: inherit; }
/* Lit by the playhead, then fading back as it moves on. */
.threads .lit { transition-duration: 0.12s; }
.threads .step.lit, .threads .chip.lit { --line: var(--gold); --fill: color-mix(in srgb, var(--gold) 14%, var(--bg)); }
.threads .lit::before { transition-duration: 0.12s; }
.threads .tk.lit { color: var(--gold); }
.threads svg.wires { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; opacity: 0; transition: opacity 0.2s; }
.threads svg.wires.on { opacity: 1; }
.threads .wires * { fill: none; stroke-width: 2; shape-rendering: crispEdges; stroke-linejoin: miter; }
.threads .wires .w { stroke: var(--fg); }
.threads .wires .dash { stroke-dasharray: 4 4; }
.threads .wires .hot { stroke: var(--gold); }
.threads .wires .ph { stroke: var(--gold); stroke-opacity: 0.55; stroke-dasharray: 2 4; }
figure.threads figcaption { font-size: var(--fs-s); color: var(--muted); margin: 14px auto 0; max-width: 34em; text-align: center; text-wrap: balance; }
@media (min-width: 1100px) {
  figure.threads { max-width: none; margin: 36px calc((100% - min(1240px, 100vw - 32px)) / 2) 8px; }
}
@container (min-width: 960px) {
  /* Lanes as rows: each lane's name in a column of its own, so no wire crosses it. */
  .threads .lanes { gap: 14px 28px; grid-template-columns: auto auto auto minmax(0, 1fr) minmax(0, auto); grid-template-rows: repeat(3, auto); }
  .threads .lane, .threads .lane.main, .threads .lane.lean, .threads .lane.render { grid-column: 1 / -1; grid-row: auto;
    grid-template-columns: subgrid; grid-template-rows: auto; align-items: center; padding: 14px 20px; }
  .threads .head { grid-column: 1; grid-row: 1; white-space: nowrap; }
  .threads .step { grid-row: 1; grid-column: var(--r); }
  .threads .ask, .threads .frame { max-width: 15em; }
  .threads .chips { flex-direction: row; align-items: center; gap: 6px; }
  .threads .chip { flex: 1; padding-inline: 6px; white-space: nowrap; }
  .threads .chev { transform: none; flex: none; }
  .threads .ticks { grid-row: 1; grid-column: 2 / -1; flex-direction: row; padding: 2px 0 0; }
  .threads .tk { flex-direction: column; gap: 6px; }
  .threads .tk::before { width: 2px; height: 10px; }
}

/* Claims: an annotated claim, the kinds, and the evidence ladder. */
h3.sub { font: 600 var(--fs-m)/1.3 var(--pixel); margin: 36px 0 10px; }
@media (min-width: 1100px) {
  .anatomy { position: relative; margin: 30px calc((100% - min(1240px, 100vw - 32px)) / 2) 24px; padding: 24px 8px;
    background: var(--bg); display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); grid-template-rows: repeat(4, auto);
    grid-auto-flow: dense; gap: 22px 56px; align-content: center; }
  .anatomy pre { grid-column: 2; grid-row: 1 / -1; align-self: center; line-height: 2.3; padding: 18px 26px 18px 14px; }
  .anatomy .mk { display: none; }
  .anatomy .br { --c: var(--gold); padding-bottom: 4px;
    background: linear-gradient(var(--c), var(--c)) left bottom / 100% 2px no-repeat,
      linear-gradient(var(--c), var(--c)) left bottom / 2px 6px no-repeat,
      linear-gradient(var(--c), var(--c)) right bottom / 2px 6px no-repeat; }
  .anatomy.pointing .br:not(.hot) { --c: color-mix(in srgb, var(--gold) 35%, transparent); }
  .anatomy .callouts { display: contents; }
  .anatomy li { list-style: none; padding: 0; margin: 0; line-height: 1.5; }
  .anatomy li::before { display: none; }
  .anatomy li b { display: block; margin-bottom: 2px; }
  /* The notes take the margins in CSS alone, so the figure paints in its final shape and
     annotate.js only adds the leaders. Dense flow stacks each side's notes in their own column. */
  .anatomy li { align-self: center; }
  .anatomy li.l { grid-column: 1; text-align: right; }
  .anatomy li.r { grid-column: 3; }
}
table.kinds { width: 100%; border-collapse: collapse; margin: 8px 0 4px; }
.kinds th { font: 600 var(--fs-s) var(--pixel); color: var(--muted); text-align: left; letter-spacing: 0.04em; padding: 0 12px 6px 0; }
.kinds td { padding: 9px 12px 9px 0; border-top: 2px solid var(--rule); vertical-align: top; }
.kinds td:first-child { font: 600 var(--fs-s) var(--pixel); color: var(--accent); white-space: nowrap; }
.kinds td:last-child { color: var(--muted); }
.ladder > li::before { content: ""; width: 18px; height: 18px; left: 6px; top: 5px; }
.ladder > li:nth-child(1)::before { background: var(--accent); }
.ladder > li:nth-child(2)::before { background: #6f8fc0; }
.ladder > li:nth-child(3)::before { background: #5a5a96; }
.ladder > li:nth-child(4)::before { background: var(--chip); }
.ladder b { font: 600 var(--fs-m) var(--pixel); }
.soon { font: var(--fs-s) var(--pixel); color: var(--gold); margin-left: 6px; }

/* Trails: the milestone and the progress log. */
.trail { list-style: none; margin: 0; padding: 0; position: relative; }
.trail::before {
  content: ""; position: absolute; left: 13px; top: 18px; bottom: 18px; width: 4px;
  background: repeating-linear-gradient(to bottom, var(--rule) 0 8px, transparent 8px 16px);
}
.trail > li { position: relative; padding-left: 48px; margin-bottom: 18px; }
.trail > li::before {
  position: absolute; left: 0; top: 0;
  width: 30px; height: 30px;
  display: grid; place-items: center;
  font: 600 var(--fs-s)/1 var(--pixel);
  background: var(--chip); color: var(--ink);
}
.trail > li::before { color: var(--fg); }

ol.trail { counter-reset: step; }
ol.trail > li { counter-increment: step; }
ol.trail > li::before { content: counter(step); }
.log > li { margin-bottom: 56px; }
.log .frame { width: min(100%, 640px * var(--ar, 1.6)); } /* a portrait shot or video stays at most about 640px tall */
/* The log is in the page's HTML, and laying out every figure before the first paint costs more
   than the rest of the page; a figure off screen is skipped until the reader nears it. Those
   above a linked entry are laid out in full, so a link to one lands on its heading. */
.log .frame { content-visibility: auto; contain-intrinsic-size: auto 600px; }
.log > li:has(~ li > :target) .frame { content-visibility: visible; }
.log > li::before { content: ""; background: var(--gold); width: 18px; height: 18px; left: 6px; top: 6px; }
.log h3 { font: 600 var(--fs-m)/1.3 var(--pixel); margin: 0 0 14px; color: var(--ink); }
.log h3 { color: var(--fg); }
.log .text p { margin: 0 0 10px; } /* a note: an entry with no video */

/* The trail markers share the stepped corners at a smaller step. */
.trail > li::before { clip-path: polygon(0 4px, 4px 4px, 4px 0, calc(100% - 4px) 0, calc(100% - 4px) 4px, 100% 4px, 100% calc(100% - 4px), calc(100% - 4px) calc(100% - 4px), calc(100% - 4px) 100%, 4px 100%, 4px calc(100% - 4px), 0 calc(100% - 4px)); }

footer {
  max-width: 760px; margin: 0 auto; padding: 24px 16px 56px;
  font: var(--fs-s)/1.4 var(--pixel); color: var(--muted);
  display: flex; align-items: center; gap: 10px;
}
footer img { width: 32px; height: 32px; image-rendering: pixelated; }
footer .feed { margin-left: auto; }
footer a { color: var(--accent); }
.scene .title .links { display: flex; flex-wrap: wrap; gap: 8px 18px; margin: 14px 0 0; font: 600 var(--fs-m)/1 var(--pixel); font-variant-ligatures: none; }
.scene .title .links a { color: var(--fg); text-shadow: 1px 1px 0 var(--ink); text-decoration: none; box-shadow: inset 0 -3px 0 var(--chip); padding-bottom: 3px; }
.scene .title .links a[aria-current="page"] { box-shadow: inset 0 -3px 0 var(--gold); }
.scene .title .links a:hover { color: var(--accent); }
.scene .title .links a.end { margin-left: auto; }
.scene .title .links a.gh { display: inline-flex; align-items: center; box-shadow: none; }
.scene .title .links a.gh img { width: 20px; height: 20px; image-rendering: pixelated; margin: -4px 0; }
/* Over the Octocat in the lake; scene.js places it. */
.scene .octocat { position: absolute; z-index: 1; cursor: pointer; }
.scene .octocat:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }

/* A feed link: a small pixel label with the feed's orange square. */
a.feed { font: 600 var(--fs-s)/1 var(--pixel); font-variant-ligatures: none; color: var(--muted); text-decoration: none; display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
a.feed::before { content: ""; width: 12px; height: 12px; flex: none; background:
  radial-gradient(circle at 2px 10px, var(--bg) 0 1.5px, transparent 2px),
  #e8924a; clip-path: polygon(0 2px, 2px 2px, 2px 0, 10px 0, 10px 2px, 12px 2px, 12px 10px, 10px 10px, 10px 12px, 2px 12px, 2px 10px, 0 10px); }
a.feed:hover { color: var(--accent); }

/* The blog (site/web/layouts/blog): the index's list of posts, and a post's page. On a post the
   scene names the blog in the title's place, and the post's own title is a headline under the
   mist, as the homepage's is under "Cairn". */
.scene .title .blog-name { margin: 0; font: 700 var(--fs-xl)/1 var(--pixel); letter-spacing: 0.02em; text-shadow: 3px 3px 0 #2b2d6a; }
.scene .title .blog-name a { color: #f3efff; text-decoration: none; }
/* With no video plate on the meadow, the scene fades out about 80 scene pixels below the header
   (scene.js), so the intro or the post starts below the mist instead of on it. */
.intro { line-height: 1.6; margin: 190px 0 0; max-width: 34em; }
.intro + .meta { margin-top: 14px; }
main.blog .post { margin-top: 190px; }
.post-title { font: 600 var(--fs-l)/1.2 var(--pixel); color: #f3efff; margin: 0; max-width: 24em; text-wrap: balance; }
.post-title + .meta { margin: 10px 0 28px; }
.post .meta span + span, ol.posts .meta span { color: var(--muted); }
.post .body ul { padding-left: 22px; margin: 0 0 14px; }
.post .body li { margin-bottom: 6px; }
.post .body li::marker { color: var(--gold); }
blockquote { margin: 22px 0; padding: 2px 0 2px 20px; box-shadow: inset 3px 0 0 var(--gold); }
blockquote p { margin: 0; }
.progress h2 { margin-top: 72px; }
ol.posts { list-style: none; margin: 44px 0 0; padding: 0; }
ol.posts > li { margin: 0 0 40px; }
ol.posts .meta { margin: 0; }
ol.posts h2 { margin: 6px 0 8px; display: block; }
ol.posts h2::before { display: none; }
ol.posts h2 a { color: var(--fg); text-decoration: none; }
ol.posts h2 a:hover { color: var(--accent); }
ol.posts p:last-child { margin: 0; color: var(--muted); max-width: 36em; }
nav.pager { display: flex; gap: 24px; margin: 72px 0 0; padding-top: 20px; border-top: 2px solid var(--rule); }
nav.pager a { display: flex; flex-direction: column; gap: 4px; max-width: 48%; text-decoration: none; color: var(--fg); font: 600 var(--fs-m)/1.3 var(--pixel); }
nav.pager a span { font: 600 var(--fs-s)/1 var(--pixel); color: var(--gold); }
nav.pager a.newer { margin-left: auto; text-align: right; }
nav.pager a:hover { color: var(--accent); }

/* The homepage's pointer to the latest post (site/web/lib/site.ts). */
.latest .label a { color: inherit; text-decoration: none; }
.latest h3 { font: 600 var(--fs-m)/1.3 var(--pixel); margin: 0 0 8px; font-variant-ligatures: none; }
.latest h3 a { color: var(--fg); text-decoration: none; }
.latest h3 a:hover { color: var(--accent); }
.latest .more { margin-top: 12px; font: var(--fs-s)/1.4 var(--pixel); display: flex; flex-wrap: wrap; gap: 6px 18px; }

/* Get started, under the lede: the way in, the docs and the version. */
.start { margin: 28px 0 0; display: flex; flex-wrap: wrap; align-items: center; gap: 10px 22px; font: var(--fs-m)/1.4 var(--pixel); }
.start .go { --s: var(--px); background: var(--gold); color: var(--ink); padding: 10px 18px; text-decoration: none; font-weight: 600; }
.start .go:hover { filter: brightness(1.08); }

@media (max-width: 600px) {
  :root { --px: 3px; }
  .scene .title { padding-top: 44px; }
  main.sheet { margin-top: 16px; padding: 28px 16px 56px; }
  .intro, main.blog .post { margin-top: 110px; }
  .scene { height: 290px; }
  h2 canvas.sprig { width: 92px; height: 28px; }
  .claim pre { padding: 14px; }
  .kinds thead { display: none; }
  .kinds tr { display: block; border-top: 2px solid var(--rule); padding: 8px 0; }
  .kinds td { display: block; border: 0; padding: 2px 0; }
}

/* The Octocat at the foot of the page (scene.js): in the margin right of the footer on a wide
   window, under the RSS link otherwise. Its canvas is 36 x 30 scene pixels. */
footer { padding-bottom: 100px; }
.peek { position: absolute; bottom: 0; right: 16px; width: 108px; height: 90px; }
.peek canvas { display: block; width: 100%; height: 100%; image-rendering: pixelated; }
.peek:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
@media (min-width: 1100px) { footer { padding-bottom: 56px; } .peek { right: auto; left: calc(100% + 60px); } }
@media (max-width: 600px) { footer { padding-bottom: 72px; } .peek { width: 72px; height: 60px; } }

/* Pixelify draws "fi" as a broken glyph. Last, because a later font shorthand resets it. */
.blog-name, .post-title, .post .meta, ol.posts h2, ol.posts .meta, nav.pager a, nav.pager a span { font-variant-ligatures: none; }
