/* CosmicForge Labs - shared stylesheet
   Studio for the homepage (flat colour tiles, big friendly type), and Showcase
   for product pages (one large screenshot per product, lots of white).

   Light only, deliberately. Earlier dark variants read as a pit to Oliver, and
   the design leans on bright flat colour that has no honest dark equivalent.

   Fonts are system fonts, on purpose: no webfont request at all, which matters
   on the school and hospital networks that block font CDNs. Headlines fall
   through to Helvetica Neue / Arial, text to the platform UI font. An earlier
   build asked Google Fonts for Bricolage Grotesque with a malformed URL (HTTP
   400), so the design was approved while showing these fallbacks. Keep them.

   NOTE: pages link this file as style.css?v=N. Bump N in the same commit as any
   change here. Cloudflare Pages serves assets with max-age=14400 on a custom
   domain and ignores Cache-Control from _headers, so the query string is the
   only thing that reaches returning visitors. */

:root {
  --ink: #1c1b3a;
  --mut: #4a4966;
  --line: #d9d8e6;
  --hair: #ececf4;
  --soft: #f6f6fb;
  --paper: #ffffff;
  --link: #2a4bd0;
  --sun: #ffd23f;
  --blue: #2f5bea;
  --coral: #ff7a66;
  --teal: #3ccdaa;
  --violet: #6d4ae8;
  --amber: #ffab2e;
  --display: "Helvetica Neue", Helvetica, Arial, sans-serif;
  --body: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, "Liberation Mono", monospace;
  --maxw: 1120px;
  color-scheme: light;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.6;
}

.wrap { max-width: var(--maxw); margin: 0 auto; padding-inline: 24px; }

a { color: var(--link); }
a:hover { color: var(--ink); }

h1, h2, h3, .brand { font-family: var(--display); }

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

.site-head { background: var(--paper); padding-block: 18px; }
.site-head .wrap { display: flex; align-items: center; gap: 10px 26px; flex-wrap: wrap; }

