/* ============================================================================
   changelog.css — release notes, everywhere they appear
   ----------------------------------------------------------------------------
   THE ONE THING TO KNOW ABOUT THIS FILE: it is LAYOUT-NEUTRAL. It is loaded on

     /changelog              public, layouts.app
     /store/{slug}           public, layouts.app
     /dashboard/changelog    authenticated, layouts.dashboard

   and the same partial (resources/views/changelog/partials/entry.blade.php)
   renders on all three. So nothing here may depend on dashboard.css tokens —
   they are declared on .dash-body and simply do not exist on a public page,
   where a var() with no fallback resolves to nothing and the rule silently
   disappears.

   The palette is therefore restated as --chg-* properties on the components
   themselves. The VALUES are the site palette, unchanged and not negotiable:

     bg #0F0E0E · surface #141313 · raised #1A1919 · border #262424
     muted #8A8585 · secondary #C9C5C5 · white #FFF · accent #EA9C22
     success #22C55E · warning #F97316 · danger #EF4444

   Every class is prefixed `chg-`. theme.css / store.css / product.css are the
   original design and are not editable, so nothing here may collide with them.

   DENSITY. 14px body text, entries a card apart, and generous padding — the
   operator's standing complaint is cramped rows, and a changelog read on a
   phone is the easiest place in the world to get that wrong.
   ========================================================================= */

/* THE TOKENS ARE DECLARED ON EVERY BLOCK THAT CAN STAND ALONE, not on one
   wrapper, because these classes are used in four templates that do not share
   an ancestor. .chg-chips is on this list even though the public changelog
   always nests it inside .chg-filters: the dashboard's What's new page puts the
   product chips inside a <x-dash.card>, where there is no .chg-filters above
   them, and a var() with no declaration anywhere in the chain makes the whole
   declaration invalid at computed-value time — so `border: 1px solid
   var(--chg-border)` silently becomes no border at all and the chips render as
   bare text. That failure has no error and no 404 behind it; the only symptom
   is a control that looks unfinished. If you reuse a chg- block somewhere new,
   check it inherits these from something. */
.chg-entry,
.chg-filters,
.chg-chips,
.chg-empty,
.chg-pager,
.chg-more {
    --chg-bg:        #0F0E0E;
    --chg-surface:   #141313;
    --chg-raised:    #1A1919;
    --chg-border:    #262424;
    --chg-muted:     #8A8585;
    --chg-secondary: #C9C5C5;
    --chg-accent:    #EA9C22;
    --chg-success:   #22C55E;
    --chg-warning:   #F97316;
    --chg-danger:    #EF4444;

    --chg-radius:    16px;
    --chg-radius-sm: 10px;
}


/* ── The page ──────────────────────────────────────────────────────────────
   Only on /changelog; the product page and the dashboard supply their own
   section frame. */
.chg-page {
    padding: 64px 0 96px;
    background: #0F0E0E;
}

.chg-product-section { padding: 64px 0; }


/* ── Filters ───────────────────────────────────────────────────────────────
   A plain GET form. Every filter therefore ends up in the URL, which is what
   makes a filtered view bookmarkable and pasteable into a ticket. */
.chg-filters {
    display: flex;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 16px 24px;
    margin-bottom: 32px;
    padding: 20px 24px;
    border: 1px solid var(--chg-border);
    border-radius: var(--chg-radius);
    background: var(--chg-surface);
}

.chg-filter { display: flex; flex-direction: column; gap: 8px; }

.chg-filter label {
    font-size: 12px;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--chg-muted);
}

.chg-select {
    min-width: 220px;
    padding: 11px 14px;
    border-radius: var(--chg-radius-sm);
    border: 1px solid var(--chg-border);
    background: var(--chg-raised);
    color: #FFFFFF;
    font-family: inherit;

    /* 14px on a pointer device, 16px on a phone. Below 16 iOS Safari zooms the
       whole page when the field is focused and never zooms back — the token,
       its measurements and why it is a floor rather than a size are in the
       block at the top of enhancements.css. This is the one text-entry control
       in this sheet; it renders on the public /changelog, where the dashboard's
       chips are not available. */
    font-size: max(var(--field-font-floor, 0px), 14px);
}

.chg-select:focus-visible {
    outline: none;
    border-color: var(--chg-accent);
    box-shadow: 0 0 0 3px rgba(234, 156, 34, .18);
}

/* Type filters as CHIPS rather than a second select: there are exactly four,
   they are what people actually filter by, and each one is a real link — so it
   needs no JavaScript and can be opened in a new tab. */
.chg-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-left: auto;
}

.chg-chip {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    /* 40px tall: a tap target, not a link. */
    min-height: 40px;
    padding: 0 15px;
    border-radius: 999px;
    border: 1px solid var(--chg-border);
    background: var(--chg-raised);
    color: var(--chg-secondary);
    font-size: 13.5px;
    text-decoration: none;
    transition: border-color .18s ease, color .18s ease, background .18s ease;
}

