/**
 * SIL Products catalog pages (/software-new/ + /fonts-new/) — styles the two
 * plugin-fed catalog templates need ON TOP of the shared card/filter styles
 * in software-style.css (site-wide) and the fonts header styles in
 * fonts-catalog.css. Tokens hardcoded per the theme's filter/toolbar design
 * system (see wp-content/CLAUDE.md): navy #002b5c, cyan #00ADEF,
 * border #e2e8f0, muted #64748b. px only — html { font-size: 62.5% } makes
 * rem values land at 62.5% of what you'd expect.
 */

/* ── Per-card Edit link (logged-in editors only) ──────────────────────────
 * A SIBLING of the card's main <a> (nested anchors are invalid HTML),
 * absolutely positioned over the card's top-right corner. The .card cell is
 * the positioning context.
 */
.software-page-wrap .cards .card {
    position: relative;
}
.product-card-edit,
.product-card-edit:visited,
.product-card-edit:hover,
.product-card-edit:focus {
    position: absolute;
    top: 7px;            /* clear of the title/star, closer to the true corner */
    right: 7px;
    z-index: 2;
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #002b5c;
    border-radius: 50%;
    font-size: 13px;
    text-decoration: none;
    opacity: 0;
    transition: opacity 0.15s, transform 0.25s;
    /* Pointer-events off while hidden so the invisible circle can't intercept
       a click meant for the card underneath it — this only affects mouse
       interaction, not Tab/keyboard focus, so it's still reachable that way. */
    pointer-events: none;
}
/* White at rest — only the button itself turns teal on hover/focus, as its
   own piece of feedback distinct from the card-level hover below. Repeated
   at matching specificity for the same reason as before: custom-style.css's
   site-wide `a:hover`/`a:focus` rules (color + text-decoration-color) are
   MORE specific than a bare `.product-card-edit`, so without restating color
   here, actually hovering/tabbing to the icon would flip it to the sitewide
   hover color instead of this teal. */
.product-card-edit,
.product-card-edit:visited {
    color: #fff;
}
.product-card-edit:hover,
.product-card-edit:focus {
    color: #00ADEF;
}
/* card:hover for mouse users, card:focus-within + the link's own :focus for
   keyboard users tabbing to it (it isn't visible until then). */
.software-page-wrap .cards .card:hover .product-card-edit,
.software-page-wrap .cards .card:focus-within .product-card-edit,
.product-card-edit:focus {
    opacity: 0.9;
    pointer-events: auto;
}

/* Moves in step with the card's own hover-lift (Card only — Compact doesn't
   lift at all, see its own :hover rule further down, so the pencil shouldn't
   shift there either) instead of staying put while everything else rises,
   which read as disconnected from the card. */
.software-page-wrap[data-view="card"] .cards .card:hover .product-card-edit {
    transform: translateY(-2px);
}

/* The card's own hover-lift (.inner-card:hover in software-style.css) only
   fires while the pointer is directly over .inner-card. The edit icon sits
   ON TOP of it (a sibling, positioned absolutely into its corner) so moving
   onto the icon takes the pointer OFF .inner-card, silently dropping the
   lift mid-hover — it looked like the card "put itself back down". Re-apply
   the identical lift keyed off the parent .card instead, which stays
   hovered continuously as long as the pointer is anywhere over the card,
   icon included. */
.software-page-wrap .cards .card:hover .inner-card {
    transform: translateY(-2px);
    border-color: #00ADEF;
    box-shadow: 0 8px 28px rgba(0, 43, 92, 0.1);
}

/* ── Fonts catalog: region sections ─────────────────────────────────────── */
.fonts-catalog-region {
    margin-top: 8px;
}
h2.fonts-region-heading {
    color: #002b5c;
    font-weight: 700;
    margin: 24px 0 4px;
    padding-bottom: 8px;
    border-bottom: 1px solid #e2e8f0;
    /* Anchor targets (#global etc.) shouldn't hide under the fixed header. */
    scroll-margin-top: 90px;
}

/* Names the catalog as a whole, above the filter card. Deliberately NOT given
   the region headings' divider: it heads the filter card and the list together,
   and a rule directly above the card read as a second, competing boundary. */
