/* ============================================================
   Deal Dog — website styles
   Consumes the Deal Dog Design System (claude.ai/design
   project "Deal Dog Design System"): the --cr-* semantic
   token layer, Sora/Inter type, blue header + white sheet,
   Untitled-UI gray ramp, soft elevation, 180ms motion.
   ============================================================ */

:root {
  /* ---- Brand blue ---- */
  --cr-blue-25:  rgb(246,248,255);
  --cr-blue-50:  rgb(232,236,253);
  --cr-blue-100: rgb(213,221,251);
  --cr-blue-200: rgb(167,184,246);
  --cr-blue-300: rgb(125,151,242);
  --cr-blue-400: rgb(79,113,237);
  --cr-blue-500: rgb(36,80,233);   /* core brand */
  --cr-blue-600: rgb(20,58,195);
  --cr-blue-700: rgb(15,44,148);

  --cr-brand:          var(--cr-blue-500);
  --cr-brand-hover:    var(--cr-blue-600);
  --cr-brand-active:   var(--cr-blue-700);
  --cr-brand-subtle:   var(--cr-blue-50);
  --cr-on-brand:       #ffffff;

  /* ---- Reward orange (points, streaks, achievement) ---- */
  --cr-orange-50:  rgb(255,250,235);
  --cr-orange-100: rgb(254,240,199);
  --cr-orange-200: rgb(254,223,137);
  --cr-orange-300: rgb(254,200,75);
  --cr-orange-400: rgb(253,176,34);
  --cr-orange-500: rgb(247,144,9);
  --cr-orange-600: rgb(220,104,3);
  --cr-orange-700: rgb(181,71,8);

  /* ---- Status ---- */
  --cr-success-50:  rgb(236,253,243);
  --cr-success-100: rgb(220,250,230);
  --cr-success-500: rgb(23,178,106);
  --cr-success-600: rgb(7,148,85);
  --cr-success-700: rgb(6,118,71);

  --cr-error-50:  rgb(254,243,242);
  --cr-error-100: rgb(254,228,226);
  --cr-error-500: rgb(240,68,56);
  --cr-error-600: rgb(217,45,32);
  --cr-error-700: rgb(180,35,24);

  /* ---- Neutral gray ramp ---- */
  --cr-gray-25:  rgb(252,252,253);
  --cr-gray-50:  rgb(249,250,251);
  --cr-gray-100: rgb(242,244,247);
  --cr-gray-200: rgb(228,231,236);
  --cr-gray-300: rgb(208,213,221);
  --cr-gray-400: rgb(152,162,179);
  --cr-gray-500: rgb(102,112,133);
  --cr-gray-600: rgb(71,84,103);
  --cr-gray-700: rgb(52,64,84);
  --cr-gray-900: rgb(16,24,40);

  /* ---- Roles ---- */
  --cr-surface:           #ffffff;
  --cr-surface-secondary: var(--cr-gray-50);
  --cr-text-primary:      var(--cr-gray-900);
  --cr-text-secondary:    var(--cr-gray-700);
  --cr-text-tertiary:     var(--cr-gray-600);
  --cr-text-placeholder:  var(--cr-gray-500);
  --cr-text-brand:        var(--cr-blue-600);
  --cr-border:            var(--cr-gray-300);
  --cr-border-secondary:  var(--cr-gray-200);

  /* ---- Radii ---- */
  --cr-radius-sm:   6px;
  --cr-radius-md:   8px;
  --cr-radius-lg:   10px;
  --cr-radius-xl:   12px;
  --cr-radius-2xl:  16px;
  --cr-radius-3xl:  20px;
  --cr-radius-full: 9999px;

  /* ---- Elevation ---- */
  --cr-shadow-xs: 0 1px 2px rgba(16,24,40,0.05);
  --cr-shadow-sm: 0 1px 3px rgba(16,24,40,0.10), 0 1px 2px rgba(16,24,40,0.06);
  --cr-shadow-md: 0 4px 8px -2px rgba(16,24,40,0.10), 0 2px 4px -2px rgba(16,24,40,0.06);
  --cr-shadow-lg: 0 12px 16px -4px rgba(16,24,40,0.08), 0 4px 6px -2px rgba(16,24,40,0.03);
  --cr-shadow-xl: 0 20px 24px -4px rgba(16,24,40,0.08), 0 8px 8px -4px rgba(16,24,40,0.03);

  /* ---- Motion / focus ---- */
  --cr-ease: cubic-bezier(0.4, 0, 0.2, 1);
  --cr-dur: 180ms;
  --cr-focus-ring: 0 0 0 4px rgba(36,80,233,0.16);

  /* ---- Type (Inter across the whole site) ---- */
  --cr-font-display: "Inter", ui-sans-serif, system-ui, sans-serif;
  --cr-font-body:    "Inter", ui-sans-serif, system-ui, sans-serif;
}

* { box-sizing: border-box; }
html, body {
  margin: 0;
  padding: 0;
  background: var(--cr-surface);
  color: var(--cr-text-primary);
  font-family: var(--cr-font-body);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; }
svg { width: 100%; height: 100%; display: block; }
.icon { width: 18px; height: 18px; color: var(--cr-text-placeholder); }

:is(button, a, [role="button"], input):focus-visible {
  outline: none;
  box-shadow: var(--cr-focus-ring);
  border-color: var(--cr-brand);
}

/* ============================================================
   Header — white band; brand-blue app banner sits above it
   ============================================================ */
.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--cr-surface);
  border-bottom: 1px solid var(--cr-border-secondary);
  padding-bottom: 16px;
}

.header-row {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 24px;
}
.brand-row { padding-top: 16px; justify-content: space-between; }
.header-actions { display: flex; align-items: center; gap: 10px; }

/* ---- Header account control (Sign in / signed-in chip) ---- */
.account-slot { display: flex; align-items: center; gap: 10px; }
.account-signin {
  /* inline-flex + centering is load-bearing: a <button> centres its own label,
     but this is also rendered as an <a> in the page header, and an inline
     anchor with a fixed height leaves the text sitting at the top of the pill
     instead of on its centreline. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  padding: 0 20px;
  border: none;
  border-radius: var(--cr-radius-full);
  background: var(--cr-brand);
  color: var(--cr-on-brand);
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--cr-dur) var(--cr-ease);
}
.account-signin:hover { background: var(--cr-brand-hover); }

/* Header "Log in", the secondary half of the Log in / Sign up pair.
   A modifier rather than a change to .account-signin, because that class is the
   solid-blue primary CTA on six other pages ("Browse deals" on /account,
   /favorites, /about, /privacy, /terms, /careers) — repainting it white there
   would leave those pages with no primary button at all. */
.account-signin.account-login {
  background: #fff;
  color: var(--cr-brand);
  box-shadow: inset 0 0 0 1.5px var(--cr-brand);
  transition: background var(--cr-dur) var(--cr-ease), color var(--cr-dur) var(--cr-ease);
}
.account-signin.account-login:hover {
  background: var(--cr-brand-subtle);
  color: var(--cr-brand-hover);
}
.account-signin.account-login:active { transform: translateY(1px); }

.account-chip {
  height: 40px;
  padding: 0 14px 0 5px;
  display: flex;
  align-items: center;
  gap: 9px;
  border: 1px solid var(--cr-border-secondary);
  border-radius: var(--cr-radius-full);
  background: var(--cr-surface);
  color: var(--cr-text-primary);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.account-chip:hover { background: var(--cr-gray-100); }
.account-avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--cr-brand);
  color: var(--cr-on-brand);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 700;
}

.search-row { padding-top: 12px; padding-bottom: 2px; }

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  white-space: nowrap;
}
.brand-icon {
  width: 36px;
  height: 36px;
  border-radius: var(--cr-radius-lg);
  display: block;
  box-shadow: 0 0 0 1px var(--cr-border-secondary);
}
.wordmark {
  font-family: var(--cr-font-display);
  font-weight: 800;
  font-size: 25px;
  letter-spacing: -0.02em;
  color: var(--cr-brand);
  white-space: nowrap;
}

.search-wrap { flex: 1; }

.search-box {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  background: var(--cr-gray-100);
  border: 1px solid var(--cr-border-secondary);
  border-radius: var(--cr-radius-lg);
  transition: box-shadow var(--cr-dur) var(--cr-ease), border-color var(--cr-dur) var(--cr-ease), background var(--cr-dur) var(--cr-ease);
}
.search-box:focus-within {
  background: var(--cr-surface);
  border-color: var(--cr-brand);
  box-shadow: var(--cr-focus-ring);
}

.search-box input {
  border: none;
  background: transparent;
  outline: none;
  flex: 1;
  font-family: var(--cr-font-body);
  font-size: 14px;
  color: var(--cr-text-primary);
}
.search-box input::placeholder { color: var(--cr-text-placeholder); }

.search-clear {
  border: none;
  background: none;
  padding: 0;
  width: 16px;
  height: 16px;
  color: var(--cr-gray-400);
}

