/* =========================================
   Browse Page Specific Styles
   ========================================= */

.page-browse {
   padding-top: 80px !important;
   max-width: 1200px;
   margin: 0 auto;
}

/* Card grids size off this column, not the viewport: at 1201px it is 830px on
   /stars and 560px on /list, so no viewport threshold fits both. Named
   because the same grids also render outside it (homepage rails, admin
   showcase), where an anonymous container would match nothing. */
.page-browse .app-content {
   container: appcol / inline-size;
}

.browse-controls {
   margin-bottom: 20px;
}

/* ── Shop header — delivery content ────────────────────────────
   The card chrome is the shared <entity-header> (.entity-header* in
   components.css). Only the shop-specific Row 2 content (delivery couriers +
   leasing + free-delivery) lives here, dropped into the component's default slot. */
/* Layout: label is a fixed left column; logos wrap INSIDE .shop-delivery-options
   so overflow lines stay right of the label instead of sliding under it
   (alleop.bg at 375px). The free-delivery note is a row of its own above these,
   separated by the .entity-header-row hairline. */
.shop-delivery-row {
   flex-wrap: wrap;
   justify-content: flex-start;
   row-gap: 6px;
}
.shop-delivery-group {
   display: flex;
   align-items: flex-start;
   gap: 5px;
   /* Don't compress next to a sibling group — wrap to the next line instead
      (leasing drops below a long delivery row); a group WIDER than the row
      still wraps its own icons via .shop-delivery-options. */
   flex-shrink: 0;
   max-width: 100%;
}
.shop-delivery-options {
   display: flex;
   align-items: center;
   flex-wrap: wrap;
   gap: 5px;
   min-width: 0;
}
/* Mobile: LEASING always gets a line of its own rather than tailing a long
   carrier row. flex-basis:100% forces that break unconditionally — `order`
   alone only worked when the row was long enough to wrap anyway. */
@media (max-width: 600px) {
   .shop-leasing-group  { flex-basis: 100%; }
}
.shop-delivery-label {
   font-size: var(--fs-sm);
   color: var(--text-light);
   white-space: nowrap;
}
.shop-delivery-icon {
   width: 16px;
   height: 16px;
   border-radius: 3px;
   object-fit: contain;
}
/* Alone on its row, so nowrap has nothing to push into: the note starts at the
   card's left edge and the .tp-hint bubble opens rightward from there on its
   own default (left: 0), no flip needed. */
.shop-free-delivery { white-space: nowrap; }

/* Mobile adjustments */
@media (max-width: 1099px) {
   .page-browse {
      padding-top: 10px !important;
      max-width: 100%;
      display: block;
   }

   .desktop-col-left,
   .desktop-col-right {
      display: none !important;
   }
}

/* Desktop Grid Layout — 1100, the width core.css was written for: its 470px
   column is this grid's centre at exactly 1100 (250 + 336 + two 20px gaps =
   626). At 1201 the two disagreed and 1100–1200 rendered a pinned 470px strip
   with both rails hidden. */
@media (min-width: 1100px) {
   .page-browse {
      max-width: 1200px !important;
      /* User requested 1250px total width */
      margin: 0 auto;
      padding-top: 80px !important;
   }

   .desktop-grid-wrapper {
      display: grid !important;
      grid-template-columns: 250px 1fr 336px !important;
      gap: 20px;
      align-items: start;
      width: 100%;
   }

   /* When showing the shop grid (no shop selected), hide the left filter column
      and let the center column take the freed space.
      This class is toggled by Vue on browse.html only — mystuff.html is unaffected. */
   .desktop-grid-wrapper.grid-no-left {
      grid-template-columns: 1fr 336px !important;
   }
   .desktop-grid-wrapper.grid-no-left .desktop-col-left {
      display: none !important;
   }

   /* Keeps a left-column section header (list.html) pinned while its
      body scrolls. */
   .desktop-col-left .component-header {
      flex-shrink: 0;
      position: sticky;
      top: 0;
      background: var(--bg-light);
      z-index: 10;
   }

   /* Fix hot-products header scrolling on desktop */
   .desktop-col-right .hot-products-content {
      display: flex;
      flex-direction: column;
      height: 100%;
   }

   /* z-index 20 keeps the sticky, opaque section header above the cards'
      absolutely-positioned bookmark (.icon-favorite, z-index:10) so it
      never overlaps the "Hot Products" header on desktop. */
   .desktop-col-right .component-header {
      flex-shrink: 0;
      position: sticky;
      top: 0;
      background: var(--bg-light);
      z-index: 20;
   }

   .desktop-col-right .items-wrapper {
      flex: 1;
      overflow-y: auto;
      padding: 10px;
   }

   .desktop-col-left,
   .desktop-col-right {
      display: block !important;
      background: var(--bg-light);
      border-radius: 12px;
      overflow-y: auto;
      overflow-x: hidden; /* prevent horizontal scrollbar from long content */
   }

   /* The left rail grows with its filters — no cap, no inner scroll. */
   .desktop-col-right {
      max-height: 1000px;
   }

   /* Star Picks modal (saved.html) — the only place this widget renders. */
   #splide-celebrities {
      padding: 0 12px 12px 12px;
   }

   /* Reset app-content constraints if any */
   .app-content {
      width: auto !important;
      max-width: 100% !important;
      margin: 0 !important;
      padding: 0 !important;
   }
}

