/* Marketplace — an Amazon/Flipkart-style ecommerce theme: dark functional
   header, filled CTA buttons, dense product-grid-ready cards, sans-serif
   throughout. Same selector names as the original design handoff so
   templates don't need to change — only the tokens and component styling
   underneath do. System font stack: no external font request, no CDN
   dependency, matches how real marketplaces actually ship type. Primary
   accent is green rather than Amazon's orange, to keep the palette clear
   of trademark association. */

:root {
  --color-bg: #f1f3f6;
  --color-surface: #ffffff;
  --color-text: #212121;
  --color-accent: #16a34a;    /* primary CTA — green, not Amazon's orange */
  --color-accent-2: #2874f0;  /* links, secondary actions — Flipkart blue */
  --color-divider: #d5d9d9;

  --color-header-bg: #131a22;   /* Amazon-style dark navy header */
  --color-header-text: #ffffff;

  --color-success: #388e3c;
  --color-danger: #cc0c39;
  --color-star: #ffa41c;

  /* Neutral ramp 100→900: near-white to near-black. */
  --color-neutral-100: #f7f8f8;
  --color-neutral-200: #eaeded;
  --color-neutral-300: #d5d9d9;
  --color-neutral-400: #c7c7c7;
  --color-neutral-500: #999999;
  --color-neutral-600: #767676;
  --color-neutral-700: #565959;
  --color-neutral-800: #37474f;
  --color-neutral-900: #131a22;

  /* Accent ramp 100→900: the green CTA colour, light tint to dark shade. */
  --color-accent-100: #e6f6ec;
  --color-accent-200: #c3ead1;
  --color-accent-300: #8fd8ac;
  --color-accent-400: #57c17f;
  --color-accent-500: #2fae64;
  --color-accent-600: #16a34a;
  --color-accent-700: #0f7c39;
  --color-accent-800: #0a5c2a;
  --color-accent-900: #063b1b;

  /* Accent-2 ramp 100→900: the blue link/secondary colour. */
  --color-accent-2-100: #e8f0fe;
  --color-accent-2-200: #c2d9fc;
  --color-accent-2-300: #90b8fa;
  --color-accent-2-400: #5c97f7;
  --color-accent-2-500: #2874f0;
  --color-accent-2-600: #1f5fc4;
  --color-accent-2-700: #174a98;
  --color-accent-2-800: #0f356c;
  --color-accent-2-900: #082040;

  --font-heading: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-heading-weight: 700;
  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --space-1: 4.6px;
  --space-2: 9.2px;
  --space-3: 13.8px;
  --space-4: 18.4px;
  --space-6: 27.6px;
  --space-8: 36.8px;

  --radius-sm: 3px;
  --radius-md: 6px;
  --radius-lg: 10px;

  /* Elevation — visible card shadows, not a whisper. This is a UI meant
     to be scanned fast, and shadow is doing real separation work. */
  --shadow-sm: 0 1px 2px rgba(15, 17, 17, 0.16);
  --shadow-md: 0 2px 8px rgba(15, 17, 17, 0.14);
  --shadow-lg: 0 12px 28px rgba(15, 17, 17, 0.24);
}

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.45;
  font-weight: 400;
}

main {
  /* A consistent side gutter so page content never sits flush against
     the viewport edge - was entirely unstyled before, so every page's
     content butted straight up against the browser edge. */
  padding: var(--space-4) var(--space-2);
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  line-height: 1.2; letter-spacing: -0.01em; margin: 0 0 var(--space-2);
}
h1 { font-size: 28px; }
h2 { font-size: 22px; }
h3 { font-size: 18px; }
h4 { font-size: 16px; }
h5 { font-size: 14px; }
h6 { font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; }