.icon-btn {
  width: 40px;
  height: 40px;
  min-width: 40px;
  border-radius: var(--cr-radius-full);
  border: none;
  background: var(--cr-gray-100);
  color: var(--cr-text-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background var(--cr-dur) var(--cr-ease);
}
.icon-btn svg { width: 18px; height: 18px; }
.icon-btn:hover { background: var(--cr-gray-200); }
.icon-btn.spinning svg { animation: spin 0.7s linear; }
@keyframes spin { to { transform: rotate(360deg); } }

/* Adding a third control to the brand row overflows a phone viewport: at 25px
   the wordmark alone is 175px of a 375px screen, and .brand is nowrap so the
   row can't absorb it. Scale the brand down rather than dropping either the
   wordmark or the sign-in entry point — both are worth keeping visible.
   MUST come after the .wordmark/.brand-icon base rules above: same specificity,
   so source order decides, and this block originally sat before them and lost. */
@media (max-width: 520px) {
  .wordmark { font-size: 20px; }
  .brand-icon { width: 32px; height: 32px; }
  .header-actions { gap: 8px; }
  .account-slot { gap: 8px; }
  .account-signin,
  .account-signup { padding: 0 14px; font-size: 13.5px; }
  .account-name { display: none; }
  .account-chip { padding: 0 5px; }
}

/* Row 3 — primary section nav (Discover / Top Deals / Promo Codes / Name
   Brands / Deal News), mirrors the app's bottom tabs and DealSeek's top nav */
.section-nav {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  gap: 4px;
  padding: 10px 24px 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.section-nav::-webkit-scrollbar { display: none; }

.section-link {
  flex: none;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 10px 16px;
  border: none;
  background: none;
  border-radius: var(--cr-radius-full);
  color: var(--cr-text-secondary);
  font-weight: 600;
  font-size: 13.5px;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--cr-dur) var(--cr-ease), color var(--cr-dur) var(--cr-ease),
              box-shadow var(--cr-dur) var(--cr-ease);
}
.section-link svg { width: 18px; height: 18px; flex: none; }
.section-link:hover { background: var(--cr-gray-100); color: var(--cr-text-primary); }
/* Selected tab: solid brand-blue pill with white text (DealSeek-style) */
.section-link.active {
  background: var(--cr-brand);
  color: #fff;
  box-shadow: 0 2px 8px rgba(36, 80, 233, 0.28);
}
.section-link.active:hover { background: var(--cr-brand-hover); color: #fff; }

.chip-row[hidden] { display: none; }
.chip-row {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  gap: 8px;
  padding: 10px 24px 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.chip-row.pulse .chip { animation: chipPulse 0.6s var(--cr-ease); }
@keyframes chipPulse {
  0%, 100% { box-shadow: none; }
  50% { box-shadow: var(--cr-focus-ring); }
}
.chip-row::-webkit-scrollbar { display: none; }

.chip {
  flex: none;
  min-height: 36px;
  padding: 8px 16px;
  border-radius: var(--cr-radius-full);
  border: 1px solid transparent;
  background: var(--cr-gray-100);
  color: var(--cr-text-secondary);
  font-weight: 600;
  font-size: 13px;
  white-space: nowrap;
  transition: background var(--cr-dur) var(--cr-ease), color var(--cr-dur) var(--cr-ease);
}
.chip:hover { background: var(--cr-gray-200); }
.chip.active {
  background: var(--cr-brand);
  color: var(--cr-on-brand);
}

/* ============================================================
   Page sheet — rounded gray sheet below the white header
   ============================================================ */
.page {
  max-width: 1200px;
  margin: -16px auto 0;
  padding: 24px 24px 80px;
  background: var(--cr-surface);
  border-radius: var(--cr-radius-3xl) var(--cr-radius-3xl) 0 0;
  position: relative;
}
@media (min-width: 1248px) {
  .page { border-radius: var(--cr-radius-3xl); }
}

/* ---------- States ---------- */
.state-banner[hidden] { display: none; }
.state-banner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  text-align: center;
  padding: 80px 20px;
  color: var(--cr-text-tertiary);
}
.state-banner .state-title {
  font-family: var(--cr-font-display);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: -0.01em;
  color: var(--cr-text-primary);
}
.state-banner .retry-btn {
  margin-top: 6px;
  height: 44px;
  padding: 0 22px;
  border-radius: var(--cr-radius-md);
  border: none;
  background: var(--cr-brand);
  color: var(--cr-on-brand);
  font-weight: 600;
  font-size: 14px;
  box-shadow: var(--cr-shadow-xs);
  transition: background var(--cr-dur) var(--cr-ease);
}
.state-banner .retry-btn:hover { background: var(--cr-brand-hover); }

/* ============================================================
   Grid cards
   ============================================================ */
.deal-grid[hidden] { display: none; }
.deal-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  grid-auto-rows: 1fr;
  gap: 20px;
}


/* SCROLL JANK, not layout shift. CLS measured 0 and card order is stable, so
   nothing is moving — the stutter is the main thread laying out and painting
   every offscreen card in a grid that grows to hundreds of items.

   content-visibility:auto lets the browser skip rendering work for cards
   outside the viewport. contain-intrinsic-size supplies the size it should
   assume while skipped: 566x510 measured live at the 4-column desktop layout.
   Getting that number wrong is worse than not setting it — the scrollbar jumps
   as real heights replace guesses — so it is measured, not estimated.

   Paired with decoding="async" on the card images, which previously decoded
   synchronously on the main thread mid-scroll. */
.deal-card {
  content-visibility: auto;
  contain-intrinsic-size: 566px 510px;
}
.deal-card {
  background: var(--cr-surface);
  border: 1px solid var(--cr-border-secondary);
  border-radius: var(--cr-radius-2xl);
  overflow: hidden;
  cursor: pointer;
  /* Column flex so .card-body can absorb the leftover height of an equal-height
     grid row and keep the price pinned to the bottom of every card. */
  display: flex;
  flex-direction: column;
  transition: transform var(--cr-dur) var(--cr-ease), border-color var(--cr-dur) var(--cr-ease);
  opacity: 0;
  transform: translateY(8px);
  animation: fadeUp 0.4s var(--cr-ease) forwards;
}
.deal-card:hover {
  transform: translateY(-1px);
  border-color: var(--cr-border);
}
@keyframes fadeUp {
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .deal-card { animation: none; opacity: 1; transform: none; }
  .deal-card:hover { transform: none; }
}

.deal-card.featured { grid-column: span 2; }
@media (max-width: 640px) {
  .deal-card.featured { grid-column: span 1; }
}

.card-media {
  position: relative;
  aspect-ratio: 1 / 1;
  background: #fff;
  overflow: hidden;
  flex: none;
}
.deal-card.featured .card-media { aspect-ratio: 16 / 9; }
.card-media img {
  width: 100%;
  height: 100%;
  /* Amazon product photos are centered on white — `contain` shows the whole
     product instead of cropping to a random slice. */
  object-fit: contain;
  padding: 12px;
  display: block;
}

/* Red is reserved for the discount badge only */
.badge-discount {
  position: absolute;
  top: 10px;
  left: 10px;
  background: var(--cr-error-500);
  color: #fff;
  font-family: var(--cr-font-display);
  font-weight: 700;
  font-size: 12px;
  padding: 4px 9px;
  border-radius: var(--cr-radius-full);
}

.badge-tag {
  position: absolute;
  top: 10px;
  right: 10px;
  font-size: 11px;
  font-weight: 600;
  padding: 3px 9px;
  border-radius: var(--cr-radius-full);
  border: 1px solid transparent;
}
.badge-tag.LIGHTNING {
  background: var(--cr-orange-100);
  color: var(--cr-orange-700);
  border-color: var(--cr-orange-200);
}
.badge-tag.COUPON {
  background: var(--cr-brand-subtle);
  color: var(--cr-brand);
  border-color: var(--cr-blue-200);
}

.card-body {
  padding: 12px 14px 14px;
  /* Absorbs the leftover height of an equal-height grid row so the price row
     lands on the same baseline on every card, however many optional rows
     (brand, rating, pills) the card above it happens to render. */
  flex: 1;
  display: flex;
  flex-direction: column;
}
.card-price-row,
.card-stale-price { margin-top: auto; }

.card-brand {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--cr-text-placeholder);
  margin: 0 0 4px;
}

.card-title {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--cr-text-primary);
  margin: 0 0 8px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.6em;
  line-height: 1.3;
}

.card-price-row {
  display: flex;
  align-items: baseline;
  gap: 7px;
  margin-bottom: 6px;
}
.card-price {
  font-family: var(--cr-font-display);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: var(--cr-text-primary);
}
.card-list-price {
  font-size: 12.5px;
  color: var(--cr-gray-400);
  text-decoration: line-through;
}
.card-stale-price {
  font-size: 12.5px;
  color: var(--cr-text-tertiary);
  font-style: italic;
}

.card-promo-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  border-radius: var(--cr-radius-full);
  background: var(--cr-success-50);
  color: var(--cr-success-700);
  border: 1px solid var(--cr-success-100);
  font-size: 11.5px;
  font-weight: 600;
  margin-bottom: 6px;
}
.card-promo-pill svg { width: 12px; height: 12px; }

.card-verified {
  font-size: 11px;
  color: var(--cr-text-placeholder);
  display: flex;
  align-items: center;
  gap: 4px;
}
.card-verified svg { width: 11px; height: 11px; color: var(--cr-success-500); flex: none; }

/* ---------- Skeleton ---------- */
.skeleton { cursor: default; animation: none; opacity: 1; transform: none; }
.skel-img {
  aspect-ratio: 1/1;
  background: linear-gradient(90deg, var(--cr-gray-100) 25%, var(--cr-gray-50) 37%, var(--cr-gray-100) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.4s ease infinite;
}
.skel-line {
  height: 12px;
  margin: 12px 14px 0;
  border-radius: var(--cr-radius-sm);
  background: linear-gradient(90deg, var(--cr-gray-100) 25%, var(--cr-gray-50) 37%, var(--cr-gray-100) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.4s ease infinite;
}
.skel-line.w-60 { width: 40%; }
.skel-line.w-90 { width: 80%; }
.skel-line.w-40 { width: 30%; margin-bottom: 14px; }
@keyframes shimmer { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }

/* ============================================================
   Modal — bottom sheet on mobile, dialog on desktop
   ============================================================ */
.modal-overlay[hidden] { display: none; }
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(16, 24, 40, 0.45);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  z-index: 100;
  animation: overlayIn var(--cr-dur) var(--cr-ease);
}
@keyframes overlayIn { from { opacity: 0; } to { opacity: 1; } }
@media (min-width: 720px) {
  .modal-overlay { align-items: center; padding: 24px; }
}

.modal {
  background: var(--cr-surface);
  width: 100%;
  max-width: 480px;
  max-height: 92vh;
  overflow-y: auto;
  border-radius: var(--cr-radius-3xl) var(--cr-radius-3xl) 0 0;
  box-shadow: var(--cr-shadow-xl);
  position: relative;
}
@media (min-width: 720px) {
  .modal { border-radius: var(--cr-radius-3xl); }
}

.modal-close {
  position: absolute;
  top: 16px;
  left: 16px;
  z-index: 2;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.92);
  color: var(--cr-text-primary);
  box-shadow: var(--cr-shadow-xs);
  display: flex;
  align-items: center;
  justify-content: center;
}
.modal-close svg { width: 14px; height: 14px; }

.modal-hero {
  position: relative;
  width: 100%;
  height: 240px;
  background: #fff;
}
/* Swipeable gallery: native horizontal scroll-snap (touch + trackpad), one
   image per slide. Same swipe-through set as Amazon. */
.modal-gallery {
  display: flex;
  width: 100%;
  height: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.modal-gallery::-webkit-scrollbar { display: none; }
.modal-gallery img {
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 16px;
  display: block;
  scroll-snap-align: center;
}
.modal-dots {
  position: absolute;
  bottom: 8px;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  gap: 6px;
  pointer-events: auto;
}
.modal-dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: rgba(15, 23, 42, 0.22);
  border: none;
  padding: 0;
  cursor: pointer;
  transition: background 0.15s, transform 0.15s;
}
.modal-dot.active {
  background: var(--cr-blue, #2f56ff);
  transform: scale(1.25);
}
/* In-flow, NOT absolute. This used to be `position:absolute; bottom:14px` to
   pin the tag over the old hero image, but the modal redesign moved #modalTags
   into .modal-body — which is static, so `bottom` resolved against the whole
   .modal and dropped the tag onto the Similar Items row, where "Free Trial"
   painted on top of a similar card's price. Keeping it in flow is what makes
   its position depend on where it actually lives in the markup. */
.modal-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 10px;
}
.modal-tags:empty { display: none; } /* no stray gap for PRICE_DROP deals */
.tag-pill {
  padding: 4px 11px;
  border-radius: var(--cr-radius-full);
  font-size: 11.5px;
  font-weight: 600;
  border: 1px solid transparent;
}
.tag-pill.LIGHTNING  { background: var(--cr-orange-100); color: var(--cr-orange-700); border-color: var(--cr-orange-200); }
.tag-pill.PROMO_CODE { background: var(--cr-success-50); color: var(--cr-success-700); border-color: var(--cr-success-100); }
.tag-pill.COUPON     { background: var(--cr-brand-subtle); color: var(--cr-blue-700); border-color: var(--cr-blue-200); }
/* These two had no rule, so the tag rendered as bare unstyled text rather than
   a pill — which is why the stray "Free Trial" read as a rendering glitch. */
.tag-pill.FREE_TRIAL,
.tag-pill.STUDENT_OFFER { background: var(--cr-brand-subtle); color: var(--cr-text-brand); border-color: var(--cr-blue-200); }

.modal-body { padding: 20px 20px 28px; }

.modal-brand {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--cr-text-placeholder);
  margin: 0 0 6px;
}
.modal-title {
  font-family: var(--cr-font-display);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--cr-text-primary);
  margin: 0 0 14px;
  line-height: 1.3;
}

