/* ==========================================================================
   Indo Spy — design system and components
   --------------------------------------------------------------------------
   Loaded AFTER bootstrap.min.css, so everything here either uses its own
   namespace (.is-*) or deliberately overrides a Bootstrap default.

   Design note. The catalogue is surveillance hardware disguised as ordinary
   objects — a calculator, a tissue box, a table clock, a wall charger. The
   product photography carries that idea on its own, so the interface stays
   quiet and instrument-like around it: near-white fields, hairline rules,
   one decisive black, and small letter-spaced labels for anything technical.
   Orange appears only where money is being saved.

   Section map
     1. Tokens          6. Product card
     2. Base            7. Hero
     3. Typography      8. Sections and bands
     4. Buttons         9. Header / nav / search
     5. Forms          10. Side cart, toasts, modals
   ========================================================================== */

/* ==========================================================================
   1. Tokens
   ========================================================================== */

:root {
  /* Brand palette — monochrome, per the black-and-white logo. */
  --is-black:      #000000;
  --is-charcoal:   #171717;
  --is-white:      #FFFFFF;
  --is-bg-soft:    #F7F7F7;
  --is-gray-light: #EAEAEA;
  --is-text-2:     #6B7280;

  /* Ink scale derived from the two neutrals above, so body copy is not a
     flat black slab and secondary text still clears WCAG AA on white. */
  --is-ink:        var(--is-charcoal);
  --is-ink-muted:  #4B5058;
  --is-line:       var(--is-gray-light);
  --is-line-soft:  #F0F0F0;

  /* Single accent. Reserved for discount and sale, never for navigation,
     never as a background for long text — #FF6B00 on white is 3.1:1, which
     passes for large text and UI, not for body copy. */
  --is-accent:     #FF6B00;
  --is-accent-ink: #B34B00;   /* same hue, AA on white for small text */

  --is-ok:         #0F7B4F;

  /* Type */
  --is-font-display: 'Plus Jakarta Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --is-font-body:    'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;

  --is-fs-hero:  clamp(2.25rem, 1.5rem + 3.2vw, 4rem);
  --is-fs-h2:    clamp(1.6rem, 1.25rem + 1.4vw, 2.35rem);
  --is-fs-h3:    clamp(1.15rem, 1.05rem + 0.4vw, 1.4rem);
  --is-fs-body:  1rem;
  --is-fs-sm:    0.9375rem;
  --is-fs-xs:    0.8125rem;
  --is-fs-label: 0.6875rem;

  --is-lh-tight: 1.08;
  --is-lh-head:  1.2;
  --is-lh-body:  1.65;
  --is-ls-label: 0.09em;

  /* Spacing — 4px base, used through the whole sheet so rhythm cannot drift */
  --is-s1: 0.25rem;  --is-s2: 0.5rem;   --is-s3: 0.75rem;  --is-s4: 1rem;
  --is-s5: 1.5rem;   --is-s6: 2rem;     --is-s7: 3rem;     --is-s8: 4rem;
  --is-section-y: clamp(3rem, 2rem + 4vw, 5.5rem);

  /* Borders, shadow, motion */
  --is-radius:    12px;   /* product cards and media */
  --is-radius-sm: 6px;    /* inputs, buttons, chips */
  --is-shadow:      0 1px 2px rgba(0,0,0,.04), 0 8px 24px rgba(0,0,0,.06);
  --is-shadow-lift: 0 2px 4px rgba(0,0,0,.05), 0 18px 40px rgba(0,0,0,.10);
  --is-t: 220ms cubic-bezier(.4, 0, .2, 1);

  --is-header-h: 72px;
  --is-container: 1320px;
}