p { margin: 0 0 var(--space-3); }
a { color: var(--color-accent-2); text-decoration: none; }
a:hover { text-decoration: underline; }
img { display: block; max-width: 100%; }
figure { margin: 0; }
figcaption { font-size: 11px; margin-top: var(--space-1); color: var(--color-neutral-600); }
.text-muted { color: var(--color-neutral-600); }
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--color-accent-2); outline-offset: 2px; }
::selection { background: color-mix(in srgb, var(--color-accent-2) 25%, transparent); }

.plate { box-sizing: border-box; border-radius: var(--radius-md); overflow: hidden; }

/* — rules — */
.hr { height: 1px; border: 0; margin: var(--space-4) 0; background: var(--color-divider); }

/* — buttons — */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  cursor: pointer; text-decoration: none;
  font-family: var(--font-heading); font-weight: 600;
  font-size: 13px; line-height: 1.2; color: var(--color-text);
  background: var(--color-neutral-100); border: 1px solid var(--color-divider);
  padding: var(--space-2) calc(var(--space-3) * 1.2);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}
.btn:hover { text-decoration: none; filter: brightness(0.97); }
.btn svg { display: block; }
.btn:disabled { opacity: 0.45; cursor: not-allowed; box-shadow: none; }

.btn-primary {
  color: #fff; background: var(--color-accent); border-color: var(--color-accent-700);
}
.btn-primary:hover { background: var(--color-accent-500); }
.btn-primary:active { background: var(--color-accent-700); }

.btn-secondary {
  color: #fff; background: var(--color-accent-2); border-color: var(--color-accent-2-700);
}
.btn-secondary:hover { background: var(--color-accent-2-400); }
.btn-secondary:active { background: var(--color-accent-2-700); }

.btn-ghost {
  color: var(--color-accent-2); background: transparent; border-color: transparent;
  box-shadow: none; padding-inline: var(--space-1);
}
.btn-ghost:hover { background: var(--color-accent-2-100); }
.btn-ghost:active { background: var(--color-accent-2-200); }

.btn-icon { width: 36px; height: 36px; padding: 0; }
.btn-block { width: 100%; margin-top: var(--space-2); }

/* — forms — */
.field { margin-bottom: var(--space-3); }
.field > label {
  display: block; font-size: 12px; font-weight: 600; margin-bottom: 5px;
  color: var(--color-neutral-700);
}
.input {
  width: 100%; min-height: 38px; padding: 7px 10px; font: inherit;
  font-size: 14px; color: var(--color-text); caret-color: var(--color-accent-2);
  background: var(--color-surface);
  border: 1px solid var(--color-neutral-400); border-radius: var(--radius-sm);
}
.input:hover { border-color: var(--color-neutral-600); }
.input:focus-visible {
  border-color: var(--color-accent-2); outline-offset: 0;
  box-shadow: 0 0 0 3px var(--color-accent-2-100);
}
textarea.input { min-height: 90px; resize: vertical; }

.radio { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 14px; }
.radio input, .seg-opt input {
  position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none;
}
.radio .dot {
  width: 16px; height: 16px; flex: none; border-radius: 50%;
  border: 1.5px solid var(--color-neutral-400); background: var(--color-surface);
}
.radio:hover .dot { border-color: var(--color-accent-2); }
.radio input:checked + .dot {
  border-color: var(--color-accent-2); background: var(--color-accent-2);
  box-shadow: inset 0 0 0 3px var(--color-surface);
}
.radio input:focus-visible + .dot { outline: 2px solid var(--color-accent-2); outline-offset: 2px; }

