/* ════════════════════════════════════════════════════════════════════
   Changelog — Figma frame "changelog" (node 177:303).

   Nav and Footer in that frame come from base.html and are out of scope
   for this rebuild.

   Every value below was read off the frame and is pinned by
   tests/test_changelog_design_fidelity.py against
   tests/design/changelog_page_tokens.json. Do not adjust a number without
   changing the frame and re-extracting: the test will fail, by design.

   Colours are written as literals rather than custom properties. The
   fidelity tests assert per-rule — that .cl-tag--fixed itself carries
   #fbbf24 and its two alphas — because the three pill variants are the
   values most likely to drift apart, and var() indirection would hide
   exactly the drift the tests exist to catch.

   Five things that are easy to get wrong, and so are called out:

     - Nothing on this frame casts a shadow. Not the CTA box, not the
       pills, not the entry rows. Reaching for one is the reflex and it is
       not this design.
     - Two slate alphas. The per-entry divider is rgba(51,65,85,0.35); the
       CTA box border is rgba(51,65,85,0.7). Collapsing them makes the
       dividers twice as loud as the frame draws them.
     - The divider is the width of the CONTENT column (672 of the entry's
       900), not of the whole entry — so it is a border-bottom on
       .cl-entry-body, which is also why no empty element exists for it.
     - base.css sets line-height 1.6 on body. Most text nodes here are
       leading-normal, and inheriting 1.6 inflates every pill and timeline
       row. The three roles that DO carry a numeric leading in the frame
       (h1 1.2, hero sub 1.55, bullet text 1.5) restate it below.
     - This page does NOT widen .container the way /contact does. Its
       widest element is the 960px CTA box and base.css already yields
       1060; copying that override would move the header and footer too.

   No inline styles anywhere on this page: style-src-attr is hash-pinned
   (chaos_tester_csp_style_hashes.py).
   ════════════════════════════════════════════════════════════════════ */

/* The frame's own background fill. Sampled off the 177:303 render: the glow
   peaks at (50%, 30%) on #173948 and closes exactly one radius out, which is
   the SAME ellipse /contact, /status, /api and /ai-website-audit use — and
   NOT the landing/scan glow. Scoped to the body class so it cannot leak onto
   any other page. */