h2.fonts-catalog-heading {
    color: #002b5c;
    font-weight: 700;
    font-size: 26px;
    margin: 0 0 8px;
}
.fonts-catalog-empty {
    color: #64748b;
    font-size: 15px;
    margin: 24px 0;
}
.fonts-catalog-empty[hidden] {
    display: none; /* author CSS beats the UA [hidden] rule — required, see CLAUDE.md */
}

/* No-longer-supported fonts — a plain link list, not a card grid. Still
   findable/linkable for the fonts team, but visually de-emphasized next to
   the current, actively-supported fonts above. */
.fonts-catalog-discontinued .fonts-region-heading {
    color: #64748b;
}
.fonts-discontinued-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 8px 20px;
}
.fonts-discontinued-list li {
    font-size: 14px;
}
.fonts-discontinued-list a {
    color: #64748b;
}
.fonts-discontinued-list a:hover,
.fonts-discontinued-list a:focus {
    color: #002b5c;
    text-decoration: underline;
}

/* Region chips sit between the header and the filter card on the new page. */
.fonts-catalog-wrap .fonts-region-chips {
    margin-bottom: 20px;
}

/* ── Filter result animation ───────────────────────────────────────────────
 * Changing a filter used to just snap the grid to its new set of cards with
 * a plain jQuery .toggle() (display:none/block) — nothing visibly happened
 * except the page's scrollbar getting shorter, so it wasn't obvious the
 * filter had actually done anything. Same fade-out/refresh-in pattern as the
 * Jobs page (see job-card-fading/job-card-refresh in job-openings.css):
 * js/software-catalog.js and js/fonts-catalog-search.js fade the currently
 * visible cards out, swap which are shown, then run this animation on the
 * newly-visible set. */
/* .inner-card is the card grid's element; .fonts-row is a <tr> in the /fonts/
   table listing. Both are the thing a filter shows or hides, so both take the
   same two states rather than each file restating the cycle. */
.product-catalog-fading .inner-card,
.product-catalog-fading .fonts-row {
    opacity: 0;
    transition: opacity 0.12s ease;
}
@keyframes productCatalogCardRefresh {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}
.product-catalog-refresh .inner-card,
.product-catalog-refresh .fonts-row {
    animation: productCatalogCardRefresh 0.35s ease-out both;
}

/* ── View-density toggle: the control itself ──────────────────────────────────
 * Segmented 3-button group in the results bar (markup:
 * views/catalog-view-toggle.twig). Visually identical to the News feed's
 * .feed-view-toggle (css/feed.css) so the two read as one system — the tokens
 * are repeated literally here because feed.css's --feed-* custom properties
 * aren't loaded on these pages.
 */
.software-view {
    display: flex;
    align-items: center;
    gap: 10px;
}

.software-view-label {
    font-size: 11px;
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: rgba(0, 43, 92, 0.6);
}

.software-view-toggle {
    display: inline-flex;
    border: 1px solid #e2e8f0;
    border-radius: 10px;
    overflow: hidden;
}

.software-view-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 16px;
    border: 0;
    background: #fff;
    color: #64748b;
    font-size: 14px;
    font-weight: 700;
    font-family: inherit; /* buttons don't inherit the page font by default */
    cursor: pointer;
    /* Deliberately NOT transitioned. The grid relayout on a view switch is
       instantaneous, so a 0.15s cross-fade on the pressed button made the
       selection visibly lag the thing it had just changed. */
}

/* Font Awesome glyph, so size with font-size — width/height sized the old
   inline SVG and does nothing for an <i>. 15px keeps the icon exactly the size
   it has always rendered at. text-align/width pin the glyph box so the Card and
   Table icons, which have different natural widths, don't shift the label. */
.software-view-icon {
    /* Font Awesome glyphs don't fill their em box, so at font-size 15px they
       inked only ~13px tall against the Card SVG's true 15px and read as
       visibly smaller and slightly high. 17px brings fa-table's ink to 15.0px,
       matching the SVG exactly; fa-bars is a flatter glyph and lands at ~12.8px,
       which is as close as a single size gets without making it overbearingly
       wide. Box widened to 18px because fa-table inks ~16.9px across at 17px
       and would otherwise be clipped by a 16px box. */
    font-size: 17px;
    line-height: 1;
    width: 18px;
    text-align: center;
    flex-shrink: 0;
}

