/**
 * jensik — Global Layout Components
 * ====================================
 * Header, SearchBar, MobileNav (drawer), BottomNav, Breadcrumb, Footer.
 * These are GLOBAL: one implementation, used on every template.
 */

/* =======================================================================
 * HEADER — .nk-header
 * Mobile  (<1024px): [burger] [logo] [cart]        — 56px, sticky
 * Desktop (≥1024px): [logo] [search] [account][cart] + category row — 80px
 *
 * The mobile order is a product decision, not a layout accident: the burger
 * sits on the inline-start (right in RTL) where the thumb rests, and the cart
 * on the inline-end. There is no search icon here — search is a bottom-nav
 * destination with a screen of its own.
 * ===================================================================== */

/**
 * The block theme wraps each template part in its own element:
 *
 *   <header class="wp-block-template-part">  ← height = the header, exactly
 *     <header class="nk-header">             ← position: sticky
 *
 * A sticky element only travels inside its containing block, and that wrapper
 * is the same height as the header itself — so the sticky range was zero
 * pixels and the header scrolled away like static content. `display: contents`
 * removes the wrapper's box (not its landmark) and hands .nk-header straight
 * to .wp-site-blocks, which is as tall as the page.
 *
 * Scoped with :has() so it only touches the two wrappers that hold our chrome;
 * every other template part keeps its box.
 */
.wp-block-template-part:has(> .nk-header),
.wp-block-template-part:has(> .nk-footer) {
  display: contents;
}

.nk-header {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--nk-z-header);
  background-color: var(--nk-surface-page);
  border-block-end: var(--nk-border-hairline);
  padding-block-start: var(--nk-safe-top);
}

/* Slight elevation once the page scrolls (toggled in ui.js). */
.nk-header--scrolled { box-shadow: var(--nk-shadow-sm); border-block-end-color: transparent; }

.nk-header__bar {
  display: flex;
  align-items: center;
  gap: var(--nk-space-2);
  block-size: var(--nk-header-height);
}

/**
 * The two side clusters are equal-width flex tracks so the logo lands on the
 * true centre of the bar. Centring it with `margin-inline: auto` instead would
 * shift it off-centre as soon as the cart badge reaches two digits — the logo
 * must not move because someone added a tenth item.
 */
.nk-header__side {
  display: flex;
  align-items: center;
  gap: var(--nk-space-1);
  flex: 1 1 0;
}
.nk-header__side--end { justify-content: flex-end; }

.nk-header__logo {
  display: inline-flex;
  align-items: center;
  gap: var(--nk-space-2);
  flex: 0 0 auto;
  font-family: var(--nk-font-display);
  font-size: var(--nk-text-xl);
  font-weight: var(--nk-weight-bold);
  color: var(--nk-text-strong);
  text-decoration: none;
  white-space: nowrap;
  min-block-size: var(--nk-touch-target);
}
/**
 * The wordmark is a raster with intrinsic dimensions; height drives, width
 * follows, so the aspect ratio cannot be squashed by a flex context.
 *
 * Scoped to its parent rather than written as a bare `.nk-logo__img`, and that
 * is load-bearing: WooCommerce ships `.woocommerce img, .woocommerce-page img
 * { height: auto }`, and `body.woocommerce-page` is on every shop, cart,
 * checkout and account page. A single class loses to that pair, so the logo
 * rendered at its intrinsic 307px and pushed the mobile header 13px past the
 * viewport — on Woo routes only, which is why the home page looked fine.
 * Beat Woo on specificity, never with !important.
 */
.nk-header__logo .nk-logo__img { block-size: 34px; inline-size: auto; max-inline-size: 100%; }

.nk-header__search { display: none; }
/* Desktop-only header furniture; on mobile these live in the drawer and the
   bottom nav respectively. */
.nk-header__account,
.nk-header__sitenav { display: none; }

/* Announcement strip above the header. */
.nk-announce {
  background-color: var(--nk-navy-800);
  color: var(--nk-text-inverse);
  font-size: var(--nk-text-sm);
}
.nk-announce a { color: var(--nk-coral-300); }
.nk-announce[hidden] { display: none; }

.nk-announce__inner {
  display: flex;
  align-items: center;
  gap: var(--nk-space-2);
  min-block-size: var(--nk-touch-target);
}
/* The message takes the row and centres in it; the close button is pinned to
   the end and does not shift the text off centre, because the flex basis of
   the body is the whole remaining track. */
.nk-announce__body {
  flex: 1 1 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--nk-space-2);
  min-block-size: var(--nk-touch-target);
  text-align: center;
  color: inherit;
  text-decoration: none;
  /* Balances the close button so a single line of text sits on the true
     centre of the bar rather than 22px off it. */
  margin-inline-start: var(--nk-touch-target);
}
@media (hover: hover) {
  a.nk-announce__body:hover .nk-announce__text { text-decoration: underline; }
}
/* Two classes deep for the same reason the logo is — see .nk-header__logo
   .nk-logo__img above. Woo's `.woocommerce-page img { height: auto }` is on
   every commerce route. */
.nk-announce .nk-announce__image {
  block-size: 24px;
  inline-size: auto;
  border-radius: var(--nk-radius-xs);
}
.nk-announce__close {
  flex: 0 0 auto;
  color: var(--nk-cream-300);
}
@media (hover: hover) {
  .nk-announce__close:hover { color: var(--nk-white); background-color: rgb(255 255 255 / 0.12); }
}

/* Category row — desktop only. */
.nk-header__catbar { display: none; }

@media (min-width: 1024px) {
  .nk-header__bar { gap: var(--nk-space-4); }
  .nk-announce .nk-announce__image { block-size: 28px; }

  /* Desktop drops the equal-track trick: the logo anchors to the start edge
     and the search takes the slack. */
  .nk-header__side { flex: 0 0 auto; }
  /* The burger is the only thing in the leading track; an empty flex item
     still contributes a gap, which pushed the logo off the container edge. */
  .nk-header__side:not(.nk-header__side--end) { display: none; }
  .nk-header__burger { display: none; }
  .nk-header__account { display: inline-flex; }
  .nk-header__logo .nk-logo__img { block-size: 44px; }

  .nk-header__sitenav {
    display: flex;
    align-items: center;
    gap: var(--nk-space-half);
    flex: 0 0 auto;
  }

  .nk-header__search { display: block; flex: 1 1 auto; max-inline-size: 420px; margin-inline-start: auto; }

  /* Positioning context for the mega panel, which spans the full header width
     and hangs off the bottom of this row. */
  .nk-header__catbar { display: block; position: relative; border-block-start: var(--nk-border-hairline); }
  .nk-header__catbar-inner {
    display: flex;
    align-items: center;
    gap: var(--nk-space-1);
    min-block-size: 48px;
    /* A long category list scrolls rather than wrapping the header into two
       rows and pushing the page down. */
    overflow-x: auto;
    scrollbar-width: none;
  }
  .nk-header__catbar-inner::-webkit-scrollbar { display: none; }
}

/* Primary nav links */
.nk-nav-link {
  display: inline-flex;
  align-items: center;
  gap: var(--nk-space-1);
  padding-inline: var(--nk-space-3);
  min-block-size: var(--nk-touch-target);
  border-radius: var(--nk-radius-md);
  font-size: var(--nk-text-md);
  font-weight: var(--nk-weight-medium);
  color: var(--nk-text-default);
  text-decoration: none;
  white-space: nowrap;
  background: none;
  border: 0;
  cursor: pointer;
  font-family: inherit;
  transition: color var(--nk-transition-base), background-color var(--nk-transition-base);
}
@media (hover: hover) {
  .nk-nav-link:hover { color: var(--nk-text-strong); background-color: var(--nk-navy-50); }
}
.nk-nav-link:active { background-color: var(--nk-navy-100); }
.nk-nav-link[disabled] { color: var(--nk-action-disabled-text); cursor: not-allowed; }

