/* ==========================================================================
   LANE: homepage
   Owner: shinari-opencart-code-42 (from shinari-opencart-code-d7, 2026-09-26)
   --------------------------------------------------------------------------
   Loaded ONLY on the homepage, via document->addStyle() from
   modifications/shinari-home-categories.ocmod.xml. It is deliberately not
   linked from header.twig, for the same reason shinari-product.css is not: a
   global <link> would download it on every page of the store for rules that
   only ever apply here.

   An earlier version of this file also hid the main nav bar on the homepage,
   which made the homepage-only scoping load-bearing rather than merely tidy.
   That was reverted at the user's direction on 2026-09-25 - the bar is back on
   every page - so the scoping is now just the ordinary reason: .sh-cats renders
   nowhere else, and shinari.css should not carry rules that can never apply to
   the page being looked at. Keeping the file also avoids editing shinari.css,
   which other lanes write to constantly.

   Load order is stylesheet.css -> shinari.css -> (styles loop) -> this file, so
   it layers on top of both and inherits the :root tokens from shinari.css. It
   defines no tokens of its own - per FRONTEND-LANES.md 4.4 the token block is
   shared, and a private palette here is how two pages start drifting apart.

   The .sh-cats block was moved here from shinari.css on 2026-09-25. It only
   ever rendered on the homepage, so a homepage-only file is where it belongs.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Browse by category - compact horizontal cards
   Name on the left, a small product photo on the right, on a grey band.
   Replaced the square photo cards on 2026-09-26 at the user's direction:
   those were 335 x 308 at 1440 and put 8 categories across 676px, more than
   a laptop screen, with a 300px photo doing a thumbnail's job. The category
   NAME is what a buyer scans for; the photo only confirms it. So the name
   leads and the photo shrinks to a recognisable 88px.

   CSS only. The markup in home.twig is unchanged - figure first, meta second
   inside the link - and `order` moves the figure to the right. Reordering
   inside a single <a> changes no focus order and no reading order that
   matters: the image has an empty alt, so the name is all a screen reader
   announces either way.

   Columns follow the category COUNT (homepage teardown finding 4: no row
   left half empty). home.twig picks the desktop count and marks the grid:
     --4  when the count divides by 4 (8 fitted 4 x 2 until 2026-09-29)
     --3  when it divides by 3 instead - 9 since Industrial Filters was
          added, so 3 x 3 rather than 4 | 4 | 1
     --5  when it divides by 5 instead (at 1200px and up only)
   plus --odd for an odd count, so where the grid is two across the last
   card spans the row instead of standing alone. Phones stay one per row.
   -------------------------------------------------------------------------- */

/* The grey band is contained, not full-bleed. A 100vw breakout from inside
   #content would bring back the horizontal scrollbar the page-width lane
   removed (FRONTEND-LANES.md 4c). A contained band reads the same. */
.sh-cats {
  margin: 26px 0 8px;
  padding: 26px 24px 28px;
  background: var(--shinari-surface-alt);
  border-radius: var(--shinari-radius);
}

.sh-cats__title {
  font-size: 22px;
  font-weight: 700;
  text-align: center;
  margin: 0 0 18px;
  padding: 0;
  border-bottom: 0;
}

.sh-cats__grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
}

.sh-cats__grid--3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* Five across only where five cards still leave a name room beside its
   photo: from 1200px. Below that a --5 grid keeps four (and then two). */
@media (min-width: 1200px) {
  .sh-cats__grid--5 {
    grid-template-columns: repeat(5, minmax(0, 1fr));
  }
}

/* Grid tracks floor at min-content, so a long unbroken category name would
   otherwise refuse to shrink and push the grid wider than its container. */
.sh-cats__item {
  min-width: 0;
}

/* The row. Every flex property is stated rather than inherited: this selector
   has carried two different layouts before this one, and a card should not
   depend on a rule's absence somewhere else. height:100% plus the grid's
   default stretch makes every card in a row as tall as the tallest, so the
   one long name ("Abrasive, Grinding & Polishing Tools") does not leave its
   card sticking out below its neighbours. */
