/* ==========================================================================
   Pet Saze — core stylesheet
   Hand-written. No framework, no reset library, no builder output.

   Design system v2. Colours are sampled from the logo: orange is the mark,
   the neutral ramp is the charcoal of the wordmark. The page is one white
   sheet divided by hairlines, not by alternating grounds.

   Rules that hold everywhere:
   - Orange is the primary action AND the brand. Its label is always charcoal:
     white on #F66F00 is 2.92:1 and fails AA, charcoal on it is 5.53:1.
   - Accent-coloured *text* on white uses #DC5F00, never #F66F00 — the brand
     orange is 2.79:1 as text and is only ever a fill.
   - Ad status (red / green / blue) sits outside the orange family, so "lost"
     never competes with "buy".
   - NEVER set letter-spacing on Persian text: it breaks the cursive joins.
     Typographic personality comes from size, weight and leading only.
   ========================================================================== */

/* --------------------------------------------------------------- 1. Fonts */

/* Dana, three weights. Medium (500) carries every label, button and card
   title in the design system — without it the interface falls back to
   Regular and the hierarchy collapses. */
@font-face {
  font-family: 'Dana';
  src: url('../fonts/Dana-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Dana';
  src: url('../fonts/Dana-Medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Dana';
  src: url('../fonts/Dana-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* -------------------------------------------------------------- 2. Tokens */

/* Sampled from the logo, not guessed. Orange is the brand mark; the neutral
   ramp is the charcoal of the wordmark. Ad status lives on its own three
   hues so "lost" never has to compete with the brand for attention. */

:root {
  /* Brand */
  --brand:        #F66F00;   /* the mark, and every primary action */
  --brand-hover:  #DC5F00;   /* hover, and accent-coloured TEXT on white */
  --brand-light:  #FF9B3D;
  --brand-surface:#FFF4E9;   /* tinted ground, secondary button */

  /* Neutral ramp */
  --ink:        #1F2124;   /* 16.14:1 on white */
  --ink-deep:   #15171A;
  --ink-soft:   #565C63;   /* 6.76:1 — secondary text */
  --ink-muted:  #6C727B;   /* 4.85:1 on white, 4.52:1 on --mist — safe for the
                              11-13px metadata it is actually used for. It was
                              #8B9199 (3.18:1), which the card counts, chip
                              numbers and captions all failed AA at. */
  --line:       #E7E9EC;
  --line-soft:  #F1F3F5;

  /* Ad status — deliberately outside the orange family */
  --lost:       #D93A2B;  --lost-bg:  #FDECEA;
  --found:      #12905C;  --found-bg: #E6F5EE;
  --adopt:      #2F6FE0;  --adopt-bg: #EAF1FD;
  --pending:    #8B6A08;  --pending-bg: #FBF3DC;

  /* Every hue above is sized for a dot, a bar or a border, where 3:1 is the
     bar. As pill TEXT on its own tint each one lands short of AA (4.00 / 3.61
     / 4.14), so text gets its own step: same hue and saturation, lightness
     walked down until the pair clears 4.5. --pending already cleared at 4.55
     and is aliased unchanged so nothing has to remember the exception. */
  --lost-ink:    #CB3324;
  --found-ink:   #107D50;
  --adopt-ink:   #2367DE;
  --pending-ink: var(--pending);

  /* Orange as TEXT. --brand is 2.79:1 on white and --brand-hover is 3.70:1 —
     both fine for an icon, both short for a word. This one clears 4.5 on white
     AND on --sand, which is where the announce bar and the eyebrows live. */

  /* A button fill dark enough to carry a white label. The brand orange is
     #F66F00 and white on it is 2.92:1 — below AA at every size and weight, so
     a white-labelled button cannot use it. These are the same hue walked down
     until white clears 4.5. The bright orange keeps every job that is not a
     text ground: dots, badges, the pagination chip, focus rings. */
  --brand-btn:       #BB5100;   /* white 4.90:1 */
  --brand-btn-hover: #A84900;   /* white 5.80:1 */

  --brand-ink:  #BB5100;

  /* Grounds */
  --paper:      #FFFFFF;
  --mist:       #F6F7F8;   /* the one neutral ground */
  --sand:       #FFF4E9;   /* the one warm ground */

  /* Legacy aliases — the shop, magazine and petban sheets still speak these */
  --accent:     var(--brand);
  --accent-ink: var(--brand-ink);
  --ok:         var(--found);
  --warn:       var(--brand-hover);

  /* Module — 4px */
  --u: 4px;
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 24px; --s6: 32px; --s7: 48px; --s8: 64px; --s9: 96px;

  /* Radius. A Persian shop reads as a stack of rounded cards, so the card
     step is the one everything else is measured against. */
  --r-sm:    8px;    /* inputs, small chips */
  --r-card:  12px;   /* cards, tiles, banners */
  --r-block: 18px;   /* panels, hero */
  --r-pill:  999px;  /* buttons, status pills */
  --r-arch:  var(--r-card);

  /* Card chrome — used by every merchandising surface so a page of them
     reads as one material. */
  --card-border: 1px solid var(--line);
  --card-shadow: 0 1px 2px rgba(31, 33, 36, .04);

  /* Elevation — one soft layer, never stacked */
  --shadow: 0 2px 10px rgba(31, 33, 36, .06);
  --shadow-lift: 0 8px 24px rgba(31, 33, 36, .10);

  /* Type — Persian needs generous leading */
  --font: 'Dana', system-ui, 'Segoe UI', Tahoma, sans-serif;
  --t-xxs: .6875rem;  /* 11 / 20 */
  --t-xs:  .8125rem;  /* 13 / 22 */
  --t-sm:  .875rem;   /* 14 / 24 */
  --t-md:  1rem;      /* 16 / 30 */
  --t-lg:  .9375rem;  /* 15 / 28 — button and input label */
  /* The display end of the scale was set for a Latin page and read a size
     too large in Persian, where Dana's tall x-height and the 1.9 leading
     already make a heading feel bigger than its number. Every step above
     body has come down one notch; the line-heights are unitless, so the
     leading followed on its own. */
  --t-xl:  1.25rem;   /* 20 / 31 — card title */
  --t-2xl: 1.5rem;    /* 24 / 34 */
  --t-3xl: 1.75rem;   /* 28 / 38 — section title */
  --t-4xl: 2.25rem;   /* 36 / 46 — display */

  /* Layout */
  --wrap: 1440px;         /* 1280 of content inside 80px margins */
  --wrap-read: 720px;     /* article measure, excluding the gutter */
  --gutter: 80px;
  --header-h: 96px;
  --chrome-h: 154px;      /* header row + nav row + their two hairlines */
}

@media (max-width: 1100px) {
  :root { --gutter: 24px; }
}

@media (max-width: 899px) {
  /* The nav row is hidden on small screens, so only the header row sticks. */
  :root { --chrome-h: 64px; }
}

@media (max-width: 700px) {
  :root { --t-3xl: 1.5rem; --t-4xl: 1.875rem; --gutter: 16px; --header-h: 64px; }
}

/* ---------------------------------------------------------------- 3. Base */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + var(--s5));
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: var(--t-md);
  line-height: 1.875;   /* 16/30, straight off the type scale */
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
  margin: 0 0 var(--s3);
  font-weight: 700;
  letter-spacing: normal; /* explicit: never spaced, it breaks the joins */
}
h1 { font-size: var(--t-4xl); line-height: 1.273; }  /* 44/56 */
h2 { font-size: var(--t-3xl); line-height: 1.375; }  /* 32/44 */
h3 { font-size: var(--t-xl);  line-height: 1.545; font-weight: 500; }  /* 22/34 */
h4 { font-size: var(--t-md);  line-height: 1.625; font-weight: 500; }

p { margin: 0 0 var(--s4); }

a { color: var(--ink); text-decoration-color: var(--line); text-underline-offset: 4px; }
a:hover { text-decoration-color: var(--brand); }

img, svg, video { max-width: 100%; height: auto; display: block; }

ul, ol { margin: 0 0 var(--s4); padding-inline-start: 1.4em; }

button, input, select, textarea { font: inherit; color: inherit; }

:focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* Fields. 4px radius, hairline border, and an orange focus ring that is never
   removed — the design system calls that out explicitly. */
input[type="text"], input[type="search"], input[type="email"], input[type="tel"],
input[type="url"], input[type="number"], input[type="password"], select, textarea {
  min-height: 54px;
  padding: 0 var(--s4);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--paper);
  font-size: var(--t-lg);
}
textarea { padding-block: var(--s3); min-height: 120px; }

input[type="checkbox"], input[type="radio"] {
  width: 18px;
  height: 18px;
  accent-color: var(--brand);
}
input[type="checkbox"] { border-radius: var(--r-sm); }

/* The searchform owns its own border, so its inner input must not draw a
   second one inside it. Scoped to the form on purpose: the bare class loses
   to the `input[type="search"]` rule above, which is one specificity step
   heavier, and the field ended up with a box inside a box. */
.searchform .searchform__input {
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  font-size: var(--t-sm);
}

.screen-reader-text {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; inset-inline-start: var(--s4); top: -100px;
  z-index: 999; background: var(--ink); color: #fff;
  padding: var(--s3) var(--s4); border-radius: var(--r-sm);
}
.skip-link:focus { top: var(--s3); }

/* -------------------------------------------------------------- 4. Layout */

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
/* The read measure is content width, so the gutter is added on top of it
   rather than eaten out of it. */
.wrap--read { max-width: calc(var(--wrap-read) + var(--gutter) * 2); }

.section { padding-block: var(--s7); }
.section--tight { padding-block: var(--s6); }
.section--rule { border-top: 1px solid var(--line); }
.section--mist { background: var(--mist); }
.section--sand { background: var(--sand); }
.section--ink  { background: var(--ink); color: #fff; }
.section--ink a { color: #fff; }

@media (max-width: 700px) {
  .section { padding-block: var(--s7); }
}

/* A section header that states what the block is and offers one way out. */
.section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  margin-bottom: var(--s5);
}
.section-head h2 {
  margin: 0;
  font-size: var(--t-2xl);
  line-height: 1.429;
}
.section-head .more {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s2) var(--s4);
  min-height: 36px;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  font-size: var(--t-xs);
  line-height: 1.846;
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
  background: var(--paper);
}
.section-head .more:hover { border-color: var(--brand); color: var(--brand-ink); }

/* More air between rows than between columns: a card carries its text under
   its image, so the gap below one card has a title and a meta line pressed
   against the next card's picture, while the gap beside it has nothing in it. */
.grid { display: grid; gap: var(--s5) var(--s4); }
.grid--5 { grid-template-columns: repeat(5, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--2 { grid-template-columns: repeat(2, 1fr); }

@media (max-width: 1180px) {
  .grid--5 { grid-template-columns: repeat(4, 1fr); }
}
@media (max-width: 1000px) {
  .grid--5, .grid--4 { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 760px) {
  .grid--5, .grid--4, .grid--3 { grid-template-columns: repeat(2, 1fr); }
  .grid--2 { grid-template-columns: 1fr; }
  .grid { gap: var(--s3); }
}

/* ---------------------------------------------------------- 5. Primitives */

/* Four buttons, all pill-shaped and 54 tall. The primary label is CHARCOAL,
   never white: white on #F66F00 measures 2.92:1 and fails AA, while charcoal
   on it measures 5.53:1 and passes. This is not a style preference. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  padding: 0 var(--s5);
  min-height: 54px;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  background: var(--brand-btn);
  color: #fff;
  font-weight: 500;
  font-size: var(--t-lg);
  line-height: 1.867;
  text-decoration: none;
  cursor: pointer;
  transition: background .18s ease, border-color .18s ease, transform .18s ease;
}
.btn:hover { background: var(--brand-btn-hover); color: #fff; }
.btn:active { transform: translateY(1px); }

/* Secondary — the tinted brand surface. Same shape, quieter voice. */
.btn--secondary {
  background: var(--brand-surface);
  color: var(--ink);
}
.btn--secondary:hover { background: #FFE8D2; color: var(--ink); }

/* Ghost — white with a hairline. For "see all" and other exits. */
.btn--ghost {
  background: var(--paper);
  color: var(--ink);
  border-color: var(--line);
}
.btn--ghost:hover { background: var(--mist); border-color: var(--ink-muted); color: var(--ink); }

.btn--on-ink {
  background: #fff;
  color: var(--ink);
}
.btn--on-ink:hover { background: var(--sand); color: var(--ink); }

/* .btn--accent predates v2, when orange was the exception. In v2 orange IS
   the primary button, so this is kept only so existing markup keeps working. */
.btn--accent { background: var(--brand-btn); color: #fff; border-color: transparent; }
.btn--accent:hover { background: var(--brand-btn-hover); color: #fff; }

.btn[disabled], .btn--disabled {
  background: var(--line);
  color: var(--ink-muted);
  cursor: not-allowed;
  pointer-events: none;
}

.btn--sm { min-height: 44px; font-size: var(--t-sm); padding: 0 var(--s4); }
.btn--wide { width: 100%; }

/* .btn--accent predates v2, when orange was the exception rather than the
   primary. Kept as an alias so existing markup keeps working. */
.btn--accent {
  background: var(--brand-btn);
  color: #fff;
  border-color: var(--brand-btn);
}
.btn--accent:hover { background: #d76800; }

/* Orange is a signal, so it appears as a small filled chip with navy text —
   never as the primary button, which would fail contrast. */
.tag {
  display: inline-block;
  padding: 2px var(--s3);
  border-radius: var(--r-pill);
  font-size: var(--t-xs);
  font-weight: 700;
  line-height: 1.8;
}
.tag--sale { background: var(--brand); color: var(--ink); }

/* ----------------------------------------------------------- Product card */

/* The funnyfuzzy pattern, rebuilt: primary image with a second on hover,
   title, strike-through price, colour swatches, one badge.

   In v2 the price is charcoal, not orange. The discount badge is the only
   orange on the card, so a row of products has exactly as many orange marks
   as it has genuine discounts — orange stays a signal instead of decoration. */
.card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--paper);
  border: var(--card-border);
  border-radius: var(--r-card);
  padding: var(--s2);
  transition: border-color .18s ease, box-shadow .18s ease;
}
.card:hover { border-color: var(--brand); box-shadow: var(--card-shadow); }

.card__media {
  position: relative;
  display: block;
  aspect-ratio: 1 / 1;
  border-radius: 10px;
  overflow: hidden;
  background: var(--mist);
}
.card__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity .3s ease;
}
.card__img--hover { opacity: 0; }
.card:hover .card__img--hover,
.card:focus-within .card__img--hover { opacity: 1; }

.card__badge {
  position: absolute;
  inset-inline-start: 10px;
  top: 10px;
  z-index: 2;
  font-size: var(--t-xxs);
  line-height: 1.818;
  font-weight: 500;
}

.card__body { padding: var(--s3) var(--s2) var(--s2); display: grid; gap: var(--s2); }

/* The price sits on the card floor, so a row of cards ends level even when one
   title wraps to two lines and another does not. There is no add-to-cart button
   here: most of the catalogue is variable, and a one-click control that can only
   ever open the product page is a button that lies about what it does. */
.card__foot {
  display: flex;
  align-items: center;
  margin-top: auto;
  padding-top: var(--s1);
}

.card__title {
  font-size: var(--t-sm);
  line-height: 1.714;
  margin: 0;
  font-weight: 400;
  color: var(--ink);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: calc(2 * 1.714em);
}
.card__title a { text-decoration: none; }
.card__title a:hover { text-decoration: underline; text-decoration-color: var(--brand); }

/* Price: charcoal at 15/28 Medium, with the struck-through old price dropping
   to 11/20 muted beside it. */
.card__price {
  margin: 0;
  min-width: 0;
  font-weight: 500;
  font-size: var(--t-sm);
  line-height: 1.714;
  color: var(--ink);
}
.card__price del {
  margin-inline-end: var(--s2);
  color: var(--ink-muted);
  font-weight: 400;
  font-size: var(--t-xxs);
  text-decoration-thickness: 1px;
}
.card__price ins { text-decoration: none; }
.card__price .unit,
.card__price .woocommerce-Price-currencySymbol {
  font-size: var(--t-xs);
  font-weight: 400;
  color: var(--ink-muted);
}

.card__stock--out { margin: 0; font-size: var(--t-sm); color: var(--ink-muted); }

/* Swatches */
.swatches { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
.swatch {
  width: 18px;
  height: 18px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: var(--mist);
}
.swatch--plain { background: repeating-linear-gradient(45deg, #fff 0 4px, var(--mist) 4px 8px); }
.swatch--more {
  width: auto;
  min-width: 18px;
  padding: 0 6px;
  border: 0;
  background: transparent;
  font-size: var(--t-xs);
  color: var(--ink-muted);
  line-height: 18px;
}

/* A featured flag is not a discount, so it stays charcoal — orange on a card
   has to mean "this one is cheaper than it was", or it stops meaning anything. */
.tag--new  { background: var(--ink); color: #fff; }
.tag--soft { background: var(--mist); color: var(--ink-soft); }

/* Ad status. Each state is a tinted pill with a solid dot in its own hue —
   the dot is what stays readable when the pill sits on a photo. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  padding: 0 var(--s3);
  min-height: 36px;
  border-radius: var(--r-pill);
  font-size: var(--t-xs);
  font-weight: 500;
  line-height: 1.846;
  white-space: nowrap;
}
.pill::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}
.pill--lost    { background: var(--lost-bg);    color: var(--lost-ink); }
.pill--found   { background: var(--found-bg);   color: var(--found-ink); }
.pill--adopt   { background: var(--adopt-bg);   color: var(--adopt-ink); }
.pill--pending { background: var(--pending-bg); color: var(--pending-ink); }

.rule {
  height: 1px;
  background: var(--line);
  border: 0;
  margin: var(--s6) 0;
}

/* Six across on desktop — the reference fits the entire shop entrance in one
   row rather than spending a screen on four large tiles. */
.grid--6 { grid-template-columns: repeat(6, 1fr); }
@media (max-width: 1180px) { .grid--6 { grid-template-columns: repeat(4, 1fr); } }
@media (max-width: 760px)  { .grid--6 { grid-template-columns: repeat(3, 1fr); } }

.cattiles .cattile {
  text-align: center;
  padding: var(--s3);
  border: var(--card-border);
  border-radius: var(--r-card);
  background: var(--paper);
  transition: border-color .18s ease;
}
.cattiles .cattile:hover { border-color: var(--brand); }
.cattiles .cattile__media {
  aspect-ratio: 1 / 1;
  margin-bottom: var(--s2);
  border-radius: 10px;
  background: var(--mist);
}
.cattiles .cattile__name { font-size: var(--t-sm); line-height: 1.714; }
.cattiles .cattile__count { font-size: var(--t-xxs); }

/* ------------------------------------------------- 6. Category tile & arch */

/* The v2 category tile. Image, name, one line of detail — no overlay label,
   no doorway shape. The name carries the weight and the detail line stays
   muted, so a row of four reads as one texture. */
.cattile {
  display: block;
  text-decoration: none;
  color: inherit;
}
.cattile__media {
  display: block;
  aspect-ratio: 292 / 190;
  border-radius: var(--r-card);
  overflow: hidden;
  background: var(--mist);
  margin-bottom: var(--s3);
}
.cattile__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .4s ease; }
.cattile:hover .cattile__media img { transform: scale(1.03); }
.cattile__name {
  display: block;
  font-size: 1.0625rem;   /* 17 */
  line-height: 1.824;     /* /31 */
  font-weight: 500;
  color: var(--ink);
}
.cattile__count {
  display: block;
  font-size: .75rem;      /* 12 */
  line-height: 1.833;     /* /22 */
  color: var(--ink-muted);
}

/* ------------------------------------------------------ 6b. The arch motif */

/* Used only for entrances: shop categories and magazine hubs. A product is
   never an arch — it is a rectangle, because it is a thing, not a doorway. */
.arch {
  display: block;
  position: relative;
  border-radius: var(--r-arch);
  overflow: hidden;
  background: var(--mist);
  text-decoration: none;
  color: inherit;
  transition: transform .22s ease, box-shadow .22s ease;
}
.arch:hover, .arch:focus-visible { transform: translateY(-4px); box-shadow: var(--shadow-lift); }

.arch__media {
  aspect-ratio: 3 / 4;
  width: 100%;
  overflow: hidden;
  background: var(--mist);
}
.arch__media img { width: 100%; height: 100%; object-fit: cover; }

.arch__label {
  position: absolute;
  inset-inline: var(--s2);
  bottom: var(--s2);
  background: rgba(255, 255, 255, .94);
  backdrop-filter: blur(6px);
  border-radius: var(--r-card);
  padding: var(--s3);
  text-align: center;
  font-weight: 700;
  font-size: var(--t-sm);
}
.arch__count {
  display: block;
  font-weight: 400;
  font-size: var(--t-xs);
  color: var(--ink-muted);
}

/* ---------------------------------------------------------- 6c. Breadcrumb */

/* The trail lives in the core sheet, not in magazine.css. petsaze_breadcrumbs()
   runs on shop and product pages too, but magazine.css is only enqueued when
   the request is NOT a shop page — so on every WooCommerce template the trail
   rendered as a bare <ol>: stacked items with «۱.» «۲.» list numbers beside
   them. Site-wide chrome belongs in the site-wide stylesheet. */

.crumbs {
  padding-block: var(--s6) var(--s3);
  font-size: .75rem;
  line-height: 1.833;
  color: var(--ink-muted);
}
.crumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin: 0;
  padding: 0;
  list-style: none;
}
.crumbs li { list-style: none; }
.crumbs li + li::before { content: '›'; margin-inline-end: var(--s2); color: var(--ink-muted); }
.crumbs a { text-decoration: none; color: var(--ink-soft); }
.crumbs a:hover { text-decoration: underline; color: var(--ink); }

/* ------------------------------------------------------------- 7. Utility */

.stack > * + * { margin-top: var(--s4); }
.muted { color: var(--ink-muted); }
.center { text-align: center; }
.nowrap { white-space: nowrap; }
.lead { font-size: var(--t-lg); color: var(--ink-soft); }

/* ------------------------------------------------------------- 8. Chrome */

/* The announce bar is the warm brand surface, not a dark plane. It renders
   only when there is something to say. */
.announce {
  background: var(--brand-surface);
  color: var(--brand-ink);
  font-size: .75rem;      /* 12 */
  line-height: 1.833;     /* /22 */
}
.announce__inner {
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s3);
  text-align: center;
}
.announce a { color: var(--brand-ink); font-weight: 500; }

.masthead {
  position: sticky;
  top: 0;
  z-index: 60;
  background: var(--paper);
  transition: transform .25s ease, box-shadow .25s ease;
}
.masthead.is-stuck { box-shadow: var(--shadow); }
.masthead.is-hidden { transform: translateY(-100%); }

.masthead__row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--s4);
  min-height: var(--header-h);
}

.masthead__burger {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;
  border: 0; background: transparent; cursor: pointer;
  color: var(--ink);
}

.masthead__brand img { width: auto; height: 66px; }

.masthead__search {
  justify-self: stretch;
  /* width, not just justify-self: an auto inline margin on a grid item wins
     over stretch and shrinks the item to its content — which is why this box
     sat at 208px while its column was over 900px wide. */
  width: 100%;
  max-width: 660px;
  margin-inline: auto;
}

.masthead__actions { display: flex; align-items: center; gap: var(--s2); }

.action {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
  min-height: 44px;
  text-decoration: none;
  font-size: var(--t-xs);
  line-height: 1.846;
  color: var(--ink-soft);
}
.action:hover { color: var(--ink); }
.action .icon { flex: none; color: var(--ink); }
.action:hover .icon { color: var(--brand-ink); }
.action__label { display: none; }
.action__count { font-variant-numeric: tabular-nums; }

@media (min-width: 900px) {
  .action__label { display: inline; }
}
@media (max-width: 899px) {
  .masthead__burger { display: inline-flex; }
  .masthead__search { display: none; }

  /* On a small screen the brand moves to the far left and the controls stack
     up on the right, next to the thumb: burger, then cart and account, then
     the logo closing the row. Explicit placement rather than source order,
     because the markup order (burger, brand, search, actions) is the one that
     reads correctly to a screen reader and should not be shuffled for layout. */
  .masthead__row { grid-template-columns: auto auto 1fr; }
  /* grid-row is pinned as well as grid-column: the brand comes before the
     actions in the markup but sits in a later column, and auto-placement
     never moves backwards — so the actions were pushed onto a second row
     under the logo instead of sitting beside the burger. */
  .masthead__burger  { grid-column: 1; grid-row: 1; }
  .masthead__actions { grid-column: 2; grid-row: 1; justify-self: start; }
  .masthead__brand   { grid-column: 3; grid-row: 1; justify-self: end; }
  .masthead__brand img { height: 48px; }
}

/* Search */
.searchform {
  display: flex;
  align-items: center;
  min-height: 48px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding-inline-start: var(--s4);
}
/* The focus ring is orange and is never removed — it is the one place the
   brand colour is allowed to mark state rather than action. */
.searchform:focus-within {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(246, 111, 0, .18);
}
.searchform__input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  padding: var(--s2) 0;
  font-size: var(--t-sm);
  line-height: 1.857;
  outline: none;
}
.searchform__input::placeholder { color: var(--ink-muted); opacity: 1; }
.searchform__submit {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  align-self: stretch;
  border: 0;
  background: transparent;
  color: var(--ink-muted);
  cursor: pointer;
}
.searchform__submit:hover { color: var(--ink); }

/* Nav row */
.mainnav {
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: var(--paper);
}
.mainnav__row { display: flex; align-items: center; gap: var(--s6); min-height: 56px; }
@media (max-width: 899px) { .mainnav { display: none; } }

/* The pills live here, not in petban.css, because petban.css only loads on the
   front page while header.php renders them on every page — the same trap that
   left the breadcrumb unstyled on the shop. Anything the header draws has to be
   styled by the sheet the header is always served with. */

/* --------------------------------------------------- nav doorways to petban

   These two pills are the only nav items that leave WordPress. They carry a
   status dot rather than a status fill, for the same reason the cards do: the
   colour says what kind of listing waits on the other side, it does not say
   "press me". In v2 each pill sits on its own tinted status ground — still
   not orange, so they never compete with the one CTA a page is allowed. */

.mainnav__ads,
.drawer__ads {
  display: flex;
  gap: var(--s2);
}

.mainnav__ads { margin-inline-start: auto; }

.drawer__ads {
  margin-top: var(--s5);
  padding-top: var(--s5);
  border-top: 1px solid var(--line);
  flex-direction: column;
}

.navpill {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s1) var(--s3);
  min-height: 32px;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  color: var(--ink);
  font-size: var(--t-xs);
  font-weight: 500;
  text-decoration: none;
  transition: border-color .18s ease, background .18s ease;
}

.navpill:hover { border-color: currentColor; }

.navpill__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex: none;
}

.navpill--lost   { background: var(--lost-bg);  color: var(--lost-ink); }
.navpill--rehome { background: var(--adopt-bg); color: var(--adopt-ink); }

.navpill__dot { background: currentColor; }

/* The label itself stays charcoal — only the dot and the ground carry the
   status hue, so a row of pills does not read as a row of error messages. */
.navpill--lost, .navpill--rehome { color: var(--ink); }
.navpill--lost   .navpill__dot { background: var(--lost); }
.navpill--rehome .navpill__dot { background: var(--adopt); }

.menu { display: flex; align-items: center; gap: 34px; margin: 0; padding: 0; list-style: none; }
.menu li { position: relative; }
.menu a {
  display: inline-flex;
  align-items: center;
  gap: var(--s1);
  padding: var(--s3) 0;
  font-size: var(--t-sm);
  line-height: 1.857;
  font-weight: 400;
  color: var(--ink-soft);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}
/* The current item is the only one that goes charcoal and picks up weight;
   the orange rule underneath is what actually marks position. */
.menu > li > a:hover { color: var(--ink); }
.menu > li.current-menu-item > a,
.menu > li.current-menu-parent > a {
  color: var(--ink);
  font-weight: 500;
  border-bottom-color: var(--brand);
}

/* A parent item announces its submenu with a small caret drawn in CSS, so no
   extra markup and no icon font. */
/* Physical borders on purpose: the logical ones flip in RTL and turn the
   down-caret on its side. A caret that points at the panel below it is not
   a direction that mirrors. */
.menu > li.menu-item-has-children > a::after {
  content: '';
  width: 6px; height: 6px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translateY(-2px);
  opacity: .5;
}

/* The submenu is a panel, not part of the row. Without this every child item
   lays itself out inline and the whole nav collapses into a wall of links. */
.menu .sub-menu {
  position: absolute;
  inset-inline-start: 0;
  top: 100%;
  z-index: 70;
  display: grid;
  gap: 2px;
  min-width: 220px;
  margin: 0;
  padding: var(--s2);
  list-style: none;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-lift);
  opacity: 0;
  visibility: hidden;
  transform: translateY(4px);
  /* Same rule as the mega panel above: visibility is switched, not animated. */
  transition: opacity .16s ease, transform .16s ease, visibility 0s linear .16s;
}
.menu li:hover > .sub-menu,
.menu li:focus-within > .sub-menu {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity .16s ease, transform .16s ease, visibility 0s;
}
.menu .sub-menu a {
  display: block;
  padding: var(--s2) var(--s3);
  border: 0;
  border-radius: var(--r-sm);
  font-weight: 400;
  color: var(--ink);
  white-space: normal;
}
.menu .sub-menu a:hover { background: var(--mist); border: 0; }