/* ==========================================================================
   2. Base
   ========================================================================== */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--is-white);
  color: var(--is-ink);
  font-family: var(--is-font-body);
  font-size: var(--is-fs-body);
  line-height: var(--is-lh-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { max-width: 100%; height: auto; }

a { color: inherit; text-decoration: none; }
a:hover { color: var(--is-black); }

/* One visible focus treatment everywhere, including for keyboard users who
   arrive via the skip link. */
:focus-visible {
  outline: 2px solid var(--is-black);
  outline-offset: 2px;
  border-radius: 2px;
}

.is-container {
  width: 100%;
  max-width: var(--is-container);
  margin-inline: auto;
  padding-inline: var(--is-s4);
}
@media (min-width: 768px) { .is-container { padding-inline: var(--is-s5); } }

.is-skip {
  position: absolute; left: -9999px; top: 0; z-index: 2000;
  background: var(--is-black); color: #fff;
  padding: var(--is-s3) var(--is-s4); font-weight: 600;
}
.is-skip:focus { left: 0; color: #fff; }

/* Visually hidden but read aloud — used for icon-only control labels. */
.is-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   3. Typography
   ========================================================================== */

h1, h2, h3, h4, h5, h6, .is-display {
  font-family: var(--is-font-display);
  color: var(--is-black);
  line-height: var(--is-lh-head);
  letter-spacing: -0.02em;
  text-wrap: balance;
  margin: 0 0 var(--is-s4);
}

h1 { font-size: var(--is-fs-hero); line-height: var(--is-lh-tight); letter-spacing: -0.035em; font-weight: 800; }
h2 { font-size: var(--is-fs-h2); font-weight: 700; }
h3 { font-size: var(--is-fs-h3); font-weight: 700; }

p { margin: 0 0 var(--is-s4); }
p:last-child { margin-bottom: 0; }

.is-lead {
  font-size: clamp(1rem, 0.95rem + 0.3vw, 1.125rem);
  color: var(--is-ink-muted);
  max-width: 60ch;
}

.is-muted { color: var(--is-text-2); }

/* Small letter-spaced label. The technical register of the catalogue —
   used for eyebrows, category names on cards, spec keys, footer headings. */
.is-label {
  font-family: var(--is-font-display);
  font-size: var(--is-fs-label);
  font-weight: 700;
  letter-spacing: var(--is-ls-label);
  text-transform: uppercase;
  color: var(--is-text-2);
  line-height: 1.4;
}

/* Prices and any figure that lines up in a column. */
.is-num { font-variant-numeric: tabular-nums; }

/* ==========================================================================
   4. Buttons
   ========================================================================== */

.is-btn {
  --_bg: var(--is-black);
  --_fg: #fff;
  --_bd: var(--is-black);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--is-s2);
  min-height: 48px;                 /* comfortable tap target on mobile */
  padding: 0 var(--is-s5);
  border: 1px solid var(--_bd);
  border-radius: var(--is-radius-sm);
  background: var(--_bg);
  color: var(--_fg);
  font-family: var(--is-font-display);
  font-size: var(--is-fs-sm);
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: background var(--is-t), color var(--is-t), border-color var(--is-t), transform var(--is-t);
}
.is-btn:hover { color: var(--_fg); transform: translateY(-1px); }
.is-btn:active { transform: none; }
.is-btn[disabled] { opacity: .45; pointer-events: none; }

.is-btn--primary:hover { --_bg: var(--is-charcoal); --_bd: var(--is-charcoal); }

.is-btn--outline { --_bg: transparent; --_fg: var(--is-black); --_bd: var(--is-black); }
.is-btn--outline:hover { --_bg: var(--is-black); --_fg: #fff; }

/* For use on the black bands. */
.is-btn--invert { --_bg: #fff; --_fg: var(--is-black); --_bd: #fff; }
.is-btn--invert:hover { --_bg: var(--is-gray-light); --_bd: var(--is-gray-light); }

.is-btn--ghost { --_bg: transparent; --_fg: var(--is-black); --_bd: var(--is-line); }
.is-btn--ghost:hover { --_bd: var(--is-black); --_bg: transparent; }

.is-btn--sm { min-height: 40px; padding: 0 var(--is-s4); font-size: var(--is-fs-xs); }
.is-btn--block { width: 100%; }

/* Text link with a rule that draws in on hover. */
.is-link {
  display: inline-flex; align-items: center; gap: var(--is-s2);
  font-family: var(--is-font-display);
  font-size: var(--is-fs-sm); font-weight: 600;
  color: var(--is-black);
  padding-bottom: 2px;
  background-image: linear-gradient(var(--is-black), var(--is-black));
  background-size: 0% 1px;
  background-position: 0 100%;
  background-repeat: no-repeat;
  transition: background-size var(--is-t);
}
.is-link:hover { background-size: 100% 1px; }
/* When .is-link is a real control rather than an inline link (the wishlist
   toggle on the product page), give it a tappable height. */
button.is-link { min-height: 36px; padding-block: var(--is-s2); }
.is-link svg { transition: transform var(--is-t); }
.is-link:hover svg { transform: translateX(3px); }

/* Icon-only control: header actions, wishlist, gallery arrows. */
.is-iconbtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px;
  border: 1px solid transparent;
  border-radius: var(--is-radius-sm);
  background: transparent;
  color: var(--is-black);
  cursor: pointer;
  position: relative;
  transition: background var(--is-t), border-color var(--is-t);
}
.is-iconbtn:hover { background: var(--is-bg-soft); }

/* ==========================================================================
   5. Forms
   ========================================================================== */

.is-field { display: block; margin-bottom: var(--is-s4); }
.is-field__label {
  display: block;
  font-family: var(--is-font-display);
  font-size: var(--is-fs-xs);
  font-weight: 600;
  margin-bottom: var(--is-s2);
  color: var(--is-black);
}
.is-input, .is-select, .is-textarea {
  width: 100%;
  min-height: 48px;
  padding: var(--is-s3) var(--is-s4);
  border: 1px solid var(--is-line);
  border-radius: var(--is-radius-sm);
  background: var(--is-white);
  font-family: var(--is-font-body);
  font-size: var(--is-fs-sm);
  color: var(--is-ink);
  transition: border-color var(--is-t), box-shadow var(--is-t);
}
.is-input::placeholder, .is-textarea::placeholder { color: #9AA0A8; }
.is-input:focus, .is-select:focus, .is-textarea:focus {
  outline: none;
  border-color: var(--is-black);
  box-shadow: 0 0 0 3px rgba(0,0,0,.07);
}
.is-textarea { min-height: 132px; padding-top: var(--is-s3); resize: vertical; }

.is-select {
  appearance: none;
  padding-right: var(--is-s7);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' stroke='%23171717' stroke-width='1.6' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--is-s4) center;
  cursor: pointer;
}

/* Validation message. Hidden until JS marks the field. */
.is-field__error {
  display: none;
  margin-top: var(--is-s2);
  font-size: var(--is-fs-xs);
  color: #B42318;
}
.is-field.is-invalid .is-input,
.is-field.is-invalid .is-select,
.is-field.is-invalid .is-textarea { border-color: #B42318; }
.is-field.is-invalid .is-field__error { display: block; }

/* ==========================================================================
   6. Product card
   Kept deliberately close to WooCommerce's own structure — one <article> per
   product, image / meta / title / price / actions — so the conversion is a
   template rename rather than a rebuild.
   ========================================================================== */

.is-pgrid {
  display: grid;
  gap: var(--is-s4);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 768px)  { .is-pgrid { gap: var(--is-s5); grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1200px) { .is-pgrid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.is-pgrid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 992px) { .is-pgrid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

.is-card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--is-white);
  border: 1px solid var(--is-line-soft);
  border-radius: var(--is-radius);
  overflow: hidden;
  transition: border-color var(--is-t), box-shadow var(--is-t), transform var(--is-t);
}
.is-card:hover { border-color: var(--is-line); box-shadow: var(--is-shadow-lift); transform: translateY(-2px); }

.is-card__media {
  position: relative;
  display: block;
  aspect-ratio: 1 / 1;
  background: var(--is-bg-soft);
  overflow: hidden;
}
.is-card__media img {
  width: 100%; height: 100%;
  object-fit: contain;
  padding: var(--is-s4);
  transition: transform 400ms cubic-bezier(.4, 0, .2, 1);
}
.is-card:hover .is-card__media img { transform: scale(1.05); }

/* Badges sit top-left, actions top-right, so they can never collide. */
.is-card__badges {
  position: absolute; top: var(--is-s3); left: var(--is-s3);
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--is-s1);
  z-index: 2;
}
.is-badge {
  display: inline-block;
  padding: 3px var(--is-s2);
  border-radius: 4px;
  background: var(--is-black);
  color: #fff;
  font-family: var(--is-font-display);
  font-size: var(--is-fs-label);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.is-badge--sale { background: var(--is-accent); color: #fff; }
.is-badge--out  { background: var(--is-text-2); }

.is-card__wish {
  position: absolute; top: var(--is-s3); right: var(--is-s3); z-index: 2;
  width: 36px; height: 36px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--is-line);
  border-radius: 50%;
  background: rgba(255,255,255,.92);
  color: var(--is-ink);
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--is-t), color var(--is-t), border-color var(--is-t);
}
.is-card:hover .is-card__wish,
.is-card__wish:focus-visible,
.is-card__wish[aria-pressed="true"] { opacity: 1; }
.is-card__wish[aria-pressed="true"] { color: var(--is-accent); border-color: var(--is-accent); }
/* Touch devices never hover, so the control must always be reachable. */
@media (hover: none) { .is-card__wish { opacity: 1; } }

.is-card__quick {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: var(--is-s3);
  transform: translateY(100%);
  transition: transform var(--is-t);
}
.is-card:hover .is-card__quick, .is-card:focus-within .is-card__quick { transform: none; }
@media (hover: none) { .is-card__quick { display: none; } }

.is-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--is-s2);
  padding: var(--is-s4);
  flex: 1 1 auto;
}
.is-card__cat { font-size: var(--is-fs-label); }
.is-card__name {
  font-family: var(--is-font-body);
  font-size: var(--is-fs-sm);
  font-weight: 500;
  line-height: 1.45;
  color: var(--is-ink);
  /* Two lines, so a long name cannot make one card taller than its row. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.is-card:hover .is-card__name { color: var(--is-black); }

.is-card__prices {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--is-s2);
  margin-top: auto;
  padding-top: var(--is-s1);
}
.is-price {
  font-family: var(--is-font-body);
  font-size: 1.0625rem;
  font-weight: 600;
  color: var(--is-black);
  font-variant-numeric: tabular-nums;
}
.is-price--was {
  font-size: var(--is-fs-xs);
  font-weight: 400;
  color: var(--is-text-2);
  text-decoration: line-through;
}
.is-price--off {
  font-family: var(--is-font-display);
  font-size: var(--is-fs-xs);
  font-weight: 700;
  color: var(--is-accent-ink);   /* darker than the badge orange: AA on white */
}

.is-card__actions { margin-top: var(--is-s3); }

/* ==========================================================================
   7. Hero
   ========================================================================== */

.is-hero {
  position: relative;
  background: var(--is-bg-soft);
  border-bottom: 1px solid var(--is-line);
  overflow: hidden;
}
.is-hero__grid {
  display: grid;
  gap: var(--is-s5);
  align-items: center;
  padding-block: var(--is-s7);
}
@media (min-width: 992px) {
  .is-hero__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    gap: var(--is-s8);
    padding-block: clamp(3rem, 1rem + 6vw, 5.5rem);
  }
}

