/** Shopify CDN: Minification failed

Line 765:10 Expected ":"
Line 769:101 Unterminated string token
Line 770:95 Unterminated string token

**/
/* CUSTOM_WEIGHTDESIGNER_BY_CLAUDE — weight-designer-kb.css
 * ==========================================================================
 * 3D Weight Designer Help & Guide. Sits directly below the WD embed on the
 * same full-bleed #000F1C surface (same box-shadow/clip-path technique), so
 * the page reads as one continuous dark canvas. Accent + column mirror the
 * .wd-embed-help band this section replaces (60×3px #4DA3FF bar, centered
 * 900px column). Everything scoped .wd-kb / .wd-kb__* — nothing leaks.
 *
 * Progressive enhancement contract with weight-designer-kb.js:
 *   no JS  → no .wd-kb--js on the root → answers expanded, tabs/search hidden
 *   JS     → .wd-kb--js → accordions collapse, tabs + search light up
 * ========================================================================== */

/* CONTAINED, NOT FULL-BLEED (Ryan 2026-08-02): *"the far left and right edges should be white…
   similar to so many sections on product pages where you can toggle a box that has sections go
   full width or not… It'll match the box width on the 'Custom Q&A' section."*

   So this is the Q&A card's box, to the character:
   `custom-q-and-a.liquid` → `.ai-faq-accordion__inner-*` is
   `max-width: calc(var(--page-width, 1320px) + var(--gutter) * 2)` + auto side margins. It is also
   the SAME formula `.wd-frame` uses for the designer window and `.wd-embed-seo__inner` used for the
   intro band, so the dark FAQ box now lines up with the canvas edge above it rather than merely
   being narrower than the viewport.

   ⚠ THE FULL-BLEED MACHINERY IS GONE ON PURPOSE — do not reinstate `width: 100vw` + negative
   half-gutter margins to "fix" the white edges; they ARE the request. Kept from the old comment,
   because it is still the rule for anything on this page that DOES need to bleed: never use
   `box-shadow: 0 0 0 100vmax` + `clip-path: inset(0 -100vmax)` here. That pair asks the compositor
   for a ~1000px-spread shadow around a 1,400px-tall section and clips it back, and the designer
   above RESIZES as it boots (the 3D canvas sizes itself), so a refresh landing mid-restore leaves
   the stale band behind — Ryan, 2026-08-01: *"the dividing line partially overlapping the top
   editor section… it covers the entire window and I can't scroll up to it."* `clip-path` also makes
   the element a containing block for `position: fixed` descendants (the trap that hid the resume
   dialog — see ui/gate.js).

   ⚠ NO `border-top` (removed 2026-08-02, Ryan): it was a 1px rgba(255,255,255,.08) hairline that
   read as a grey rule separating the designer from the FAQ. With the box now inset, the change in
   width is the separation. */
.wd-kb {
  background: #000F1C;
  position: relative;
  /* WHITE BESIDE THE BOX, AT EVERY WIDTH (Ryan 2026-08-05: *"there needs to be a minimum white
     padding/margin/gap on the left and right sides of this section, same as what is built into the
     custom q&a section found on collection pages and product pages… narrow displays maintain some
     space on the left and right side of the Q&A on that Spirit collection page, but narrow displays
     don't require a minimum padding/margin on the WD public page"*).

     ⚠ THE MAX-WIDTH WAS NEVER THE GUTTER — it only LOOKED like one. `max-width` + `margin: auto`
     produces white beside the box exactly when the viewport EXCEEDS the cap; below it the box takes
     the full 100% and runs edge to edge. So the wide desktop looked correct and every narrower
     display lost the gap, which is why this read as a mobile-only fault when it is really "the cap
     is not doing the job everyone assumed it was".

     THE Q&A DOES IT WITH `.container` (`sections/custom-q-and-a.liquid` wraps its card in one):
     the SAME `max-width` as this line, PLUS `padding: 0 var(--gutter)` (assets/main.css). The
     padding is the part that survives below the cap, and the part this rule was missing.

     ⛔ BUT IT CANNOT BE PADDING HERE, and that is the one thing to get right. `.container` carries
     no background — the card inside it does — so its padding shows the page white through. This
     element IS the dark box (`background: #000F1C`), so padding would simply make the dark wider and
     produce no gap at all. The gutter has to come off the element's own WIDTH, which is the same
     reasoning the `margin-top` below is written up for: the box's background must not extend into
     the gap.

     `--gutter` is the theme's own responsive gutter (20px / 32px / 80px by breakpoint,
     assets/main.css) and carries units at every tier — unlike `--section-gap`, see the ⛔ below — so
     this matches the Q&A's inset breakpoint for breakpoint rather than inventing a number. `margin`
     stays `auto` so the box still centres once the cap binds on wide screens. */
  width: calc(100% - var(--gutter, 32px) * 2);
  max-width: calc(var(--page-width, 1320px) + var(--gutter, 32px) * 2);
  margin-left: auto;
  margin-right: auto;
  /* WHITE ABOVE THE BOX (Ryan 2026-08-02: *"there should be white margin/padding along the top edge
     of the FAQ section too"*). `margin`, not padding — the box's own background must NOT extend into
     this gap, which is the whole point. `--section-gap` is the theme's own between-sections rhythm
     (48px on live), so this matches the spacing every other section pair on the site uses rather
     than being a number invented here.
     ⚠ This gap USED TO BE what makes the designer's lower dark band visible. Measured on Live before
     it existed: dark above the designer 20px, dark below 20px — already equal — but the lower one
     ran straight into this box (also #000F1C) with a 0px seam, so it never read as a band and the
     top looked thicker. Nothing about the designer was asymmetric; the boundary was missing.

     ⚠ NO LONGER THIS BOX'S JOB (2026-08-10). Ryan moved "Why Design Your Weights with Blue Sky"
     between the designer and this section, so `.ecore-why` (#F9F9F9) now provides that boundary and
     this margin is plain section rhythm again. Keep it — the gap is still wanted above a dark
     full-bleed box sitting under a light one — but do not reason about the designer's band from
     here, because this element is no longer adjacent to it.

     ⛔ `--section-gap` IS UNITLESS. theme.liquid emits `--section-gap: {{ settings.section_gap }}`
     → literally `48`, and every consumer in main.css multiplies it by `--fluid-1-5` (which carries
     the unit) rather than using it directly. So `margin-top: var(--section-gap, 48px)` resolves to
     `margin-top: 48`, an invalid declaration that the browser drops **silently** — the push
     succeeded, the rule was in the served CSS, and the measured gap was still 0px. Only a
     measurement caught it. The plain `48px` below is a fallback that stands if the calc is ever
     invalid; the calc wins when it parses, and is the same fluid rhythm every other section pair
     on the site uses. */
  margin-top: calc(48px + var(--wd-kb-mt-extra, 0px));
  margin-top: calc(var(--section-gap) * var(--fluid-1-5) + var(--wd-kb-mt-extra, 0px));
  /* WHITE BELOW THE BOX (Ryan 2026-08-13: *"what I want on the Help Guide is bottom white padding
     that can be added… below the card, or top"*). MARGIN for the same reason every other gap here
     is: this element IS the dark box, so padding can only ever make the dark taller and would
     produce no white at all.

     Editor-controlled and defaulting to 0, so a section saved before the setting existed renders
     exactly as it did. The top counterpart ADDS to the section rhythm above rather than replacing
     it — otherwise dialling it to 0 would close a gap that was never the editor's to close. Both
     terms of that calc carry units; see the ⛔ above for why that matters with --section-gap. */
  margin-bottom: var(--wd-kb-mb, 0px);
  /* Editor-controlled (sections/weight-designer-kb.liquid emits the vars). The rem fallbacks are
     the values this rule shipped with, so a section saved before the settings existed — or any
     other consumer of this stylesheet — renders exactly as it did. */
  padding: var(--wd-kb-pt, 3rem) 0 var(--wd-kb-pb, 4.5rem);
  font-family: Montserrat, sans-serif;
  color: rgba(255, 255, 255, 0.85);
}

