/* ═══════════════════════════════════════════════════════════════════════
   SIGNAL — CHROME. Header, footer, and the ground under every page.

   The first Signal stylesheet that is NOT gated to a template. That is the
   point at which the theme stops decorating three pages and starts being the
   site — and the first file that will still be needed after Woostify is gone.
   ═══════════════════════════════════════════════════════════════════════ */

/* The ground. Woostify paints the page white; Signal's paper is warm cream,
   and a white band above and below a cream page is the single most visible
   way to break it. */
body { background: var(--sig-paper); color: var(--sig-ink); font-family: var(--sig-body); }

/* ── Skip link ──────────────────────────────────────────────────────────
   Off screen until focused, then a real visible target. Woostify shipped two
   of these; one is enough, and it has to actually appear when tabbed to. */
.sig-skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--sig-ink); color: var(--sig-paper);
  padding: 12px 18px; border-radius: 0 0 var(--sig-r-img) 0;
  font-size: 15px; font-weight: 600; text-decoration: none;
}
.sig-skip:focus { left: 0; }

/* ══════════════════════════════════════════════════════════════════════
   HEADER AND FOOTER — REBUILT TOGETHER 2026-09-02.

   They are one component with a page between them, and they had been
   maintained as two.

   EVERY RULE HERE IS WRITTEN AT (0,2,0), and that is not style.
   `.sig-foot__h` was (0,1,0). The checkout page loads Elementor's kit
   stylesheet — `post-1809.css` — which contains

       .elementor-kit-1809 h2 { font-size: 32px; font-family: Poppins;
                                color: var(--e-global-color-primary) }

   at (0,1,1). So on ONE page of the site the footer headings rendered
   **32px Poppins #262626** instead of 12px Barlow muted, and nothing in
   this file explained why. The chrome is the one thing that must be
   identical on every page, and it was written at a specificity any plugin
   could outrank. Scoping each rule under `.sig-head` / `.sig-foot` costs
   nothing and closes the whole class of bug, not just this instance.

   THE YELLOW BUDGET. `../design/README.md` reserves exactly two yellow
   FILLS per page — the primary CTA and the "best value" tab — and the
   critique found the budget already overspent. The header was quietly
   taking one of the two for the cart count badge, on every page, before
   any page content existed. The badge is ink now. Yellow survives in the
   chrome as one MARK: the navigation underline, which is Treatment C and
   is what the system says a selected state looks like.
   ══════════════════════════════════════════════════════════════════════ */

/* ── Header ─────────────────────────────────────────────────────────────
   A mark, a name, the navigation, a phone number and the cart.

   Woostify's carried a search overlay and an account icon too. Eight
   products do not need a search box — it is a control whose best answer is
   the shop page — and a cash-on-delivery store with guest checkout does not
   need an account door on every screen. Both removed rather than restyled. */
/* ⚠️ THE FACE MUST BE DECLARED, NOT INHERITED — and this is the (0,2,0) note
   above, one layer deeper.

   chrome.css sets `body { font-family: var(--sig-body) }` at (0,0,1).
   Elementor's kit sets `font-family: Poppins` on the body element via
   `.elementor-kit-1809` — (0,1,0), in a stylesheet loaded AFTER this one. So
   on checkout the body face was Poppins, and every chrome element that simply
   INHERITED its face came out Poppins with it: the footer links, the plain
   facts, the legal line and the phone number. Only the elements that declare a
   family of their own — the keyed headings, the wordmark, the nav — were
   right, which is why the page looked *almost* correct and the fault survived
   a pass that checked the headings alone.

   `line-height` is pinned for the same reason and is worth stating separately,
   because it fails in a way that looks like nothing: the kit sets
   `line-height: 1.6em` on the body, and an `em` line-height computes to a
   LENGTH at the element that declares it, so it inherits as a fixed 22.4px
   rather than as a ratio. Measured before this: the footer's legal line was
   13px/22.4px on checkout against 13px/20.15px on every other page, and the
   whole footer stood **2.27px taller there** — a difference no one would ever
   find by looking, on the one page where the money is taken.

   Doubling the class is (0,2,0) and outranks the kit. Everything inside both
   landmarks inherits from here instead of from `body`. */
.sig-head.sig-head,
.sig-foot.sig-foot { font-family: var(--sig-body); line-height: 1.55; }

/* THE THEME WAS BORROWING WooCommerce's `.screen-reader-text` RULE.
   The cart badge's hidden count carried that class and the theme never
   defined it — it was invisible only because woocommerce.css happens to load
   on every page that renders a cart link. That holds until the day someone
   dequeues it for performance, at which point a stray "1 item" appears beside
   the cart icon and the cause is in another plugin's stylesheet. Ours now.

   `clip-path` with a 1px box rather than `display: none`, because content
   hidden with `display: none` is removed from the accessibility tree and this
   text exists solely to be announced. */
.sig-sr {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px; border: 0;
  overflow: hidden; clip-path: inset(50%);
  white-space: nowrap;
}

.sig-head {
  background: var(--sig-paper);
  /* --sig-hair, not --sig-rule: the header's own edge was 1.25:1 against
     paper and effectively undrawn. See the token note in style.css. */
  border-bottom: 1px solid var(--sig-hair);
  position: relative; z-index: 10;
}

/* THE CHROME MEASURE — CORRECTED 2026-09-02, SAME DAY, AFTER MEASURING IT.
   This first shipped on `--sig-gut` with a 1600px cap, reasoning that chrome
   should agree with the homepage, which runs full-bleed because the plates
   want the width. Measured across viewports, that reasoning bought one page
   and lost four:

     1280 /shop/   header brand x=38  · page content x=70   →  32px
     1440 /cart/   x=43               · x=150               → 107px
     1600 /shop/   x=48               · x=230               → 182px
     1920 /shop/   x=212              · x=390               → 178px

   32px is the worst possible amount — too small to read as a decision, too
   large to read as alignment — and it grows to 182px by 1600. The previous
   commit's own claim was "one measure on every page"; there were two.

   The chrome now takes the SAME rule as `.sig-main`: max-width 1180, 20px of
   padding, border-box. So the logo sits directly above the first pixel of page
   content on the shop, the PDP, the cart, About and the policy pages, at every
   width. The homepage is the exception it already declares itself to be —
   full-bleed images under a contained header is a relationship that reads as
   intentional, which an inconsistent 32–182px stagger never did.

   `--sig-shell` is retired with this: a 1180px cap cannot run away at 2560px,
   so the cap it existed to provide is now inherent. */
.sig-head .sig-head__in {
  box-sizing: border-box;
  max-width: 1180px;
  margin-inline: auto;
  padding-inline: 20px;
  padding-block: var(--sig-2);
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--sig-2);
}

/* ── The mark and the name ──────────────────────────────────────────────
   ONE link, not two. `the_custom_logo()` emits its own anchor; putting a
   wordmark beside it would have produced two adjacent links to the same
   destination, one an image and one text, both announcing "home". The
   image is rendered inside this anchor instead — see seamless_the_logo(),
   which also states the `sizes` that had the browser fetching a 1080px
   file for a 59px slot on every page of the site. */
.sig-head .sig-head__brand {
  display: inline-flex; align-items: center; gap: 10px;
  min-height: 44px; flex: 0 1 auto; min-width: 0;
  color: var(--sig-ink); text-decoration: none;
}
.sig-head .sig-head__logo { width: auto; height: 34px; display: block; flex: none; }
.sig-head .sig-head__name {
  font-family: var(--sig-display); font-weight: 400;
  font-size: 17px; line-height: 1.1; letter-spacing: -.01em;
  /* Truncates rather than wraps. A two-line wordmark would change the
     header's height, and the header's height is on every page. */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── Navigation ─────────────────────────────────────────────────────────
   44px AT BOTH WIDTHS. It was 44px on desktop and 38px on mobile —
   inverted, and named as such in critique-2026-09-01. A pointer is precise
   and a thumb is not, so where the two differ the phone gets the larger
   target. The font size was 15/14.5 for the same absence of a reason; one
   value removes a step from a scale that has eight inside a 5px band. */
.sig-head .sig-nav { min-width: 0; }
.sig-head .sig-nav__list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; align-items: center;
  gap: clamp(10px, 1.6vw, 26px);
}
.sig-head .sig-nav__list a {
  position: relative;
  display: inline-flex; align-items: center; min-height: 44px;
  color: var(--sig-ink); text-decoration: none;
  font-family: var(--sig-body); font-size: 15px; font-weight: 500;
}