.sh-cats__link {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  height: 100%;
  min-height: 92px;
  padding: 14px 16px;
  border: 1px solid var(--shinari-rule);
  border-radius: var(--shinari-radius);
  background: var(--shinari-surface);
  box-shadow: var(--shinari-shadow);
  color: var(--shinari-ink);
  text-decoration: none;
  overflow: hidden;
  transition: border-color .14s ease, box-shadow .14s ease;
}

/* No lift and no zoom - the listing tile removed both for the same reason.
   Border, shadow and an underlined name say "this is the one you are
   pointing at"; the underline also marks it as a link for anyone who cannot
   tell a border colour change apart. */
.sh-cats__link:hover,
.sh-cats__link:focus {
  border-color: var(--shinari-primary);
  box-shadow: var(--shinari-shadow-raised);
  background: var(--shinari-surface);
  color: var(--shinari-ink);
  text-decoration: none;
}

.sh-cats__link:hover .sh-cats__name,
.sh-cats__link:focus .sh-cats__name {
  color: var(--shinari-primary-dark);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.sh-cats__link:focus-visible {
  outline: 2px solid var(--shinari-primary);
  outline-offset: 1px;
}

/* The photo, moved to the right. 88px wide at the thumbnail's own 4:3, so the
   176x132 image OpenCart pads to that ratio fills the box with no second
   letterbox inside it. No border and no background of its own: most supplier
   shots are already on white, and a framed box would print a rectangle
   inside every card. */
.sh-cats__figure {
  order: 2;
  flex: 0 0 88px;
  width: 88px;
  aspect-ratio: 4 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  background: transparent;
  overflow: hidden;
}

.sh-cats__img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}

/* Name and count, stacked, on the left. margin-top is reset because the
   previous card layout used margin-top:auto to pin this row to the bottom. */
.sh-cats__meta {
  order: 1;
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 6px;
  margin: 0;
  padding: 0;
  background: transparent;
}

/* No line clamp. The previous layout clamped to two lines and had to reserve
   the second line's height on every card; here the row stretches instead, so
   the long name can simply wrap. Nothing a buyer scans for gets an ellipsis. */
.sh-cats__name {
  min-width: 0;
  max-width: 100%;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--shinari-ink);
}

/* Product count - real data from the OCMOD, so it stays, but quieter than
   before: it is secondary to the name. Tabular digits so the numbers line up
   down a column. */
.sh-cats__count {
  flex: 0 0 auto;
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--shinari-muted);
  background: var(--shinari-surface-alt);
  border: 1px solid var(--shinari-rule);
  border-radius: 10px;
  padding: 0 8px;
  line-height: 18px;
}

/* --------------------------------------------------------------------------
   Narrower viewports
   -------------------------------------------------------------------------- */

/* Small laptops, 992-1199px. Bootstrap fixes the container at 970px here, so
   four cards come out ~213px wide. With the full 88px photo that left the name
   78px - measured at 1000px, "Components", "Pneumatic" and "Lubricants" each
   overflowed their box and ran into the photo, and the long name wrapped to
   five lines. A 56px photo and tighter padding give the name ~123px: every
   word fits and the longest name takes four lines, inside the same card
   height as the rest of its row. Four columns kept, so 8 still fill 4 x 2. */
@media (min-width: 992px) and (max-width: 1199px) {
  .sh-cats__link {
    gap: 10px;
    padding: 12px;
  }

  .sh-cats__figure {
    flex-basis: 56px;
    width: 56px;
  }

  .sh-cats__name {
    font-size: 14px;
  }
}

/* Tablets: two across. Four horizontal cards in a 720-990px column leave the
   name about 100px beside its photo, and three would end 8 categories on a
   short row. Two gives each name room and still fills every row. */
@media (max-width: 991px) {
  .sh-cats__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* An odd count on a two-across grid: the last card takes the whole row,
     so the grid ends square instead of on one lone half-width card. */
  .sh-cats__grid--odd:not(.sh-cats__grid--3) > .sh-cats__item:last-child {
    grid-column: 1 / -1;
  }
}

/* Tablets with a --3 grid: three across keeps 9 at 3 x 3. The cards come out
   ~215px wide at 768px, the same as four across at 992-1199, so they take
   the same compact card: a 56px photo, tighter padding, 14px names. */
