/* ==========================================================================
   /partners — the trading-partner logo wall

   Everything scoped under `.ptn`, per the house rule that page CSS never leaks
   globally (CLAUDE.md rule 5). Logical properties throughout, so one set of
   rules serves fa (RTL) and en (LTR) with no direction override anywhere.

   The head band deliberately matches /catalogues and /companies — this is a
   third listing page in the same family, and giving it its own header language
   would make the site read as three sites.
   ========================================================================== */

.ptn {
  --ptn-radius: 16px;
  /* 84, not 68: most of these legacy marks are WORDMARKS with the company name
     drawn into the artwork, so a short plate shrinks real Persian text until it
     is a grey smudge. This is the height at which the smallest of the 25 is
     still readable without the tallest one dominating the wall. */
  --ptn-logo-h: 84px;
}

/* ================================================================== head */

/* ⚠️ THIS HEAD DELIBERATELY MIRRORS THE `/companies` BAND — breadcrumb, one
   large solid title, the lede behind a vertical accent bar, and a faint dot
   field bleeding in from the END edge. The user asked for the two to match
   (2026-08-16). It is COPIED, not shared: page CSS never leaks globally
   (CLAUDE.md rule 5), and `/about/capabilities` carries the same block under
   `.cap-head`. Change one and change the other. */
.ptn-head {
  position: relative;
  background: linear-gradient(160deg, var(--c-primary-soft) 0%, var(--c-paper) 46%, var(--c-surface) 100%);
  border-block-end: 1px solid var(--c-line);
  padding-block: clamp(44px, 6vw, 84px) clamp(32px, 4vw, 60px);
  overflow: hidden;
}
/* The dot field. A radial-gradient tile, masked so it fades out before it
   reaches the words — an asset would be a request for something this faint,
   and the tile inherits the theme's primary if it is ever re-coloured. */
