/* ===================================================
   GEM DOWNLOADS
   O3DE gem cards, licence gate, and the module archive
   ===================================================
   Sibling of release-downloads.css, deliberately a separate file: these
   components sit on a different data model (O3DE repo.json catalogues
   rather than versions.json builds) and gs-docsy's static assets are
   UNFINGERPRINTED, so editing an existing stylesheet serves stale CSS to
   every returning visitor. A new filename has no cached predecessor.

   Same surface strategy as its sibling: every fill and border is mixed
   from `currentColor`, so a card adopts whichever Docsy `td-box` surface
   it is dropped onto, in either theme, with no per-surface rules. The
   flat rgba line above each color-mix is the fallback.

   ACCENT: --bs-primary, not the --gs-accent pair defined in
   release-downloads.css. That pair is hardcoded to OPAL's navy/gold at
   :root and would brand a GS_Play page with OPAL's colours. --bs-primary
   is set per-site by the Bootstrap theme map, so it is correct everywhere.
   =================================================== */

/* Spacing here is deliberately SMALL. These blocks are dropped between a
   heading and a button bar inside a Docsy `blocks/section`, which already
   supplies the generous outer padding -- so anything this element adds is
   spacing on top of spacing, and it read as a gulf.

   Both margins are also overridable per call site: the `class` param on
   gem-downloads / gem-archive lands on this element, so `class="mt-0 mb-0"`
   (or any Bootstrap spacing utility) wins from the stylesheet's own
   specificity of 0-1-0.

   KEEPING THIS AT 0-1-0 IS WHY THE MARKUP USES <div>. Docsy puts 5rem of
   block padding on `.td-default main section` -- a DESCENDANT selector, so it
   hits nested sections too, and a shortcode always renders inside the page's
   own td-box <section>. As a <section> this element inherited that a second
   time and rendered with 10rem at each end; the `padding: 0 1rem` below never
   applied, because 0-1-0 loses to Docsy's 0-1-2.

   Beating it in CSS would need `.td-default main section.gs-gems` at 0-2-2,
   which would also outrank the very utilities the `class` param exists to
   pass in. Changing the element sidesteps the whole contest. Do not turn
   these back into <section> elements. */
.gs-gems {
    /* Room for THREE 32rem cards plus their gaps (1584px) and this element's
       own padding. This is the governing width only when the block is NOT
       wrapped in a Bootstrap `.container` -- a `{{% blocks/section %}}` with no
       `type` emits one, capping the row at 1140/1320px no matter what is set
       here. Use `type="row"` on the section, as the specs and feature blocks
       already do, and this cap takes over. */
    max-width: 1616px;
    margin: 0 auto 1rem;
    padding: 0 1rem;
    text-align: left;
}

.gs-gems__head {
    margin-bottom: 1rem;
}

/* --- Category groups within a tier ---
   Subordinate to the tier heading and clearly above the cards: enough weight
   to break a long list into readable sets, not so much that a group competes
   with the tier it sits inside. */
.gs-gems__group {
    margin-top: 0;
    margin-bottom: 4rem;
}

/* Spacing lives on ONE side only, so groups cannot stack their gaps: nothing
   above the first, nothing below the last, a single value between. */
.gs-gems__group:last-child {
    margin-bottom: 0;
}

.gs-gems__group-title {
    margin: 0 0 0.25rem;
    font-size: 1.35rem;
    font-weight: 700;
}

.gs-gems__group-tagline {
    margin: 0 0 1.1rem;
    font-size: 0.95rem;
    opacity: 0.75;
}

.gs-gems__title {
    margin: 0;
    font-size: 1.6rem;
    font-weight: 700;
}

.gs-gems__tagline {
    margin: 0.35rem 0 0;
    opacity: 0.82;
}


/* ===================================================
   LICENCE GATE -- modal
   ===================================================
   A <dialog>, so it costs no layout until something opens it. The panel
   this replaced pushed the first card most of a screen down for a thing
   most visitors read once.

   Colours here cannot use the currentColor trick the cards rely on: a
   modal is painted over the page, not dropped onto a Docsy surface, so
   it has no host surface to inherit from and a transparent-ish fill
   would show the page through it. It gets explicit tokens instead,
   flipped by [data-bs-theme], which is what Docsy stamps on <html>. */

.gs-eula {
    width: min(34rem, calc(100vw - 2rem));
    max-height: calc(100vh - 4rem);
    padding: 0;
    border: 1px solid rgba(127, 127, 127, 0.3);
    border-radius: 14px;
    background: #fff;
    color: #212529;
    box-shadow: 0 18px 48px rgba(0, 0, 0, 0.28);
    overflow: auto;
}

