/* ==========================================================================
   Per-product custom badge
   --------------------------------------------------------------------------
   Registered with NopHtml.AddCssFileParts (list END, highest priority) so it
   is emitted after badge-v2.css and badge-shop-tokens-v1.css. It must stay
   after them; AppendCssFileParts would insert it at index 0 and it would lose.

   Emission order:
     badge-v2.css                 <- _ProductBox Append (index 0)
     badge-shop-tokens-v1.css     <- view body Add
     product-badge-overlay-v1.css <- view body Add   (this file)
     mobile-shop-overrides.css    <- shop Head.cshtml Add (shop branches only)

   NO ?v= CACHE BUSTING. With bundling on, the bundler resolves a registration
   path as a physical path and silently drops the file. Filename versioning is
   the only invalidation mechanism: any edit after deploy means renaming this
   file to -v2 AND updating ALL FOUR registrations:
       _ProductBox.cshtml, _ProductDetailsPictures.cshtml,
       ProductTemplate.Simple.cshtml, ProductTemplate.Grouped.cshtml
   (The detail templates register it themselves rather than relying on the
   gallery partial, because THEY render the TitleRow badge.)

   --------------------------------------------------------------------------
   THE --cb-* TOKENS FOLLOW THREE DIFFERENT RULES. Getting these confused is
   the easiest way to break this file.

   1. --cb-bg / --cb-fg          INLINE style attribute only.
      Per product, written by the view. NEVER declare them in :root here - an
      inline declaration always wins, but a :root declaration would collide with
      a shop's mobile-shop-overrides.css and kill per-product colour. The var()
      fallbacks are literals for the same reason: a fallback does not fire if a
      later file declares the token globally.

   2. --cb-fs / --cb-py / --cb-px / --cb-dia / --cb-scale   ELEMENT CLASS only.
      The size ladder. Set by the context and shape classes below, never in
      :root. An element's own declaration always beats an inherited :root value,
      so a shop cannot hijack sizing.

      Resolution:  font-size = --cb-fs * --cb-scale
                   padding   = (--cb-py * --cb-scale) (--cb-px * --cb-scale)
                   circle    = --cb-dia * --cb-scale  (width and height)

      --cb-scale carries ONE thing: the size preset the admin chose. The
      context x breakpoint ladder is hand-tuned data, NOT a formula - the
      detail/catalog ratio is 1.182 desktop, 1.111 at 768 and 1.125 at 480, and
      inline moves from 0.909x to 1.0x. Do not try to express it as multipliers.

   3. --cb-brand-font            :root, and ONLY from a shop override.
      The sanctioned branding hook. A shop sets it in mobile-shop-overrides.css
      and it affects badges set to "theme default" only.
   --------------------------------------------------------------------------

   Shape, position, size, font, weight, case, style and border are all fixed
   modifier classes generated from C# enums/bools, so admin input never reaches
   a class name. Only the two colours are per-product values, and they arrive
   sanitised as inline custom properties.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Positioning contexts
   -------------------------------------------------------------------------- */

/* Catalog card: already relative via simplex.styles.css:1957. Restated so this
   file is self-contained if that rule ever moves. */
.item-box .product-item .picture {
    position: relative;
}

/* Product detail gallery: NOT relative anywhere today. cloud-zoom-simplex.css
   sets position:relative on .picture-wrapper (multi-picture branch only) and on
   .main-product-link, but never on .picture itself. Without this rule the badge
   would position against the nearest positioned ancestor instead of the box. */
.gallery > .picture {
    position: relative;
}

/* --------------------------------------------------------------------------
   Overlay layer
   -------------------------------------------------------------------------- */

.custom-badge-layer {
    position: absolute;
    inset: 0;
    /* never steal the card link, the swiper drag or the gallery drag-to-swipe */
    pointer-events: none;
    /* above the image (auto), below the catalog hover arrows (25,
       product-image-hover-arrows.css:35) and far below the wishlist/compare
       wrapper (999, simplex.styles.css:2108) */
    z-index: 20;
    /* The 3:4 containment in product-box-aspect-ratio.css is scoped to
       .product-grid .item-box .picture, so carousels, home-page recommended
       products and related-product strips get no containment from it. Clip here
       so the badge can never escape the picture box in those contexts either. */
    overflow: hidden;
}

/* --------------------------------------------------------------------------
   Badge
   -------------------------------------------------------------------------- */

