/**
 * Qoliber Free Gift — storefront styles.
 *
 * Part of the Qoliber Free Gift Suite for Magento 2 / Mage-OS.
 * Copyright (c) 2026 Fiero Group Sp. z o.o. (https://qoliber.com)
 * Proprietary. See LICENSE.md, or https://qoliber.com/license
 *
 * Written as a plain stylesheet loaded from layout, not as inline style attributes, so the
 * module needs no CSP exemption — the same reason its scripts are x-magento-init only.
 *
 * Every colour is a custom property. A merchant's theme overrides the four below and the whole
 * module follows, without touching this file or recompiling anything.
 */

:root {
    --qoliber-freegift-accent: #1c7a52;
    --qoliber-freegift-accent-contrast: #ffffff;
    --qoliber-freegift-surface: #f2f8f5;
    --qoliber-freegift-border: #cfe3d8;
    --qoliber-freegift-muted: #5c6b64;
}

/* ------------------------------------------------------------------ badge */

/*
 * Sits on a product page and on a category tile, at two different sizes, from one rule set.
 * `display: inline-flex` rather than block: on a tile it has to sit in the flow the theme
 * already established, not claim a line of its own.
 */
.qoliber-freegift-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0.5rem 0;
    padding: 0.35rem 0.7rem;
    border: 1px solid var(--qoliber-freegift-border);
    border-radius: 1rem;
    background: var(--qoliber-freegift-surface);
    color: var(--qoliber-freegift-accent);
    font-size: 1.2rem;
    font-weight: 600;
    line-height: 1.3;
}

/* The gift mark. A pseudo-element, so it is decoration and screen readers never announce it. */
.qoliber-freegift-badge::before {
    content: "\1F381";
    flex: none;
    font-size: 1.3rem;
    line-height: 1;
}

.qoliber-freegift-badge__label {
    font-weight: 700;
}

.qoliber-freegift-badge__campaigns {
    margin: 0;
    padding: 0;
    list-style: none;
}

.qoliber-freegift-badge__campaign {
    font-weight: 500;
}

/* Tiles are dense and their text is small; the badge follows rather than shouting. */
.product-item .qoliber-freegift-badge {
    margin: 0.4rem 0 0;
    padding: 0.2rem 0.5rem;
    font-size: 1.1rem;
}

/* -------------------------------------------------------------- cart block */

.qoliber-freegift-cart {
    /* Belt and braces for the float layout the cart page is built on. The layout keeps this
       block out of `.cart-container`, where two floated columns would render it underneath the
       items table; a theme that moves it back in gets a panel below the floats rather than
       behind them. */
    clear: both;

    /* Wide enough for a choice card grid, narrow enough that a single line of text does not
       stretch across the whole cart with its button marooned at the far edge. */
    max-width: 70rem;
    margin: 2rem 0;
    padding: 1.5rem;
    border: 1px solid var(--qoliber-freegift-border);
    border-radius: 0.4rem;
    background: var(--qoliber-freegift-surface);
}

.qoliber-freegift-cart__heading {
    margin: 0 0 1rem;
    font-size: 1.8rem;
    font-weight: 600;
    line-height: 1.2;
}

/*
 * Each list gets its own sub-heading. Without them the declined list reads as a continuation of
 * the earned one, and the panel appears to say a gift was both earned and removed.
 */
.qoliber-freegift-cart__subheading {
    margin: 1.5rem 0 0.75rem;
    color: var(--qoliber-freegift-muted);
    font-size: 1.3rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
}

.qoliber-freegift-cart__earned,
.qoliber-freegift-cart__choices,
.qoliber-freegift-cart__declined {
    margin: 0;
    padding: 0;
    list-style: none;
}

.qoliber-freegift-cart__gift,
.qoliber-freegift-cart__choice,
.qoliber-freegift-cart__declined-item {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1rem;
    padding: 0.75rem 0;
    border-bottom: 1px solid var(--qoliber-freegift-border);
}

.qoliber-freegift-cart__gift:last-child,
.qoliber-freegift-cart__choice:last-child,
.qoliber-freegift-cart__declined-item:last-child {
    border-bottom: 0;
}

/*
 * The name takes only the room it needs, and the action sits beside it.
 *
 * It used to be `flex: 1 1 12rem`, which reads fine in Luma's narrow summary column and badly
 * everywhere else: in the full-width cart the name stretched and threw "No thanks" hundreds of
 * pixels to the right, so the button looked unrelated to the gift it belonged to.
 */