[data-bs-theme="dark"] .gs-eula {
    background: #131a26;
    color: #f2f4f7;
    border-color: rgba(255, 255, 255, 0.16);
}

.gs-eula::backdrop {
    background: rgba(8, 12, 20, 0.62);
    backdrop-filter: blur(2px);
}

/* Fallback for browsers without showModal(): the script sets the `open`
   attribute, which displays the dialog in normal flow rather than in the
   top layer. Pin it so it still reads as a dialog. */
.gs-eula[open]:not(:modal) {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 1080;
}

.gs-eula__form {
    padding: 1.75rem 1.6rem 1.4rem;
    margin: 0;
}

.gs-eula__title {
    margin: 0 0 0.75rem;
    font-size: 1.25rem;
    font-weight: 700;
}

.gs-eula__title i {
    margin-right: 0.5rem;
    opacity: 0.85;
}

.gs-eula__lede {
    margin: 0 0 1rem;
    font-size: 0.95rem;
    line-height: 1.55;
}

.gs-eula__check {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    margin-bottom: 1.25rem;
    cursor: pointer;
    font-weight: 600;
}

.gs-eula__box {
    flex: 0 0 auto;
    width: 1.15rem;
    height: 1.15rem;
    margin-top: 0.15rem;
    accent-color: var(--bs-primary);
    cursor: pointer;
}

.gs-eula__actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.gs-eula__accept:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.gs-eula__cancel {
    text-decoration: none;
    opacity: 0.7;
}

.gs-eula__cancel:hover {
    opacity: 1;
}

.gs-eula__note {
    margin: 1.1rem 0 0;
    font-size: 0.8rem;
    line-height: 1.5;
    opacity: 0.7;
}

/* Rendered only when scripting is off, and deliberately outside the
   dialog -- a closed <dialog> renders none of its contents, so a notice
   in there would be invisible in exactly the case it exists for. */
.gs-eula__noscript {
    max-width: 1100px;
    margin: 0 auto 1.5rem;
    padding: 0.9rem 1.1rem;
    border-radius: 10px;
    border-left: 4px solid var(--bs-primary);
    background: rgba(127, 127, 127, 0.12);
    background: color-mix(in srgb, currentColor 9%, transparent);
    font-weight: 600;
    text-align: left;
}


/* ===================================================
   GEM CARDS
   =================================================== */

/* CARD WIDTH IS FIXED; THE ROW COUNT GIVES WAY.

   Tracks are capped at 32rem rather than sized in `fr`, so a card is 512px
   whether it sits alone, beside one sibling, or among six. A fractional max
   made the same card a different component depending on how many neighbours
   it happened to have -- ~520px at two-up, 340px at three-up.

   Cards therefore WRAP rather than shrink. With a definite max the grid takes
   its column count from that max, so three cards land as two-plus-one on any
   ordinary display: three 512px tracks need 1584px of grid, and Bootstrap's
   .container tops out at 1320px (xxl). True three-up would mean breaking the
   grid out of the theme container, which is a site-wide change, not a card
   one. */
.gs-gem-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(19rem, 32rem));
    gap: 1.5rem;
    justify-content: center;
}

/* A lone card is already capped by the track above; this keeps the explicit
   rule in place so a single-card grid cannot be widened by accident. */
.gs-gem-grid--single {
    grid-template-columns: minmax(0, 32rem);
}

.gs-gem-card {
    display: flex;
    flex-direction: column;
    padding: 1.6rem 1.5rem 1.35rem;
    border-radius: 14px;
    background: rgba(127, 127, 127, 0.10);
    background: color-mix(in srgb, currentColor 7%, transparent);
    border: 1px solid rgba(127, 127, 127, 0.28);
    border: 1px solid color-mix(in srgb, currentColor 20%, transparent);
    transition: transform 0.18s ease, border-color 0.18s ease;
}

.gs-gem-card.is-ready:hover {
    transform: translateY(-3px);
    border-color: var(--bs-primary);
}

.gs-gem-card.is-soon {
    opacity: 0.72;
}

.gs-gem-card__head {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    margin-bottom: 0.6rem;
}

.gs-gem-card__icon {
    font-size: 1.45rem;
    line-height: 1;
    opacity: 0.9;
}

.gs-gem-card__name {
    margin: 0;
    font-size: 1.2rem;
    font-weight: 700;
}

.gs-gem-card__version {
    margin-left: auto;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 700;
    white-space: nowrap;
    background: var(--bs-primary);
    color: #fff;
}