.modal-price-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.modal-price {
  font-family: var(--cr-font-display);
  font-weight: 800;
  font-size: 28px;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--cr-brand);
}
.modal-list-price {
  font-size: 15px;
  color: var(--cr-gray-400);
  text-decoration: line-through;
}
.modal-discount {
  font-size: 12px;
  font-weight: 700;
  color: #fff;
  background: var(--cr-error-500);
  padding: 4px 9px;
  border-radius: var(--cr-radius-full);
}
.modal-stale {
  font-size: 14px;
  color: var(--cr-text-tertiary);
  font-style: italic;
  margin-bottom: 12px;
}

.modal-ends[hidden] { display: none; }
.modal-ends {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--cr-brand);
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 12px;
}
.modal-ends svg { width: 14px; height: 14px; }

.modal-verified {
  font-size: 12px;
  color: var(--cr-text-placeholder);
  margin: 0 0 4px;
}

.modal-divider {
  border: none;
  border-top: 1px solid var(--cr-border-secondary);
  margin: 18px 0;
}

/* ---------- Promo code box ---------- */
.promo-box {
  background: var(--cr-gray-50);
  border: 1px solid var(--cr-border-secondary);
  border-radius: var(--cr-radius-xl);
  padding: 16px;
  margin-bottom: 18px;
}
.promo-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.5px;
  color: var(--cr-text-placeholder);
  margin: 0 0 10px;
}
.promo-code-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }

.promo-reveal-btn {
  width: 100%;
  height: 44px;
  border: none;
  border-radius: var(--cr-radius-md);
  background: var(--cr-brand);
  color: var(--cr-on-brand);
  font-weight: 600;
  font-size: 14px;
  box-shadow: var(--cr-shadow-xs);
  transition: background var(--cr-dur) var(--cr-ease);
}
.promo-reveal-btn:hover { background: var(--cr-brand-hover); }

.promo-code-display[hidden] { display: none; }
.promo-code-display {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  gap: 10px;
}
.promo-code-display span {
  font-family: var(--cr-font-display);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 1.5px;
  color: var(--cr-brand);
}
.promo-copy-btn {
  border: 1px solid var(--cr-blue-200);
  padding: 7px 14px;
  border-radius: var(--cr-radius-md);
  background: var(--cr-surface);
  color: var(--cr-brand);
  font-weight: 600;
  font-size: 13px;
  box-shadow: var(--cr-shadow-xs);
  transition: background var(--cr-dur) var(--cr-ease), color var(--cr-dur) var(--cr-ease);
}
.promo-copy-btn:hover { background: var(--cr-brand-subtle); }
.promo-copy-btn.copied {
  background: var(--cr-success-50);
  border-color: var(--cr-success-100);
  color: var(--cr-success-700);
}
.promo-verified {
  display: flex;
  align-items: center;
  gap: 5px;
  margin: 10px 0 0;
  font-size: 12px;
  font-weight: 500;
  color: var(--cr-success-700);
}
.promo-verified:empty { display: none; }

/* ---------- CTA ---------- */
.cta-button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  height: 48px;
  border-radius: var(--cr-radius-lg);
  background: var(--cr-brand);
  color: var(--cr-on-brand);
  font-weight: 600;
  font-size: 16px;
  box-shadow: var(--cr-shadow-xs);
  margin-bottom: 16px;
  transition: background var(--cr-dur) var(--cr-ease);
}
.cta-button:hover { background: var(--cr-brand-hover); }
.cta-button svg { width: 15px; height: 15px; }
.cta-button.cta-green { background: var(--cr-success-600); }
.cta-button.cta-green:hover { background: var(--cr-success-700); }

.cta-hint[hidden] { display: none; }
.cta-hint {
  font-size: 11.5px;
  color: var(--cr-text-tertiary);
  text-align: center;
  margin: -8px 0 14px;
}

.disclosure {
  font-size: 11px;
  color: var(--cr-text-placeholder);
  text-align: center;
  line-height: 1.5;
  margin: 0;
}

/* ============================================================
   Home sections
   ============================================================ */
#homeSections[hidden] { display: none; }

/* ---------- Hero band ---------- */
/* Three equal columns, each a flex stack. Columns (not a row-spanning grid)
   because the tiles have different heights — flex-grow lets a tall tile and a
   short tile in one column always add up to the same height as its neighbours,
   with no fixed row track to keep in sync. */
.hero-band {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin-bottom: 6px;
}
.hero-col {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}
@media (max-width: 980px) {
  .hero-band { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 640px) {
  .hero-band { grid-template-columns: 1fr; }
}

/* Hero banner cards — implements the "Home hero banners" spec from the Class
   Rewards design project (Banners.dc.html): 158deg three-stop gradient, a light
   bloom rising from the bottom edge, Sora 800 display headline on a 0.95 leading
   with -0.035em tracking, and a #FF5A2C CTA pill. Radius is the design's 20pt
   (--cr-radius-3xl). One deliberate deviation: the design floats transparent
   product cutouts straight on the gradient, but our catalog images are
   white-background packshots, so products keep a white card and sit on the
   design's lit "shelf" instead of on bare gradient. */
.hero-tile {
  position: relative;
  border: none;
  border-radius: var(--cr-radius-3xl);
  padding: 16px 16px 0;
  /* Kept deliberately compact: at 296px these six tiles stacked to ~800px and
     pushed "Today's Top Deals" below the fold. DealSeek keeps its hero mosaic
     short enough that the Top Deals row is visible on the same screen, which is
     the point of the section. */
  min-height: 208px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  text-align: left;
  color: #fff;
  overflow: hidden;
  box-shadow: var(--cr-shadow-md);
  transition: transform var(--cr-dur) var(--cr-ease), box-shadow var(--cr-dur) var(--cr-ease);
}
/* The bloom. Sits at z-index 0 with the content lifted to 1, so decoration can
   never paint over the headline. */
.hero-tile::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(120% 70% at 50% 108%, rgba(255, 255, 255, 0.46), rgba(255, 255, 255, 0) 60%);
}
/* Decorative ring, repositioned per tile below (the design varies it per card). */
.hero-tile::after {
  content: '';
  position: absolute;
  top: -40px;
  right: -60px;
  width: 220px;
  height: 220px;
  border-radius: 50%;
  z-index: 0;
  pointer-events: none;
  border: 22px solid rgba(255, 255, 255, 0.10);
}
.hero-tile > * { position: relative; z-index: 1; }
.hero-tile:hover { transform: translateY(-2px); box-shadow: var(--cr-shadow-lg); }
@media (prefers-reduced-motion: reduce) {
  .hero-tile:hover { transform: none; }
}

.hero-tile { flex: 1 1 auto; }
.hero-tall { flex-grow: 1.9; }          /* balances a tall+short column pair */

/* The design's five card gradients, plus a violet in the same language for the
   Prime tile (the app has six tiles to the design's five). */