/* Treatment C — ink on paper, yellow as a mark. Drawn as a bar rather than
   an inset shadow: on a 44px-tall inline-flex box an inset shadow paints at
   the bottom of the TARGET, ~11px clear of the baseline, so the underline
   floated away from the word it belonged to. Same failure mode as the
   category chip's crescent, different cause. */
.sig-head .sig-nav__list a::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 10px;
  height: 2px; border-radius: 2px; background: var(--sig-yellow);
  opacity: 0; transition: opacity .12s ease;
}
.sig-head .sig-nav__list a:hover::after { opacity: 1; }
/* WordPress sets these itself, so the state costs nothing. */
.sig-head .sig-nav__list .current-menu-item > a::after,
.sig-head .sig-nav__list .current_page_item > a::after { opacity: 1; height: 3px; }

/* ── The right-hand end: phone, then cart ───────────────────────────────  */
.sig-head .sig-head__end {
  display: flex; align-items: center; gap: var(--sig-2);
  margin-left: auto; flex: none;
}

.sig-head .sig-tel {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px; min-width: 44px;
  color: var(--sig-ink); text-decoration: none;
  font-size: 15px; font-weight: 500; font-variant-numeric: tabular-nums;
}
.sig-head .sig-tel svg {
  width: 19px; height: 19px; fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}
.sig-head .sig-tel:hover .sig-tel__n { text-decoration: underline; text-underline-offset: 3px; }
/* Nothing an editor needs to see belongs in the header of a live store. The
   unset-number prompt renders in the footer, where there is room for the
   sentence. */
.sig-head .sig-tel--empty { display: none; }

/* ── Cart ───────────────────────────────────────────────────────────────  */
/* ⚠️ `.sig-cart` IS THE HEADER LINK, NOT THE CART PAGE. The bag on /cart/ is
   `.sig-bag` — see woocommerce/cart/cart.php. Naming the cart form `.sig-cart`
   put `display:inline-flex; min-width:44px` on a whole <form>, a collision that
   only surfaces as a mangled layout on one page. */
.sig-head .sig-cart {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  min-height: 44px; min-width: 44px;
  color: var(--sig-ink); text-decoration: none;
}
.sig-head .sig-cart svg {
  width: 23px; height: 23px; fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}
/* INK, NOT YELLOW — see the budget note at the top of this file. It also
   simply reads better: ink on paper is 16.9:1 where yellow on paper is
   1.7:1, and a count is a number worth seeing. */
.sig-head .sig-cart__n {
  min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px;
  background: var(--sig-ink); color: var(--sig-paper);
  display: grid; place-items: center;
  font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums;
}
/* An empty cart does not need a badge saying so. */
.sig-head .sig-cart__n.is-empty { display: none; }

.sig-head a:focus-visible {
  outline: 2px solid var(--sig-ink); outline-offset: 2px; border-radius: 4px;
}

/* ── Header, narrow ─────────────────────────────────────────────────────
   No hamburger, and no drawer to build. At this catalogue size the whole
   menu is five words, so it takes its own row under the brand instead. A
   menu you can read beats a menu you have to open.

   The phone keeps its number as the link's ACCESSIBLE NAME while the digits
   are clipped — `display: none` would leave a tap-to-call control that
   announces itself as "link" and nothing else. The full number is printed
   in the footer, where there is width for it. */