.seg {
  display: inline-flex; overflow: hidden;
  border: 1px solid var(--color-neutral-400); border-radius: var(--radius-md);
  background: var(--color-surface);
}
.seg-opt { display: inline-flex; align-items: center; gap: 6px; padding: 7px 12px; font-size: 13px; cursor: pointer; }
.seg-opt + .seg-opt { border-left: 1px solid var(--color-neutral-400); }
.seg-opt:has(input:checked) { color: #fff; background: var(--color-accent-2); }
.seg-opt:not(:has(input:checked)):hover { background: var(--color-neutral-100); }
.seg-opt:has(input:focus-visible) { outline: 2px solid var(--color-accent-2); outline-offset: -2px; }

/* — product detail: Amazon-style variant picker (not an SRS item, founder
   request) — one pill row per attribute dimension (Size, Colour, ...),
   swapped in for the plain SKU dropdown by variant_picker.js whenever
   catalogue.buyer_views._variant_picker_groups finds a clean, shared set
   of attribute names across every variant. */
.variant-pill {
  padding: 6px 14px; border: 1.5px solid var(--color-neutral-400); border-radius: var(--radius-md);
  background: var(--color-surface); color: var(--color-text); font-size: 13px; cursor: pointer;
}
.variant-pill:hover { border-color: var(--color-accent-2); }
.variant-pill-active { border-color: var(--color-accent-2); background: var(--color-accent-2-100); color: var(--color-accent-2-800); font-weight: 600; }
.variant-pill:focus-visible { outline: 2px solid var(--color-accent-2); outline-offset: 2px; }

/* — cards — */
.card {
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-3); border-radius: var(--radius-md);
  background: var(--color-surface); border: 1px solid var(--color-divider);
  box-shadow: var(--shadow-sm);
}
.card-kicker { font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--color-accent-2); font-weight: 700; }
.card-title { font-family: var(--font-heading); font-weight: 600; font-size: 15px; line-height: 1.3; }
.card-body { margin: 0; font-size: 13px; color: var(--color-neutral-700); flex: 1; }
.card-meta { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--color-neutral-600); }
.elev-sm { box-shadow: var(--shadow-sm); }
.elev-md { box-shadow: var(--shadow-md); }
.elev-lg { box-shadow: var(--shadow-lg); }

/* — tags — */
.tag {
  display: inline-flex; align-items: center; font-size: 11px; font-weight: 600;
  letter-spacing: 0.01em; padding: 3px 9px; border-radius: 999px;
}
.tag-accent { background: var(--color-accent-100); color: var(--color-accent-800); }
.tag-accent-2 { background: var(--color-accent-2-100); color: var(--color-accent-2-800); }
.tag-neutral { background: var(--color-neutral-200); color: var(--color-neutral-800); }
.tag-outline { border: 1px solid var(--color-accent-2); color: var(--color-accent-2); }
.tag-danger { background: var(--color-danger); color: #fff; }

/* — navigation — */
.nav {
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--color-header-bg); color: var(--color-header-text);
  box-shadow: var(--shadow-sm);
}
.nav-brand {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-heading); font-weight: 700;
  font-size: 18px; color: var(--color-header-text); margin-right: auto;
}
.nav a { color: var(--color-header-text); text-decoration: none; font-size: 14px; }
.nav a:hover, .nav a[aria-current='page'] { color: var(--color-accent); text-decoration: none; }
.nav .text-muted { color: var(--color-neutral-400); }
.nav-links { display: flex; align-items: center; gap: var(--space-3); }
/* Buttons inside the dark header keep readable contrast rather than the light-theme defaults. */
.nav .btn-ghost { color: var(--color-header-text); }
.nav .btn-ghost:hover { background: rgba(255, 255, 255, 0.1); }
.nav .btn-secondary { background: var(--color-accent-2); }

/* Mobile nav: pure-CSS checkbox toggle (no JS), same zero-JS-interactivity
   convention used everywhere else in this app. Below the breakpoint the
   link row collapses behind a hamburger button instead of wrapping into
   a disorganised jumble of buttons. */