/* In the drawer the same submenu is a plain indented list — a hover panel is
   meaningless on a touch screen — and it starts closed. Left open, «گربه» and
   «سگ» contributed nine extra rows between them and pushed the last two menu
   items and both ad pills below the fold. */
.menu--drawer .sub-menu {
  position: static;
  opacity: 1;
  visibility: visible;
  transform: none;
  border: 0;
  box-shadow: none;
  padding: 0 var(--s4) var(--s2);
  background: transparent;
  display: none;
}
.menu--drawer li.is-open > .sub-menu { display: grid; }
.menu--drawer .sub-menu a { font-size: var(--t-sm); color: var(--ink-muted); }

/* The parent row becomes link + toggle: the link still goes to the category,
   the button only opens the list underneath it. */
.menu--drawer > li.menu-item-has-children {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
}
.menu--drawer li.menu-item-has-children > .sub-menu { flex: 0 0 100%; }

/* The decorative caret drawn on the desktop parent link is now the toggle's
   job, so the link stops drawing one of its own. */
.menu--drawer > li.menu-item-has-children > a::after { content: none; }

.submenu-toggle {
  flex: none;
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: transparent;
  color: var(--ink-muted);
  cursor: pointer;
}
.submenu-toggle::before {
  content: '';
  width: 8px;
  height: 8px;
  /* Physical borders: a chevron that points down must not mirror in RTL. */
  border-right: 1.7px solid currentColor;
  border-bottom: 1.7px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .18s ease;
}
.submenu-toggle[aria-expanded="true"] { color: var(--ink); }
.submenu-toggle[aria-expanded="true"]::before {
  transform: rotate(225deg) translate(-2px, -2px);
}