.custom-badge {
    position: absolute;
    /* the tile is narrow; never let a long text push past the box */
    max-width: calc(100% - 16px);
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background-color: var(--cb-bg, #111111);
    color: var(--cb-fg, #ffffff);
    --cb-fs: 11px;
    --cb-py: 4px;
    --cb-px: 8px;
    font-size: calc(var(--cb-fs, 11px) * var(--cb-scale, 1));
    padding: calc(var(--cb-py, 4px) * var(--cb-scale, 1))
             calc(var(--cb-px, 8px) * var(--cb-scale, 1));
    line-height: 1.2;
    /* font-weight / text-transform / letter-spacing / font-style / border / font-family are NOT
       declared here - every one of those axes is carried by an always-emitted modifier class, so
       reading this file never requires holding "what did the base say?" in your head. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .18);
}

/* positions - picture box corners */
.custom-badge-pos-topleft {
    top: 8px;
    left: 8px;
}

.custom-badge-pos-topright {
    top: 8px;
    right: 8px;
}

.custom-badge-pos-bottomleft {
    bottom: 8px;
    left: 8px;
}

.custom-badge-pos-bottomright {
    bottom: 8px;
    right: 8px;
}

/* shapes */
.custom-badge-shape-rectangle {
    border-radius: 0;
}

.custom-badge-shape-rounded {
    border-radius: 4px;
}

.custom-badge-shape-pill {
    border-radius: 999px;
    --cb-px: 12px;
}

.custom-badge-shape-circle {
    border-radius: 50%;
    --cb-dia: 46px;
    --cb-fs: 10px;
    --cb-py: 0px;
    --cb-px: 0px;
    width: calc(var(--cb-dia, 46px) * var(--cb-scale, 1));
    height: calc(var(--cb-dia, 46px) * var(--cb-scale, 1));
}

.custom-badge-shape-ribbon {
    border-radius: 0 3px 3px 0;
    padding-left: 10px;
}

/* --------------------------------------------------------------------------
   Style axes. Every one is emitted on every badge, both sides, derived from a
   C# enum or bool - admin input never reaches a class name.
   -------------------------------------------------------------------------- */

/* font family. "Theme default" resolves through the shop branding hook first:
   a shop sets --cb-brand-font in its mobile-shop-overrides.css :root, and if it
   does not, --font-default (the shop theme's own UI font token, wigstheme.css)
   is used, falling back to plain inheritance on the trunk. Do NOT bind directly
   to --font-primary: its value differs per branch (serif on the trunk,
   sans-serif on the shop branches), so the same code would render differently. */
.custom-badge-font-themedefault {
    font-family: var(--cb-brand-font, var(--font-default, inherit));
}

.custom-badge-font-sans {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

.custom-badge-font-serif {
    font-family: Garamond, Baskerville, Caslon, Georgia, "Times New Roman", serif;
}

.custom-badge-font-monospace {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
}

/* size presets. A unitless multiplier applied on top of whatever the context x
   breakpoint ladder resolved to, so the ladder keeps working untouched and a
   future breakpoint needs no size-preset rows at all. */
.custom-badge-size-small {
    --cb-scale: .85;
}

.custom-badge-size-medium {
    --cb-scale: 1;
}

.custom-badge-size-large {
    --cb-scale: 1.2;
}

/* weight. 600 matches every other badge in the store (badge-v2.css); the badge
   was the only one at 700, which its own "reads as one family" comment shows was
   not intentional. */
.custom-badge-weight-bold {
    font-weight: 600;
}

.custom-badge-weight-normal {
    font-weight: 400;
}

/* letter case. The .3px tracking exists to open up all-caps text, so it goes
   away with the capitals - mixed case at badge size does not want it. */
.custom-badge-case-upper {
    text-transform: uppercase;
    letter-spacing: .3px;
}

.custom-badge-case-normal {
    text-transform: none;
    letter-spacing: normal;
}

.custom-badge-style-italic {
    font-style: italic;
}

.custom-badge-style-roman {
    font-style: normal;
}

/* border in the text colour, so it always coordinates and needs no extra column */
.custom-badge-border-on {
    border: 1px solid currentColor;
}

.custom-badge-border-off {
    border: 0;
}

/* --------------------------------------------------------------------------
   No background: shape "None" and/or a transparent background colour.
   -------------------------------------------------------------------------- */

.custom-badge-shape-none {
    border-radius: 0;
    background-color: transparent;
    --cb-py: 0px;
    --cb-px: 0px;
}

/* a border needs something to enclose, so restore just enough padding. Keeps the
   two axes genuinely orthogonal: "no chrome" and "outlined" can be combined. */
.custom-badge-shape-none.custom-badge-border-on {
    --cb-py: 2px;
    --cb-px: 4px;
}

/* a drop shadow on an invisible box reads as a rendering bug */
.custom-badge-shape-none,
.custom-badge-bg-transparent {
    box-shadow: none;
}

/* Text over a product photo still needs 4.5:1, and the photo is unknowable, so
   apply a legibility halo. Direction matters: a dark halo under dark text makes
   it LESS readable. The fg-light / fg-dark class comes from the text colour's
   WCAG relative luminance, computed server-side. */
.custom-badge-shape-none.custom-badge-fg-light,
.custom-badge-bg-transparent.custom-badge-fg-light {
    text-shadow: 0 1px 2px rgba(0, 0, 0, .60), 0 0 3px rgba(0, 0, 0, .40);
}

.custom-badge-shape-none.custom-badge-fg-dark,
.custom-badge-bg-transparent.custom-badge-fg-dark {
    text-shadow: 0 1px 2px rgba(255, 255, 255, .75), 0 0 3px rgba(255, 255, 255, .55);
}

/* larger on the product detail page */
.custom-badge-detail {
    --cb-fs: 13px;
    --cb-py: 5px;
    --cb-px: 10px;
}

.custom-badge-detail.custom-badge-shape-pill {
    --cb-py: 5px;
    --cb-px: 14px;
}

.custom-badge-detail.custom-badge-shape-circle {
    --cb-dia: 58px;
    --cb-fs: 12px;
    --cb-py: 0px;
    --cb-px: 0px;
}

/* --------------------------------------------------------------------------
   TitleRow - rendered OUTSIDE the picture box, inline in the product title row
   next to the existing NEW / BULK / Sold Out badges.

   Deliberately declares nothing about .product-name or .product-title-inline:
   the Grouped product template does not register badge-v2.css precisely to keep
   its <h1> layout, and any rule on those containers here would reintroduce the
   problem through the back door.
   -------------------------------------------------------------------------- */

.custom-badge-inline {
    position: static;
    max-width: none;
    vertical-align: middle;
    /* match .new-arrival-badge / .bulk-discount-badge exactly so the row reads
       as one family */
    --cb-fs: 10px;
    --cb-py: 3px;
    --cb-px: 8px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .1);
}

/* Large is ignored in the title row. `.product-name` is flex-wrap:nowrap above 480px
   (badge-v2.css:23) and `.custom-badge` sets overflow:hidden, which resolves the flex
   min-width:auto to 0 - so the LAST item in the row shrinks and ellipsises, and this badge is
   always emitted last. Recorded incident: 12 characters at a 164px column silently clipped the
   last badge. Small still applies inline; shrinking is always safe.
   Two-class selector, so it beats .custom-badge-size-large regardless of source order.
   NOTE this squeeze applies to the catalog card and the Simple detail template only -
   ProductTemplate.Grouped deliberately does not register badge-v2.css, so it has no
   flex-wrap:nowrap rule to begin with. */
.custom-badge-inline.custom-badge-size-large {
    --cb-scale: 1;
}

.custom-badge-inline.custom-badge-shape-pill {
    --cb-py: 3px;
    --cb-px: 12px;
}

.custom-badge-inline.custom-badge-shape-circle {
    --cb-dia: 34px;
    --cb-fs: 9px;
    --cb-py: 0px;
    --cb-px: 0px;
}

/* --------------------------------------------------------------------------
   Breakpoints. The steps mirror the .backorder-badge blocks at the tail of
   badge-v2.css so every badge family shrinks in lockstep.
   -------------------------------------------------------------------------- */

@media (max-width: 768px) {
    .custom-badge {
        --cb-fs: 10px;
        --cb-py: 3px;
        --cb-px: 6px;
    }

    .custom-badge-catalog {
        --cb-fs: 9px;
        --cb-py: 2px;
        --cb-px: 5px;
    }

    .custom-badge-detail {
        --cb-fs: 10px;
        --cb-py: 3px;
        --cb-px: 6px;
    }

    .custom-badge-inline {
        --cb-fs: 9px;
        --cb-py: 2px;
        --cb-px: 6px;
    }

    .custom-badge-shape-circle {
        --cb-dia: 38px;
    }

    .custom-badge-detail.custom-badge-shape-circle {
        --cb-dia: 42px;
    }

    .custom-badge-inline.custom-badge-shape-circle {
        --cb-dia: 30px;
    }

    .custom-badge-pos-topleft {
        top: 6px;
        left: 6px;
    }

    .custom-badge-pos-topright {
        top: 6px;
        right: 6px;
    }

    .custom-badge-pos-bottomleft {
        bottom: 6px;
        left: 6px;
    }

    .custom-badge-pos-bottomright {
        bottom: 6px;
        right: 6px;
    }
}

@media (max-width: 480px) {
    .custom-badge {
        --cb-fs: 9px;
        --cb-py: 2px;
        --cb-px: 5px;
    }

    .custom-badge-catalog {
        --cb-fs: 8px;
        --cb-py: 1px;
        --cb-px: 4px;
    }

    .custom-badge-detail {
        --cb-fs: 9px;
        --cb-py: 2px;
        --cb-px: 5px;
    }

    .custom-badge-inline {
        --cb-fs: 8px;
        --cb-py: 2px;
        --cb-px: 5px;
    }

    .custom-badge-shape-circle {
        --cb-dia: 32px;
    }

    .custom-badge-detail.custom-badge-shape-circle {
        --cb-dia: 36px;
    }

    .custom-badge-inline.custom-badge-shape-circle {
        --cb-dia: 26px;
    }
}