.nav-toggle-checkbox { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.nav-toggle-btn {
  display: none;
  align-items: center; justify-content: center;
  cursor: pointer; font-size: 22px; line-height: 1;
  color: var(--color-header-text);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
}
.nav-toggle-btn:hover { background: rgba(255, 255, 255, 0.1); }

@media (max-width: 960px) {
  .nav { flex-wrap: wrap; }
  .nav-toggle-btn { display: inline-flex; }
  .nav-links {
    display: none;
    flex-direction: column; align-items: stretch;
    gap: var(--space-1);
    width: 100%;
    padding-top: var(--space-3);
  }
  .nav-toggle-checkbox:checked ~ .nav-links { display: flex; }
  .nav-links .btn { width: 100%; }
  .nav-links > a.text-muted { padding: var(--space-1) var(--space-1); }
}

/* — seller sub-nav — */
.subnav {
  display: flex; align-items: center; gap: var(--space-4);
  padding: 0 var(--space-4); margin-bottom: var(--space-4);
  background: var(--color-surface); border-bottom: 1px solid var(--color-divider);
  /* This bar can carry a dozen-plus tabs (Dashboard, Products, Orders,
     Returns, Inventory, Communities, Custom Domain, Discounts, Payouts,
     Sales Summary, Reviews, Marketing, Support, Shop Profile, All Shops)
     — wide enough to run off the right edge on anything narrower than
     ~1300px with no way to reach the later tabs at all. Scrolls
     horizontally instead of overflowing invisibly, same "swipeable tab
     strip" pattern real dashboards (GitHub, Gmail settings) use for the
     same problem, rather than hiding tabs behind a menu. */
  overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: thin;
}
.subnav a {
  display: inline-block; flex: none; padding: 12px 2px; font-size: 14px; font-weight: 600;
  color: var(--color-neutral-700); text-decoration: none; white-space: nowrap;
  border-bottom: 2px solid transparent;
}
.subnav a:hover { color: var(--color-text); text-decoration: none; }
.subnav a[aria-current='page'] { color: var(--color-accent-2); border-bottom-color: var(--color-accent-2); }

/* — stat tiles — */
.stat-grid { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-bottom: var(--space-4); }
.stat-tile {
  flex: 1 1 160px; background: var(--color-surface); border: 1px solid var(--color-divider);
  border-radius: var(--radius-md); box-shadow: var(--shadow-sm); padding: var(--space-3);
}
.stat-tile .num { font-size: 26px; font-weight: 700; line-height: 1; margin-bottom: 4px; }
.stat-tile .num.danger { color: var(--color-danger); }
.stat-tile .label { font-size: 12px; color: var(--color-neutral-600); }

/* — community landing: shop grid (Matrix item 26) — a real CSS Grid on
   desktop, not just however many 220px-basis flex items happen to fit, since
   .stat-grid's flex-wrap is shared by too many other pages to safely force
   into columns everywhere. Founder-reported: the original fixed
   repeat(4, 1fr) divided the *container* width into exactly 4 tracks
   regardless of how many tiles actually existed, so 1-2 shops on a wide
   screen each stretched to roughly a quarter of the page — the same
   unbounded-track bug already fixed for .product-grid, just a fixed
   column *count* instead of a fixed column *count with no width cap*.
   auto-fill + minmax bounds each tile to a real, roughly 60%-of-before
   size (was ~480px on a wide screen with few tiles; capped at 260px
   now) and naturally adds more columns instead of stretching existing
   ones when there's more than a screenful — no separate breakpoints
   needed, auto-fill collapses to fewer/one column on its own as the
   viewport narrows. */
.shop-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 260px)); gap: var(--space-3); margin-bottom: var(--space-4); }
/* Mobile: a single tile should fill the screen's width (auto-fill's own
   260px cap would otherwise leave dead space beside it on a narrow
   screen, since it isn't a stretchy 1fr track) — explicit override
   below the app's existing small-screen breakpoint. */
@media (max-width: 560px) { .shop-grid { grid-template-columns: 1fr; } }