/* Mega panels.

   Two top-level items open one instead of a dropdown; which ones is a CSS class
   on the menu item, not a rule here (see inc/nav.php). The panel spans the page,
   so its containing block has to be the nav row and not the <li> it hangs from —
   hence position:static on the item, which overrides the .menu li rule above. */
.mainnav { position: relative; }
.menu--primary > li.mega { position: static; }

.megamenu {
  position: absolute;
  inset-inline: 0;
  top: 100%;
  z-index: 70;
  background: var(--paper);
  border-top: 1px solid var(--line);
  box-shadow: var(--shadow-lift);
  opacity: 0;
  visibility: hidden;
  transform: translateY(4px);
  /* visibility gets 0s with a delay, not a duration. Given a duration it is
     interpolated discretely and the panel can sit on the `hidden` end of that
     interpolation indefinitely — which is exactly what it did: the pointer was
     over the item, the selector matched, and the computed value never moved off
     hidden. Delaying it to the end of the fade keeps the close animating. */
  transition: opacity .16s ease, transform .16s ease, visibility 0s linear .16s;
}
.menu--primary > li.mega:hover > .megamenu,
.menu--primary > li.mega:focus-within > .megamenu {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity .16s ease, transform .16s ease, visibility 0s;
}
.megamenu__inner { padding-block: var(--s6); }