@media (max-width: 899px) {
  /* GRID, NOT WRAP — two rows guaranteed at every width.
     As a wrapping flex row this collapsed to THREE rows at 360px and below as
     soon as the cart badge appeared: a filled cart widens `.sig-cart` from
     44px to 62px, the brand's 215px and the end's 114px stopped fitting in
     324px of content, and the end block wrapped to a row of its own — an
     orphan band holding a phone glyph and a cart icon, 165px of header on a
     700px screen. `minmax(0, 1fr)` lets the wordmark ellipsize instead, which
     is what its `text-overflow` was always for. */
  .sig-head .sig-head__in {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "brand end" "nav nav";
    row-gap: var(--sig-2); column-gap: var(--sig-2);
  }
  .sig-head .sig-head__brand { grid-area: brand; }
  .sig-head .sig-head__end   { grid-area: end; margin-left: 0; }
  .sig-head .sig-nav { grid-area: nav; }
  .sig-head .sig-tel__n {
    position: absolute; width: 1px; height: 1px;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
}

@media (min-width: 900px) {
  /* The navigation sits on the page's centre line rather than being shoved
     against the cart. Measured before this: the logo ended at x=97 and the
     first nav item began at x=839 — 742px of nothing, which is most of the
     "it looks thin" complaint. `1fr auto 1fr` centres the menu on the page
     however unequal the two flanks are. */
  .sig-head .sig-head__in {
    display: grid; grid-template-columns: 1fr auto 1fr;
    align-items: center; gap: var(--sig-4);
    padding-block: 14px; min-height: 72px;
  }
  .sig-head .sig-head__brand { justify-self: start; }
  .sig-head .sig-nav        { justify-self: center; }
  .sig-head .sig-head__end  { grid-column: 3; justify-self: end; margin-left: 0; }
  .sig-head .sig-head__logo { height: 44px; }
  .sig-head .sig-head__name { font-size: 20px; }
}

@media (prefers-reduced-motion: reduce) {
  .sig-head .sig-nav__list a::after { transition: none; }
}

/* ── Footer ─────────────────────────────────────────────────────────────
   Woostify's was a single "Pages" widget listing Cart, Checkout, My account
   and Wishlist beside the real pages — a sitemap of the plumbing. On a
   low-trust COD store the job is narrower: what you sell, how to reach a
   human, and who is legally behind the shop.

   IT IS DRAWN AS A TITLE BLOCK, and the reason is not decorative. The
   homepage's signature is a plate with numbered pins and a schedule; the
   PDP's is a measured elevation. The vernacular this site already speaks is
   the technical drawing, and a drawing's constant element — the one part
   identical on every sheet — is the title block: an identity band, a row of
   ruled fields under keyed labels, a legal line. That is exactly what site
   chrome is. So the footer is ruled rather than floated in whitespace, and
   it now rhymes with the header: mark and name at the left, the phone at
   the right, one gutter, one hairline.

   The old grid was `repeat(4, 1fr)` with a fourth cell that renders only
   when a `footer` menu is assigned, and none is. Measured at 1280px: three
   columns ending at x=929 and **351px of empty grid** beside them. */
.sig-foot {
  background: var(--sig-panel);
  border-top: 1px solid var(--sig-hair);
  margin-top: var(--sig-8);
  color: var(--sig-ink);
}
.sig-foot .sig-foot__in {
  box-sizing: border-box;
  max-width: 1180px;
  margin-inline: auto;
  padding-inline: 20px;
}

/* ── The identity band ──────────────────────────────────────────────────  */
.sig-foot .sig-foot__id {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: var(--sig-4);
  padding-block: var(--sig-4);
}
.sig-foot .sig-foot__brand {
  display: inline-flex; align-items: center; gap: 10px;
  min-height: 44px; color: var(--sig-ink); text-decoration: none;
}
.sig-foot .sig-foot__logo { width: auto; height: 38px; display: block; flex: none; }
.sig-foot .sig-foot__name {
  font-family: var(--sig-display); font-weight: 400;
  font-size: 19px; line-height: 1.1; letter-spacing: -.01em;
}

/* THE PHONE, AT THE SIZE THE SCORE SAYS IT IS WORTH. Help & Documentation
   scored 3/12 across the site for one reason: there is no phone number on
   it. Every BD store in `references/2026-08-14-bd-reference-teardown.md`
   leads with one. This is the largest element in the footer on purpose. */
.sig-foot .sig-foot__tel {
  display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap;
  min-height: 44px; color: var(--sig-ink); text-decoration: none;
  font-size: 18px; font-weight: 600; font-variant-numeric: tabular-nums;
}
.sig-foot .sig-foot__tel svg {
  width: 20px; height: 20px; fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}
.sig-foot .sig-tel__hrs { font-size: 14px; font-weight: 400; color: var(--sig-muted); }
.sig-foot .sig-foot__tel:hover .sig-tel__n { text-decoration: underline; text-underline-offset: 3px; }

/* Editors only — a missing trust element is invisible by nature, which is
   how this one survived months of looking at the site. */
.sig-foot .sig-foot__tel--empty {
  font-size: 13px; font-weight: 400; line-height: 1.5;
  color: var(--sig-warn); background: var(--sig-card);
  border: 1px dashed var(--sig-hair); border-radius: var(--sig-r-row);
  padding: 10px 14px; max-width: 46ch;
}

/* ── The ruled field row ────────────────────────────────────────────────  */
.sig-foot .sig-foot__grid { display: grid; border-top: 1px solid var(--sig-hair); }
/* --sig-4 on a phone, --sig-5 from 760px up. Stacked, the block measured
   832px against the old footer's 540 — a full viewport of footer. It is
   carrying a phone number, hours and a wordmark the old one did not, so some
   of that is earned; three cells' worth of 24px padding was not. */
.sig-foot .sig-foot__cell { padding-block: var(--sig-4); border-top: 1px solid var(--sig-hair); }
.sig-foot .sig-foot__cell:first-child { border-top: 0; }

.sig-foot .sig-foot__h {
  font-family: var(--sig-body); font-size: 12px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; line-height: 1.2;
  color: var(--sig-muted); margin: 0 0 var(--sig-3);
}

/* ONE ROW HEIGHT FOR EVERY CELL, links and plain facts alike.
   Before this the Shop column ran on a 48px pitch and the Ordering column
   beside it on 30px, because links carried a target height and facts did
   not. Two adjacent columns on two leadings is the kind of self-disagreement
   critique-2026-09-01 spent most of its deductions on — it is visible, and
   it is not nameable by a reader, which is the worst combination. */
.sig-foot .sig-foot__cell ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.sig-foot .sig-foot__cell li { color: var(--sig-muted); font-size: 14.5px; line-height: 1.5; }

/* THE UNIFORM ROW HEIGHT IS A DESKTOP RULE, and only there does it pay.
   Its job is to line the three columns up with each other. Stacked on a
   phone there are no parallel columns to line up, so a 36px box on the three
   Ordering statements — which are text, not targets — was buying nothing and
   costing 132px. The footer measured 768px on a 390x844 screen: 91% of the
   viewport, and 61% of the whole document on an empty cart. Links keep their
   target size at every width; only the plain facts give theirs back. */
@media (min-width: 760px) {
  .sig-foot .sig-foot__cell li { min-height: 36px; display: flex; align-items: center; }
}

/* ON A PHONE, LINK LISTS FLOW IN TWO COLUMNS. Prose does not.
   Stacked one-per-row, four categories and four help links spent 453px of a
   770px footer on eight short labels. Category names are taxonomy terms and
   are short by nature; the one item that is not — the support address — says
   so and takes the full row. The Ordering cell is deliberately excluded: it
   holds sentences, not labels, and a sentence in a 168px column is worse than
   a sentence in a 350px one. */
@media (max-width: 759px) {
  .sig-foot .sig-foot__cell--links ul {
    grid-template-columns: 1fr 1fr;
    column-gap: var(--sig-4);
  }
  .sig-foot .sig-foot__cell--links li.is-wide { grid-column: 1 / -1; }
}

/* THE LINKS WERE 2px APART. `gap: 2px` against a 34px invisible target meant
   adjacent hit areas all but touched — named in critique-2026-09-01, and the
   `ux` guideline "Touch Spacing" puts the floor at 8px between targets.
   36px tall, 8px apart — a 44px pitch shared with every other row in the
   block. */
.sig-foot .sig-foot__cell a {
  display: inline-flex; align-items: center; min-height: 36px;
  color: var(--sig-ink); text-decoration: none;
}
.sig-foot .sig-foot__cell a:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ── The Ordering cell is a title block, not a third menu ───────────────
   critique-2026-09-01: it "reads as a menu you cannot click". It had the
   same eyebrow, the same list shape and the same column position as the two
   link cells beside it, and then went one step further into `--sig-muted` —
   which is exactly how a DISABLED nav item is drawn. The most valuable
   BD-specific content in the chrome was styled as the least prominent text
   in the footer.

   Keyed field/value pairs fix both halves at once. A label above a value is
   not a list shape, and ink is not a disabled colour. It also makes the
   footer's title-block reading true in the one cell whose content genuinely
   is field/value data — the same critique's sharpest point, which was that
   nothing here was actually keyed.

   SPECIFICITY IS DELIBERATE. The shared rules above are (0,2,1) and one of
   them lives inside a `min-width: 760px` query — and a media query does not
   add specificity, so an equal-specificity override would be decided by
   source order alone. `.sig-foot__cell.sig-foot__cell--facts li` is (0,3,1)
   and wins wherever it is placed. The same class of leak cost this file two
   fixes already (`font-family`, then `line-height`, both inherited from
   Elementor's kit as computed lengths). */
.sig-foot .sig-foot__cell.sig-foot__cell--facts li {
  display: block;      /* beats `display: flex` from the >=760px pitch rule */
  min-height: 0;       /* 36px is a TARGET height; nothing here is a target */
  color: var(--sig-ink);
}
/* THE KEY GOES INLINE ON A PHONE AND STACKS ON A DESKTOP, and that is a
   measurement rather than a preference. Stacked at every width, the four
   dedicated key lines put the mobile footer at 724px — giving back most of
   the 770 -> 638px reduction the previous session bought by flowing the link
   lists into two columns. A key line is ~13px of pure overhead, four of them
   ~52px, on the surface where the footer already dominates the document.
   Inline, the key sits in the value's own first line and costs nothing.
   At >=760px the cell is one of three columns with room to spare, and there
   the stacked form earns its height: the values align into a left column,
   which is what makes a title block read as ruled fields rather than prose. */
.sig-foot .sig-foot__cell--facts .sig-foot__key {
  font-family: var(--sig-body);
  font-size: 11px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; line-height: 1.2;
  color: var(--sig-muted);   /* 5.66:1 on paper — AA at any size */
  margin-right: 8px;
}

/* INLINE, BUT A COLUMN — from 360px up, where there is width to spare.
   The four keys are different widths, so a plain inline label starts each
   value at a different x and the block reads ragged rather than ruled. 68px
   clears the longest ("Returns") and still leaves ~274px at 390px, which all
   four values fit on one line.

   Below 360px it is switched OFF, because there it inverts: the reserved
   column pushes every value into a second line, taking the cell 192 -> 236px
   and breaking the very alignment it exists to create (a wrapped value's
   second line returns to x=0 regardless). Measured at 320px, the narrowest
   width this site is checked at. A ragged label is cheaper than a wrapped
   one. */
@media (min-width: 360px) {
  .sig-foot .sig-foot__cell--facts .sig-foot__key {
    display: inline-block; min-width: 68px; vertical-align: baseline;
  }
}
.sig-foot .sig-foot__cell--facts .sig-foot__val {
  font-size: 14.5px; line-height: 1.5;
  color: var(--sig-ink);     /* 16.9:1 — and no longer reads as disabled */
}
@media (min-width: 760px) {
  .sig-foot .sig-foot__cell--facts .sig-foot__key {
    display: block; margin-right: 0; margin-bottom: 1px;
  }
  .sig-foot .sig-foot__cell--facts .sig-foot__val { display: block; }
}

@media (min-width: 760px) {
  .sig-foot .sig-foot__id { padding-block: var(--sig-5); }
  .sig-foot .sig-foot__grid { grid-template-columns: repeat(3, 1fr); }
  .sig-foot .sig-foot__cell {
    border-top: 0; border-left: 1px solid var(--sig-hair);
    padding-block: var(--sig-5); padding-inline: var(--sig-5);
  }
  .sig-foot .sig-foot__cell:first-child { border-left: 0; padding-left: 0; }
}

/* ── The checkout's reduced chrome ──────────────────────────────────────
   The markup does the removing — see header.php and footer.php. All this
   needs to do is stop the two-column grid from leaving the brand marooned
   against the far edge once the nav and cart are gone. */
.sig-head--lean .sig-head__in { grid-template-columns: minmax(0, 1fr) auto; }
@media (min-width: 900px) {
  .sig-head--lean .sig-head__in { display: flex; justify-content: space-between; }
}
.sig-foot--lean .sig-foot__id { border-bottom: 0; }

/* ── The legal line ─────────────────────────────────────────────────────
   The `footer` menu renders here rather than as a fourth grid cell. It is
   where a reader looks for terms and privacy, and an unassigned menu then
   costs a row of text instead of a quarter of the footer's width. */
.sig-foot .sig-foot__legal { border-top: 1px solid var(--sig-hair); }
.sig-foot .sig-foot__legal .sig-foot__in {
  padding-block: var(--sig-2);
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: var(--sig-3);
}
.sig-foot .sig-foot__legal p { margin: 0; color: var(--sig-muted); font-size: 13px; }
.sig-foot .sig-foot__legallist {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: var(--sig-4);
}
.sig-foot .sig-foot__legallist a {
  display: inline-flex; align-items: center; min-height: 40px;
  color: var(--sig-muted); font-size: 13px; text-decoration: none;
}
.sig-foot .sig-foot__legallist a:hover { color: var(--sig-ink); text-decoration: underline; text-underline-offset: 3px; }

.sig-foot a:focus-visible {
  outline: 2px solid var(--sig-ink); outline-offset: 2px; border-radius: 4px;
}

/* ── Standalone templates ───────────────────────────────────────────────
   index.php, page.php, search.php and 404.php answer for themselves now.
   Until the parent came out these four files did not exist and Woostify
   supplied them, which is a fair summary of the whole dependency: it was
   answering for pages nobody had looked at.                              */

/* ⚠️ `box-sizing` IS THE WHOLE DESKTOP INCONSISTENCY, and it is inherited from
   nowhere obvious. signal.css sets border-box on `.sig *` and home.css on
   `.sig-home *` — scoped, never global. So `.sig__wrap` INSIDE `.sig` reads
   `max-width: 1180` as including its 20px padding (content 1140, starting at
   x=70), while `.sig-main` OUTSIDE it adds the padding on top (content 1180,
   starting at x=50).

   Identical declarations, 40px apart, and it is why the PDP's sections never
   lined up with the shop's or About's on desktop. Declared here so both
   containers resolve the same way.

   The proper fix is a global `*, *::before, *::after { box-sizing: border-box }`
   — the scoped version is the anomaly, not this. Left for a pass with time to
   re-verify every surface, rather than the day before a deploy. */
.sig-main {
  box-sizing: border-box;
  max-width: 1180px;
  margin: 0 auto;
  padding: var(--sig-6) 20px var(--sig-8);
}
/* The PRODUCT page brings its own measure — `.sig__wrap` centres itself and
   pads itself, so a second set here would double it. The archive does not,
   and left as `--shop` it put the product grid flush against the viewport
   edge with a 7px overflow. Two modifiers, because they are two situations. */
.sig-main--product { max-width: none; padding-left: 0; padding-right: 0; }

/* …but its notices are NOT inside `.sig__wrap`, so with the padding removed
   above they ran the full 1280px while every section below them started at
   x=70. Full-bleed chrome over inset content is the most visible misalignment
   on the page. Give them the same measure.

   The breadcrumb used to be listed here too. It no longer renders on this
   surface at all — woocommerce/global/breadcrumb.php returns early on
   products, shop and product taxonomies — so the selector was styling nothing.
   The notices still need it. */
.sig-main--product > .woocommerce-notices-wrapper {
  box-sizing: border-box;
  max-width: 1180px;
  margin-inline: auto;
  padding-inline: 20px;
}
.sig-main--shop { max-width: 1180px; }

/* ONE MEASURE, EVERY PAGE — and it was three.

   Measured at 1280px before this: the PDP's content sat at x=70 w=1140, the
   shop at x=20 w=1240, About and cart at x=50 w=1180. Three left edges and
   three widths across four pages, so navigating between them slid the content
   sideways by up to 50px and changed its width by 100px. At 390px all four
   were identical — which is exactly why mobile read clean and desktop did not.

   `--shop` was widened to 1400 to stop the grid touching the viewport edge.
   That fixed the overflow and made the shop the odd page out; the container is
   the same everywhere now and the grid gets fewer, wider columns instead. */

.sig-page__head { margin-bottom: var(--sig-6); }
.sig-page__title { font-size: 30px; line-height: 1.15; margin: 0 0 var(--sig-3); }
@media (min-width: 900px) { .sig-page__title { font-size: 38px; } }
.sig-page__lede { color: var(--sig-muted); font-size: 16px; margin: 0; max-width: 46ch; }

.sig-page--narrow { max-width: 34em; }

/* Prose. The pages this styles are the policy pages, and prose is what they
   are — a page that decorates a refund policy reads as one that is hiding
   something, which in a COD market is the opposite of the job. */
/* 33em, not 40. At 16px, 40em is a 640px line — about 80 characters, which is
   where the eye starts losing its place on the return sweep. Measured on the
   About page at 1280px before the change. 33em lands near 66. */
/* ⚠️ THE MEASURE GOES ON THE CHILDREN, NOT ON THIS BOX.

   `.sig-prose` is page.php's content wrapper, and page.php renders the policy
   pages, About, AND — because both are ordinary WordPress pages holding a
   shortcode — the CART and the CHECKOUT.

   So capping the wrapper capped them. Setting `max-width: 33em` here for the
   About page's reading measure squeezed the entire cart form and the entire
   checkout into a 528px column inside an 1180px page. It was 40em before, so
   the bug predates the change — tightening the measure for prose made two
   transactional layouts measurably worse.

   Running text wants ~66 characters. A cart table does not. The cap applies to
   the text-level children, so prose reads correctly and anything structural
   inside — a form, a table, a grid — gets the full page. */
.sig-prose { font-size: 16px; line-height: 1.65; }
.sig-prose > p,
.sig-prose > h2,
.sig-prose > h3,
.sig-prose > h4,
.sig-prose > ul,
.sig-prose > ol,
.sig-prose > blockquote,
.sig-prose > figure { max-width: 33rem; }

/* ⚠️ rem, NOT em. `max-width` in `em` resolves against the element's OWN
   font-size, so `33em` on a 23px h2 is 759px while the same rule on a 16px
   paragraph is 528px — the headings ran a third wider than the text they
   introduce, which is the opposite of a measure. `rem` resolves against the
   root, so every block in the column shares one edge. */
.sig-prose > * + * { margin-top: var(--sig-4); }
.sig-prose h2 { font-size: 23px; margin-top: var(--sig-7); }
.sig-prose h3 { font-size: 19px; margin-top: var(--sig-6); }
.sig-prose ul, .sig-prose ol { padding-left: 1.3em; }
.sig-prose li + li { margin-top: var(--sig-2); }
.sig-prose a { color: var(--sig-ink); text-underline-offset: 3px; }

.sig-posts { display: grid; gap: var(--sig-6); max-width: 40em; }
.sig-post__title { font-size: 21px; margin: 0 0 var(--sig-2); }
.sig-post__title a { color: var(--sig-ink); text-decoration: none; }
.sig-post__title a:hover { text-decoration: underline; text-underline-offset: 3px; }
.sig-post__excerpt { color: var(--sig-muted); font-size: 15px; }
.sig-post__excerpt p { margin: 0; }

/* The one button outside the product page. Yellow fills the shape; ink writes
   the word — the locked rule, and the reason this is not a yellow label. */
.sig-btn {
  display: inline-block; padding: 14px 26px;
  background: var(--sig-yellow); color: var(--sig-ink);
  border-radius: var(--sig-r-chip);
  font-weight: 600; font-size: 15px; text-decoration: none;
}
.sig-btn:hover { filter: brightness(.96); }
.sig-btn:focus-visible { outline: 2px solid var(--sig-ink); outline-offset: 3px; }

/* ── What Woostify used to answer for ───────────────────────────────────
   Standing alone means WooCommerce's own defaults are now visible, and they
   are written for a theme with no design of its own. Everything below was
   invisible until the parent came out, which is the honest cost of the cut —
   and the reason to pay it once rather than override a parent forever. */

body {
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--sig-display);
  font-weight: 400;
  line-height: 1.18;
  color: var(--sig-ink);
}

a { color: inherit; }

/* WooCommerce's primary button is #7f54b3 — its own purple — set with
   `.woocommerce:where(body:not(...)) button.button.alt`. `:where()` adds no
   specificity, so that is (0,3,1); `.button.alt` here is (0,3,0) plus the
   body class, which is why the pairs below are written out rather than
   collapsed. Yellow fills the shape, ink writes the word. */
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce a.button.alt,
.woocommerce button.button.alt,
.woocommerce input.button.alt,
.woocommerce #respond input#submit,
.woocommerce #respond input#submit.alt {
  background: var(--sig-yellow);
  color: var(--sig-ink);
  border: 0;
  border-radius: var(--sig-r-chip);
  padding: 13px 24px;
  font-family: var(--sig-body);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
  text-transform: none;
  text-decoration: none;
}
.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce a.button.alt:hover,
.woocommerce button.button.alt:hover,
.woocommerce input.button.alt:hover,
.woocommerce #respond input#submit:hover,
.woocommerce #respond input#submit.alt:hover {
  background: var(--sig-yellow);
  color: var(--sig-ink);
  filter: brightness(.96);
}
.woocommerce a.button.disabled,
.woocommerce button.button.disabled,
.woocommerce button.button:disabled,
.woocommerce button.button.alt.disabled,
.woocommerce button.button.alt:disabled {
  background: var(--sig-rule);
  color: var(--sig-muted);
  opacity: 1;
}