@media (min-width: 768px) and (max-width: 991px) {
  .sh-cats__grid--3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .sh-cats__grid--3 .sh-cats__link {
    gap: 10px;
    padding: 12px;
  }

  .sh-cats__grid--3 .sh-cats__figure {
    flex-basis: 56px;
    width: 56px;
  }

  .sh-cats__grid--3 .sh-cats__name {
    font-size: 14px;
  }
}

@media (max-width: 767px) {
  .sh-cats {
    padding: 18px 12px 20px;
  }

  .sh-cats__title {
    font-size: 19px;
    margin-bottom: 14px;
  }

  .sh-cats__grid {
    gap: 10px;
  }

  /* Two across for every count here, --3 included. */
  .sh-cats__grid--3 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .sh-cats__grid--odd > .sh-cats__item:last-child {
    grid-column: 1 / -1;
  }

  .sh-cats__link {
    min-height: 76px;
    padding: 10px 12px;
    gap: 10px;
  }

  .sh-cats__figure {
    flex-basis: 64px;
    width: 64px;
  }

  .sh-cats__name {
    font-size: 14px;
  }
}

/* Phones: one per row. Two horizontal cards side by side at 390px leave the
   name under 100px next to its photo, which breaks "Abrasive, Grinding &
   Polishing Tools" over four lines. One per row is still far shorter than
   the old two-across photo grid, because each row is ~76px, not ~190px. */
@media (max-width: 575px) {
  .sh-cats__grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 6px;
  }

  /* Shorter rows. At 76px with a 64px photo each row carried ~20px of empty
     space above and below a two-line name block; 64px is what the name plus
     its count actually need, and still clears the 44px touch target. */
  .sh-cats__link {
    min-height: 64px;
    padding: 8px 12px;
  }

  .sh-cats__figure {
    flex-basis: 56px;
    width: 56px;
  }

  .sh-cats__meta {
    gap: 4px;
  }
}

/* --------------------------------------------------------------------------
   Slideshow and carousel controls
   Both sliders render on the homepage only, so their chrome lives here.
   Markup and behaviour: template/extension/module/shinari_slider_controls.twig.
   -------------------------------------------------------------------------- */

/* Centre the slide image. Stock gives each slide `text-center`, but the
   image is Bootstrap's .img-responsive - display:block - which text-align
   cannot move. That did not show while the container was a fixed 1170px,
   because the 1140px slideshow image filled it. Since the page-width lane let
   the container follow the window, the frame reaches 1368px at 1440 and
   1488px at 1920, and every slide sat hard left with a 228-348px white strip
   on the right (measured; reported by c4). Auto margins centre it. Carousel
   images are always narrower than their slot, so this is a no-op there.

   Deliberately NOT fixed by raising the Slideshow module past 1140 wide:
   every current banner is already padded with white inside its image (see
   WAITING-ON-CLIENT.md 7a), so a wider image would only add white - and
   bytes. That setting should rise with purpose-made artwork, not before. */
.swiper-viewport .swiper-slide > img,
.swiper-viewport .swiper-slide > a > img {
  margin-left: auto;
  margin-right: auto;
}

/* The pause / play button itself is styled in shinari.css ("sliders - pause
   control"), because the category-page banner uses it too and this file
   loads on the homepage only. What stays here is its effect on the dots,
   which only the homepage sliders have. */

@media (max-width: 767px) {
  /* Keep the dots clear of the button. The carousel's ten dots are ~210px
     wide; on a 320px phone, centred across the full row, the first one sat
     under the 44px button. Centring them in the space to its right fixes it,
     and at 390+ the shift is invisible. */
  .swiper-viewport .swiper-pagination {
    box-sizing: border-box;
    padding-left: 52px;
  }
}