/* .menu a sets white-space:nowrap for the nav row itself, and it reaches every
   link inside a panel too — which is why a two-line article title measured 262px
   wide inside a 151px column and pushed the page 87px sideways. Panels wrap. */
.megamenu a { white-space: normal; }

/* ---- cards: the shop's categories, as picture tiles ---- */

.megamenu__cards {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--s4);
  margin: 0;
  padding: 0;
  list-style: none;
}
.megamenu__card > a { display: block; text-decoration: none; border: 0; }
.megamenu__thumb {
  display: block;
  aspect-ratio: 1 / 1;
  margin-bottom: var(--s3);
  border-radius: var(--r-card);
  background: var(--mist);
  overflow: hidden;
}
.megamenu__img { display: block; width: 100%; height: 100%; object-fit: cover; }
.megamenu__label {
  display: block;
  color: var(--ink);
  font-size: var(--t-sm);
  font-weight: 500;
  line-height: 1.6;
}
.megamenu__count { display: block; margin-top: 2px; color: var(--ink-soft); font-size: var(--t-xs); }
.megamenu__card > a:hover .megamenu__label { color: var(--brand-ink); }

/* ---- columns: the magazine's hubs, each over its own topics ---- */

.megamenu__columns {
  display: grid;
  /* auto-fit, not a fixed count: the magazine has two hubs today and may have
     four tomorrow, and auto-fit collapses the tracks nobody filled instead of
     leaving two ghost columns of white between the last hub and the rail. */
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--s5) var(--s6);
  margin: 0;
  padding: 0;
  list-style: none;
}
.megamenu__colhead {
  display: block;
  margin-bottom: var(--s3);
  padding-bottom: var(--s2);
  border-bottom: 1px solid var(--line);
  color: var(--ink);
  font-size: var(--t-sm);
  font-weight: 700;
  text-decoration: none;
}
.megamenu__colhead:hover { color: var(--brand-ink); }
.megamenu__list {
  display: grid;
  gap: var(--s2);
  margin: 0;
  padding: 0;
  list-style: none;
}
.megamenu__list a {
  display: block;
  padding: 0;
  border: 0;
  color: var(--ink-soft);
  font-size: var(--t-xs);
  line-height: 1.7;
  text-decoration: none;
  white-space: normal;
}
.megamenu__list a:hover { color: var(--brand-ink); border: 0; }