/* Hidden below 759px (see the responsive block at the end of this file) — the
   SVG icon alone identifies the button there, and each button's aria-label
   keeps it accessible either way. */
.software-view-btn-label {
    white-space: nowrap;
}

.software-view-btn + .software-view-btn {
    border-left: 1px solid #e2e8f0;
}

.software-view-btn:hover,
.software-view-btn:focus-visible {
    color: #002b5c;
}

.software-view-btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(0, 173, 239, 0.15);
}

.software-view-btn.is-active {
    background: #002b5c;
    color: #fff;
}

/* ── View modes: Card / Compact ───────────────────────────────────────────────
 * data-view lives on .software-page-wrap (both catalogs; the Fonts page's
 * wrapper carries .fonts-catalog-wrap as well, so one attribute restyles every
 * region section's list at once).
 *
 *   Card         the DEFAULT — the multi-column card grid these pages have
 *                always had. It deliberately has NO rules of its own, so
 *                picking Card can never drift from the base CSS.
 *   Compact      a full-width SINGLE-COLUMN list with the card chrome removed —
 *                thin divider between rows, small icon, title, and the
 *                secondary details (status / external-link / featured) pushed
 *                to the right of the same row. No description at all.
 *                Modelled directly on .feed[data-view="compact"].
 *
 * (A third "Comfortable" mode — a roomier bordered row with the description —
 * was removed: it read as too close to Card, and Compact covers the need for a
 * dense list.)
 *
 * The list mode never touches opacity or transform on .inner-card, so it can't
 * fight the .product-catalog-fading / .product-catalog-refresh filter
 * animation (switching view is a different action from filtering and
 * deliberately doesn't fade).
 */

/* ── Shared list-mode groundwork ──────────────────────────────────────────── */

/* The grid becomes a plain vertical stack. On the Fonts page this rule hits
   every region's own .row.cards, which is why data-view sits on the one shared
   wrapper. */
.software-page-wrap[data-view="compact"] .row.cards {
    display: flex;
    flex-direction: column;
    /* .cust-card-style's own `flex-wrap: wrap` would otherwise let this column
       spill into a SECOND column once the rows overflow. */
    flex-wrap: nowrap;
}

/* The flex-basis-on-the-wrong-axis trap CLAUDE.md warns about, in the flesh:
   software-style.css sets `.card { flex-basis: 33.33333% }` (plus 50%/100%
   variants at other widths) for the old Bootstrap ROW layout, where it means a
   width. Flipping this container to `flex-direction: column` silently re-reads
   those as HEIGHTS — every row became a third of the whole list tall, ~850px of
   empty space under one line of text. Reset the flex shorthand outright. */
.software-page-wrap[data-view="compact"] .row.cards > .card {
    flex: none;
}

/* .inner-card is a flex COLUMN in card view (icon/title stacked over the
   description). A list row needs the opposite: icon in its own column beside a
   text column, with the secondary details pinned right. `display: contents` on
   the two structural wrappers (.top-sec, .first-section) dissolves them so
   .title-img / .title-txt / .title-icon / .content / .third-section all become
   direct grid items of .inner-card and can be placed freely — no markup change,
   so Card view is untouched. */
.software-page-wrap[data-view="compact"] .top-sec,
.software-page-wrap[data-view="compact"] .first-section {
    display: contents;
}

/* Card view centres the product name over the icon; a list row reads left. */
.software-page-wrap[data-view="compact"] h2.title-text {
    text-align: left;
}

/* .title-txt is width-capped for the narrow card column — a list row's title
   should use the whole line. */
.software-page-wrap[data-view="compact"] .title-txt,
.software-page-wrap[data-view="compact"] .first-section .title-txt {
    max-width: none;
    width: auto;
    min-width: 0;
}

/* No badge-on-the-icon here (tried and reverted) — Card keeps its original
   look untouched (software-style.css's `.first-section .title-icon` flex
   layout, star at the end of the title row). */

/* ── Compact — dense divider list, details on the right, no card ──────────── */

.software-page-wrap[data-view="compact"] .row.cards {
    gap: 0;
}