/* Woo's messages are green/blue/red bars with a 3px top border. On cream they
   read as somebody else's UI. */
.woocommerce-message,
.woocommerce-info,
.woocommerce-error {
  background: var(--sig-card);
  /* A hairline all round rather than a thick left bar. The bar was the first
     thing written and the detector was right about it: a coloured edge on one
     side of a card is the tell it flags, and unlike Treatment C — which the
     brand locks — nothing here justified keeping it. Errors change the whole
     border, which is quieter and says the same thing. */
  border: 1px solid var(--sig-rule);
  border-radius: var(--sig-r-row);
  color: var(--sig-ink);
  font-size: 15px;
  padding: var(--sig-4) var(--sig-5);
  list-style: none;
}
.woocommerce-error { border-color: var(--sig-warn); color: var(--sig-warn); }
.woocommerce-message::before,
.woocommerce-info::before,
.woocommerce-error::before { display: none; }

/* The product loop. woocommerce-layout.css floats these into percentage
   columns; a grid is what we want and it collapses on its own. */
.woocommerce ul.products {
  display: grid;
  /* A COUNTED GRID, NOT auto-fill.
     `minmax(min(150px,100%), 1fr)` gave the 2-up wanted at 390px and then, at
     1140px, quietly produced SIX columns of 163px cards carrying five-line
     titles — with the eighth product orphaned on its own row beside ~950px of
     nothing. auto-fill optimises for filling the row, which is not the same
     as reading well. Counted columns at 2 / 3 / 4 keep the card a card, and
     eight products divide into 4 exactly. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sig-6) var(--sig-5);
  margin: 0; padding: 0; list-style: none;
}
.woocommerce ul.products::before,
.woocommerce ul.products::after { content: none; }
.woocommerce ul.products li.product {
  width: auto !important;
  margin: 0 !important;
  float: none !important;
  clear: none !important;
}
.woocommerce ul.products li.product a img {
  border-radius: var(--sig-r-img);
  background: var(--sig-panel);
  margin-bottom: var(--sig-3);
}
.woocommerce ul.products li.product .woocommerce-loop-product__title {
  font-family: var(--sig-body);
  font-size: 15px; font-weight: 600; line-height: 1.35;
  color: var(--sig-ink);
  padding: 0; margin: 0 0 var(--sig-1);
}
.woocommerce ul.products li.product .price {
  font-family: var(--sig-display);
  font-size: 17px; color: var(--sig-ink);
}
.woocommerce ul.products li.product .price del { color: var(--sig-muted); font-size: .8em; }
.woocommerce ul.products li.product .price ins { text-decoration: none; }

/* Woo's sale flash is #77a464, a green that reads olive on cream. Seamless
   DOES discount — bundles and ladders are the pricing model here, so this is
   not the badge to suppress, it is one to dress. Ink pill, paper text: the
   yellow fill stays reserved for the button that takes the money. */
.woocommerce span.onsale {
  position: absolute; top: 10px; left: 10px; right: auto;
  min-height: 0; min-width: 0; margin: 0; padding: 4px 11px;
  background: var(--sig-ink); color: var(--sig-paper);
  border-radius: var(--sig-r-chip); line-height: 1.4;
  font-family: var(--sig-body); font-size: 12px; font-weight: 600;
}
.woocommerce ul.products li.product { position: relative; }

@media (min-width: 700px)  { .woocommerce ul.products { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .woocommerce ul.products { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* ── Cards that line up ──────────────────────────────────────────────────
   The catalogue's titles run one line ("Solar Fan") to five ("Fireplace Aroma
   diffuser/Humidifier – Cozy Fireplace Diffuser with Free Essential Oils +
   Free Home Delivery"). Left alone that staggered every row: buttons in the
   same row landed up to 154px apart, which is the most visible "unfinished"
   tell on the browse surface.

   Two rules fix it. The title is clamped to two lines and reserves the space
   for both, so every card's price starts at the same height. The card is a
   flex column with the button pushed to the bottom, so the CTAs line up even
   when the copy above them does not.

   Clamping is a guard, not a licence — the titles still need rewriting, and
   the Solar Fan sets that pattern. This stops the layout being hostage to
   content nobody has fixed yet. */
.woocommerce ul.products li.product {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.woocommerce ul.products li.product .woocommerce-loop-product__title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  /* Two lines at 15px/1.35 — reserved whether or not both are used. */
  min-height: calc(2 * 1.35em);
}
/* `margin-top: auto` lives in the LATER rule for this selector — see below.
   Two rules for one selector at equal specificity means the last one wins, and
   setting it here as well as there is how a card's button silently stops
   sitting at the bottom of its cell. */
/* The image is the one thing that must not stretch in a flex column. */
.woocommerce ul.products li.product a img { width: 100%; }

/* ── The path, where a path still earns its row ──────────────────────────

   `.woocommerce-breadcrumb` is gone: the theme renders its own markup now
   (woocommerce/global/breadcrumb.php) and renders NOTHING on the shop, the
   category archives and the product pages. "Home / Shop" was one level deep,
   duplicated a nav item three inches above it, and on a product it printed the
   entire 105-character title as its last crumb. The category row is the better
   breadcrumb on an archive — it shows the siblings too — and on a product the
   category is now the eyebrow above the title.

   What is left renders on search, 404 and the policy pages: surfaces someone
   can genuinely land on with no idea where they are. Muted, no underlines, and
   the separator is a middot rather than a slash borrowed from a URL bar. */
.sig-crumb { margin: 0 0 var(--sig-5); }
.sig-crumb__list {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 0 var(--sig-2);
  margin: 0; padding: 0; list-style: none;
  font-size: 13.5px; color: var(--sig-muted);
}
.sig-crumb__item + .sig-crumb__item::before {
  content: "·";
  margin-right: var(--sig-2);
  color: var(--sig-hair);
}
.sig-crumb__item a { color: var(--sig-muted); text-decoration: none; }
.sig-crumb__item a:hover { color: var(--sig-ink); }
.sig-crumb__item a:focus-visible { outline: 2px solid var(--sig-ink); outline-offset: 3px; }
.sig-crumb__item [aria-current] { color: var(--sig-ink); }

.woocommerce .woocommerce-result-count { color: var(--sig-muted); font-size: 14px; }
.woocommerce .woocommerce-ordering select {
  min-height: 40px; padding: 0 14px;
  border: 1px solid var(--sig-rule); border-radius: var(--sig-r-chip);
  background: var(--sig-card); color: var(--sig-ink);
  font-family: var(--sig-body); font-size: 14px;
}

/* ── The category row ────────────────────────────────────────────────────
   Treatment C: ink on paper with a yellow underline for the selected chip,
   so yellow stays a MARK. The page's two yellow fills are spoken for — the
   primary CTA and the best-value tab — and a third would spend the accent. */

.sig-cats {
  display: flex; flex-wrap: wrap; gap: var(--sig-2);
  margin: 0 0 var(--sig-5);
}
.sig-cats__chip {
  display: inline-flex; align-items: baseline; gap: 7px;
  padding: 9px 15px; border-radius: var(--sig-r-chip);
  border: 1px solid var(--sig-rule);
  background: var(--sig-card); color: var(--sig-ink);
  font-size: 14px; font-weight: 500; text-decoration: none;
  /* 44px is the touch target; the padding above plus this floor gets there
     without making the chips look like buttons. */
  min-height: 40px;
}
/* ⚠️ `font-variant-numeric: tabular-nums` WAS HERE. That is the "1 , 500" bug
   this codebase has now caught five times — a tabular comma occupies a full
   digit cell. These counts are one or two digits so it did no visible harm
   yet, which is exactly how it survived; the rule is that money and counts on
   this site are set in proportional figures, everywhere, with no exceptions
   left lying around to be copied. */
.sig-cats__chip span {
  font-size: 12px; color: var(--sig-muted);
  font-variant-numeric: normal;
}
.sig-cats__chip:hover { border-color: var(--sig-muted); }
/* ⚠️ AN INSET SHADOW ON A PILL IS NOT AN UNDERLINE — IT IS A CRESCENT.
   `border-radius: 999px` clips the inset box-shadow to the pill's curve, so
   Treatment C's yellow underline rendered as a swoosh hugging the bottom-left
   arc. Dropping the border at the same time left the selected chip as the only
   one without an outline, and the pair read as a rendering fault rather than a
   selection.

   The border stays; the underline is drawn straight, inside the chip, under
   the label. Ink on paper with a yellow mark — the rule was right, the
   execution was wrong. */
.sig-cats__chip.is-current {
  border-color: var(--sig-rule);
  background: var(--sig-card);
  font-weight: 600;
  position: relative;
}
.sig-cats__chip.is-current::after {
  content: '';
  position: absolute;
  left: 15px; right: 15px; bottom: 7px;
  height: 3px; border-radius: 2px;
  background: var(--sig-yellow);
}
.sig-cats__chip.is-current span { color: var(--sig-ink); }
.sig-cats__chip:focus-visible { outline: 2px solid var(--sig-ink); outline-offset: 2px; }

/* ── Cards that cannot be bought ─────────────────────────────────────────
   The homepage draws an unstocked room DASHED — the drafting convention for
   planned, not built. The same dash marks an unstocked product, so both
   surfaces say "not yet" in the same language rather than inventing a second
   one. The picture desaturates; the price does not, because the price is
   still true and will be true again when it restocks. */

.woocommerce ul.products li.product.sig-card--out a img {
  filter: saturate(.25) opacity(.72);
  outline: 1.5px dashed var(--sig-rule);
  outline-offset: -1.5px;
}
.woocommerce ul.products li.product.sig-card--out .woocommerce-loop-product__title {
  color: var(--sig-muted);
}
.sig-card__out {
  margin: var(--sig-1) 0 0;
  font-size: 12px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--sig-muted);
}

/* What the product actually is, under what it is called.

   The card was picture / title / price / button, and the title was carrying
   two jobs badly because every title in this store was written for a
   marketplace search box. The catalogue rename fixed the names; this is where
   the description they used to smuggle now lives — read from the short
   description, which is the same sentence the product page opens with, so the
   card and the page it leads to agree.

   Clamped at two lines and NOT given a reserved min-height. The buttons align
   because `margin-top: auto` puts them there, which is a better mechanism than
   reserving space in four places and hoping they add up. */
.woocommerce ul.products li.product .sig-card__desc {
  margin: 0 0 var(--sig-3);
  font-size: 13px; line-height: 1.45;
  color: var(--sig-muted);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  /* Two lines reserved whether or not both are used, so the price below it
     starts at the same height on every card in the row. Without this the
     one-line descriptors floated their prices 19px above their neighbours'. */
  min-height: calc(2 * 1.45em);
}

/* ── The hole above the button ───────────────────────────────────────────
   `margin-top: auto` bottom-aligns the buttons, which is right, but it does it
   by absorbing the difference between the tallest card and every other one
   into a single gap. The Fireplace is the only product carrying a "You save"
   line, so on a row of four it opened a **64px void** on three cards against
   32px on the fourth — the alignment was correct and the rhythm was not.

   Reserving the saving's row on the cards that lack one turns one big hole
   into four equal ones. `:has()` is the honest way to ask "does this card have
   a saving?" — the alternative is printing an empty element on every card,
   which is markup that exists to be invisible. Where `:has()` is unsupported
   the rule simply does not apply and the layout falls back to what it did
   before: aligned, with a looser gap. */
.woocommerce ul.products li.product > a:not(:has(.sig-save)) .price {
  margin-bottom: calc(13px * 1.5 + var(--sig-1));
}

/* The archive's own add-to-cart button. Kept quiet: on this shop the product
   page carries the whole argument — the angles, the rail, the delivered price
   — so the card's job is to get someone onto it, not to take the money before
   they have read any of that.

   FULL WIDTH, because the alternative was worse than it looked. `margin-top:
   auto` correctly bottom-aligns the buttons across a row, but on a card whose
   copy is short that opens a gap above a small pill hugging its own text at
   the left edge — and a row of four of those reads as four things that failed
   to fill their boxes. Stretched, the same gap becomes the card's structure:
   picture, words, then one full-width action on the baseline every other card
   shares. The quiet outline is unchanged; this is not a promotion to primary,
   the page's yellow fill is still spoken for. */
.woocommerce ul.products li.product .button {
  /* auto, not a fixed gap: this is what pushes the CTA to the bottom of the
     card so buttons line up across a row whose titles and "You save" lines
     are different heights. A fixed margin-top here left the Fireplace's
     button 48px below its neighbours'. */
  margin-top: auto;
  /* The card is `align-items: flex-start`, so a flex item is shrink-to-fit
     unless it says otherwise. `align-self` rather than `width: 100%` — it
     stretches the box itself instead of setting a width that padding then
     adds to, which is the border-box trap this file is already carrying one
     scoped workaround for. */
  align-self: stretch;
  text-align: center;
  background: none; color: var(--sig-ink);
  border: 1.5px solid var(--sig-ink);
  font-size: 14px; font-weight: 500;
  padding: 10px 16px; border-radius: var(--sig-r-chip);
  min-height: 44px;
}
.woocommerce ul.products li.product .button:hover {
  background: var(--sig-ink); color: var(--sig-paper);
}
.woocommerce ul.products li.product.sig-card--out .button {
  border-color: var(--sig-rule); color: var(--sig-muted);
}

/* ── The bag ─────────────────────────────────────────────────────────────
   See woocommerce/cart/cart.php for why these are list rows and not a
   `shop_table_responsive`, which at 390px prints every product as four
   stacked label-value rows with no picture. */

.sig-bag__items {
  list-style: none; margin: 0 0 var(--sig-6); padding: 0;
  border-top: 1px solid var(--sig-rule);
}

.sig-bag__row {
  display: grid;
  /* picture · body · remove. The body is the only flexible track, so a long
     marketplace product name wraps instead of pushing the price off-screen. */
  grid-template-columns: 64px minmax(0, 1fr) 32px;
  gap: var(--sig-3);
  align-items: start;
  padding: var(--sig-4) 0;
  border-bottom: 1px solid var(--sig-rule);
}

.sig-bag__pic { grid-column: 1; }
.sig-bag__pic a { display: block; line-height: 0; }
.sig-bag__pic img {
  width: 64px; height: 64px; object-fit: contain;
  background: var(--sig-panel); border-radius: 8px;
  /* Supplier artwork is shot on white; multiply melts it into the panel the
     same way it does in the gallery, so the bag matches the product page. */
  mix-blend-mode: multiply;
}

.sig-bag__body { grid-column: 2; min-width: 0; }

.sig-bag__name {
  margin: 0 0 var(--sig-2);
  font-size: 15px; line-height: 1.35; font-weight: 500;
}
.sig-bag__name a { color: var(--sig-ink); text-decoration: none; }
.sig-bag__name a:hover { text-decoration: underline; }
/* The chosen variation, printed by wc_get_formatted_cart_item_data(). */
.sig-bag__name dl.variation {
  margin: var(--sig-1) 0 0; font-size: 13px; color: var(--sig-muted);
  display: flex; flex-wrap: wrap; gap: 0 8px;
}
.sig-bag__name dl.variation dt,
.sig-bag__name dl.variation dd { margin: 0; }
.sig-bag__name dl.variation dd::after { content: ''; }

.sig-bag__line {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sig-3); flex-wrap: wrap;
}
.sig-bag__sub {
  font-family: var(--sig-display); font-size: 17px;
  font-variant-numeric: tabular-nums;
}

/* The quantity field. 44px tall so it is a real touch target, and wide enough
   for two digits without the spinner clipping them. */
.sig-bag__row .quantity input.qty {
  width: 66px; min-height: 44px; padding: 0 6px;
  text-align: center; font-variant-numeric: tabular-nums;
  border: 1px solid var(--sig-rule); border-radius: 8px;
  background: var(--sig-card); color: var(--sig-ink);
  font-family: var(--sig-body); font-size: 15px;
}
.sig-bag__qty-fixed { color: var(--sig-muted); font-size: 14px; }

/* Remove. Stock Woo prints a red x FIRST in the row; here it is last in both
   source and tab order, and it is ink rather than warning-red — removing a
   line you chose to add is not an error state. */
.sig-bag__x {
  grid-column: 3; justify-self: end;
  display: flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 50%;
  color: var(--sig-muted); text-decoration: none;
  font-size: 20px; line-height: 1;
}
.sig-bag__x:hover { background: var(--sig-panel); color: var(--sig-ink); }
.sig-bag__x:focus-visible { outline: 2px solid var(--sig-ink); outline-offset: 2px; }

.sig-bag__actions {
  display: flex; flex-wrap: wrap; gap: var(--sig-3);
  align-items: center; padding: var(--sig-4) 0 0;
}
.sig-bag__update {
  background: none; color: var(--sig-ink);
  border: 1.5px solid var(--sig-ink); border-radius: var(--sig-r-chip);
  min-height: 44px; padding: 10px 20px;
  font-family: var(--sig-body); font-size: 14px; font-weight: 500;
}
.sig-bag__update[disabled] { opacity: .4; border-color: var(--sig-rule); color: var(--sig-muted); }

@media (min-width: 760px) {
  .sig-bag__row { grid-template-columns: 88px minmax(0, 1fr) 40px; }
  .sig-bag__pic img { width: 88px; height: 88px; }
  .sig-bag__name { font-size: 16px; }
}

/* A range must not break across lines. An en dash is a legal break point, so
   "2–4 days" rendered as "2–" then "4 days" on the About page — a number split
   in half on the page a hesitant buyer reads to decide whether to trust the
   delivery promise. */
.sig-nowrap { white-space: nowrap; }

/* ═══════════════════════════════════════════════════════════════════════
   THE CART PAGE'S TOTALS

   Nothing in this theme had ever styled `.cart_totals`, so the one block on
   the page carrying the number the buyer is deciding about was rendering as
   bare WooCommerce: a `shop_table_responsive` with a "Cart totals" heading
   over it, in a theme that has a title block for exactly this.

   It IS a title block already — `<th>` key, `<td>` value — so this is a
   restyle and not a template. That matters more than it sounds: every
   `<tr>`-emitting hook in cart-totals.php (`woocommerce_cart_totals_before_
   shipping` and the rest) keeps working, and the shipping calculator, which
   renders itself into one of those rows, is untouched.
   ═══════════════════════════════════════════════════════════════════════ */

.woocommerce-cart .cart-collaterals { margin-top: var(--sig-7); }

/* `box-sizing` IS NOT DECORATION HERE — measured, not assumed.
   Without it this padded block computed to 100% + 32px and pushed the CART
   PAGE 45px sideways at every width up to 1024. This theme does not set a
   universal `* { box-sizing: border-box }`, and the commit that settled the
   site measure on 2026-09-02 says why the omission keeps costing: "one
   measure on every page, and box-sizing was why there were three." */
.woocommerce-cart .cart_totals {
  box-sizing: border-box;
  padding: var(--sig-4);
  background: var(--sig-panel);
  border: 1px solid var(--sig-hair);
  border-radius: var(--sig-r-row);
}
/* WooCommerce tints every `.shop_table td` `rgba(0,0,0,.024)`. Inside a panel
   that already has a colour, that is a second, slightly darker shade laid
   over the first for no reason anyone chose. */
.woocommerce-cart .cart_totals .shop_table td,
.woocommerce-cart .cart_totals .shop_table th { background: transparent; }
.woocommerce-cart .cart_totals > h2 {
  margin: 0 0 var(--sig-3);
  font-family: var(--sig-display); font-weight: 400; font-size: 20px;
  color: var(--sig-ink);
}
.woocommerce-cart .cart_totals table { width: 100%; border-collapse: collapse; }
.woocommerce-cart .cart_totals th,
.woocommerce-cart .cart_totals td {
  padding: 7px 0; border: 0; vertical-align: baseline;
}
.woocommerce-cart .cart_totals th {
  text-align: left; font-weight: 600; font-size: 11px;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--sig-muted);
}
.woocommerce-cart .cart_totals td {
  text-align: right; font-size: 16px; font-weight: 600; color: var(--sig-ink);
}
/* The total is the number the page is accountable to, so it is the display
   face and it sits under a rule of its own. */
.woocommerce-cart .cart_totals tr.order-total th,
.woocommerce-cart .cart_totals tr.order-total td {
  padding-top: var(--sig-3); border-top: 1px solid var(--sig-hair);
}
.woocommerce-cart .cart_totals tr.order-total td {
  font-family: var(--sig-display); font-weight: 400; font-size: 22px;
}
/* The shipping row carries an address, a method list and a change link, none
   of which are a single right-aligned figure. */
.woocommerce-cart .cart_totals tr.shipping td {
  font-size: 14px; font-weight: 400; color: var(--sig-muted);
}
.woocommerce-cart .cart_totals #shipping_method {
  list-style: none; margin: 0; padding: 0;
}
.woocommerce-cart .cart_totals #shipping_method label { font-weight: 400; }
.woocommerce-cart .cart_totals .woocommerce-shipping-destination { margin: 6px 0 0; }