/* — product grid (shop page, search results, community landing's
   Discover Products) — same real-CSS-Grid reasoning as .shop-grid just
   above, for the same underlying problem: these three listings used to
   share .stat-grid (flex-wrap + flex: 1 1 220px per card), which looks
   fine with a handful of stat tiles but visibly misbehaves with a real
   product count on a wide monitor — flex-grow stretches whichever few
   cards land in the last, most-empty row far past their natural size,
   so a page ends up with a handful of oddly oversized cards instead of
   Amazon/Flipkart's evenly-sized ones. A capped max-width plus a fixed
   column count per breakpoint (more columns as the screen grows, never
   a wider card) fixes both: every card in every row is the same size,
   and the grid stops adding width once it's already comfortably a
   multi-column layout instead of stretching forever on an ultrawide
   screen. */
.product-grid {
  display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--space-3);
  max-width: 1400px; margin: 0 0 var(--space-4);
}
@media (max-width: 1400px) { .product-grid { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 1100px) { .product-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 700px)  { .product-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 460px)  { .product-grid { grid-template-columns: 1fr; } }

/* — image-forward tile cards (product/shop grids) — every marketplace
   listing card needs a thumbnail up top, Amazon/Flipkart-style: a square
   frame that always reserves the same space whether or not a real photo
   exists yet, so a mixed grid of photographed and unphotographed listings
   still lines up cleanly instead of jumping between tall and short cards.
   .card is already `display:flex; flex-direction:column`, so this is just
   the first child in that stack. */
.tile-img-wrap {
  aspect-ratio: 1 / 1; width: 100%; display: flex; align-items: center; justify-content: center;
  background: var(--color-neutral-100); border-radius: var(--radius-sm); overflow: hidden;
  margin: calc(var(--space-3) * -1) calc(var(--space-3) * -1) 0;
  width: calc(100% + var(--space-3) * 2);
}
.tile-img-wrap img { width: 100%; height: 100%; object-fit: contain; }
.tile-img-wrap.tile-img-cover img { object-fit: cover; }
.tile-img-placeholder {
  display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;
  color: var(--color-neutral-400); font-size: 24px;
}
.tile-img-placeholder::after { content: "\1F4E6"; } /* package emoji — a neutral "nothing to show yet" glyph, not a broken-image icon */

/* — Amazon/Flipkart-style star rating — filled star glyphs at the
   platform's own star colour, sized to sit inline with a price line. */
.stars { color: var(--color-star); font-size: 12px; letter-spacing: 1px; }

/* — product detail image gallery — pure CSS, same zero-JS-interactivity
   convention as the mobile nav toggle above: each thumbnail is a <label>
   for a radio input that sits immediately before its own full-size image,
   so `:checked + img` alone swaps which one shows. No stacking/nth-child
   bookkeeping needed since every radio/image pair is self-contained. */
.gallery-main {
  position: relative; aspect-ratio: 1 / 1; border-radius: var(--radius-md);
  border: 1px solid var(--color-divider); overflow: hidden; background: var(--color-neutral-100);
  /* Founder-reported: on a wide desktop monitor the product photo's own
     flex column had no cap and grew to dominate half the screen — capped
     at the template level (product_detail.html's column is now
     flex: 0 1 480px, not 1 1 320px). This max-height is the mobile half
     of the same complaint: width already tracks the phone's screen width
     via that same column, and since aspect-ratio would otherwise force
     an equally tall square, this stops the photo from ever exceeding
     ~60% of the viewport's height on a short/landscape phone screen —
     object-fit: contain on the actual <img> (below) keeps it undistorted
     as both dimensions shrink together. */
  max-height: 60vh;
}
.gallery-radio { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.gallery-main-img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; opacity: 0;
  transition: opacity 0.15s ease;
}
.gallery-radio:checked + .gallery-main-img { opacity: 1; }
.gallery-thumbs { display: flex; gap: var(--space-2); margin-top: var(--space-2); flex-wrap: wrap; }
.gallery-thumb { display: block; cursor: pointer; }
.gallery-thumb img {
  width: 56px; height: 56px; object-fit: cover; border-radius: var(--radius-sm);
  border: 2px solid var(--color-divider);
}
.gallery-thumb:hover img { border-color: var(--color-accent-2); }

/* — tables — */
.table { width: 100%; border-collapse: collapse; font-size: 13px; background: var(--color-surface); }
.table th {
  text-align: left; font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--color-neutral-700); background: var(--color-neutral-100);
  padding: var(--space-2); border-bottom: 1px solid var(--color-divider);
}
.table td { padding: var(--space-2); border-bottom: 1px solid var(--color-divider); }
.table tbody tr:hover { background: var(--color-neutral-100); }