.is-hero__eyebrow { margin-bottom: var(--is-s4); color: var(--is-ink-muted); }
.is-hero h1 { margin-bottom: var(--is-s4); }
.is-hero__copy { margin-bottom: var(--is-s6); }
/* The one line that states what is sold here. Sits above the rotating product
   copy, which changes with the hero image and so cannot carry it. */
.is-hero__sub { font-size: var(--is-fs-lg); line-height: 1.45; margin: 0 0 var(--is-s4); max-width: 32ch; }
.is-hero__cta { display: flex; flex-wrap: wrap; gap: var(--is-s3); }

/* --------------------------------------------------------------------------
   Page banner — a full-bleed picture band at the top of a page
   --------------------------------------------------------------------------
   Used by About. The picture is the whole band: no copy over it, because the
   images used here have content across their full width and anything laid on
   top lands on either the people or the products.

   The intrinsic ratio is declared so the space is reserved before the image
   decodes — a banner that pushes the page down when it arrives is the most
   visible layout shift a page can have.
   -------------------------------------------------------------------------- */

.is-pagebanner { background: #0B1C2E; }
.is-pagebanner img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 2000 / 727;
  object-fit: cover;
}

@media (max-width: 767px) {
  /* 2.75:1 across a phone is a 136px strip, which reads as a rule rather than
     a picture. 16:9 gives it height; centring the crop keeps the cameras and
     the screens behind them, which is the half that says what is sold. */
  .is-pagebanner img { aspect-ratio: 16 / 9; object-position: center; }
}

/* --------------------------------------------------------------------------
   Banner hero — the home page
   --------------------------------------------------------------------------
   The supplied banner puts its product cluster in the right third and leaves
   the left deliberately empty, so the copy sits over the empty side and the
   image is anchored from the right: at every width the products stay in frame
   and the words stay off them.

   The hero is one column here. The banner carries the product photography, so
   the three-product card the default hero shows would be a second set of the
   same thing in one band.
   -------------------------------------------------------------------------- */

.is-hero--banner {
  /* The banner's own navy, so the band is the right colour before the image
     decodes and anywhere cover does not reach. */
  background-color: #091626;
  background-image: url("../images/banner/home-hero.webp");
  background-repeat: no-repeat;
  background-position: right center;
  background-size: cover;
  border-bottom: 0;
}

/* Weighted to the left, because that is where the words are. The banner's
   left side is dark but not uniformly so - there is a bright blue glow around
   the shield - and a cover background slides that glow under the copy at some
   widths. This makes the contrast a property of the design rather than of the
   viewport. */
.is-hero--banner::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,
    rgba(5, 14, 24, .94) 0%,
    rgba(5, 14, 24, .88) 34%,
    rgba(5, 14, 24, .55) 56%,
    rgba(5, 14, 24, .12) 78%,
    rgba(5, 14, 24, 0) 100%);
  pointer-events: none;
}
.is-hero--banner > .is-container { position: relative; z-index: 1; }

.is-hero--banner .is-hero__grid { grid-template-columns: minmax(0, 1fr); }
@media (min-width: 992px) {
  .is-hero--banner .is-hero__grid {
    /* Narrower than half, so the copy never reaches the product cluster. */
    grid-template-columns: minmax(0, 52%);
    padding-block: clamp(3.5rem, 1rem + 7vw, 6.5rem);
  }
}

.is-hero--banner h1,
.is-hero--banner .is-hero__sub { color: var(--is-white); }
.is-hero--banner .is-hero__eyebrow { color: rgba(255, 255, 255, .72); }
.is-hero--banner .is-hero__copy { color: rgba(255, 255, 255, .88); }

/* The button pair for a dark band. These are the values .is-btn--invert
   already uses, applied by scope rather than by adding classes to the markup
   in two builds - there is still one definition of "button on dark". */