/**
 * The page you are on is coral.
 *
 * `--nk-text-accent` is coral-700, not the coral-500 of the brand accent:
 * coral-500 measures 2.9:1 on the cream ground and fails AA at nav size. The
 * underline underneath is coral-500 — it is a fill, not text, so the brand
 * colour lands where contrast rules do not bind it.
 *
 * Weight and the bar both change too. Colour alone may not carry state.
 */
.nk-nav-link[aria-current="page"] {
  color: var(--nk-text-accent);
  font-weight: var(--nk-weight-semibold);
  position: relative;
}
.nk-nav-link[aria-current="page"]::after {
  content: "";
  position: absolute;
  inset-inline: var(--nk-space-3);
  inset-block-end: var(--nk-space-1);
  block-size: 2px;
  border-radius: var(--nk-radius-pill);
  background-color: var(--nk-action-primary);
}

/**
 * The one promotional link in the bar — حراج.
 *
 * A tinted pill rather than coloured text: as plain coral text it read as one
 * more nav item that happened to be a different colour, and the row has eight
 * of them. Coral is otherwise reserved for actions, so nothing else here may
 * use this treatment.
 */
.nk-nav-link--accent {
  color: var(--nk-text-accent);
  font-weight: var(--nk-weight-bold);
  background-color: var(--nk-coral-50);
}
@media (hover: hover) {
  .nk-nav-link--accent:hover {
    color: var(--nk-coral-800);
    background-color: var(--nk-coral-100);
  }
}
.nk-nav-link--accent .nk-icon { color: var(--nk-action-primary); }

/* =======================================================================
 * MEGA MENU — .nk-mega
 * A full-width panel under the category row. Opens on hover and on focus,
 * so it is reachable by keyboard as well as pointer.
 * ===================================================================== */

.nk-mega { position: static; }

.nk-mega__trigger[aria-expanded="true"] { background-color: var(--nk-navy-50); color: var(--nk-text-strong); }
.nk-mega__trigger[aria-expanded="true"] .nk-mega__chev { transform: rotate(180deg); }
.nk-mega__chev { transition: transform var(--nk-transition-base); }

/**
 * The panel opens as a short drop and a fade, not a cut.
 *
 * `hidden` alone is a display switch, and a full-width panel appearing between
 * two frames reads as the page jumping rather than as a menu opening. `hidden`
 * is still what keeps it out of the tab order, so ui.js removes the attribute
 * first and sets `data-open` on the next frame — display cannot be
 * transitioned, opacity and transform can.
 *
 * Standard easing in both directions, deliberately: --nk-ease-out spends three
 * quarters of its travel in the first 50ms, which is right for a drawer
 * crossing 300px and invisible on an 8px drop.
 */
.nk-mega__panel {
  position: absolute;
  inset-inline: 0;
  inset-block-start: 100%;
  z-index: var(--nk-z-dropdown);
  background-color: var(--nk-surface-raised);
  border-block-end: var(--nk-border-hairline);
  box-shadow: var(--nk-shadow-md);
  padding-block: var(--nk-space-6);
  opacity: 0;
  transform: translateY(calc(-1 * var(--nk-space-2)));
  pointer-events: none;
  transition:
    opacity var(--nk-duration-fast) var(--nk-ease-standard),
    transform var(--nk-duration-fast) var(--nk-ease-standard);
}
.nk-mega__panel[data-open="true"] {
  opacity: 1;
  transform: none;
  pointer-events: auto;
  transition-duration: var(--nk-duration-normal);
}
.nk-mega__panel[hidden] { display: none; }

/**
 * Two-pane layout for "همه محصولات": departments in column 1, the selected
 * department's subcategories in column 2.
 *
 * Every pane is placed in the same grid cell and all but one is `hidden`. That
 * lets the markup interleave each department with its own pane — dept, pane,
 * dept, pane — which is what puts a department's subcategories next in the tab
 * order instead of five links later. See nk_all_products_mega().
 */
/**
 * The two panes sit next to each other, not at opposite ends of the header.
 *
 * The department column was `minmax(200px, 240px)` and the pane took every
 * remaining pixel, so on a 1280px container a 90px department label and its own
 * subcategory list ended up with ~200px of nothing between them and the list
 * ran to the far edge. `max-content` on the departments and a measure on the
 * pane keep the two halves as one object, and `justify-content: start` parks
 * the pair at the reading edge instead of stretching it.
 */
/**
 * One explicit row per department, plus a flexible row that absorbs the rest.
 *
 * The panes span the department column with `grid-row: 1 / -1`, and `-1` means
 * the last line of the *explicit* grid — with no `grid-template-rows` at all
 * that resolved to row 1, so a 300px pane sat inside the first department's
 * row and opened a ~200px hole between دخترانه and the department under it.
 * Naming the rows fixes the span; the trailing `1fr` takes the height a tall
 * pane adds, so the departments stay a compact 44px stack instead of being
 * spread down the panel. The count comes from PHP — CSS cannot count children.
 */
.nk-mega__two {
  display: grid;
  grid-template-columns: minmax(160px, 220px) minmax(0, 1fr);
  grid-template-rows: repeat(var(--nk-mega-rows, 1), min-content) 1fr;
  gap: 0 var(--nk-space-6);
  align-items: start;
}
.nk-mega__dept {
  grid-column: 1;
  display: flex;
  align-items: center;
  gap: var(--nk-space-2);
  min-block-size: var(--nk-touch-target);
  padding-inline: var(--nk-space-3);
  border-radius: var(--nk-radius-md);
  color: var(--nk-text-default);
  font-size: var(--nk-text-md);
  font-weight: var(--nk-weight-medium);
  text-decoration: none;
  transition: background-color var(--nk-transition-base), color var(--nk-transition-base);
}
.nk-mega__dept span { flex: 1 1 auto; }
.nk-mega__dept-chev { color: var(--nk-text-subtle); opacity: 0; transition: opacity var(--nk-transition-base); }
.nk-mega__dept[data-active="true"] {
  background-color: var(--nk-navy-50);
  color: var(--nk-text-strong);
}
@media (hover: hover) {
  .nk-mega__dept:hover {
    background-color: var(--nk-navy-50);
    color: var(--nk-text-strong);
  }
}
.nk-mega__dept[data-active="true"] .nk-mega__dept-chev { opacity: 1; }

/* All panes share one cell. `grid-row: 1 / -1` spans the department column so
   a five-item list and a two-item pane both start at the top. */
.nk-mega__pane {
  grid-column: 2;
  grid-row: 1 / -1;
  padding-inline-start: var(--nk-space-6);
  border-inline-start: var(--nk-border-hairline);
  transition:
    opacity var(--nk-duration-fast) var(--nk-ease-standard),
    transform var(--nk-duration-fast) var(--nk-ease-standard);
}
.nk-mega__pane[hidden] { display: none; }
/* Swapping department was a hard cut between two full panes. ui.js sets this
   on the incoming pane and drops it on the next frame, so the new content
   arrives instead of replacing the old one mid-glance. */
.nk-mega__pane[data-enter] {
  opacity: 0;
  transform: translateY(var(--nk-space-1));
}

/* Single-department panel — no pane switching, just the subcategory grid. */
.nk-mega__single { display: block; }