.hero-snacks { background: linear-gradient(158deg, #FF7A18 0%, #FF9A2B 46%, #FFC163 100%); }
.hero-promo  { background: linear-gradient(158deg, #F0456F 0%, #FA6B6B 52%, #FF9E7A 100%); }
.hero-tech   { background: linear-gradient(158deg, #0BA5B8 0%, #12BFC4 48%, #3FD9AE 100%); }
.hero-brands { background: linear-gradient(158deg, #2F35DD 0%, #5A56F0 50%, #8E82FA 100%); }
.hero-picks  { background: linear-gradient(158deg, #1B3FD1 0%, #2450E9 46%, #5B8CFF 100%); }
.hero-prime  { background: linear-gradient(158deg, #6D28D9 0%, #8B5CF6 50%, #B79CFB 100%); }

/* Per-card decoration, following the design: filled disc low-left on Promo,
   concentric hairline rings on Brands, a soft disc top-left on Picks. */
.hero-promo::after  { top: auto; bottom: 150px; left: -30px; right: auto; width: 160px; height: 160px; border: none; background: rgba(255, 255, 255, 0.10); }
.hero-brands::after { top: auto; bottom: 120px; right: -70px; width: 240px; height: 240px; border: 1px solid rgba(255, 255, 255, 0.22); }
.hero-picks::after  { top: -40px; left: -40px; right: auto; width: 200px; height: 200px; border: none; background: rgba(255, 255, 255, 0.08); }
/* Tech gets the design's faint grid, fading out downward, instead of a ring. */
.hero-tech::after {
  inset: 0;
  top: 0; right: 0; width: auto; height: auto;
  border: none;
  border-radius: 0;
  opacity: 0.16;
  background:
    repeating-linear-gradient(90deg, rgba(255,255,255,.9) 0 1px, transparent 1px 26px),
    repeating-linear-gradient(0deg, rgba(255,255,255,.9) 0 1px, transparent 1px 26px);
  -webkit-mask-image: linear-gradient(180deg, rgba(0,0,0,.9), transparent 62%);
          mask-image: linear-gradient(180deg, rgba(0,0,0,.9), transparent 62%);
}

.hero-eyebrow {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: rgba(16, 24, 40, 0.28);
  padding: 6px 11px;
  border-radius: var(--cr-radius-full);
}
.hero-heading {
  font-family: "Sora", var(--cr-font-display);
  /* Design calls 42px on a 334px-wide x 400px-tall card; scaled down here since
     these tiles are shorter (see min-height above) and clamped so it tracks the
     column width instead of overflowing at tablet sizes. */
  font-size: clamp(20px, 2vw, 29px);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 0.95;
}
.hero-sub {
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.3;
  color: rgba(255, 255, 255, 0.92);
  margin-top: -1px;
}
.hero-cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 35px;
  padding: 0 15px;
  margin-top: 2px;
  font-size: 13.5px;
  background: #FF5A2C;
  color: #fff;
  font-weight: 700;
  font-size: 15px;
  border-radius: var(--cr-radius-full);
  box-shadow: 0 4px 12px rgba(90, 25, 0, 0.28);
  transition: background var(--cr-dur) var(--cr-ease);
}
.hero-tile:hover .hero-cta { background: #E8410A; }
.hero-cta-arrow { width: 13px; height: 13px; flex: none; }

/* Product shelf. Bleeds to the tile's bottom/side edges via negative margins
   (the tile's own padding would otherwise inset it), giving the design's lit
   plinth that the products stand on. Pinned to the bottom by the `auto` top
   margin and kept IN FLOW rather than absolutely positioned — an absolute
   collage would slide under the headline at narrow widths. */
.hero-collage {
  margin: auto -16px 0;
  padding: 8px 16px 10px;
  align-self: stretch;
  display: grid;
  gap: 8px;
  pointer-events: none;
  border-radius: 18px 18px 0 0;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.26), rgba(255, 255, 255, 0.04));
}
.hero-collage-2 { grid-template-columns: repeat(2, 1fr); }
/* Three across, not four: the design's cards carry 2-3 generous product slots,
   and a 4-up row shrank each packshot to ~60px — a big product on a small stage
   is the whole look. The 4th image stays in the DOM and is simply not shown. */
.hero-collage-4 { grid-template-columns: repeat(3, 1fr); }
.hero-collage-4 .hero-thumb:nth-child(n + 4) { display: none; }
.hero-tile:hover .hero-collage .hero-thumb { transform: translateY(-3px); }

.hero-thumb {
  position: relative;
  background: #fff;
  border-radius: 13px;
  /* Near-square (the design's slots run ~1.2:1) so a square packshot fills the
     card instead of floating in a short, wide letterbox. */
  aspect-ratio: 1.2;
  max-height: 88px;
  overflow: hidden;
  display: block;
  box-shadow: 0 6px 16px rgba(16, 24, 40, 0.22);
  transition: transform var(--cr-dur) var(--cr-ease);
}
/* `contain`, not `cover` — these are white-background packshots, and cropping
   them to fill the tile cut the product itself in half. */
.hero-thumb img { width: 100%; height: 100%; object-fit: contain; display: block; padding: 6px; }

.hero-thumb .thumb-rank {
  position: absolute;
  top: 4px;
  left: 4px;
  background: var(--cr-orange-500);
  color: #fff;
  font-size: 10px;
  font-weight: 800;
  border-radius: var(--cr-radius-full);
  padding: 2px 6px;
}

/* Narrow tiles can't fit four thumbs at a sensible size — show two. */
@media (max-width: 1120px) and (min-width: 641px) {
  .hero-collage-4 { grid-template-columns: repeat(2, 1fr); }
  .hero-collage-4 .hero-thumb:nth-child(n + 3) { display: none; }
}
.hero-thumb .thumb-pct {
  position: absolute;
  bottom: 4px;
  left: 4px;
  background: var(--cr-error-500);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  border-radius: var(--cr-radius-full);
  padding: 2px 6px;
}

/* ---------- Section headers ---------- */
#allDeals[hidden] { display: none; }
.section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 26px 0 14px;
}
.section-header h2 {
  font-family: var(--cr-font-display);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--cr-text-primary);
  margin: 0;
}
.view-all {
  border: 1px solid var(--cr-blue-200);
  background: var(--cr-surface);
  color: var(--cr-brand);
  font-weight: 600;
  font-size: 13px;
  padding: 7px 14px;
  border-radius: var(--cr-radius-md);
  box-shadow: var(--cr-shadow-xs);
  transition: background var(--cr-dur) var(--cr-ease);
}
.view-all:hover { background: var(--cr-brand-subtle); }

/* ---------- Horizontal deal rows ---------- */
.deal-row-wrap { position: relative; }

.deal-row {
  display: flex;
  gap: 16px;
  overflow-x: auto;
  padding: 2px 2px 10px;
  scrollbar-width: none;
  scroll-snap-type: x proximity;
}
.deal-row::-webkit-scrollbar { display: none; }

/* Mouse-drag rows (desktop) to slide through the shelf without a scrollbar. */
.row-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--cr-blue-200);
  background: var(--cr-surface);
  color: var(--cr-text-primary);
  font-size: 20px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--cr-shadow-md);
  cursor: pointer;
  transition: background var(--cr-dur) var(--cr-ease), opacity var(--cr-dur) var(--cr-ease);
}
.row-arrow:hover { background: var(--cr-brand-subtle); }
.row-arrow[hidden] { display: none; }
.row-arrow-prev { left: -6px; }
.row-arrow-next { right: -6px; }

/* Touch devices already scroll the row directly with a finger; the hover-only
   affordance would just sit there un-tappable-looking, so hide it there. */
@media (hover: none) {
  .row-arrow { display: none !important; }
}

.mini-card {
  flex: none;
  width: 212px;
  background: var(--cr-surface);
  border: 1px solid var(--cr-border-secondary);
  border-radius: var(--cr-radius-2xl);
  overflow: hidden;
  cursor: pointer;
  scroll-snap-align: start;
  transition: transform var(--cr-dur) var(--cr-ease), border-color var(--cr-dur) var(--cr-ease);
}
.mini-card:hover { transform: translateY(-1px); border-color: var(--cr-border); }
@media (prefers-reduced-motion: reduce) {
  .mini-card:hover { transform: none; }
}

.mini-media {
  position: relative;
  height: 150px;
  background: #fff;
}
.mini-media img { width: 100%; height: 100%; object-fit: contain; padding: 10px; display: block; }

/* Reward orange = achievement accent (trophy ranks) */
.badge-rank {
  position: absolute;
  top: 8px;
  left: 8px;
  background: var(--cr-orange-300);
  color: var(--cr-gray-900);
  font-size: 11px;
  font-weight: 700;
  padding: 4px 8px;
  border-radius: var(--cr-radius-full);
}
.badge-hearts {
  position: absolute;
  top: 8px;
  right: 8px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: rgba(16, 24, 40, 0.55);
  color: #fff;
  font-size: 10.5px;
  font-weight: 600;
  border-radius: var(--cr-radius-full);
  padding: 3px 8px;
}
.badge-hearts svg { width: 10px; height: 10px; color: var(--cr-error-500); }

.mini-body { padding: 10px 12px 12px; }
.mini-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--cr-text-primary);
  margin: 0 0 8px;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.6em;
}
.mini-price-row {
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.mini-pct {
  background: var(--cr-error-500);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: var(--cr-radius-full);
}
.mini-price {
  font-family: var(--cr-font-display);
  font-weight: 700;
  font-size: 15.5px;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: var(--cr-text-primary);
}
.mini-list {
  font-size: 12px;
  color: var(--cr-gray-400);
  text-decoration: line-through;
}
.mini-source {
  font-size: 11px;
  color: var(--cr-text-placeholder);
  margin: 2px 0 0;
}

/* ---------- Peel-style reveal button (opens the deal modal) ---------- */
.peel-btn {
  display: flex;
  align-items: stretch;
  width: 100%;
  margin-top: 8px;
  border: none;
  background: none;
  padding: 0;
}
.peel-main {
  flex: 1;
  background: var(--cr-success-600);
  color: #fff;
  font-weight: 600;
  font-size: 12.5px;
  padding: 9px 0 9px 14px;
  border-radius: var(--cr-radius-md) 0 0 var(--cr-radius-md);
  text-align: left;
  letter-spacing: 0.2px;
  transition: background var(--cr-dur) var(--cr-ease);
}
.peel-btn:hover .peel-main { background: var(--cr-success-700); }
.peel-tab {
  background: var(--cr-success-50);
  color: var(--cr-success-700);
  font-family: var(--cr-font-display);
  font-weight: 700;
  font-size: 12px;
  padding: 9px 12px;
  border-radius: 0 var(--cr-radius-md) var(--cr-radius-md) 0;
  border-left: 2px dashed #fff;
  display: flex;
  align-items: center;
}

/* ===================== App download banner + modal ===================== */

/* Announcement banner — brand blue band above the white header */
.app-banner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 9px 16px;
  background: var(--cr-brand);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  /* The whole bar is the hit target (see app.js), so it has to look like it. */
  cursor: pointer;
  user-select: none;
}
.app-banner:hover { background: color-mix(in srgb, var(--cr-brand) 88%, #000); }
.app-banner-phone { width: 18px; height: 18px; flex: none; }
.app-banner-dot { opacity: 0.7; }
.app-banner-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 14px;
  border: none;
  border-radius: var(--cr-radius-full);
  background: #fff;
  color: var(--cr-brand);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
  transition: transform var(--cr-dur) var(--cr-ease), box-shadow var(--cr-dur) var(--cr-ease);
}
.app-banner-btn:hover { transform: translateY(-1px); box-shadow: var(--cr-shadow-md); }
.app-banner-btn svg { width: 14px; height: 14px; }
@media (max-width: 640px) {
  .app-banner-text { display: none; }
  .app-banner-dot { display: none; }
}

/* App download modal */
.app-modal {
  position: relative;
  width: min(760px, 100%);
  background: var(--cr-blue-500);
  color: #fff;
  border-radius: var(--cr-radius-3xl) var(--cr-radius-3xl) 0 0;
  padding: 36px 32px;
  animation: modalIn var(--cr-dur) var(--cr-ease);
}
@media (min-width: 720px) {
  .app-modal { border-radius: var(--cr-radius-3xl); }
}
.app-modal-close {
  /* .modal-close puts the X at top-LEFT, which is right for the deal modal
     (it sits over the image) but collides here: .app-modal has 32px side
     padding, so the ratings row starts at x=32 and the 32px-wide X at x=16
     lands directly on the stars. Top-right clears the copy entirely and is the
     conventional spot for a dialog like this. */
  left: auto;
  right: 16px;
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
}
.app-modal-close:hover { background: rgba(255, 255, 255, 0.28); }

.app-modal-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 28px;
  align-items: center;
}
@media (min-width: 720px) {
  .app-modal-grid { grid-template-columns: 1.4fr 1fr; }
}

.app-modal-stats {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 13.5px;
  font-weight: 600;
  opacity: 0.95;
  margin: 0 0 14px;
}
.app-stars { color: var(--cr-orange-300); letter-spacing: 2px; font-size: 15px; }

.app-modal-title {
  margin: 0 0 10px;
  font-size: clamp(24px, 4vw, 32px);
  font-weight: 800;
  letter-spacing: -0.5px;
  line-height: 1.15;
}
.app-modal-title span { color: var(--cr-orange-300); }
.app-modal-sub { margin: 0 0 20px; font-size: 15px; line-height: 1.5; opacity: 0.9; }

.app-modal-perks {
  list-style: none;
  margin: 0 0 24px;
  padding: 0;
  display: grid;
  gap: 12px;
  font-size: 14.5px;
  font-weight: 600;
}
.app-modal-perks li { display: flex; align-items: center; gap: 12px; }
.perk-icon {
  flex: none;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: var(--cr-radius-lg);
  background: rgba(255, 255, 255, 0.14);
}
.perk-icon svg { width: 19px; height: 19px; }

.store-badges { display: flex; gap: 12px; flex-wrap: wrap; }
.store-badge {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 8px 16px;
  border-radius: var(--cr-radius-lg);
  background: #101828;
  color: #fff;
  text-decoration: none;
  transition: transform var(--cr-dur) var(--cr-ease), box-shadow var(--cr-dur) var(--cr-ease);
}
.store-badge:hover { transform: translateY(-1px); box-shadow: var(--cr-shadow-md); }
.store-logo { width: 26px; height: 26px; flex: none; }
.store-badge-text { display: flex; flex-direction: column; line-height: 1.15; font-size: 16px; font-weight: 600; }
.store-badge-text small { font-size: 10px; font-weight: 500; letter-spacing: 0.3px; opacity: 0.85; }

.app-modal-qr { text-align: center; }
.qr-frame {
  display: inline-block;
  padding: 12px;
  background: #fff;
  border-radius: var(--cr-radius-2xl);
}
.qr-frame img { display: block; border-radius: var(--cr-radius-md); }
@keyframes modalIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
.app-modal-qr p {
  margin: 12px auto 0;
  max-width: 220px;
  font-size: 13px;
  line-height: 1.45;
  opacity: 0.9;
}

/* ===================== Deal News page ===================== */

.news-page[hidden] { display: none; }
.news-page {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
  margin-top: 4px;
}
@media (min-width: 720px) {
  .news-page { grid-template-columns: 1fr 1fr; }
}

.news-card {
  background: var(--cr-surface);
  border: 1px solid var(--cr-border-secondary);
  border-radius: var(--cr-radius-2xl);
  padding: 24px;
  box-shadow: var(--cr-shadow-xs);
}
.news-card h3 {
  margin: 0 0 8px;
  font-size: 18px;
  font-weight: 800;
  color: var(--cr-text-primary);
}
.news-card p {
  margin: 0 0 18px;
  color: var(--cr-text-secondary);
  line-height: 1.55;
  font-size: 14.5px;
}
.news-cta {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 9px 16px;
  border: none;
  border-radius: var(--cr-radius-lg);
  background: var(--cr-brand-subtle);
  color: var(--cr-brand);
  font-weight: 700;
  font-size: 13.5px;
  transition: background var(--cr-dur) var(--cr-ease);
}
.news-cta:hover { background: var(--cr-blue-100); }

/* ============================================================
   DealSeek-style card polish (2026-07-15)
   Pill row (discount + deal-type), sold badge, bigger prices,
   gold rank pill, heart chip, softer card shells.
   ============================================================ */

.pill-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-bottom: 8px;
}
.pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--cr-font-display);
  font-weight: 700;
  font-size: 12px;
  line-height: 1;
  padding: 5px 9px;
  border-radius: var(--cr-radius-full);
  white-space: nowrap;
}
.pill svg { width: 13px; height: 13px; flex: none; }
.pill-discount  { background: var(--cr-error-500); color: #fff; }
.pill-drop      { background: rgb(238,233,254); color: rgb(109,74,255); }
.pill-promo     { background: rgb(236,253,243); color: var(--cr-success-600); }
.pill-offer     { background: var(--cr-brand-subtle); color: var(--cr-text-brand); }
.pill-lightning { background: rgb(255,244,229); color: rgb(180,95,6); }
.pill-coupon    { background: var(--cr-brand-subtle); color: var(--cr-brand); }

.sold-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  font-weight: 600;
  color: var(--cr-success-600);
  background: var(--cr-success-50);
  padding: 4px 9px;
  border-radius: var(--cr-radius-full);
  margin: 0 0 8px;
}
.sold-badge svg { width: 13px; height: 13px; flex: none; }

