/* static/style.css -- deliberately simple. Two-column layout via
   flexbox: .main-content grows to fill available space, .sidebar
   stays a fixed width and ends up on the right since it comes
   second in HTML source order (flex items lay out in document
   order by default).

   Background is ivory (a warm, slightly off-white), borders
   throughout are gainsboro (a neutral light gray). These don't
   clash -- gainsboro is desaturated/neutral, not competing with
   ivory's warm tint the way two saturated colors might -- but this
   is a color-theory judgment, not something visually confirmed;
   worth a real look once it's actually rendered. */

body {
  font-family: system-ui, sans-serif;
  margin: 0;
  padding: 1rem 2rem;
  color: #222;
  background: lightpink;
}

h1 {
  margin-bottom: 0.5rem;
}

.tagline {
  color: midnightblue;
  font-size: 0.95rem;
  margin-top: 0;
  margin-bottom: 1.5rem;
}

/* Navbar -- plain horizontal row of links, no dropdowns/mobile
   handling yet. Fine for three links; worth revisiting once there's
   enough here to need a real menu. */
.navbar {
  display: flex;
  gap: 1.5rem;
  padding-bottom: 1rem;
  margin-bottom: 1rem;
  border-bottom: 1px solid black;
}

.navbar a {
  text-decoration: none;
  color: #6b0075;
  font-weight: 600;
}

.navbar a:hover {
  color: #0008fc;
}

/* Plain HTML form, GET to /search -- works with zero JS. Centered
   via margin auto on a max-width block, not flex/grid, since it's
   the only thing that needs centering on its own line. flex-wrap so
   the checkbox label doesn't force the bar wider than intended on
   narrow viewports. */
.search-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.5rem;
  max-width: 600px;
  margin: 0 auto 1rem auto;
}

.search-bar input[type="text"] {
  flex: 1;
  min-width: 150px;
  padding: 0.5rem 0.75rem;
  font-size: 1rem;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.search-bar label {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.85rem;
  color: #d603e1;
  white-space: nowrap;
}

.search-bar button {
  padding: 0.5rem 1rem;
  font-size: 1rem;
  border: none;
  border-radius: 4px;
  background: #e605fb;
  color: white;
  cursor: pointer;
}

/* The whole filter/sort/search form's top row -- text input, the
   within checkbox, sort/page-size selects, submit button. */
.search-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}

/* flex: 0 1 280px, not flex: 1 -- flex: 1 was letting this grow to
   consume ALL leftover space in the row (checkbox + sort select +
   button take up some, this ate the rest), which on the wide
   .search-main column made it look enormous. The homepage's search
   bar looks normal-sized because ITS container has max-width: 600px
   bounding the whole bar -- .search-controls has no such limit, so
   the input itself needs its own cap instead. flex-shrink stays 1
   so it can still shrink on narrow/mobile screens. */