/* A long dot row on a phone. OpenCart's dots are 11px with 5px either side,
   21px each: the brand-logo carousel's 18 need 378px, and beside the button a
   390px phone has 300 and a 320px one 230, so the row broke onto two lines
   (measured 2026-09-29). From 13 dots up, 8px dots 2px apart - 12px each,
   216px for 18 - keep it one row. From 19 up (the strip grew to 20 logos
   the same day), 7px dots 1.5px apart: 10px each, 200px for 20, and up to
   23 still fit at 320. The 8 and 10-dot sliders are untouched; a browser
   without :has() just wraps as before. */
@media (max-width: 575px) {
  .swiper-viewport .swiper-pagination:has(> .swiper-pagination-bullet:nth-child(13)) .swiper-pagination-bullet {
    width: 8px;
    height: 8px;
    margin: 0 2px;
  }

  .swiper-viewport .swiper-pagination:has(> .swiper-pagination-bullet:nth-child(19)) .swiper-pagination-bullet {
    width: 7px;
    height: 7px;
    margin: 0 1.5px;
  }
}

/* The arrows. Stock (swiper/css/opencart.css:39-58) keeps them at opacity 0,
   parked outside the box, until the pointer hovers the slider - so once the
   a11y module makes them focusable, a keyboard user would land on an
   invisible control. Reveal them whenever focus is anywhere inside the
   slider, exactly as hover does, and outline the one that has it.
   Specificity (0,3,0) beats stock's (0,2,0); no !important needed. */
.swiper-viewport:focus-within .swiper-button-prev {
  opacity: .7;
  left: 10px;
}

.swiper-viewport:focus-within .swiper-button-next {
  opacity: .7;
  right: 10px;
}

.swiper-viewport .swiper-button-prev:focus-visible,
.swiper-viewport .swiper-button-next:focus-visible,
.swiper-viewport .swiper-pagination-bullet:focus-visible {
  opacity: 1;
  outline: 2px solid var(--shinari-primary);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .swiper-viewport .swiper-button-prev,
  .swiper-viewport .swiper-button-next {
    transition: none;
  }
}

/* ==========================================================================
   service strip (c4)
   template/common/shinari_service_strip.twig - delivery, collection and
   quotes, under the category grid (homepage teardown finding 6). Every value
   in it comes from Settings; see the template's header. Lane c4; lane 42 owns
   the rest of this file.

   Quieter than the category cards above it on purpose: this answers
   questions, it is not somewhere to browse. No shadow, no band, and the text
   is a size smaller than the category names. Three across from 768px, one
   per row below that - on a phone each row is still a 44px+ touch target.
   ========================================================================== */
.sh-service {
  margin: 18px 0 8px;
}

.sh-service__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}

.sh-service__item {
  min-width: 0;
}

.sh-service__link {
  display: flex;
  align-items: center;
  gap: 12px;
  height: 100%;
  min-height: 64px;
  padding: 12px 14px;
  border: 1px solid var(--shinari-rule);
  border-radius: var(--shinari-radius);
  background: var(--shinari-surface);
  color: var(--shinari-ink);
  text-decoration: none;
  transition: border-color .14s ease;
}

.sh-service__link:hover,
.sh-service__link:focus {
  border-color: var(--shinari-primary);
  color: var(--shinari-ink);
  text-decoration: none;
}

.sh-service__link:hover .sh-service__name,
.sh-service__link:focus .sh-service__name {
  color: var(--shinari-primary-dark);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.sh-service__link:focus-visible {
  outline: 2px solid var(--shinari-primary);
  outline-offset: 1px;
}

.sh-service__icon {
  flex: 0 0 38px;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--shinari-primary-light);
  color: var(--shinari-primary-dark);
  font-size: 17px;
}

/* WhatsApp's own green, darkened to 4.5:1 on its tint so the glyph is not
   the only low-contrast thing on the strip. */
.sh-service__icon--whatsapp {
  background: #E7F6EC;
  color: #12743A;
  font-size: 20px;
}

.sh-service__text {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.sh-service__name {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--shinari-ink);
}

.sh-service__detail {
  font-size: 13px;
  line-height: 1.4;
  color: var(--shinari-muted);
  overflow-wrap: anywhere;
}

@media (max-width: 767px) {
  .sh-service__list {
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
  }

  .sh-service__link {
    min-height: 56px;
    padding: 10px 12px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .sh-service__link {
    transition: none;
  }
}