/* Bigger, bolder prices (DealSeek) */
.mini-price, .card-price {
  font-family: var(--cr-font-display);
  font-size: 20px;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--cr-gray-900);
}
.mini-list, .card-list-price {
  font-size: 13px;
  color: var(--cr-gray-400);
  text-decoration: line-through;
}
.mini-price-row, .card-price-row { align-items: baseline; gap: 8px; margin-bottom: 6px; }
.mini-title, .card-title { font-size: 14.5px; font-weight: 700; }

/* Gold "Top N" rank pill, overlaid top-left on the image */
.badge-rank {
  position: absolute;
  top: 10px;
  left: 10px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: rgb(254,240,199);
  color: rgb(146,64,14);
  font-family: var(--cr-font-display);
  font-weight: 800;
  font-size: 12.5px;
  padding: 5px 11px;
  border-radius: var(--cr-radius-full);
  box-shadow: 0 1px 2px rgba(16,24,40,.08);
}

/* Heart + count chip, top-right on the image */
.badge-hearts {
  position: absolute;
  top: 10px;
  right: 10px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: rgba(255,255,255,.94);
  color: var(--cr-gray-700);
  font-weight: 700;
  font-size: 12px;
  padding: 4px 8px;
  border-radius: var(--cr-radius-full);
  box-shadow: 0 1px 3px rgba(16,24,40,.12);
}
.badge-hearts svg { width: 12px; height: 12px; color: var(--cr-error-500); }

/* Flat card shells — grey hairline outline, no elevation */
.mini-card, .deal-card {
  border-radius: 18px;
  border: 1px solid var(--cr-gray-200);
  background: #fff;
  overflow: hidden;
}
.mini-source { margin-top: 2px; }