/* Strict A–Z regardless of the Settings-tab "pin featured to the top" option
   — Card/Comfortable honour that setting via their DOM/data order (unchanged
   here), but Compact always re-sorts by --alpha-order, a per-card custom
   property set inline from a separately-fetched, un-pinned rank (see
   page-software-catalog.php / page-fonts-catalog.php). Scoped to Compact
   only, so it has no effect on Card/Comfortable's own order. */
.software-page-wrap[data-view="compact"] .row.cards > .card {
    order: var(--alpha-order, 0);
}

/*  [icon] Title [ext] ……………………………………………………  Status
 *  Title and the ext-link marker are both content-sized (auto) so they hug
 *  each other regardless of how long the title is; Status's column is the
 *  one flexible (1fr) track, absorbing whatever space is left and pinning
 *  the status text to the row's right edge via justify-self: end below. */
.software-page-wrap[data-view="compact"] .card > .inner-card {
    display: grid;
    grid-template-columns: auto auto auto minmax(0, 1fr);
    align-items: center;
    /* .card > .inner-card's base `justify-content: space-between` was written
       for its flex-column layout; on a grid it distributes the TRACKS. */
    justify-content: start;
    column-gap: 14px;
    padding: 8px 10px;
    min-height: 0;
    /* No card at all — just a hairline between rows, exactly like
       .feed[data-view="compact"] .feed-item. Per-row bottom borders rather than
       an outer container border, so a filtered-to-empty region leaves nothing
       behind. */
    border: 0 !important;
    border-bottom: 1px solid #e2e8f0 !important;
    border-radius: 0;
    box-shadow: none;
}

.software-page-wrap[data-view="compact"] .first-section .title-img {
    grid-column: 1;
    grid-row: 1;
    max-width: none;
    display: flex;
    align-items: center;
}

/* 30px, vs the News feed's 26px logo: these are glyph specimens on
   /fonts-new/, and below ~28px an "Aa" sample stops being readable. Verified on
   the rendered page, not just in the stylesheet. */
.software-page-wrap[data-view="compact"] .first-section .title-img img {
    width: 30px;
}

.software-page-wrap[data-view="compact"] .title-txt {
    grid-column: 2;
    grid-row: 1;
}

.software-page-wrap[data-view="compact"] h2.title-text {
    font-size: 15px;
    line-height: 1.3;
}

/* No description in this view at all — that's what Card view is for. */
.software-page-wrap[data-view="compact"] .content {
    display: none;
}

/* Secondary details: the external-link marker sits right after the title
   (column 3), status text is pinned at the far right (column 4). Dissolving
   .third-section (display:contents, compact-only) so its two children — the
   status text and the external-link marker — can each get their own grid
   column instead of being stuck together as one flex group. The OS-icon strip
   is dropped here deliberately — at 16px a row of six platform icons is
   noise, and it's still one click away in Card view. */
.software-page-wrap[data-view="compact"] .third-section {
    display: contents;
}

.software-page-wrap[data-view="compact"] .sub-icon {
    display: none;
}

.software-page-wrap[data-view="compact"] div.sub-txt {
    grid-column: 4;
    grid-row: 1;
    justify-self: end;
}

.software-page-wrap[data-view="compact"] h1.sub-txt {
    font-size: 12px;
    width: auto;
    text-align: right;
    white-space: nowrap;
}

/* Small and unobtrusive, but kept: it's the one cue that the link leaves the
   site, which matters more to visitors than it does to the page. Right after
   the title rather than grouped with Status, per feedback. */
/* The row's 14px column-gap is right between the specimen and the title, but a
   touch wide between the title and its own external-link marker — that marker
   is a footnote ON the title, not a separate field, so it wants to sit nearer
   than the grid's general spacing. Pulled back 4px (net ~10px) rather than
   tightening column-gap, which would close the specimen/title gap too. */
.software-page-wrap[data-view="compact"] .per-link {
    grid-column: 3;
    grid-row: 1;
    margin-left: -4px;
    /* The base .per-link is `text-align: right` (written for the card corner,
       where it is pushed to the far edge). Here the box is a few px wider than
       the glyph, so right-aligning left that slack BETWEEN the title and the
       icon — the software list still measured 14px to the icon after the
       margin had moved the box to 10px. Left-aligning makes the box and the
       glyph start at the same place, so both lists measure the same. */
    text-align: left;
}