.wd-kb__container {
  max-width: 900px;
  margin: 0 auto;
  padding: 0 20px;
}

/* ── header (matches the retired .wd-embed-help band) ── */
/* `padding-top: 27px` REPLACES the removed accent bar's own footprint (3px rule + its 24px
   margin-bottom), so dropping the mark leaves the gap rather than pulling the heading up by 27px.
   Ryan asked to "remove it and just leave it as a gap here" — this is that gap.
   ⚠ The `.wd-kb__accent` rule is deleted, not just unused: leaving dead CSS for an element the
   markup no longer emits is how a future session "restores" a thing that was deliberately cut. */
.wd-kb__header { text-align: center; margin-bottom: 28px; padding-top: 27px; }
.wd-kb__heading {
  color: #fff; margin: 0 0 12px;
  font-size: 28px; font-weight: 700; line-height: 1.2;
}
/* The two halves of a colon-separated heading. Inline on desktop — one line, as
   written. The mobile rule that splits them lives in the max-width:749px block. */
.wd-kb__heading-a,
.wd-kb__heading-b { display: inline; }
.wd-kb__subheading {
  color: rgba(255, 255, 255, 0.85);
  margin: 0 auto; max-width: 560px;
  font-size: 16px; line-height: 1.6;
}

/* ── search ── */
.wd-kb__search {
  position: relative;
  max-width: 560px;
  margin: 0 auto 10px;
}
.wd-kb__search-icon {
  position: absolute; left: 16px; top: 50%; transform: translateY(-50%);
  color: rgba(255, 255, 255, 0.45); pointer-events: none;
}
.wd-kb__search-input {
  width: 100%;
  padding: 13px 44px 13px 46px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 999px;
  color: #fff;
  font: 400 15px/1.4 Montserrat, sans-serif;
  outline: none;
  transition: border-color 0.15s ease, background 0.15s ease;
  -webkit-appearance: none;
  appearance: none;
}
.wd-kb__search-input::placeholder { color: rgba(255, 255, 255, 0.4); }
.wd-kb__search-input:focus { border-color: #4DA3FF; background: rgba(255, 255, 255, 0.09); }
.wd-kb__search-input::-webkit-search-cancel-button { display: none; }
.wd-kb__search-clear {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  width: 28px; height: 28px; border-radius: 50%;
  border: 0; background: rgba(255, 255, 255, 0.12);
  color: #fff; font-size: 16px; line-height: 1;
  cursor: pointer;
}
.wd-kb__search-clear:hover { background: rgba(255, 255, 255, 0.22); }
/* ⛔ THE COUNT HOLDS ITS LINE WHETHER OR NOT IT SAYS ANYTHING. It only has text
   while searching, so hiding it when empty made every search state 26px taller
   than every browse state — a jump that survived all the paging work because it
   fires on typing rather than on a page turn, and only ever in one direction.
   weight-designer-kb.js un-hides it once on init and empties the TEXT instead;
   the attribute stays in the markup so a JS-off visitor, who has no search box
   either, never sees a blank reserved line. */
.wd-kb__result-count {
  text-align: center;
  margin: 0 0 6px;
  min-height: 19px;
  font-size: 13px; color: rgba(255, 255, 255, 0.55);
}

/* ══ THE RAIL ═══════════════════════════════════════════════════════════════
   Ryan, 2026-08-13: *"The pills at the top. I don't like the color choice and
   how they're kind of randomly scattered."* They were ten labels of ten widths
   in `flex-wrap: wrap; justify-content: center`, so they broke into ragged
   centred rows that re-broke at every viewport — and carried three competing
   treatments at once (a light #E6EBF2 fill against the navy, a blue wipe on
   hover, a white ring with a bloom when active), which made the navigation the
   loudest thing in the section.

   They are now a quiet vertical rail BESIDE the answers: one column, uniform
   width, a count on each row, and the active row marked by a soft wash and a
   3px edge. Nothing wipes, nothing glows.

   ⚠ THE TWO-COLUMN GRID IS GATED ON .wd-kb--js, like everything else here.
   Without JS the tabs are display:none and the body must stay a plain block, or
   the answers would render in a 1fr column beside an empty 194px gutter.

   📌 The old `.wd-kind-chip` wipe this replaced still lives in the WD bundle
   (app/src/styles/weight-designer.css) where the buyer first meets it on the
   welcome screen. That copy is untouched and still correct there — this was a
   deliberate port, and un-porting it is not a reason to change the original. */
.wd-kb__tabs { display: none; }
.wd-kb--js .wd-kb__body {
  display: grid;
  grid-template-columns: 194px 1fr;
  /* ⚠ ROW GAP MUST BE ZERO. The pager became a grid ROW of its own (see below), and a 38px row gap
     would stack on top of its existing 18px margin-top and shove it down. The column gap is the
     one that was ever wanted here. */
  column-gap: 38px;
  row-gap: 0;
  align-items: start;
  margin-top: 18px;
}
/* ⛔ THE RAIL STOPS AT THE BOTTOM OF THE QUESTION FRAME, NOT THE PAGER (Ryan 2026-08-14).
   A sticky grid item travels within its GRID AREA, and `.wd-kb__panels` was a single grid item
   holding BOTH the viewport and the pager — so the row measured 763px where the question frame is
   692, and the rail overran the last question by exactly the pager's 53px plus its 18px margin.
   `display: contents` dissolves that wrapper's box so the viewport and the pager become grid items
   in their own right, on two rows. The rail then shares row 1 with the viewport alone and comes to
   rest level with the bottom of the tenth question.
   ⚠ Safe only because NOTHING styles or measures `.wd-kb__panels` — checked, it has no rules in
   this file and no reference in weight-designer-kb.js. It stays in the DOM for selector matching;
   only its box goes away. If it ever gains a background, a border or a measured height, this
   stops being free and the pager has to move in the generated snippet instead. */
.wd-kb--js .wd-kb__panels   { display: contents; }
.wd-kb--js .wd-kb__tabs     { grid-column: 1; grid-row: 1; }
.wd-kb--js .wd-kb__viewport { grid-column: 2; grid-row: 1; }
.wd-kb--js .wd-kb__pager    { grid-column: 2; grid-row: 2; }
/* THE RAIL FOLLOWS YOU DOWN (Ryan 2026-08-13: *"The left-side pane with the
   categories doesn't slide down as you scroll down"*).
   ⚠ `--header-end-padded` is the THEME'S OWN sticky offset, written in px by
   main.js `setHeaderEnd()` on every scroll and already used by the product page,
   the cart summary and featured collections. Use it rather than inventing a
   number: the header collapses and re-expands as you scroll, so any constant is
   wrong at one end or the other. Unlike `--section-gap` it carries its unit, so
   `var()` here is safe — see the ⛔ on `margin-top` above for the one that
   doesn't and dies silently.
   ⚠ A sticky GRID ITEM travels within its grid AREA, not its own box, so
   `align-items: start` on .wd-kb__body does not pin it — the area is as tall as
   the answers column beside it, which is exactly the distance it should cover.
   ⛔ ANY ancestor with `overflow: hidden` would kill this outright. .wd-kb and
   .wd-kb__container deliberately have none (the full-bleed box-shadow/clip-path
   machinery was removed 2026-08-02 and must not come back); the frame's own
   clip is on .wd-kb__viewport, a SIBLING, which is why the page turn can clip
   without breaking this.
   The max-height is the guard for a short window: a rail taller than the space
   under the header would otherwise have its last categories unreachable. */
.wd-kb--js .wd-kb__tabs {
  display: flex; flex-direction: column;
  gap: 2px;
  /* ⛔ THE RAIL STOPS LEVEL WITH THE LAST QUESTION, AND THIS MARGIN IS WHAT STOPS IT.
     Putting the pager on its own grid row (see .wd-kb__panels above) was necessary but NOT
     sufficient: Chrome constrains a sticky grid item to the grid CONTAINER, not to its grid area,
     so the rail still travelled the full two-row height and came to rest against the pager —
     measured 67px past the question frame with the row placement provably correct
     (grid-template-rows: 700px 70.5px, tabs in row 1). A sticky box IS inset by its own margins,
     which is the one lever that reliably shortens the travel.
     ⚠ The value is the pager row's height and is written by the JS (`--wd-kb-rail-tail`), not
     hardcoded — 70.5px today is the pager's border, padding and button metrics added up, and any
     restyle of those would silently put the rail back over the pager. Falls back to 0 so a
     JS-less render is simply unchanged. */
  margin: 0 0 var(--wd-kb-rail-tail, 0px);
  position: sticky;
  top: var(--header-end-padded, 48px);
  max-height: calc(100vh - var(--header-end-padded, 48px) - 24px);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.18) transparent;
}
/* A rail row. The accent edge is an INSET box-shadow rather than a border-left,
   so arriving at the active state costs no layout — a 3px border would shove the
   label 3px right on every selection. */
