/* catalogue page — page-specific rules only; shared light-page theme lives in css/light.css */
.prodgrid{padding-bottom:40px}
/* Reserved only while empty. catalogue.js fills this div on load; without the
   reserve .ctaband paints just under the filter bar and then drops the full
   height of the grid — measured as the page's entire CLS (0.0884, one shift at
   172ms, source .ctaband). Same fix as .prodroot on product.html. The selector
   stops matching the moment a card lands, so a filtered view still collapses to
   its natural height. */
.prodgrid:empty{min-height:100vh}
.seg{flex-wrap:wrap;justify-content:center;border-radius:var(--r-seg)}

/* A catalogue is a tool, not a landing page. light.css gives .pagehead 170px of
   top padding, which is right for blog.html and wrong here: with it the first
   card sat at y=803 in a 900px viewport, so applying a filter changed nothing
   the visitor could see. Scoped to this sheet, which loads after light.css. */
.pagehead{padding:104px 0 0}
.seghold{margin:36px 0 28px}
.ftoggle{display:none}
.pcount{font-family:var(--body);font-weight:600;font-size:0.6875rem;letter-spacing:.1em;text-transform:uppercase;color:var(--text-2);margin:-18px 0 20px;text-align:center}
.pcard-top{flex-wrap:wrap;gap:6px 12px}
/* padding-right clears the .sglyph parked in the card's top-right corner */
.pname{font-family:var(--display);font-size:1.25rem;font-weight:600;color:var(--ink);margin:12px 0 0;padding-right:54px;letter-spacing:-.015em;line-height:1.25}
.ptorque{margin-top:22px}
.prow .v{max-width:58%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* A ratio list is the one spec value that must not lose its tail: "30 / 50 / 80
   / 100 / 120 / 160" ellipsed at 58% hides the high ratios, which are the half
   an engineer is usually scanning for. Slash-separated values wrap instead; the
   nowrap default stays for everything else so "134 N·m" never splits. */
.prow .v.list{max-width:64%;overflow:visible;white-space:normal;text-align:right}
.pcard{cursor:pointer;border:1px solid transparent;position:relative}
/* Catalogue only: 95 cards are in the grid at once and every category switch
   rebuilds the lot. Letting the browser skip layout and paint for cards outside
   the viewport cut the median filter response from 381ms to 217ms, measured at
   4x CPU throttle over eight category switches -- and halved the worst case,
   which is what was actually being felt.
   contain-intrinsic-size uses the `auto` keyword so the browser substitutes a
   card's real height once it has been rendered even the once; the number is only
   the first guess, and it is the mean GRID ROW height rather than the mean card
   height, because an unrendered row is as tall as the tallest estimate in it.
   Measured mean row heights: 527px at three columns, 518-542 at two, 497-502 at
   one. 530 covers both multi-column cases; the one-column layout gets its own
   value at .prodgrid's 640px breakpoint, because a flat 520 over-estimated every
   one of its 95 rows and the scrollbar visibly shortened as you scrolled the
   longest version of the page. Residual drift is now under a percent or two,
   which is scrollbar precision only -- scroll anchoring holds the content still.
   Not applied to .bcard or .relcard: those grids hold at most a dozen items, so
   there is nothing to skip and the placeholder guess would be pure risk. */
.pcard{content-visibility:auto;contain-intrinsic-size:auto 530px}
@media(max-width:640px){.pcard{contain-intrinsic-size:auto 500px}}

/* spec-parameter filters */
/* .filters is the surface; .fgroups is the row. Split so the mobile disclosure
   can collapse the row without also collapsing the panel it sits in. */
.filters{background:var(--surface-sunk);border-radius:var(--r-seg);padding:18px 22px;margin:-26px 0 26px}
.fgroups{display:flex;flex-wrap:wrap;align-items:flex-end;gap:16px 28px}
.flabel{display:block;font-family:var(--body);font-weight:600;font-size:0.625rem;letter-spacing:.14em;text-transform:uppercase;color:var(--text-2);margin-bottom:8px}
.fchips{display:flex;flex-wrap:wrap;gap:6px}
/* outlined pill toggle — shared by the spec filters and the card quote button */
.fchip,.qadd{color:var(--steel);background:var(--surface);border:1px solid var(--line);border-radius:var(--r-pill);cursor:pointer;transition:background .2s,border-color .2s,color .2s}
.fchip:hover,.fchip{font-size:var(--t-fine);font-weight:500;padding:7px 14px}
.fchip.on{background:var(--ink);border-color:var(--ink);color:var(--text-hi)}
.fchip.enc.on{background:rgb(var(--amber-rgb)/.18);border-color:rgb(var(--amber-rgb)/.55);color:var(--index)}
.finput{display:flex;align-items:center;gap:8px;font-size:var(--t-fine);color:var(--text-2)}
.finput input{width:88px;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-chip);padding:8px 10px;font-family:var(--mono);font-size:var(--t-small);color:var(--ink)}
.finput input:focus,.filters select:focus{border-color:var(--accent-line)}
.filters select{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-chip);padding:8px 32px 8px 10px;font-family:var(--mono);font-size:var(--t-small);color:var(--ink);appearance:none;cursor:pointer;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%237C8A99' fill='none' stroke-width='1.5'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 11px center}
.fclear{margin-left:auto;align-self:center;background:none;border:none;cursor:pointer;font-size:var(--t-fine);font-weight:600;color:var(--accent);padding:8px 4px}
.fclear:hover{color:var(--accent-hover)}
.fempty{grid-column:1/-1;padding:56px 40px;text-align:center}
.fempty h3{font-family:var(--display);font-size:1.375rem;font-weight:600;color:var(--ink);margin:0 0 8px;letter-spacing:-.015em}
.fempty p{color:var(--steel);font-size:var(--t-copy);margin:0 auto;max-width:52ch}
.femptycta{display:flex;gap:12px;justify-content:center;margin-top:26px;flex-wrap:wrap}
@media(max-width:640px){
  .fclear{margin-left:0}

  /* 330px of stacked chips before a single part number is visible. One
     scrollable row instead; the chip clipped at the right edge is the
     affordance, and catalogue.js scrolls the active one into view on load so a
     deep link never opens on a selection you cannot see. */
  .seghold{display:block;margin:22px 0 18px}
  .seg{display:flex;flex-wrap:nowrap;overflow-x:auto;overscroll-behavior-x:contain;
    justify-content:flex-start;width:100%;border-radius:var(--r-pill);
    scroll-snap-type:x proximity;scroll-padding-left:4px;
    scrollbar-width:none;-ms-overflow-style:none}
  .seg::-webkit-scrollbar{display:none}
  .seg button{flex:0 0 auto;scroll-snap-align:start}

  /* the five groups collapse behind .ftoggle */
  .filters{display:block;padding:0;background:none;margin:0 0 22px}
  .ftoggle{display:flex;align-items:center;gap:10px;width:100%;min-height:44px;
    padding:11px 16px;background:var(--surface-sunk);border:none;
    border-radius:var(--r-seg);font-family:var(--body);font-weight:600;
    font-size:var(--t-small);color:var(--steel);cursor:pointer;text-align:left}
  .ftoggletext{flex:1}
  .ftoggle::after{content:'';width:8px;height:8px;flex:0 0 auto;margin-bottom:3px;
    border-right:1.6px solid currentColor;border-bottom:1.6px solid currentColor;
    transform:rotate(45deg);transition:transform .25s var(--ease-out)}
  .ftoggle[aria-expanded="true"]::after{transform:rotate(225deg);margin:3px 0 0}
  /* an author display: wins over the UA rule for [hidden], so say it explicitly
     or the badge renders a "0" whenever no filter is set */
  .fbadge[hidden]{display:none}
  .fbadge{display:inline-flex;align-items:center;justify-content:center;
    min-width:20px;height:20px;padding:0 6px;border-radius:var(--r-pill);
    background:var(--ink);color:var(--surface);font-family:var(--mono);
    font-size:var(--t-meta);font-weight:500}
  .fgroups{display:none;flex-wrap:wrap;gap:14px 20px;background:var(--surface-sunk);
    border-radius:var(--r-seg);padding:16px;margin-top:8px}
  .filters.open .fgroups{display:flex}
}
/* filter controls are the working surface of this page on a phone */
@media(pointer:coarse){
  .fchip{min-height:44px;padding:12px 16px}
  .finput input,.filters select{min-height:44px}
  .fclear{min-height:44px}
}

/* the border is the only non-text carrier of this state, so it needs 3:1;
   the .pbadge label still names it in text -- colour is never the only cue */
.pcard.enc23{border-color:var(--index-line);box-shadow:0 1px 2px rgb(var(--ink-rgb)/.04),0 8px 28px rgb(var(--amber-rgb)/.14)}
.pcard.enc23:hover{box-shadow:0 2px 4px rgb(var(--ink-rgb)/.05),0 24px 48px rgb(var(--amber-rgb)/.22)}

/* add-to-quote on catalogue cards */
.cardactions{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-top:24px}
.cardactions .pcta{margin-top:0}
.qadd{font-size:0.75rem;font-weight:600;padding:7px 13px;white-space:nowrap}
.qadd:hover{border-color:var(--slate);color:var(--ink)}
.qadd.on{background:rgb(var(--cyan-rgb)/.12);border-color:rgb(var(--cyan-rgb)/.45);color:var(--accent)}