/* The columns and the article rail share the panel: the hubs take the reading
   side, the articles the rest. Without this the two hubs sat in a quarter of a
   full-width panel and the other three quarters were blank. */
.megamenu__inner:has(.megamenu__feature) {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 340px);
  gap: var(--s7);
  align-items: start;
}
.megamenu__feature {
  min-width: 0;
  padding-inline-start: var(--s6);
  border-inline-start: 1px solid var(--line);
}
.megamenu__feature-title {
  display: block;
  margin-bottom: var(--s4);
  color: var(--ink);
  font-size: var(--t-sm);
  font-weight: 700;
}
/* min-width:0 on all three levels. A grid item and a flex item both default to
   min-width:auto, so the <li>, the <a> and the title each have to be told they
   may shrink — fixing only the innermost one left the rail 87px wide of the
   page at 1100. */
.megamenu__posts { display: grid; gap: var(--s4); margin: 0; padding: 0; list-style: none; }
.megamenu__posts > li { min-width: 0; }
.megamenu__posts a {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: 0;
  border: 0;
  text-decoration: none;
  /* A flex item defaults to min-width:auto, so the title refused to wrap and
     pushed the whole rail 87px past the left edge of the page at 1100. */
  min-width: 0;
}
.megamenu__post-thumb {
  flex: none;
  width: 64px;
  height: 64px;
  border-radius: var(--r-sm);
  background: var(--mist);
  overflow: hidden;
}
.megamenu__post-img { display: block; width: 100%; height: 100%; object-fit: cover; }
.megamenu__post-title {
  min-width: 0;
  overflow-wrap: anywhere;
  color: var(--ink);
  font-size: var(--t-xs);
  line-height: 1.7;
  font-weight: 500;
}
.megamenu__posts a:hover .megamenu__post-title { color: var(--brand-ink); }