.software-page-wrap[data-view="compact"] i.fa.fa-external-link {
    font-size: 13px;
    margin-top: 0;
    color: #64748b;
}

/* No per-row star in Compact — featured products are grouped under their own
   "Featured" heading at the top of the list instead (see
   .software-compact-heading / .software-compact-break below), so the marker
   would just be redundant clutter on every one of those rows. */
.software-page-wrap[data-view="compact"] .first-section .title-icon {
    display: none;
}

/* No lift and no shadow — a row-highlight instead, matching
   .feed[data-view="compact"] .feed-item:hover. #F1F5F9 (not the lighter
   #F8FAFC page background) to match the filter dropdown's own hover fix —
   that tint was chosen there for real contrast headroom, not just style,
   see .software-filter-option:hover in software-style.css. */
.software-page-wrap[data-view="compact"] .cards .card:hover .inner-card {
    transform: none;
    box-shadow: none;
    background: #F1F5F9;
}

/* The hover-only edit pencil is positioned for a 20px-padded card corner. On a
   compact row it belongs vertically centred at the right edge; it may overlap
   the featured star on the handful of featured rows while hovered, which only
   ever affects logged-in editors. */
.software-page-wrap[data-view="compact"] .product-card-edit {
    top: 50%;
    margin-top: -11px;
    right: 4px;
    width: 22px;
    height: 22px;
    font-size: 10px;
}

/* ── Fonts catalog: region spacing in the list mode ──────────────────────── */

/* .cust-card's generic 30px padding above each region's list is a lot of empty
   space to repeat once per region in a view whose point is density. */
/* On /fonts-new/ this image isn't a logo, it's a glyph specimen — the whole
   point is being able to read the sample. 30px (fine for a software product
   icon you only need to recognise) makes a non-Latin specimen like Busra or Dai
   Banna unreadable, so the fonts list runs a size up. Checked on the rendered
   page, not just in the stylesheet. */
.fonts-catalog-wrap[data-view="compact"] .first-section .title-img img {
    width: 36px;
}

.fonts-catalog-wrap[data-view="compact"] .fonts-catalog-region .inner-wrapper.cust-card {
    padding-top: 8px;
}

.fonts-catalog-wrap[data-view="compact"] h2.fonts-region-heading {
    margin: 22px 0 4px;
}

/* ── Phone width (theme's custom 759px breakpoint) ────────────────────────── */
@media (max-width: 759px) {
    /* The fonts page's badge text ("Looking for Software? …") is longer than the
       software page's, and the shared .software-page-badge rule sets
       white-space: nowrap — which overflows a 375px viewport. Let it wrap. */
    .fonts-catalog-wrap .software-page-badge {
        white-space: normal;
        text-align: left;
    }

    /* Toggle reduces to icon-only so the count + both buttons still fit one
       line on a phone; each button's aria-label (in the Twig partial) carries
       the meaning once the visible text is gone. */
    .software-view-label,
    .software-view-btn-label {
        display: none;
    }

    .software-view-btn {
        padding: 9px 12px;
    }

    /* Compact on a phone keeps the SAME one-line row as desktop, just tighter.
       (The News feed has to stack its compact row at this width, but only
       because it truncates the title with an ellipsis; these titles simply wrap,
       so nothing is ever cut off and the details can stay on the right where the
       whole point of the view puts them.) */
    .software-page-wrap[data-view="compact"] .card > .inner-card {
        column-gap: 10px;
        padding: 8px 4px;
    }

    /* NB: software-style.css's own 759px rule widens .row.cards' gap to 32px,
       but it's one specificity point lighter than the [data-view] rules above,
       so the list modes' own gaps still hold on phones. */
}

/* ══════════════════════════════════════════════════════════════════════════
 * Compact view: OS support matrix — SOFTWARE CATALOG ONLY
 * ══════════════════════════════════════════════════════════════════════════
 * Promoted from the /software-test/ experiment (css/software-test.css). Scoped
 * to .software-catalog-wrap, NOT .software-page-wrap: the Fonts catalog shares
 * that outer class and has no OS data, so it must not inherit the extra matrix
 * column or the narrower table width.
 *
 * One column per operating system with a checkmark per supported platform, so
 * they line up down the page, under a sticky header of OS icons.
 */

