/* papyr theme — "Typeset": precise typography with a monospaced data layer. */

/* Self-hosted webfonts (SIL OFL 1.1 — free for commercial use).
   IBM Plex Sans for prose, JetBrains Mono for code + metadata, served from /fonts. */
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/ibm-plex-sans-400.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/ibm-plex-sans-500.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/fonts/ibm-plex-sans-600.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/ibm-plex-sans-700.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/jetbrains-mono-400.woff2") format("woff2");
}
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/jetbrains-mono-700.woff2") format("woff2");
}

:root {
  /* Declare support for both schemes so the browser honors the user's
     preference (OS *or* browser appearance setting) and themes native UI
     — scrollbars, form controls, the pre-CSS canvas — to match. No JS. */
  color-scheme: light dark;
  --bg: #fcfcfb;
  --fg: #18181b;
  --muted: #5c5c66;
  --border: #e9e8e3;
  /* accent pulled from the dark code theme's function color, so links and code
     feel related */
  --accent: #6d3bd8;
  --accent-soft: #f1ecfd;
  --code-bg: #0d1117;
  --code-fg: #c9d1d9;
  --code-label: #6e7681;
  --max-width: 52rem;
  --font: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f0f12;
    --fg: #e7e7ea;
    --muted: #9a9aa6;
    --border: #24242b;
    --accent: #c4a0ff;
    --accent-soft: #221a35;
  }
}