/* ---------- Star ratings (2026-07-16) ---------- */
.rating-row {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 2px 0 8px;
  font-size: 13px;
}
.stars {
  position: relative;
  display: inline-block;
  font-size: 14px;
  line-height: 1;
  letter-spacing: 1px;
  white-space: nowrap;
}
.stars-bg { color: var(--cr-gray-300, #d0d5dd); }
.stars-fg {
  position: absolute;
  left: 0;
  top: 0;
  overflow: hidden;
  color: #f5a623;
  white-space: nowrap;
}
.rating-num { font-weight: 700; color: var(--cr-gray-900, #101828); }
.rating-count { color: var(--cr-gray-500, #667085); }
.modal-body .rating-row { font-size: 14px; margin: 4px 0 12px; }
.modal-body .stars { font-size: 16px; }

/* ---------- Category filter (Filters button + chip bar, 2026-07-16) ---------- */
.search-row { gap: 10px; }
.filter-btn {
  display: flex;
  align-items: center;
  gap: 7px;
  flex: none;
  padding: 10px 16px;
  border: 1px solid var(--cr-border-secondary);
  background: var(--cr-gray-100);
  color: var(--cr-text-secondary);
  border-radius: var(--cr-radius-lg);
  font-family: var(--cr-font-body);
  font-weight: 600;
  font-size: 14px;
  white-space: nowrap;
  transition: background var(--cr-dur) var(--cr-ease), border-color var(--cr-dur) var(--cr-ease), color var(--cr-dur) var(--cr-ease);
}
.filter-btn svg { width: 18px; height: 18px; }
.filter-btn:hover { background: var(--cr-gray-200); }
.filter-btn.open { border-color: var(--cr-brand); color: var(--cr-brand); background: var(--cr-brand-subtle); }
.filter-btn.has-filter { border-color: var(--cr-brand); color: var(--cr-brand); }

.category-bar[hidden] { display: none; }
.category-bar {
  display: flex;
  gap: 8px;
  padding-top: 12px;
  overflow-x: auto;
  scrollbar-width: none;
}
.category-bar::-webkit-scrollbar { display: none; }
.cat-chip {
  flex: none;
  padding: 8px 16px;
  border: 1px solid var(--cr-border-secondary);
  background: var(--cr-surface);
  color: var(--cr-text-secondary);
  border-radius: var(--cr-radius-full);
  font-family: var(--cr-font-body);
  font-weight: 600;
  font-size: 13.5px;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--cr-dur) var(--cr-ease), border-color var(--cr-dur) var(--cr-ease), color var(--cr-dur) var(--cr-ease);
}
.cat-chip:hover { background: var(--cr-gray-100); }
.cat-chip.active {
  background: var(--cr-brand);
  border-color: var(--cr-brand);
  color: var(--cr-on-brand);
}

/* ---------- Shop by Category (Name Brands tab, 2026-07-16) ---------- */
.brand-cat-section { max-width: 1200px; margin: 0 auto; padding: 0 24px; }
.brand-cat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 16px;
  margin-bottom: 8px;
}
.brand-cat-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 18px;
  text-align: left;
  background: var(--cr-surface);
  border: 1px solid var(--cr-border-secondary);
  border-radius: var(--cr-radius-xl);
  cursor: pointer;
  transition: box-shadow var(--cr-dur) var(--cr-ease), border-color var(--cr-dur) var(--cr-ease), transform var(--cr-dur) var(--cr-ease);
}
.brand-cat-card:hover {
  border-color: var(--cr-brand);
  box-shadow: var(--cr-shadow-md);
  transform: translateY(-2px);
}
.brand-cat-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.brand-cat-name { font-family: var(--cr-font-display); font-weight: 800; font-size: 18px; color: var(--cr-text-primary); }
.brand-cat-count { font-size: 12.5px; font-weight: 600; color: var(--cr-text-tertiary); white-space: nowrap; }
.brand-cat-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.brand-chip {
  padding: 4px 10px;
  background: var(--cr-gray-100);
  border-radius: var(--cr-radius-full);
  font-size: 12px;
  font-weight: 600;
  color: var(--cr-text-secondary);
}
.brand-chip-more { background: var(--cr-brand-subtle); color: var(--cr-text-brand); }
.brand-cat-cta { font-size: 13.5px; font-weight: 700; color: var(--cr-brand); }

.cat-back-btn {
  border: none;
  background: none;
  padding: 6px 0;
  color: var(--cr-brand);
  font-family: var(--cr-font-body);
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
}
.cat-back-btn:hover { text-decoration: underline; }

/* ---------- Shop by Category — product image previews (2026-07-16) ---------- */
.brand-cat-previews {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.cat-preview {
  position: relative;
  display: block;
  aspect-ratio: 1 / 1;
  background: var(--cr-gray-50);
  border: 1px solid var(--cr-border-secondary);
  border-radius: var(--cr-radius-md);
  overflow: hidden;
}
.cat-preview img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 6px;
}
.cat-preview-badge {
  position: absolute;
  bottom: 5px;
  left: 5px;
  background: var(--cr-error-500);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: var(--cr-radius-full);
  line-height: 1.2;
}

/* ---- Share deal (modal CTA row + toast) ---- */
.cta-row {
  display: flex;
  gap: 10px;
  align-items: stretch;
  margin-bottom: 16px;
}
.cta-row .cta-button { flex: 1; margin-bottom: 0; }
.share-btn {
  flex: 0 0 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--cr-radius-lg);
  border: 1.5px solid var(--cr-blue-200);
  background: var(--cr-blue-25);
  color: var(--cr-brand);
  cursor: pointer;
  transition: background var(--cr-dur) var(--cr-ease), border-color var(--cr-dur) var(--cr-ease);
}
.share-btn:hover { background: var(--cr-blue-50); border-color: var(--cr-blue-300); }
.share-btn svg { width: 20px; height: 20px; }

.share-toast[hidden] { display: none; }
.share-toast {
  position: fixed;
  left: 50%;
  bottom: 32px;
  transform: translateX(-50%);
  background: var(--cr-text-primary, #111);
  color: #fff;
  font-size: 13.5px;
  font-weight: 600;
  padding: 10px 18px;
  border-radius: var(--cr-radius-full);
  box-shadow: 0 6px 24px rgba(0,0,0,.25);
  z-index: 300;
  animation: share-toast-in .18s ease-out;
}
@keyframes share-toast-in {
  from { opacity: 0; transform: translateX(-50%) translateY(8px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}

/* ---- Hover state: title goes brand-blue + flag reveals ----
   Applies to EVERY card surface, not just the grid: the Top Deals and Promo
   Codes carousels use .mini-card, and scoping these rules to .deal-card alone
   left both rows with no hover state at all. */
.deal-card, .mini-card { position: relative; }
.deal-card:hover .card-title,
.deal-card:focus-visible .card-title,
.mini-card:hover .mini-title,
.mini-card:focus-visible .mini-title { color: var(--cr-brand); }
.card-title, .mini-title { transition: color var(--cr-dur) var(--cr-ease); }

.card-flag {
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: var(--cr-radius-full);
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 1px 4px rgba(0, 0, 0, .14);
  color: var(--cr-text-tertiary);
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--cr-dur) var(--cr-ease), color var(--cr-dur) var(--cr-ease), background var(--cr-dur) var(--cr-ease);
}
.card-flag svg { width: 15px; height: 15px; }
.deal-card:hover .card-flag,
.mini-card:hover .card-flag,
.card-flag:focus-visible { opacity: 1; }
.card-flag:hover { color: var(--cr-brand); background: #fff; }
.card-flag.reported { opacity: 1; color: var(--cr-brand); }

/* Tooltip — sits left of the flag so it never clips the card edge. */
.card-flag-tip {
  position: absolute;
  top: 50%;
  right: calc(100% + 8px);
  transform: translateY(-50%);
  white-space: nowrap;
  background: var(--cr-surface);
  color: var(--cr-text-primary);
  border: 1px solid var(--cr-border-secondary);
  box-shadow: var(--cr-shadow-sm, 0 4px 14px rgba(0,0,0,.12));
  border-radius: var(--cr-radius-md, 8px);
  font-size: 12px;
  font-weight: 600;
  padding: 6px 10px;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--cr-dur) var(--cr-ease);
}
.card-flag:hover .card-flag-tip,
.card-flag:focus-visible .card-flag-tip { opacity: 1; }

/* Touch devices have no hover — keep the flag discoverable but subtle. */
@media (hover: none) {
  .card-flag { opacity: .55; }
  .card-flag-tip { display: none; }
}

/* ---- Report confirmation modal ---- */
.report-modal {
  background: var(--cr-surface);
  border-radius: var(--cr-radius-2xl);
  padding: 24px;
  width: min(420px, calc(100vw - 40px));
  box-shadow: 0 20px 60px rgba(0,0,0,.28);
  text-align: left;
}
.report-title { font-size: 18px; font-weight: 700; margin: 0 0 8px; color: var(--cr-text-primary); }
.report-sub { font-size: 14px; color: var(--cr-text-secondary); margin: 0 0 20px; line-height: 1.45; }
.report-actions { display: flex; justify-content: flex-end; gap: 10px; }
.report-btn {
  height: 40px;
  padding: 0 18px;
  border-radius: var(--cr-radius-lg);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  border: 1px solid transparent;
  transition: background var(--cr-dur) var(--cr-ease);
}
.report-btn-ghost { background: transparent; border-color: var(--cr-border-secondary); color: var(--cr-text-secondary); }
.report-btn-ghost:hover { background: var(--cr-blue-25); }
.report-btn-primary { background: var(--cr-brand); color: var(--cr-on-brand); }
.report-btn-primary:hover { background: var(--cr-brand-hover); }

/* ---- Card action column (favorite + report), top-right ---- */
.card-actions {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 3;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.card-fav {
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: var(--cr-radius-full);
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 1px 4px rgba(0, 0, 0, .14);
  color: var(--cr-text-tertiary);
  cursor: pointer;
  position: relative;
  transition: color var(--cr-dur) var(--cr-ease), background var(--cr-dur) var(--cr-ease), transform var(--cr-dur) var(--cr-ease);
}
.card-fav svg { width: 17px; height: 17px; }
.card-fav:hover { color: var(--cr-danger-600, #d92d20); background: #fff; }
.card-fav:active { transform: scale(.88); }
.card-fav.faved { color: var(--cr-danger-600, #d92d20); }
.card-fav.faved svg path { fill: currentColor; stroke: currentColor; }
.card-flag { position: relative; }

/* ---- Sign-in prompt modal ---- */
.auth-modal {
  position: relative;
  background: var(--cr-surface);
  border-radius: var(--cr-radius-2xl);
  padding: 32px 28px 22px;
  width: min(400px, calc(100vw - 40px));
  box-shadow: 0 20px 60px rgba(0,0,0,.28);
  text-align: center;
}
.auth-close { position: absolute; top: 12px; right: 12px; }
.auth-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  margin-bottom: 20px;
}
.auth-logo { width: 34px; height: 34px; border-radius: 9px; }
.auth-wordmark {
  font-family: var(--cr-font-display);
  font-size: 21px;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--cr-brand);
}
.auth-title { font-size: 22px; font-weight: 700; margin: 0 0 6px; color: var(--cr-text-primary); }
.auth-sub { font-size: 14.5px; line-height: 1.5; color: var(--cr-text-secondary); margin: 0 0 22px; }

.auth-providers { display: flex; flex-direction: column; gap: 10px; }
.auth-provider {
  height: 52px;
  border-radius: var(--cr-radius-full);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  border: 1px solid transparent;
  transition: background var(--cr-dur) var(--cr-ease), transform var(--cr-dur) var(--cr-ease);
}
.auth-provider:active { transform: scale(.99); }
.auth-provider svg { width: 19px; height: 19px; flex: none; }
.auth-google { background: var(--cr-bg-secondary, #f2f4f7); color: var(--cr-text-primary); }
.auth-google:hover { background: var(--cr-border-secondary, #e4e7ec); }
.auth-apple { background: #000; color: #fff; }
.auth-apple:hover { background: #1a1a1a; }

.auth-more {
  margin: 18px auto 0;
  display: flex;
  align-items: center;
  gap: 5px;
  background: none;
  border: none;
  font-size: 14px;
  font-weight: 600;
  color: var(--cr-text-tertiary);
  cursor: pointer;
}
.auth-more:hover { color: var(--cr-text-secondary); }
.auth-more svg { width: 16px; height: 16px; transition: transform var(--cr-dur) var(--cr-ease); }
.auth-more.open svg { transform: rotate(180deg); }

.auth-signup {
  margin: 18px 0 0;
  font-size: 14px;
  color: var(--cr-text-secondary);
}
.auth-signup button {
  background: none;
  border: none;
  padding: 0;
  font-size: inherit;
  font-weight: 700;
  color: var(--cr-brand);
  cursor: pointer;
}
.auth-signup button:hover { text-decoration: underline; }

.auth-actions { display: flex; flex-direction: column; gap: 10px; margin-top: 12px; }
/* A class rule with `display` beats the UA's [hidden]{display:none}, so the
   collapsed "more options" panel stayed visible without this. */
.auth-actions[hidden] { display: none; }
.auth-btn {
  height: 46px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  border-radius: var(--cr-radius-lg);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  border: 1px solid var(--cr-border-secondary);
  background: var(--cr-surface);
  color: var(--cr-text-primary);
  transition: background var(--cr-dur) var(--cr-ease);
}
.auth-btn:hover { background: var(--cr-blue-25); }
.auth-btn-primary { background: var(--cr-brand); border-color: var(--cr-brand); color: var(--cr-on-brand); }
.auth-btn-primary:hover { background: var(--cr-brand-hover); }
.auth-btn svg { width: 18px; height: 18px; }
.auth-later {
  margin-top: 14px;
  background: none;
  border: none;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--cr-text-tertiary);
  cursor: pointer;
}
.auth-later:hover { color: var(--cr-text-secondary); }

/* ---- Wider, two-column deal modal (DealSeek-style) ---- */
@media (min-width: 860px) {
  .modal { max-width: 940px; }
  .modal-grid {
    display: grid;
    grid-template-columns: 1.02fr 1fr;
    gap: 28px;
    padding: 0 28px 4px;
    align-items: start;
  }
  .modal-grid .modal-hero { height: 420px; border-radius: var(--cr-radius-xl); overflow: hidden; }
  .modal-grid .modal-body { padding-top: 4px; }
}

/* Breadcrumb */
.modal-crumb {
  display: flex;
  align-items: center;
  gap: 8px;
  /* Left padding clears the floating close button (absolute, left:16px, 32px
     wide) — without it the ✕ sat directly on top of "Home". The top padding
     centers the trail on the button, so they read as one row: ✕  Home › CAT. */
  padding: 22px 24px 12px 58px;
  font-size: 13px;
  font-weight: 600;
}
.crumb-home { color: var(--cr-text-primary); }
.crumb-sep { color: var(--cr-text-tertiary); }
.crumb-cat { color: var(--cr-text-tertiary); letter-spacing: .02em; }
@media (min-width: 860px) { .modal-crumb { padding: 22px 28px 14px 58px; } }

/* Floating action cluster over the gallery */
.modal-actions {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 4;
  display: flex;
  gap: 8px;
}
.modal-act {
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: var(--cr-radius-full);
  background: rgba(255,255,255,.94);
  box-shadow: 0 1px 6px rgba(0,0,0,.16);
  color: var(--cr-text-secondary);
  cursor: pointer;
  transition: color var(--cr-dur) var(--cr-ease), background var(--cr-dur) var(--cr-ease), transform var(--cr-dur) var(--cr-ease);
}
.modal-act svg { width: 18px; height: 18px; }
.modal-act:hover { background: #fff; color: var(--cr-brand); }
.modal-act:active { transform: scale(.9); }
#modalFav:hover { color: var(--cr-danger-600, #d92d20); }
#modalFav.faved { color: var(--cr-danger-600, #d92d20); }
#modalFav.faved svg path { fill: currentColor; stroke: currentColor; }
#modalFlag.reported { color: var(--cr-brand); }

/* ---- Similar Items ---- */
.modal-similar[hidden] { display: none; }
.modal-similar {
  border-top: 1px solid var(--cr-border-secondary);
  margin-top: 18px;
  padding: 20px 0 24px;
}
.similar-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 24px 14px;
}
.similar-head h3 { font-size: 18px; font-weight: 700; margin: 0; color: var(--cr-text-primary); }
@media (min-width: 860px) { .similar-head { padding: 0 28px 16px; } }

.similar-row {
  display: flex;
  gap: 12px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  padding: 2px 24px 6px;
  scrollbar-width: thin;
}
@media (min-width: 860px) { .similar-row { padding: 2px 28px 6px; } }
.similar-row::-webkit-scrollbar { height: 6px; }
.similar-row::-webkit-scrollbar-thumb { background: var(--cr-border-secondary); border-radius: 999px; }

.similar-card {
  flex: 0 0 168px;
  scroll-snap-align: start;
  text-align: left;
  background: var(--cr-surface);
  border: 1px solid var(--cr-border-secondary);
  border-radius: var(--cr-radius-xl);
  padding: 10px;
  cursor: pointer;
  transition: box-shadow var(--cr-dur) var(--cr-ease), transform var(--cr-dur) var(--cr-ease);
}
.similar-card:hover { box-shadow: var(--cr-shadow-sm, 0 4px 14px rgba(0,0,0,.10)); transform: translateY(-2px); }
.similar-card:hover .similar-title { color: var(--cr-brand); }
.similar-media {
  height: 108px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  border-radius: var(--cr-radius-lg);
  overflow: hidden;
  margin-bottom: 8px;
}
.similar-media img { max-width: 100%; max-height: 100%; object-fit: contain; }
.similar-title {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--cr-text-primary);
  margin: 0 0 6px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  transition: color var(--cr-dur) var(--cr-ease);
}
.similar-pills { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 6px; }
.similar-price-row { display: flex; align-items: baseline; gap: 6px; }
.similar-price { font-size: 15px; font-weight: 800; color: var(--cr-text-primary); }
.similar-list { font-size: 12px; color: var(--cr-text-tertiary); text-decoration: line-through; }
.similar-source { font-size: 11px; color: var(--cr-text-tertiary); margin: 5px 0 0; }

/* ---------- Site footer (shared by the deals page and About) ---------- */
.site-footer {
  border-top: 1px solid var(--cr-border-secondary);
  background: var(--cr-surface-secondary);
  margin-top: 56px;
  padding: 48px 0 40px;
}
.footer-inner { max-width: 1200px; margin: 0 auto; padding: 0 24px; }

.footer-cols {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr)) minmax(0, 1.3fr);
  gap: 32px;
  padding-bottom: 40px;
}
@media (max-width: 1000px) { .footer-cols { grid-template-columns: repeat(2, 1fr); gap: 30px 24px; } }
@media (max-width: 560px)  { .footer-cols { grid-template-columns: 1fr; } }

.footer-col { display: flex; flex-direction: column; align-items: flex-start; gap: 11px; min-width: 0; }
.footer-col h3 {
  font-size: 14.5px;
  font-weight: 700;
  color: var(--cr-text-primary);
  margin: 0 0 3px;
  letter-spacing: -0.01em;
}
.footer-col a {
  font-size: 14px;
  color: var(--cr-text-tertiary);
  text-decoration: none;
  transition: color var(--cr-dur) var(--cr-ease);
}
.footer-col a:hover { color: var(--cr-brand); }

.footer-app-copy { font-size: 13.5px; line-height: 1.55; color: var(--cr-text-tertiary); margin: 0 0 4px; max-width: 30ch; }
.footer-qr {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px;
  border: 1px solid var(--cr-border-secondary);
  border-radius: var(--cr-radius-xl);
  background: var(--cr-surface);
  cursor: pointer;
  transition: border-color var(--cr-dur) var(--cr-ease), box-shadow var(--cr-dur) var(--cr-ease);
}
.footer-qr:hover { border-color: var(--cr-brand); box-shadow: 0 4px 14px rgba(16,24,40,.08); }
.footer-qr img { width: 74px; height: 74px; display: block; border-radius: var(--cr-radius-md); }
.footer-qr-label { font-size: 13px; font-weight: 650; color: var(--cr-text-secondary); text-align: left; }

.footer-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding-top: 26px;
  border-top: 1px solid var(--cr-border-secondary);
}
.footer-brand { display: flex; align-items: center; gap: 9px; text-decoration: none; }
.footer-brand img { border-radius: 7px; display: block; }
.footer-brand span { font-family: var(--cr-font-display); font-weight: 800; font-size: 16px; color: var(--cr-brand); }
.footer-legal { font-size: 13px; color: var(--cr-text-tertiary); }

.footer-disclosure {
  margin: 18px 0 0;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--cr-text-placeholder);
  max-width: 78ch;
}

/* ---------- Filter bar (replaces the old category chips) ----------
   Pills sit in one scrollable row; the ones with choices open a popover
   anchored under them. Only ONE popover is open at a time (see app.js), so the
   bar never turns into a stack of overlapping panels. */
/* MUST come before the display rule wins: the `hidden` attribute is only
   `display:none` in the UA stylesheet, so any author `display` declaration
   overrides it and the bar stays on screen even while hidden=true. */
.filter-bar[hidden] { display: none !important; }
.filter-bar {
  display: flex;
  align-items: center;
  /* WRAPS — it must not scroll. `overflow-x: auto` here silently clipped every
     popover: CSS does not allow one axis to scroll while the other stays
     visible, so `overflow-y: visible` computed to `auto` and cut the panels off
     at the bar's own edge. Wrapping also stops the last pill (Sort) being
     chopped at the right edge on narrow viewports. */
  flex-wrap: wrap;
  gap: 10px;
  /* Own vertical breathing room, overriding .header-row's `padding: 0 24px`.
     The bottom value is deliberately large: .page sits at margin-top:-16px to
     tuck under the header's rounded corner, so the last 16px of header padding
     is covered by the page and only what's beyond it reads as real spacing. */
  padding: 12px 24px 22px;
}
/* The popovers are absolutely positioned children, so the row itself must not
   clip them — but it still needs to scroll horizontally on narrow screens.
   position:relative on the item (not the bar) keeps each popover under its pill. */
.fb-item { position: relative; flex: none; }

.fb-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: none;
  height: 40px;
  padding: 0 15px;
  border: 1px solid var(--cr-border);
  background: var(--cr-surface);
  color: var(--cr-text-primary);
  font-size: 14px;
  font-weight: 600;
  border-radius: var(--cr-radius-full);
  box-shadow: var(--cr-shadow-xs);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--cr-dur) var(--cr-ease), border-color var(--cr-dur) var(--cr-ease);
}
.fb-pill svg { width: 17px; height: 17px; flex: none; color: var(--cr-brand); }
.fb-pill:hover { background: var(--cr-brand-subtle); }
.fb-pill[aria-expanded="true"] { border-color: var(--cr-brand); background: var(--cr-brand-subtle); }
/* Active state: a filter that is actually narrowing the results. */
.fb-pill.on {
  border-color: var(--cr-brand);
  background: var(--cr-brand-subtle);
  color: var(--cr-brand);
}
.fb-pill.on svg { color: var(--cr-brand); }
.fb-check { display: none; font-weight: 800; color: var(--cr-brand); }
.fb-pill.on .fb-check { display: inline; }

.fb-pop {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  z-index: 40;
  min-width: 236px;
  padding: 14px;
  background: var(--cr-surface);
  border: 1px solid var(--cr-border);
  border-radius: var(--cr-radius-xl);
  box-shadow: var(--cr-shadow-lg);
}
.fb-pop[hidden] { display: none; }
/* Keep the rightmost popovers from running off the viewport. */
.fb-item:last-of-type .fb-pop, .fb-pop-sort { left: auto; right: 0; }
.fb-pop-title { font-size: 14px; font-weight: 700; color: var(--cr-text-primary); }
.fb-pop-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.fb-pop-val { font-size: 13px; font-weight: 700; color: var(--cr-text-secondary); }
.fb-pop-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 12px; }
.fb-reset, .fb-apply {
  height: 34px; padding: 0 16px; border-radius: var(--cr-radius-md);
  font-size: 13px; font-weight: 700; cursor: pointer;
}
.fb-reset { border: 1px solid var(--cr-border); background: var(--cr-surface-alt); color: var(--cr-text-primary); }
.fb-apply { border: none; background: var(--cr-brand); color: #fff; }
.fb-reset:hover { background: var(--cr-border); }
.fb-apply:hover { filter: brightness(0.94); }

.fb-store-grid { display: flex; gap: 8px; margin-top: 10px; }
.fb-store {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 10px 6px; border: 1.5px solid var(--cr-border); border-radius: var(--cr-radius-lg);
  background: var(--cr-surface); font-size: 11.5px; font-weight: 600;
  color: var(--cr-text-primary); cursor: pointer; text-align: center; line-height: 1.15;
}
.fb-store.selected { border-color: var(--cr-text-primary); }
.fb-store-dot {
  width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center;
  font-size: 12px; font-weight: 800; color: #fff;
}
.fb-dot-all { background: linear-gradient(135deg, var(--cr-orange-500), var(--cr-brand)); font-size: 10px; }
.fb-dot-a { background: var(--cr-orange-500); }
.fb-dot-p { background: var(--cr-brand); }

.fb-range { width: 100%; accent-color: var(--cr-brand); }

.fb-sort-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 10px; }
.fb-sort {
  padding: 11px 8px; border: 1.5px solid var(--cr-border); border-radius: var(--cr-radius-lg);
  background: var(--cr-surface); font-size: 13px; font-weight: 600;
  color: var(--cr-text-primary); cursor: pointer;
}
.fb-sort:hover { background: var(--cr-brand-subtle); }
.fb-sort.selected { border-color: var(--cr-brand); background: var(--cr-brand-subtle); color: var(--cr-brand); }

.fb-clear {
  flex: none; height: 40px; padding: 0 12px; border: none; background: none;
  color: var(--cr-brand); font-size: 13px; font-weight: 700; cursor: pointer; white-space: nowrap;
}
.fb-clear[hidden] { display: none; }

/* ---------- In-app browser prompt ----------
   Only rendered inside Instagram / Facebook / TikTok's embedded browser. Sits
   above everything as a bottom sheet because that is the one place a thumb is
   already resting, and those browsers put their own chrome at the top. */
.iab-sheet {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 9999;
  background: #fff;
  border-radius: 20px 20px 0 0;
  box-shadow: 0 -8px 40px rgba(16, 24, 40, .22);
  padding: 18px 18px calc(18px + env(safe-area-inset-bottom, 0px));
  animation: iabUp .28s cubic-bezier(.22, 1, .36, 1);
}
@keyframes iabUp { from { transform: translateY(110%); } to { transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) { .iab-sheet { animation: none; } }

.iab-close {
  position: absolute; top: 10px; right: 10px;
  width: 32px; height: 32px; padding: 7px;
  border: 0; border-radius: 50%;
  background: #f2f4f7; color: #667085; cursor: pointer;
}
.iab-close svg { width: 100%; height: 100%; display: block; }

.iab-row { display: flex; align-items: center; gap: 12px; padding-right: 36px; }
.iab-icon { width: 52px; height: 52px; border-radius: 12px; flex: none; }
.iab-copy { min-width: 0; }
.iab-title { margin: 0; font-size: 16px; font-weight: 700; color: #101828; line-height: 1.25; }
.iab-sub { margin: 3px 0 0; font-size: 13.5px; color: #667085; line-height: 1.4; }

.iab-cta {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  margin-top: 14px; padding: 14px 18px;
  background: #2450e9; color: #fff;
  border-radius: 12px;
  font-size: 16px; font-weight: 700; text-decoration: none;
}
.iab-cta svg { width: 18px; height: 18px; flex: none; }
.iab-cta:active { background: #1c3fbb; }

.iab-alt {
  display: block; width: 100%;
  margin-top: 8px; padding: 10px;
  background: none; border: 0;
  color: #667085; font-size: 14px; font-weight: 600;
  text-decoration: underline; cursor: pointer;
}

.iab-hint {
  margin: 6px 0 0;
  font-size: 13px; line-height: 1.5; color: #475467; text-align: center;
}
.iab-hint strong { color: #101828; }

/* ---------- Auth: phone / SMS step ---------- */
.auth-phone { display: flex; flex-direction: column; gap: 8px; }
.auth-label { font-size: 13px; font-weight: 600; color: #344054; }
.auth-input {
  width: 100%; padding: 12px 14px;
  border: 1px solid #d0d5dd; border-radius: 10px;
  font-size: 16px; /* 16px stops iOS Safari zooming the page on focus */
  font-family: inherit; color: #101828; background: #fff;
}
.auth-input:focus { outline: none; border-color: #2450e9; box-shadow: 0 0 0 3px rgba(36,80,233,.12); }
.auth-error { margin: 8px 0 0; font-size: 13.5px; color: #d92d20; line-height: 1.45; }
.auth-linkbtn {
  background: none; border: 0; padding: 6px 0;
  color: #667085; font-size: 13.5px; text-decoration: underline; cursor: pointer;
}
.auth-microsoft svg { width: 18px; height: 18px; }

/* ---------- In-app browser: copy-link + manual steps ---------- */
.iab-copy {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  width: 100%; margin-top: 8px; padding: 12px 16px;
  background: #f2f4f7; border: 1px solid #e4e7ec; border-radius: 12px;
  color: #344054; font-size: 15px; font-weight: 600; font-family: inherit; cursor: pointer;
}
.iab-copy svg { width: 17px; height: 17px; flex: none; }
.iab-copy:active { background: #e4e7ec; }

.iab-steps {
  margin: 12px 0 0; padding: 0 0 0 20px;
  font-size: 13.5px; line-height: 1.7; color: #475467;
}
.iab-steps li { margin: 2px 0; }
.iab-steps strong { color: #101828; }

/* ---------- Sign up button (header) ---------- */
/* Geometry deliberately mirrors .account-signin — the two sit side by side, and
   a 40px pill next to a 38px one reads as a mistake even when nobody can say why. */
.account-signup {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  padding: 0 20px;
  background: #2450e9;
  border: 0; border-radius: 100px;
  color: #fff; font-size: 14.5px; font-weight: 600; font-family: inherit;
  line-height: 1;
  cursor: pointer; white-space: nowrap;
}
.account-signup:hover { background: #1c3fbb; }
.account-signup:active { transform: translateY(1px); }

/* ---------- Like animation ----------
   Two parts: the heart itself springs, and a ring of particles flies out.
   Both are pure CSS off a single class so the JS only has to add and remove. */
@keyframes favPop {
  0%   { transform: scale(1); }
  30%  { transform: scale(.82); }
  55%  { transform: scale(1.28); }
  75%  { transform: scale(.94); }
  100% { transform: scale(1); }
}
.fav-pop { animation: favPop .42s cubic-bezier(.34, 1.56, .64, 1); }

.fav-burst {
  position: absolute; inset: 0;
  pointer-events: none;             /* never steal the next tap */
  display: block;
}
.fav-burst i {
  position: absolute; top: 50%; left: 50%;
  width: 5px; height: 5px; margin: -2.5px 0 0 -2.5px;
  border-radius: 50%;
  background: #f0436c;
  /* --a is the particle's angle, set per-dot in JS; --d staggers them slightly
     so the ring reads as a burst rather than a mechanical hexagon. */
  transform: rotate(var(--a)) translateY(0) scale(1);
  animation: favBurst .58s ease-out forwards;
  animation-delay: calc(var(--d) - 90ms);
}
.fav-burst i:nth-child(even) { background: #ffb020; width: 4px; height: 4px; }

@keyframes favBurst {
  0%   { transform: rotate(var(--a)) translateY(0) scale(.4); opacity: 0; }
  25%  { opacity: 1; }
  100% { transform: rotate(var(--a)) translateY(-17px) scale(0); opacity: 0; }
}

/* The burst is absolutely positioned against the heart button. */
.card-fav, .modal-fav { position: relative; }

@media (prefers-reduced-motion: reduce) {
  .fav-pop { animation: none; }
  .fav-burst { display: none; }
}


/* ---------- Auth modal: entrance, mode copy, busy state ----------
   The card previously had NO entrance animation — only the overlay faded, so
   the modal itself snapped into place fully formed. That read as a jump. It now
   rises with the overlay, and honours reduced-motion. */
.modal-overlay:not([hidden]) > .auth-modal {
  animation: authCardIn 260ms cubic-bezier(.22, 1, .36, 1);
  transform-origin: center bottom;
}
@keyframes authCardIn {
  from { opacity: 0; transform: translateY(16px) scale(.985); }
  to   { opacity: 1; transform: none; }
}

/* The phone section used to appear by unhiding, which resized the card in one
   frame. Animating grid-template-rows 0fr -> 1fr expands it to its own natural
   height without hardcoding a max-height that would clip on a narrow screen. */
.auth-actions:not([hidden]) {
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows 260ms cubic-bezier(.22, 1, .36, 1);
}
.auth-actions > * { min-height: 0; }

.auth-error-top {
  margin: -8px 0 16px;
  padding: 10px 12px;
  border-radius: 10px;
  background: #fef3f2;
  border: 1px solid #fecdca;
  text-align: left;
}

/* Indeterminate loading bar. Sits above the providers so the eye is already
   there when the row disables. */
.auth-loading {
  position: relative;
  height: 3px;
  margin: 0 0 14px;
  border-radius: 100px;
  background: var(--cr-brand-subtle, #eff4ff);
  overflow: hidden;
}
.auth-loading[hidden] { display: none; }
.auth-loading span {
  position: absolute;
  inset: 0 auto 0 0;
  width: 40%;
  border-radius: 100px;
  background: var(--cr-brand, #2450e9);
  animation: authBarSlide 1.1s ease-in-out infinite;
}
@keyframes authBarSlide {
  0%   { left: -40%; }
  100% { left: 100%; }
}

.auth-provider:disabled { opacity: .55; cursor: default; }
.auth-provider.is-busy { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .modal-overlay:not([hidden]) > .auth-modal { animation: none; }
  .auth-actions:not([hidden]) { transition: none; }
  .auth-loading span { animation-duration: 2.4s; }
}

/* ---------- Catalog load progress ----------
   Replaces the "No deals right now" banner during the initial load. That banner
   is a factual statement about the catalog and it was firing before the first
   fetch had even returned, so a healthy site with 60k+ deals announced it had
   none for the first second or two of every visit. */
.load-progress {
  max-width: 420px;
  margin: 48px auto;
  text-align: center;
}
.lp-label {
  font-size: 14px;
  font-weight: 600;
  color: var(--cr-text-muted, #6b7280);
  margin-bottom: 12px;
  font-variant-numeric: tabular-nums;
}
.lp-track {
  height: 6px;
  border-radius: 999px;
  background: var(--cr-border, #e5e7eb);
  overflow: hidden;
}
.lp-fill {
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: var(--cr-blue, #1d4ed8);
  transition: width .28s ease;
}
/* Before X-Total-Count is known there is no percentage to show, so the bar
   sweeps instead of sitting at 0 — motion reads as "working", a stalled 0%
   reads as "broken". */
.lp-track.indeterminate .lp-fill {
  width: 35%;
  animation: lp-sweep 1.1s ease-in-out infinite;
}
@keyframes lp-sweep {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(320%); }
}
@media (prefers-reduced-motion: reduce) {
  .lp-track.indeterminate .lp-fill { animation: none; width: 100%; opacity: .45; }
  .lp-fill { transition: none; }
}

/* ---------- Hero entrance stagger ----------
   Borrowed technique, not code: motion.dev's "Editorial Stagger Hero" is a
   Motion-for-React component, and this app is vanilla JS — so the idea (an
   orchestrated entrance rather than six tiles popping in together) is rebuilt
   in plain CSS with zero runtime cost.

   Deliberately restrained. This is a storefront, not a landing page: the job is
   to make the mosaic feel composed for ~400ms and then get out of the way of
   someone scanning prices. Short duration, small travel, no scroll-linking. */
.hero-tile {
  animation: heroRise 460ms var(--cr-ease, cubic-bezier(.22,1,.36,1)) backwards;
  animation-delay: calc(var(--hero-i, 0) * 55ms);
}
@keyframes heroRise {
  from { opacity: 0; transform: translateY(14px) scale(.985); }
  to   { opacity: 1; transform: none; }
}

/* The CTA arrow already nudges on hover; give the whole tile a touch of lift so
   the mosaic reads as interactive rather than decorative. */
.hero-tile { transition: transform 220ms var(--cr-ease, ease), box-shadow 220ms var(--cr-ease, ease); }
@media (hover: hover) {
  .hero-tile:hover { transform: translateY(-3px); }
}

/* Motion is an enhancement; the layout must be complete without it. */
@media (prefers-reduced-motion: reduce) {
  .hero-tile { animation: none; transition: none; }
  .hero-tile:hover { transform: none; }
}

/* Screen-reader-only. Used by the SEO <h1>: real text for crawlers and assistive
   tech, no visual change. Clip-based, not display:none — hidden elements are
   ignored by both. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* Server-rendered deal list. Visible only for the moment before the interactive
   grid replaces it, so it is deliberately plain — matching the real card design
   would be wasted CSS for content that is removed on hydration. */
#ssrDeals { max-width: 1180px; margin: 0 auto; padding: 1.25rem; }
#ssrDeals h2 { font-size: 1.05rem; margin: 0 0 .6rem; }
#ssrDeals .ssr-list { list-style: none; margin: 0; padding: 0; display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: .5rem .9rem; }
#ssrDeals .ssr-deal { font-size: .82rem; line-height: 1.45; }
#ssrDeals .ssr-brand { opacity: .7; }
#ssrDeals .ssr-off { color: #b91c1c; font-weight: 600; }
#ssrDeals .ssr-code { color: #047857; font-weight: 600; }

/* ---- Referral welcome (celebration on opening a ?referid= link) ---- */
.ref-welcome {
  position: fixed; inset: 0; z-index: 4000;
  display: flex; align-items: center; justify-content: center; padding: 20px;
  background: rgba(17, 26, 34, 0);
  transition: background .26s ease;
}
.ref-welcome.is-open { background: rgba(17, 26, 34, .55); }
.ref-confetti { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.ref-welcome-card {
  position: relative; width: 100%; max-width: 400px; background: #fff;
  border-radius: 22px; padding: 30px 26px 22px; text-align: center;
  box-shadow: 0 24px 60px -20px rgba(17, 26, 34, .5);
  transform: translateY(16px) scale(.94); opacity: 0;
  transition: transform .3s cubic-bezier(.2,.8,.2,1), opacity .3s ease;
}
.ref-welcome.is-open .ref-welcome-card { transform: none; opacity: 1; }
.ref-welcome-close {
  position: absolute; top: 12px; right: 14px; border: 0; background: transparent;
  font-size: 26px; line-height: 1; color: #9aa5b1; cursor: pointer; padding: 4px;
}
.ref-welcome-close:hover { color: #46525f; }
.ref-welcome-badge {
  font-size: 52px; line-height: 1; margin-bottom: 12px;
  animation: refPop .5s cubic-bezier(.2,1.3,.4,1) both;
}
@keyframes refPop { from { transform: scale(0) rotate(-18deg); } to { transform: scale(1) rotate(0); } }
.ref-welcome-title {
  font-size: 22px; font-weight: 800; letter-spacing: -.01em; color: #121a22;
  margin: 0 0 8px; line-height: 1.2;
}
.ref-welcome-sub { font-size: 14.5px; line-height: 1.55; color: #46525f; margin: 0 0 20px; }
.ref-welcome-cta {
  display: block; width: 100%; border: 0; cursor: pointer;
  background: #1E5EF0; color: #fff; font-size: 15px; font-weight: 700;
  padding: 14px 20px; border-radius: 100px; transition: background .15s ease, transform .1s ease;
}
.ref-welcome-cta:hover { background: #1848c0; }
.ref-welcome-cta:active { transform: scale(.98); }
.ref-welcome-later {
  display: block; width: 100%; border: 0; background: transparent; cursor: pointer;
  color: #78848f; font-size: 13.5px; font-weight: 600; padding: 12px 0 2px;
}
.ref-welcome-later:hover { color: #46525f; }
@media (prefers-reduced-motion: reduce) {
  .ref-welcome-card, .ref-welcome-badge { transition: none; animation: none; transform: none; opacity: 1; }
}

/* ---- Top Deals editorial hero (DealSeek-style treatment) ---- */
/* Full-bleed GOLD gradient band that fades down into the deal grid, matching
   DealSeek's Top Deals page. Negative margins pull it to the content edges so it
   reads as a background wash, not a contained card; the fade-to-transparent at
   the bottom lets the first row of deals sit on the tail of the gradient. */
.td-hero {
  margin: -4px -20px 12px;
  padding: 30px 24px 44px;
  border: 0;
  border-radius: 0;
  background:
    radial-gradient(90% 130% at 18% -20%, #F7D98C 0%, rgba(247,217,140,0) 55%),
    linear-gradient(180deg, #FCEBB4 0%, #FEF6D9 40%, rgba(255,251,240,0) 100%);
}
@media (min-width: 1100px) { .td-hero { margin-left: 0; margin-right: 0; border-radius: 18px; } }
.td-crumbs {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 13px; color: #94a0ac; margin-bottom: 14px;
}
.td-crumb-home {
  border: 0; background: transparent; color: #94a0ac; font: inherit; cursor: pointer; padding: 0;
}
.td-crumb-home:hover { color: #1E5EF0; text-decoration: underline; }
.td-crumb-sep { color: #cbd3db; }
.td-crumb-current { color: #46525f; font-weight: 600; }
.td-hero-title {
  margin: 0 0 8px;
  font-size: clamp(30px, 5.2vw, 46px);
  font-weight: 800; letter-spacing: -0.025em; line-height: 1.04; color: #121a22;
}
.td-hero-title em {
  font-style: italic; font-weight: 800;
  color: #E0A012;
  padding-right: 2px;
}
.td-hero-sub {
  margin: 0; font-size: clamp(14px, 2vw, 16.5px); line-height: 1.5;
  color: #5a6470; max-width: 60ch;
}
@media (max-width: 640px) { .td-hero { padding: 20px 16px 18px; border-radius: 14px; } }

/* ---- Price-history sparkline (deal modal) ---- */
.modal-price-history { margin: 6px 0 2px; padding: 12px 14px; background: #f7f9fb; border: 1px solid #eef1f5; border-radius: 12px; }
.ph-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.ph-title { font-size: 12.5px; font-weight: 700; color: #46525f; }
.ph-days { color: #9aa5b1; font-weight: 500; }
.ph-low-badge { font-size: 11px; font-weight: 700; color: #1c9765; background: rgba(28,151,101,.12); padding: 3px 9px; border-radius: 100px; }
.ph-svg { width: 100%; height: 74px; display: block; }
.ph-grid { stroke: #d9e0e7; stroke-width: 1; stroke-dasharray: 3 3; vector-effect: non-scaling-stroke; }
.ph-area { stroke: none; }
.ph-line { fill: none; stroke: #1E5EF0; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.ph-dot { fill: #1E5EF0; stroke: #fff; stroke-width: 1.5; }
.ph-dot.is-low { fill: #1c9765; }
.ph-legend { display: flex; gap: 16px; margin-top: 8px; font-size: 12px; color: #78848f; }
.ph-legend b { color: #121a22; font-variant-numeric: tabular-nums; font-weight: 700; }