.software-catalog-wrap[data-view="compact"] {
    --compact-os-width: 192px; /* 6 OS columns × 32px */
    /* Icon track is a fixed 30px (the icon image's own width) rather than
       `auto`: auto tracks are sized per grid instance, and the header has no
       icon, so its second column — and therefore the "Software name" label —
       would start in a different place from every row's title. */
    --compact-columns: 30px auto 16px minmax(0, 1fr) var(--compact-os-width);
    /* Narrower than the page, and CENTRED — the table plus its own
       "Showing N / View" toolbar share this width, so the inset reads as
       deliberate rather than as a list that ran out of content on the right.
       One number to tune. */
    --compact-table-width: 750px;
}

/* Only the LIST narrows. The "Showing N / View" bar deliberately keeps the
   full page width: it used to share this max-width so the table and its
   toolbar lined up, but that moved the View buttons ~195px left the instant
   you pressed one — the control jumping out from under the cursor that just
   activated it, which breaks "click again to go back". A control shouldn't
   move as a result of its own use; the table's sticky header already carries
   the alignment. */
.software-catalog-wrap[data-view="compact"] .row.cards {
    max-width: var(--compact-table-width);
    margin-left: auto;
    margin-right: auto;
}

/*  [icon] [title] [ext] ……spacer…… [Win][Lin][Mac][And][Web][iOS]
 *  Everything from the OS block rightwards is a FIXED width and the flexible
 *  spacer soaks up each row's different title length — that's what makes the
 *  OS columns align down the list even though every row is its own
 *  independent grid. The ext-link column keeps its 16px even on rows without
 *  one, for the same reason. */
.software-catalog-wrap[data-view="compact"] .card > .inner-card {
    grid-template-columns: var(--compact-columns);
    /* No right padding: it left a 10px strip of un-ruled, un-highlighted row
       after the last OS column, which read as a narrow empty 7th column —
       most obvious when the column hover tint stopped short of the edge. The
       matrix is now flush with the table's right edge. */
    padding-right: 0;
}

/* No Status label in the Compact row — it's still a fully working filter
   facet, just not echoed as text in every row. Nor the sitewide gray fill
   Discontinued/Unsupported rows get elsewhere (.inner-card.Discontinued in
   software-style.css). Card view keeps both. */
.software-catalog-wrap[data-view="compact"] div.sub-txt {
    display: none;
}

.software-catalog-wrap[data-view="compact"] .inner-card.Discontinued,
.software-catalog-wrap[data-view="compact"] .inner-card.Unsupported {
    background: #fff;
}

/* ── The matrix itself ──────────────────────────────────────────────────────
 * A nested 6-column grid rather than six top-level columns: the fixed template
 * guarantees the cells line up between the header and every row, and it keeps
 * the outer grid to one OS track instead of six.
 */
.software-os-header,
.software-catalog-wrap .os-matrix {
    display: none; /* Card view keeps the inline .sub-icon strip instead */
}

.software-catalog-wrap[data-view="compact"] .os-matrix {
    display: grid;
    grid-template-columns: repeat(6, 32px);
    grid-column: 5;
    grid-row: 1;
    /* Full row height, not content height: `stretch` beats .inner-card's
       `align-items: center`, and the negative margins cancel its 8px vertical
       padding so the column rules below run edge to edge and MEET the row's
       horizontal hairline. Without this they're short stubs floating beside
       each checkmark — separators rather than a table. */
    align-self: stretch;
    margin-top: -8px;
    margin-bottom: -8px;
}

.software-catalog-wrap[data-view="compact"] .os-cell {
    display: flex;
    align-items: center;    /* centres the checkmark in a now full-height cell */
    justify-content: center;
    border-left: 1px solid #e2e8f0; /* same color as the row hairlines */
}

.software-catalog-wrap[data-view="compact"] .os-cell:first-child {
    border-left: 0; /* no line against the spacer column */
}

/* Navy, not the filter panel's cyan: at this size a cyan glyph on white is
   about 2.3:1, well under the 4.5:1 these need as real information rather
   than decoration. */