.wd-kb__tab {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px;
  width: 100%;
  text-align: left;
  border: 0;
  border-radius: 8px;
  padding: 9px 11px;
  background: transparent;
  color: rgba(255, 255, 255, 0.60);
  font: 600 13px/1.35 Montserrat, sans-serif;
  cursor: pointer;
  box-shadow: inset 3px 0 0 0 transparent;
  transition: background 0.16s ease, color 0.16s ease, box-shadow 0.16s ease;
}
.wd-kb__tab-n {
  flex: 0 0 auto;
  font-size: 11.5px; font-weight: 600;
  color: rgba(255, 255, 255, 0.32);
  font-variant-numeric: tabular-nums;
}
/* Bare `hover: hover` — NEVER `and (pointer: fine)`: Ryan's desktop is a touch
   laptop and reports a coarse pointer. The label's hover lives in here too, not
   outside: a touch browser holds :hover on the last-tapped element, so an ungated
   text rule keeps the label lit after the background has already reverted. */
@media (hover: hover) {
  .wd-kb__tab:hover { background: rgba(255, 255, 255, 0.055); color: rgba(255, 255, 255, 0.9); }
}
.wd-kb__tab--active {
  background: rgba(77, 163, 255, 0.13);
  color: #fff;
  box-shadow: inset 3px 0 0 0 #4DA3FF;
}
.wd-kb__tab--active .wd-kb__tab-n { color: rgba(255, 255, 255, 0.6); }
/* "All" is a different KIND of choice from the nine categories — it is the whole
   corpus, not one of them — so a hairline separates it rather than leaving it as
   the first of ten identical rows. */