.woocommerce-cart .wc-proceed-to-checkout { margin-top: var(--sig-4); }
.woocommerce-cart .wc-proceed-to-checkout .checkout-button {
  display: block; box-sizing: border-box; width: 100%; padding: 15px 20px;
  background: var(--sig-yellow); color: var(--sig-ink);
  border: 0; border-radius: var(--sig-r-chip);
  font-family: var(--sig-body); font-size: 16px; font-weight: 600;
  text-align: center; text-decoration: none;
}
.woocommerce-cart .wc-proceed-to-checkout .checkout-button:hover { filter: brightness(.96); }
.woocommerce-cart .wc-proceed-to-checkout .checkout-button:focus-visible {
  outline: 2px solid var(--sig-ink); outline-offset: 3px;
}

/* ═══════════════════════════════════════════════════════════════════════
   THE BAG DRAWER

   Signal's vernacular is the technical drawing, and a drawing's parts list
   is exactly what a cart is: a ruled column of items with a title block
   underneath stating what the whole thing comes to. So the drawer is that,
   not a floating card — it is flush to the edge of the sheet, ruled, with
   the totals keyed field-over-value the way the footer and the PDP fold
   already do it.

   Yellow appears once, in the Checkout fill. `design/README.md` budgets two
   fills per surface; the drawer is a surface that opens over one, so one is
   the honest number.
   ═══════════════════════════════════════════════════════════════════════ */