/* Native cross-page motion (Chromium today; ignored elsewhere). */
@view-transition {
  navigation: auto;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: 1.0625rem;
  line-height: 1.7;
  color: var(--fg);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection {
  background: color-mix(in oklab, var(--accent) 22%, transparent);
}

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

/* --- the monospaced "data layer" ------------------------------------------ */
/* metadata, labels, nav, tags, footer — set like spec/terminal output */
.brand-tagline,
.post-meta,
.tag-cloud,
.site-header nav,
.site-footer {
  font-family: var(--mono);
  font-feature-settings: "liga" 0;
}

/* --- layout --------------------------------------------------------------- */
.container {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 1.25rem;
}

/* --- header / nav --------------------------------------------------------- */
.site-header {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 2rem 1.25rem 1.25rem;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  view-transition-name: header;
}
.site-header p { margin: 0; }
.masthead { display: flex; flex-direction: column; gap: 0.3rem; }
.site-header .brand {
  font-weight: 700;
  font-size: 1.35rem;
  letter-spacing: -0.03em;
  color: var(--fg);
  text-decoration: none;
  line-height: 1;
}
.brand-tagline {
  color: var(--muted);
  font-size: 0.78rem;
  letter-spacing: 0.01em;
}
.site-header nav {
  display: flex;
  gap: 1.1rem;
  padding-top: 0.5rem;
}
.site-header nav a {
  color: var(--muted);
  text-decoration: none;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  transition: color 0.15s;
}
.site-header nav a:hover { color: var(--accent); }

/* --- footer --------------------------------------------------------------- */
.site-footer {
  max-width: var(--max-width);
  margin: 3.5rem auto 0;
  padding: 1.5rem 1.25rem 3rem;
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-size: 0.75rem;
  letter-spacing: 0.02em;
}
.site-footer p { margin: 0; }
.site-footer a { color: var(--accent); text-decoration: none; }
.site-footer a:hover { text-decoration: underline; text-underline-offset: 0.15em; }

/* --- links & headings ----------------------------------------------------- */
a { color: var(--accent); text-decoration: none; }
a:hover {
  text-decoration: underline;
  text-underline-offset: 0.15em;
  text-decoration-thickness: 1px;
}

h1, h2, h3, h4 {
  line-height: 1.2;
  letter-spacing: -0.02em;
  margin: 2.5rem 0 0.75rem;
  text-wrap: balance;
  font-weight: 600;
}
h1 { font-size: 2rem; font-weight: 700; }
h2 { font-size: 1.4rem; }
h3 { font-size: 1.15rem; }
p { text-wrap: pretty; }

/* --- post list ------------------------------------------------------------ */
.post-list { list-style: none; padding: 0; margin: 1.5rem 0 0; }
.post-list li { padding: 1.75rem 0; border-bottom: 1px solid var(--border); }
.post-list li:first-child { padding-top: 0; }
.post-list .post-link { margin: 0 0 0.4rem; font-size: 1.3rem; }
.post-list .post-link a { color: var(--fg); transition: color 0.15s; }
.post-list .post-link a:hover { color: var(--accent); text-decoration: none; }
.post-list .summary { margin: 0.4rem 0 0; color: var(--muted); }

/* --- prev / next post navigation ------------------------------------------ */
.post-nav {
  display: flex;
  justify-content: space-between;
  gap: 1.5rem;
  margin-top: 3rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
}
.post-nav a {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  max-width: 48%;
  color: var(--fg);
}
.post-nav a:hover { color: var(--accent); text-decoration: none; }
.post-nav .next { margin-left: auto; text-align: right; }
.post-nav span {
  font-family: var(--mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
}

/* --- table of contents + heading anchors ---------------------------------- */
.toc {
  margin: 1.5rem 0 2rem;
  padding: 0.6rem 1rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 0.95rem;
}
.toc summary {
  font-family: var(--mono);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  cursor: pointer;
}
.toc ul { margin: 0.6rem 0 0; padding-left: 1.2rem; }
.toc ul ul { margin: 0.2rem 0; }
.toc li { margin: 0.2rem 0; }
.toc a { color: var(--fg); }
.toc a:hover { color: var(--accent); }
/* keep an anchored heading clear of the viewport top when jumped to */
h2[id], h3[id] { scroll-margin-top: 1.5rem; }
.anchor {
  margin-left: 0.4rem;
  color: var(--muted);
  text-decoration: none;
  opacity: 0;
  transition: opacity 0.12s;
}
h2:hover > .anchor,
h3:hover > .anchor,
.anchor:focus { opacity: 1; }

/* --- post meta & tags (mono data layer) ----------------------------------- */
.post-title { margin-top: 0.5rem; }
.post-meta {
  color: var(--muted);
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  margin: 0 0 1.75rem;
}
.post-meta time { font-variant-numeric: tabular-nums; }
.tags { display: inline; }
.tag {
  display: inline-block;
  color: var(--accent);
  font-size: 0.78rem;
  margin-right: 0.5rem;
  text-decoration: none;
}
.tag:hover { text-decoration: underline; text-underline-offset: 0.15em; }
.tag-cloud {
  list-style: none;
  padding: 0;
  margin: 1.5rem 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}
.tag-cloud .tag {
  background: var(--accent-soft);
  padding: 0.3rem 0.7rem;
  border-radius: 4px;
  margin-right: 0;
}
.tag-cloud .count { color: var(--muted); margin-left: 0.35rem; }

/* --- inline code ---------------------------------------------------------- */
code { font-family: var(--mono); font-size: 0.88em; }
:not(pre) > code {
  background: var(--accent-soft);
  color: var(--fg);
  padding: 0.12em 0.4em;
  border-radius: 4px;
}

/* --- code blocks (always dark) -------------------------------------------- */
pre {
  position: relative;
  background: var(--code-bg);
  color: var(--code-fg);
  padding: 1.6rem 1.15rem 1.15rem;
  border-radius: 8px;
  overflow-x: auto;
  font-size: 0.85rem;
  line-height: 1.6;
  border: 1px solid #1c2128;
}
pre code { color: var(--code-fg); background: none; padding: 0; font-size: 1em; }
/* language label from the data-lang attribute papyr emits */
pre code[data-lang]::before {
  content: attr(data-lang);
  position: absolute;
  top: 0;
  right: 0;
  padding: 0.5rem 0.8rem;
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--code-label);
}

/* line numbers (opt-in per post via `line-numbers: true`). Each line is wrapped
   in a <span class="line"> at build time; CSS counters draw the gutter. */
pre.numbered code { counter-reset: line; }
pre.numbered .line { counter-increment: line; }
pre.numbered .line::before {
  content: counter(line);
  display: inline-block;
  min-width: 2ch;
  margin-right: 1.25rem;
  text-align: right;
  color: var(--code-label);
  -webkit-user-select: none;
  user-select: none;
}

/* --- images & math -------------------------------------------------------- */
img { max-width: 100%; height: auto; }
math { font-size: 1.05em; }
math[display="block"] { display: block; overflow-x: auto; margin: 1.5rem 0; }

/* --- misc ----------------------------------------------------------------- */
blockquote {
  margin: 1.5rem 0;
  padding: 0.25rem 0 0.25rem 1.25rem;
  border-left: 2px solid var(--accent);
  color: var(--muted);
}
hr { border: none; border-top: 1px solid var(--border); margin: 2.5rem 0; }
table { border-collapse: collapse; width: 100%; margin: 1.5rem 0; font-size: 0.95rem; }
th, td { border: 1px solid var(--border); padding: 0.5rem 0.75rem; text-align: left; }
th {
  font-family: var(--mono);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* --- callouts (note / tip / warning) -------------------------------------- */
.callout {
  margin: 1.5rem 0;
  padding: 0.85rem 1.1rem;
  border-left: 3px solid var(--callout-accent, var(--accent));
  border-radius: 0 6px 6px 0;
  background: var(--callout-bg, var(--accent-soft));
}
.callout > :first-child { margin-top: 0; }
.callout > :last-child { margin-bottom: 0; }
.callout::before {
  display: block;
  margin-bottom: 0.35rem;
  font-family: var(--mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--callout-accent, var(--accent));
}
.callout-note { --callout-accent: #3b82f6; --callout-bg: #eff4ff; }
.callout-note::before { content: "Note"; }
.callout-tip { --callout-accent: #16a34a; --callout-bg: #ecfdf3; }
.callout-tip::before { content: "Tip"; }
.callout-warning { --callout-accent: #d97706; --callout-bg: #fff7ed; }
.callout-warning::before { content: "Warning"; }
@media (prefers-color-scheme: dark) {
  .callout-note { --callout-bg: #14203a; }
  .callout-tip { --callout-bg: #0f2418; }
  .callout-warning { --callout-bg: #2a1e0a; }
}

/* --- back to top ---------------------------------------------------------- */
/* Revealed on scroll via a scroll-driven animation — zero JS. Where scroll
   timelines aren't supported the animation collapses to its end state, so the
   button is simply always visible (a fine fallback). Hidden near the top so it
   never appears on short pages. */
.to-top {
  position: fixed;
  right: 1.5rem;
  bottom: 1.5rem;
  z-index: 10;
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: color-mix(in oklab, var(--bg) 85%, transparent);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  color: var(--muted);
  font-size: 1.1rem;
  line-height: 1;
  text-decoration: none;
  box-shadow: 0 2px 14px rgb(0 0 0 / 0.12);
  animation: to-top-reveal linear both;
  animation-timeline: scroll(root block);
  animation-range: 350px 650px;
  transition: color 0.15s, border-color 0.15s;
}
.to-top:hover {
  color: var(--accent);
  border-color: var(--accent);
  text-decoration: none;
}
@keyframes to-top-reveal {
  from { opacity: 0; visibility: hidden; transform: translateY(0.5rem); }
  to   { opacity: 1; visibility: visible; transform: none; }
}

/* --- reduced motion ------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* don't animate the reveal; keep the affordance available */
  .to-top { animation: none; opacity: 1; visibility: visible; transform: none; }
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}

/* --- print: ink-friendly, content only ------------------------------------ */
@media print {
  :root {
    --bg: #fff;
    --fg: #000;
    --muted: #444;
    --accent: #000;
  }
  .site-header nav,
  .site-footer,
  .to-top { display: none; }
  .container,
  .site-header { max-width: none; }
  a { color: #000; text-decoration: underline; }
  /* code on paper instead of the dark terminal surface */
  pre {
    background: #fff;
    color: #000;
    border: 1px solid #999;
  }
  pre span { color: #000 !important; }
  pre code[data-lang]::before { color: #555; }
  /* expose link targets that paper can't click */
  .container a[href^="http"]::after {
    content: " <" attr(href) ">";
    font-size: 0.85em;
    color: #555;
    word-break: break-all;
  }
  h1, h2, h3 { break-after: avoid; }
  pre, blockquote, table, figure, .callout { break-inside: avoid; }
}