.wd-kb--js .wd-kb__tab[data-category="all"] {
  margin-bottom: 8px; padding-bottom: 13px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 8px 8px 0 0;
}
.wd-kb__tab:focus-visible,
.wd-kb__q-btn:focus-visible,
.wd-kb__search-input:focus-visible,
.wd-kb__search-clear:focus-visible {
  outline: 2px solid #4DA3FF; outline-offset: 2px;
}

/* ══ THE FRAME, THE FLOOR, AND THE PAGE TURN ════════════════════════════════
   Ryan, 2026-08-13: *"How big it is. When you click on a pill like 'All', the
   questions go down 4 pages long."* — 114 collapsed rows plus nine headings is
   about seven screens. The answer is not a smaller list, it is TEN AT A TIME
   with a pager, which also keeps every category at one height.

   ⛔ EVERY RULE BELOW IS A HEIGHT DECISION, and each one exists because a
   version without it visibly moved the Next button under the cursor. The three
   causes found by walking every page of every category at three viewports:
     1. category headings — 33px each, and a page carries a different NUMBER of
        them depending on which categories it spans (see .wd-kb__q-cat)
     2. the pager vanishing on a single-page category — 76px
     3. a question wrapping to two lines — 16px per wrapped row, and on a phone
        at 390px, 81 of the 114 questions wrap

   ⚠ NONE OF IT APPLIES WITHOUT JS. No floor is set (--wd-kb-min-h is written by
   weight-designer-kb.js), nothing is clipped, and the pager is display:none — so
   a crawler and a JS-off visitor still get all 114 answers expanded in one flat
   list, which is the whole progressive-enhancement contract of this section. */

/* The FRAME. --wd-kb-min-h is the tallest page that CAN occur — the ten tallest
   rows in the corpus, summed, measured at the current viewport. No page of ten
   rows can beat the ten tallest rows, so a wrap can never grow it.
   ⛔ MINIMUM, NOT A CAP: an opened answer must still be free to push it taller.
   That is the one height change this section should make, and clamping it would
   scroll the answer inside a box instead. */
.wd-kb__viewport { position: relative; min-height: var(--wd-kb-min-h, 0px); }
/* A search that matched nothing is the one place the floor should NOT hold:
   there is nothing to page, so a frame-height box of empty navy sitting above
   the "no answers" card would be all cost and no benefit. The pager goes with
   it — a pager over an empty frame is a control for a list that isn't there. */
.wd-kb--empty .wd-kb__viewport { min-height: 0; }
.wd-kb--js.wd-kb--empty .wd-kb__pager { display: none; }
/* Clipping is TRANSIENT — only while a turn runs. Permanent overflow:hidden
   would cut off an opened answer the moment it passed the floor. */
.wd-kb--js .wd-kb__viewport.is-turning {
  overflow: hidden;
  transition: height 0.28s cubic-bezier(0.16, 1, 0.3, 1);
}
/* The measuring pass: every row laid out at the real column width, off the
   paint. Absolute inside the relative frame keeps the width honest without the
   frame briefly growing to fit all 114 rows. */
.wd-kb__stack.is-measuring {
  position: absolute; left: 0; right: 0; top: 0;
  visibility: hidden; pointer-events: none;
}
.wd-kb__stack.is-measuring .wd-kb__category,
.wd-kb__stack.is-measuring .wd-kb__item { display: block; }
.wd-kb__stack.is-measuring .wd-kb__a { grid-template-rows: 0fr; }
/* ⚠ ROWS ARE MEASURED TWICE, and the second pass is what this class is for. The
   in-row label takes its width off the question and can therefore CAUSE a wrap,
   so a row is a different height in "All" and in a search than it is in a single
   category. Packing a page against the wrong set either overfills it (the frame
   grows) or underfills it (dead space), so weight-designer-kb.js measures both
   and uses the set that matches the current view. */
@media (min-width: 900px) {
  .wd-kb__stack.is-measuring.is-measuring-multi .wd-kb__q-cat { display: block; }
}