.sig-drawer {
  position: fixed; inset: 0; z-index: 9000;
}
.sig-drawer[hidden] { display: none; }

.sig-drawer__scrim {
  position: absolute; inset: 0;
  background: rgba(20, 18, 14, 0.42);
  opacity: 0;
  transition: opacity 240ms ease;
}
.sig-drawer.is-open .sig-drawer__scrim { opacity: 1; }

.sig-drawer__panel {
  position: absolute; top: 0; right: 0; bottom: 0;
  display: flex; flex-direction: column;
  width: min(420px, 100%);
  background: var(--sig-paper);
  border-left: 1px solid var(--sig-hair);
  transform: translateX(100%);
  transition: transform 240ms ease;
}
.sig-drawer.is-open .sig-drawer__panel { transform: none; }

/* A pending request must not look like a dead button. */
.sig-drawer.is-busy .sig-drawer__body { opacity: .55; pointer-events: none; }

.sig-drawer__head {
  flex: 0 0 auto;
  display: flex; align-items: center; justify-content: space-between; gap: var(--sig-3);
  padding: var(--sig-4);
  border-bottom: 1px solid var(--sig-hair);
}
.sig-drawer__title {
  margin: 0;
  font-family: var(--sig-display); font-weight: 400; font-size: 22px;
  color: var(--sig-ink);
}
.sig-drawer__close {
  display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; margin: -10px -10px -10px 0; padding: 0;
  color: var(--sig-ink); background: none; border: 0; cursor: pointer;
}
.sig-drawer__close:focus-visible { outline: 2px solid var(--sig-ink); outline-offset: -2px; }