.ptn-head::before {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-end: 0;
  inline-size: min(46%, 560px);
  background-image: radial-gradient(var(--c-primary) 1px, transparent 1px);
  background-size: 16px 16px;
  opacity: 0.13;
  -webkit-mask-image: linear-gradient(to left, #000, transparent 88%);
  mask-image: linear-gradient(to left, #000, transparent 88%);
  pointer-events: none;
}
[dir="ltr"] .ptn-head::before {
  -webkit-mask-image: linear-gradient(to right, #000, transparent 88%);
  mask-image: linear-gradient(to right, #000, transparent 88%);
}
.ptn-head > .container {
  position: relative;
}

.ptn-head__crumb {
  display: flex;
  gap: var(--s-2);
  font-size: var(--t-sm);
  color: var(--c-muted);
  margin-block-end: var(--s-6);
}
.ptn-head__crumb a { color: var(--c-muted); }
.ptn-head__crumb a:hover { color: var(--c-primary); }

/* Bigger and solid, not the token step — the `/companies` band's title is the
   largest type on its page and this has to sit at the same weight beside it.
   ⚠️ RTL gets more leading and no negative tracking: Persian letterforms carry
   marks above and below, and -0.01em closes the counters on ی/ج. Same pair of
   rules as `.subs-hero__title`. */
.ptn-head__title {
  font-size: clamp(1.9rem, 4.2vw, 3rem);
  line-height: 1.22;
  letter-spacing: -0.01em;
  font-weight: 700;
  color: var(--c-ink);
  margin: 0;
}
[dir="rtl"] .ptn-head__title {
  letter-spacing: 0;
  line-height: 1.42;
}

/* The vertical accent bar. `border-inline-start`, so it sits at the reading
   edge — the right in fa, the left in en — with no direction override. */
.ptn-head__lede {
  margin: var(--s-6) 0 0;
  padding-inline-start: var(--s-5);
  border-inline-start: 3px solid var(--c-primary);
  font-size: var(--t-lg);
  line-height: var(--lh-loose, 1.9);
  color: var(--c-body);
}

.ptn-head__count {
  margin-block-start: var(--s-6);
  font-size: var(--t-sm);
  color: var(--c-muted);
}
.ptn-head__count b {
  color: var(--c-ink);
  font-size: var(--t-lg);
  font-weight: 700;
}

/* ================================================================ filter */

.ptn-body {
  padding-block: var(--s-12) var(--sec-y);
}

.ptn-filter {
  display: flex;
  gap: var(--s-2);
  flex-wrap: wrap;
  margin-block-end: var(--s-8);
  padding-block-end: var(--s-4);
  border-block-end: 1px solid var(--c-line);
}

/* ⚠️ These are <a>, not <button> — the filter is a set of real URLs so it works
   with scripting off. They are STYLED as chips; do not "fix" the markup to
   buttons without moving the filtering back to the server-only path. */
.ptn-filter__chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: 10px var(--s-5);
  border: 1px solid var(--c-line);
  border-radius: 24px;
  background: var(--c-surface);
  color: var(--c-body);
  font-size: var(--t-sm);
  text-decoration: none;
  transition: border-color var(--dur-1, 0.15s), background-color var(--dur-1, 0.15s),
              color var(--dur-1, 0.15s);
}
.ptn-filter__chip:hover {
  border-color: var(--c-primary);
  color: var(--c-primary-deep);
}
.ptn-filter__chip.is-active {
  background: var(--c-primary-deep);
  border-color: var(--c-primary-deep);
  color: #fff;
}

.ptn-filter__icon {
  inline-size: 16px;
  block-size: 16px;
  flex: none;
}

.ptn-filter__n {
  font-size: var(--t-xs);
  opacity: 0.7;
}

/* ================================================================== wall */

/* `auto-fill`, not `auto-fit`: with one partner left after a filter, auto-fit
   would collapse the empty tracks and stretch that single card across the whole
   row. auto-fill keeps the column rhythm and the card keeps its size. */
.ptn-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: var(--s-5);
}

.ptn-card {
  display: flex;
}
.ptn-card[hidden] {
  display: none;
}

.ptn-card__inner {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  padding: var(--s-6) var(--s-5) var(--s-5);
  border: 1px solid var(--c-line);
  border-radius: var(--ptn-radius);
  background: var(--c-surface);
  color: inherit;
  text-decoration: none;
  transition: border-color var(--dur-1, 0.15s), box-shadow var(--dur-1, 0.15s),
              transform var(--dur-1, 0.15s);
}
a.ptn-card__inner:hover {
  border-color: var(--c-primary);
  box-shadow: 0 14px 30px rgba(14, 31, 39, 0.1);
  transform: translateY(-2px);
}
/* A card with no website is not a link and must not pretend to be one — no
   lift, no pointer, no hover border. See partner_website(). */
.ptn-card__inner.is-static {
  cursor: default;
}

/* The logo plate. A fixed height with `object-fit: contain` is what keeps 25
   logos of wildly different aspect ratios reading as one wall — the legacy
   files run from near-square marks to long wordmarks.

   ⚠️ THE IMAGE CAP IS AN ABSOLUTE LENGTH, NOT `max-block-size: 100%`.
   `hitco.css` sets `img { max-width: 100%; height: auto }` globally, so the
   logo takes the plate's full WIDTH and then computes its height from its own
   aspect ratio — a 400×300 legacy PNG became ~170×128 inside a 68px plate,
   burst out of it, and printed itself straight over the partner's name. The
   percentage cap did not save it; `var(--ptn-logo-h)` does, because it needs no
   containing block to resolve against. `overflow: hidden` is the second lock:
   whatever a future logo's dimensions are, nothing leaves this box. */
.ptn-card__logo {
  display: grid;
  place-items: center;
  block-size: var(--ptn-logo-h);
  padding-inline: var(--s-2);
  overflow: hidden;
}
.ptn-card__logo img {
  max-inline-size: 100%;
  max-block-size: var(--ptn-logo-h);
  inline-size: auto;
  block-size: auto;
  object-fit: contain;
}
.ptn-card__logo svg {
  inline-size: 34px;
  block-size: 34px;
  color: var(--c-line-strong);
}

.ptn-card__body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
  text-align: center;
}

.ptn-card__name {
  font-size: var(--t-sm);
  font-weight: 600;
  line-height: var(--lh-snug);
  color: var(--c-ink);
}

.ptn-card__cat {
  font-size: var(--t-xs);
  color: var(--c-muted);
}

.ptn-card__foot {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  flex-wrap: wrap;
  padding-block-start: var(--s-4);
  border-block-start: 1px solid var(--c-line);
}

/* دولتی / خصوصی. Present on only 9 of the 25 rows, so the foot has to look
   finished without it — which is why it sits beside the link line rather than
   in a slot of its own. */
.ptn-card__badge {
  font-size: var(--t-xs);
  color: var(--c-primary-deep);
  background: var(--c-primary-soft);
  border-radius: 12px;
  padding: 2px 10px;
}

.ptn-card__visit {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--t-xs);
  color: var(--c-primary);
}
.ptn-card__visit-icon {
  inline-size: 14px;
  block-size: 14px;
}
a.ptn-card__inner:hover .ptn-card__visit {
  color: var(--c-primary-deep);
}

.ptn-card__nosite {
  font-size: var(--t-xs);
  color: var(--c-muted);
}

.ptn-empty {
  margin-block-start: var(--s-8);
  text-align: center;
  color: var(--c-muted);
}

/* ============================================================ responsive */

@media (max-width: 640px) {
  .ptn {
    --ptn-logo-h: 64px;
  }
  .ptn-head {
    padding-block: var(--s-10) var(--s-8);
  }
  .ptn-grid {
    grid-template-columns: repeat(auto-fill, minmax(155px, 1fr));
    gap: var(--s-4);
  }
  .ptn-card__inner {
    padding: var(--s-5) var(--s-4) var(--s-4);
  }
}

/* The lift is decoration; a visitor who asked for less motion gets none. */
@media (prefers-reduced-motion: reduce) {
  .ptn-card__inner {
    transition: border-color var(--dur-1, 0.15s);
  }
  a.ptn-card__inner:hover {
    transform: none;
  }
}
