/* p5loom site, in the Dawnshift design language (dawnshift.co).
   Night is the base and warms toward dawn as you scroll. Paper is the text. Dawn is the one accent, used sparingly.
   Urbanist sets the display, Hanken Grotesk the reading text, IBM Plex Mono the labels and code.
   Tokens come from tokens.css (written by the build from site/brand.mjs). No inline styles (the CSP forbids them). */

@import url("fonts.css");
@import url("tokens.css");

:root {
  --display: "Urbanist", system-ui, -apple-system, "Segoe UI", sans-serif;
  --sans: "Hanken Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --gutter: 20px;
  --card-radius: 20px;
  --panel-radius: 24px;
  --control-radius: 4px;
  /* 0 at the top of the page, 1 at the bottom. site.js sets it on scroll. */
  --dawn-p: 0;
}

* { box-sizing: border-box; }
html { background: hsl(var(--night)); -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100vh;
  background: hsl(var(--night));
  color: hsl(var(--paper));
  font: 400 17px/1.65 var(--sans);
  -webkit-font-smoothing: antialiased;
  font-feature-settings: "ss01";
}

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

a {
  color: hsl(var(--paper));
  text-decoration-line: underline;
  text-decoration-color: hsl(var(--dawn) / 0.7);
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}
a:hover { text-decoration-color: hsl(var(--dawn)); text-decoration-thickness: 2px; }

:focus-visible { outline: 2px solid hsl(var(--dawn)); outline-offset: 3px; border-radius: 2px; }

.skip {
  position: absolute; left: var(--gutter); top: -120px; z-index: 20;
  background: hsl(var(--paper)); color: hsl(var(--night));
  font: 400 0.8rem/1 var(--mono); padding: 10px 14px; text-decoration: none;
}
.skip:focus { top: 10px; }

.wrap { width: min(1120px, 100% - 2 * var(--gutter)); margin-inline: auto; }
main.wrap { padding-block: 40px 96px; position: relative; z-index: 1; }

/* The dawn wash: fixed behind everything. Faint at the top of the page, warmer toward the bottom. */
.dawn-wash {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  opacity: calc(0.12 + var(--dawn-p) * 0.5);
  background:
    radial-gradient(90% 55% at 50% 100%, hsl(var(--ember) / 0.34), transparent 70%),
    radial-gradient(70% 40% at 50% 100%, hsl(var(--dawn) / 0.24), transparent 75%);
}
/* On the paler ground the wash is quieter. Explicit light choice first, then the system setting. */
:root[data-theme="light"] .dawn-wash { opacity: calc(0.06 + var(--dawn-p) * 0.2); }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .dawn-wash { opacity: calc(0.06 + var(--dawn-p) * 0.2); }
}

/* Header */
.top {
  position: sticky; top: 0; z-index: 10;
  background: hsl(var(--night) / 0.82);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border-bottom: 1px solid hsl(var(--line));
}
.bar-top { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 22px; padding-block: 14px; }
.brand { display: inline-flex; align-items: center; gap: 10px; color: hsl(var(--paper)); text-decoration: none; font: 500 1.2rem/1 var(--display); letter-spacing: -0.01em; }
.brand:hover { text-decoration: none; }
.brand svg { width: 26px; height: 26px; flex: none; }
.top nav { display: flex; flex-wrap: wrap; gap: 6px 18px; flex: 1; }
.top nav a {
  font: 400 0.8rem/1.2 var(--mono); letter-spacing: 0.01em; color: hsl(var(--mute));
  text-decoration: none; padding: 5px 0; position: relative;
}
.top nav a:hover { color: hsl(var(--paper)); }
.top nav a[aria-current="page"] { color: hsl(var(--paper)); }
.top nav a[aria-current="page"]::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 1px; background: hsl(var(--dawn));
}

