.changelog {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 150;   
}
.changelog.is-open {
  display: block;
}
.changelog__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(2, 2, 2, 0.92);
  cursor: pointer;
}
.changelog__panel {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  background: var(--surface-000);
  animation: scaleIn 0.35s var(--ease-out-expo);
  overflow: hidden;
}
.changelog__aura {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 60% 40% at 15% 0%, var(--accent-glow), transparent 60%),
    radial-gradient(ellipse 50% 35% at 100% 100%, rgba(124, 92, 240, 0.18), transparent 65%);
  opacity: 0.6;
}
.changelog__bar {
  position: relative;
  z-index: 2;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: var(--header-height);
  padding-inline: var(--page-inset);
  border-bottom: 1px solid var(--border);
  background: rgba(5, 5, 5, 0.6);
  backdrop-filter: blur(var(--blur-md));
}
.changelog__bar-label {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font-family: var(--font-mono);
  font-size: calc(var(--text-xs) * 1.12);
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--text-50);
}
.changelog__close {
  position: static;
}
.changelog__scroll {
  position: relative;
  z-index: 1;
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
}
.changelog__intro {
  max-width: var(--content-width);
  margin: 0 auto;
  padding: var(--space-16) var(--page-inset) var(--space-10);
}
.changelog__eyebrow {
  font-family: var(--font-mono);
  font-size: calc(var(--text-2xs) * 1.12);
  text-transform: uppercase;
  letter-spacing: var(--tracking-widest);
  color: var(--text-25);
  margin-bottom: var(--space-4);
}
.changelog__title {
  font-size: clamp(calc(var(--text-3xl) * 1.12), 4.5vw, calc(var(--text-5xl) * 1.12));
  font-weight: 500;
  color: var(--text-100);
}
.changelog__subtitle {
  font-size: calc(var(--text-base) * 1.12);
  color: var(--text-50);
  max-width: 58ch;
  margin-top: var(--space-4);
  line-height: var(--leading-relaxed);
}
.changelog__timeline {
  --rail: 26px;
  --node-size: 19px;
  position: relative;
  max-width: var(--content-width);
  margin: 0 auto;
  padding: 0 var(--page-inset) var(--space-24);
}
.changelog__track {
  position: absolute;
  left: calc(var(--page-inset) + var(--rail) - 1px);   
  top: 0;
  bottom: var(--space-24);
  width: 2px;
  background: linear-gradient(to bottom,
    transparent 0%,
    var(--border-hover) 6%,
    var(--border-hover) 94%,
    transparent 100%);
}
.changelog__beam {
  position: absolute;
  inset-inline: 0;
  top: 0;
  height: 0%;
  width: 2px;
  opacity: 0;
  border-radius: 2px;
  background: linear-gradient(to top,
    var(--accent) 0%,
    #7c5cf0 22%,
    transparent 92%);
  will-change: height, opacity;
}
.changelog__row {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding-top: var(--space-10);
}
.changelog__row:first-child {
  padding-top: var(--space-4);
}
.changelog__marker {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.changelog__node {
  flex-shrink: 0;
  width: var(--node-size);
  height: var(--node-size);
  margin-left: calc(var(--rail) - (var(--node-size) / 2));
  border-radius: 50%;
  background: var(--surface-100);
  border: 1px solid var(--border-hover);
  display: flex;
  align-items: center;
  justify-content: center;
}
.changelog__node::after {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--text-25);
}
.changelog__row:first-child .changelog__node {
  border-color: var(--accent-muted);
}
.changelog__row:first-child .changelog__node::after {
  background: var(--accent);
  box-shadow: 0 0 6px var(--accent-glow);
}
.changelog__marker-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.changelog__version {
  font-family: var(--font-mono);
  font-size: calc(var(--text-lg) * 1.2);
  font-weight: 600;
  color: var(--text-90);
  white-space: nowrap;
}
.changelog__date {
  font-family: var(--font-mono);
  font-size: calc(var(--text-xs) * 1.2);
  color: var(--text-25);
  white-space: nowrap;
}
.changelog__meta-note {
  font-family: var(--font-mono);
  font-size: calc(var(--text-2xs) * 1.05);
  color: var(--text-25);
  white-space: nowrap;
}
.changelog__meta-note--warn {
  color: var(--status-warning);
  opacity: 0.85;
}
.changelog__row--end .changelog__version,
.changelog__row--end .changelog__date {
  white-space: normal;
}
.changelog__row--end .changelog__version {
  color: var(--text-70);
}
.changelog__end-btn {
  margin-top: var(--space-5);
}
@media (min-width: 861px) {
  .changelog__row--end .changelog__marker {
    flex: 0 0 280px;
  }
}
.changelog__content {
  min-width: 0;
  padding-left: calc(var(--rail) + (var(--node-size) / 2) + var(--space-3));
}
.changelog__content-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.changelog__content-head .badge {
  font-size: calc(var(--text-2xs) * 1.12);
}
.changelog__content-title {
  font-size: calc(var(--text-2xl) * 1.12);
  font-weight: 500;
  color: var(--text-100);
  margin-bottom: var(--space-3);
  line-height: var(--leading-snug);
}
.changelog__content-body {
  font-size: calc(var(--text-sm) * 1.12);
  color: var(--text-50);
  line-height: var(--leading-relaxed);
  max-width: none;
}
.changelog__content code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  color: var(--text-90);
  white-space: nowrap;
}
.changelog__ship-list {
  /* The kind of a change lives in its own right-aligned column, so a
     release reads as a legend down the left edge before you read a word
     of it. Declared here rather than on the item because the label is
     absolutely positioned and needs the same two numbers to line its
     box up with the item's first line. */
  --kind-col: 5rem;
  --kind-gap: var(--space-4);
  --note-size: calc(var(--text-xs) * 1.15);
  --note-line: 1.75;
  margin-top: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.changelog__ship-list li {
  position: relative;
  padding-left: calc(var(--kind-col) + var(--kind-gap));
  font-family: var(--font-mono);
  font-size: var(--note-size);
  line-height: var(--note-line);
  color: var(--text-70);
  text-wrap: pretty;
}
@media (min-width: 861px) {
  .changelog__row {
    flex-direction: row-reverse;
    gap: var(--space-8);
    padding-top: var(--space-16);
  }
  .changelog__row:first-child {
    padding-top: var(--space-4);
  }
  .changelog__track {
    left: auto;
    right: calc(var(--page-inset) + var(--rail) - 1px);
  }
  .changelog__marker {
    flex: 0 0 260px;
    flex-direction: row-reverse;
    align-items: center;
    position: sticky;
    top: calc(var(--space-10) + var(--space-4));
    align-self: flex-start;
  }
  .changelog-page .changelog__marker {
    top: calc(var(--header-height) + var(--space-4));
  }
  .changelog__node {
    margin-left: 0;
    margin-right: calc(var(--rail) - (var(--node-size) / 2));
  }
  .changelog__marker-text {
    align-items: flex-end;
    text-align: right;
  }
  .changelog__content {
    flex: 1;
    max-width: 680px;
    padding-left: 0;
  }
  .changelog__content-head {
    justify-content: flex-start;
  }
}
@media (max-width: 560px) {
  .changelog__intro {
    padding: var(--space-10) var(--page-inset) var(--space-8);
  }
  .changelog__content-title {
    font-size: calc(var(--text-xl) * 1.12);
  }
}
@media (prefers-reduced-motion: reduce) {
  .changelog__panel {
    animation: none;
  }
  .changelog__beam {
    transition: none;
  }
}
.theme-light .changelog__backdrop {
  background: rgba(24, 28, 26, 0.42);
}
.theme-light .changelog__panel {
  background: #fbfdfb;
}
.theme-light .changelog__aura {
  background:
    radial-gradient(ellipse 60% 40% at 15% 0%, rgba(126, 214, 165, 0.30), transparent 60%),
    radial-gradient(ellipse 50% 35% at 100% 100%, rgba(154, 226, 178, 0.28), transparent 65%);
  opacity: 0.75;
}
.theme-light .changelog__bar {
  background: rgba(251, 253, 251, 0.85);
}
.theme-light .changelog__beam {
  background: linear-gradient(to top, #1d7a56 0%, #57b98c 22%, transparent 92%);
}
.theme-light .changelog__node {
  background: #ffffff;
}
.theme-light .changelog__row:first-child .changelog__node {
  border-color: rgba(29, 122, 86, 0.55);
}
.theme-light .changelog__row:first-child .changelog__node::after {
  background: #1d7a56;
  box-shadow: 0 0 6px rgba(29, 122, 86, 0.35);
}
.theme-light .changelog__end-btn {
  border-color: rgba(18, 18, 26, 0.22);
}


/* ── Release-note kinds and feature names ──────────────────
   These lists ran "New: ...", "Fixed: ...", "Security: ..." with the
   kind set in the same weight and colour as the sentence explaining it.
   At a dozen items per release that is a wall of mono text where the
   one word telling you whether a line is a feature or a break is the
   hardest thing to find.

   The first fix painted the kind and the feature's name as one tinted
   run. It found them, but two tints butted together inside body text
   read as highlighter smear, and every item started at a different
   horizontal position because the kinds are different lengths.

   So the kind is out of the sentence entirely. It sits in a fixed
   column, right-aligned, which lines every label up against the same
   edge and lets you scan a release vertically: five SECURITY rows in a
   column is a fact you read before any sentence. The feature's name
   keeps the kind's colour and takes the weight, with no fill behind it,
   because one coloured word inside grey mono is already the strongest
   thing on the line.

   Only 13 of the 23 tagged items have a name to highlight. The rest are
   a single sentence with no title in it, and those keep the label alone
   rather than having 150 characters of description weighted to force a
   consistency that would defeat the point. The cut is at 60 characters,
   measured against the real text. */
.changelog__head {
  /* Sets the kind colour once; label and name both inherit it. */
  display: inline;
}
.changelog__head--security  { color: var(--status-critical); }
.changelog__head--new       { color: var(--status-contained); }
.changelog__head--fixed     { color: var(--status-dormant); }
/* Not --status-warning: that token is #9a6408, which measures 4.33:1
   against this card at this size, just under AA. Darkened to 4.9:1. The
   token stays as it is for the badges elsewhere that use it larger. */
.changelog__head--changed   { color: #8f5c07; }
.changelog__head--upgrading { color: var(--status-unknown); }

.changelog__tag {
  position: absolute;
  left: 0;
  top: 0;
  /* Matching the item's first line box centres the label against it at
     any font size, which guessing a top offset in em does not. */
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  width: var(--kind-col);
  height: calc(var(--note-size) * var(--note-line));
  font-size: calc(var(--text-2xs) * 1.02);
  font-weight: 600;
  line-height: 1;
  letter-spacing: var(--tracking-wider);
  text-transform: uppercase;
  white-space: nowrap;
  color: inherit;
}
.changelog__lead {
  font-weight: 600;
  color: inherit;
}
/* A command inside the name is part of the name. Left on the body
   colour it breaks the one coloured run in two. */
.changelog__ship-list .changelog__lead code {
  color: inherit;
  background: color-mix(in srgb, currentColor 13%, transparent);
}
/* An item with no kind gets a hairline in the same column, so a
   continuation or a minor note is visibly subordinate to the labelled
   items rather than looking like one that lost its label. */
.changelog__ship-list li:not(:has(.changelog__tag)) {
  /* Pulled up against the item above: an unlabelled note is usually a
     second paragraph of the one before it, and an even gap made it look
     like a peer. */
  margin-top: -0.4rem;
}
.changelog__ship-list li:not(:has(.changelog__tag))::before {
  content: '';
  position: absolute;
  left: calc(var(--kind-col) - 0.75rem);
  top: 0;
  width: 0.75rem;
  height: calc(var(--note-size) * var(--note-line));
  background: linear-gradient(var(--text-12), var(--text-12)) no-repeat center / 0.75rem 1px;
}

/* Everything in these lists is mono, so a command set in mono is
   invisible as a command. A faint plate is what separates the two. */
.changelog__ship-list code {
  padding: 0.1em 0.26em;
  border-radius: 3px;
  background: color-mix(in srgb, var(--text-100) 8%, transparent);
  color: var(--text-90);
  font-size: 0.93em;
}

/* Under the label column's width there is nothing to align to, so the
   label goes back inline and leads the sentence. */
@media (max-width: 620px) {
  .changelog__ship-list li {
    padding-left: 0;
  }
  .changelog__tag {
    position: static;
    display: inline;
    height: auto;
    width: auto;
    margin-right: 0.6em;
    vertical-align: baseline;
  }
  .changelog__ship-list li:not(:has(.changelog__tag))::before {
    display: none;
  }
}

/* The explanation is the thing you read once the label has told you
   what kind of line it is, so it stays on the body colour. */
.changelog__ship-list li {
  color: var(--text-70);
}