/* Air between the page heading and the shop search bar below it
   (shared by /browse and /stars — both load this file). */
.shop-grid-header { margin-bottom: 12px; }
/* Sits under the page <h1>. Same role and metrics as .mystuff-subtitle on
   /saved; both /browse and /stars load this file, so one rule serves both. */
.shop-grid-subtitle {
    margin: 4px 0 0;
    font-size: var(--fs-base);
    color: var(--text-light);
    line-height: 1.4;
}

/* Shop Grid Styles */
.shop-grid-container {
   display: grid;
   grid-template-columns: repeat(2, 1fr);
   gap: 12px;
   /* Top gap only — no horizontal padding, so card edges line up with the
      search field / .browse-filter-row controls above (which have none).
      Was `padding: 10px`, whose side padding indented the whole grid. */
   margin-top: 10px;
}

@media (min-width: 601px) {
   .shop-grid-container {
      grid-template-columns: repeat(3, 1fr);
   }
}

@media (min-width: 1201px) {
   .shop-grid-container {
      grid-template-columns: repeat(4, 1fr);
   }
}

/* Gated at 1100 because below it the column is the viewport and the rules above
   already fit; ungated, these moved the 2→3 step to a 580px viewport. Both
   branches present so the 4-across rule above can't reach into a narrow column
   (forced to 459px it drew four 104px cards). */
@media (min-width: 1100px) {
   @container appcol (max-width: 699px) {
      .shop-grid-container {
         grid-template-columns: repeat(3, 1fr);
      }
   }

   @container appcol (min-width: 700px) {
      .shop-grid-container {
         grid-template-columns: repeat(4, 1fr);
      }
   }
}

.shop-card {
   background: #fff;
   border: 1px solid var(--border-color);
   border-radius: 10px;
   /* Same resting elevation as .product-card (components.css). */
   box-shadow: var(--shadow-sm);
   /* 2026-05-20: shrunk from min-height 52px / padding 10/12 so more
      shop cards fit in one screen. Two-line text block (name 17px +
      product-count subtitle 10.5px) sets the floor — bump min-height
      to 44px so the larger name + subtitle don't get clipped. Still
      ~15% shorter than the original 52px. */
   padding: 6px 10px;
   display: flex;
   flex-direction: row;
   align-items: center;
   gap: 0;
   cursor: pointer;
   transition: all 0.2s ease;
   position: relative;
   min-height: 44px;
   /* Grid items default to min-width:auto (= content width), so one long
      unbreakable shop name ("Ballistic-sport.com") widened the whole 2-col
      grid past narrow phone viewports. Let the card shrink instead. */
   min-width: 0;
}

.shop-card:hover {
   transform: translateY(-2px);
   box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
   border-color: var(--pink-highlight);
}

/* Compact inner layout: favicon + name */
/* Grid, not flex, so the favicon can centre on the name + product-count rows
   ALONE. With flex + align-items:center it centred on the whole text column, so
   adding a third line (the rating) pushed it 7px down and rated cards no longer
   matched unrated ones. Rows are assigned explicitly rather than auto-placed:
   the product count is conditional, and without an explicit row a shop with no
   count would let the rating fall into row 2 and drag the favicon again. */