/* Buttons. Mono labels and small corners, as on dawnshift.co. */
button, .btn {
  font: 400 0.8rem/1 var(--mono); letter-spacing: 0.02em; cursor: pointer; text-decoration: none;
  display: inline-flex; align-items: center; gap: 0.6rem; padding: 0.85rem 1.1rem;
  border: 1px solid transparent; border-radius: var(--control-radius);
  background: hsl(var(--paper)); color: hsl(var(--night));
  transition: background-color 180ms ease, color 180ms ease, border-color 180ms ease;
}
button:hover, .btn:hover { background: hsl(var(--dawn)); color: hsl(var(--on-dawn)); text-decoration: none; }
.btn-line, button.line { background: hsl(var(--night)); color: hsl(var(--paper)); border-color: hsl(var(--line)); }
.btn-line:hover, button.line:hover { background: hsl(var(--night)); color: hsl(var(--paper)); border-color: hsl(var(--paper)); }
button.small, .btn.small { padding: 0.55rem 0.8rem; font-size: 0.74rem; }
button:disabled { opacity: 0.45; cursor: not-allowed; }

/* Type. Urbanist at 400 for headlines, 500 for card titles. */
h1, h2, h3 { font-family: var(--display); color: hsl(var(--paper)); margin: 0; }
h1 { font-weight: 400; font-size: clamp(2.4rem, 5.1vw, 4.1rem); line-height: 1.02; letter-spacing: -0.025em; margin-bottom: 22px; }
h2 { font-weight: 400; font-size: clamp(1.6rem, 3vw, 2.2rem); line-height: 1.12; letter-spacing: -0.015em; margin: 64px 0 16px; }
h3 { font-weight: 500; font-size: 1.12rem; line-height: 1.3; margin-bottom: 8px; }
p { margin: 0 0 18px; max-width: 66ch; }
.lede { font-size: 1.2rem; line-height: 1.6; color: hsl(var(--mute)); max-width: 58ch; }
.mute { color: hsl(var(--mute)); }
.teaches { color: hsl(var(--mute)); font-size: 0.95rem; }
ul, ol { padding-left: 1.2em; margin: 0 0 18px; }
li { margin-bottom: 8px; }
strong { font-weight: 600; }
code {
  font-family: var(--mono); font-size: 0.86em; background: hsl(var(--surface));
  padding: 0.12em 0.4em; border-radius: 3px; color: hsl(var(--paper));
}
pre.code {
  font-family: var(--mono); font-size: 0.86rem; line-height: 1.6;
  background: hsl(var(--surface)); border: 1px solid hsl(var(--line)); border-radius: var(--card-radius);
  padding: 18px 20px; overflow-x: auto; margin: 0 0 22px; max-width: 100%;
}
pre.code code { background: none; padding: 0; font-size: inherit; }

/* Mono section label: a hairline, what the section is, in sentence case. */
.bar {
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
  border-top: 1px solid hsl(var(--line)); padding: 14px 0; margin-top: 72px;
  font: 400 0.8rem/1.2 var(--mono); color: hsl(var(--mute));
}
.bar strong { font: 400 0.8rem/1.2 var(--mono); color: hsl(var(--paper)); }

table { width: 100%; border-collapse: collapse; margin: 0 0 24px; font-size: 0.95rem; display: block; overflow-x: auto; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid hsl(var(--line)); vertical-align: top; }
th { font: 400 0.76rem/1.2 var(--mono); color: hsl(var(--mute)); letter-spacing: 0.02em; }

.sw { display: inline-block; width: 14px; height: 14px; border-radius: 3px; border: 1px solid hsl(var(--line)); vertical-align: -2px; margin-right: 6px; }

/* Hero: the horizon. */
.hero { position: relative; padding-top: 24px; }
.hero-grid { display: grid; gap: 40px; align-items: center; }
.hero-copy { position: relative; z-index: 2; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; }
.hero-art figure.demo { margin: 0; }
.hero-art .demo-stage { border-radius: var(--panel-radius); }
.hero .kicker { font: 400 0.82rem/1.4 var(--mono); color: hsl(var(--mute)); margin-bottom: 18px; }

/* One orchestrated moment on load: the headline rises out of its mask. Off for reduced motion. */
.rise { display: block; overflow: hidden; padding-bottom: 0.08em; }
.rise > span { display: block; animation: rise 900ms cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.rise + .rise > span { animation-delay: 120ms; }
@keyframes rise { from { transform: translateY(105%); } to { transform: none; } }

.horizon-line {
  height: 1px; margin-top: 56px;
  background: linear-gradient(90deg, transparent, hsl(var(--dawn) / 0.8), transparent);
}

/* Cards and panels. */
.cards { display: grid; gap: 14px; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); margin-top: 22px; }
.card {
  border: 1px solid hsl(var(--line)); background: hsl(var(--surface));
  border-radius: var(--card-radius); padding: 22px 22px 20px;
}
.card p { margin: 0; color: hsl(var(--mute)); font-size: 0.97rem; line-height: 1.6; }

