:root {
  --sbx-ink: var(--ink, #1a1a1a);
  --sbx-surface: var(--bg, #fbfbf9);
  --sbx-muted: var(--muted, #6b6b70);
  --sbx-rule: var(--rule, #e0e0dc);
  --sbx-accent: var(--accent, #2f6f4f);
  --sbx-hover: var(--hover-bg, rgba(0, 0, 0, 0.05));
  --sbx-danger: #c0392b;
  --sbx-warn: var(--warn, #8a6100);
  --sbx-panel: var(--surface, #ffffff);
  --sbx-radius: var(--radius, 7px);
  --sbx-mono: ui-monospace, "SF Mono", Menlo, monospace;
  --sbx-sans: var(--sans, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif);

  --sbx-code-foreground: var(--ink, #1a1a1a);
  --sbx-code-comment: #7a7f8a;
  --sbx-code-keyword: #a2264b;
  --sbx-code-string: #2a7d4f;
  --sbx-code-expression: #1f7a7a;
  --sbx-code-constant: #b3541e;
  --sbx-code-function: #3a5ccc;
  --sbx-code-punctuation: #6b6b70;
  --sbx-code-link: #3a5ccc;
}

@media (prefers-color-scheme: dark) {
  :root {
    --sbx-ink: var(--ink, #e9e9e6);
    --sbx-surface: var(--bg, #17171a);
    --sbx-muted: var(--muted, #9a9aa0);
    --sbx-rule: var(--rule, #34343a);
    --sbx-accent: var(--accent, #7fc0a0);
    --sbx-hover: var(--hover-bg, rgba(255, 255, 255, 0.07));
    --sbx-danger: #e06a5c;
    --sbx-warn: var(--warn, #d8a745);
    --sbx-panel: var(--surface, #1e1e22);

    --sbx-code-foreground: var(--ink, #e9e9e6);
    --sbx-code-comment: #7e8794;
    --sbx-code-keyword: #ff7b9c;
    --sbx-code-string: #7fd1a0;
    --sbx-code-expression: #66d9d9;
    --sbx-code-constant: #f0a868;
    --sbx-code-function: #8ab4ff;
    --sbx-code-punctuation: #9a9aa0;
    --sbx-code-link: #8ab4ff;
  }
}


.sandbox { width: 90%; margin: 1.75rem auto; position: relative; }
.sandbox-frame {
  width: 100%;
  border: 0;
  outline: 1px solid var(--sbx-rule);
  outline-offset: -1px;
  border-radius: 6px;
  background: var(--sbx-surface);
  display: block;
}
/* A hover figure fills whatever box the host gives it, so the height it reports back is
   its own box height — circular. Hold the declared proportions instead. */
.sandbox[data-control='hover'] .sandbox-frame { height: auto; aspect-ratio: var(--sandbox-ar); }
/* A frame waiting to load holds the shape it will draw at. */
.sandbox-frame[data-srcdoc] { height: auto; aspect-ratio: var(--sandbox-ar); }
.sandbox[data-control='hover'] .sandbox-stage { position: relative; }
.sandbox-hover { position: absolute; inset: 0; }

.sandbox-code > pre { margin: 0; height: var(--sandbox-h); overflow: auto; }
/* The corner tools float over the code, so the code carries its own room on the right:
   a long line scrolls clear of them instead of ending underneath. The padding sits on the
   code box rather than the pre, since a scroll container's own end padding is not part of
   the scrollable area in every browser, but a child's box always is. */
.sandbox-code > pre > code {
  display: block;
  box-sizing: border-box;
  width: max-content;
  min-width: 100%;
  padding-right: 4.6rem;
}
/* The line a figure's error pointed at, once the reader followed the link to it. */
::highlight(sandbox-goto) { background: color-mix(in srgb, var(--sbx-danger) 22%, transparent); }
.sandbox[data-mode='preview'] .sandbox-code { display: none; }
.sandbox[data-mode='code'] .sandbox-stage { display: none; }
.sandbox-tools {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
  display: flex;
  gap: 0.3rem;
}
.sandbox-toggle,
.sandbox-copy,
.sandbox-expand,
.sandbox-fullscreen,
.sandbox-tool-btn,
.sandbox-knobs-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--sbx-surface);
  cursor: pointer;
  line-height: 1;
  color: var(--sbx-muted);
  border: 1px solid var(--sbx-rule);
  border-radius: 4px;
  padding: 0.3rem;
}
.sandbox-toggle:hover,
.sandbox-copy:hover,
.sandbox-expand:hover,
.sandbox-fullscreen:hover,
.sandbox-tool-btn:hover,
.sandbox-knobs-btn:hover,
.sandbox-knobs-btn[aria-expanded='true'] { color: var(--sbx-ink); }
.sandbox[data-mode='preview'] .sandbox-copy { display: none; }
.sandbox:not([data-expanded]) .sandbox-fullscreen,
.sandbox-fullscreen[hidden] { display: none; }

/* Expanded, a figure covers the page at the size it was written for rather than the
   column's: the stage is as wide as the figure asks, centred, and never stretched past it.
   The tools stay pinned to the viewport corner while a tall figure scrolls under them. */
html:has(.sandbox[data-expanded]) { overflow: hidden; }
.sandbox[data-expanded] {
  position: fixed;
  inset: 0;
  z-index: 1000;
  width: auto;
  margin: 0;
  box-sizing: border-box;
  padding: 3.25rem 1rem 1rem;
  overflow: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  background: var(--sbx-surface);
}
.sandbox[data-expanded] > .sandbox-stage { width: min(100%, var(--sandbox-w, 100%)); margin-block: auto; }
.sandbox[data-expanded][data-mode='code'] > .sandbox-code {
  align-self: stretch;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.sandbox[data-expanded] > .sandbox-code > pre { flex: 1 1 auto; height: auto; min-height: 0; }
.sandbox[data-expanded] > .sandbox-tools { position: fixed; top: 0.75rem; right: 0.75rem; z-index: 1; }
.sandbox[data-expanded] > .sandbox-knobs { position: fixed; top: 3rem; right: 0.75rem; }
/* Fullscreen is the one place a canvas grows past its own size: as large as the screen
   holds at its proportions, below the tool corner. */
.sandbox[data-preset='canvas']:fullscreen > .sandbox-stage {
  width: min(100%, calc((100vh - 4.25rem) * var(--sandbox-ar)));
}
.sandbox[data-mode='code'] .sandbox-knobs-btn,
.sandbox[data-mode='code'] .sandbox-knobs { display: none; }

/* The knobs a figure's code declared, dialled from a popover under the tool corner. It hangs
   off whatever is positioned around it: the figure on a page, the frame wrap in the editor. */
.sandbox-knobs {
  position: absolute;
  top: 2.4rem;
  right: 0.4rem;
  z-index: 5;
  box-sizing: border-box;
  width: 14rem;
  max-width: calc(100% - 0.8rem);
  max-height: 70vh;
  overflow: auto;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 0.65rem 0.8rem 0.8rem;
  color: var(--sbx-ink);
  font-size: 0.8rem;
  line-height: 1.3;
  background: var(--sbx-surface);
  border: 1px solid var(--sbx-rule);
  border-radius: 8px;
  box-shadow: 0 2px 14px rgba(0, 0, 0, 0.12);
}
.sandbox-knobs[hidden] { display: none; }
.sandbox-knobs-foot {
  display: flex;
  justify-content: flex-end;
  margin-top: 0.15rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--sbx-rule);
}
.sandbox-knobs-reset {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.2rem;
  color: var(--sbx-muted);
  background: none;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
.sandbox-knobs-reset:hover { color: var(--sbx-ink); background: var(--sbx-hover); }
.sandbox-knob { display: flex; flex-direction: column; gap: 0.25rem; cursor: default; }
.sandbox-knob[data-type='boolean'] { flex-direction: row; align-items: center; gap: 0.5rem; cursor: pointer; }
.sandbox-knob-name {
  font-family: var(--sbx-mono);
  font-size: 0.72rem;
  color: var(--sbx-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sandbox-knob-ctl { display: flex; align-items: center; gap: 0.5rem; min-width: 0; }
.sandbox-knob-ctl input[type='range'] { flex: 1 1 0; min-width: 0; margin: 0; accent-color: var(--sbx-accent); }
.sandbox-knob-ctl output {
  flex: none;
  min-width: 3.5ch;
  text-align: right;
  font-family: var(--sbx-mono);
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
}
.sandbox-knob-ctl input[type='number'],
.sandbox-knob-ctl input[type='text'],
.sandbox-knob-ctl select {
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  font: inherit;
  font-size: 0.8rem;
  color: var(--sbx-ink);
  background: var(--sbx-surface);
  border: 1px solid var(--sbx-rule);
  border-radius: 5px;
  padding: 0.25rem 0.4rem;
}
.sandbox-knob-ctl input[type='color'] {
  box-sizing: border-box;
  width: 2.4rem;
  height: 1.7rem;
  padding: 0.1rem;
  background: var(--sbx-surface);
  border: 1px solid var(--sbx-rule);
  border-radius: 5px;
  cursor: pointer;
}
.sandbox-knob[data-type='rgb'] input[type='range'] {
  appearance: none;
  height: 0.6rem;
  border-radius: 999px;
  background: var(--sbx-knob-track);
  box-shadow: inset 0 0 0 1px var(--sbx-rule);
}
.sandbox-knob[data-type='rgb'] input[type='range']::-webkit-slider-thumb {
  appearance: none;
  width: 0.9rem;
  height: 0.9rem;
  border-radius: 50%;
  background: var(--sbx-surface);
  border: 2px solid var(--sbx-ink);
  cursor: pointer;
}
.sandbox-knob[data-type='rgb'] input[type='range']::-moz-range-thumb {
  width: 0.9rem;
  height: 0.9rem;
  box-sizing: border-box;
  border-radius: 50%;
  background: var(--sbx-surface);
  border: 2px solid var(--sbx-ink);
  cursor: pointer;
}
.sandbox-knob-ctl output.sandbox-knob-swatch {
  width: 1.1rem;
  height: 1.1rem;
  min-width: 0;
  border-radius: 4px;
  box-shadow: inset 0 0 0 1px var(--sbx-rule);
}
.sandbox-knob input[type='checkbox'] { margin: 0; accent-color: var(--sbx-accent); }

/* A shared block has no frame, so the card the editor draws for it stands in as the stage:
   a head with the label and its kind tags, which the code replaces when shown. The tools
   sit in the corner just as they do on a figure, so the head keeps room for them. */
.sandbox-lib-head {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.4rem;
  min-height: 2.5rem;
  padding: 0.55rem 4.6rem 0.55rem 0.7rem;
  color: var(--sbx-ink);
  font-size: 0.78rem;
  border: 1px solid var(--sbx-rule);
  border-radius: 6px;
  background: color-mix(in srgb, var(--sbx-ink) 3%, transparent);
}
/* No frame height to match, so the code takes its own — never shorter than the head it
   replaces, or the corner tools would hang off a one-liner. */
.sandbox-lib .sandbox-code > pre,
.sandbox-lib .sandbox-external-urls { box-sizing: border-box; height: auto; min-height: 2.5rem; }
.sandbox-lib-tag {
  display: inline-flex;
  align-items: center;
  line-height: 1;
  color: var(--sbx-surface);
  background: var(--sbx-muted);
  border-radius: 4px;
  padding: 0.22rem 0.28rem;
}
.sandbox-tag-text { font: 600 0.68rem/13px ui-monospace, monospace; }
.sandbox-lib-label {
  max-width: min(34ch, 100%);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sandbox-external-urls {
  margin: 0;
  padding-right: 2.6rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-family: var(--sbx-mono);
  font-size: 0.85rem;
}
.sandbox-external-urls a { word-break: break-all; }
.sandbox-external-bad { color: var(--sbx-muted); word-break: break-all; }

.sbx-code-block {
  margin: 0;
  overflow-x: auto;
  padding: 0.6rem 0.8rem;
  border-radius: 6px;
  background: color-mix(in srgb, var(--sbx-ink) 5%, transparent);
  color: var(--sbx-code-foreground);
  font-family: var(--sbx-mono);
  font-size: 0.82rem;
  line-height: 1.6;
}
.sbx-tok-comment { color: var(--sbx-code-comment); font-style: italic; }
.sbx-tok-keyword { color: var(--sbx-code-keyword); }
.sbx-tok-string { color: var(--sbx-code-string); }
.sbx-tok-expression { color: var(--sbx-code-expression); }
.sbx-tok-constant { color: var(--sbx-code-constant); }
.sbx-tok-function { color: var(--sbx-code-function); }
.sbx-tok-punctuation { color: var(--sbx-code-punctuation); }
.sbx-tok-link { color: var(--sbx-code-link); text-decoration: underline; }

/* A link the markdown pass sent to a new tab carries an arrow leaving a frame, sized to
   the text it follows rather than to the icon's own pixels. */
.sandbox-external > svg {
  display: inline-block;
  width: 0.72em;
  height: 0.72em;
  margin-left: 0.15em;
  vertical-align: -0.02em;
  stroke-width: 2.2;
}

:root {
  --ink: #e8e7e1;
  --muted: #9a9a92;
  --rule: #2b2b30;
  --bg: #17171a;
  --accent: #e07a5f;
  --code-bg: #23232a;
  --hover-bg: #27272e;
  --edge: #3a3a42;
  --faint: #6e6e68;
  --max: 42rem;
  color-scheme: dark;
}

* { box-sizing: border-box; }

html {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  color: var(--ink);
  background: var(--bg);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

body { margin: 0; padding: 0 1.25rem; }

.wrap { max-width: var(--max); margin: 0 auto; padding: 3.5rem 0 5rem; }

a {
  color: var(--accent);
  text-underline-offset: 2px;

  &:hover { text-decoration: none; }
}

.shiki, .astro-code { background-color: var(--code-bg) !important; }

.site-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: 1rem;
  margin-bottom: 2.5rem;

  & nav a {
    color: var(--muted);
    font-size: 0.85rem;
    text-decoration: none;

    &:hover { color: var(--accent); }
  }
}

.brand {
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration: none;
}

.jr-empty { color: var(--muted); margin-top: 3rem; }

.jr-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.jr-card {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1rem 1.25rem;
  border: 1px solid var(--rule);
  border-radius: 8px;
  color: inherit;
  text-decoration: none;
  transition: border-color 0.15s;

  &:hover { border-color: var(--edge); }
  &:hover .jr-card-title { color: var(--accent); }
}

.jr-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}

.jr-card-title {
  min-width: 0;
  margin: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--ink);
}

.jr-card-date {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.75rem;
  color: var(--faint);
  flex-shrink: 0;
}

.jr-card-excerpt {
  display: -webkit-box;
  margin: 0;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  font-size: 13.5px;
  line-height: 1.625;
  color: var(--muted);
}

.jr-thumb {
  display: block;
  align-self: center;
  max-width: 100%;
  border: 0;
  border-radius: 6px;
  background: var(--code-bg);
  object-fit: cover;
}

.jr-thumb-frame { pointer-events: none; }

.entry-h1 {
  font-size: 2rem;
  line-height: 1.2;
  font-weight: 700;
  color: var(--ink);
  margin: 0 0 2rem;
}

.prose {
  line-height: 1.65;

  & > :first-child { margin-top: 0; }
  & p { margin: 1rem 0; }
  & :is(h2, h3) { margin: 2.25rem 0 0.5rem; line-height: 1.25; }
  & h2 { font-size: 1.45rem; }
  & h3 { font-size: 1.18rem; }
  & :is(ul, ol) { padding-left: 1.4rem; margin: 1rem 0; }
  & li { margin: 0.25rem 0; }

  & img {
    display: block;
    margin: 1.75rem auto;
    max-width: 68%;
    max-height: 70vh;
    height: auto;
    border-radius: 8px;
    border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  }

  & blockquote {
    margin: 1.5rem 0;
    padding-left: 1rem;
    border-left: 3px solid var(--rule);
    color: var(--muted);
    font-style: italic;
  }

  & hr {
    border: 0;
    margin: 2.5rem 0;
    color: var(--muted);
    text-align: center;

    &::before {
      content: "\2022\a0\a0\a0\2022\a0\a0\a0\2022";
      font-size: 0.7rem;
      letter-spacing: 0.2em;
    }
  }

  & :not(pre) > code {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 0.85em;
    background: var(--code-bg);
    padding: 0.1em 0.35em;
    border-radius: 3px;
  }

  & pre {
    font-size: 0.8rem;
    padding: 1rem;
    border-radius: 6px;
    overflow-x: auto;
  }
}

.entry-nav {
  display: flex;
  justify-content: space-between;
  gap: 1.5rem;
  margin-top: 3.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--rule);
}

.entry-nav-link {
  display: inline-flex;
  align-items: flex-start;
  gap: 0.4rem;
  min-width: 0;
  text-decoration: none;
  color: var(--ink);
  font-size: 0.9rem;

  &.next { text-align: right; }

  &:hover {
    color: var(--accent);

    & .nav-arrow { color: var(--accent); }
  }
}

.nav-arrow { color: var(--muted); flex-shrink: 0; }

.nav-t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }

.back {
  display: inline-block;
  margin-top: 2rem;
  color: var(--muted);
  text-decoration: none;
  font-size: 0.85rem;

  &:hover { color: var(--accent); }
}