/* ── the page turn ──────────────────────────────────────────────────────────
   The whole page moves as ONE block: the outgoing set rides up and out of the
   frame, then the incoming set follows it up from below. Never row by row — a
   stagger across ten rows reads as a carousel shuffling cards rather than a page
   being pushed past. --wd-kb-turn-d is the FRAME's height, written by the JS:
   a short page (a four-result search) is shorter than the frame it sits in, and
   translating by its own 100% would leave it mid-frame instead of below it. */
.wd-kb--js .wd-kb__stack {
  transition: transform 0.2s cubic-bezier(0.55, 0, 1, 0.45),
              opacity 0.2s cubic-bezier(0.55, 0, 1, 0.45);
}
.wd-kb__stack.is-out { transform: translateY(calc(-1 * var(--wd-kb-turn-d, 100%))); opacity: 0; }
.wd-kb__stack.is-below { transform: translateY(var(--wd-kb-turn-d, 100%)); opacity: 0; }
.wd-kb__stack.is-entering {
  transition: transform 0.28s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.2s ease-out;
}
/* The single frame where the stack is repositioned below the frame after the
   swap. That jump must never tween, or it rides back down through the outgoing
   position and the turn reads as a bounce. */
.wd-kb__stack.no-anim { transition: none !important; }
/* Answers are closed during the invisible half of the turn, so their own 0.6s
   collapse must not run — it would fight the frame's height tween. */
.wd-kb__stack.no-anim .wd-kb__a { transition: none; }

/* ── the pager ──────────────────────────────────────────────────────────────
   ONE control for the whole list, never one per category: a page of "All" or of
   a search result spans categories, so a per-category pager could not describe
   what is on screen.
   ⛔ ALWAYS IN THE LAYOUT once JS is up, buttons and all — a category that fits
   on one page keeps the space and reads "Page 1 of 1" with both disabled.
   Letting it disappear moved everything below it by 76px. */
.wd-kb__pager { display: none; }
.wd-kb--js .wd-kb__pager {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px;
  margin-top: 18px; padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.10);
}
.wd-kb__pager-btn {
  display: inline-flex; align-items: center;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 8px;
  background: transparent;
  color: rgba(255, 255, 255, 0.72);
  font: 600 13.5px/1 Montserrat, sans-serif;
  padding: 10px 15px;
  cursor: pointer;
  transition: background 0.16s ease, color 0.16s ease, border-color 0.16s ease;
}
.wd-kb__pager-btn:hover:not(:disabled) {
  background: rgba(77, 163, 255, 0.10); border-color: #4DA3FF; color: #fff;
}
.wd-kb__pager-btn:disabled { opacity: 0.28; cursor: default; }
.wd-kb__pager-at {
  margin: 0;
  font-size: 12.5px; font-weight: 600; letter-spacing: 0.05em;
  color: rgba(255, 255, 255, 0.32);
  font-variant-numeric: tabular-nums;
  text-align: center;
}
.wd-kb__pager-at b { color: rgba(255, 255, 255, 0.72); font-weight: 700; }
.wd-kb__pager-btn:focus-visible { outline: 2px solid #4DA3FF; outline-offset: 2px; }

/* ── categories & items ── */
/* Panels are hidden by DEFAULT and the active one is marked in the generated
   markup — so the resting view is right at first paint. (Filtering them after
   load meant painting all nine categories and then collapsing eight, i.e. the
   same layout-shift problem as the answers.) <noscript> re-shows them all. */
.wd-kb__category { display: none; margin-bottom: 8px; }
.wd-kb__category--active { display: block; }
.wd-kb__category-title {
  color: #fff;
  font-size: 18px; font-weight: 700; line-height: 1.3;
  margin: 26px 0 10px;
}
/* ⛔ HIDDEN ONCE JS IS UP, and it is a height fix as much as a design one. The
   rail already names the single category being shown, so the heading is
   redundant there; and in "All" or a search — the only places it was not — it
   made the page height depend on HOW MANY categories a page happened to span.
   One heading on one page, three on the next, 33px each: the pager moved on
   almost every turn. Ryan, 2026-08-13: *"when you go to the All category, it
   feels like almost every single click results in the next and back buttons
   jumping up or down slightly... which makes for bad UX."*
   ⚠ IT STAYS IN THE MARKUP. Crawlers read the grouped structure and the no-JS
   view renders it, so this is a JS-only presentation change, never a content
   one — do not "tidy" it out of build-help.mjs. */
.wd-kb--js .wd-kb__category-title { display: none; }
/* What replaces it: the category rides INSIDE the row, at no cost in height
   because the row already has the room. Shown only where it says something the
   rail does not — "All" and searches — and only where there is width for it.
   ⚠ It uses the SHORT category name (corpus/categories.json `short`). The full
   one takes enough width off the question to wrap rows that would otherwise fit
   on one line, which raises the floor for every page: measured, the long labels
   cost 108px of frame height. */
.wd-kb__q-cat {
  flex: 0 0 auto;
  display: none;
  margin-left: auto;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.38);
  white-space: nowrap;
}
.wd-kb--js.wd-kb--multi .wd-kb__q-cat { display: block; }
@media (max-width: 899px) { .wd-kb--js.wd-kb--multi .wd-kb__q-cat { display: none; } }
.wd-kb__item {
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.04);
  margin-bottom: 8px;
  overflow: hidden;
}
.wd-kb__item--hidden { display: none; }