.next { list-style: none; padding: 0; margin: 18px 0 0; border-top: 1px solid hsl(var(--line)); max-width: none; }
.next li { margin: 0; border-bottom: 1px solid hsl(var(--line)); }
.next a {
  display: grid; grid-template-columns: minmax(10rem, 14rem) 1fr; gap: 16px; padding: 16px 0;
  text-decoration: none; color: hsl(var(--paper));
}
.next a:hover { color: hsl(var(--dawn)); }
.next a span { color: hsl(var(--mute)); }
.next a strong { font: 400 1.05rem/1.4 var(--display); }

/* Figures and live demos. */
figure.demo { margin: 0; }
.demo-stage {
  background: hsl(var(--surface)); border: 1px solid hsl(var(--line)); border-radius: var(--card-radius);
  padding: 14px; display: flex; justify-content: center; align-items: center; min-height: 120px; overflow: hidden;
}
.demo-stage figure { margin: 0; width: 100%; }
.demo-stage canvas, .pg-stage canvas { width: 100% !important; height: auto !important; max-width: 100%; }
.demo-stage .p5loom-sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.demo-stage .msg, .pg-stage .msg { color: hsl(var(--mute)); font-size: 0.92rem; text-align: center; margin: 0; }
figure.demo figcaption { font: 400 0.8rem/1.5 var(--mono); color: hsl(var(--mute)); margin-top: 10px; }

.pair { display: grid; gap: 36px; align-items: center; }
.pair-text p { color: hsl(var(--mute)); }
.pair-demo { max-width: 460px; }

.examples { display: grid; gap: 22px; }
.example {
  display: grid; gap: 20px; align-items: start;
  border: 1px solid hsl(var(--line)); border-radius: var(--card-radius); padding: 18px; background: hsl(var(--surface));
}
.example > div { min-width: 0; }
.example h2 { margin-top: 0; font-size: 1.4rem; }
.example p { margin-bottom: 10px; }

/* Playground. */
.playground { display: grid; gap: 28px; grid-template-columns: minmax(0, 1fr); }
.pg-edit, .pg-view { min-width: 0; }
.pg-toolbar { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 12px; }
.pg-toolbar label { font: 400 0.8rem/1 var(--mono); color: hsl(var(--mute)); margin-right: 4px; }
select {
  font: 400 0.82rem/1 var(--mono); color: hsl(var(--paper)); background: hsl(var(--surface));
  border: 1px solid hsl(var(--line)); border-radius: var(--control-radius); padding: 0.8rem 0.9rem;
}
textarea#pg-spec {
  width: 100%; min-height: 440px; font: 400 0.86rem/1.55 var(--mono);
  color: hsl(var(--paper)); background: hsl(var(--surface)); border: 1px solid hsl(var(--line));
  border-radius: var(--card-radius); padding: 18px; resize: vertical; tab-size: 2;
}
textarea#pg-spec:focus { border-color: hsl(var(--dawn)); outline: none; }
.pg-status { margin: 12px 0; font-size: 0.95rem; color: hsl(var(--mute)); }
.pg-status.ok { color: hsl(var(--paper)); }
.pg-status.bad { color: hsl(var(--dawn)); }
.pg-problems { list-style: none; padding: 0; margin: 0; font: 400 0.82rem/1.5 var(--mono); }
.pg-problems li {
  border-left: 2px solid hsl(var(--dawn)); padding: 6px 12px; margin-bottom: 6px;
  background: hsl(var(--surface)); color: hsl(var(--paper));
}
.pg-stage {
  background: hsl(var(--surface)); border: 1px solid hsl(var(--line)); border-radius: var(--panel-radius);
  padding: 16px; min-height: 260px; display: flex; justify-content: center; align-items: center; overflow: hidden;
}
.pg-desc { font-size: 0.95rem; color: hsl(var(--mute)); margin-top: 14px; }
.pg-facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; margin: 18px 0 0; }
.pg-facts div { border: 1px solid hsl(var(--line)); border-radius: var(--card-radius); padding: 12px 14px; }
.pg-facts dt { font: 400 0.74rem/1.3 var(--mono); color: hsl(var(--mute)); }
.pg-facts dd { margin: 4px 0 0; font: 400 1.15rem/1.2 var(--display); }
.pg-note { color: hsl(var(--mute)); font-size: 0.9rem; margin-top: 20px; }
.pg-view h2 { margin: 0 0 14px; font-size: 1.25rem; }