/* Six tiles need room. Below this the panel steps down rather than shrinking
   each tile past the point where its label fits on one line. */
@media (max-width: 1200px) {
  .megamenu__cards { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .megamenu__columns { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .megamenu__inner:has(.megamenu__feature) { grid-template-columns: minmax(0, 1fr) minmax(0, 260px); gap: var(--s5); }
}

/* Mobile drawer */
.drawer { position: fixed; inset: 0; z-index: 100; }
/* The scrim is painted BEHIND the panel.
   Both are absolutely positioned children of .drawer and the scrim comes
   second in the markup, so with `z-index: auto` it painted on top of the
   panel: the menu was dimmed by its own overlay, and — far worse —
   elementFromPoint at any menu item returned the scrim, so every tap on a
   link, the search field or an ad pill hit the close button instead of the
   thing under the finger. The drawer opened and then closed on the next tap,
   whatever you aimed at. */
.drawer__scrim {
  position: absolute; inset: 0;
  z-index: 0;
  border: 0; padding: 0;
  background: rgba(31, 33, 36, .5);
}
.drawer__panel {
  position: absolute;
  z-index: 1;
  inset-block: 0;
  inset-inline-start: 0;
  width: min(88vw, 340px);
  padding: var(--s5);
  background: var(--paper);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--s5);
}
.drawer__close {
  align-self: flex-end;
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; background: transparent; cursor: pointer; color: var(--ink);
}
.menu--drawer { flex-direction: column; align-items: stretch; gap: 0; }
.menu--drawer a {
  padding: var(--s3) 0;
  border-bottom: 1px solid var(--line-soft);
  font-size: var(--t-md);
}
.menu--drawer a:hover { border-bottom-color: var(--line-soft); color: var(--brand-ink); }

/* Footer */
/* Footer.

   Geometry measured off the approved reference rather than eyeballed: column
   headings 14/700 with 30px under them, links 13px with 15px between them, and
   a 6px round dot before each one. The reference's dot is its pink; ours is the
   brand orange — it is the one place in the footer colour appears, which is why
   the rest of the block can stay this quiet. */
.footer {
  background: var(--mist);
  color: var(--ink);
  margin-top: var(--s9);
}
.trust + .footer { margin-top: 0; }
.footer a { color: var(--ink-soft); text-decoration: none; }
.footer a:hover { color: var(--brand-ink); }

/* ------------------------------------------------------- support strip */

.footer__support { border-bottom: 1px solid var(--line); }
.footer__support-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s3) var(--s6);
  padding-block: var(--s4);
}
.footer__support-item {
  display: flex;
  align-items: center;
  gap: var(--s2);
  margin: 0;
  font-size: var(--t-xs);
  color: var(--ink-soft);
}
.footer__support-item .icon { color: var(--brand-ink); flex: none; }
.footer__support-label { color: var(--ink); font-weight: 500; }
.footer__support-item a { color: var(--ink); }
.footer__support-item a + a { margin-inline-start: var(--s3); }