.nk-mega__pane-title {
  display: flex;
  align-items: center;
  gap: var(--nk-space-2);
  margin: 0 0 var(--nk-space-4);
  font-family: var(--nk-font-display);
  font-size: var(--nk-text-lg);
  font-weight: var(--nk-weight-bold);
  color: var(--nk-text-strong);
}
.nk-mega__pane-title .nk-icon { color: var(--nk-text-accent); }

.nk-mega__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--nk-space-2); }
/**
 * Columns track the card, not the viewport.
 *
 * A fixed three columns across a full-width panel left ~300px between a label
 * and the next one, and the list stopped reading as a list. Capping the list
 * at a measure instead fixed that but pushed the emptiness out to the panel
 * edge, so the whole band read as content stuck in one corner. `auto-fill`
 * does both: the columns stay card-width, and there are as many of them as the
 * panel can hold. The track grew from 200px to 240px when the rows became
 * cards — a 64px thumbnail plus a two-word Persian label needs it.
 */
.nk-mega__list,
.nk-mega__list--grid {
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}

/**
 * A subcategory is a horizontal card: artwork, label, chevron.
 *
 * As plain links the six children of a department were six identical runs of
 * Persian text and the pane had to be read rather than scanned. The thumbnail
 * is the same generated artwork the category cards and the search screen use,
 * so a category looks like itself everywhere it appears — and when real
 * photography lands, nk_category_thumb() picks it up here with no change.
 */
.nk-mega__card {
  display: flex;
  align-items: center;
  gap: var(--nk-space-3);
  min-block-size: var(--nk-touch-target);
  padding: var(--nk-space-2);
  border-radius: var(--nk-radius-lg);
  color: var(--nk-text-default);
  font-size: var(--nk-text-base);
  text-decoration: none;
  transition:
    background-color var(--nk-transition-base),
    color var(--nk-transition-base);
}
.nk-mega__card-media {
  flex: 0 0 auto;
  inline-size: 64px;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--nk-radius-md);
  /* The ground behind a thumbnail that has not loaded, or a category with no
     artwork at all — an empty white box beside a filled one reads as broken. */
  background-color: var(--nk-navy-50);
}
/* Two classes: base.css sizes bare images, and Woo's own stylesheet sizes
   every img on a commerce route. See .claude/rules/css.md. */
.nk-mega__card-media .nk-mega__card-img {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}
.nk-mega__card-name { flex: 1 1 auto; }
.nk-mega__card-chev {
  flex: 0 0 auto;
  color: var(--nk-text-subtle);
  opacity: 0;
  transition: opacity var(--nk-transition-base);
}
@media (hover: hover) {
  .nk-mega__card:hover {
    background-color: var(--nk-navy-50);
    color: var(--nk-text-accent);
  }
}
@media (hover: hover) {
  .nk-mega__card:hover .nk-mega__card-chev { opacity: 1; }
}
.nk-mega__all { margin-block-start: var(--nk-space-5); }

/* =======================================================================
 * SEARCH BAR — .nk-search
 * ===================================================================== */

.nk-search { position: relative; }
.nk-search__input {
  inline-size: 100%;
  min-block-size: var(--nk-touch-target);
  padding-inline-start: var(--nk-space-10);
  padding-inline-end: var(--nk-space-4);
  background-color: var(--nk-surface-raised);
  border: var(--nk-border-width) solid var(--nk-border-default);
  border-radius: var(--nk-radius-pill);
  font-size: var(--nk-text-md);
}
.nk-search__input:focus-visible { border-color: var(--nk-border-accent); outline-offset: 0; }
/* WebKit draws its own clear affordance inside type="search", which lands on
   top of .nk-search__clear and reads as two overlapping crosses. Ours stays:
   it is a 44px target with an accessible name, and theirs is neither. */
.nk-search__input::-webkit-search-cancel-button,
.nk-search__input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; }
.nk-search__icon {
  position: absolute;
  inset-inline-start: var(--nk-space-4);
  inset-block-start: 50%;
  transform: translateY(-50%);
  color: var(--nk-text-muted);
  pointer-events: none;
}
.nk-search__clear {
  position: absolute;
  inset-inline-end: var(--nk-space-2);
  inset-block-start: 50%;
  transform: translateY(-50%);
}

/**
 * Mobile search overlay — full screen, opened from the header icon.
 * Full screen beats a cramped inline field: the keyboard takes half the
 * viewport and suggestions need the rest.
 */
.nk-search-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--nk-z-search);
  background-color: var(--nk-surface-page);
  padding: var(--nk-space-4) var(--nk-gutter);
  padding-block-start: calc(var(--nk-space-4) + var(--nk-safe-top));
  display: none;
  flex-direction: column;
  gap: var(--nk-space-4);
}
.nk-search-overlay[data-open="true"] { display: flex; }
.nk-search-overlay__head { display: flex; align-items: center; gap: var(--nk-space-2); flex: 0 0 auto; }
/* The desktop dropdown is the ≥1024px presentation; the overlay never opens
   there, so it must not be able to trap focus off-screen either. */
@media (min-width: 1024px) { .nk-search-overlay { display: none !important; } }

/* =======================================================================
 * MOBILE NAV DRAWER — .nk-drawer
 * Slides in from the inline-start edge (right in RTL).
 * ===================================================================== */

.nk-scrim {
  position: fixed;
  inset: 0;
  z-index: var(--nk-z-overlay);
  background-color: var(--nk-surface-overlay);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--nk-duration-normal) var(--nk-ease-standard), visibility var(--nk-duration-normal);
}
.nk-scrim[data-open="true"] { opacity: 1; visibility: visible; }

.nk-drawer {
  position: fixed;
  inset-block: 0;
  inset-inline-start: 0;
  z-index: var(--nk-z-drawer);
  inline-size: min(86vw, 360px);
  background-color: var(--nk-surface-page);
  display: flex;
  flex-direction: column;
  /* Logical translate: -100% moves it off the inline-start edge in both
     directions, so no [dir="rtl"] override is needed. */
  transform: translateX(-100%);
  transition: transform var(--nk-duration-normal) var(--nk-ease-out);
  padding-block-start: var(--nk-safe-top);
  padding-block-end: var(--nk-safe-bottom);
  overscroll-behavior: contain;
}
[dir="rtl"] .nk-drawer { transform: translateX(100%); }
.nk-drawer[data-open="true"] { transform: translateX(0); }
[dir="rtl"] .nk-drawer[data-open="true"] { transform: translateX(0); }

/* A transformed-off-screen panel is still in the tab order, so a keyboard user
   tabs into an invisible menu. visibility removes it; the delay lets the slide
   finish before it disappears. */
.nk-drawer { visibility: hidden; transition: transform var(--nk-duration-normal) var(--nk-ease-out), visibility 0s linear var(--nk-duration-normal); }
.nk-drawer[data-open="true"] { visibility: visible; transition-delay: 0s; }

.nk-drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--nk-space-4);
  border-block-end: var(--nk-border-hairline);
}
.nk-drawer__body { flex: 1; overflow-y: auto; padding: var(--nk-space-2) var(--nk-space-2) var(--nk-space-6); }
.nk-drawer__foot { padding: var(--nk-space-4); border-block-start: var(--nk-border-hairline); }

/**
 * Rows are the 44px touch target, not the 48px large one.
 *
 * At 48px a 360x740 phone fitted seven rows above the fold and the catalogue
 * ran off the bottom of the drawer; the shop's own departments were the part
 * you had to scroll for. 44px is the documented minimum, still comfortably
 * over it with the icon gap, and it buys back a whole row per screen.
 */