/* Footer: the horizon again, then the small print. */
.foot { position: relative; z-index: 1; padding-bottom: 36px; font: 400 0.8rem/1.6 var(--mono); color: hsl(var(--mute)); }
.foot .horizon-line { margin-top: 0; }
.foot .wrap { padding-top: 26px; }
.foot p { margin-bottom: 6px; max-width: none; }
.foot a { color: hsl(var(--mute)); }
.foot a:hover { color: hsl(var(--paper)); }

/* Phones: one column, the 20px gutter, nothing wider than the screen. */
@media (max-width: 760px) {
  body { font-size: 16px; }
  .top nav { gap: 4px 14px; }
  .next a { grid-template-columns: 1fr; gap: 4px; }
  .pg-facts { grid-template-columns: 1fr; }
  pre.code { font-size: 0.8rem; }
  .bar { flex-direction: column; align-items: flex-start; gap: 6px; }
}
@media (min-width: 900px) {
  .cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .hero-grid { grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr); }
  .pair { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .example { grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); }
  .playground { grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); align-items: start; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
  .rise > span { transform: none; }
}

/* The sun mark in the header. Colours come from the palette, so light and dark both work. */
.brand .sun { fill: hsl(var(--dawn)); }
.brand .horizon { stroke: hsl(var(--paper)); stroke-width: 1.5; stroke-linecap: round; }

/* Controls drawn by the library next to a picture (p5loom-controls, p5loom-control). */
.p5loom-controls {
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px 24px; margin: 0 0 16px;
  font: 400 0.84rem/1.4 var(--mono); color: hsl(var(--mute));
}
.p5loom-control { display: flex; align-items: center; gap: 10px; }
.p5loom-control label { color: hsl(var(--paper)); }
.p5loom-control input[type="range"] { accent-color: hsl(var(--dawn)); width: 180px; max-width: 100%; }
.p5loom-control input[type="checkbox"] { accent-color: hsl(var(--dawn)); width: 18px; height: 18px; }
.p5loom-control output { min-width: 3ch; color: hsl(var(--paper)); font-variant-numeric: tabular-nums; }
.demo-stage .p5loom, .pg-stage .p5loom { width: 100%; }

/* The second nav row: every docs page. It wraps on a phone, and the current page is marked with the dawn underline. */
.subnav { border-bottom: 1px solid hsl(var(--line)); }
.subnav .wrap { display: flex; flex-wrap: wrap; gap: 6px 18px; padding-block: 10px; }
.subnav a {
  font: 400 0.78rem/1.2 var(--mono); color: hsl(var(--mute)); text-decoration: none; padding: 4px 0;
  overflow-wrap: anywhere; position: relative;
}
.subnav a:hover { color: hsl(var(--paper)); }
.subnav a[aria-current="page"] { color: hsl(var(--paper)); box-shadow: inset 0 -1px 0 hsl(var(--dawn)); }

/* The second nav row: every docs page. It wraps on a phone, and the current page is marked with the dawn underline. */
.subnav { border-bottom: 1px solid hsl(var(--line)); }
.subnav .wrap { display: flex; flex-wrap: wrap; gap: 6px 18px; padding-block: 10px; }
.subnav a {
  font: 400 0.78rem/1.2 var(--mono); color: hsl(var(--mute)); text-decoration: none; padding: 4px 0;
  overflow-wrap: anywhere; position: relative;
}
.subnav a:hover { color: hsl(var(--paper)); }
.subnav a[aria-current="page"] { color: hsl(var(--paper)); box-shadow: inset 0 -1px 0 hsl(var(--dawn)); }