.gs-gem-card__version--soon {
    background: rgba(127, 127, 127, 0.28);
    background: color-mix(in srgb, currentColor 22%, transparent);
    color: inherit;
    font-weight: 600;
    opacity: 0.85;
}

.gs-gem-card__summary {
    margin: 0 0 1rem;
    font-size: 0.94rem;
    line-height: 1.55;
    opacity: 0.9;
}

.gs-gem-card__summary p:last-child {
    margin-bottom: 0;
}

/* Release date, size and notes link. One line, wrapping as a unit --
   it is scan material, not prose. */
.gs-gem-card__meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin: 0 0 0.9rem;
    font-size: 0.85rem;
    opacity: 0.85;
}

.gs-gem-card__sep {
    opacity: 0.5;
}

/* --- Facts list --- */
.gs-gem-card__facts {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.3rem 0.75rem;
    margin: 0 0 1.1rem;
    font-size: 0.85rem;
}

.gs-gem-card__facts dt {
    font-weight: 700;
    opacity: 0.7;
    white-space: nowrap;
}

.gs-gem-card__facts dd {
    margin: 0;
}

.gs-gem-card__hint {
    opacity: 0.65;
    font-style: italic;
}

/* --- Subscribe row --- */
.gs-gem-subscribe {
    margin-bottom: 1rem;
}

/* The locked stand-in for the copy row. Full width so swapping it for the
   row on acceptance does not shift the card's height. */
.gs-gem-reveal {
    display: block;
    width: 100%;
}

.gs-gem-card__label {
    display: block;
    margin-bottom: 0.35rem;
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    opacity: 0.7;
}

.gs-gem-card__label i {
    margin-right: 0.35rem;
}

.gs-copy {
    display: flex;
    align-items: stretch;
    border-radius: 8px;
    overflow: hidden;
    border: 1px solid rgba(127, 127, 127, 0.34);
    border: 1px solid color-mix(in srgb, currentColor 26%, transparent);
}

.gs-copy__field {
    flex: 1 1 auto;
    min-width: 0;
    padding: 0.45rem 0.6rem;
    border: 0;
    background: rgba(127, 127, 127, 0.10);
    background: color-mix(in srgb, currentColor 8%, transparent);
    color: inherit;
    font-family: var(--bs-font-monospace, monospace);
    font-size: 0.78rem;
    text-overflow: ellipsis;
}

.gs-copy__field:focus {
    outline: 2px solid var(--bs-primary);
    outline-offset: -2px;
}

.gs-copy__btn {
    flex: 0 0 auto;
    padding: 0.45rem 0.8rem;
    border: 0;
    border-left: 1px solid rgba(127, 127, 127, 0.34);
    border-left: 1px solid color-mix(in srgb, currentColor 26%, transparent);
    background: var(--bs-primary);
    color: #fff;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
}

.gs-copy__btn i {
    margin-right: 0.35rem;
}

.gs-copy__btn:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

.gs-copy__btn.is-copied {
    background: #1f9d55;
}

/* --- Card footing ---
   The card is a flex column: header and summary sit at the top, and everything
   from the release meta down is grouped here so it can be pushed to the bottom
   TOGETHER. `margin-top: auto` belongs on this group, not on the buttons --
   putting it on the buttons alone strands the meta and facts against the
   description and opens the gap in the middle of the card instead. */
.gs-gem-card__base {
    display: flex;
    flex-direction: column;
    margin-top: auto;
}

.gs-gem-card__base > :last-child {
    margin-bottom: 0;
}

/* --- Actions + footer --- */
.gs-gem-card__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
}

.gs-gem-card__btn {
    flex: 1 1 auto;
}

.gs-gem-card__btn--alt {
    flex: 0 0 auto;
}

/* A locked link has no href, so the UA gives it a text cursor and no
   hover affordance -- which reads as "you cannot click this". It IS
   clickable; it opens the licence dialog and carries on to the download.
   Restore the pointer, and do NOT dim it: a greyed, not-allowed button is
   a lie about what the click will do. */
.gs-gem-card__btn.is-locked,
.gs-gem-rel__dl .is-locked {
    cursor: pointer;
}

.gs-gem-card__foot {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0.9rem 0 0;
    font-size: 0.8rem;
    opacity: 0.78;
}

.gs-gem-card__sha {
    font-size: 0.72rem;
    opacity: 0.8;
}

.gs-gem-card__note {
    margin: 0.4rem 0 0;
    font-size: 0.88rem;
}

.gs-gem-card__note .badge {
    margin-right: 0.4rem;
}

.gs-gem-card__note--warn {
    opacity: 0.85;
}


/* ===================================================
   ARCHIVE -- module rail + panel
   ===================================================
   Two columns above md, one below. The rail is sticky so the module list
   stays reachable while a long version table scrolls. */