.wd-kb__q { margin: 0; font-size: inherit; }
.wd-kb__q-btn {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  width: 100%;
  /* 16px/24px matches the GLD header, so the question and the answer text below
     it share one 24px left edge. */
  padding: 16px 24px;
  border: 0; background: transparent;
  color: #fff; text-align: left;
  font: 600 15px/1.45 Montserrat, sans-serif;
  cursor: pointer;
}
.wd-kb__q-btn:hover { background: rgba(255, 255, 255, 0.04); }
/* ⚠ THE HIGHLIGHT MUST NOT CHANGE THE TEXT'S WIDTH. `padding: 0 1px` on every
   match widens the question by 2px per hit, which is enough to tip a long one
   onto a second line — so a row's height would depend on what was typed, and no
   floor measured against un-highlighted text could hold. The negative margin
   gives the padding back to the layout: the box still paints 1px proud on each
   side, and the line occupies exactly what it did unmarked. */
.wd-kb__q-text mark {
  background: rgba(77, 163, 255, 0.35);
  color: inherit;
  border-radius: 3px;
  padding: 0 1px;
  margin: 0 -1px;
}
/* ── the +/− glyph, adopted verbatim from the product-page Custom Q&A block
   (blocks/custom-q-and-a.liquid): a text "+" that becomes "−" and spins a full
   360° on open. The glyph is swapped in JS; the spin is this transition. ── */
.wd-kb__q-icon {
  flex: 0 0 auto;
  font-size: 28px;
  font-weight: 300;
  line-height: 1;
  opacity: 0.75;
  transition: transform 0.4s ease-out;
}
.wd-kb__item.is-open .wd-kb__q-icon { transform: rotate(360deg); opacity: 1; }

/* Answer collapse — CSS grid rows, no scrollHeight math.
   ⚠ COLLAPSED AT PARSE TIME, deliberately NOT gated on .wd-kb--js. The first
   build gated it on the JS class, so the page shipped 104 EXPANDED answers and
   collapsed them after load — a ~12,000px layout shift landing in the same
   frame the browser restores scroll position on a refresh. That is a Core Web
   Vitals (CLS) problem on every load and a scroll-restoration hazard on any
   refresh below the fold. The no-JS guarantee is kept by the <noscript> block
   in sections/weight-designer-kb.liquid, which re-expands everything — same
   crawler/accessibility floor, zero shift. */
/* Open/close timing adopted from the product-page Custom Q&A block: the panel
   opens over 0.6s ease-in-out and the content fades in + rises 10px over 0.5s
   on a 0.1s delay, so the text arrives just after the box has started moving.
   That block animates `max-height` to a JS-measured scrollHeight; grid rows do
   the same thing to real auto height with no measuring, so the motion matches
   without the height math (and cannot desync if content reflows). */
.wd-kb__a {
  display: grid;
  grid-template-rows: 0fr;
  /* ⚠ THE CONTAINER MUST CLIP, not just the item. `0fr` sizes the ROW to zero,
     but the grid item's own padding still gives it a 20px box that overflows
     that row — which peeked out under the question as a sliver of the answer
     panel while closed (Ryan 2026-08-02). `overflow: hidden` on the item does
     not help: the overflow escapes the ROW, so it is the grid container that
     has to clip. Appeared the moment the padding became constant (the fix for
     the open-snap), because before that there was no padding to overflow. */
  overflow: hidden;
  transition: grid-template-rows 0.6s ease-in-out;
}
.wd-kb__a-inner {
  overflow: hidden;
  min-height: 0;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.5s ease 0.1s, transform 0.5s ease 0.1s;
}
.wd-kb__item.is-open .wd-kb__a { grid-template-rows: 1fr; }
.wd-kb__item.is-open .wd-kb__a-inner { opacity: 1; transform: translateY(0); }

/* Answer spacing adopted from the GLD KB (assets/custom-designer-kb.css —
   `.gld-kb__accordion-divider` + `.gld-kb__accordion-content`): a hairline under
   the question, then 20px before the text, 24px horizontal rhythm, line-height
   1.7 and 12px between paragraphs. The divider is a ::before rather than an
   <hr> so it needs no markup change, and it inherits the box's 24px side
   padding — which is exactly the inset the GLD gets from its
   `max-width: calc(100% - 48px)`.
   ⚠ The vertical padding is CONSTANT, never applied on `.is-open`. Adding it
   with the class made the box taller the instant the class flipped, and the row
   animation then ran from that taller start — the snap Ryan caught on
   2026-08-02. Nothing that changes this box's measured height may be tied to
   the open class; the collapsed row is 0fr with overflow hidden, so the padding
   costs nothing while closed. */