.qoliber-freegift-cart__gift,
.qoliber-freegift-cart__declined-item {
    justify-content: flex-start;
}

.qoliber-freegift-cart__name {
    flex: 0 1 auto;
    font-weight: 600;
}

.qoliber-freegift-cart__gift .qoliber-freegift-cart__name::before {
    content: "\1F381";
    margin-right: 0.5rem;
}

/*
 * The campaign name on a declined row. This is what stops three turned-down campaigns from
 * rendering as the same sentence three times over.
 */
.qoliber-freegift-cart__campaign {
    flex: 0 1 auto;
    font-weight: 600;
}

/* Which campaign a gift came from — quiet, because the gift's own name leads. */
.qoliber-freegift-cart__from {
    flex: 1 1 auto;
    color: var(--qoliber-freegift-muted);
    font-size: 1.2rem;
}

.qoliber-freegift-cart__declined-message {
    flex: 1 1 100%;
    order: 3;
    color: var(--qoliber-freegift-muted);
    font-size: 1.2rem;
}

.qoliber-freegift-cart__unavailable {
    color: var(--qoliber-freegift-muted);
    font-size: 1.2rem;
    font-style: italic;
}

.qoliber-freegift-cart__choice--unavailable .qoliber-freegift-cart__name {
    color: var(--qoliber-freegift-muted);
    text-decoration: line-through;
}

.qoliber-freegift-cart form {
    margin: 0;
}

/*
 * "Choose this gift" is the primary action and keeps the theme's own button styling. The
 * secondary actions are quiet on purpose: declining a gift should never look more inviting than
 * keeping it.
 */
.qoliber-freegift-cart__decline,
.qoliber-freegift-cart__restore {
    padding: 0.4rem 0.9rem;
    border: 1px solid var(--qoliber-freegift-border);
    border-radius: 0.3rem;
    background: transparent;
    color: var(--qoliber-freegift-muted);
    font-size: 1.2rem;
    line-height: 1.4;
    cursor: pointer;
}

.qoliber-freegift-cart__decline:hover,
.qoliber-freegift-cart__restore:hover,
.qoliber-freegift-cart__decline:focus,
.qoliber-freegift-cart__restore:focus {
    border-color: var(--qoliber-freegift-accent);
    color: var(--qoliber-freegift-accent);
}

/*
 * Choice cards.
 *
 * One card per campaign, because two campaigns running at once used to pour their pools into a
 * single flat list where nothing said which gift belonged to which offer, or how many of each
 * the customer could have.
 */
.qoliber-freegift-cart__campaign-card {
    margin: 1.5rem 0 0;
    padding: 1.25rem;
    border: 1px solid var(--qoliber-freegift-border);
    border-radius: 0.4rem;
    background: #fff;
}

.qoliber-freegift-cart__campaign-card .qoliber-freegift-cart__subheading {
    margin-top: 0;
}