.gs-gem-archive {
    display: grid;
    grid-template-columns: minmax(12rem, 15rem) minmax(0, 1fr);
    gap: 2rem;
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 1rem;
    text-align: left;
}

/* The mobile module picker. Hidden where the rail is shown. */
.gs-gem-archive__picker {
    display: none;
}

.gs-gem-archive__picker-label {
    display: block;
    margin-bottom: 0.35rem;
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    opacity: 0.7;
}

.gs-gem-archive__select {
    width: 100%;
    padding: 0.5rem 0.6rem;
    border-radius: 8px;
    border: 1px solid rgba(127, 127, 127, 0.34);
    border: 1px solid color-mix(in srgb, currentColor 26%, transparent);
    background: rgba(127, 127, 127, 0.10);
    background: color-mix(in srgb, currentColor 8%, transparent);
    color: inherit;
    font: inherit;
}

.gs-gem-archive__rail {
    position: sticky;
    top: 5rem;
    align-self: start;
    max-height: calc(100vh - 7rem);
    overflow-y: auto;
    padding-right: 0.25rem;
}

.gs-gem-archive__group {
    margin: 1.1rem 0 0.4rem;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    opacity: 0.6;
}

.gs-gem-archive__group:first-child {
    margin-top: 0;
}

.gs-gem-archive__tab {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    width: 100%;
    padding: 0.5rem 0.7rem;
    margin-bottom: 0.15rem;
    border: 0;
    border-radius: 8px;
    border-left: 3px solid transparent;
    background: none;
    color: inherit;
    font: inherit;
    font-size: 0.92rem;
    text-align: left;
    cursor: pointer;
}

.gs-gem-archive__tab:hover {
    background: rgba(127, 127, 127, 0.12);
    background: color-mix(in srgb, currentColor 9%, transparent);
}

.gs-gem-archive__tab:focus-visible {
    outline: 2px solid var(--bs-primary);
    outline-offset: 1px;
}

.gs-gem-archive__tab.is-active {
    font-weight: 700;
    border-left-color: var(--bs-primary);
    background: rgba(127, 127, 127, 0.16);
    background: color-mix(in srgb, currentColor 12%, transparent);
}

/* Nothing published yet. Still listed -- the roster is part of the story. */
.gs-gem-archive__tab.is-empty {
    opacity: 0.55;
}

.gs-gem-archive__tab i {
    flex: 0 0 1.1rem;
    opacity: 0.8;
}

.gs-gem-archive__tab-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.gs-gem-archive__count {
    flex: 0 0 auto;
    padding: 0.05rem 0.4rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    background: rgba(127, 127, 127, 0.22);
    background: color-mix(in srgb, currentColor 16%, transparent);
}

.gs-gem-archive__head {
    margin-bottom: 1.25rem;
}

.gs-gem-archive__name {
    margin: 0;
    font-size: 1.5rem;
    font-weight: 700;
}

.gs-gem-archive__name i {
    margin-right: 0.4rem;
    opacity: 0.8;
}

.gs-gem-archive__links {
    margin: 0.3rem 0 0;
    font-size: 0.85rem;
    opacity: 0.8;
}

.gs-gem-archive__empty {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 2rem 1rem;
    opacity: 0.75;
}

/* --- Version table --- */
.gs-gem-rel {
    width: 100%;
}

.gs-gem-rel__badge {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.05rem 0.45rem;
    border-radius: 999px;
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    background: var(--bs-primary);
    color: #fff;
}

.gs-gem-rel__sha code {
    font-size: 0.72rem;
    opacity: 0.75;
}

.gs-gem-rel__dl {
    text-align: right;
    white-space: nowrap;
}


/* ===================================================
   RESPONSIVE
   ===================================================
   Below md the rail becomes a select. Bootstrap's md breakpoint is
   768px; matching it keeps the switch aligned with the Docsy sidebar's
   own collapse rather than introducing a second, competing one. */

@media (max-width: 767.98px) {
    .gs-gem-archive {
        grid-template-columns: minmax(0, 1fr);
        gap: 1.25rem;
    }

    .gs-gem-archive__picker {
        display: block;
    }

    .gs-gem-archive__rail {
        display: none;
    }

    .gs-gem-card__actions {
        flex-direction: column;
    }

    .gs-gem-card__btn--alt {
        flex: 1 1 auto;
    }
}

@media (prefers-reduced-motion: reduce) {
    .gs-gem-card,
    .gs-eula {
        transition: none;
    }

    .gs-gem-card.is-ready:hover {
        transform: none;
    }
}