/* ------------------------------------------------------------- columns */

/* One track per column, counted by the grid itself rather than written down:
   the customer-services column only exists when WooCommerce does, and the
   follow column has been removed entirely, so a hard-coded count leaves an
   empty track and the row stops being centred. `auto-fit` collapses the tracks
   nothing lands in. */
.footer__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--s6) var(--s5);
  padding-block: 56px 48px;
}

.footer__title {
  font-size: .875rem;    /* 14 */
  line-height: 1.6;
  font-weight: 700;
  color: var(--ink);
  margin: 0 0 30px;
}

.menu--footer {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 15px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.menu--footer li { position: relative; padding-inline-start: 14px; }
/* The dot is a marker, not a bullet character: ::marker cannot be positioned
   in a flex column list, and a real element would be read out by a screen
   reader as content it is not. */
.menu--footer li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: .62em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--brand);
}
.menu--footer a {
  padding: 0;
  border: 0;
  font-weight: 400;
  font-size: .8125rem;   /* 13 */
  line-height: 1.6;
}
.menu--footer a:hover { border: 0; }

/* -------------------------------------------------------------- follow */

.socials { display: flex; gap: var(--s3); margin: 0 0 var(--s6); padding: 0; list-style: none; }
.socials__link {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: var(--paper);
  border: 1px solid var(--line);
  color: var(--ink-soft);
  transition: background .16s ease, color .16s ease, border-color .16s ease;
}
.socials__link:hover { background: var(--brand); border-color: var(--brand); color: var(--ink); }

.subscribe__label {
  display: block;
  margin-bottom: var(--s3);
  font-size: .8125rem;
  font-weight: 700;
  color: var(--ink);
  line-height: 1.7;
}
.subscribe__row {
  display: flex;
  gap: var(--s2);
  align-items: stretch;
}
.subscribe__input {
  flex: 1;
  min-width: 0;
  height: 46px;
  padding-inline: var(--s4);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--paper);
  color: var(--ink);
  font: inherit;
  font-size: var(--t-xs);
}
.subscribe__input::placeholder { color: var(--ink-muted); }
.subscribe__go {
  flex: none;
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--brand-btn);
  color: #fff;
  cursor: pointer;
  transition: background .16s ease, color .16s ease;
}
.subscribe__go:hover { background: var(--brand-btn-hover); color: #fff; }
.subscribe__msg { margin: var(--s3) 0 0; font-size: var(--t-xs); line-height: 1.7; }
.subscribe__msg--ok { color: var(--found-ink); }
.subscribe__msg--bad { color: var(--lost-ink); }

/* --------------------------------------------------------- about block */

.footer__about { padding-block: var(--s6); border-top: 1px solid var(--line); }
.footer__about-title { font-size: 1rem; font-weight: 700; color: var(--ink); margin: 0 0 9px; }
.footer__about-text {
  color: var(--ink-soft);
  font-size: var(--t-xs);
  line-height: 2;
}
.footer__about-text p { margin: 0 0 var(--s3); }
.footer__about-text p:last-child { margin-bottom: 0; }
/* Clamped rather than max-height'd: a height guess either cuts a line in half
   or leaves a gap, and line-clamp counts the lines the browser actually drew. */
.footer__about-text[data-clamp] {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.footer__about-text.is-open {
  display: block;
  -webkit-line-clamp: none;
  line-clamp: none;
  overflow: visible;
}
.footer__about-more {
  margin-top: var(--s2);
  padding: 0;
  border: 0;
  background: none;
  color: var(--brand-ink);
  font: inherit;
  font-size: var(--t-xs);
  font-weight: 700;
  cursor: pointer;
}
.footer__about-more:hover { text-decoration: underline; }

/* ----------------------------------------------------------- base bar */

.footer__base { border-top: 1px solid var(--line); }
.footer__base-row {
  padding-block: var(--s4);
  font-size: .75rem;
  line-height: 1.833;
  color: var(--ink-soft);
}
.footer__base-row p { margin: 0; }

@media (max-width: 900px) {
  .footer__grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 560px) {
  .footer__grid { grid-template-columns: 1fr; gap: var(--s6); padding-block: var(--s6); }
  .footer__support-row { gap: var(--s2) var(--s4); }
  .footer__title { margin-bottom: var(--s4); }
}



/* ---------------------------------------------------------- 9. Front page */

/* The hero leads with a real article and puts the shop entrance beside it —
   the bridge the whole rebuild is built on, stated on the first screen. */
/* The hero is two columns that are deliberately unequal: a 620x480 image
   panel on the trailing side and a text column that overhangs it. The comp
   sets the copy against the panel rather than centring anything, and that
   asymmetry is the whole composition — see .hero__panel for why the panel
   holds its place even when empty. */
.hero { padding-block: var(--s5) var(--s6); }

@media (min-width: 900px) and (min-height: 700px) {
  .hero {
    position: sticky;
    top: var(--chrome-h);
    z-index: 0;
  }

  /* The header hides itself on a downward scroll. When it does, the hero has
     to close the gap it leaves, or a 154px band of empty page opens above a
     hero that is supposed to be pinned to the top. */
  .masthead.is-hidden ~ .site-main .hero { top: 0; }

  /* Every block after the hero is a layer above it, with a ground of its own. */
  .site-main > *:not(.hero),
  .footer { position: relative; z-index: 1; }

  .site-main > .section,
  .site-main > .trust { background: var(--paper); }

  /* The rehoming band keeps the neutral ground that tells it apart from the
     lost band — it must come after the blanket rule above. */
  .site-main > .band--rehome { background: var(--mist); }
}

/* Under 900px the nav collapses and a 460px hero would hold most of the
   viewport open, so it scrolls away like any other section. */

/* The hero is one banner card on the warm brand surface, the way a Persian
   shop opens: a coloured plane you land on, not a white page with type on it. */
.hero__banner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 560px);
  gap: var(--s7);
  align-items: center;
  padding: var(--s6) var(--s7);
  background: var(--brand-surface);
  border-radius: var(--r-block);
  overflow: hidden;
}
.hero__grid {
  display: grid;
  /* Column one is the right-hand column in RTL, so the copy — which is first
     in the source — lands on the right and the panel on the left, with no
     explicit placement needed. Fixing the panel to 620px and letting the copy
     take the remainder is what produces the comp's overhang. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 620px);
  gap: 60px;
  align-items: center;
}
.hero__banner .hero__panel {
  aspect-ratio: 560 / 340;
  background: rgba(255, 255, 255, .55);
}

.hero__copy { min-width: 0; }

.hero__eyebrow {
  margin: 0 0 var(--s2);
  color: var(--brand-ink);
  font-size: var(--t-xs);
  line-height: 1.846;
  font-weight: 500;
}

/* 44/56 with the break the design draws, not one the container invents. */
.hero__title {
  margin: 0 0 var(--s4);
  font-size: var(--t-4xl);
  line-height: 1.273;
  font-weight: 700;
  color: var(--ink);
}
.hero__line { display: block; }

.hero__desc {
  margin: 0 0 var(--s5);
  max-width: 480px;
  color: var(--ink-soft);
  font-size: var(--t-md);
  line-height: 1.875;
}

.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s3); }

