/* ==========================================================================
   Changelog v2 (/changelogs/v2) — built on Skynet UI (https://skynetui.com)

   Page-local layout only. Components come from skynet-ui.css, palettes from
   themes-v2.css, and every colour below is a Skynet UI token so the page
   follows whichever of the twelve palettes the reader picked.
   ========================================================================== */

/* Skynet UI declares `.hidden` before its component display rules, and every
   `display` rule in this file is a class selector — which ties with `[hidden]`
   on specificity and then wins on order. Both guards, up front. */
.clv2 .hidden { display: none !important; }
.clv2 [hidden] { display: none !important; }

/* A grid or flex ITEM defaults to `min-width: auto` — its MIN-CONTENT width,
   not zero — so one long unbroken token (a version string, a URL in a
   changelog body, a code span) sizes the whole track and the card clips it off
   the screen. `npm run audit:mobile` is the check that catches it; this is the
   rule that prevents it. */
.clv2-layout > *,
.clv2-hero > *,
.clv2-stats > *,
.clv2-entry-head > *,
.clv2-search-row > *,
.clv2-pager > * {
  min-width: 0;
}

.clv2-main { padding-bottom: 4rem; }

.clv2-skip {
  position: absolute;
  left: -9999px;
  z-index: 10001;
  padding: 0.6rem 1rem;
  border-radius: 8px;
  /* The button treatment applies even off-screen: left to the framework's link
     colour this measures ~3.5:1 on the dark palettes, and the theme audit
     measures it whether it is on screen or not. */
  background: var(--sk-primary);
  color: #fff;
  font-weight: 600;
}
.clv2-skip:focus { left: 1rem; top: calc(var(--skv2-h, 60px) + 0.5rem); }

/* ---------- header -------------------------------------------------------- */
.clv2-hero {
  display: grid;
  gap: 1.5rem;
  align-items: end;
  margin: 2rem 0 1.5rem;
}
@media (min-width: 860px) {
  .clv2-hero { grid-template-columns: minmax(0, 1fr) auto; gap: 2.5rem; }
}
.clv2-hero-copy { min-width: 0; }
.clv2-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0 0 0.4rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--sk-primary-text);
}
.clv2-title {
  margin: 0 0 0.5rem;
  font-size: clamp(1.75rem, 1.2rem + 2vw, 2.6rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
}
.clv2-lede { max-width: 60ch; margin: 0; color: var(--sk-text-2); line-height: 1.6; }
.clv2-lede a { color: var(--sk-primary-text); text-decoration: underline; }

.clv2-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin: 0;
}
.clv2-stat {
  padding: 0.6rem 0.9rem;
  border: 1px solid var(--sk-border);
  border-radius: 10px;
  background: var(--sk-surface);
  min-width: 92px;
}
.clv2-stat dt { margin: 0; }
.clv2-stat dd {
  margin: 0.1rem 0 0;
  font-size: 1.3rem;
  font-weight: 700;
  line-height: 1.1;
  color: var(--sk-text);
}
.clv2-stat-date { font-size: 0.95rem !important; }

.clv2-alert { display: flex; gap: 0.6rem; align-items: flex-start; margin-bottom: 1.5rem; }

/* ---------- layout -------------------------------------------------------- *
   Source order puts the ENTRIES first, so a phone gets the changelog and not a
   screenful of filters it has to scroll past — a search box and seven category
   links is most of a phone screen. Above 1024px grid placement moves the
   sidebar back into the left column. Same shape /cmds/v2 uses, and the reason
   is the same.                                                               */
.clv2-layout { display: grid; gap: 1.5rem; align-items: start; }
@media (min-width: 1024px) {
  .clv2-layout { grid-template-columns: 260px minmax(0, 1fr); gap: 2rem; }
  .clv2-side { grid-column: 1; grid-row: 1; position: sticky; top: calc(var(--skv2-h, 60px) + 1rem); }
  .clv2-list { grid-column: 2; grid-row: 1; }
}

/* ---------- filters ------------------------------------------------------- */
.clv2-side { display: grid; gap: 1.25rem; }
.clv2-side-title {
  margin-bottom: 0.5rem;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--sk-muted);
}
.clv2-search { display: block; }
.clv2-search-row { display: flex; gap: 0.5rem; margin-top: 0.35rem; }
.clv2-search-row .sk-input { flex: 1 1 auto; }
.clv2-cats { display: grid; gap: 0.15rem; }
.clv2-cat {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.5rem 0.7rem;
  border-radius: 9px;
  color: var(--sk-text-2);
  font-size: 0.9rem;
}
.clv2-cat span { display: inline-flex; align-items: center; gap: 0.5rem; min-width: 0; }
.clv2-cat i { width: 1em; text-align: center; color: var(--sk-muted); }
.clv2-cat:hover { background: var(--sk-surface-2); color: var(--sk-text); }
.clv2-cat.is-on { background: var(--sk-primary-soft); color: var(--sk-text); font-weight: 600; }
.clv2-cat.is-on i { color: var(--sk-primary-text); }
.clv2-cat-count { color: var(--sk-muted); font-size: 0.8rem; font-variant-numeric: tabular-nums; }
.clv2-side-empty { margin: 0; color: var(--sk-muted); font-size: 0.85rem; }
.clv2-clear { justify-self: start; }