.nk-drawer__link {
  display: flex;
  align-items: center;
  gap: var(--nk-space-3);
  min-block-size: var(--nk-touch-target);
  padding-inline: var(--nk-space-3);
  border-radius: var(--nk-radius-md);
  color: var(--nk-text-strong);
  font-size: var(--nk-text-md);
  font-weight: var(--nk-weight-medium);
  text-decoration: none;
}
@media (hover: hover) {
  .nk-drawer__link:hover { background-color: var(--nk-navy-50); }
}
.nk-drawer__link:active { background-color: var(--nk-navy-100); }
/* Account and service rows are secondary to the catalogue above them. */
.nk-drawer__link--sm { font-size: var(--nk-text-base); color: var(--nk-text-default); }

/* The same coral pill the header bar gives حراج, so the promotion looks like
   one thing across both surfaces. */
.nk-drawer__link--accent {
  color: var(--nk-text-accent);
  font-weight: var(--nk-weight-bold);
  background-color: var(--nk-coral-50);
}
@media (hover: hover) {
  .nk-drawer__link--accent:hover { color: var(--nk-coral-800); background-color: var(--nk-coral-100); }
}
.nk-drawer__link--accent .nk-icon { color: var(--nk-action-primary); }
.nk-drawer__link[aria-current="page"] { color: var(--nk-text-accent); font-weight: var(--nk-weight-semibold); }
/* Chevron pointing "forward" — mirrored in RTL via .nk-icon--directional. */
.nk-drawer__link .nk-drawer__chev { margin-inline-start: auto; color: var(--nk-text-subtle); }

.nk-drawer__brand {
  display: inline-flex;
  align-items: center;
  font-family: var(--nk-font-display);
  font-size: var(--nk-text-xl);
  font-weight: var(--nk-weight-bold);
  color: var(--nk-text-strong);
}
.nk-drawer__brand .nk-logo__img { block-size: 34px; inline-size: auto; }

.nk-drawer__search { padding: var(--nk-space-2) var(--nk-space-2) var(--nk-space-4); }

/**
 * Nested categories are native <details>, not a second sliding panel: a parent
 * scanning one-handed keeps sight of where they are, and the element brings its
 * own keyboard and screen-reader behaviour.
 */
.nk-drawer__group > .nk-drawer__summary { list-style: none; cursor: pointer; }
.nk-drawer__group > .nk-drawer__summary::-webkit-details-marker { display: none; }
.nk-drawer__group[open] > .nk-drawer__summary .nk-drawer__chev { transform: rotate(180deg); }
.nk-drawer__chev { transition: transform var(--nk-transition-base); }

.nk-drawer__sub {
  display: grid;
  padding-inline-start: var(--nk-space-4);
  margin-inline-start: var(--nk-space-4);
  border-inline-start: var(--nk-border-width) solid var(--nk-border-subtle);
}
.nk-drawer__sublink {
  display: flex;
  align-items: center;
  min-block-size: var(--nk-touch-target);
  padding-inline: var(--nk-space-3);
  border-radius: var(--nk-radius-md);
  color: var(--nk-text-muted);
  font-size: var(--nk-text-base);
  text-decoration: none;
}
@media (hover: hover) {
  .nk-drawer__sublink:hover { color: var(--nk-text-strong); background-color: var(--nk-navy-50); }
}

.nk-drawer__rule {
  border: 0;
  border-block-start: var(--nk-border-hairline);
  margin-block: var(--nk-space-4);
}

/* Locks background scroll while the drawer/modal is open. */
body.nk-scroll-locked { overflow: hidden; touch-action: none; }

/* =======================================================================
 * BOTTOM NAV — .nk-bottom-nav
 * Mobile only. Five slots max; labels always visible.
 * ===================================================================== */

.nk-bottom-nav {
  position: fixed;
  inset-inline: 0;
  inset-block-end: 0;
  z-index: var(--nk-z-bottom-nav);
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  background-color: var(--nk-surface-raised);
  border-block-start: var(--nk-border-hairline);
  padding-block-end: var(--nk-safe-bottom);
}
.nk-bottom-nav__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--nk-space-half);
  min-block-size: var(--nk-bottom-nav-height);
  color: var(--nk-text-muted);
  font-size: var(--nk-text-2xs);
  text-decoration: none;
  transition: color var(--nk-transition-base);
}
@media (hover: hover) {
  .nk-bottom-nav__item:hover { color: var(--nk-text-strong); }
}
.nk-bottom-nav__item:active { background-color: var(--nk-navy-50); }
.nk-bottom-nav__item[aria-current="page"] { color: var(--nk-action-primary); }
/* Colour alone never carries state: the active tab also thickens its stroke. */
.nk-bottom-nav__item[aria-current="page"] .nk-icon { stroke-width: var(--nk-icon-stroke-bold); }
/* The label must survive a long Persian word at 360px without wrapping the
   row into two lines. "پروفایل کاربری" is the widest of the four. */
.nk-bottom-nav__item span {
  max-inline-size: 100%;
  padding-inline: var(--nk-space-half);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (min-width: 1024px) { .nk-bottom-nav { display: none; } }

/**
 * Reserve space for the bar. The selector covers both worlds: `main` in a
 * classic template, and the block theme's own wrapper — TT5 renders the group
 * as <main class="wp-block-group">, but a Woo template may not, so the body
 * gets the padding as the backstop.
 */
.nk-has-bottom-nav {
  padding-block-end: var(--nk-bottom-nav-space);
}
@media (min-width: 1024px) { .nk-has-bottom-nav { padding-block-end: 0; } }

/* =======================================================================
 * BACK TO TOP — .nk-scrolltop
 *
 * A `.nk-icon-btn--solid --lg` that floats in the bottom-inline-end corner —
 * bottom *left* in Persian, because the corner is stated logically and never
 * as `right`. Everything about the button itself (44/48px box, pill radius,
 * hover and press) is the primitive's; this block is only where it sits and
 * how it arrives. The hover lift lives in motion.css with the other lifts.
 * ===================================================================== */

/*
 * Three things share the bottom edge on a phone: the nav, the product page's
 * sticky add-to-cart and this. The offsets stack rather than overlap.
 *
 * `--nk-bottom-nav-space`, not `--nk-bottom-nav-height` — the nav pads itself
 * by the safe-area inset, and every emulator resolves that inset to 0, so the
 * difference is invisible until it is on a real notched phone with the button
 * sitting under the tabs.
 *
 * `--nk-sticky-cta-space` is published by initStickyCta() in ui.js and is
 * `0px` everywhere else, including the moment before the script runs: the bar
 * is a fixed height only while it is on screen, and a hard-coded guess would
 * be wrong for a price that wraps. It is deliberately *not* transitioned —
 * `inset-block-end` is a layout property, and the design system animates
 * transform and opacity only.
 */
.nk-scrolltop {
  position: fixed;
  inset-block-end: calc(
    var(--nk-space-4) + var(--nk-bottom-nav-space) + var(--nk-sticky-cta-space, 0px)
  );
  inset-inline-end: var(--nk-gutter);
  /* Below the header, the bottom nav and every overlay: when the drawer or the
     filter sheet opens, the scrim covers this too, which is what it should do. */
  z-index: var(--nk-z-sticky);
  color: var(--nk-text-strong);
  box-shadow: var(--nk-shadow-md);

  /*
   * At rest, and until the page has actually been scrolled.
   *
   * `visibility` is what takes it out of the tab order — opacity alone leaves
   * an invisible button focusable in the corner of every page, which is the
   * same defect the sticky CTA had. It is transitioned rather than switched so
   * the exit is still painted, and because the duration tokens collapse to 0ms
   * under prefers-reduced-motion, that user gets a plain appear/disappear with
   * no extra rule.
   */
  opacity: 0;
  visibility: hidden;
  transform: translateY(var(--nk-space-2)) scale(0.9);
  transition:
    opacity var(--nk-duration-normal) var(--nk-ease-out),
    transform var(--nk-duration-normal) var(--nk-ease-out),
    visibility var(--nk-duration-normal),
    background-color var(--nk-transition-base),
    box-shadow var(--nk-transition-base);
}

.nk-scrolltop--visible {
  opacity: 1;
  visibility: visible;
  transform: none;
}

@media (min-width: 1024px) {
  /* No bottom nav from here up, and no sticky CTA either — only the inset. */
  .nk-scrolltop {
    inset-block-end: calc(var(--nk-space-6) + var(--nk-safe-bottom));
  }
}

/* =======================================================================
 * FLOATING CONTACT MENU — .nk-contact-fab
 *
 * A coral disc in the bottom-inline-**start** corner — the bottom *right* of
 * the screen in Persian, and the opposite corner from `.nk-scrolltop`, which
 * is what keeps two floating controls apart in either direction without either
 * one knowing about the other.
 *
 * A speed dial, not a dialog: no scrim, no scroll lock, no focus trap. See
 * `initContactFab()` in ui.js and the skill's components-chrome.md.
 * ===================================================================== */

.nk-contact-fab {
  position: fixed;
  /* The same stack the back-to-top button clears: nav (content + safe inset)
     then the product page's sticky bar, which publishes its own height. */
  inset-block-end: calc(
    var(--nk-space-4) + var(--nk-bottom-nav-space) + var(--nk-sticky-cta-space, 0px)
  );
  inset-inline-start: var(--nk-gutter);
  z-index: var(--nk-z-sticky);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--nk-space-3);
  /*
   * The container must not be a click target.
   *
   * It is a fixed flex column that still *reserves* the closed menu's height —
   * 120x260 at 360px — and with a hit area of its own it swallows every click
   * on the page behind it. Found on 2026-08-23 when the product card's new
   * add-to-cart button landed under it in the shop grid and could not be
   * pressed at all: the FAB was receiving the click and doing nothing with it.
   * `visibility: hidden` on the menu is not enough — that stops the *menu*
   * receiving clicks, not this box.
   *
   * The two real controls opt back in below. Do not remove this without
   * giving the container a hit area that matches what is actually visible.
   */
  pointer-events: none;
}