.is-hero--banner .is-btn--primary { --_bg: #fff; --_fg: var(--is-black); --_bd: #fff; }
.is-hero--banner .is-btn--primary:hover { --_bg: var(--is-gray-light); --_bd: var(--is-gray-light); }
.is-hero--banner .is-btn--ghost { --_fg: #fff; --_bd: rgba(255, 255, 255, .55); }
.is-hero--banner .is-btn--ghost:hover { --_bd: #fff; --_bg: rgba(255, 255, 255, .08); }

@media (max-width: 991px) {
  /* A 16:9 banner cropped to a phone-shaped box loses most of its width. Held
     at the right edge the copy would sit directly on the cameras; pulled to
     68% some of the cluster stays visible as texture and the words sit on the
     darker side of it. The scrim turns vertical to match. */
  .is-hero--banner { background-position: 68% center; }
  .is-hero--banner::before {
    background: linear-gradient(180deg,
      rgba(5, 14, 24, .94) 0%,
      rgba(5, 14, 24, .88) 58%,
      rgba(5, 14, 24, .93) 100%);
  }
  .is-hero--banner .is-hero__grid { padding-block: var(--is-s7); }
}

.is-hero__media {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--is-white);
  border: 1px solid var(--is-line);
  border-radius: var(--is-radius);
  overflow: hidden;
}
.is-hero__media img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
  padding: var(--is-s6);
  opacity: 0;
  transition: opacity 320ms ease;
}
.is-hero__media img.is-active { opacity: 1; }

/* Thumbnails double as the slide control — no auto-rotation, so the reader
   is never fighting the page for the thing they were reading. */
.is-hero__thumbs {
  display: flex; gap: var(--is-s3);
  margin-top: var(--is-s4);
}
.is-hero__thumb {
  flex: 1 1 0;
  display: flex; align-items: center; gap: var(--is-s3);
  padding: var(--is-s2);
  border: 1px solid var(--is-line);
  border-radius: var(--is-radius-sm);
  background: var(--is-white);
  cursor: pointer;
  text-align: left;
  transition: border-color var(--is-t), box-shadow var(--is-t);
}
.is-hero__thumb:hover { border-color: #C9CDD2; }
.is-hero__thumb[aria-selected="true"] { border-color: var(--is-black); box-shadow: inset 0 0 0 1px var(--is-black); }
.is-hero__thumb img { width: 46px; height: 46px; object-fit: contain; flex: none; }
.is-hero__thumb span {
  font-size: var(--is-fs-xs);
  font-weight: 500;
  line-height: 1.35;
  color: var(--is-ink);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
@media (max-width: 575px) {
  .is-hero__thumb span { display: none; }
  .is-hero__thumb { flex: 0 0 auto; }
}

/* ==========================================================================
   8. Sections and bands
   ========================================================================== */

.is-section { padding-block: var(--is-section-y); }
.is-section--tight { padding-block: calc(var(--is-section-y) * .6); }
.is-section--soft { background: var(--is-bg-soft); }

/* Black band, used for the feature explainer and the promo. Sparingly —
   three dark sections in a row would flatten the page. */
.is-band-dark {
  background: var(--is-black);
  color: #fff;
}
.is-band-dark h2, .is-band-dark h3 { color: #fff; }
.is-band-dark .is-lead, .is-band-dark p { color: rgba(255,255,255,.72); }
.is-band-dark .is-label { color: rgba(255,255,255,.55); }
.is-band-dark .is-link { color: #fff; background-image: linear-gradient(#fff, #fff); }

.is-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--is-s4);
  margin-bottom: var(--is-s6);
}
.is-head__text { max-width: 62ch; }
.is-head__text .is-label { margin-bottom: var(--is-s2); display: block; }
.is-head h2 { margin-bottom: var(--is-s2); }
.is-head p { margin: 0; }

/* --- Category tiles ------------------------------------------------------ */

.is-cats {
  display: grid;
  gap: var(--is-s4);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 992px) { .is-cats { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.is-cat {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--is-line-soft);
  border-radius: var(--is-radius);
  background: var(--is-white);
  overflow: hidden;
  transition: border-color var(--is-t), box-shadow var(--is-t), transform var(--is-t);
}
.is-cat:hover { border-color: var(--is-line); box-shadow: var(--is-shadow-lift); transform: translateY(-2px); }
.is-cat__media { aspect-ratio: 4 / 3; background: var(--is-bg-soft); overflow: hidden; }
.is-cat__media img {
  width: 100%; height: 100%; object-fit: contain; padding: var(--is-s4);
  transition: transform 400ms cubic-bezier(.4, 0, .2, 1);
}
.is-cat:hover .is-cat__media img { transform: scale(1.06); }
.is-cat__body { padding: var(--is-s4); display: flex; flex-direction: column; gap: var(--is-s2); flex: 1 1 auto; }
.is-cat__name { font-family: var(--is-font-display); font-weight: 700; font-size: 1.0625rem; color: var(--is-black); }
.is-cat__count { font-size: var(--is-fs-xs); color: var(--is-text-2); }
.is-cat__subs { display: flex; flex-wrap: wrap; gap: var(--is-s1) var(--is-s2); margin-top: var(--is-s1); }
.is-cat__sub {
  font-size: var(--is-fs-xs);
  color: var(--is-ink-muted);
  padding: 2px var(--is-s2);
  border: 1px solid var(--is-line);
  border-radius: 999px;
  position: relative; z-index: 2;
}
.is-cat__sub:hover { border-color: var(--is-black); color: var(--is-black); }
.is-cat__go { margin-top: auto; padding-top: var(--is-s3); }
/* The whole tile is clickable, but the subcategory chips stay individually
   targetable because they sit above this overlay. */
.is-cat__link::after { content: ''; position: absolute; inset: 0; z-index: 1; }

/* --- Feature explainer --------------------------------------------------- */

.is-features { display: grid; gap: var(--is-s5); }
@media (min-width: 992px) { .is-features { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--is-s8); align-items: center; } }

.is-featlist { display: grid; gap: var(--is-s4); margin: var(--is-s6) 0 0; padding: 0; list-style: none; }
@media (min-width: 576px) { .is-featlist { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.is-feat { display: flex; gap: var(--is-s3); }
.is-feat__icon {
  flex: none; width: 38px; height: 38px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid rgba(255,255,255,.22);
  border-radius: var(--is-radius-sm);
  color: #fff;
}
.is-feat__t { font-family: var(--is-font-display); font-weight: 600; font-size: var(--is-fs-sm); color: #fff; margin-bottom: 2px; }
.is-feat__d { font-size: var(--is-fs-xs); color: rgba(255,255,255,.62); line-height: 1.55; margin: 0; }

/* A light panel on the dark band. The catalogue photography is shot on white,
   so a dark frame would just present it as a white rectangle floating in
   black; making the panel itself light reads as a deliberate inset instead. */
.is-featmedia {
  border-radius: var(--is-radius);
  overflow: hidden;
  background: var(--is-white);
  aspect-ratio: 4 / 3;
  display: grid; place-items: center;
}
.is-featmedia img { width: 100%; height: 100%; object-fit: contain; padding: var(--is-s5); }

/* --- Trust row ----------------------------------------------------------- */

.is-trust { display: grid; gap: var(--is-s5); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 992px) { .is-trust { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--is-s6); } }
.is-trust__item { display: flex; flex-direction: column; gap: var(--is-s2); }
.is-trust__icon { color: var(--is-black); }
.is-trust__t { font-family: var(--is-font-display); font-weight: 700; font-size: var(--is-fs-sm); color: var(--is-black); }
.is-trust__d { font-size: var(--is-fs-xs); color: var(--is-text-2); line-height: 1.6; margin: 0; }

/* --- Promo --------------------------------------------------------------- */

.is-promo { display: grid; gap: var(--is-s6); align-items: center; }
@media (min-width: 992px) { .is-promo { grid-template-columns: 1.1fr 1fr; gap: var(--is-s8); } }
.is-promo__media {
  aspect-ratio: 16 / 10;
  background: var(--is-white);   /* same reasoning as .is-featmedia above */
  border-radius: var(--is-radius);
  overflow: hidden;
  display: grid; place-items: center;
}
.is-promo__media img { width: 100%; height: 100%; object-fit: contain; padding: var(--is-s5); }

/* --- Reviews ------------------------------------------------------------- */

.is-reviews { display: grid; gap: var(--is-s4); }
@media (min-width: 768px) { .is-reviews { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.is-review {
  display: flex; flex-direction: column; gap: var(--is-s3);
  padding: var(--is-s5);
  border: 1px solid var(--is-line);
  border-radius: var(--is-radius);
  background: var(--is-white);
}
.is-review__text { font-size: var(--is-fs-sm); color: var(--is-ink-muted); margin: 0; }
.is-review__who { font-size: var(--is-fs-xs); color: var(--is-text-2); margin-top: auto; }
.is-review__name { font-weight: 600; color: var(--is-black); display: block; font-family: var(--is-font-display); }


/* --- Google reviews (Trustindex widget) ---------------------------------- */

/* The reviews themselves are drawn by the Trustindex plugin and are not ours
   to style. What is ours is the frame: the strip that says where they come
   from and links to the profile they come from, so the block is evidence
   rather than a claim — the same argument the rating block makes.
   Deliberately nothing here reaches inside .is-gr__slot. A plugin update
   cannot break this section, and this section cannot restyle a review. */

.is-gr {
  border: 1px solid var(--is-line);
  border-radius: var(--is-radius);
  background: var(--is-white);
  box-shadow: var(--is-shadow);
  overflow: hidden;
}

.is-gr__brand {
  display: flex;
  align-items: center;
  gap: var(--is-s4);
  padding: var(--is-s5);
  border-bottom: 1px solid var(--is-line-soft);
  background: linear-gradient(180deg, #FAFAFA, var(--is-white));
}

.is-gr__mark { flex: 0 0 auto; display: block; width: 26px; height: 26px; }

.is-gr__brand-text { flex: 1 1 0; min-width: 0; }

.is-gr__brand-name {
  margin: 0;
  font-family: var(--is-font-display);
  font-size: var(--is-fs-sm);
  font-weight: 700;
  line-height: 1.3;
  color: var(--is-black);
}

.is-gr__brand-note {
  margin: 2px 0 0;
  font-size: var(--is-fs-xs);
  line-height: 1.4;
  color: var(--is-text-2);
}

/* Pushed to the right edge on wide screens; drops to its own line rather than
   squeezing the note when there is no room. */
.is-gr__brand-link {
  margin-left: auto;
  font-family: var(--is-font-display);
  font-size: var(--is-fs-xs);
  font-weight: 600;
  white-space: nowrap;
}

/* The mount point. The min-height holds the section's shape for the moment
   between first paint and the widget's own script filling it, so the rest of
   the page does not jump downwards as the reviews arrive. */
.is-gr__slot { padding: var(--is-s5); min-height: 200px; }

/* Prototype only. The static build cannot run a WordPress shortcode, so the
   slot states what fills it instead of pretending to be reviews. The theme
   renders the shortcode here and never emits this element. */
.is-gr__stub {
  margin: 0;
  padding: var(--is-s7) var(--is-s5);
  border: 1px dashed var(--is-line);
  border-radius: var(--is-radius-sm);
  text-align: center;
  font-size: var(--is-fs-sm);
  line-height: 1.9;
  color: var(--is-text-2);
}

.is-gr__stub code {
  display: inline-block;
  padding: 2px var(--is-s2);
  border-radius: 4px;
  background: var(--is-bg-soft);
  color: var(--is-ink);
  font-size: var(--is-fs-xs);
}

@media (max-width: 575.98px) {
  .is-gr__brand { flex-wrap: wrap; }
  .is-gr__brand-link { margin-left: 0; flex-basis: 100%; }
  .is-gr__slot { padding: var(--is-s4); }
}

/* A visible, honest marker on any block holding sample content. It is meant
   to be seen in review and removed with the placeholder it wraps. */
.is-placeholder {
  border: 1px dashed #C9A227;
  border-radius: var(--is-radius);
  padding: var(--is-s5);
  background: #FFFDF5;
}
.is-placeholder__flag {
  display: inline-block;
  margin-bottom: var(--is-s4);
  padding: 3px var(--is-s2);
  border-radius: 4px;
  background: #C9A227;
  color: #fff;
  font-family: var(--is-font-display);
  font-size: var(--is-fs-label);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* --- Newsletter ---------------------------------------------------------- */

.is-news { display: grid; gap: var(--is-s5); align-items: center; }
@media (min-width: 992px) { .is-news { grid-template-columns: 1fr 1fr; gap: var(--is-s8); } }
.is-news__form { display: flex; flex-wrap: wrap; gap: var(--is-s3); }
.is-news__form .is-field { flex: 1 1 260px; margin: 0; }
.is-news__note { font-size: var(--is-fs-xs); color: var(--is-text-2); margin-top: var(--is-s3); }
.is-news__ok { display: none; color: var(--is-ok); font-size: var(--is-fs-sm); font-weight: 500; margin-top: var(--is-s3); }
.is-news.is-done .is-news__ok { display: block; }
.is-news.is-done .is-news__form { display: none; }

/* ==========================================================================
   9. Header, navigation, search
   ========================================================================== */

.is-announce {
  background: var(--is-black);
  color: rgba(255,255,255,.88);
  font-size: var(--is-fs-xs);
}
.is-announce__inner {
  display: flex; align-items: center; justify-content: center; gap: var(--is-s4);
  min-height: 38px;
  padding-block: var(--is-s2);
  text-align: center;
}
.is-announce a { color: #fff; text-decoration: underline; text-underline-offset: 3px; }
.is-announce__close {
  position: absolute; right: var(--is-s2); top: 50%; transform: translateY(-50%);
  background: none; border: 0; color: rgba(255,255,255,.6); cursor: pointer;
  /* 36px square: the icon is 14px, so the padding is doing the work of making
     this a real tap target rather than a pixel-hunt on a phone. */
  width: 36px; height: 36px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0; line-height: 0;
}
.is-announce__close:hover { color: #fff; }
.is-announce__inner { position: relative; }
.is-announce[hidden] { display: none; }

.is-header {
  position: sticky; top: 0; z-index: 900;
  background: var(--is-white);
  border-bottom: 1px solid var(--is-line);
  transition: box-shadow var(--is-t);
}
.is-header.is-stuck { box-shadow: 0 1px 12px rgba(0,0,0,.07); }

.is-header__bar {
  display: flex; align-items: center; gap: var(--is-s4);
  min-height: var(--is-header-h);
}
.is-logo { display: inline-flex; align-items: center; flex: none; }
.is-logo img { height: 26px; width: auto; display: block; }

/* At 320px the burger, a 145px logo and three 42px actions do not fit on one
   row. Tighten all three rather than wrapping the bar, which would double the
   header height on the narrowest screens. */
@media (max-width: 400px) {
  .is-header__bar { gap: var(--is-s2); }
  .is-logo img { height: 21px; }
  .is-header__actions .is-iconbtn { width: 38px; }
  .is-header__actions { gap: 0; }
}

.is-header__nav { display: none; }
@media (min-width: 992px) { .is-header__nav { display: block; margin-inline: auto; } }

/* Between 992 and 1200 the full menu no longer fits beside the logo and the
   action icons — it pushed the bar to 1181px inside a 1024px viewport. The
   secondary items drop out at that range; every one of them is still in the
   mega menu, the mobile drawer and the footer, so nothing becomes unreachable. */
@media (max-width: 1199px) {
  .is-menu > li.is-menu--secondary { display: none; }
}

.is-menu { display: flex; align-items: center; gap: var(--is-s2); list-style: none; margin: 0; padding: 0; }
.is-menu > li { position: relative; }
.is-menu > li > a, .is-menu > li > button {
  display: inline-flex; align-items: center; gap: var(--is-s1);
  padding: var(--is-s3) var(--is-s3);
  border: 0; background: none; cursor: pointer;
  font-family: var(--is-font-display);
  font-size: var(--is-fs-sm);
  font-weight: 600;
  color: var(--is-ink);
  white-space: nowrap;
}
.is-menu > li > a:hover, .is-menu > li > button:hover,
.is-menu > li > a[aria-current="page"] { color: var(--is-black); }
.is-menu > li > a[aria-current="page"] { text-decoration: underline; text-underline-offset: 6px; text-decoration-thickness: 2px; }
.is-menu__caret { transition: transform var(--is-t); }
.is-menu > li > button[aria-expanded="true"] .is-menu__caret { transform: rotate(180deg); }

/* Mega menu — one panel listing real categories and their children. */
.is-mega {
  position: absolute; top: calc(100% + 1px); left: 50%; transform: translateX(-50%);
  width: min(880px, calc(100vw - 3rem));
  background: var(--is-white);
  border: 1px solid var(--is-line);
  border-radius: var(--is-radius);
  box-shadow: var(--is-shadow-lift);
  padding: var(--is-s5);
  display: grid;
  gap: var(--is-s5);
  grid-template-columns: repeat(4, minmax(0, 1fr));
  z-index: 950;
}
.is-mega[hidden] { display: none; }
.is-mega__col > .is-label { display: block; margin-bottom: var(--is-s3); }
.is-mega__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--is-s2); }
.is-mega__list a { font-size: var(--is-fs-sm); color: var(--is-ink-muted); }
.is-mega__list a:hover { color: var(--is-black); }
.is-mega__all { grid-column: 1 / -1; border-top: 1px solid var(--is-line-soft); padding-top: var(--is-s4); }

.is-header__actions { display: flex; align-items: center; gap: var(--is-s1); margin-left: auto; }
@media (min-width: 992px) { .is-header__actions { margin-left: 0; } }

.is-count {
  position: absolute; top: 4px; right: 2px;
  min-width: 18px; height: 18px; padding: 0 4px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px;
  background: var(--is-black);
  color: #fff;
  font-family: var(--is-font-display);
  font-size: 10px; font-weight: 700; line-height: 1;
}
.is-count[data-count="0"] { display: none; }

.is-burger { display: inline-flex; }
@media (min-width: 992px) { .is-burger { display: none; } }

/* --- Search overlay ------------------------------------------------------ */

.is-search {
  position: fixed; inset: 0; z-index: 1200;
  background: rgba(0,0,0,.5);
  display: flex; align-items: flex-start; justify-content: center;
  padding: var(--is-s5) var(--is-s4);
  opacity: 0;
  transition: opacity var(--is-t);
}
.is-search[hidden] { display: none; }
.is-search.is-open { opacity: 1; }
.is-search__panel {
  width: min(720px, 100%);
  margin-top: 8vh;
  background: var(--is-white);
  border-radius: var(--is-radius);
  padding: var(--is-s5);
  box-shadow: var(--is-shadow-lift);
}
.is-search__row { display: flex; gap: var(--is-s3); }
.is-search__results { margin-top: var(--is-s4); max-height: 46vh; overflow-y: auto; }
.is-search__item {
  display: flex; align-items: center; gap: var(--is-s3);
  padding: var(--is-s2);
  border-radius: var(--is-radius-sm);
}
.is-search__item:hover, .is-search__item:focus-visible { background: var(--is-bg-soft); }
.is-search__item img { width: 48px; height: 48px; object-fit: contain; background: var(--is-bg-soft); border-radius: 4px; flex: none; }
.is-search__name { font-size: var(--is-fs-sm); line-height: 1.4; }
.is-search__empty { padding: var(--is-s5) 0; color: var(--is-text-2); font-size: var(--is-fs-sm); }

/* --- Mobile drawer nav --------------------------------------------------- */

.is-mnav {
  position: fixed; inset: 0 auto 0 0; z-index: 1300;
  width: min(360px, 88vw);
  background: var(--is-white);
  transform: translateX(-100%);
  transition: transform var(--is-t);
  display: flex; flex-direction: column;
  overflow-y: auto;
}
.is-mnav.is-open { transform: none; }
.is-mnav__head {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--is-s4);
  border-bottom: 1px solid var(--is-line);
}
.is-mnav__body { padding: var(--is-s4); }
.is-mnav__list { list-style: none; margin: 0 0 var(--is-s4); padding: 0; }
.is-mnav__list > li { border-bottom: 1px solid var(--is-line-soft); }
.is-mnav__list a, .is-mnav__toggle {
  display: flex; align-items: center; justify-content: space-between; width: 100%;
  padding: var(--is-s3) 0;
  border: 0; background: none; text-align: left;
  font-family: var(--is-font-display); font-weight: 600; font-size: var(--is-fs-sm);
  color: var(--is-ink); cursor: pointer;
}
/* The group headings - SHOP, CATEGORIES, HELP. Small, spaced and quiet: they
   label the list under them and must not read as another thing to tap. */
.is-mnav__grouplabel {
  margin: var(--is-s5) 0 var(--is-s2);
  font-family: var(--is-font-display);
  font-weight: 700;
  font-size: var(--is-fs-xs);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--is-text-2);
}

/* The first one sits at the top of the drawer and needs no space above it. */
.is-mnav__grouplabel:first-child { margin-top: 0; }

/* Says "this opens a page of its own". Pushed to the end by the flex rule the
   links already carry. */
.is-mnav__chev { color: var(--is-text-2); font-size: 1.1rem; line-height: 1; }

.is-mnav__sub { list-style: none; margin: 0 0 var(--is-s3); padding: 0 0 0 var(--is-s4); display: grid; gap: var(--is-s2); }
.is-mnav__sub[hidden] { display: none; }
.is-mnav__sub a { font-family: var(--is-font-body); font-weight: 400; color: var(--is-text-2); padding: var(--is-s1) 0; }

/* A category with sub-categories: the name goes to the category page, the
   "+" beside it opens its sub-categories in place and turns into a "-". */
.is-mnav__row { display: flex; align-items: center; gap: var(--is-s2); }
.is-mnav__row > a { flex: 1 1 auto; min-width: 0; }
.is-mnav__plus {
  position: relative; flex: none;
  width: 40px; height: 40px; margin-right: -10px;
  border: 0; background: none; border-radius: 50%;
  color: var(--is-ink); cursor: pointer;
}
.is-mnav__plus::before, .is-mnav__plus::after {
  content: ''; position: absolute; top: 50%; left: 50%;
  width: 14px; height: 2px; margin: -1px 0 0 -7px;
  border-radius: 2px; background: currentColor;
  transition: transform var(--is-t), opacity var(--is-t);
}
.is-mnav__plus::after { transform: rotate(90deg); }
.is-mnav__plus[aria-expanded="true"]::after { transform: rotate(0deg); opacity: 0; }
.is-mnav__plus:hover, .is-mnav__plus:focus-visible { background: var(--is-bg-soft, #f4f4f6); }
.is-mnav__item--parent .is-mnav__sub { padding-bottom: var(--is-s2); }

/* ==========================================================================
   10. Side cart, overlay, toasts, modal
   ========================================================================== */

.is-overlay {
  position: fixed; inset: 0; z-index: 1250;
  background: rgba(0,0,0,.5);
  opacity: 0;
  transition: opacity var(--is-t);
}
.is-overlay[hidden] { display: none; }
.is-overlay.is-open { opacity: 1; }

.is-sidecart {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 1300;
  width: min(420px, 92vw);
  background: var(--is-white);
  display: flex; flex-direction: column;
  transform: translateX(100%);
  transition: transform var(--is-t);
}
.is-sidecart.is-open { transform: none; }
.is-sidecart__head {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--is-s4) var(--is-s5);
  border-bottom: 1px solid var(--is-line);
}
.is-sidecart__head h2 { margin: 0; font-size: 1.0625rem; }
.is-sidecart__body { flex: 1 1 auto; overflow-y: auto; padding: var(--is-s4) var(--is-s5); }
.is-sidecart__foot { border-top: 1px solid var(--is-line); padding: var(--is-s4) var(--is-s5); }
.is-sidecart__row { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: var(--is-s2); }
.is-sidecart__total { font-family: var(--is-font-display); font-weight: 700; font-size: 1.125rem; color: var(--is-black); }
.is-sidecart__note { font-size: var(--is-fs-xs); color: var(--is-text-2); margin: 0 0 var(--is-s4); }
.is-sidecart__actions { display: grid; gap: var(--is-s2); }

.is-line {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr);
  gap: var(--is-s3);
  padding-block: var(--is-s4);
  border-bottom: 1px solid var(--is-line-soft);
}
.is-line:last-child { border-bottom: 0; }
.is-line__media { aspect-ratio: 1/1; background: var(--is-bg-soft); border-radius: var(--is-radius-sm); overflow: hidden; }
.is-line__media img { width: 100%; height: 100%; object-fit: contain; padding: 6px; }
.is-line__name { font-size: var(--is-fs-xs); line-height: 1.45; margin-bottom: var(--is-s1); display: block; }
.is-line__price { font-size: var(--is-fs-sm); font-weight: 600; font-variant-numeric: tabular-nums; }
.is-line__foot { display: flex; align-items: center; justify-content: space-between; gap: var(--is-s3); margin-top: var(--is-s2); }
.is-line__remove {
  border: 0; background: none; cursor: pointer;
  /* Vertical padding rather than a bare text link: this is a standalone
     destructive control, and at 21px tall it was an awkward tap on a phone. */
  padding: var(--is-s2) 0;
  min-height: 32px;
  font-size: var(--is-fs-xs); color: var(--is-text-2); text-decoration: underline; text-underline-offset: 2px;
}
.is-line__remove:hover { color: #B42318; }

/* Quantity stepper — shared by side cart, cart page and product page. */
.is-qty {
  display: inline-flex; align-items: center;
  border: 1px solid var(--is-line);
  border-radius: var(--is-radius-sm);
  overflow: hidden;
}
.is-qty button {
  width: 34px; height: 34px;
  border: 0; background: var(--is-white); cursor: pointer;
  color: var(--is-ink);
  display: inline-flex; align-items: center; justify-content: center;
}
.is-qty button:hover { background: var(--is-bg-soft); }
.is-qty input {
  width: 40px; height: 34px;
  border: 0; border-inline: 1px solid var(--is-line);
  text-align: center;
  font-family: var(--is-font-body); font-size: var(--is-fs-xs);
  font-variant-numeric: tabular-nums;
  -moz-appearance: textfield;
}
.is-qty input::-webkit-outer-spin-button, .is-qty input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.is-qty--lg button { width: 44px; height: 46px; }
.is-qty--lg input { width: 52px; height: 46px; font-size: var(--is-fs-sm); }

/* Empty state, reused by cart, wishlist, search and filtered grids. */
.is-empty { text-align: center; padding: var(--is-s7) var(--is-s4); }
.is-empty__icon {
  width: 56px; height: 56px; margin: 0 auto var(--is-s4);
  display: grid; place-items: center;
  border: 1px solid var(--is-line);
  border-radius: 50%;
  color: var(--is-text-2);
}
.is-empty h2, .is-empty h3 { font-size: var(--is-fs-h3); margin-bottom: var(--is-s2); }
.is-empty p { color: var(--is-text-2); font-size: var(--is-fs-sm); max-width: 38ch; margin-inline: auto; }
.is-empty__actions { margin-top: var(--is-s5); display: flex; gap: var(--is-s3); justify-content: center; flex-wrap: wrap; }

/* Toasts */
.is-toasts {
  position: fixed; z-index: 1400; right: var(--is-s4);
  /* Same treatment as the float: a toast behind the buy bar is a toast
     nobody reads. */
  bottom: calc(var(--is-bottombar-h, 0px) + var(--is-s4));
  display: flex; flex-direction: column; gap: var(--is-s2);
  pointer-events: none;
}
.is-toast {
  display: flex; align-items: center; gap: var(--is-s3);
  min-width: 260px; max-width: 340px;
  padding: var(--is-s3) var(--is-s4);
  background: var(--is-black);
  color: #fff;
  border-radius: var(--is-radius-sm);
  box-shadow: var(--is-shadow-lift);
  font-size: var(--is-fs-sm);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--is-t), transform var(--is-t);
}
.is-toast.is-in { opacity: 1; transform: none; }
.is-toast__icon { color: #7CE2AE; display: inline-flex; flex: none; }

/* Scroll lock. The padding compensates for the scrollbar the lock removes,
   measured in JS, so the sticky header does not jump when a panel opens. */
body.is-locked { overflow: hidden; padding-right: var(--scrollbar-w, 0px); }
body.is-locked .is-header { padding-right: var(--scrollbar-w, 0px); }

/* ==========================================================================
   Footer
   ========================================================================== */

.is-footer { background: var(--is-black); color: rgba(255,255,255,.66); }
.is-footer a { color: rgba(255,255,255,.66); }
.is-footer a:hover { color: #fff; }
.is-footer__top { padding-block: var(--is-s8) var(--is-s6); }
.is-footer__grid { display: grid; gap: var(--is-s6); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 768px) { .is-footer__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 992px) { .is-footer__grid { grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: var(--is-s7); } }
.is-footer__brand { grid-column: 1 / -1; }
@media (min-width: 992px) { .is-footer__brand { grid-column: auto; } }
.is-footer__logo { height: 24px; width: auto; filter: invert(1); margin-bottom: var(--is-s4); }
.is-footer__about { font-size: var(--is-fs-sm); line-height: 1.7; max-width: 40ch; }
.is-footer .is-label { color: rgba(255,255,255,.5); display: block; margin-bottom: var(--is-s4); }
.is-footer__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--is-s3); }
.is-footer__list a { font-size: var(--is-fs-sm); }
.is-footer__contact { display: grid; gap: var(--is-s3); font-size: var(--is-fs-sm); font-style: normal; }
.is-footer__contact a { color: #fff; }
.is-footer__social { display: flex; gap: var(--is-s2); margin-top: var(--is-s5); }
.is-footer__social a {
  width: 38px; height: 38px; display: grid; place-items: center;
  border: 1px solid rgba(255,255,255,.2); border-radius: var(--is-radius-sm);
}
.is-footer__social a:hover { border-color: #fff; }
.is-footer__bottom {
  border-top: 1px solid rgba(255,255,255,.14);
  padding-block: var(--is-s5);
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--is-s4);
  font-size: var(--is-fs-xs);
}
.is-footer__pay { display: flex; align-items: center; gap: var(--is-s3); flex-wrap: wrap; }
.is-footer__pay span {
  padding: 4px var(--is-s2);
  border: 1px solid rgba(255,255,255,.2);
  border-radius: 4px;
  font-size: var(--is-fs-label);
  letter-spacing: 0.04em;
}

/* --- WhatsApp / call float ----------------------------------------------- */

.is-float {
  position: fixed; right: var(--is-s4); z-index: 880;
  /* Sits above any bar at the bottom of the screen rather than on top of it.
     --is-bottombar-h is published by the bottom-stack script in main.js and is
     0 when nothing is showing, which gives the plain 16px offset. */
  bottom: calc(var(--is-bottombar-h, 0px) + var(--is-s4));
  display: inline-flex; align-items: center; gap: var(--is-s2);
  padding: var(--is-s3) var(--is-s4);
  background: #128C7E;
  color: #fff;
  border-radius: 999px;
  font-family: var(--is-font-display);
  font-size: var(--is-fs-xs);
  font-weight: 700;
  box-shadow: var(--is-shadow-lift);
}
.is-float:hover { color: #fff; background: #0E7466; }
/* Mobile: a real circular button, not a squashed pill.
   Three things were wrong on a phone. The label was hidden but the padding was
   left to define the size, so the tap target came out under the 44px minimum;
   there was no allowance for the iOS home indicator, so on a notched phone it
   sat in the swipe area; and at 880 it could cover the sticky add-to-cart bar's
   own controls when the bottom-bar variable had not been published yet. */
@media (max-width: 575px) {
  .is-float {
    width: 52px; height: 52px; padding: 0;
    justify-content: center;
    bottom: calc(var(--is-bottombar-h, 0px) + var(--is-s4) + env(safe-area-inset-bottom, 0px));
    right: calc(var(--is-s3) + env(safe-area-inset-right, 0px));
  }
  .is-float span { display: none; }
  .is-float svg { width: 24px; height: 24px; }
}
/* A phone in landscape has almost no vertical room; shrink rather than cover
   the content. */
@media (max-width: 900px) and (max-height: 460px) {
  .is-float { width: 44px; height: 44px; }
  .is-float svg { width: 20px; height: 20px; }
}
