/* ===== Per-app background image support ===== */

/* When an app card has a background image, layer content on top with a
       semi-transparent overlay so text remains readable in both light/dark themes.
       Backgrounds are desaturated to reduce visual noise. */
.app-card.app-card-has-background {
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    position: relative;
    overflow: hidden;
    color: #fff;
}

/* Desaturate the background image itself via a filtered pseudo-element layer.
       We move the actual image rendering into ::after so we can apply filter()
       to the image without affecting child text content. */
.app-card.app-card-has-background {
    background-image: none !important;
}

.app-card.app-card-has-background::after {
    content: "";
    position: absolute;
    inset: 0;
    background-image: var(--app-card-bg-image, none);
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    filter: saturate(0.25) brightness(0.85);
    z-index: 0;
    pointer-events: none;
    transition: filter 0.2s ease;
}

.app-card.app-card-has-background:hover::after {
    filter: saturate(0.4) brightness(0.95);
}

/* Dark gradient overlay for readability */
.app-card.app-card-has-background::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg,
            rgba(0, 0, 0, 0.35) 0%,
            rgba(0, 0, 0, 0.55) 60%,
            rgba(0, 0, 0, 0.75) 100%);
    z-index: 1;
    pointer-events: none;
    transition: background 0.2s ease;
}

.app-card.app-card-has-background:hover::before {
    background: linear-gradient(180deg,
            rgba(0, 0, 0, 0.25) 0%,
            rgba(0, 0, 0, 0.45) 60%,
            rgba(0, 0, 0, 0.70) 100%);
}

/* Ensure card content sits above the overlay */
.app-card.app-card-has-background .app-card-content,
.app-card.app-card-has-background .app-card-badge {
    position: relative;
    z-index: 2;
}

/* Force readable text colors on background cards regardless of theme */
.app-card.app-card-has-background h3,
.app-card.app-card-has-background p,
.app-card.app-card-has-background .app-card-readme-hint {
    color: #fff;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}

.app-card.app-card-has-background .app-card-tag {
    background: rgba(255, 255, 255, 0.18);
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.3);
    backdrop-filter: blur(2px);
}

/* New wrapper to keep flex/layout intact for cards without background too */
.app-card-content {
    display: flex;
    flex-direction: column;
    flex: 1;
    width: 100%;
}

/* Custom image icons (when hasIcon + iconUrl provided) */
.app-card-icon-img {
    width: 48px;
    height: 48px;
    object-fit: contain;
    display: block;
}

.app-readme-icon-img {
    width: 56px;
    height: 56px;
    object-fit: contain;
    display: block;
}

/* ===== Readme modal with background image =====
       Apply the background to the entire modal content (not just header),
       with heavy desaturation and a dark overlay for readability. */
.app-readme-modal-content.app-readme-modal-has-background {
    position: relative;
    color: #fff;
}

.app-readme-modal-content.app-readme-modal-has-background::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image: var(--app-readme-bg-image, none);
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    filter: saturate(0.2) brightness(0.7);
    z-index: 0;
    pointer-events: none;
}

.app-readme-modal-content.app-readme-modal-has-background::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(135deg,
            rgba(0, 0, 0, 0.65) 0%,
            rgba(0, 0, 0, 0.55) 100%);
    z-index: 1;
    pointer-events: none;
}

/* Ensure all modal content sits above the background layers */
.app-readme-modal-content.app-readme-modal-has-background>* {
    position: relative;
    z-index: 2;
}

/* The scroll body itself must also establish a stacking context so its
           children (readme, video, examples) render above the background layers */
.app-readme-modal-content.app-readme-modal-has-background .app-readme-scroll-body {
    position: relative;
    z-index: 2;
}

/* Ensure the readme body scrolls when content exceeds available space.
      This applies whether or not the modal has a background image. */
.app-readme-modal-content {
    display: flex;
    flex-direction: column;
    max-height: 90vh;
}

/* When there is a background, the ::before/::after layers are absolutely
        positioned to the modal-content. Since we removed overflow:hidden, ensure
        they remain clipped to the modal-content's rounded corners by clipping
        via border-radius inheritance and an explicit clip-path fallback. */
.app-readme-modal-content.app-readme-modal-has-background::before,
.app-readme-modal-content.app-readme-modal-has-background::after {
    border-radius: inherit;
}


/* Make text readable over the washed background */
.app-readme-modal-content.app-readme-modal-has-background h2,
.app-readme-modal-content.app-readme-modal-has-background h3,
.app-readme-modal-content.app-readme-modal-has-background h4,
.app-readme-modal-content.app-readme-modal-has-background p,
.app-readme-modal-content.app-readme-modal-has-background li,
.app-readme-modal-content.app-readme-modal-has-background span,
.app-readme-modal-content.app-readme-modal-has-background .app-readme-description {
    color: #fff;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}

.app-readme-modal-content.app-readme-modal-has-background .app-readme-section-title {
    color: #fff;
    border-bottom-color: rgba(255, 255, 255, 0.25);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}

.app-readme-modal-content.app-readme-modal-has-background .app-readme-example-link {
    background: rgba(255, 255, 255, 0.15);
    border-color: rgba(255, 255, 255, 0.3);
    color: #fff;
    backdrop-filter: blur(4px);
}

.app-readme-modal-content.app-readme-modal-has-background .app-readme-example-link:hover {
    background: rgba(255, 255, 255, 0.28);
    border-color: rgba(255, 255, 255, 0.5);
    color: #fff;
}

/* Style code blocks within the readme so they remain legible on the
       darkened background */
.app-readme-modal-content.app-readme-modal-has-background pre,
.app-readme-modal-content.app-readme-modal-has-background code {
    background: rgba(0, 0, 0, 0.45);
    color: #f5f5f5;
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 4px;
}

.app-readme-modal-content.app-readme-modal-has-background pre {
    padding: 10px;
    overflow-x: auto;
}

.app-readme-modal-content.app-readme-modal-has-background a {
    color: #9ecbff;
}

/* Close (×) button visibility on dark background */
.app-readme-modal-content.app-readme-modal-has-background .close {
    color: #fff;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}

/* Header no longer carries the background image; keep it transparent
       so the modal-wide background shows through */
.app-readme-header.app-readme-header-has-background {
    position: relative;
    background: transparent;
    padding: 24px 0;
    color: #fff;
}