.nk-contact-fab__trigger,
.nk-contact-fab__menu { pointer-events: auto; }

/* ---- The trigger ---------------------------------------------------- */

/*
 * 48px, exactly like `.nk-scrolltop`, so the two corners read as a pair rather
 * than as two components that happen to float. Coral because it is an action
 * — the one place besides the primary CTA where that is allowed — and the
 * accent shadow is the token reserved for a coral action.
 */
.nk-contact-fab__trigger {
  inline-size: var(--nk-touch-target-lg);
  block-size: var(--nk-touch-target-lg);
  display: grid;
  place-items: center;
  border: 0;
  border-radius: var(--nk-radius-pill);
  background-color: var(--nk-action-primary);
  color: var(--nk-text-on-accent);
  box-shadow: var(--nk-shadow-accent);
  cursor: pointer;
  transition: background-color var(--nk-transition-base),
    box-shadow var(--nk-transition-base),
    transform var(--nk-duration-instant) var(--nk-ease-standard);
}
@media (hover: hover) {
  .nk-contact-fab__trigger:hover { background-color: var(--nk-action-primary-hover); }
}
.nk-contact-fab__trigger:active { background-color: var(--nk-action-primary-active); }

/* Both glyphs are printed; which one shows is read off the button's own state,
   so open/close costs no script and the icon cannot drift out of sync. They
   share one grid cell, so swapping them moves nothing. */
.nk-contact-fab__trigger > .nk-icon {
  grid-area: 1 / 1;
  transition: opacity var(--nk-duration-fast) var(--nk-ease-standard),
    transform var(--nk-duration-fast) var(--nk-ease-standard);
}
.nk-contact-fab__icon-close { opacity: 0; transform: rotate(-90deg); }
.nk-contact-fab__trigger[aria-expanded="true"] .nk-contact-fab__icon-open {
  opacity: 0;
  transform: rotate(90deg);
}
.nk-contact-fab__trigger[aria-expanded="true"] .nk-contact-fab__icon-close {
  opacity: 1;
  transform: none;
}

/* ---- The menu ------------------------------------------------------- */

/*
 * `order: -1` puts the list above the trigger in the flex column while leaving
 * the **trigger first in the DOM** — the tab order then goes trigger → actions,
 * which is the order they are used in, and a keyboard user is not walked
 * backwards through four links to reach the control that opens them.
 */
.nk-contact-fab__menu {
  order: -1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--nk-space-2);
  /* `ul[class]` is (0,1,1) in base.css and beats a single class, so the reset
     has to be restated here rather than assumed. */
  margin: 0;
  padding: 0;
  list-style: none;
}

/*
 * `visibility` on the whole list is what takes the closed menu out of the tab
 * order — four `tel:` links parked behind a button are otherwise reachable by
 * keyboard on every page. It is delayed by the length of the exit so the
 * collapse is still painted, exactly as `.nk-sticky-cta` does it.
 */
.nk-contact-fab[data-open="false"] .nk-contact-fab__menu {
  visibility: hidden;
  transition: visibility 0s linear var(--nk-duration-normal);
}

/*
 * **Open is the default state, closed is applied.** `[data-open="false"]` is
 * written by `initContactFab()` on start-up and never by PHP, so with the
 * script blocked or still loading the four links are simply there, above the
 * trigger, working. Nothing this component offers is hidden by a stylesheet.
 */
.nk-contact-fab__item {
  transition: opacity var(--nk-duration-normal) var(--nk-ease-out),
    transform var(--nk-duration-normal) var(--nk-ease-out);
  /* Entering: nearest the trigger first. `--nk-fab-i` is printed per row by
     nk_contact_fab(), because the row count depends on which contact fields
     the shop owner filled in and a stylesheet cannot know that. The divisor
     keeps the whole sequence inside one `--nk-duration-normal` and introduces
     no new timing value. */
  transition-delay: calc(var(--nk-duration-instant) / 2 * var(--nk-fab-i, 0));
}
.nk-contact-fab[data-open="false"] .nk-contact-fab__item {
  opacity: 0;
  transform: translateY(var(--nk-space-2)) scale(0.94);
  /* Leaving, reversed: the row nearest the trigger goes last, so the menu
     collapses towards the control that opened it. */
  transition-delay: calc(
    var(--nk-duration-instant) / 2 * (var(--nk-fab-count, 4) - 1 - var(--nk-fab-i, 0))
  );
}

/* ---- One action row ------------------------------------------------- */

/*
 * A compact pill: the mark on the inline-start edge — the edge the trigger is
 * pinned to — so the four glyphs line up in a column directly above it, then
 * the label. White and raised, the same surface language as a card, rather
 * than a second kind of panel.
 */
.nk-contact-fab__action {
  display: flex;
  align-items: center;
  gap: var(--nk-space-2);
  min-block-size: var(--nk-touch-target);
  padding-inline: var(--nk-space-3);
  border-radius: var(--nk-radius-pill);
  background-color: var(--nk-surface-raised);
  color: var(--nk-text-strong);
  font-size: var(--nk-text-sm);
  font-weight: var(--nk-weight-medium);
  text-decoration: none;
  white-space: nowrap;
  box-shadow: var(--nk-shadow-md);
  transition: background-color var(--nk-transition-base),
    box-shadow var(--nk-transition-base),
    transform var(--nk-duration-instant) var(--nk-ease-standard);
}
@media (hover: hover) {
  .nk-contact-fab .nk-contact-fab__action:hover { color: var(--nk-text-strong); }
}
@media (hover: hover) {
  .nk-contact-fab__action:hover { background-color: var(--nk-navy-50); }
}
.nk-contact-fab__action:active { background-color: var(--nk-navy-100); }

