/* ==========================================================================
   InvestShop theme — dynamic-page additions
   --------------------------------------------------------------------------
   tokens.css and styles.css are the design system and stay untouched. This
   file only adds what a database-backed shop needs and a static mock-up did
   not: a navigation built from the shop owner's own menu tree, server-side
   pagination, the search suggestion list, and the handful of state classes
   the Blade views set.

   Everything here reads from the same tokens, so a change to the palette
   still reaches all of it.
   ========================================================================== */

/* ---------------------------------------------------------- utilities */

.d-block { display: block; }
.text-danger { color: var(--color-danger, #d92d20); }

.is-busy {
  opacity: 0.6;
  pointer-events: none;
}

/* Set while a dialog is open, so the page behind it cannot scroll away. */
html.is-locked,
html.is-locked body { overflow: hidden; }

/* --------------------------------------------------- primary navigation
   The menu tree is authored in the admin panel, so its depth is unknown at
   design time. Hover opens a panel on a pointer; `.is-open` is what the
   script sets for touch and keyboard, which have no hover to give. */

.nav-drop { position: relative; }

.nav-drop__trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

.nav-drop__caret {
  width: 1rem;
  height: 1rem;
  transition: transform 0.16s ease;
}

.nav-drop:hover .nav-drop__caret,
.nav-drop.is-open .nav-drop__caret { transform: rotate(180deg); }

.nav-drop__panel {
  position: absolute;
  inset-inline-start: 0;
  top: calc(100% + 0.65rem);
  z-index: 60;
  min-width: 14rem;
  padding: 0.6rem;
  border: 1px solid var(--color-border, rgba(0, 0, 0, 0.08));
  border-radius: var(--radius-md, 0.75rem);
  background: var(--color-surface, #fff);
  box-shadow: var(--shadow-md, 0 12px 32px rgba(0, 0, 0, 0.12));
  opacity: 0;
  visibility: hidden;
  transform: translateY(-0.35rem);
  transition: opacity 0.16s ease, transform 0.16s ease, visibility 0.16s;
}

.nav-drop:hover .nav-drop__panel,
.nav-drop:focus-within .nav-drop__panel,
.nav-drop.is-open .nav-drop__panel {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

.nav-drop__panel--mega {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: 1rem 1.5rem;
  width: min(60rem, calc(100vw - 3rem));
  padding: 1.25rem;
}

.nav-drop__list,
.nav-drop__sublist,
.nav-mega__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.nav-drop__list a,
.nav-mega__list a {
  display: block;
  padding: 0.4rem 0.55rem;
  border-radius: var(--radius-sm, 0.5rem);
  color: inherit;
  text-decoration: none;
  font-size: 0.92rem;
}

.nav-drop__list a:hover,
.nav-mega__list a:hover {
  background: var(--color-surface-2, rgba(0, 0, 0, 0.04));
  color: var(--color-brand, #037c5c);
}

.nav-drop__sublist { padding-inline-start: 0.75rem; }
.nav-drop__sublist a { font-size: 0.85rem; opacity: 0.85; }

.nav-mega__title {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.5rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--color-border, rgba(0, 0, 0, 0.08));
  color: inherit;
  font-weight: 700;
  text-decoration: none;
}

.nav-mega__title:hover { color: var(--color-brand, #037c5c); }

/* ------------------------------------------------------ language switch */

.lang-btn__code {
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
}

.lang-pop { min-width: 10rem; }

/* ------------------------------------------------------------ branding */

.brand__logo {
  display: block;
  height: 2.5rem;
  width: auto;
  object-fit: contain;
}

/* ------------------------------------------------------- search results */

.search__item { list-style: none; }

.search__item a {
  display: grid;
  grid-template-columns: 3rem 1fr;
  gap: 0.7rem;
  align-items: center;
  padding: 0.5rem;
  border-radius: var(--radius-sm, 0.5rem);
  color: inherit;
  text-decoration: none;
}

.search__item a:hover,
.search__item.is-active a { background: var(--color-surface-2, rgba(0, 0, 0, 0.04)); }

.search__item img {
  width: 3rem;
  height: 3rem;
  border-radius: var(--radius-sm, 0.5rem);
  object-fit: contain;
  background: var(--color-surface-2, rgba(0, 0, 0, 0.04));
}

.search__item b { display: block; font-size: 0.9rem; }
.search__item small { display: block; font-size: 0.78rem; opacity: 0.7; }

.search__empty {
  list-style: none;
  padding: 0.75rem 0.5rem;
  font-size: 0.9rem;
  opacity: 0.7;
}

/* ----------------------------------------------------------- pagination */

.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  margin: 2rem 0;
}

.pager__pages {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  flex-wrap: wrap;
}

.pager__btn,
.pager__page {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.4rem;
  height: 2.4rem;
  padding: 0 0.5rem;
  border: 1px solid var(--color-border, rgba(0, 0, 0, 0.1));
  border-radius: var(--radius-sm, 0.5rem);
  background: var(--color-surface, #fff);
  color: inherit;
  font-size: 0.9rem;
  text-decoration: none;
}

.pager__btn:hover,
.pager__page:hover { border-color: var(--color-brand, #037c5c); }

.pager__page.is-current {
  border-color: var(--color-brand, #037c5c);
  background: var(--color-brand, #037c5c);
  color: #fff;
  font-weight: 700;
}

.pager__btn.is-disabled { opacity: 0.4; pointer-events: none; }
.pager__gap { padding: 0 0.35rem; opacity: 0.6; }

/* ------------------------------------------------------------ home page */

.hero--reverse { direction: rtl; }
.hero--reverse > * { direction: inherit; }

.hero-banners {
  display: grid;
  gap: 1rem;
  align-content: start;
}

.hero-mobile { margin-block: 1rem; }
.hero-mobile .promo-tile { min-width: min(80vw, 22rem); }

/* The reference tile carries a vector at --icon-2xl and nothing else. A
   category that has its own artwork uploaded gets the identical box, so a
   rail that mixes uploaded images with fallback vectors still reads as one
   row rather than a row of stamps at whatever size the file happened to be.
   `contain` keeps a non-square upload inside the box instead of stretching
   it; the hover nudge is the same one .category-tile .icon gets. */
.category-tile img {
  inline-size: var(--icon-2xl);
  block-size: var(--icon-2xl);
  object-fit: contain;
  transition: var(--transition-transform);
}

.category-tile:hover img { scale: 1.1; }

.category-tile__count {
  display: block;
  font-size: 0.75rem;
  opacity: 0.65;
}

/* پنل لاین محصول بدون تصویر: وکتور عنوان کادر جای آثار هنری را می گیرد و
   دقیقا همان جعبه ای را اشغال می کند که .lineup-promo img می گیرد — همان
   ارتفاع و همان padding — پس برچسب پایین پنل هیچ وقت رویش نمی افتد. */
.lineup-promo__glyph {
  display: grid;
  place-items: center;
  block-size: 18.25rem;
  padding: var(--space-5) var(--space-6) calc(var(--space-20) + var(--space-5));
  color: inherit;
  font-size: 8rem;
  transition: var(--transition-transform);
}

.lineup-promo__glyph .icon {
  stroke-width: 1.1;
  opacity: 0.92;
}

.lineup-promo:hover .lineup-promo__glyph {
  transform: scale(1.04);
}

.coworker-rail {
  display: flex;
  gap: 1rem;
  overflow-x: auto;
  padding-block: 0.5rem;
}

.coworker-tile {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 9rem;
  height: 5rem;
  padding: 0.75rem;
  border: 1px solid var(--color-border, rgba(0, 0, 0, 0.08));
  border-radius: var(--radius-md, 0.75rem);
  background: var(--color-surface, #fff);
}

.coworker-tile img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.custom-page-block {
  padding: 1.5rem;
  border-radius: var(--radius-lg, 1rem);
}

.line-tile__media {
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--radius-md, 0.75rem);
  background: var(--color-surface-2, rgba(0, 0, 0, 0.04));
}

.line-tile__media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.footer-copyright {
  padding-top: 1rem;
  margin-top: 1rem;
  border-top: 1px solid var(--color-border, rgba(255, 255, 255, 0.15));
  text-align: center;
  font-size: 0.85rem;
  opacity: 0.8;
}

/* ------------------------------------------------------------- popups */

.modal--wide { width: min(56rem, calc(100vw - 2rem)); }

.index-popup { width: min(40rem, calc(100vw - 2rem)); }
.index-popup__image { width: 100%; height: auto; border-radius: var(--radius-md, 0.75rem); }
.index-popup__image--mobile { display: none; }

@media (max-width: 40rem) {
  .index-popup__image--desktop:not(:only-child) { display: none; }
  .index-popup__image--mobile { display: block; }
}

/* --------------------------------------------------------------- forms */

.captcha-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.captcha-row .field__control { flex: 1 1 auto; }

.captcha-image {
  height: 2.75rem;
  border-radius: var(--radius-sm, 0.5rem);
  background: #fff;
}

.form-alert--danger {
  border-color: var(--color-danger, #d92d20);
  color: var(--color-danger, #d92d20);
}

.field.has-error .field__control { border-color: var(--color-danger, #d92d20); }

/* forms.css نشان دادن پیام خطا را به aria-invalid روی خود کنترل گره زده است،
   ولی خطاهای سمت سرور از shop.js می آیند و آنجا فقط کلاس has-error روی .field
   می نشیند — بدون این قانون، متن خطا نوشته می شد و پنهان می ماند. */
.field.has-error .field__error { display: flex; }

.price-range__inputs {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.price-range__inputs .field__control { min-width: 0; }

.coupon-form__row {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.coupon-form__row .coupon-form__input { flex: 1 1 auto; }

.ui-input--add-point {
  display: flex;
  gap: 0.5rem;
}

.ui-input--add-point .field__control { flex: 1 1 auto; }

.chip__remove {
  margin-inline-start: 0.35rem;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
  font-size: 1rem;
  line-height: 1;
}

/* ------------------------------------------------------- product page
   product.css carries the whole design of this page. What is left here is
   only what a database-backed product needs and a hand-written mock-up did
   not: an attribute that is out of stock, a radio hidden behind its label,
   and the number field the basket endpoint insists on. */

.option.is-disabled {
  opacity: 0.4;
  pointer-events: none;
  text-decoration: line-through;
}

/* The attribute swatches are labels wrapping a visually hidden radio, so the
   focus ring has to be borrowed from the input and drawn on the label — a
   ring around a 1px box in the corner of the screen is no ring at all. */
.option:has(.variant-selector:focus-visible) {
  outline: var(--ring-width, 2px) solid var(--ring-color, #037c5c);
  outline-offset: var(--ring-offset, 2px);
}

/* The quantity field is type=number because the cart endpoint validates a
   number and shop.js steps it; the design has no spinner, and product.js
   wires the arrow keys up by hand in its place. */
.qty__input::-webkit-outer-spin-button,
.qty__input::-webkit-inner-spin-button {
  margin: 0;
  -webkit-appearance: none;
  appearance: none;
}

.qty__input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}

/* Tabs on this page are the ARIA kind — one panel revealed with `hidden`,
   which product.css already styles. Everywhere else a tabset still toggles
   a class, so both spellings have to keep working. */
.tab.is-active { color: var(--color-brand, #037c5c); font-weight: 700; }

.tabs:not([data-tabs="aria"]) .tabs__panel { display: none; }
.tabs:not([data-tabs="aria"]) .tabs__panel.is-active { display: block; }

/* The set discount is only ever quoted alongside the code that grants it. */
.bundle__code {
  margin-block-start: var(--space-1, 0.25rem);
  font-size: 0.8rem;
}

/* The buy box holds up to five secondary controls once compare, the price
   chart and the admin edit link are switched on; product.css sizes the pair
   the design drew, and an odd one out spans the row rather than sitting
   half-width beside a gap. */
.buybox__secondary > :last-child:nth-child(odd) { grid-column: 1 / -1; }

.price-chart .chips { margin-bottom: 1rem; }

/* Questions and answers reuse the comment thread, which brings its own
   heading. Inside a section that already has one, that is a duplicate. */
.qa .comments > .section-head { display: none; }

/* -------------------------------------------------------- compare table */

.compare-table td,
.compare-table th { vertical-align: top; }

.compare-group th {
  background: var(--color-surface-2, rgba(0, 0, 0, 0.04));
  font-weight: 700;
}

.compare-cell { position: relative; display: block; text-align: center; }
.compare-cell img { width: 100%; max-width: 9rem; height: auto; margin-inline: auto; }
.compare-cell a { color: inherit; text-decoration: none; }
.compare-cell span { display: block; margin-top: 0.4rem; font-size: 0.85rem; }

.compare-cell__remove {
  position: absolute;
  inset-block-start: 0;
  inset-inline-end: 0;
  color: var(--color-danger, #d92d20);
}

/* ------------------------------------------------------------- account */

.order-status.is-paid { color: #067647; background: rgba(6, 118, 71, 0.1); }
.order-status.is-unpaid { color: #b54708; background: rgba(181, 71, 8, 0.1); }
.order-status.is-canceled { color: var(--color-danger, #d92d20); background: rgba(217, 45, 32, 0.1); }

.is-credit { color: #067647; font-weight: 700; }
.is-debit { color: var(--color-danger, #d92d20); font-weight: 700; }

.profile-fact--wide { grid-column: 1 / -1; }

.order-thumb__body {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}

.order-thumb__body img {
  width: 3rem;
  height: 3rem;
  border-radius: var(--radius-sm, 0.5rem);
  object-fit: contain;
}

.order-thumb__title small {
  display: block;
  font-size: 0.75rem;
  opacity: 0.7;
}

.timeline__step.is-done .timeline__mark {
  background: var(--color-brand, #037c5c);
  color: #fff;
}

.thread__files {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.thread__files a {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.8rem;
}

.empty-state--page {
  padding-block: 4rem;
  text-align: center;
}

/* -------------------------------------------------------------- flow */

.flow-step.is-done .flow-step__mark,
.flow-step.is-current .flow-step__mark {
  background: var(--color-brand, #037c5c);
  color: #fff;
}

.flow-step.is-current { font-weight: 700; }

.checkout-aside {
  display: grid;
  gap: 1rem;
  align-content: start;
}

/* ------------------------------------------------------------ filters */

@media (max-width: 62rem) {
  .filters {
    display: none;
  }

  .filters.is-open {
    display: block;
  }
}

/* --------------------------------------------------------- auth pages */

.auth-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  max-width: 75rem;
  margin-inline: auto;
  padding: 1.25rem 1.5rem;
}

.auth-footer {
  padding: 2rem 1.5rem;
  text-align: center;
  font-size: 0.85rem;
  opacity: 0.7;
}

.auth-card--wide { max-width: 46rem; }

.auth-card--wide .form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1rem;
}

.auth-card--wide .form-foot { grid-column: 1 / -1; }

/* ------------------------------------------------------- mega-menu column */

.nav-mega__col {
  min-inline-size: 0;
}

/* ----------------------------------------------------------- line cards
   The shop index and the category page list child categories rather than
   products. The design has no such card — its lines are hard-coded tiles —
   so this is built from the same tokens as .product-card. */

.line-card {
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: var(--space-3);
  padding: var(--space-4);
  border: var(--border-hairline) solid var(--card-border, rgba(0, 0, 0, 0.08));
  border-radius: var(--card-radius, 1rem);
  background: var(--bg-surface, #fff);
  color: inherit;
  text-decoration: none;
  transition: border-color 0.16s ease, transform 0.16s ease;
}

.line-card:hover {
  border-color: var(--brand-600, #037c5c);
  transform: translateY(-2px);
}

.line-card__media {
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--radius-md, 0.75rem);
  background: var(--bg-subtle, rgba(0, 0, 0, 0.04));
}

.line-card__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: contain;
}

.line-card__body {
  display: grid;
  gap: 0.15rem;
}

.line-card__body strong {
  font-size: var(--text-lg, 1.05rem);
}

.line-card__body small {
  color: var(--fg-muted, rgba(0, 0, 0, 0.6));
  font-size: var(--text-sm, 0.85rem);
}

.line-card__go {
  justify-self: start;
  display: inline-grid;
  place-items: center;
  inline-size: 2rem;
  block-size: 2rem;
  border-radius: 999px;
  background: var(--bg-subtle, rgba(0, 0, 0, 0.05));
  color: var(--brand-600, #037c5c);
}

.line-card:hover .line-card__go {
  background: var(--brand-600, #037c5c);
  color: #fff;
}

/* The category copy block that sits below the results. */
.cat-copy {
  padding: var(--space-6);
  border: var(--border-hairline) solid var(--card-border, rgba(0, 0, 0, 0.08));
  border-radius: var(--card-radius, 1rem);
  background: var(--bg-surface, #fff);
}