.software-catalog-wrap[data-view="compact"] .os-check {
    color: #002b5c;
    font-size: 15px;
    line-height: 1;
}

/* Column hover — js/software-catalog.js tags the same-index cell in every row
   (and the header) when you hover any one of them, so you can trace a single
   OS down the whole table. CSS can't do this alone: each row is its own grid,
   so there's no "column" element to select. A cyan wash rather than the row
   hover's gray tint, so where the two cross reads as both at once. */
.software-catalog-wrap[data-view="compact"] .os-cell.is-col-hover {
    background: rgba(0, 173, 239, 0.1);
}

/* ── Sticky column header ───────────────────────────────────────────────────
 * A child of .row.cards, so it pins to the top of the PRODUCT LIST: it holds
 * while you scroll the list and releases as soon as the last row goes past,
 * instead of floating over the whole page. The site nav scrolls away on
 * desktop, so top: 0 is right; there's nothing fixed above it to clear.
 */
.software-catalog-wrap[data-view="compact"] .software-os-header {
    display: grid;
    grid-template-columns: var(--compact-columns);
    align-items: center;
    column-gap: 14px;
    /* Taller than a row, with the extra weighted towards the top: once it's
       pinned there's nothing above it, so without that the icons sit right up
       against the top of the window. */
    padding: 14px 0 10px 10px; /* right: 0, so the header columns reach the table edge too */
    position: sticky;
    top: 0;
    z-index: 3; /* over the edit pencil (z-index: 2) */
    background: #F1F5F9; /* same tint rows take on hover — reads as a header band */
    border-bottom: 2px solid #cbd5e1; /* heavier than the rows' 1px hairline */
    order: -1; /* above every row, whatever --alpha-order they carry */
}

/* Hidden by js/software-catalog.js when a filter leaves no rows, so the header
   isn't left stranded over an empty list. Author CSS has to beat the UA
   [hidden] rule — see CLAUDE.md. */
.software-catalog-wrap[data-view="compact"] .software-os-header[hidden] {
    display: none;
}

/* The rules run edge to edge in the header too, so its columns read as
   continuous with the rows'. Margins mirror the header's own padding above,
   not a row's 8px. */
.software-catalog-wrap[data-view="compact"] .software-os-header .os-matrix {
    margin-top: -14px;
    margin-bottom: -10px;
}

/* Two column headings, same small-caps treatment as the filter section's
   field labels. */
.software-catalog-wrap[data-view="compact"] .software-os-header-label {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #64748b;
}

/* Sits in the title column, so it lines up exactly with the product names
   below it (see the fixed 30px icon track above). */
.software-catalog-wrap[data-view="compact"] .software-os-header-label--name {
    grid-column: 2;
    justify-self: start;
    white-space: nowrap;
}

/* In the spacer column, pushed right so it sits against the matrix. */
.software-catalog-wrap[data-view="compact"] .software-os-header-label--os {
    grid-column: 4;
    justify-self: end;
    white-space: nowrap;
}

.software-catalog-wrap[data-view="compact"] .software-os-header .os-cell img {
    display: block;
    width: 18px;
    height: auto;
}

/* Every in-table position for the edit pencil collides with something: at the
   generic right: 4px it sits on the iOS column's checkmarks, and parked in the
   spacer it sits under the "Runs on" heading. So it goes in the page gutter
   just outside the table, where the 750px centred width leaves ~195px of free
   space either side — clear of every column, still obviously attached to its
   row, and only ever visible to a logged-in editor on hover. */
.software-catalog-wrap[data-view="compact"] .product-card-edit {
    right: auto;
    left: -34px;
}

/* Sitting in the gutter leaves a 12px gap between the pencil and the row's
   own box. The pencil only shows while .card is hovered — and although
   hovering the pencil itself keeps that true (:hover matches ancestors of the
   hovered element, box geometry notwithstanding), crossing that gap hovers
   NEITHER, so it vanished before the pointer could reach it. This invisible
   strip bridges the gap so the hover is continuous the whole way across.
   Not needed in the in-table positions below, where it just extends into the
   empty spacer column and harms nothing. */
.software-catalog-wrap[data-view="compact"] .product-card-edit::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 100%;
    width: 14px;
}