.nk-contact-fab__glyph {
  display: grid;
  place-items: center;
  inline-size: var(--nk-icon-lg);
  block-size: var(--nk-icon-lg);
  flex: none;
}

/*
 * Only the mark carries the third-party colour, never the pill behind it.
 * Four coloured discs in a corner is the clutter this component is trying not
 * to be, and a brand colour as a *surface* would put white text on a value
 * whose contrast nobody controls.
 *
 * Call and SMS are not brands and deliberately take the theme's own colours:
 * inventing a "native" green for each would put three greens in one column.
 */
.nk-contact-fab__action--call .nk-icon { color: var(--nk-status-success); }
.nk-contact-fab__action--sms .nk-icon { color: var(--nk-action-primary); }
.nk-contact-fab__action--instagram .nk-icon { color: var(--nk-brand-instagram); }
.nk-contact-fab__action--whatsapp .nk-icon { color: var(--nk-brand-whatsapp); }

/* ---- Sharing the bottom edge ---------------------------------------- */

/*
 * Two floating controls can both push the toast region up, so each states its
 * own claim and the region takes the larger. One variable per claimant beats
 * one expression that has to be rewritten every time a third appears — and
 * `feedback.css` still owns the offset itself; this only says how much.
 */
body {
  --nk-lift-scrolltop: 0px;
  --nk-lift-contact: 0px;
  --nk-toast-lift: max(var(--nk-lift-scrolltop), var(--nk-lift-contact));
}
body:has(.nk-scrolltop--visible) {
  --nk-lift-scrolltop: calc(
    var(--nk-sticky-cta-space, 0px) + var(--nk-touch-target-lg) + var(--nk-space-3)
  );
}
/* Below 768px the toast region is full-bleed, so it crosses this corner too.
   From 768 it is a 360px panel pinned to the *other* inline edge and the two
   never meet — hence the claim being dropped rather than a max-width query. */
body:has(.nk-contact-fab) {
  --nk-lift-contact: calc(
    var(--nk-sticky-cta-space, 0px) + var(--nk-touch-target-lg) + var(--nk-space-3)
  );
}

@media (min-width: 768px) {
  body:has(.nk-contact-fab) { --nk-lift-contact: 0px; }
}

@media (min-width: 1024px) {
  /* No bottom nav and no sticky CTA from here up — only the inset. */
  .nk-contact-fab {
    inset-block-end: calc(var(--nk-space-6) + var(--nk-safe-bottom));
  }
}

/* =======================================================================
 * BREADCRUMB — .nk-breadcrumb
 * Separators are CSS-generated and direction-aware.
 * ===================================================================== */

.nk-breadcrumb {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: var(--nk-space-2);
  font-size: var(--nk-text-sm);
  color: var(--nk-text-muted);
  padding-block: var(--nk-space-3);
  /* Long trails scroll instead of wrapping into a tall block on mobile. */
  overflow-x: auto;
  scrollbar-width: none;
  white-space: nowrap;
}
.nk-breadcrumb::-webkit-scrollbar { display: none; }

/*
 * The trail is a real <ol>: the order *is* the meaning, and a screen reader
 * should be told how many steps there are and which one this is. So
 * `.nk-breadcrumb` is the scrollport and `__list` is the track inside it.
 *
 * This shape has existed since Woo's own breadcrumb was mapped onto the
 * component for the product page, where `woocommerce.css` states it again at a
 * higher specificity. The product archive is the second consumer, so it belongs
 * here rather than being written a third time. `list-style: none` is the one
 * declaration base.css does not already provide — its `ol[class]` reset covers
 * the margin and the padding but leaves the markers.
 */
