/* ─────────────────────────────────────────────────────────────────────────
   Categories: a photographic mosaic of what people here actually trade.

   Was ten equal boxes, each an emoji and a word. Now each category is a real
   scene — a phone being repaired, wax-print fabric, a barber mid-cut, cocoa
   just harvested — so the list reads as places and people you know rather
   than a taxonomy.

   The photos come from sixteen different photographers, so they share one
   grade (a little less saturation, a little darker, a dark scrim at the
   foot) to read as a single set. A very slow pan-and-zoom keeps them alive
   without the weight of video on a phone's data plan.
   ───────────────────────────────────────────────────────────────────────── */

.cx { padding: clamp(80px, 10vw, 120px) 0; }
.cx-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 24px; flex-wrap: wrap; margin-bottom: clamp(28px, 3.5vw, 44px); }
.cx-head > div { max-width: 720px; }
.cx-head .sub { margin-bottom: 0; }
.cx-browse { color: var(--ink); text-decoration: none; font-weight: 600; font-size: 15px; display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.cx-browse::after { content: "→"; color: var(--lime); transition: transform .25s; }
.cx-browse:hover::after { transform: translateX(4px); }

/* Six columns, four rows on desktop: wide and narrow tiles alternate so no
   row repeats the one above it. `dense` packs anything the API adds later
   into the first free cell rather than leaving a hole. */
.cx-grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  grid-auto-rows: clamp(170px, 15vw, 220px);
  grid-auto-flow: dense;
  gap: 12px;
}
.cx-tile.w { grid-column: span 2; }

@media (max-width: 1000px) {
  .cx-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); grid-auto-rows: 180px; }
}
@media (max-width: 600px) {
  .cx-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-rows: 150px; gap: 10px; }
  .cx-tile.w { grid-column: span 1; }
  /* `cx-first`, not `lead`: styles.css already uses .lead for the hero
     paragraph, with margins that shrank this tile inside its cell. */
  .cx-tile.w.cx-first { grid-column: span 2; }
  /* The full-width lead leaves an odd number of half tiles whenever the total
     is even — sixteen today — and the last one sat alone beside an empty
     cell. It closes the grid at full width instead. Keyed to the count, so
     it switches itself off if the app's category list changes to odd. */
  .cx-tile.cx-first ~ .cx-tile:last-child:nth-child(even) { grid-column: span 2; }
}

/* ── Tile ────────────────────────────────────────────────────────────────── */

.cx-tile {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: 22px;
  color: #fff;
  text-decoration: none;
  background: #14161f;
  isolation: isolate;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .06);
  transition: box-shadow .35s, transform .35s;
}
.cx-tile:hover { box-shadow: inset 0 0 0 1px rgba(201, 238, 10, .55), 0 18px 40px rgba(0, 0, 0, .35); transform: translateY(-2px); }
.cx-tile:focus-visible { outline: 2px solid var(--lime); outline-offset: 3px; }

.cx-tile img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: -2;
  /* The shared grade: sixteen photographers, one set. */
  filter: saturate(.86) contrast(1.04) brightness(.8);
  transform-origin: var(--ox, 50%) var(--oy, 50%);
  transition: filter .5s;
}
.cx-tile:hover img { filter: saturate(1) contrast(1.04) brightness(.9); }

/* Scrim: dark at the foot where the words sit, clear above so the photo
   still carries the tile. */
.cx-tile::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(180deg, rgba(7, 8, 15, 0) 35%, rgba(7, 8, 15, .55) 68%, rgba(7, 8, 15, .9) 100%),
    linear-gradient(0deg, rgba(7, 8, 15, .12), rgba(7, 8, 15, .12));
}

.cx-body { position: absolute; left: 0; right: 0; bottom: 0; padding: 16px 18px; }
.cx-name { display: block; font-size: clamp(16px, 1.35vw, 20px); font-weight: 700; letter-spacing: -.01em; line-height: 1.2; }
.cx-subs {
  /* Two lines, not one: the sub-category names are long ("Cosmetics &
     make-up"), and a single line cut them mid-word on every narrow tile. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  margin-top: 4px;
  font-size: 12.5px;
  line-height: 1.4;
  color: rgba(255, 255, 255, .72);
}
.cx-kind {
  position: absolute;
  top: 12px;
  left: 12px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  padding: 5px 9px;
  border-radius: 999px;
  background: rgba(7, 8, 15, .55);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  color: var(--lime);
  border: 1px solid rgba(201, 238, 10, .3);
}
.cx-arrow {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--lime);
  color: #0a0b10;
  font-weight: 700;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity .3s, transform .3s;
}
.cx-tile:hover .cx-arrow, .cx-tile:focus-visible .cx-arrow { opacity: 1; transform: none; }

@media (max-width: 600px) {
  .cx-body { padding: 12px 13px; }
  .cx-subs { display: none; } /* the name and the photo carry it at this size */
}

/* ── The slow drift ──────────────────────────────────────────────────────── *
   Each tile pans and zooms on its own long cycle, from its own corner, so
   the mosaic never moves in unison. Only while the section is on screen
   (categories.js toggles .is-live), and never for reduced motion. */

.cx.is-live .cx-tile img { animation: cx-drift var(--dur, 26s) ease-in-out infinite alternate; animation-delay: var(--delay, 0s); }
@keyframes cx-drift {
  from { transform: scale(1.02) translate(0, 0); }
  to   { transform: scale(1.12) translate(var(--dx, -1.5%), var(--dy, -1%)); }
}
@media (prefers-reduced-motion: reduce) {
  .cx.is-live .cx-tile img { animation: none; }
  .cx-tile, .cx-tile img, .cx-arrow { transition: none; }
}

.cx-credit { margin-top: 16px; font-size: 12px; color: rgba(139, 144, 163, .7); }
.cx-credit a { color: inherit; }