/* — dialog — */
.dialog-backdrop {
  position: fixed; inset: 0; display: grid; place-items: center;
  padding: var(--space-4); background: rgba(19, 26, 34, 0.6);
}
.dialog {
  width: min(440px, 100%); display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-4); border-radius: var(--radius-lg);
  background: var(--color-surface); box-shadow: var(--shadow-lg);
}
.dialog-title { font-family: var(--font-heading); font-weight: 700; font-size: 18px; }
.dialog-body { font-size: 14px; color: var(--color-neutral-700); }
.dialog-actions { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-2); }

/* — My Shops: rotating-photo tile (not an SRS item, founder request) —
   pure CSS crossfade slideshow, same zero-JS-interactivity convention as
   the product-detail gallery above: every gallery photo is stacked in
   the same square frame and takes turns fading in via animation-delay,
   so no single photo sits static forever. animation-duration/-delay are
   set inline per shop/photo (catalogue.views.shop_list computes the
   cycle length from how many photos that shop actually has) since a
   fixed CSS duration can't adapt to 1 photo vs 5. */
.shop-tile { text-decoration: none; color: inherit; display: flex; flex-direction: column; }
.shop-tile-photo {
  position: relative; aspect-ratio: 1 / 1; width: 100%; overflow: hidden;
  border-radius: var(--radius-sm); background: var(--color-neutral-100);
  /* Same fix as .gallery-main on the product detail page: width already
     tracks the tile's own (now-capped) column, this stops the square
     from exceeding ~60% of the viewport's height on a short/landscape
     mobile screen instead of growing as tall as it is wide. */
  max-height: 60vh;
}
.shop-tile-photo img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; animation-name: shop-tile-fade; animation-iteration-count: infinite; animation-timing-function: ease-in-out;
}
.shop-tile-photo img:only-of-type { opacity: 1; animation: none; }
@keyframes shop-tile-fade {
  0%   { opacity: 0; }
  6%   { opacity: 1; }
  28%  { opacity: 1; }
  34%  { opacity: 0; }
  100% { opacity: 0; }
}
/* Product/order counts overlaid on the tile photo itself, not competing
   with the shop name below it for space — a translucent dark bar at the
   bottom of the square, same "overlay on the image" idiom as a video
   player's own duration badge. */
.shop-tile-stats {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 1;
  display: flex; gap: var(--space-3);
  padding: 6px var(--space-2); background: linear-gradient(transparent, rgba(19, 26, 34, 0.78));
}
.shop-tile-stat { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; font-weight: 700; color: #fff; }
.shop-tile-stat svg { flex: none; }
.shop-tile-name {
  font-family: var(--font-heading); font-weight: 600; font-size: 15px; line-height: 1.3;
  margin: var(--space-2) 0 var(--space-1);
}
.shop-tile-actions { display: flex; gap: var(--space-2); margin-top: auto; }
.shop-tile-actions .btn { flex: 1; text-align: center; }

/* — footer strip: seller ads (approved, admin-moderated) + ComCom Live's
   own self-promotion — appears below every page's own content
   (base.html), same square-tile idiom as .tile-img-wrap. Each section
   renders only when it actually has something to show — no empty
   "no ads yet" placeholder box, per the founder's own instruction. */
.footer-strip { padding: var(--space-4); border-top: 1px solid var(--color-divider); margin-top: var(--space-6); }
.footer-strip-title { font-size: 13px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-neutral-600); margin: 0 0 var(--space-3); }
.footer-strip-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-3); }
@media (max-width: 960px) { .footer-strip-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .footer-strip-grid { grid-template-columns: 1fr; } }
.footer-tile { display: block; text-decoration: none; color: inherit; }
.footer-tile-photo { aspect-ratio: 1 / 1; width: 100%; border-radius: var(--radius-sm); overflow: hidden; background: var(--color-neutral-100); }
.footer-tile-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.footer-tile-caption { display: block; margin-top: var(--space-1); font-size: 12px; color: var(--color-neutral-700); }