.nk-breadcrumb__list {
  display: flex;
  align-items: center;
  gap: var(--nk-space-2);
  list-style: none;
}
.nk-breadcrumb__item { display: flex; align-items: center; gap: var(--nk-space-2); }
.nk-breadcrumb__item + .nk-breadcrumb__item::before {
  content: "/";
  color: var(--nk-text-subtle);
}
[dir="rtl"] .nk-breadcrumb__item + .nk-breadcrumb__item::before { content: "\\"; }
.nk-breadcrumb a {
  color: inherit;
  text-decoration: none;
  /* Meets the 44px touch minimum without making the trail look tall.
     Short Persian crumbs like "خانه" measure ~23px wide, just under the
     24px WCAG 2.5.8 floor, so the inline padding is load-bearing. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-block-size: var(--nk-touch-target);
  min-inline-size: 24px;
  padding-inline: var(--nk-space-1);
}
@media (hover: hover) {
  .nk-breadcrumb a:hover { color: var(--nk-text-accent); }
}
.nk-breadcrumb__item[aria-current="page"] { color: var(--nk-text-strong); font-weight: var(--nk-weight-medium); }

/* =======================================================================
 * FOOTER — .nk-footer
 * Mobile: accordion column groups. Desktop: 4-column grid.
 * ===================================================================== */

.nk-footer {
  margin-block-start: var(--nk-section-gap);
}
/**
 * The dark plane is this wrapper, not .nk-footer.
 *
 * The contact band is a child of <footer> and its cards are now navy — the
 * footer's own navy. Painting the ground on an inner wrapper leaves the band
 * above it, on the page's cream, where a navy card is legible, and keeps the
 * band inside the footer where it belongs. See nk_footer().
 */
.nk-footer__body {
  background-color: var(--nk-surface-inverse);
  color: var(--nk-cream-300);
  padding-block: var(--nk-space-10) var(--nk-space-6);
}
.nk-footer__body a { color: var(--nk-cream-300); text-decoration: none; }
@media (hover: hover) {
  .nk-footer__body a:hover { color: var(--nk-white); }
}

.nk-footer__grid { display: grid; gap: var(--nk-space-8); }
.nk-footer__brand { max-inline-size: 44ch; }
.nk-footer__logo { display: block; margin-block-end: var(--nk-space-4); }
.nk-footer__logo .nk-logo__img { block-size: 48px; inline-size: auto; }
.nk-footer__tagline {
  margin: 0;
  font-size: var(--nk-text-base);
  line-height: var(--nk-leading-relaxed);
  color: var(--nk-cream-300);
}
/* The one Brand Heart on the page. */
.nk-footer__origin {
  display: flex;
  align-items: center;
  gap: var(--nk-space-2);
  margin-block: var(--nk-space-4) 0;
  font-size: var(--nk-text-sm);
  color: var(--nk-navy-200);
}

.nk-footer__title {
  font-size: var(--nk-text-md);
  font-weight: var(--nk-weight-semibold);
  color: var(--nk-white);
  margin-block-end: var(--nk-space-3);
}

/**
 * Link columns.
 *
 * Every row is exactly one touch target tall and the gap is zero. They were
 * `min-block-size: 44px` links inside a `gap: 4px` grid, which stacked into a
 * list whose rhythm changed with the length of each label — the columns read
 * as three different components sitting next to each other. One row height,
 * one rhythm, all four columns.
 */
/**
 * Two sub-columns from 480px, one below it.
 *
 * The footer went from four columns to three, and the two link columns became
 * one — so this list carries every site link on its own. As a single column of
 * nine it was taller than the brand block beside it and dragged the footer's
 * whole height with it.
 *
 * Two *explicit* columns, not `auto-fill` with a track floor: at 768px the
 * links column is ~265px wide and a 140px floor silently resolved to one
 * column, which is the width where two are most wanted. `minmax(0, 1fr)` is
 * what keeps a long label from pushing the track wide instead of wrapping.
 */
.nk-footer__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0 var(--nk-space-4);
}
@media (min-width: 480px) {
  .nk-footer__list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.nk-footer__list a {
  display: flex;
  align-items: center;
  /* Room for the marker, which is positioned rather than a list-style so it
     can be sized and coloured. */
  gap: var(--nk-space-2);
  /* 32px rows with a mouse. A footer column of eight links at the 44px touch
     target is 350px tall — taller than the brand column beside it, which is
     what made the columns look ragged. The 24px WCAG 2.5.8 floor still holds
     with room to spare, and the touch bump below restores 44px where a finger
     is actually doing the pointing. */
  min-block-size: var(--nk-space-8);
  font-size: var(--nk-text-base);
  line-height: var(--nk-leading-snug);
}
@media (pointer: coarse) {
  .nk-footer__list a { min-block-size: var(--nk-touch-target); }
}
/**
 * The coral marker.
 *
 * A dot, not the Brand Heart. The heart is a brand motif with a hard rule — at
 * most once per screenful, never as a repeating element — and nine of them down
 * a footer column would spend the whole motif on a bullet list. The one heart on
 * this page stays in .nk-footer__origin.
 *
 * A pseudo-element rather than `list-style`, so it can take the accent colour
 * and a size, and so it sits on the anchor's first line rather than the row.
 */
.nk-footer__list a::before {
  content: "";
  flex: 0 0 auto;
  inline-size: 5px;
  block-size: 5px;
  border-radius: var(--nk-radius-circle);
  background-color: var(--nk-action-primary);
  transition: transform var(--nk-transition-base);
}
@media (hover: hover) {
  .nk-footer__list a:hover::before { transform: scale(1.6); }
}

/* Contact block — shared by the footer and the drawer foot, so a phone number
   can never look like two different components. */
.nk-contact { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
/**
 * The icon column is fixed and the icon is centred in it.
 *
 * `align-items: center` on the row centred the icon against the *whole* item,
 * so a two-line address dropped its pin to the middle of the second line and
 * the column stopped reading as a column. Aligning to the start and giving the
 * icon the height of one text line puts it on the first line every time,
 * whatever the value wraps to.
 */
.nk-contact__item {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  align-items: start;
  gap: var(--nk-space-2);
  min-block-size: var(--nk-touch-target);
  font-size: var(--nk-text-base);
  line-height: var(--nk-leading-snug);
}
.nk-contact__item > .nk-icon {
  flex: 0 0 auto;
  color: var(--nk-text-subtle);
  /* One line box tall, so the glyph optically centres on the first line. */
  block-size: calc(var(--nk-text-base) * var(--nk-leading-snug));
}
/* A phone number is a tel: link and a real tap target. At the natural line
   height it measured 23px — one pixel under WCAG 2.5.8's 24px floor. */
/**
 * The value box never carries `direction: ltr` itself — see nk_contact_lines(),
 * where the isolation lives on an inner <bdi>. An LTR flex anchor resolves its
 * own start edge to the left, which is what used to throw the phone number and
 * the email address to the far side of the column while the Persian address
 * stayed on the right.
 */
.nk-contact__item a,
.nk-contact__item > span {
  display: flex;
  align-items: center;
  min-block-size: var(--nk-touch-target);
  text-decoration: none;
  /* Fill the cell and align to the grid's own start, rather than shrinking to
     the value: a shrink-wrapped box has no start edge to share with the row
     above it, which is what made four rows read as four indents. */
  justify-self: stretch;
  text-align: start;
}

/* =======================================================================
 * CONTACT CARDS — .nk-contact-cards
 * The band that bridges the page and the footer: address, email, phone, one
 * navy card each, sitting on the cream ground just above the footer's plane.
 * ===================================================================== */

/**
 * Two classes deep, and that is load-bearing.
 *
 * base.css resets lists with `ul[class], ol[class] { margin: 0 }` — (0,1,1),
 * which beats a single class no matter how late it is declared. A bare
 * `.nk-contact-cards { margin-block: … }` computes to 0 and the cards sit
 * flush against .nk-footer__body. Same trap as Woo's `.woocommerce-page img`;
 * the answer is specificity, never !important.
 */
.nk-footer .nk-contact-cards {
  list-style: none;
  padding: 0;
  display: grid;
  gap: var(--nk-space-3);
  /* Nothing negative here any more: the band sits above the dark plane rather
     than over its edge, so it does not have to guess its own height. The small
     end margin is the only gap between the cards and the navy. */
  margin-block: 0 var(--nk-space-3);
  margin-inline: 0;
}

/* The card itself is the anchor when the fact is dialable or mailable — see
   nk_contact_cards() for why the value alone was not a legal target. */
.nk-footer .nk-contact-card {
  display: flex;
  align-items: center;
  gap: var(--nk-space-3);
  padding: var(--nk-space-3) var(--nk-space-4);
  /* The same navy as the footer's plane, deliberately: the three cards read as
     the top edge of the footer stepping out onto the page, not as a separate
     component parked above it. Legible only because .nk-footer__body carries
     the ground and this band sits above it — see .nk-footer__body. */
  background-color: var(--nk-surface-inverse);
  border-radius: var(--nk-radius-lg);
  box-shadow: var(--nk-shadow-md);
  min-inline-size: 0;
  text-decoration: none;
  transition: box-shadow var(--nk-transition-base), transform var(--nk-transition-base);
}
@media (hover: hover) {
  a.nk-contact-card:hover { box-shadow: var(--nk-shadow-lg); }
}
@media (hover: hover) {
  a.nk-contact-card:hover .nk-contact-card__value { color: var(--nk-text-accent-inverse); }
}
/* The coral disc is a fill, not text, so the brand accent is allowed here —
   and it is the only coral in the footer besides the Brand Heart. */
.nk-contact-card__icon {
  flex: 0 0 auto;
  inline-size: var(--nk-touch-target);
  block-size: var(--nk-touch-target);
  display: grid;
  place-items: center;
  border-radius: var(--nk-radius-circle);
  background-color: var(--nk-action-primary);
  color: var(--nk-white);
}
/**
 * Each value gets its own box, and that is the point of the component.
 *
 * As rows of a shared icon+value list these three never lined up: the address
 * wraps to two lines, the email is a Latin run, the phone is a digit run, so
 * every row resolved its own baseline and inline start. One card each means
 * the three *cards* stay aligned and the values inside them are free to be
 * different shapes.
 */
.nk-contact-card__body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-inline-size: 0;
}
.nk-contact-card__label {
  font-size: var(--nk-text-sm);
  font-weight: var(--nk-weight-semibold);
  color: var(--nk-white);
}
/**
 * Scoped to .nk-footer, and that is load-bearing.
 *
 * The band sits outside `.nk-footer__body`, so the footer's own link colour no
 * longer reaches it — a bare `.nk-contact-card__value` would inherit the page's
 * dark body colour and print navy on navy. The value carries its on-dark colour
 * itself, and the two-class scope keeps it ahead of anything single-class.
 */
.nk-footer .nk-contact-card__value {
  font-size: var(--nk-text-sm);
  line-height: var(--nk-leading-snug);
  color: var(--nk-cream-300);
  text-decoration: none;
  /* Long enough to wrap rather than push the card past the grid track. */
  overflow-wrap: anywhere;
}


/* =======================================================================
 * FOOTER MAP — .nk-footer__map
 * One pre-composed image, not an <iframe>. See nk_footer_map() for why, and
 * tools/build-static-map.py for how it is built.
 * ===================================================================== */

.nk-footer__map { margin-block-end: var(--nk-space-3); }
.nk-footer__map-link {
  position: relative;
  display: block;
  border-radius: var(--nk-radius-lg);
  overflow: hidden;
  border: var(--nk-border-width) solid var(--nk-border-inverse);
  transition: border-color var(--nk-transition-base);
}
@media (hover: hover) {
  .nk-footer__map-link:hover { border-color: var(--nk-action-primary); }
}
/* Two classes deep: Woo ships `.woocommerce-page img { height: auto }`, which
   out-specifies a single-class rule on every commerce route. */
.nk-footer__map .nk-footer__map-img {
  display: block;
  inline-size: 100%;
  block-size: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}
/* The label sits on the image, over a scrim strong enough to hold white text
   at AA whatever the tiles underneath happen to be. */
.nk-footer__map-cta {
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--nk-space-1);
  min-block-size: var(--nk-touch-target);
  padding-inline: var(--nk-space-3);
  background-color: rgb(16 26 44 / 0.72);
  color: var(--nk-white);
  font-size: var(--nk-text-sm);
  font-weight: var(--nk-weight-medium);
}
/* No image built yet, or the pin has moved since it was: the label is the
   whole control and needs to look like one on its own. */