.wd-kb__a-inner {
  /* ⚠ NO VERTICAL PADDING HERE — the bottom gap is the ::after spacer below.
     This box is the grid item, and padding lives OUTSIDE the content box, so it
     contributes height even when the row is `0fr` and `min-height: 0` has let
     the content collapse. 20px of padding-bottom therefore held the closed
     panel 20px tall and peeked out under the question. `overflow: hidden` does
     not help — it clips the paint, it does not shrink the box. Expressing the
     gap as CONTENT means it collapses with everything else while closed. */
  padding: 0 24px;
  font-size: 15px; line-height: 1.7;
  color: rgba(255, 255, 255, 0.82);
}
.wd-kb__a-inner::before {
  content: "";
  display: block;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  margin-bottom: 20px;
}
.wd-kb__a-inner::after { content: ""; display: block; height: 20px; }
.wd-kb__a-inner p { margin: 0 0 12px; }
.wd-kb__a-inner p:last-child { margin-bottom: 0; }
.wd-kb__a-inner ul, .wd-kb__a-inner ol { margin: 0 0 12px; padding-left: 22px; }
.wd-kb__a-inner li { margin-bottom: 4px; }
.wd-kb__a-inner strong { color: #fff; }
.wd-kb__a-inner a { color: #4DA3FF; text-decoration: underline; text-underline-offset: 2px; }
.wd-kb__a-inner a:hover { color: #fff; }

/* ── no-results ── */
.wd-kb__no-results {
  text-align: center;
  padding: 26px 16px;
  border: 1px dashed rgba(255, 255, 255, 0.18);
  border-radius: 12px;
  color: rgba(255, 255, 255, 0.75);
  font-size: 15px; line-height: 1.6;
}
.wd-kb__no-results strong { color: #fff; }
/* The one dead end in the help loop, closed: hand the failed query to the
   in-tool assistant. Stays hidden unless the designer bundle announces itself
   (wd:help-ready), so it can never be a button that does nothing. */
.wd-kb__ask {
  margin-top: 14px;
  border: 1px solid #4DA3FF;
  background: rgba(77, 163, 255, 0.12);
  color: #fff;
  border-radius: 999px;
  padding: 9px 18px;
  font: 600 13.5px/1.2 Montserrat, sans-serif;
  cursor: pointer;
}
.wd-kb__ask:hover { background: #4DA3FF; color: #000F1C; }

/* ── deep-link target flash ── */
.wd-kb__item:target { border-color: #4DA3FF; }

/* ── mobile ── */
@media (max-width: 749px) {
  /* The -m variants are consumed HERE rather than by redefining the desktop custom
     property, because the section emits both inline and an inline custom property
     beats anything this @media block could say about it — the same trap the padding
     pair is written up for in the section file. */
  .wd-kb {
    padding: var(--wd-kb-pt-m, 2.25rem) 0 var(--wd-kb-pb-m, 3.5rem);
    margin-top: calc(48px + var(--wd-kb-mt-extra-m, 0px));
    margin-top: calc(var(--section-gap) * var(--fluid-1-5) + var(--wd-kb-mt-extra-m, 0px));
    margin-bottom: var(--wd-kb-mb-m, 0px);
  }
  /* FLUID, so the lead-in fits on ONE line at every phone width (Ryan 2026-08-15:
     "make the 'Designing Custom Weights:' on mobile small enough so it doesn't wrap
     onto 2 lines").

     ⚠ DERIVED FROM THE REAL BOX MODEL, not a vw fraction picked by eye. The text
     column is inset TWICE and missing either one produces a size that still wraps:
        `.wd-kb`            width: calc(100% - var(--gutter) * 2)   → 20px a side on mobile
        `.wd-kb__container` padding: 0 20px                         → 20px a side again
     so the available width is `100vw - gutter*2 - 40px`, i.e. 280px on a 360px
     phone rather than the 320px a single inset would suggest.

     "Designing Custom Weights:" is 25 characters; at 700 weight, counting the three
     capitals properly rather than a flat lowercase average, it needs ~14.5 × the
     font-size. Dividing the available width by that is exact by construction, so it
     holds at any width and survives a re-worded heading of similar length instead of
     being tuned to one device.
     The divisor is 15.2 rather than 14.5 on purpose: dividing by the exact figure
     fits with ZERO slack, which is correct arithmetic and a wrap the moment the real
     typeface is a hair wider than the estimate. The extra ~5% buys ~13px of room on a
     360px phone and costs under a pixel of type size.

     ⚠ A FIXED smaller size would not do: 24px fits a 390px iPhone and wraps on a
     360px Android, and anything that fits a 320px SE is needlessly small on a 430px
     Pro Max. The 24px cap keeps the top of the range exactly where it was.
     ⚠ Desktop is untouched — the 28px base rule lives outside this media query. */
  .wd-kb__heading {
    font-size: clamp(15px, calc((100vw - var(--gutter, 20px) * 2 - 40px) / 15.2), 24px);
  }
  /* Break the heading at its colon on a phone (Ryan 2026-08-15): the lead-in on line
     one, the rest on line two. `display:block` on the second half forces the break —
     the space between the spans then falls at the end of line one and collapses.
     A heading with no colon emits no spans at all, so this rule cannot touch it. */
  .wd-kb__heading-b { display: block; }
  /* "Page 1 of 2" wraps mid-label in the pager row on a narrow phone. Drop the word, keep the
     count — "1 of 2" beside the arrows is unambiguous and fits (Ryan 2026-08-13). */
  .wd-kb__pager-word { display: none; }
  /* The rail lies down. There is no room for a 194px column beside the answers,
     so the two-column grid collapses and the categories become one quiet
     scrolling row above them. */
  .wd-kb--js .wd-kb__body { display: block; }
  .wd-kb--js .wd-kb__tabs {
    flex-direction: row;
    flex-wrap: nowrap;
    justify-content: flex-start;
    gap: 6px;
    /* ⛔ NOT STICKY ON A PHONE. The rail lies down into a horizontal chip row
       here, and pinning that to the top would park a bar of chips over the
       answers for the whole scroll — it follows you down only when it is a
       column beside them. Both the offset and the height guard are unwound. */
    position: static;
    top: auto;
    max-height: none;
    overflow-y: visible;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
    /* The gap between the chips and the native scrollbar track under them. 6px read as the bar
       crowding the pills (Ryan 2026-08-14). */
    padding-bottom: 14px;
    /* ⛔ NOT FULL-BLEED ANY MORE (Ryan 2026-08-15: *"make it so the scroll bar only extends as far
       left as the left-most side of the question cards.. same thing for the right-side"*).

       A native scrollbar is painted at the SCROLL CONTAINER's own edges — there is no way to inset
       it independently. So the only way to line it up with the cards is to stop the container
       bleeding past them: it was `margin: 0 -20px` (out to the screen edge) with `padding: 0 20px`
       putting the first chip back on the content edge, which left the bar 20px wider than the
       cards at each end. Container is now exactly the content column, so the bar starts and stops
       where the cards do.

       ⚠ The chips no longer run under the bleed — they clip at the content edge like everything
       else in the column. That is the trade the alignment costs, and it is the tidier of the two.

       ⛔ SCROLL-PADDING MUST STAY EQUAL TO THE PADDING, WHICH IS NOW ZERO. `scroll-snap-align:
       start` aligns to the SNAPPORT — the scrollport reduced by `scroll-padding` — so leaving the
       old 20px behind with no padding to match would settle every chip 20px RIGHT of where it was
       laid out: the same magnet Ryan reported on 2026-08-14 (*"like there's a magnet pulling the
       scroll list slightly to the left"*), mirrored. Both sides move together or neither does. */
    margin: 0 0 22px;
    scroll-padding-left: 0;
    scroll-padding-right: 0;
    /* ⛔ THE SAME SCROLLBAR RECIPE AS THE THEME'S `.slider` (Ryan 2026-08-15: *"make this scroll
       bar as thick as the one below the 4 category images in the custom multi-column section"*).
       That section is a `.slider` (sections/multi-column.liquid), and main.css:4086 styles it on
       TWO code paths — the standards properties AND a `::-webkit-scrollbar` block. This strip only
       ever set the first, which is exactly why the two bars did not match: whichever engine the
       phone runs, one element was being drawn by a rule the other did not have.

       ⚠ THE TWO PATHS ARE NOT ADDITIVE, THEY COMPETE. Chrome 121+ honours `scrollbar-width` and
       then IGNORES every `::-webkit-scrollbar` rule; older Safari does the reverse. So both have to
       describe the same bar, or it changes shape between devices — which is the fault being fixed
       here, not a belt-and-braces nicety.

       Colours stay the KB's own: this is a #000F1C box, so the theme's scheme-derived
       `--scrollbar-color` would resolve dark-on-dark. Same structure (solid thumb, faint track),
       white values. */
       ⛔ AND IT CANNOT BE MATCHED EXACTLY, which is worth writing down so nobody spends another
       hour on it. The multi-column bar is NOT a native scrollbar: main.js:1735 runs the
       OverlayScrollbars library on every `.slider`, hiding the native bar and drawing its own. The
       library is not an option here — `custom-ecore-collection-drill.js:78` records it being ripped
       out of another flex strip for "distorting the flex layout … and rendering a phantom vertical
       scrollbar", and main.css forces `scroll-snap-type: none` + `margin: 0 !important` on any
       element it owns, which would undo both the snap fix and the inset above.

       So this is the thinnest a NATIVE bar goes: `thin` is already the smallest keyword short of
       hiding it, and the remaining lever is weight — a TRANSPARENT track so only the thumb reads,
       rather than a filled band the full width of the strip. */
    --scrollbar-border-width: 11px;
    scrollbar-width: thin;
    scrollbar-color: rgb(255 255 255 / 0.28) transparent;
  }
  @supports selector(::-webkit-scrollbar) {
    /* 24px is the BAND, not the line: an 11px transparent border on each side leaves a 2px bar
       drawn by the inset shadow, centred in a 24px touch target. Straight from `.slider`. */
    .wd-kb--js .wd-kb__tabs::-webkit-scrollbar { height: 24px; }
    .wd-kb--js .wd-kb__tabs::-webkit-scrollbar-thumb {
      border: var(--scrollbar-border-width) solid transparent;
      border-radius: var(--btn-border-radius, 0);
      box-shadow: inset 0 0 0 2px rgb(255 255 255 / 0.55);
    }
    .wd-kb--js .wd-kb__tabs::-webkit-scrollbar-track {
      /* No inset needed here, unlike `.slider`, which offsets its track by the page gutter. The
         strip above is no longer full-bleed, so the scroll container IS the content column and the
         bar already starts and stops level with the question cards.
         NO track line: `.slider` draws a faint one, but a band running the full width of the strip
         is the thing that reads as a THICK bar, which is what Ryan is asking to lose. The 2px thumb
         alone is the whole indicator. */
      margin: 0;
      background: transparent;
      box-shadow: none;
    }
  }
  .wd-kb__tab {
    scroll-snap-align: start;
    width: auto;
    white-space: nowrap;
    box-shadow: none;                                  /* the inset edge reads as a stray tick on a horizontal chip */
    border: 1px solid rgba(255, 255, 255, 0.09);
  }
  .wd-kb__tab--active { box-shadow: none; border-color: #4DA3FF; }
  .wd-kb__tab-n { display: none; }                     /* the count crowds a chip that has to stay thumb-sized */
  .wd-kb--js .wd-kb__tab[data-category="all"] {
    margin-bottom: 0; padding-bottom: 9px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.09);
    border-radius: 8px;
  }
  .wd-kb__pager-btn { padding: 10px 12px; font-size: 13px; }
  .wd-kb__q-btn { padding: 14px 18px; font-size: 14px; }
  .wd-kb__a-inner { padding: 0 18px; font-size: 14px; }
  .wd-kb__a-inner::before { margin-bottom: 16px; }
  .wd-kb__a-inner::after { height: 16px; }
}

/* ── reduced motion ── */
/* The page still turns — it just arrives instead of travelling. The JS checks
   the same query and skips the out/in phases rather than running them at zero
   duration, because a 0s transition still fires transitionend and would leave
   the sequencing intact for no benefit. */
@media (prefers-reduced-motion: reduce) {
  .wd-kb__a, .wd-kb__a-inner, .wd-kb__q-icon { transition: none; }
  .wd-kb__item.is-open .wd-kb__q-icon { transform: none; }
  .wd-kb--js .wd-kb__stack, .wd-kb__stack.is-entering { transition: none; }
  .wd-kb--js .wd-kb__viewport.is-turning { transition: none; }
  .wd-kb__tab { transition: none; }
}