body.changelog-page {
    background:
        radial-gradient(ellipse 60% 30% at 50% 30%, #173948 0%, #0e1a2c 55%, rgba(6, 9, 20, 0) 100%),
        #020617;
    background-attachment: fixed;
}

.changelog {
    /* The frame puts 64px between the nav's bottom edge and the eyebrow.
       main.container carries u-padding-y (80px top), but the site's header is
       `position: fixed` and 75px tall, so that padding clears the header by
       only 5px. This restores the frame's gap: 80 + 59 - 75 = 64 visible.
       Recompute if the header's height ever changes. */
    padding-top: 59px;
}

/* ── header (177:317) ──────────────────────────────────────────────── */

.cl-head {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    max-width: 800px;
    margin: 0 auto;
    text-align: center;
}
.cl-eyebrow {
    margin: 0;
    font-size: 12px;
    font-weight: 700;
    line-height: normal;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: #00bfff;
}
.cl-head h1 {
    margin: 0;
    font-size: 44px;
    font-weight: 700;
    line-height: 1.2;
    color: #ffffff;
}
.cl-hero-sub {
    margin: 0;
    font-size: 16px;
    font-weight: 400;
    line-height: 1.55;
    color: #b0b8c8;
}

/* ── release list (177:321) ────────────────────────────────────────── */

.cl-entries {
    list-style: none;
    /* 64px from the header block, then the frame's own 24px of top padding
       inside the list — 88px in total to the first entry. */
    margin: 64px auto 0;
    padding: 0;
    padding-top: 24px;
    max-width: 900px;
    display: flex;
    flex-direction: column;
    gap: 40px;
}

/* ── one entry (177:322) ───────────────────────────────────────────── */

.cl-entry {
    display: grid;
    /* minmax(0,1fr) rather than 1fr: a bare 1fr floors at min-content, and a
       long unbroken token in a bullet would push the column past its share. */
    grid-template-columns: 180px minmax(0, 1fr);
    gap: 48px;
    align-items: start;
}

/* The month is an <h2> for structure and the frame's cyan timeline label for
   looks. Left alone it would inherit the browser's 1.5em bold. */
.cl-entry-date {
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    line-height: normal;
    color: #00bfff;
}

.cl-entry-body {
    display: flex;
    flex-direction: column;
    gap: 18px;
    min-width: 0;
    /* 177:344 — the hairline under each entry, 18px below the bullets and
       only as wide as this column. Every entry has one, including the last. */
    padding-bottom: 18px;
    border-bottom: 1px solid rgba(51,65,85,0.35);
}

/* ── bullets (177:328) ─────────────────────────────────────────────── */

.cl-bullets {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.cl-bullet {
    display: flex;
    align-items: flex-start;
    gap: 12px;
}
/* 177:330 — 3px of optical alignment that lines the pill's cap height up with
   the first line of the bullet text beside it. */
.cl-tag-wrap {
    display: flex;
    align-items: flex-start;
    padding-top: 3px;
    flex-shrink: 0;
}
.cl-tag {
    display: inline-flex;
    padding: 4px 10px;
    border-radius: 6px;
    border: 1px solid transparent;
    font-size: 11px;
    font-weight: 600;
    line-height: normal;
    /* "IMPROVED" breaking in half would double the row's height. */
    white-space: nowrap;
}
/* The fill is the ink at 10% and the border the ink at 25% — the same two
   alphas for all three kinds. The label is the full-strength ink: the wash is
   nowhere near readable against #020617. */
.cl-tag--new {
    background: rgba(0,191,255,0.1);
    border-color: rgba(0,191,255,0.25);
    color: #00bfff;
}
.cl-tag--improved {
    background: rgba(74,222,128,0.1);
    border-color: rgba(74,222,128,0.25);
    color: #4ade80;
}
.cl-tag--fixed {
    background: rgba(251,191,36,0.1);
    border-color: rgba(251,191,36,0.25);
    color: #fbbf24;
}
.cl-bullet-text {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 14px;
    font-weight: 400;
    line-height: 1.5;
    color: #b0b8c8;
}
/* base.css gives <code> a mono face; the frame draws this inline with the
   sentence, so it keeps the row's size rather than the browser's default. */
.cl-bullet-text code {
    font-size: 13px;
    color: #cbd5e1;
}

/* ── final CTA (177:404) ───────────────────────────────────────────── */

/* The body frame's 40px bottom padding plus the CTA frame's 80px top padding
   put 120px above the box. Below it the frame leaves 80, of which
   main.container's u-padding-y already supplies 48. */
.cl-cta {
    padding: 120px 0 32px;
}
.cl-cta-box {
    width: 960px;
    max-width: 100%;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 20px;
    padding: 48px 64px;
    background: #0f172a;
    border: 1px solid rgba(51,65,85,0.7);
    border-radius: 16px;
    text-align: center;
}
.cl-cta-box h2 {
    margin: 0;
    font-size: 32px;
    font-weight: 700;
    line-height: normal;
    color: #ffffff;
}
.cl-cta-sub {
    max-width: 600px;
    margin: 0;
    font-size: 15px;
    font-weight: 400;
    line-height: normal;
    color: #b0b8c8;
}
.cl-cta-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 15px 36px;
    border-radius: 12px;
    background: #00bfff;
    color: #0d121a;
    font-size: 15px;
    font-weight: 600;
    line-height: normal;
    text-decoration: none;
}
.cl-cta-btn:hover { background: #33c7ff; color: #0d121a; }

/* ── responsive (project convention: base.css collapses at 768px) ───── */

/* The frame gives no phone layout, so the project's own breakpoint applies.
   The 180px timeline plus its 48px gutter costs 228px of a 375px viewport
   before a word of content, so the date moves above the bullets it labels —
   which is also its reading order already. */
@media (max-width: 768px) {
    .changelog { padding-top: 8px; }

    .cl-entries {
        margin-top: 40px;
        gap: 32px;
    }
    .cl-entry {
        grid-template-columns: minmax(0, 1fr);
        gap: 12px;
    }

    .cl-head h1 { font-size: 2.2rem; }
    .cl-hero-sub { font-size: 1rem; }

    .cl-cta { padding: 64px 0 8px; }
    .cl-cta-box { padding: 32px 20px; }
    .cl-cta-box h2 { font-size: 24px; }
}

/* The pill and its text sit side by side down to the narrowest phone: the
   longest label ("IMPROVED") is 78px, which still leaves 250px of text
   column at 375px. Only below that does the row need to stack. */
@media (max-width: 360px) {
    .cl-bullet {
        flex-direction: column;
        gap: 6px;
    }
    .cl-tag-wrap { padding-top: 0; }
}