/* ---------- the list ------------------------------------------------------ */
.clv2-list { display: grid; gap: 1.1rem; }
.clv2-count { margin: 0; color: var(--sk-muted); font-size: 0.85rem; }
.clv2-empty { border: 1px dashed var(--sk-border-2); border-radius: 14px; padding: 2.5rem 1rem; }
.clv2-empty a { color: var(--sk-primary-text); text-decoration: underline; }

.clv2-entry { scroll-margin-top: calc(var(--skv2-h, 60px) + 1rem); }
/* Landing on #entry-12 from a Discord link should show you which of the ten
   entries on the page you were sent to. */
.clv2-entry.is-target { outline: 2px solid var(--sk-primary); outline-offset: 3px; }
.clv2-entry-head {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  align-items: flex-start;
  justify-content: space-between;
}
.clv2-entry-id { min-width: 0; }
.clv2-entry-title { margin: 0; font-size: 1.15rem; letter-spacing: -0.01em; line-height: 1.25; }
.clv2-anchor { color: inherit; }
.clv2-anchor:hover { color: var(--sk-primary-text); }
.clv2-entry-meta { margin: 0.25rem 0 0; color: var(--sk-muted); font-size: 0.82rem; }
.clv2-version {
  font-family: "JetBrains Mono", ui-monospace, monospace;
  color: var(--sk-text-2);
  font-size: 0.95em;
}
.clv2-pill { display: inline-flex; align-items: center; gap: 0.35rem; white-space: nowrap; }
.clv2-pill-quiet { background: var(--sk-surface-2); color: var(--sk-text-2); border: 1px solid var(--sk-border-2); }

/* ---------- the rendered Markdown ----------------------------------------- *
   utils/markdown.js emits a fixed, small set of tags, so this is the whole
   list — there is no arbitrary HTML to defend against styling-wise either.   */
.clv2-body {
  color: var(--sk-text-2);
  line-height: 1.65;
  /* A changelog is full of URLs, package names and identifiers nobody put a
     break opportunity in. `anywhere` rather than `break-word` because only
     `anywhere` also shrinks the box's min-content width, which is what stops
     one long token sizing the grid track and pushing the card off the screen.
     Caught by `npm run audit:mobile`: a bare GitHub URL ran 188px past the
     card at 320px while every ELEMENT on the page measured clean — the box was
     the right size and the ink inside it was not. */
  overflow-wrap: anywhere;
}
.clv2-body > :first-child { margin-top: 0; }
.clv2-body > :last-child { margin-bottom: 0; }
.clv2-body h3,
.clv2-body h4,
.clv2-body h5,
.clv2-body h6 {
  margin: 1.4rem 0 0.5rem;
  color: var(--sk-text);
  line-height: 1.3;
}
.clv2-body h3 { font-size: 1.02rem; }
.clv2-body h4 { font-size: 0.95rem; }
.clv2-body h5,
.clv2-body h6 { font-size: 0.9rem; }
.clv2-body p { margin: 0 0 0.85rem; }
.clv2-body ul,
.clv2-body ol { margin: 0 0 0.85rem; padding-left: 1.35rem; }
.clv2-body li { margin: 0.2rem 0; }
.clv2-body a { color: var(--sk-primary-text); text-decoration: underline; }
.clv2-body strong { color: var(--sk-text); }
.clv2-body code {
  padding: 0.1em 0.35em;
  border-radius: 5px;
  background: var(--sk-surface-2);
  border: 1px solid var(--sk-border);
  font-family: "JetBrains Mono", ui-monospace, monospace;
  font-size: 0.88em;
  /* A long token in a code span must wrap rather than size the grid track. */
  overflow-wrap: anywhere;
}
.clv2-body pre {
  margin: 0 0 0.85rem;
  padding: 0.8rem 0.9rem;
  border-radius: 10px;
  background: var(--sk-surface-2);
  border: 1px solid var(--sk-border);
  /* A code block is one of the few things allowed to be wider than the screen,
     inside its own scroller. */
  overflow-x: auto;
}
.clv2-body pre code {
  padding: 0;
  border: 0;
  background: none;
  overflow-wrap: normal;
  white-space: pre;
}
.clv2-body blockquote {
  margin: 0 0 0.85rem;
  padding: 0.1rem 0 0.1rem 0.9rem;
  border-left: 3px solid var(--sk-border-2);
  color: var(--sk-muted);
}
.clv2-body blockquote p { margin: 0.5rem 0; }
.clv2-body hr { margin: 1.2rem 0; border: 0; border-top: 1px solid var(--sk-border); }
.clv2-body del { color: var(--sk-muted); }

/* ---------- pager --------------------------------------------------------- */
.clv2-pager {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: center;
  justify-content: space-between;
  padding-top: 0.5rem;
}
.clv2-pager-at { color: var(--sk-muted); font-size: 0.85rem; font-variant-numeric: tabular-nums; }
.clv2-pager .sk-btn { display: inline-flex; align-items: center; gap: 0.4rem; }

.clv2-totop { position: fixed; right: 1rem; bottom: 1rem; z-index: 50; }

/* ---------- touch --------------------------------------------------------- *
   Skynet UI sizes for a mouse. Below 16px iOS zooms the page on focus, and a
   sub-44px target is a miss on a phone.                                      */
@media (pointer: coarse) {
  .clv2-cat { min-height: 44px; }
  .clv2-search-row .sk-input,
  .clv2-search-row .sk-btn { min-height: 44px; font-size: 16px; }
  .clv2-pager .sk-btn { min-height: 44px; }
}