.qoliber-freegift-cart__chosen,
.qoliber-freegift-cart__campaign-card .qoliber-freegift-cart__choices {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
    gap: 0.75rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.qoliber-freegift-cart__chosen-item,
.qoliber-freegift-cart__campaign-card .qoliber-freegift-cart__choice {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    padding: 0.85rem;
    border: 1px solid var(--qoliber-freegift-border);
    border-radius: 0.4rem;
    background: var(--qoliber-freegift-surface);
    text-align: center;
}

/* A gift already taken reads as settled rather than as another thing to decide. */
.qoliber-freegift-cart__chosen-item {
    border-color: var(--qoliber-freegift-accent);
}

.qoliber-freegift-cart__thumb {
    width: 7rem;
    height: 7rem;
    object-fit: contain;
    mix-blend-mode: multiply;
}

.qoliber-freegift-cart__campaign-card .qoliber-freegift-cart__name {
    flex: none;
    font-size: 1.3rem;
    line-height: 1.35;
}

.qoliber-freegift-cart__change {
    padding: 0.35rem 0.8rem;
    border: 1px solid var(--qoliber-freegift-border);
    border-radius: 0.3rem;
    background: transparent;
    color: var(--qoliber-freegift-muted);
    font-size: 1.2rem;
    cursor: pointer;
}

.qoliber-freegift-cart__change:hover,
.qoliber-freegift-cart__change:focus {
    border-color: var(--qoliber-freegift-accent);
    color: var(--qoliber-freegift-accent);
}

.qoliber-freegift-cart__choice--unavailable {
    opacity: 0.6;
}

/* ------------------------------------------------------------ campaigns widget */

.qoliber-freegift-campaigns {
    margin: 1.5rem 0;
    padding: 1rem 1.25rem;
    border-left: 3px solid var(--qoliber-freegift-accent);
    background: var(--qoliber-freegift-surface);
}

.qoliber-freegift-campaigns__list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.qoliber-freegift-campaigns__item {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    padding: 0.25rem 0;
    font-size: 1.3rem;
    line-height: 1.4;
}

.qoliber-freegift-campaigns__item::before {
    content: "\1F381";
    flex: none;
    line-height: 1.4;
}

.qoliber-freegift-campaigns__heading {
    margin: 0 0 0.5rem;
    font-size: 1.4rem;
    font-weight: 600;
    line-height: 1.3;
}

/* ------------------------------------------------- campaigns widget, one line */

/*
 * The banner goes in headers and footers, where the theme owns the background and the width is
 * whatever is left over. It therefore paints no surface of its own and wraps rather than
 * scrolls: a strip that clips its own text in a header is worse than one that grows a line.
 */

.qoliber-freegift-banner {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: center;
    gap: 0.25rem 0.5rem;
    padding: 0.5rem 1rem;
    font-size: 1.3rem;
    line-height: 1.4;
}

.qoliber-freegift-banner__heading {
    font-weight: 600;
}

.qoliber-freegift-banner__separator {
    opacity: 0.5;
}

/* --------------------------------------------------------------------- popup */

/*
 * The element carrying `data-qoliber-freegift-popup` *is* the dialog — the markup has no wrapper
 * and no close button, and three specs assert against it, so it is not worth adding elements for
 * the sake of styling.
 *
 * **The backdrop is a spread shadow, not a pseudo-element.** A `::before` with `z-index: -1`
 * looks like the obvious way to dim the page behind a card, and it is wrong: inside the card's
 * own stacking context a negative-z-index child paints *above* the element's background and
 * below its text, so the dimming layer greyed out the very card it was meant to sit behind. A
 * shadow with a viewport-sized spread paints strictly outside the element and cannot.
 *
 * Hidden through the `hidden` attribute rather than a class, so the markup still means what it
 * says with no CSS and no JavaScript at all.
 */
[data-qoliber-freegift-popup] {
    position: fixed;
    /* Above Luma's own modals, which sit at 900: an add-to-cart can be on screen already. */
    z-index: 1001;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    box-sizing: border-box;
    max-width: 38rem;
    width: calc(100% - 3rem);
    max-height: 85vh;
    overflow-y: auto;
    padding: 3rem 2.5rem 2.5rem;
    border: 1px solid var(--qoliber-freegift-border);
    border-top: 4px solid var(--qoliber-freegift-accent);
    border-radius: 0.6rem;
    background: #fff;
    box-shadow:
        0 0 0 100vmax rgba(20, 24, 28, 0.55),
        0 1.6rem 4rem rgba(0, 0, 0, 0.3);
    text-align: center;
}

[data-qoliber-freegift-popup][hidden] {
    display: none;
}

.qoliber-freegift-popup__heading {
    margin: 0 0 0.6rem;
    color: var(--qoliber-freegift-accent);
    font-size: 2.2rem;
    font-weight: 700;
    line-height: 1.2;
}

/* Decoration, so it is a pseudo-element and no screen reader announces it. */
.qoliber-freegift-popup__heading::before {
    content: "\1F381";
    display: block;
    margin: 0 auto 1.2rem;
    width: 6.4rem;
    height: 6.4rem;
    border-radius: 50%;
    background: var(--qoliber-freegift-surface);
    font-size: 3.2rem;
    line-height: 6.4rem;
}

[data-qoliber-freegift-popup-body] {
    margin: 0;
    color: var(--qoliber-freegift-muted);
    font-size: 1.5rem;
    line-height: 1.5;
}

@media (max-width: 480px) {
    [data-qoliber-freegift-popup] {
        padding: 2rem 1.5rem 1.5rem;
    }

    .qoliber-freegift-popup__heading {
        font-size: 1.9rem;
    }
}

/* The announcer carries messages to screen readers and must never be seen or take up space. */
[data-qoliber-freegift-announcer] {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* Keyboard focus must stay visible: these are real buttons in real forms. */
.qoliber-freegift-cart button:focus-visible {
    outline: 2px solid var(--qoliber-freegift-accent);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    .qoliber-freegift-cart,
    [data-qoliber-freegift-popup] {
        transition: none;
    }
}