.chg-chip:hover { border-color: rgba(234, 156, 34, .45); color: #FFFFFF; }
.chg-chip > i   { font-size: 16px; }

.chg-chip.is-on {
    border-color: var(--chg-accent);
    background: rgba(234, 156, 34, .12);
    color: #FFFFFF;
}

/* Each type keeps its own colour on the chip icon, so the chips and the group
   headings below are recognisably the same vocabulary. */
.chg-chip-added   > i { color: var(--chg-success); }
.chg-chip-changed > i { color: var(--chg-accent); }
.chg-chip-fixed   > i { color: var(--chg-warning); }
.chg-chip-removed > i { color: var(--chg-danger); }

/* The Apply button is the NO-JAVASCRIPT path. The page's inline script stamps
   .has-chg-auto on <html> once it has bound the auto-submit, so this
   disappears exactly when it stops being needed — the same pattern the admin
   panel's live-toggle uses for its Save buttons. */
.has-chg-auto .chg-filter-go { display: none; }


/* ── One entry ─────────────────────────────────────────────────────────────
   A card per release. The alternative — a continuous stream with headings —
   makes it impossible to see where one release stops and the next starts once
   two of them are short. */
.chg-stream {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.chg-entry {
    border: 1px solid var(--chg-border);
    border-radius: var(--chg-radius);
    background: var(--chg-surface);
    padding: 28px 32px;
}

.chg-entry-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px 24px;
    padding-bottom: 18px;
    margin-bottom: 20px;
    border-bottom: 1px solid var(--chg-border);
}

.chg-entry-ident { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 14px; min-width: 0; }

.chg-entry-version {
    margin: 0;
    font-size: 22px;
    font-weight: 600;
    color: var(--chg-accent);
    letter-spacing: -.01em;
    /* Tabular figures so a column of versions lines up rather than shimmying
       by a pixel per digit. */
    font-variant-numeric: tabular-nums;
}

.chg-entry-title {
    margin: 0;
    font-size: 17px;
    font-weight: 500;
    color: #FFFFFF;
}

.chg-entry-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px 18px;
    font-size: 13.5px;
    color: var(--chg-muted);
}

.chg-entry-meta i { font-size: 15px; }

.chg-entry-product,
.chg-entry-date {
    display: inline-flex;
    align-items: center;
    gap: 7px;
}

.chg-entry-product {
    color: var(--chg-secondary);
    text-decoration: none;
    transition: color .18s ease;
}

.chg-entry-product:hover { color: var(--chg-accent); }

.chg-entry-summary {
    margin: 0 0 22px;
    font-size: 14.5px;
    line-height: 1.7;
    color: var(--chg-secondary);
    max-width: 76ch;
}

.chg-entry-summary strong { color: #FFFFFF; font-weight: 600; }

.chg-entry-none {
    margin: 0;
    font-size: 14px;
    color: var(--chg-muted);
    font-style: italic;
}


/* ── Grouped items ─────────────────────────────────────────────────────────
   Two columns on a wide screen, one on a narrow one. auto-fit rather than a
   fixed count: an entry with only "Fixed" gets a full-width group instead of a
   half-width one with a hole beside it. */
.chg-groups {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 24px;
}

.chg-group {
    border-radius: var(--chg-radius-sm);
    border: 1px solid var(--chg-border);
    background: var(--chg-raised);
    padding: 18px 20px 20px;
}

.chg-group-head {
    display: flex;
    align-items: center;
    gap: 9px;
    margin: 0 0 14px;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--chg-secondary);
}

.chg-group-head > i { font-size: 17px; }

.chg-group-count {
    margin-left: auto;
    padding: 2px 9px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .05);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0;
    color: var(--chg-muted);
    font-variant-numeric: tabular-nums;
}

.chg-items {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 11px;
}

.chg-items li {
    position: relative;
    padding-left: 20px;
    font-size: 14px;
    line-height: 1.65;
    color: var(--chg-secondary);
}

.chg-items li strong { color: #FFFFFF; font-weight: 600; }

/* A drawn marker rather than list-style, so its colour is per-type and its
   offset does not depend on the browser's bullet metrics. */
.chg-items li::before {
    content: '';
    position: absolute;
    left: 2px;
    top: .62em;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    opacity: .55;
}

/* THE FOUR TYPES. Colour on the heading icon, the left border and the bullet —
   three cues, because colour alone is not one for a colour-blind reader and
   the heading text is the fourth. */
.chg-added   { border-left: 3px solid var(--chg-success); }
.chg-changed { border-left: 3px solid var(--chg-accent); }
.chg-fixed   { border-left: 3px solid var(--chg-warning); }
.chg-removed { border-left: 3px solid var(--chg-danger); }

.chg-added   .chg-group-head > i { color: var(--chg-success); }
.chg-changed .chg-group-head > i { color: var(--chg-accent); }
.chg-fixed   .chg-group-head > i { color: var(--chg-warning); }
.chg-removed .chg-group-head > i { color: var(--chg-danger); }

.chg-added   .chg-items li::before { background: var(--chg-success); }
.chg-changed .chg-items li::before { background: var(--chg-accent); }
.chg-fixed   .chg-items li::before { background: var(--chg-warning); }
.chg-removed .chg-items li::before { background: var(--chg-danger); }


/* ── Empty state ───────────────────────────────────────────────────────────
   A real panel, not a bare sentence. "Nothing here" set as loose text in the
   middle of a page reads as a rendering fault. */
.chg-empty {
    text-align: center;
    padding: 72px 32px;
    border: 1px solid var(--chg-border);
    border-radius: var(--chg-radius);
    background: var(--chg-surface);
}

.chg-empty > i { font-size: 40px; color: var(--chg-muted); }

.chg-empty h2 {
    margin: 18px 0 10px;
    font-size: 20px;
    font-weight: 600;
    color: #FFFFFF;
}

.chg-empty p { margin: 0; font-size: 14.5px; line-height: 1.7; color: var(--chg-muted); }
.chg-empty a { color: var(--chg-accent); }


/* ── Pager ─────────────────────────────────────────────────────────────────
   Prev/next rather than a numbered strip: this is a stream read from the top,
   not a table people jump around in. */
.chg-pager {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 12px 20px;
    margin-top: 32px;
}

.chg-pager-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 42px;
    padding: 0 18px;
    border-radius: var(--chg-radius-sm);
    border: 1px solid var(--chg-border);
    background: var(--chg-raised);
    color: var(--chg-secondary);
    font-size: 14px;
    text-decoration: none;
    transition: border-color .18s ease, color .18s ease;
}