.brand {
  font-weight: 800;
  font-size: 1.28rem;
  letter-spacing: -0.025em;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
.brand .dim { font-weight: 800; color: var(--ink); }
.brand:hover { color: var(--ink); }

.nav { margin-left: auto; display: flex; gap: 22px; flex-wrap: wrap; font-size: 0.95rem; font-weight: 600; }
.nav a { color: var(--ink); text-decoration: none; padding-bottom: 3px; }
.nav a:hover { box-shadow: inset 0 -3px 0 var(--line); color: var(--ink); }
.nav a[aria-current="page"] { box-shadow: inset 0 -3px 0 var(--sun); }

/* ---------- hero band ---------- */

.hero { background: var(--sun); color: var(--ink); padding-top: 56px; }
.hero .wrap { padding-bottom: 60px; }
.hero.with-shot .wrap { padding-bottom: 40px; }

.hero h1 {
  margin: 0 0 18px;
  font-weight: 800;
  font-size: clamp(2.3rem, 5.4vw, 4rem);
  line-height: 1.02;
  letter-spacing: -0.035em;
  max-width: 20ch;
  text-wrap: balance;
}
.hero.home h1 { font-size: clamp(2.6rem, 5.6vw, 4.4rem); line-height: 0.98; letter-spacing: -0.04em; max-width: 14ch; }

.hero .lede { margin: 0 0 6px; font-size: 1.22rem; line-height: 1.45; max-width: 54ch; }
.eyebrow { display: block; margin: 0 0 14px; font-size: 0.95rem; font-weight: 600; opacity: 0.88; }

.hero.c-blue, .hero.c-violet { color: #fff; }
.c-blue { background: var(--blue); }
.c-coral { background: var(--coral); }
.c-teal { background: var(--teal); }
.c-violet { background: var(--violet); }
.c-amber { background: var(--amber); }
.c-sun { background: var(--sun); }

.hero code { background: rgba(0, 0, 0, 0.09); border: 0; color: inherit; }
.c-blue code, .c-violet code { background: rgba(0, 0, 0, 0.22); }

/* the screenshot rises out of the bottom of the colour band */
.shot { padding-inline: 24px; }
.shot img {
  display: block;
  width: min(1000px, 100%);
  height: auto;
  max-width: 100%;
  margin: 0 auto;
  border-radius: 14px 14px 0 0;
}

/* ---------- buttons ---------- */

.btn-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin: 24px 0 8px; }

.btn {
  display: inline-block;
  padding: 11px 22px;
  border: 2px solid currentColor;
  border-radius: 999px;
  background: transparent;
  color: inherit;
  font-weight: 700;
  font-size: 0.97rem;
  text-decoration: none;
}
.btn:hover { color: inherit; opacity: 0.8; }
button.btn { font: inherit; font-weight: 700; font-size: 0.97rem; cursor: pointer; }
[hidden] { display: none !important; }

.btn-primary { background: var(--ink); border-color: var(--ink); color: #fff; }
.btn-primary:hover { color: #fff; opacity: 0.88; }

.btn-sub { display: block; font-size: 0.9rem; opacity: 0.9; margin-top: 4px; }
.hero .ask { max-width: 66ch; margin-top: 12px; line-height: 1.5; }

/* ---------- home: colour tiles ---------- */

.tiles { padding-block: 16px 56px; }
.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }

.t {
  border-radius: 22px;
  padding: 28px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
  overflow: hidden;
  color: var(--ink);
}
.t.wide { grid-column: 1 / -1; display: grid; grid-template-columns: 1fr 1.15fr; gap: 28px; align-items: center; }
.t.wide.solo { grid-template-columns: 1fr; }
.t .st { font-size: 0.9rem; font-weight: 600; opacity: 0.88; }
.t h3 { margin: 0; font-weight: 800; font-size: clamp(1.8rem, 3vw, 2.6rem); letter-spacing: -0.03em; line-height: 1; }
.t h3 a { color: inherit; text-decoration: none; }
.t p { margin: 0; font-size: 1.04rem; line-height: 1.45; max-width: 46ch; }
.t .ln { color: inherit; font-weight: 700; text-decoration: underline; text-underline-offset: 3px; margin-top: auto; padding-top: 8px; }
.t img { display: block; width: 100%; height: 200px; object-fit: cover; object-position: top left; border-radius: 12px; margin-top: 8px; }
.t.wide img { height: auto; object-fit: contain; margin: 0; }
.t code { background: rgba(0, 0, 0, 0.09); border: 0; color: inherit; }
.t.blue code, .t.violet code, .t.ink code { background: rgba(0, 0, 0, 0.22); }
.t.blue, .t.violet, .t.ink { color: #fff; }
.t.blue { background: var(--blue); }
.t.coral { background: var(--coral); }
.t.teal { background: var(--teal); }
.t.violet { background: var(--violet); }
.t.amber { background: var(--amber); }
.t.ink { background: var(--ink); }
.t img.crop-right { object-position: 92% 60%; }
.t img.crop-panel { object-position: center; }

/* ---------- prose ---------- */

.section { padding-block: 52px 70px; }
.prose > * { max-width: 72ch; }

.prose h2 {
  margin: 46px 0 12px;
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.1;
}
.prose h2:first-child { margin-top: 0; }
.prose h3 { margin: 28px 0 8px; font-size: 1.2rem; font-weight: 700; letter-spacing: -0.02em; }
.prose p { margin: 0 0 14px; }
.prose p.caption { margin: 0 0 6px; font-size: 0.92rem; color: var(--mut); }
.prose ul { margin: 0 0 16px; padding-left: 22px; }
.prose li { margin-bottom: 8px; }
.prose ol { margin: 0 0 16px; padding-left: 24px; }
.prose ol li::marker { color: var(--blue); font-weight: 700; }
.prose li::marker { color: var(--blue); }

code {
  font-family: var(--mono);
  font-size: 0.86em;
  background: var(--soft);
  border: 1px solid var(--hair);
  border-radius: 6px;
  padding: 1px 6px;
}

.callout { background: #fff3c7; border-radius: 16px; padding: 18px 22px; margin: 0 0 12px; }
.callout.warn { background: #ffe6d4; }
.callout p { margin: 0; }

.specs { margin: 22px 0; border-top: 2px solid var(--ink); }
.specs div { display: flex; gap: 8px 20px; flex-wrap: wrap; padding: 11px 0; border-bottom: 1px solid var(--line); font-size: 0.96rem; }
.specs dt { flex: 0 0 170px; color: var(--mut); margin: 0; }
.specs dd { margin: 0; flex: 1 1 200px; font-weight: 600; }

.prose .btn-row { margin-top: 30px; }

/* plain tables, for the downloads page */
.prose > .table-scroll { max-width: none; overflow-x: auto; margin: 0 0 8px; }
.dl-table { width: 100%; min-width: 640px; border-collapse: collapse; font-size: 0.96rem; }
.dl-table th { text-align: left; font-weight: 700; background: var(--soft); border: 1px solid var(--line); padding: 10px 14px; }
.dl-table td { border: 1px solid var(--line); padding: 12px 14px; vertical-align: top; line-height: 1.45; }
.dl-table td strong { display: block; font-size: 1.05rem; margin-bottom: 3px; }
.dl-table td.get { white-space: nowrap; }
.dl-table .meta { display: block; color: var(--mut); font-size: 0.86rem; margin-top: 3px; }

/* ---------- footer ---------- */

.site-foot { background: var(--paper); border-top: 1px solid var(--line); padding-block: 26px 44px; color: var(--mut); font-size: 0.9rem; }
.site-foot .wrap { display: flex; gap: 12px 32px; flex-wrap: wrap; }
.site-foot a { color: var(--mut); }
.site-foot a:hover { color: var(--ink); }
.site-foot strong { color: var(--ink); }
.site-foot .legal { margin-left: auto; }

@media (max-width: 860px) {
  .grid { grid-template-columns: 1fr; }
  .t.wide { grid-template-columns: 1fr; }
}

@media (max-width: 640px) {
  .hero { padding-top: 38px; }
  .hero .wrap { padding-bottom: 40px; }
  .nav { margin-left: 0; gap: 16px; }
  .site-foot .legal { margin-left: 0; }
  .specs dt { flex-basis: 100%; }
  .t { padding: 22px; }
}

/* ---------- gallery ---------- */

.prose > .gallery { max-width: none; }
.gallery { display: grid; gap: 18px; margin: 22px 0 8px; }
.gallery.g2 { grid-template-columns: 1fr 1fr; }
.gallery.g3 { grid-template-columns: repeat(3, 1fr); }
.gallery.g1 { grid-template-columns: minmax(0, 780px); }
.gallery figure { margin: 0; min-width: 0; }
.gallery img { display: block; width: 100%; height: auto; border-radius: 12px; border: 1px solid var(--line); }
/* two screenshots of slightly different proportions: crop them to one shape so captions line up */
.gallery.even img { aspect-ratio: 1090 / 540; object-fit: cover; }
.gallery figcaption { font-size: 0.92rem; color: var(--mut); margin-top: 8px; line-height: 1.45; }

/* ---------- home hero collage ---------- */

.hero.home .wrap { display: grid; grid-template-columns: 1.02fr 1fr; gap: 40px; align-items: center; }
.collage { position: relative; aspect-ratio: 1.16 / 1; min-width: 0; }
.collage img {
  position: absolute;
  display: block;
  height: auto;
  border-radius: 12px;
  box-shadow: 0 18px 40px rgba(28, 27, 58, 0.28);
}
.collage .c1 { top: 0; left: 0; width: 86%; }
.collage .c2 { bottom: 0; right: 0; width: 60%; }
.collage .c3 { bottom: 12%; left: 4%; width: 46%; }

/* ---------- motion ---------- */

/* Every animation runs from a keyframe "from" state with fill-mode both, so with
   animation switched off the element simply sits in its normal, visible state. */

@keyframes wordup { from { transform: translateY(105%); } to { transform: none; } }
@keyframes fadeup { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes shotup { from { opacity: 0; transform: translateY(44px); } to { opacity: 1; transform: none; } }
@keyframes pop { from { opacity: 0; transform: translateY(26px) scale(0.96); } to { opacity: 1; transform: none; } }

.hero h1 .w { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: 0.14em; margin-bottom: -0.14em; }
.hero h1 .w > span {
  display: inline-block;
  animation: wordup 0.75s cubic-bezier(0.2, 0.7, 0.2, 1) both;
  animation-delay: calc(var(--i, 0) * 75ms + 60ms);
}

.hero .eyebrow { animation: fadeup 0.7s ease both; }
.hero .lede { animation: fadeup 0.8s ease both 0.35s; }
.hero .btn-row { animation: fadeup 0.8s ease both 0.5s; }
.hero .btn-sub { animation: fadeup 0.8s ease both 0.6s; }
.shot img { animation: shotup 1s cubic-bezier(0.2, 0.7, 0.2, 1) both 0.45s; }

.collage .c1 { animation: pop 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) both 0.35s; }
.collage .c2 { animation: pop 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) both 0.6s; }
.collage .c3 { animation: pop 0.9s cubic-bezier(0.2, 0.7, 0.2, 1) both 0.85s; }

/* scroll reveals: hidden only when the script has run and motion is welcome */
.js .reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1);
  transition-delay: var(--d, 0ms);
}
.js .reveal.in { opacity: 1; transform: none; }

.t { transition: box-shadow 0.25s ease; }
.t:hover { box-shadow: 0 10px 28px rgba(28, 27, 58, 0.18); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .js .reveal { opacity: 1 !important; transform: none !important; }
}

@media (max-width: 860px) {
  .gallery.g2, .gallery.g3 { grid-template-columns: 1fr; }
  .hero.home .wrap { grid-template-columns: 1fr; gap: 28px; }
  .collage { max-width: 560px; }
}

/* ---------- release notes (filled from GitHub by releases.js) ---------- */

.rel { margin: 6px 0 18px; }
.rel-item { border-top: 1px solid var(--line); padding: 16px 0; }
.rel details.rel-item { padding: 12px 0; }
.rel h4 { margin: 0 0 10px; font-family: var(--display); font-size: 1.2rem; font-weight: 800; letter-spacing: -0.02em; }
.rel .meta { display: inline-block; margin-left: 10px; color: var(--mut); font-family: var(--body); font-size: 0.9rem; font-weight: 400; letter-spacing: 0; }
.rel summary { cursor: pointer; font-weight: 700; padding: 2px 0; }
.rel summary .meta { font-weight: 400; }
.rel .notes { margin-top: 10px; }
.rel .notes h5 { margin: 16px 0 6px; font-size: 1rem; font-weight: 700; }
.rel .notes p { margin: 0 0 10px; }
.rel .notes ul { margin: 0 0 12px; padding-left: 20px; }
.rel .notes li { margin-bottom: 6px; }
.rel code.hash { display: inline-block; max-width: 100%; overflow-wrap: anywhere; font-size: 0.8em; }
.rel .more { margin: 10px 0 0; font-size: 0.95rem; }
.rel > p:only-child { color: var(--mut); }