.nk-footer__map-link:not(:has(.nk-footer__map-img)) {
  border: 0;
  border-radius: var(--nk-radius-md);
}
.nk-footer__map-link:not(:has(.nk-footer__map-img)) .nk-footer__map-cta {
  position: static;
  justify-content: flex-start;
  background: none;
  color: var(--nk-cream-300);
  padding-inline: 0;
}
.nk-footer__map-credit {
  margin-block: var(--nk-space-1) 0;
  font-size: var(--nk-text-2xs);
  color: var(--nk-navy-300);
}

.nk-footer__hours {
  display: flex;
  align-items: center;
  gap: var(--nk-space-2);
  margin-block: var(--nk-space-3) 0;
  font-size: var(--nk-text-sm);
  color: var(--nk-cream-300);
}
.nk-footer__hours .nk-icon { flex: 0 0 auto; color: var(--nk-navy-300); }
/* The drawer sits on the cream ground, not the navy footer. The anchor colour
   is set explicitly because theme.json paints every link coral, and coral is
   reserved for actions — a phone number is not one, and three coral items in
   one panel reads as three competing CTAs. */
.nk-drawer__foot .nk-contact { color: var(--nk-text-muted); }
.nk-drawer__foot .nk-contact a { color: var(--nk-text-default); }
@media (hover: hover) {
  .nk-drawer__foot .nk-contact a:hover { color: var(--nk-text-accent); }
}
.nk-drawer__foot .nk-footer__social { border-color: var(--nk-border-default); color: var(--nk-text-muted); }

.nk-footer__socials { display: flex; gap: var(--nk-space-2); margin-block-start: var(--nk-space-5); }
.nk-footer__social {
  inline-size: var(--nk-touch-target);
  block-size: var(--nk-touch-target);
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  border-radius: var(--nk-radius-circle);
  border: var(--nk-border-width) solid var(--nk-border-inverse);
  color: var(--nk-cream-300);
  transition: background-color var(--nk-transition-base), border-color var(--nk-transition-base), color var(--nk-transition-base);
}
/* Filled brand glyphs read heavier than Lucide's strokes at the same box, so
   they stay at the default icon size inside the 44px ring rather than being
   bumped up — the Instagram mark was spilling over its own border. */
.nk-footer__social .nk-icon { inline-size: var(--nk-icon-md); block-size: var(--nk-icon-md); }
@media (hover: hover) {
  .nk-footer__social:hover { background-color: var(--nk-action-primary); border-color: transparent; color: var(--nk-white); }
}

/* =======================================================================
 * TRUST BAND — .nk-footer__trust
 * Iranian storefronts carry نماد اعتماد and ساماندهی. An Iranian buyer looks
 * for them deliberately, so they get their own band rather than a corner of
 * the legal line.
 * ===================================================================== */

/* The break above this band is `nk_divider( 'mark' )`, not a border of its
   own — two rules in the same place read as a double line. */
.nk-footer__trust {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--nk-space-3);
}

/* The footer's own dividers carry the section rhythm, so they override the
   component's default block margin rather than adding to it. */
.nk-footer__divider { margin-block: var(--nk-space-6); }
@media (min-width: 768px) {
  .nk-footer__divider { margin-block: var(--nk-space-8); }
}
.nk-footer__trust-title {
  font-size: var(--nk-text-sm);
  font-weight: var(--nk-weight-medium);
  color: var(--nk-navy-200);
}
.nk-footer__trust-marks { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--nk-space-4); }
.nk-footer__trust-marks a { display: inline-flex; }
.nk-footer__trust img {
  block-size: 96px;
  inline-size: auto;
  border-radius: var(--nk-radius-md);
  background: var(--nk-white);
}

/* The legal line is centred at every width — it belongs to nobody's column. */
.nk-footer__bottom {
  margin-block-start: var(--nk-space-6);
  padding-block-start: var(--nk-space-5);
  border-block-start: var(--nk-border-width) solid var(--nk-border-inverse);
  text-align: center;
  font-size: var(--nk-text-sm);
  color: var(--nk-navy-200);
}
.nk-footer__copy { margin: 0; }

/*
 * The links column is desktop-only, at the shop owner's request (2026-08-23).
 *
 * On a phone the footer is a long scroll a buyer reaches at the end of one,
 * and eight text links stacked in it repeat what the bottom nav and the drawer
 * already offer with a thumb's reach. `display: none` rather than a PHP branch:
 * the footer is served from one full-page cache to every device, so there is no
 * viewport to test when it renders — and it takes the column out of the
 * accessibility tree along with the pixels, which is the intent.
 *
 * **Know what this costs.** The drawer deliberately does not carry the four
 * site links (see the skill's `components-chrome-mobile.md`) on the argument
 * that they live in the footer — so below 768px درباره ما and حساب کاربری من
 * now have no link anywhere except the bottom nav's profile tab, and تماس با ما
 * only the contact FAB. If those need a home on a phone, the drawer is where
 * they go back; do not undo this rule to get them.
 */
.nk-footer__col--links { display: none; }

@media (min-width: 768px) {
  .nk-footer__col--links { display: block; }
  /* Three columns: brand · لینک‌های مفید · نشانی فروشگاه. The links column is
     the widest of the three because it holds two sub-columns of its own. */
  .nk-footer__grid { grid-template-columns: 1.3fr 1.4fr 1.1fr; gap: var(--nk-space-8); }
  /* Three across, matching the three facts. Below this they stack: at 360px a
     third of the width is narrower than the address itself. */
  .nk-footer .nk-contact-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--nk-space-4); }
}

@media (min-width: 1024px) {
  .nk-footer__body { padding-block: var(--nk-space-12) var(--nk-space-8); }
  .nk-footer__grid { grid-template-columns: 1.4fr 1.4fr 1.2fr; gap: var(--nk-space-12); }
  .nk-footer__logo .nk-logo__img { block-size: 60px; }
  .nk-footer .nk-contact-cards { margin-block-end: var(--nk-space-4); }
  /* Desktop has the width for the seals at full size; below it they would
     take the whole column. */
  .nk-footer__trust img { block-size: 120px; }
}