/* The gutter the pencil sits in only exists once the container is wider than
   the 750px table. Below roughly 860px it isn't — the table fills the
   container, and left: -34px put the pencil off the left edge of the screen
   entirely (measured: x = -10 at a 768px viewport). Park it back in the empty
   spacer column for that range: not ideal, since it sits under the "Runs on"
   heading, but visible and still clear of the checkmarks.
   MUST come before the 759px block below, which overrides it again for phones
   where there's no matrix to avoid. */
@media (max-width: 859px) {
    .software-catalog-wrap[data-view="compact"] .product-card-edit {
        left: auto;
        right: calc(var(--compact-os-width) + 30px);
    }
}

/* Six 32px columns plus a title can't fit a phone; drop the matrix and its
   header and fall back to the ordinary Compact row. */
@media (max-width: 759px) {
    .software-catalog-wrap[data-view="compact"] {
        --compact-columns: 30px auto 16px minmax(0, 1fr);
    }

    .software-catalog-wrap[data-view="compact"] .software-os-header,
    .software-catalog-wrap[data-view="compact"] .os-matrix {
        display: none;
    }

    /* No edit pencil at all on a phone: nobody edits the catalog from one, and
       it would otherwise need a third position here. */
    .software-catalog-wrap .product-card-edit {
        display: none;
    }

    .software-catalog-wrap[data-view="compact"] .card > .inner-card {
        padding-right: 4px;
    }
}

/* ── Compact-row chevron (phones) ─────────────────────────────────────────────
 * Shared pattern — see CLAUDE.md "Compact list rows". A compact row navigates
 * to one destination, so it carries a right chevron saying so. Navigation, not
 * disclosure: nothing expands inline, so a caret or plus would be wrong.
 *
 * Targets .inner-card, NOT .card: .inner-card is what renders as the row (it
 * carries the border and padding), and on Fonts the .card is an item in a
 * multi-column flow, where an absolutely positioned child escapes its column
 * box and widens the page.
 *
 * Each selector spells out its own ::after. Writing the pair as a shared
 * comma list with one ::after on the end silently applies the whole
 * declaration block to the FIRST selector as a plain rule — which turned
 * every Software compact card into an 8px absolutely positioned box.
 *
 * The chevron is absolutely positioned and pulled to the row's true vertical
 * centre rather than laid out as a grid/flex cell, which would centre it
 * across whatever it spans and drift once the row's lines differ in height.
 * It is drawn from borders, never a text glyph: text in CSS content cannot be
 * reached by GTranslate (see CLAUDE.md), and it is decoration anyway — the
 * row's own link carries the destination.
 *
 * Phones only: wider layouts show real columns, where this would be noise.
 */
@media (max-width: 759px) {
    .software-page-wrap[data-view="compact"] .card > .inner-card,
    .fonts-catalog-wrap[data-view="compact"] .card > .inner-card {
        position: relative;
        padding-right: 26px;
    }

    .software-page-wrap[data-view="compact"] .card > .inner-card::after {
        content: '';
        position: absolute;
        right: 10px;
        top: 50%;
        transform: translateY(-50%) rotate(-45deg);
        width: 8px;
        height: 8px;
        border-right: 2px solid #64748b;
        border-bottom: 2px solid #64748b;
        opacity: 0.6;
        pointer-events: none;   /* never intercept the row's own link */
    }

    .fonts-catalog-wrap[data-view="compact"] .card > .inner-card::after {
        content: '';
        position: absolute;
        right: 10px;
        top: 50%;
        transform: translateY(-50%) rotate(-45deg);
        width: 8px;
        height: 8px;
        border-right: 2px solid #64748b;
        border-bottom: 2px solid #64748b;
        opacity: 0.6;
        pointer-events: none;
    }
}

/* The Card icon is an inline SVG while Table/Compact are Font Awesome glyphs,
   so it needs sizing in its own right — font-size does nothing to an <svg>,
   and the 16px box the font icons sit in would stretch it. 15px against its
   15-unit viewBox keeps one unit to one pixel, which is what keeps its edges
   sharp. If you ever change one of those numbers, change both. */
svg.software-view-icon {
    width: 15px;
    height: 15px;
}