.sig-drawer__body {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column;
}

/* ── Items ───────────────────────────────────────────────────────────── */

.sig-drawer__items {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  margin: 0; padding: 0; list-style: none;
}
.sig-drawer__row {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr) 32px;
  gap: var(--sig-3);
  padding: var(--sig-4);
  border-bottom: 1px solid var(--sig-rule);
}
.sig-drawer__pic img {
  display: block; width: 56px; height: 56px;
  object-fit: contain;
  background: var(--sig-panel);
  border-radius: var(--sig-r-chip);
  /* Supplier artwork is shot on white; multiply melts it into the panel
     rather than leaving a bright rectangle. Same treatment as the gallery. */
  mix-blend-mode: multiply;
}
.sig-drawer__main { min-width: 0; }
.sig-drawer__name {
  margin: 0 0 2px;
  font-family: var(--sig-body); font-size: 14px; font-weight: 500; line-height: 1.35;
  color: var(--sig-ink);
}
.sig-drawer__name a { color: inherit; text-decoration: none; }
.sig-drawer__name a:hover { text-decoration: underline; text-underline-offset: 2px; }
.sig-drawer__meta {
  margin: 0 0 var(--sig-2);
  font-size: 12px; color: var(--sig-muted);
}
.sig-drawer__line {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sig-2);
  margin-top: var(--sig-2);
}