/* — product card: shop icon + community-count badge (not an SRS item,
   founder request) — replaces naming one arbitrary community on a
   product card that can legitimately belong to several (the logged-in
   homepage feed spans every community a buyer can see). A small round
   shop avatar with a numeric badge answers "how many communities is
   this shop in" honestly without picking one to name; the shop's own
   name sits on its own line right below the product photo instead. */
.product-shop-line { display: flex; align-items: center; gap: 6px; margin-top: 2px; }
/* Sized up 20% from the original 20px/15px pass, per direct founder
   feedback from a screenshot. */
.shop-icon-badge { position: relative; width: 24px; height: 24px; flex: none; }
.shop-icon-avatar {
  width: 24px; height: 24px; border-radius: 50%; object-fit: cover; display: block;
  background: var(--color-neutral-200);
}
.shop-icon-placeholder { display: flex; align-items: center; justify-content: center; font-size: 13px; }
/* The founder's own shop-storefront line-art icon (static/img/shop_icon_placeholder.png),
   used in place of the emoji glyph above wherever a shop has no icon_image of its own yet. */
.shop-icon-placeholder-img { object-fit: contain; padding: 4px; box-sizing: border-box; background: var(--color-neutral-100); }
.shop-icon-count {
  position: absolute; top: -6px; right: -6px; min-width: 18px; height: 18px; padding: 0 3px;
  border-radius: 999px; background: var(--color-accent-2); color: #fff;
  font-size: 10px; font-weight: 700; border: 1.5px solid var(--color-surface);
  /* Flexbox centering, not line-height/text-align — line-height centering
     left the digit visibly off-center (a real font-metrics quirk, not a
     layout bug to just nudge with padding), flex centers the glyph box
     itself regardless of the font's own ascender/descender metrics. */
  display: flex; align-items: center; justify-content: center;
}
/* A Public shop (open to everyone regardless of membership) shows this
   label instead of the community-count circle above — the founder's own
   call: "public" is a more useful, at-a-glance fact about the shop than
   how many communities it happens to be in. Same corner-overlay position
   and border treatment as .shop-icon-count, just a rounded rectangle
   sized for a short word instead of a circle sized for a digit. */
.shop-badge-label {
  position: absolute; top: -6px; right: -8px; height: 14px; padding: 0 5px;
  border-radius: 4px; background: var(--color-accent-2); color: #fff;
  font-size: 8px; font-weight: 700; letter-spacing: 0.03em; white-space: nowrap;
  border: 1.5px solid var(--color-surface);
  display: flex; align-items: center; justify-content: center;
}
.shop-name-text { font-size: 12px; font-weight: 600; color: var(--color-neutral-700); }

/* — "Save to Wishlist" confirmation (not an SRS item, founder request):
   a messages.success() flash at the top of the page was too easy to
   miss — this sits right next to the button itself, on the very next
   render after the add-to-wishlist redirect. Same flexbox-centering
   fix already applied to .shop-icon-count, for the same reason (a
   glyph centered by line-height/text-align sits visibly off-centre). */
.wishlist-saved-check {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--color-success); color: #fff; font-size: 11px; font-weight: 700;
  flex: none;
}