.shop-card-inner {
   display: grid;
   grid-template-columns: auto minmax(0, 1fr);
   column-gap: 8px;
   flex: 1;
   min-width: 0;
   line-height: 1.15;
}
.shop-favicon         { grid-column: 1; grid-row: 1 / span 2; align-self: center; }
.shop-name            { grid-column: 2; grid-row: 1; }
.shop-products-count  { grid-column: 2; grid-row: 2; }
.shop-card-rating     { grid-column: 2; grid-row: 3; }

.shop-favicon {
   width: 20px;
   height: 20px;
   border-radius: 4px;
   flex-shrink: 0;
   object-fit: contain;
}

.shop-name {
   font-size: var(--fs-lg);     /* +23% from 13px (originally tried 17, dialed back) */
   font-weight: 600;
   color: var(--text-color);
   text-align: left;
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
}

/* Rating line under the product count. The shared .shop-rating is sized for a
   page header, so everything is scaled down HERE rather than in the component —
   ShopRating is used on six other surfaces that still want the larger size.
   The stars are <app-icon size="15">, i.e. an svg with explicit width/height
   attributes, so font-size alone cannot shrink them; the svg box is set
   directly. The gold fill overlay is width:%-based, so it keeps tracking. */
.shop-card-rating {
   margin-top: 2px;
   gap: 4px;
   align-self: flex-start;
   /* Informational only on a card. <shop-rating> is a button elsewhere and stops
      click propagation, which meant tapping the stars opened the review popover
      INSTEAD of opening the shop — the one thing the whole card is for. Letting
      pointer events pass through hands every pixel of the card back to
      selectShop(), and the cursor stops lying about there being a second target.
      The popover stays fully available on the shop page itself. */
   pointer-events: none;
}
.shop-card-rating .shop-rating-avg {
   font-size: var(--fs-3xs);                 /* matches .shop-products-count above it */
   color: var(--text-light, #888);    /* ...and its colour, so the two lines read as one block */
   font-weight: 600;                  /* kept: it is the only thing separating the number from the label */
}
.shop-card-rating .star-row svg {
   width: 11px;
   height: 11px;
}
.shop-card-rating .star-row-base,
.shop-card-rating .star-row-fill {
   gap: 1px;
}
/* Stars + average only on the card. The "(N)" count and the "Rate it" prompt
   both carry this class; neither belongs in a dense 100-card grid. */
.shop-card-rating .shop-rating-count {
   display: none;
}

.shop-products-count {
   font-size: var(--fs-3xs);
   color: var(--text-light, #888);
   margin-top: 1px;
   white-space: nowrap;
   overflow: hidden;
   text-overflow: ellipsis;
}

/* Favourite bookmark — top-right of card */
.shop-favourite-btn {
   flex-shrink: 0;
   cursor: pointer;
   line-height: 1;
   padding: 2px;
   margin-left: 4px;
   /* No opacity dimming — it washed the unfollowed heart's pink out to a muted
      grey-pink. Keep the heart at the official --pink-highlight at full strength
      (outline = not followed, solid = followed). */
}

/* Legacy logo classes kept for safety but hidden */
.shop-logo-wrapper,
.shop-logo,
.shop-fallback-icon,
.shop-badge {
   display: none;
}

/* Shop Loader - Localized */
.shop-loader-container {
   padding: 40px;
   text-align: center;
   width: 100%;
   min-height: 300px;
   display: flex;
   flex-direction: column;
   align-items: center;
   justify-content: center;
   gap: 15px;
}

.shop-loader-container .loading-spinner {
   width: 48px;
   height: 48px;
   border: 4px solid var(--border-color);
   border-top-color: var(--pink-highlight);
   border-radius: 50%;
   animation: spin 0.8s linear infinite;
}

.shop-loader-container p {
   color: var(--text-light);
   font-size: var(--fs-md);
   margin: 0;
}

/* ── Compare banner ─────────────────────────────────────────────── */
.compare-banner {
   display: flex;
   align-items: center;
   gap: 8px;
   padding: 10px 16px;
   background: var(--bg-light);
   border: 1px solid var(--border-color);
   border-radius: 8px;
   margin-bottom: 16px;
   font-size: var(--fs-md);
   color: var(--text-color);
}
.compare-banner .btn-sm { padding: 4px 12px; font-size: var(--fs-base); margin-left: auto; }

/* Empty state moved to components.css as the shared .empty-state (2026-06). */

/* ── Browse product controls (search + filter row) ───────────────── */
.browse-filter-row {
   display: flex;
   gap: 8px;
   margin-top: 10px;
   flex-wrap: nowrap;
   align-items: center;
}

/* Layout overrides for browse filter dropdowns — visual base from .form-select */
.browse-filter-select {
   flex: 1;
   min-width: 140px;
   border-radius: 20px; /* pill shape for browse filters */
}

/* Sort dropdown — plain text + chevron, right-aligned */
.browse-sort-select {
   flex: 0 0 auto;
   margin-left: auto;
   border: none;
   background-color: transparent;
   background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236c757d' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
   background-repeat: no-repeat;
   background-position: right 2px center;
   padding: 4px 20px 4px 4px;
   color: var(--text-color);
   font-size: var(--fs-base);
   font-weight: 500;
   font-family: inherit;
   cursor: pointer;
   outline: none;
   appearance: none;
   -webkit-appearance: none;
}
.browse-sort-select:hover {
   color: var(--pink-highlight);
}

/* Shop search wrapper spacing */
.shop-search-wrapper {
   margin-bottom: 14px;
}

/* Shop controls row: checkbox left, sort select right */
.shop-controls-row {
   justify-content: space-between;
   align-items: center;
   flex-wrap: nowrap;
}

/* "Show My shops" checkbox label in shop sort row */
.shop-show-my-label {
   display: flex;
   align-items: center;
   gap: 6px;
   font-size: var(--fs-base);
   font-weight: 500;
   color: var(--text-color);
   cursor: pointer;
   white-space: nowrap;
}

/* ── Motion opt-out ──────────────────────────────────────────────────────
   Every animated rule in this file, behind the one query that asks. This
   sheet already carried the pattern for a handful of components; the rest
   were simply never enumerated. Listed selector by selector rather than as
   a `*` reset, because a universal reset only beats these rules with
   !important, which this project does not add.
   ──────────────────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    .shop-card {
        transition: none;
        animation: none;
    }

    /* Progress feedback, not decoration: a spinner that stops spinning
       stops saying "still working". Its transitions go; its spin stays. */
    .shop-loader-container .loading-spinner {
        transition: none;
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   Shop-category carousel + filter (/browse shops view)
   ══════════════════════════════════════════════════════════════════════════
   The catalogue's front door: one cell per shop category, so a visitor can
   enter by what they want to BUY instead of by a shop name they have to know
   already. Lives here rather than in components.css because the strip is
   /browse's alone — per the page-scoped rule, a class only this page uses
   belongs to this page's stylesheet.

   The cells borrow the platform card language wholesale (white, 1px hairline,
   12px radius, the same lift on hover as .celeb-card) rather than inventing a
   second card look; only the pale-pink icon disc is new, and it is built from
   the existing --pill-pink-bg / --pink-highlight tokens. */

/* The strip is a distinct step — choose a category, THEN read the grid — so it
   sits in its own tinted panel rather than running straight into the shops. The
   panel does the separating that a rule did before, and it disappears with the
   strip the moment a category is picked.
   Pale blue, and the cards inside stay white: the tint groups the step, the
   white cells stay the things you click. */
.cat-carousel {
    /* A generous gap above, not the 4px it started with: the controls row
       directly above (scope toggle, sort, Categories) belongs to the shop grid,
       and at 4px the tinted panel read as part of that toolbar rather than as
       its own step. */
    margin: 20px 0;
    padding: 18px 16px 10px;
    background: var(--blue-highlight-pale);
    border-radius: 14px;
}

.cat-carousel-head {
    display: flex;
    flex-direction: column;
    margin-bottom: 16px;
}

/* Same type treatment as .home-rail-title / -sub, so the strip reads as one of
   the platform's carousels rather than a control that happens to scroll. */
.cat-carousel-title {
    font-size: var(--fs-xl);
    font-weight: 600;
    letter-spacing: -0.01em;
    line-height: 1.2;
    color: var(--text-color);
    margin: 0;
}

.cat-carousel-sub {
    font-size: var(--fs-md);
    color: var(--text-light);
    margin: 4px 0 0;
}

/* Splide sizes the slide (perPage), so the cell simply fills it — every cell
   the same width. min-width:0 lets it follow a track narrower than its longest
   word instead of forcing the row wider. */
.cat-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    width: 100%;
    min-width: 0;
    height: 100%;
    padding: 14px 10px 12px;
    background: var(--surface);
    border: 1px solid var(--border-color);
    border-radius: 12px;
    cursor: pointer;
    text-align: center;
    /* The button reset: these are real <button>s so they are keyboard-operable
       and announce as controls, which a <div> with a click handler would not. */
    font: inherit;
    color: inherit;
    transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}

/* Hover is the one place colour returns: it is interaction feedback, not the
   resting look, and it ties the lifted card back to the panel it sits in. */
@media (hover: hover) {
    .cat-card:hover {
        transform: translateY(-2px);
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
        border-color: var(--blue-highlight);
    }
}

/* Stretch the slides so every card in view is the same HEIGHT as well as the
   same width — .cat-card is height:100% and needs a filled track row. */
.cat-carousel-splide .splide__list { align-items: stretch; }
.cat-carousel-splide .splide__slide { display: flex; }

/* The track padding that gives the hover lift somewhere to land, and the
   edge-fade arrows, both come from the shared carousel-rail block in
   components.css — the same chrome the homepage rails wear.

   Only the fade COLOUR is overridden here. That block fades to --surface
   (white), which is right on the homepage's white ground but reads as a white
   smear across a tinted panel. Same gradient, same geometry, panel colour. The
   transparent end is the panel colour at alpha 0, not `transparent`: CSS
   interpolates transparent as rgba(0,0,0,0), which greys the midpoint of the
   fade in some engines. */
.cat-carousel-splide .splide__arrow--prev {
    background: linear-gradient(90deg, var(--blue-highlight-pale) 32%, rgba(236, 235, 251, 0) 100%);
}
.cat-carousel-splide .splide__arrow--next {
    background: linear-gradient(270deg, var(--blue-highlight-pale) 32%, rgba(236, 235, 251, 0) 100%);
}

/* The disc echoes the panel behind the card — the SAME --blue-highlight-pale,
   so the tint reads as one idea rather than two, and the white cell sits as a
   window onto its container. Still monochrome: the glyph stays ink, so the
   strip never shouts louder than the shop grid it exists to filter. (Pink was
   wrong twice over — it is the platform's action colour, and 21 pink discs read
   as 21 calls to action.) */
.cat-card-icon {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--blue-highlight-pale);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

/* Two lines, always. Equal-width cells mean "Бижута и аксесоари" wraps while
   "Спорт" does not, and without a fixed box the cells in one row would end at
   different heights. Clamped rather than truncated mid-word: the second line is
   where most of these labels finish. */
.cat-card-name {
    font-size: var(--fs-base);
    font-weight: 700;
    line-height: 1.25;
    color: var(--text-color);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    min-height: calc(2 * 1.25em);
    width: 100%;
    /* break-word, NOT anywhere: `anywhere` breaks at whatever character runs
       out of room, which split "Хранителни стоки" as "Хранителн / и стоки".
       break-word keeps the break at a space and only splits a word that cannot
       fit on a line by itself — which, at this cell width, none of them do in
       any of the four languages. */
    overflow-wrap: break-word;
}

.cat-card-count {
    font-size: var(--fs-xs);
    color: var(--text-light);
    white-space: nowrap;
}

/* The shops view has no desktop left column (.grid-no-left), so unlike /search
   its Filters trigger cannot be .mobile-only — there would be no other way to
   reach the categories on a wide screen. This is the same .btn-neutral button
   <sort-filter-bar> renders, minus that class. */
.shop-filter-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* No styles for the categories sheet: it renders the SAME .filter-section /
   .filter-options / .filter-option facet rows the Brand filter on /search uses,
   with the category glyph in the .filter-avatar slot. The one addition lives in
   components.css next to its siblings: .filter-avatar-icon. */