/* A drawn field, not a pill: hairline box, 8px, the ruled look the rest of
   the system uses. */
.sig-drawer__qty {
  display: inline-flex; align-items: center;
  border: 1px solid var(--sig-hair);
  border-radius: var(--sig-r-chip);
  background: var(--sig-card);
}
.sig-drawer__step {
  width: 36px; height: 36px; padding: 0;
  font-size: 16px; line-height: 1; color: var(--sig-ink);
  background: none; border: 0; cursor: pointer;
}
.sig-drawer__step:hover { background: var(--sig-panel); }
.sig-drawer__step:focus-visible { outline: 2px solid var(--sig-ink); outline-offset: -2px; }
.sig-drawer__n {
  min-width: 28px; text-align: center;
  font-size: 14px; font-weight: 600; font-variant-numeric: tabular-nums;
  color: var(--sig-ink);
}
.sig-drawer__qty-fixed { font-size: 13px; color: var(--sig-muted); }
.sig-drawer__amt {
  font-size: 15px; font-weight: 600; color: var(--sig-ink);
}

.sig-drawer__x {
  width: 32px; height: 32px; padding: 0;
  font-size: 20px; line-height: 1; color: var(--sig-muted);
  background: none; border: 0; cursor: pointer;
  align-self: start;
}
.sig-drawer__x:hover { color: var(--sig-warn); }
.sig-drawer__x:focus-visible { outline: 2px solid var(--sig-ink); outline-offset: 2px; }

/* ── The title block ─────────────────────────────────────────────────── */

.sig-drawer__foot {
  flex: 0 0 auto;
  padding: var(--sig-4);
  border-top: 1px solid var(--sig-hair);
  background: var(--sig-panel);
}
.sig-drawer__totals { margin: 0 0 var(--sig-3); }
.sig-drawer__field {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--sig-3);
  padding: 5px 0;
}
.sig-drawer__field dt {
  font-size: 11px; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--sig-muted);
}
.sig-drawer__field dd {
  margin: 0; text-align: right;
  font-size: 16px; font-weight: 600; color: var(--sig-ink);
}
.sig-drawer__field--note dd {
  font-size: 12px; font-weight: 400; color: var(--sig-muted);
}

.sig-drawer__go {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; padding: 15px 20px;
  text-align: center;
}
/* The dot between the word and the price — the same separator the PDP's
   Order now uses, so the two primary buttons on the site read as one
   component in two places. */
.sig-drawer__go-amt {
  position: relative; padding-left: 16px;
  font-variant-numeric: tabular-nums;
}
.sig-drawer__go-amt::before {
  content: ''; position: absolute; left: 0; top: 50%;
  width: 4px; height: 4px; margin-top: -2px;
  border-radius: 50%; background: currentColor; opacity: .45;
}
.sig-drawer__go-amt .amount { font-weight: 700; }

.sig-drawer__view {
  display: block; margin-top: var(--sig-3);
  text-align: center; font-size: 13px; color: var(--sig-muted);
  text-underline-offset: 3px;
}
.sig-drawer__view:hover { color: var(--sig-ink); }

/* ── Empty ───────────────────────────────────────────────────────────── */

.sig-drawer__empty {
  flex: 1 1 auto;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--sig-4); padding: var(--sig-7) var(--sig-4);
  text-align: center;
}
.sig-drawer__empty-t { margin: 0; font-size: 15px; color: var(--sig-muted); }
.sig-btn--quiet {
  background: none; color: var(--sig-ink);
  border: 1.5px solid var(--sig-ink);
}
.sig-btn--quiet:hover { background: var(--sig-panel); filter: none; }

html.sig-drawer-open { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .sig-drawer__scrim,
  .sig-drawer__panel { transition: none; }
}

/* ── The language switch ───────────────────────────────────────────────
   EN | বাংলা. Two options, the active one carrying Signal's locked
   "selected" mark — the same yellow bottom rule as a chosen variation
   swatch, a product tab and the selected payment method. Yellow fills a
   shape; it never writes a word. No new visual language here on purpose.

   Sits in the header end, next to the phone and the cart. It fits on mobile
   because the dead Wishlist link came out — that link could never be
   populated (nothing anywhere adds to it) and was eating ~20% of the
   mobile nav row. */
.sig-lang {
  display: inline-flex; align-items: center; gap: 2px;
  margin-inline-end: var(--sig-3);
}
.sig-lang__opt {
  appearance: none; background: none; border: 0;
  font-family: var(--sig-body); font-size: 13px; line-height: 1;
  color: var(--sig-muted); cursor: pointer;
  padding: 8px 6px; border-radius: 2px;
  box-shadow: inset 0 0 0 var(--sig-yellow);
  transition: box-shadow .12s ease, color .12s ease;
}
/* ⚠️ NOT --sig-body-bn, AND THIS IS THE WHOLE POINT.
   The claim in style.css is that an English-only reader never downloads the
   71 KB Bengali face, because a glyph that never renders never triggers a
   fetch. Measured in a real browser, that claim was FALSE: this button's own
   label is Bengali text, visible on first paint, on every page — so naming
   Hind Siliguri here pulled the whole face down for every visitor including
   the ones who never toggle.

   Five characters in a header control render perfectly well in whatever
   Bengali face the device already has. The webfont now arrives only when
   somebody actually asks for Bengali. Verified: 0 font requests on load,
   1 after the click. */
.sig-lang__opt[lang="bn"] {
  font-family: system-ui, 'Noto Sans Bengali', sans-serif;
  font-size: 13.5px;
}
.sig-lang__opt:hover { color: var(--sig-ink); }
.sig-lang__opt[aria-pressed="true"] {
  color: var(--sig-ink);
  /* DETECTOR OVERRIDE — `side-tab` (slop/warning). Third time, same call as
     home.css `.sig-facts strong` and checkout.css: this is a BOTTOM underline,
     not a side stripe, and it is Signal's locked Treatment C — already the mark
     on variation swatches, product tabs and the selected payment method.
     Reusing it is the whole point; a new "selected" idiom for this one control
     would be the actual mistake. Brand beats skill (CLAUDE.md). */
  box-shadow: inset 0 -4px 0 var(--sig-yellow);
}
.sig-lang__opt:focus-visible {
  outline: 2px solid var(--sig-ink); outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .sig-lang__opt { transition: none; }
}

/* ── Which language is showing ─────────────────────────────────────────
   `display: none` and NOT a visually-hidden clip, deliberately. Two reasons,
   both load-bearing:

   1. A clipped element stays in the accessibility tree, so a screen reader
      would announce every paragraph twice, once per language.
   2. A glyph that never renders never triggers a font fetch — so an
      English-only reader does not download the 71 KB Bengali face at all.

   The second is why the Bengali face costs nothing until someone asks for it. */
.sig-lx--bn { display: none; }
.sig-bn .sig-lx--en { display: none; }
.sig-bn .sig-lx--bn { display: inline; }

/* ── Hide the switch where it would do nothing ─────────────────────────
   INTERIM, and it should stop mattering. Today the only Bengali is theme
   gettext — the homepage, About, 404 and search. A product page's prose is
   product CONTENT (short description, the kit and step bodies, "About this
   one"), which lives in the database and does not pass through gettext at
   all. So the header control renders on a PDP with nothing to flip.

   That is the Wishlist failure exactly: a control that cannot do its job.
   Better to show nothing than to show a lie.

   `:has()` rather than JavaScript so there is no flash of a control that then
   vanishes. lang.js carries the same rule as a fallback for engines without
   `:has()` — an old Android WebView would otherwise still see the dead
   control.

   DELETE THIS BLOCK once Phase 4 (seamless-i18n) puts Bengali on product
   pages, because at that point every page has something to switch. */
body:not(:has(.sig-lx)) .sig-lang { display: none; }

/* Block-level bilingual pairs. wpautop returns <p> elements, which cannot sit
   inside a <span>, so the description swaps two <div>s instead of two spans.
   Element selectors rather than a modifier class, so nothing has to remember
   to add one. */
.sig-bn div.sig-lx--bn,
.sig-bn p.sig-lx--bn { display: block; }