/* Holds 620x480 whether or not an image is set. An empty panel is the comp's
   own neutral ground, not a collapsed row. */
.hero__panel {
  aspect-ratio: 620 / 480;
  border-radius: var(--r-card);
  overflow: hidden;
  background: var(--mist);
  display: grid;
  place-items: center;
}
/* The padding belongs to the empty state — with an image in place it would
   letterbox the photo inside its own panel. */
.hero__panel:not(:has(.hero__img)) { padding: var(--s5); }
/* No image and nobody to tell about it: hold the space, draw nothing.
   Listed for the banner variant too — .hero__banner .hero__panel sets its own
   translucent fill with two classes, and a one-class rule loses to it. */
.hero__panel--bare,
.hero__banner .hero__panel--bare { background: none; }
.hero__img { width: 100%; height: 100%; object-fit: cover; }

@media (max-width: 900px) {
  .hero { padding-block: var(--s5); }
  .hero__banner { grid-template-columns: 1fr; gap: var(--s5); padding: var(--s5); }
  .hero__grid { grid-template-columns: 1fr; gap: var(--s6); }
  .hero__copy, .hero__panel { grid-column: 1; }
  .hero__copy { order: 1; }
  .hero__panel { order: 2; }
  .hero__desc { margin-bottom: var(--s5); }
}

.arch--sm .arch__media { aspect-ratio: 4 / 3; }

/* Category / hub chips */
.hubs { display: flex; flex-wrap: wrap; gap: var(--s2); margin-bottom: var(--s5); }
.hubs__item {
  display: inline-flex; align-items: center; gap: var(--s2);
  padding: var(--s2) var(--s4);
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--paper);
  font-size: var(--t-sm); font-weight: 700; text-decoration: none;
}
.hubs__item:hover { border-color: var(--ink); }
.hubs__count { color: var(--ink-muted); font-weight: 400; }

/* Carousel */
.carousel { position: relative; }
.carousel__track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(230px, 1fr);
  gap: var(--s5);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: var(--s3);
  scrollbar-width: thin;
}
.carousel__track > * { scroll-snap-align: start; }
@media (min-width: 1000px) {
  .carousel__track { grid-auto-columns: minmax(0, calc(25% - 18px)); }
}
.carousel__nav { display: flex; gap: var(--s2); justify-content: flex-end; margin-top: var(--s3); }
.carousel__btn {
  width: 40px; height: 40px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line);
  border-radius: var(--r-pill);
  background: var(--paper);
  cursor: pointer;
  color: var(--ink);
}
.carousel__btn:hover:not(:disabled) { border-color: var(--ink); }
.carousel__btn:disabled { opacity: .35; cursor: default; }

/* Editor-only setup hint */
.setup-hint {
  margin: 0;
  padding: var(--s4);
  border: 1px dashed var(--line);
  border-radius: var(--r-card);
  background: var(--paper);
  color: var(--ink-muted);
  font-size: var(--t-sm);
}
.setup-hint strong { color: var(--ink); }

/* WordPress prints its comment textarea with a cols attribute, which sizes it
   in character widths and ignores the container — at 390px that pushed it 7px
   past the viewport and gave the whole article page a horizontal scrollbar.
   Every form control gets the same guard rather than just this one, because
   any plugin form dropped into a template has the same failure mode. */
input,
select,
textarea {
  max-width: 100%;
  box-sizing: border-box;
}

textarea { resize: vertical; }

/* ------------------------------------------------------------ trust strip */

.trust {
  border-block: 1px solid var(--line);
  padding-block: var(--s7);
}

.trust__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s5);
}

.trust__item {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s3);
  font-size: var(--t-sm);
  line-height: 1.857;
  font-weight: 400;
  color: var(--ink-soft);
}

.trust__item svg { color: var(--brand-ink); flex: none; }
.trust__item span { white-space: nowrap; }

@media (max-width: 1100px) {
  .trust__item span { white-space: normal; }
}

@media (max-width: 900px) {
  .trust__grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 480px) {
  .trust__grid { grid-template-columns: 1fr; }
}