.chg-pager-link:hover { border-color: rgba(234, 156, 34, .45); color: #FFFFFF; }

/* The disabled ends are <span>, not <a> — a link that goes nowhere is still
   announced and focusable, which is worse than not being there. */
.chg-pager-link.is-disabled { opacity: .4; cursor: default; }
.chg-pager-link.is-disabled:hover { border-color: var(--chg-border); color: var(--chg-secondary); }

.chg-pager-info {
    font-size: 13.5px;
    color: var(--chg-muted);
    font-variant-numeric: tabular-nums;
}

.chg-more { margin-top: 28px; text-align: center; }


/* ── Narrow viewports ──────────────────────────────────────────────────────
   The chips drop below the select rather than being squeezed beside it, and
   the entry loses its wide padding. */
@media (max-width: 860px) {
    .chg-chips { margin-left: 0; width: 100%; }
    .chg-select { min-width: 0; width: 100%; }
    .chg-filter { width: 100%; }
}

@media (max-width: 640px) {
    .chg-page { padding: 40px 0 64px; }
    .chg-entry { padding: 22px 18px; }
    .chg-filters { padding: 16px 18px; }
    .chg-entry-version { font-size: 20px; }
    .chg-groups { grid-template-columns: 1fr; gap: 16px; }
}

@media (prefers-reduced-motion: reduce) {
    .chg-chip,
    .chg-pager-link,
    .chg-entry-product { transition: none; }
}


/* ── TOUCH TARGETS ─────────────────────────────────────────────────────────
   This sheet was never given the pass the rest of the panel had, and it is a
   member page: /dashboard/changelog is in the sidebar, and the same partial
   renders the public /changelog. Measured on both, at all twelve device
   profiles AND on the desktop — neither control has a floor at any width, so
   unlike everything else fixed this round these were short everywhere, not
   only above some rung.

     a.chg-chip            126.5 x 40    the product filter, the page's only
                                         control and the first thing a thumb
                                         goes for
     a.chg-entry-product   168 x 24.8    the link from a release note to the
                                         product it is about, once per entry

   THE CHIP TAKES THE FLOOR DIRECTLY. Its own note already calls it "a tap
   target, not a link" and then declares 40, which is four short; nothing is
   competing for the vertical space (the chips wrap onto their own rows at
   every width) so the row simply grows 4px on a touch device and is untouched
   on a pointer one.

   THE ENTRY LINK TAKES A HIT AREA INSTEAD, because it must not. It sits in
   .chg-entry-meta, a 24.8px flex row shared with the release date, and a
   min-height there would add ~19px to the header of every entry on both pages
   — a page of ten notes pays 190px for one link. A positioned ::after
   participates in hit testing and in no layout at all, which is the technique
   .adm-check, .dash-footer-links a and .dash-bill-resume already use here.

   THE ROOM WAS MEASURED, NOT ASSUMED. A 44px band centred on 24.8px of ink
   reaches 9.6px above and below it. The nearest other interactive element in
   the same column is 95-143px above (a filter chip) and 458-728px below (the
   next entry's product link), at 320, 360, 768 and 852 — so the band cannot
   take a tap meant for anything else. It grows vertically only: the date sits
   18px to the RIGHT and is not a link, but widening into it would still put
   an invisible box over text somebody may be trying to select.

   NOT .chg-entry-product AS A WHOLE. The same class is a <span> when the
   product has been withdrawn — that variant is deliberately not a link, and
   giving it a hit area would advertise a tap that does nothing. `a.` is the
   whole difference and it is load-bearing. */
@media (hover: none) {
    .chg-chip { min-height: 44px; }

    a.chg-entry-product { position: relative; }

    a.chg-entry-product::after {
        content: '';
        position: absolute;
        left: 0;
        right: 0;
        top: 50%;
        height: 44px;
        transform: translateY(-50%);
    }
}