.search-controls input[type="text"] {
  flex: 0 1 280px;
  min-width: 200px;
  padding: 0.5rem 0.75rem;
  font-size: 1rem;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.search-controls label,
.sort-label {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.85rem;
  color: #d603e1;
  white-space: nowrap;
}

.pagination-row {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  margin-top: 1.5rem;
}

.page-size-label {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.85rem;
  color: #d603e1;
}

.search-controls select {
  padding: 0.4rem 0.5rem;
  font-size: 0.9rem;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.search-controls button {
  padding: 0.5rem 1rem;
  font-size: 1rem;
  border: none;
  border-radius: 4px;
  background: #c0392b;
  color: white;
  cursor: pointer;
}

/* Left filter panel + results, side by side. */
.search-layout {
  display: flex;
  gap: 2rem;
  align-items: flex-start;
}

.filter-panel {
  flex: 0 0 220px;
}

.filter-section {
  margin-bottom: 1.5rem;
}

.filter-section h3 {
  font-size: 0.9rem;
  margin-bottom: 0.5rem;
}

/* 15 visible items, scrolls beyond that -- the heading above stays
   outside this container (see filter-panel.lisp) so it's always
   visible even while the option list itself scrolls. Height is an
   ESTIMATE based on each .filter-option's font-size + margin-bottom
   (roughly 1.55rem per row, x 15), not a measured/rendered value --
   worth eyeballing once this is actually visible and adjusting if
   it's noticeably off from exactly 15 rows. */
.filter-options-list {
  max-height: 23rem;
  overflow-y: auto;
  padding-right: 0.5rem;
}

.filter-option {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
  margin-bottom: 0.35rem;
}

.price-range-inputs {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.price-range-inputs input {
  width: 4.5rem;
  padding: 0.3rem 0.4rem;
  font-size: 0.85rem;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.price-range-sep {
  color: #666;
}

.search-main {
  flex: 1;
  min-width: 0;
}

/* Numbered pagination -- these are submit BUTTONS now (see
   components/pagination.lisp), not links, so they need their own
   reset away from default browser button chrome to read the same
   as the old link-based version did. */
.pagination {
  display: flex;
  gap: 0.75rem;
  align-items: center;
}

.pagination-link,
.pagination-prev,
.pagination-next {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: #c0392b;
  font-weight: 600;
  cursor: pointer;
}

.pagination-current {
  color: #222;
  font-weight: 700;
  text-decoration: underline;
}

.pagination-ellipsis {
  color: #999;
}

/* Top Categories / Top Brands / Top Retailers -- all three share
   this one set of classes now (see components/facet-grid.lisp),
   5 columns x 4 rows, thin gainsboro borders around each link
   rather than the earlier plain-text/no-chrome version. */
.facet-grid-section {
  margin-top: 0;
  margin-bottom: 2.5rem;
}

.facet-grid-section h2 {
  font-size: 1rem;
  font-weight: 600;
  color: #f704f3;
  margin-bottom: 1rem;
}

.facet-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0.5rem;
}

.facet-grid-item {
  display: block;
  padding: 0.5rem 0.75rem;
  border: 1px solid gainsboro;
  border-radius: 4px;
  color: #1a5276;
  text-decoration: none;
  font-size: 0.85rem;
  text-align: center;
  background: white;
}

.facet-grid-item:hover {
  background: gainsboro;
}

.facet-grid-see-all {
  color: #d603e1;
  font-style: italic;
}

.page-layout {
  display: flex;
  gap: 2rem;
  align-items: flex-start;
}

.main-content {
  flex: 1;
}

.sidebar {
  flex: 0 0 280px;
}

/* Newest Promotional Offers -- 1 column, up to 5 rows, different
   shape from the facet-grid tables above so it gets its own
   styling. Currently always shows the empty state (see
   components/offers-table.lisp) -- the list/see-more styling below
   is ready for when real offer data exists, not yet exercised. */
.offers-section {
  margin-top: 0;
  margin-bottom: 2.5rem;
}

.offers-section h2 {
  font-size: 1rem;
  font-weight: 600;
  color: #f704f3;
  margin-bottom: 1rem;
}

.offers-list {
  list-style: none;
  padding: 0;
  margin: 0 0 0.75rem 0;
}

.offers-list li {
  padding: 0.5rem 0.75rem;
  border: 1px solid gainsboro;
  border-radius: 4px;
  margin-bottom: 0.5rem;
  background: white;
}

.offers-empty {
  color: #666;
  font-style: italic;
}

.offers-see-more {
  color: #1a5276;
  font-size: 0.9rem;
  text-decoration: none;
}

.offers-see-more:hover {
  text-decoration: underline;
}

/* Brands / Retailers full alphabetical listing pages -- also used
   by pages/categories.lisp now for the same 4-column layout, even
   though categories is ranked, not alphabetical (see that file's
   own comment on the class name being a slight misnomer there). */
.alpha-list {
  list-style: none;
  padding: 0;
  margin: 0;
  columns: 4;
  gap: 2rem;
}

.alpha-list li {
  margin-bottom: 0.5rem;
  break-inside: avoid;
}

.alpha-list a {
  color: #f704f3;
  text-decoration: none;
}

.alpha-list a:hover {
  text-decoration: underline;
}

/* Alphabetical-range bottom nav (Brands/Retailers) -- reuses the
   same visual language as the numbered .pagination (link color,
   current-page styling), just a different set of labels. */
.alpha-pagination {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: 2rem;
}

.alpha-pagination a {
  color: #c0392b;
  text-decoration: none;
  font-weight: 600;
}

.alpha-pagination-current {
  color: #222;
  font-weight: 700;
  text-decoration: underline;
}

/* Search results / sales listing -- these reuse .deal-item's card
   styling (see below) but need their own list container, since
   they're plain vertical lists rather than the widget's numbered
   sidebar list. */
.search-results,
.categories-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

/* /stats -- deliberately plain, this is an internal tool, not a
   polished public page. */
.stats-section {
  margin-bottom: 2rem;
}

.stats-section h2 {
  font-size: 1rem;
  margin-bottom: 0.5rem;
}

.stats-table {
  border-collapse: collapse;
  font-size: 0.85rem;
}

.stats-table td {
  padding: 0.3rem 1rem 0.3rem 0;
  border-bottom: 1px solid #eee;
}

.stats-empty {
  color: #666;
  font-style: italic;
}

.stats-total {
  color: #d603e1;
  margin-bottom: 2rem;
}

.search-results li {
  margin-bottom: 1rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid #eee;
}

.categories-list li {
  margin-bottom: 0.5rem;
}

.result-count {
  color: #d603e1;
  margin-top: -1rem;
}

.top-deals-widget {
  border: 1px solid #ddd;
  border-radius: 6px;
  padding: 1.15rem 1rem 1rem 1rem;
  background: #fafafa;
}

.top-deals-widget h2 {
  margin-top: 0;
  font-size: 1.1rem;
}

.top-deals-widget ol {
  list-style: decimal;
  padding-left: 1.25rem;
  margin: 0 0 1rem 0;
}

.top-deals-widget li {
  margin-bottom: 0.4rem;
}

/* Direct-child selector -- targets ONLY the "See more" link (a
   direct child of .top-deals-widget), not the deal-item links
   nested inside <li> further down. Without the >, this rule would
   also apply to those too, which isn't the intent. */
.top-deals-widget > a {
  font-size: 0.9rem;
}

/* deal-item is a plain container now, not a link itself -- image,
   name, and brand are three SEPARATE links inside it, each going
   somewhere different, which is why the link-reset styling lives on
   THEM below rather than on this outer div. Flex row: fixed-size
   image on the left, everything else (.deal-details) filling the
   rest. */
.deal-item {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
}

.deal-image-link {
  display: block;
  flex-shrink: 0;
}

.deal-image {
  width: 48px;
  height: 48px;
  object-fit: cover;
  border-radius: 4px;
  display: block;
}

.deal-details {
  flex: 1;
  /* Flex items default to min-width:auto, which can prevent them
     shrinking below their content's natural width -- this override
     is what actually lets long product names wrap/truncate inside
     the sidebar instead of forcing the row wider than it should
     be. Easy to miss; worth the comment. */
  min-width: 0;
}

.deal-name {
  display: block;
  font-weight: 600;
  font-size: 0.9rem;
  line-height: 1.3;
  color: inherit;
  text-decoration: none;
}

.deal-name:hover {
  text-decoration: underline;
}

.deal-brand {
  display: block;
  font-size: 0.8rem;
  color: #d603e1;
  text-decoration: none;
}

.deal-brand:hover {
  text-decoration: underline;
}

/* Original price, sale price, and discount% all flow on ONE line
   now -- no <br> between them in the markup, and .deal-discount is
   an inline span here (not a block div like it used to be), which
   is what actually keeps it on the same line as the prices. */
.deal-prices {
  margin-top: 0.25rem;
  font-size: 0.85rem;
}

.original-price {
  color: #666;
}

.sale-price {
  color: #c0392b;
}

.regular-price {
  color: #222;
  font-weight: 600;
}

.deal-discount {
  color: #27ae60;
  font-weight: 600;
}

.site-footer {
  margin-top: 4rem;
  padding-top: 1.5rem;
  border-top: 1px solid #ddd;
  color: #666;
  font-size: 0.8rem;
  text-align: center;
}

.site-footer a {
  color: #666;
}

.built-with {
  margin-bottom: 0.25rem;
}

.built-with a {
  margin-left: 0.15rem;
}

.lisp-logo {
  height: 0.95em;
  width: auto;
  vertical-align: middle;
  position: relative;
  top: -0.05em;
}

/* Product detail pages -- gallery + info side by side on desktop.
   Price/brand/category/retailer/type classes below deliberately
   REUSE existing classes (.original-price, .sale-price,
   .regular-price, .deal-discount from deal-item's price display)
   rather than redefining colors -- none of those set their own
   font-size, only color/weight, so bumping .product-price's
   font-size here correctly cascades a bigger size to all of them
   without touching deal-item's own compact-card sizing at all. */

.product-detail {
  display: flex;
  gap: 2.5rem;
  align-items: flex-start;
  margin-top: 1rem;
}

.product-gallery {
  flex: 0 0 29%;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.gallery-main {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

.gallery-main-image {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  border: 1px solid gainsboro;
  border-radius: 4px;
  cursor: pointer;
  background: white;
}

.gallery-main-prev,
.gallery-main-next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  background: rgba(255, 255, 255, 0.85);
  border: 1px solid gainsboro;
  border-radius: 50%;
  width: 2.5rem;
  height: 2.5rem;
  font-size: 1.2rem;
  cursor: pointer;
  z-index: 1;
}

.gallery-main-prev {
  left: 0.5rem;
}

.gallery-main-next {
  right: 0.5rem;
}

.gallery-main-prev:hover,
.gallery-main-next:hover {
  background: white;
  border-color: #c0392b;
}

/* Horizontal scroll rather than wrapping -- a product with many
   alt images gets a scrollable strip instead of growing the
   gallery's height unpredictably. */
.gallery-thumbs {
  display: flex;
  gap: 0.5rem;
  overflow-x: auto;
}

.gallery-thumb {
  width: 4rem;
  height: 4rem;
  object-fit: cover;
  border: 1px solid gainsboro;
  border-radius: 4px;
  cursor: pointer;
  flex-shrink: 0;
  opacity: 0.7;
}

.gallery-thumb:hover {
  opacity: 1;
  border-color: #c0392b;
}

/* .active is toggled by the gallery script onto whichever thumbnail
   matches the currently-displayed main image -- also present on the
   first thumbnail directly in the initial HTML (see
   render-product-gallery's own comment), so this is correct even
   before the script runs. */
.gallery-thumb.active {
  opacity: 1;
  border-color: #c0392b;
  border-width: 2px;
}

/* Hidden by default (display:none) -- the lightbox script sets
   style.display = 'flex' to show it, which is what actually makes
   the align-items/justify-content below take effect (they're no-ops
   while display is none). */
.lightbox-overlay {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.9);
  z-index: 1000;
  align-items: center;
  justify-content: center;
  gap: 1rem;
}

.lightbox-image {
  max-width: 80%;
  max-height: 85vh;
  object-fit: contain;
  transition: transform 0.1s ease;
}

.lightbox-close {
  position: absolute;
  top: 1.5rem;
  right: 1.5rem;
  background: none;
  border: none;
  color: white;
  font-size: 2rem;
  cursor: pointer;
  line-height: 1;
}

.lightbox-nav {
  background: none;
  border: none;
  color: white;
  font-size: 3rem;
  cursor: pointer;
  padding: 0 1rem;
  line-height: 1;
}

.lightbox-nav:hover {
  color: #c0392b;
}

.product-info {
  flex: 1;
  min-width: 0;
}

.product-info h1 {
  margin-top: 0;
  margin-bottom: 0.75rem;
}

.buy-now-button {
  display: inline-block;
  padding: 0.75rem 1.5rem;
  font-size: 1.1rem;
  font-weight: 600;
  background: #c0392b;
  color: white;
  text-decoration: none;
  border-radius: 4px;
  margin-bottom: 1rem;
}

.buy-now-button:hover {
  background: #a93226;
}

.product-price {
  font-size: 1.2rem;
  margin-bottom: 1.5rem;
}

.product-meta p {
  margin: 0.4rem 0;
  font-size: 0.9rem;
}

.product-meta a {
  color: #1a5276;
  text-decoration: none;
}

.product-meta a:hover {
  text-decoration: underline;
}

.product-description {
  margin-top: 1.5rem;
}

.product-description h2 {
  font-size: 1rem;
  font-weight: 600;
  color: #d603e1;
  margin-bottom: 0.5rem;
}

/* Similar Products -- reuses .deal-item's own card styling
   unchanged (see that component), just placed in a wider grid than
   its usual narrow-sidebar context. */
.similar-products-section {
  margin-top: 3rem;
  padding-top: 2rem;
  border-top: 1px solid #ddd;
}

.similar-products-section h2 {
  font-size: 1.1rem;
  font-weight: 600;
  color: #d603e1;
  margin-bottom: 1rem;
}

.similar-products-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}

/* The second grid of 6 (items 7-12) -- hidden via class, not just
   the first-load inline style trick used elsewhere tonight, since
   the toggle script itself flips this same class rather than
   touching style.display directly. Applied directly in the initial
   HTML too (see render-similar-products), so it's correctly hidden
   even before the toggle script runs. */
.similar-products-hidden {
  display: none;
}

/* margin-top only applies when .similar-products-hidden is NOT
   present (i.e. once revealed) -- when hidden, display:none makes
   margin irrelevant anyway, so this never causes a visible gap
   while collapsed. */
.similar-products-grid + .similar-products-grid:not(.similar-products-hidden) {
  margin-top: 1.5rem;
}

.similar-products-actions {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-top: 1.5rem;
}

.similar-products-see-more {
  background: none;
  border: 1px solid gainsboro;
  border-radius: 4px;
  padding: 0.5rem 1rem;
  font-size: 0.9rem;
  color: #c0392b;
  font-weight: 600;
  cursor: pointer;
}

.similar-products-see-more:hover {
  background: gainsboro;
}

.similar-products-see-all {
  color: #1a5276;
  font-size: 0.9rem;
  text-decoration: none;
}

.similar-products-see-all:hover {
  text-decoration: underline;
}

/* ===============================================================
   MOBILE (max-width: 768px)
   Everything above this point is untouched on desktop -- these
   rules only activate on narrow screens. The main problem being
   solved: several layouts use fixed pixel widths and multi-column
   grids that make sense with real screen space (a 280px sidebar
   next to main content, 5-column facet grids, 4-column alpha
   listings) but would force horizontal scrolling or cram things
   unreadably small on a ~375px phone. Below, those collapse to
   single-column stacks or fewer columns instead.
   =============================================================== */

@media (max-width: 768px) {
  html, body {
    overflow-x: hidden;
  }

  body {
    padding: 1rem;
  }

  .navbar {
    flex-wrap: wrap;
    gap: 1rem;
  }

  /* Homepage sidebar+main, and search page's filter-panel+results --
     side-by-side flex rows with a fixed-width column -- both stack
     to single-column on mobile instead. Product detail's
     gallery+info gets the same treatment. */
  .page-layout,
  .search-layout,
  .product-detail {
    flex-direction: column;
  }

  .sidebar,
  .filter-panel,
  .product-gallery {
    flex: 1 1 auto;
    width: 100%;
  }

  /* 5-column facet grids (Top Categories/Brands/Retailers) and
     4-column alphabetical listings (Brands/Retailers full pages) --
     both would be unreadably cramped at 5 or 4 columns on a phone
     screen. */
  .facet-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .alpha-list {
    columns: 2;
  }

  .similar-products-grid {
    grid-template-columns: 1fr;
  }

  /* Slightly larger tap targets -- finger accuracy is worse than
     mouse precision, so filter checkboxes and pagination links get
     a bit more breathing room specifically on mobile. Lightbox
     nav/close buttons get the same treatment -- easy to fat-finger
     otherwise. */
  .filter-option {
    margin-bottom: 0.6rem;
  }

  .pagination-link,
  .pagination-prev,
  .pagination-next {
    padding: 0.3rem 0.5rem;
  }

  .lightbox-nav,
  .lightbox-close {
    padding: 0.5rem 1rem;
  }
}

/* "Visit retailer" second link -- Top Retailers grid (see
   components/facet-grid.lisp's extra-link-fn) and the /retailers
   alphabetical list (pages/retailers.lisp) both get one, styled
   distinctly from the main facet link so it doesn't read as part of
   the same click target. */
.facet-grid-item-wrapper {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.facet-grid-visit-link {
  display: block;
  text-align: center;
  font-size: 0.75rem;
  color: #062c16;
  text-decoration: none;
}

.facet-grid-visit-link:hover {
  text-decoration: underline;
}

.alpha-list-visit-link {
  color: #062c16;
  font-size: 0.8rem;
  text-decoration: none;
}

.alpha-list-visit-link:hover {
  text-decoration: underline;
}
