@font-face{font-family:"Saira Condensed";font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/saira-condensed-latin-500.22c6c5bf.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Saira Condensed";font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/saira-condensed-latin-ext-500.da5cf8e6.woff2) format("woff2");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Saira Condensed";font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/saira-condensed-latin-600.d20f5b8d.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Saira Condensed";font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/saira-condensed-latin-ext-600.0bf20d8a.woff2) format("woff2");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Saira Condensed";font-style:normal;font-weight:700;font-display:swap;src:url(/assets/fonts/saira-condensed-latin-700.eb1cf59a.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Saira Condensed";font-style:normal;font-weight:700;font-display:swap;src:url(/assets/fonts/saira-condensed-latin-ext-700.f15c9a22.woff2) format("woff2");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"IBM Plex Sans";font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/ibm-plex-sans-latin-400.3b646991.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"IBM Plex Sans";font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/ibm-plex-sans-latin-ext-400.c93d2a12.woff2) format("woff2");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"IBM Plex Sans";font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/ibm-plex-sans-latin-500.0717336f.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"IBM Plex Sans";font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/ibm-plex-sans-latin-ext-500.2846035d.woff2) format("woff2");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"IBM Plex Sans";font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/ibm-plex-sans-latin-600.8960851d.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"IBM Plex Sans";font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/ibm-plex-sans-latin-ext-600.b25dfd4f.woff2) format("woff2");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/ibm-plex-mono-latin-400.08949f72.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/ibm-plex-mono-latin-ext-400.6bc0f226.woff2) format("woff2");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/ibm-plex-mono-latin-500.01d28544.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/ibm-plex-mono-latin-ext-500.6bb06407.woff2) format("woff2");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
/* Optic Mounting — shared stylesheet for generated pages.
   Same design system as the interactive tool: cool industrial neutrals,
   blueprint accent, Saira Condensed / IBM Plex pairing. 2.0 (2026-09-23) adds
   the always-dark header, hero and footer bands, card grids, larger radii and
   a deeper dark theme; the design system artifact is the reference for it. */
:root{
  --ground:#EBEEF0; --surface:#FBFCFD; --surface-2:#DFE4E8; --inset:#E4E8EB;
  --line:#C4CCD3; --line-soft:#D8DEE3;
  --ink:#14181C; --ink-2:#4B5661; --ink-3:#5B656F;
  --accent:#1A5478; --accent-soft:#D3E2EC; --on-accent:#FBFCFD;
  --ok:#2A6B4C; --ok-soft:#D1E5D9; --ok-edge:#5D9E7C;
  --warn:#845513; --warn-soft:#F0E3C6; --warn-edge:#C08F3C;
  --bad:#8E312A; --bad-soft:#EED7D4; --bad-edge:#C0645C;
  --flag:#5B4A86; --flag-soft:#E0DBEE;
  --shadow:0 1px 1px rgba(16,24,32,.05), 0 10px 26px -18px rgba(16,24,32,.45);
  --shadow-lift:0 1px 2px rgba(16,24,32,.06), 0 14px 30px -16px rgba(16,24,32,.38);
  /* the header, hero and footer bands: dark in every theme, so these do not
     change with it. band-accent is the light blue — the dark accent is
     illegible on the band. */
  --band:#12171C; --band-2:#1A2128; --band-line:#2C353E;
  --band-ink:#EEF2F5; --band-ink-2:#A9B4BE; --band-accent:#7CB4D9; --on-band-accent:#0E1215;
  --mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  --sans:"IBM Plex Sans",system-ui,-apple-system,Segoe UI,sans-serif;
  --disp:"Saira Condensed","Arial Narrow",system-ui,sans-serif;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --ground:#0B0D10; --surface:#14181C; --surface-2:#1D2329; --inset:#101317;
    --line:#2B333B; --line-soft:#1C2228;
    --ink:#E4EAEF; --ink-2:#9AA6B1; --ink-3:#85919C;
    --accent:#7CB4D9; --accent-soft:#1B2E3C; --on-accent:#0E1215;
    --ok:#74C098; --ok-soft:#17291F; --ok-edge:#33613F;
    --warn:#D9A65E; --warn-soft:#2B2317; --warn-edge:#6B5226;
    --bad:#E19189; --bad-soft:#2C1D1B; --bad-edge:#6E3B36;
    --flag:#A99BD6; --flag-soft:#211E30;
    --shadow:0 1px 1px rgba(0,0,0,.4), 0 10px 26px -18px rgba(0,0,0,.8);
    --shadow-lift:0 1px 2px rgba(0,0,0,.5), 0 16px 34px -16px rgba(0,0,0,.9);
  }
}
:root[data-theme="dark"]{
  --ground:#0B0D10; --surface:#14181C; --surface-2:#1D2329; --inset:#101317;
  --line:#2B333B; --line-soft:#1C2228;
  --ink:#E4EAEF; --ink-2:#9AA6B1; --ink-3:#85919C;
  --accent:#7CB4D9; --accent-soft:#1B2E3C; --on-accent:#0E1215;
  --ok:#74C098; --ok-soft:#17291F; --ok-edge:#33613F;
  --warn:#D9A65E; --warn-soft:#2B2317; --warn-edge:#6B5226;
  --bad:#E19189; --bad-soft:#2C1D1B; --bad-edge:#6E3B36;
  --flag:#A99BD6; --flag-soft:#211E30;
  --shadow:0 1px 1px rgba(0,0,0,.4), 0 10px 26px -18px rgba(0,0,0,.8);
  --shadow-lift:0 1px 2px rgba(0,0,0,.5), 0 16px 34px -16px rgba(0,0,0,.9);
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--ground); color:var(--ink);
  font-family:var(--sans); font-size:16px; line-height:1.55;
  -webkit-font-smoothing:antialiased;
}
.wrap{max-width:1000px; margin:0 auto; padding-inline:16px; padding-block:0 56px}
/* grid pages — home, and anything laid out as cards — use the header's width */
.wrap-wide{max-width:1200px; margin:0 auto; padding-inline:16px; padding-block:0 56px}
@media (min-width:900px){ .wrap, .wrap-wide{padding-inline:24px} }
img{max-width:100%}
a{color:var(--accent)}
a:focus-visible,button:focus-visible{outline:2px solid var(--accent); outline-offset:2px}

/* ── site header ─────────────────────────────────────────────────────────
   An always-dark band on every page: the mark and name, one search field
   over every pistol and optic, the fit checker, and a bar of sections. The
   3px rule on top is the old masthead's three bands, kept. Sticky on a
   desktop, where it costs nothing; on a phone it scrolls away, because a
   header that tall would take a fifth of the screen for good. */
/* first thing a keyboard reaches: jumps past the header and its search */
.skip{position:absolute; left:-9999px; top:8px; z-index:100; padding:8px 12px; border-radius:6px;
  background:var(--band-accent); color:var(--on-band-accent); font-weight:600; text-decoration:none}
.skip:focus{left:16px}
.skip:focus-visible{outline:2px solid var(--band-ink); outline-offset:2px}
/* In the dark theme the ground is near-black too, so the bands lift a step
   to stay a separate layer (they measured 1.08:1 against the ground). */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){--band:#1A2027; --band-2:#222A32; --band-line:#36414B}
}
:root[data-theme="dark"]{--band:#1A2027; --band-2:#222A32; --band-line:#36414B}
.sh{position:sticky; top:0; z-index:50; background:var(--band); color:var(--band-ink)}
.sh::before{
  content:""; display:block; height:3px;
  background:linear-gradient(90deg,var(--band-accent) 0 38%,var(--warn-edge) 38% 62%,var(--ok-edge) 62% 100%);
}
html{scroll-padding-top:112px}
.vh{
  position:absolute; width:1px; height:1px; margin:-1px; padding:0; border:0;
  overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap;
}
.sh-in{max-width:1200px; margin:0 auto; padding-inline:16px; display:flex; align-items:center; gap:12px 24px}
@media (min-width:900px){ .sh-in{padding-inline:24px} }
.sh-top .sh-in{padding-block:12px}
.sh-brand{display:flex; align-items:center; gap:11px; color:var(--band-ink); text-decoration:none; flex:0 0 auto}
.sh-brand svg{width:36px; height:36px; color:var(--band-accent); flex:0 0 auto}
.sh-brand small{
  display:block; font-family:var(--disp); font-size:12px; font-weight:600; letter-spacing:.14em;
  text-transform:uppercase; color:var(--band-accent); margin-bottom:3px;
}
.sh-brand b{display:block; font-family:var(--disp); font-size:24px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; line-height:1}
.sh-search{position:relative; flex:1 1 360px; display:flex; max-width:640px; min-width:0; margin:0}
.sh-search input{
  flex:1; min-width:0; font-family:var(--sans); font-size:15px; color:var(--band-ink);
  background:var(--band-2); border:1px solid var(--band-line); border-right:0;
  border-radius:6px 0 0 6px; padding:10px 13px; appearance:none;
}
.sh-search input::placeholder{color:var(--band-ink-2)}
.sh-search input:focus-visible{outline:2px solid var(--band-accent); outline-offset:-1px}
.sh-search button{
  font-family:var(--disp); font-size:14px; font-weight:700; letter-spacing:.09em; text-transform:uppercase;
  background:var(--band-accent); color:var(--on-band-accent); border:0; cursor:pointer;
  border-radius:0 6px 6px 0; padding:0 20px;
}
.sh-search button:hover{background:var(--band-ink)}
/* the results: the combobox's own list, so they look like every other picker */
.sh-search .combo-list{color:var(--ink); right:auto; width:100%; max-width:520px}
.sh-search .combo-opt{display:flex; align-items:baseline; gap:8px}
.sh-search .combo-opt .ob{color:var(--ink-3); font-size:12.5px; white-space:nowrap}
.sh-search .combo-opt.is-active .ob{color:var(--on-accent); opacity:.8}
.sh-search .combo-go:not(.is-active){color:var(--accent); font-weight:500}
.sh-cta{
  margin-left:auto; font-family:var(--disp); font-size:13px; font-weight:700; letter-spacing:.09em;
  text-transform:uppercase; color:var(--band-ink); text-decoration:none; white-space:nowrap;
  border:1px solid var(--band-line); border-radius:6px; padding:9px 14px;
}
.sh-cta:hover{border-color:var(--band-accent); color:var(--band-accent)}
.sh-cats{background:var(--band-2); border-top:1px solid var(--band-line); border-bottom:1px solid var(--band-line)}
.sh-cats .sh-in{gap:0; overflow-x:auto; scrollbar-width:none}
/* on a narrow screen the bar scrolls; the fade at the right edge says so */
@media (max-width:760px){
  .sh-cats .sh-in{-webkit-mask-image:linear-gradient(to right,#000 82%,transparent); mask-image:linear-gradient(to right,#000 82%,transparent); padding-right:40px; scroll-snap-type:x proximity; scroll-padding-inline:16px}
  .sh-cats a{scroll-snap-align:start}
  /* search.js marks which edges have sections past them */
  .sh-cats .sh-in[data-more-l]{-webkit-mask-image:linear-gradient(to right,transparent,#000 14%,#000 86%,transparent); mask-image:linear-gradient(to right,transparent,#000 14%,#000 86%,transparent)}
  .sh-cats .sh-in[data-more-l]:not([data-more-r]){-webkit-mask-image:linear-gradient(to right,transparent,#000 14%); mask-image:linear-gradient(to right,transparent,#000 14%)}
}
.sh-cats a{
  font-family:var(--disp); font-size:13px; font-weight:600; letter-spacing:.08em; text-transform:uppercase;
  color:var(--band-ink-2); text-decoration:none; white-space:nowrap;
  padding:11px 14px 9px; border-bottom:2px solid transparent;
}
.sh-cats a:hover{color:var(--band-ink)}
.sh-cats a[aria-current]{color:var(--band-ink); border-bottom-color:var(--band-accent)}
.sh-meta{margin-left:auto; padding-left:16px; font-family:var(--mono); font-size:12px; color:var(--band-ink-2); white-space:nowrap}
.sh a:focus-visible, .sh button:focus-visible{outline:2px solid var(--band-accent); outline-offset:2px}
@media (max-width:760px){
  .sh{position:relative}
  html{scroll-padding-top:0}
  .sh-top .sh-in{flex-wrap:wrap}
  .sh-search{order:3; flex-basis:100%; max-width:none}
  .sh-brand b{font-size:20px}
  .sh-brand svg{width:30px; height:30px}
  .sh-meta{display:none}
}
/* A phone: the mark, the name and "Fit checker" on one row, the search under
   them. With the tagline over the name the three wrapped to three rows. */
@media (max-width:480px){
  .sh-top .sh-in{padding-block:10px; gap:10px 12px}
  .sh-brand small{display:none}
  .sh-brand{flex:1 1 auto; min-width:0}
  .sh-cta{padding:8px 12px}
}
/* The iPhone "add to home screen" hint, right under the header (build.mjs,
   INSTALL_HINT; assets/install.js shows it). In this section so the tool
   page, which takes the header's CSS from here, gets it too. Never printed. */
.a2hs{background:var(--accent-soft); color:var(--ink); border-bottom:1px solid var(--line)}
.a2hs .sh-in{padding-block:10px; gap:12px}
.a2hs p{margin:0; flex:1; font-size:14px; line-height:1.5; color:var(--ink-2)}
.a2hs p b{color:var(--ink)}
.a2hs-k{font-weight:600; color:var(--ink); white-space:nowrap}
.a2hs-k svg{width:13px; height:16px; vertical-align:-2px; color:var(--accent)}
.a2hs-x{
  flex:0 0 auto; width:36px; height:36px; font-size:22px; line-height:1; cursor:pointer;
  background:none; border:1px solid transparent; border-radius:6px; color:var(--ink-2);
}
.a2hs-x:hover{color:var(--ink); border-color:var(--line)}
.a2hs-x:focus-visible{outline:2px solid var(--accent); outline-offset:2px}
@media print{ .a2hs{display:none !important} }

/* breadcrumb + headings */
.crumb{font-family:var(--mono); font-size:12px; color:var(--ink-3); margin-block:18px 0}
.asof{font-size:12.5px; color:var(--ink-3); margin:6px 0 0}
.crumb a{color:var(--ink-3)}
h1{
  font-family:var(--disp); font-weight:700; font-size:clamp(28px,5.4vw,40px);
  letter-spacing:.01em; line-height:1.08; margin:10px 0 0; text-wrap:balance;
}
h2{
  font-family:var(--disp); font-size:27px; line-height:1.15; font-weight:700; letter-spacing:.01em;
  margin:40px 0 0;
}
h3{font-family:var(--disp); font-size:19px; font-weight:700; letter-spacing:.01em; margin:26px 0 8px}
/* a maker's group on an index page: an h2 for the outline, sized as a label */
/* the indexes: an A-Z bar of makers, then makers as cards in columns */
.azbar{display:flex; flex-wrap:wrap; gap:4px 6px; margin:14px 0 6px; padding:8px 0; background:var(--ground)}
.azbar a{font-family:var(--disp); font-size:12px; font-weight:600; letter-spacing:.06em; text-transform:uppercase;
  padding:4px 8px; min-height:28px; display:inline-flex; align-items:center; border:1px solid var(--line); border-radius:6px;
  background:var(--surface); color:var(--ink-2); text-decoration:none}
.azbar a:hover{border-color:var(--accent); color:var(--accent)}
.bgrid{columns:340px; column-gap:28px; margin-top:10px}
.bcard{break-inside:avoid; margin:0 0 24px; scroll-margin-top:60px}
.bcard[hidden]{display:none}
.bcard h2.grp{margin:0 0 8px}
.blist li[hidden], .blist[hidden]{display:none}
/* a directory has hundreds of rows, so its rows are one line: the bar sits
   beside the counts instead of under them */
.blist .rrow{grid-template-columns:minmax(0,1fr) auto auto 64px; gap:0 10px; align-items:center; padding:8px 12px}
.blist .rr-n{font-size:15px}
.blist .rr-bar{grid-column:auto; width:64px}
h2.grp{font-family:var(--disp); font-size:19px; font-weight:700; letter-spacing:.01em; margin:26px 0 10px}
.tlist{margin-top:0}
.tlist li[hidden]{display:none}
/* /fit/: one row per pairing, the verdict lined up on the right */
.flist{list-style:none; margin:0; padding:0; display:grid; grid-template-columns:repeat(auto-fill,minmax(250px,1fr)); gap:0 18px}
.flist a{display:flex; align-items:center; justify-content:space-between; gap:10px; padding:7px 2px;
  border-bottom:1px solid var(--line-soft); color:var(--ink); text-decoration:none; font-size:14px}
.flist a:hover span:first-child{color:var(--accent); text-decoration:underline}
.flist .chip{flex:none; font-size:12px; padding:1px 6px}
.flist li[hidden], ul.flist[hidden]{display:none}
.every-none{margin-top:26px}
.incl{padding-left:20px; max-width:72ch}
.incl li{margin:6px 0}
.every-none summary{cursor:pointer; font-family:var(--disp); font-size:19px; font-weight:700; letter-spacing:.01em}
/* /footprints/: the chart */
.fpchart .fpc{display:flex; align-items:center; gap:12px; color:var(--ink); text-decoration:none}
.fpchart .fpc:hover b{color:var(--accent); text-decoration:underline}
.fpc-d svg{display:block; width:64px; height:auto}
.fpc-aka{display:block; font-size:12.5px; color:var(--ink-3); line-height:1.35}
@media (max-width:640px){
  .fpchart thead{display:none}
  .fpchart tr{display:grid; grid-template-columns:repeat(3,auto); gap:4px 14px; padding:12px 0; border-bottom:1px solid var(--line-soft)}
  .fpchart td{border:0; padding:0}
  .fpchart td:first-child{grid-column:1 / -1}
  .fpchart td:nth-child(n+4)::before{content:attr(data-l); display:block; font-size:12.5px; font-weight:600; color:var(--ink-2)}
}
/* the glossary on /guides/#terms, and the one line that links to it */
.terms-link{margin:14px 0 0; font-size:14px; color:var(--ink-2)}
.terms-dl{display:grid; grid-template-columns:minmax(140px,max-content) 1fr; gap:8px 18px; margin:12px 0 0; font-size:14.5px}
.terms-dl dt{font-weight:600}
.terms-dl dd{margin:0; color:var(--ink-2)}
@media (max-width:560px){ .terms-dl{grid-template-columns:1fr; gap:2px} .terms-dl dd{margin-bottom:10px} }
.lede{font-size:16px; color:var(--ink-2); max-width:70ch; margin:14px 0 0; line-height:1.6}
p{max-width:72ch}

/* fact row: ruled, not boxed. A 2px rule above, a hairline under each cell, the
   label above its value. On a pistol or optic page its first cell is the reach
   bar (below), and the cells that share its colours carry a dot. */
.facts{
  /* wrapping flex, not a grid: the cells on a short last row stretch to fill
     it, instead of one cell sitting alone beside empty columns */
  display:flex; flex-wrap:wrap; gap:0 28px; margin-top:22px; border-top:2px solid var(--line);
}
.facts > div{flex:1 1 150px; min-width:0}
.facts > div.wide{flex-basis:100%}
.facts > div{padding:12px 0 12px; border-bottom:1px solid var(--line-soft)}
.facts > .reach{padding:14px 0 10px}
.facts .reach .rr-bar{height:8px}
.facts .reach .rkey{margin:8px 0 0}
.facts .rkey span{font-family:var(--sans); font-size:12.5px}
.facts .rr-free b::before, .facts .rr-plate b::before{
  content:""; display:inline-block; width:8px; height:8px; margin-right:6px; border-radius:50%; background:var(--ok);
}
.facts .rr-plate b::before{background:var(--warn)}
.facts b{
  font-family:var(--sans); font-size:13px; font-weight:600; letter-spacing:0; color:var(--ink-2); display:block; margin-bottom:2px;
}
.facts span{font-family:var(--mono); font-size:13px; overflow-wrap:anywhere}
table.grid.sib tr.me, table.grid.sib tr.me td{background:var(--accent-soft)}
table.grid.sib td{font-size:13px}
/* on a phone each optic is a card: name across the top, its specs two-up, labelled */
@media (max-width:600px){
  table.grid.sib thead th{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0)}
  table.grid.sib tr{display:grid; grid-template-columns:1fr 1fr; gap:4px 14px; padding:10px 12px; border-bottom:1px solid var(--line-soft)}
  table.grid.sib td{border:0; padding:0}
  table.grid.sib td:first-child{grid-column:1 / -1}
  table.grid.sib td[data-l]::before{content:attr(data-l); display:block; font-size:12.5px; font-weight:600; color:var(--ink-2)}
}
.pl-note{display:block; margin-top:3px; font-size:13px; color:var(--ink-2); line-height:1.45}
.facts-cap{margin:8px 0 0; font-size:12.5px; line-height:1.5; color:var(--ink-3); max-width:72ch}
.facts-cap b{color:var(--ink-2); font-weight:600}
/* a count that opens the table filtered to it: a tap target, not just a digit */
.facts span.txt{font-family:var(--sans); font-size:14px; line-height:1.5}
.facts a[data-filter]{display:inline-block; min-width:24px; padding:3px 0}
/* on a phone: one row per fact, label left and value right, so a long value
   gets the width instead of wrapping a word per line */
@media (max-width:600px){
  .facts > div{flex-basis:100%}
  .facts > div{display:flex; align-items:baseline; justify-content:space-between; gap:14px;
    padding:9px 0}
  .facts > .reach{display:block}
  .facts b{flex:none; margin:0}
  .facts span{text-align:right}
}

/* ── the home page's primary action ─────────────────────────────────────
   Two grouped selects in a GET form, upgraded to searchable comboboxes by
   pick.js. Sized so the two fields and the button sit on one line at desktop
   width and stack cleanly on a phone. */
.find{
  margin:22px 0 0; padding:16px 18px 14px; background:var(--surface);
  border:1px solid var(--line); border-top:3px solid var(--accent); border-radius:10px;
  box-shadow:var(--shadow);
}
.find-row{display:grid; grid-template-columns:1fr 1fr auto; gap:12px; align-items:end}
@media (max-width:760px){ .find-row{grid-template-columns:1fr} }
.find .field{display:flex; flex-direction:column; gap:6px; min-width:0}
.find label{
  font-family:var(--sans); font-size:13px; font-weight:600; letter-spacing:0; color:var(--ink-2);
}
.find label .opt{
  font-family:var(--sans); font-size:12px; letter-spacing:0; text-transform:none;
  color:var(--ink-3); opacity:.8;
}
.find select{
  font-family:var(--sans); font-size:15px; color:var(--ink); background-color:var(--surface);
  border:1px solid var(--line); border-radius:6px; padding:10px 34px 10px 11px;
  width:100%; appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,var(--ink-3) 50%),linear-gradient(135deg,var(--ink-3) 50%,transparent 50%);
  background-position:calc(100% - 17px) 50%, calc(100% - 12px) 50%;
  background-size:5px 5px, 5px 5px; background-repeat:no-repeat;
}
.find select:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
.find .go{
  font-family:var(--disp); font-size:14px; font-weight:700; letter-spacing:.09em;
  text-transform:uppercase; background:var(--accent); color:var(--on-accent);
  border:1px solid var(--accent); border-radius:6px; padding:11px 20px; cursor:pointer;
  white-space:nowrap;
}
.find .go:hover{background:var(--ink); border-color:var(--ink); color:var(--surface)}
.find-hint{margin:11px 0 0; font-size:12.5px; color:var(--ink-3); line-height:1.5; max-width:76ch}
.find-hint #find-msg{color:var(--bad); font-weight:500}

/* the combobox, once pick.js has upgraded a select. Same visual language as
   the tool's own pickers — the two are the same code. */
.combo{position:relative; min-width:0}
.combo-input{
  /* the tool's own pickers are on the surface colour; a grey fill read as disabled */
  font-family:var(--sans); font-size:15px; color:var(--ink); background:var(--surface);
  border:1px solid var(--line); border-radius:6px; padding:10px 34px 10px 11px;
  width:100%; appearance:none;
}
.combo-input::placeholder{color:var(--ink-3)}
.combo-input:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
.combo-caret{
  position:absolute; right:12px; top:50%; margin-top:-2px; pointer-events:none;
  width:0; height:0; border-left:4.5px solid transparent; border-right:4.5px solid transparent;
  border-top:5px solid var(--ink-3);
}
.combo[data-open="1"] .combo-caret{transform:rotate(180deg)}
.combo-list{
  position:absolute; z-index:40; top:calc(100% + 4px); left:0; right:0;
  margin:0; padding:4px; list-style:none; max-height:320px; overflow-y:auto;
  background:var(--surface); color:var(--ink); border:1px solid var(--line); border-radius:8px;
  box-shadow:0 2px 4px rgba(16,24,32,.08), 0 14px 34px -14px rgba(16,24,32,.45);
  overscroll-behavior:contain;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .combo-list{box-shadow:0 2px 4px rgba(0,0,0,.4), 0 14px 34px -14px rgba(0,0,0,.85)}
}
:root[data-theme="dark"] .combo-list{box-shadow:0 2px 4px rgba(0,0,0,.4), 0 14px 34px -14px rgba(0,0,0,.85)}
.combo-group{
  font-family:var(--sans); font-size:13px; font-weight:600; letter-spacing:0; color:var(--ink-2); padding:9px 9px 4px;
}
.combo-opt{padding:7px 9px; border-radius:4px; cursor:pointer; font-size:14.5px}
.combo-opt.combo-any{color:var(--ink-3); font-style:italic}
.combo-opt[aria-selected="true"]{font-weight:600}
.combo-opt.is-active{background:var(--accent); color:var(--on-accent)}
.combo-opt.is-active.combo-any{color:var(--on-accent)}
.combo-empty{padding:12px 9px; font-size:13.5px; color:var(--ink-3)}
/* how the chosen pistol takes this optic — home page only */
.combo-opt .chip{float:right; margin:1px 0 0 10px; font-size:12px; padding:1px 6px; font-style:normal}
.find-fit{margin:6px 0 0; font-size:13px; color:var(--ink-2); line-height:1.5; max-width:76ch}
.find-fit[hidden]{display:none}
.combo-count{
  padding:7px 9px 4px; font-family:var(--mono); font-size:12px; color:var(--ink-3);
  border-top:1px solid var(--line-soft); margin-top:4px;
}

/* route cards */
.routes{display:grid; grid-template-columns:repeat(auto-fit,minmax(210px,1fr)); gap:12px; margin-top:18px}
.route{
  background:var(--surface); border:1px solid var(--line); border-top:3px solid var(--accent);
  border-radius:8px; padding:12px 14px 13px;
}
.route.is-direct{border-top-color:var(--ok-edge)}
.route.is-enc, .route.is-buy{border-top-color:var(--warn-edge)}
.route b{
  font-family:var(--sans); font-size:13px; font-weight:600; letter-spacing:0; color:var(--ink-2); display:block;
}
.route .p{font-family:var(--mono); font-size:19px; font-variant-numeric:tabular-nums; display:block; margin:2px 0 1px}
.route .w{font-size:13.5px; display:block; line-height:1.35}
.route .h{font-family:var(--mono); font-size:12px; color:var(--ink-3); display:block; line-height:1.4; margin-top:2px}
.route .go{display:block; margin-top:8px; font-size:13.5px; font-weight:600}
.route .go a{text-decoration:none}
.route .go a:hover{text-decoration:underline}
/* optic pages: the other slides that share the card's answer */
.route .more{display:block; margin-top:6px; font-size:12.5px; line-height:1.4; color:var(--ink-2)}

/* ── table controls ─────────────────────────────────────────────────────
   Hidden in the HTML and revealed by table.js, so the no-JS reader never
   sees a control that would not work. Four axes, each labelled — the same
   rule the tool follows: controls are not clutter, undifferentiated data is. */
.tfilter{
  margin:16px 0 0; padding:12px 14px 10px; background:var(--inset);
  border:1px solid var(--line-soft); border-radius:8px;
}
.tf-row{display:grid; grid-template-columns:1.4fr 1fr 1fr 1fr; gap:10px 12px}
.has-fp .tf-row{grid-template-columns:1.3fr 1fr 1.1fr 1fr 1fr}
@media (max-width:980px){ .has-fp .tf-row{grid-template-columns:1fr 1fr 1fr} }
@media (max-width:820px){ .tf-row, .has-fp .tf-row{grid-template-columns:1fr 1fr} }
@media (max-width:360px){ .tf-row, .has-fp .tf-row{grid-template-columns:1fr} }
.tfilter .field{display:flex; flex-direction:column; gap:5px; min-width:0}
.tfilter label{
  font-family:var(--sans); font-size:13px; font-weight:600; letter-spacing:0; color:var(--ink-2);
}
.tfilter input, .tfilter select{
  font-family:var(--sans); font-size:14px; color:var(--ink); background:var(--surface);
  border:1px solid var(--line); border-radius:6px; padding:8px 10px; width:100%; appearance:none;
}
.tfilter select{
  padding-right:30px;
  background-image:linear-gradient(45deg,transparent 50%,var(--ink-3) 50%),linear-gradient(135deg,var(--ink-3) 50%,transparent 50%);
  background-position:calc(100% - 15px) 50%, calc(100% - 10px) 50%;
  background-size:5px 5px, 5px 5px; background-repeat:no-repeat;
}
.tfilter input:focus-visible, .tfilter select:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
.tf-foot{
  margin:10px 0 0; display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  font-family:var(--mono); font-size:12px; color:var(--ink-3);
}
.tf-reset{
  font-family:var(--disp); font-size:12px; font-weight:600; letter-spacing:.09em;
  text-transform:uppercase; background:var(--surface); color:var(--ink-2);
  border:1px solid var(--line); border-radius:4px; padding:4px 10px; cursor:pointer;
}
.tf-reset:hover{color:var(--ink); border-color:var(--accent)}
.tfilter[hidden]{display:none}
/* what the table is filtered to, in words — for print, where the controls are gone */
.tf-said{display:none}

/* ── the compatibility table on a phone ─────────────────────────────────
   Four columns do not fit in 390px, and the one that fell off the right
   edge was cost — the column the sort and budget controls exist for. Below
   560px each row becomes a small card: name and cost on the first line,
   footprint (or mount system) and how it mounts beneath. Same cells, same
   order in the markup; only the layout changes. The column headings are
   hidden from sight but not from a screen reader, which still announces
   "Cost to mount" on the cost cell — display:none would have taken them out
   of the table altogether. build.mjs puts explicit roles on the table's parts
   so that changing their display cannot strip the table semantics either. */
@media (max-width:560px){
  [data-filterable] table.grid thead{
    position:absolute; width:1px; height:1px; margin:-1px; padding:0; border:0;
    overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap;
  }
  [data-filterable] table.grid tr[data-t]{
    display:grid; grid-template-columns:1fr auto; gap:3px 12px;
    padding:10px 12px; border-bottom:1px solid var(--line-soft);
  }
  /* the grid rule above outranks the plain tr[hidden] rule, so say it again */
  [data-filterable] table.grid tr[data-t][hidden]{display:none}
  [data-filterable] table.grid tr[data-t] td{padding:0; border:0}
  [data-filterable] table.grid tr[data-t] td:nth-child(1){grid-column:1; grid-row:1}
  /* the cost spans two lines so a "check price" link under it sits beside
     the footprint instead of pushing it down a line */
  [data-filterable] table.grid tr[data-t] td:nth-child(4){grid-column:2; grid-row:1 / span 2; text-align:right}
  [data-filterable] table.grid tr[data-t] td:nth-child(2){grid-column:1; grid-row:2; font-size:12px; color:var(--ink-3)}
  [data-filterable] table.grid tr[data-t] td:nth-child(3){grid-column:1 / -1; grid-row:3; font-size:12px}
  [data-filterable] table.grid th[colspan]{display:block}
  [data-filterable] .tw{overflow-x:visible}
}

/* the same idea on an index page, where there is one axis worth having */
.lfilter{
  margin:18px 0 6px; padding:12px 14px 10px; background:var(--inset);
  border:1px solid var(--line-soft); border-radius:8px; max-width:420px;
}
.lfilter[hidden]{display:none}
.lfilter .field{display:flex; flex-direction:column; gap:5px}
.lfilter label{
  font-family:var(--sans); font-size:13px; font-weight:600; letter-spacing:0; color:var(--ink-2);
}
.lfilter input{
  font-family:var(--sans); font-size:14px; color:var(--ink); background:var(--surface);
  border:1px solid var(--line); border-radius:6px; padding:8px 10px; width:100%;
}
.lfilter input:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
.lf-foot{
  margin:9px 0 0; display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  font-family:var(--mono); font-size:12px; color:var(--ink-3);
}
/* explicit, rather than trusting the UA rule: any heading here that later gains
   a display value of its own would otherwise quietly reappear over an empty list */
h2[hidden], h3[hidden], ul.pills[hidden], .pills li[hidden]{display:none}
tbody[hidden]{display:none}
tr[hidden]{display:none}

/* tables */
.tw{overflow-x:auto; margin-top:14px; border:1px solid var(--line); border-radius:8px; background:var(--surface)}
table.grid{width:100%; border-collapse:collapse; font-size:14px}
table.grid th{
  font-family:var(--sans); font-size:13px; letter-spacing:0;
  color:var(--ink-2); text-align:left; font-weight:600; padding:10px 12px 8px;
  border-bottom:1px solid var(--line); background:var(--inset); white-space:nowrap;
}
table.grid td{padding:9px 12px; border-bottom:1px solid var(--line-soft); vertical-align:top}
table.grid tr:last-child td{border-bottom:0}
table.grid td.mono{font-family:var(--mono); font-size:12.5px; color:var(--ink-2)}
table.grid td.num{font-family:var(--mono); font-size:12.5px; white-space:nowrap; font-variant-numeric:tabular-nums}
table.grid a{text-decoration:none; font-weight:500}
table.grid a:hover{text-decoration:underline}
/* "how it mounts" doubles as the link to that pairing's verdict — same weight
   and colour as the surrounding mono text, so the table stays a table */
table.grid a.pair{color:inherit; font-weight:inherit; border-bottom:1px dotted var(--line)}
table.grid a.pair:hover{color:var(--accent); text-decoration:none; border-bottom-color:var(--accent)}
/* the folded "no known route" group (table.js): its heading row stays, with
   the button that opens it; its rows come back in print */
@media screen{ [data-filterable] table.grid tr.folded{display:none !important} }
/* a long group's "Show all" row (table.js): a full-width button, not a card */
.tf-more-row td{padding:8px 0 !important; border:0 !important}
@media (max-width:560px){ .tf-more-row, .tf-more-row td{display:block} }
.tf-more-row td::before{content:none !important}
.tf-more{width:100%; min-height:44px; font:inherit; font-size:14px; font-weight:600; color:var(--accent);
  background:var(--surface); border:1px dashed var(--line); border-radius:6px; cursor:pointer}
.tf-more:hover{border-color:var(--accent); border-style:solid}
.tf-more:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
@media print{ .tf-more-row{display:none} }
.tf-fold{margin-left:10px; padding:4px 10px; min-height:28px; font:inherit; font-size:12px; font-weight:600;
  letter-spacing:.04em; text-transform:none; color:var(--accent); background:var(--surface);
  border:1px solid var(--line); border-radius:var(--r-sm, 6px); cursor:pointer}
.tf-fold:hover{border-color:var(--accent)}
.tf-fold:focus-visible{outline:2px solid var(--accent); outline-offset:1px}
/* "Build sheet →" under an item's name: straight to that pairing's build
   sheet, for the reader who has found the one they want and doesn't need its
   page first. Smaller and quieter than the name, so the name still reads as
   the row's label. */
table.grid a.to-build{
  /* 24px tall at least, the WCAG 2.5.8 target size: it repeats on every row */
  /* on the name's own line, so a row is one line tall, not two */
  display:inline-flex; align-items:center; min-height:24px; margin-left:10px; vertical-align:middle; font-family:var(--sans); font-size:13px; font-weight:600;
  color:var(--accent); white-space:nowrap;
}

/* affiliate links — visibly a different kind of link from a citation */
.blabel{
  font-family:var(--sans); font-size:13px; font-weight:600; letter-spacing:0; color:var(--ink-2); white-space:nowrap; margin-right:2px;
}
a.aff{
  font-family:var(--disp); font-size:12px; font-weight:600; letter-spacing:.09em; text-transform:uppercase;
  text-decoration:none; background:var(--accent); color:var(--on-accent); border:1px solid var(--accent);
  border-radius:4px; padding:2px 7px; white-space:nowrap; display:inline-block; margin:2px 0;
}
a.aff:hover{background:var(--ink); border-color:var(--ink); color:var(--surface)}
a.aff-sm{
  font-family:var(--disp); font-size:12px; font-weight:600; letter-spacing:.08em; text-transform:uppercase;
  text-decoration:none; color:var(--accent); white-space:nowrap;
}
a.aff-sm:hover{text-decoration:underline}
.buyline{display:flex; flex-wrap:wrap; align-items:center; gap:6px 8px}
.disc-inline{font-size:12.5px; color:var(--ink-3); line-height:1.5; margin:12px 0 0; max-width:76ch}
.disc-inline b{color:var(--ink-2)}

.chip{
  font-family:var(--sans); font-size:12.5px; font-weight:600; letter-spacing:0;
  padding:3px 9px; border-radius:4px; border:1px solid transparent;
  white-space:nowrap; display:inline-block;
}
.chip-ok{background:var(--ok-soft); color:var(--ok); border-color:var(--ok-edge)}
.chip-plate{background:var(--warn-soft); color:var(--warn); border-color:var(--warn-edge)}
.chip-none{background:var(--bad-soft); color:var(--bad); border-color:var(--bad-edge)}
.chip-flag{background:var(--flag-soft); color:var(--flag); border-color:var(--flag)}
.chip-enc{background:var(--accent-soft); color:var(--accent); border-color:var(--accent)}

/* callouts */
/* A note that explains is ruled, not boxed: several stack on a page and a box
   each would give every one the same weight. The box, with its red edge, is
   kept for the ones that warn — a verify flag, a thread trap — so they are the
   only boxes on the page. */
.note{
  margin-top:20px; padding:9px 0 2px; border-top:2px solid var(--line);
  font-size:14.5px; color:var(--ink-2); line-height:1.55;
}
.note b{
  font-family:var(--sans); font-size:14.5px; font-weight:600;
  color:var(--ink); display:block; margin-bottom:3px;
}
.note.warn{
  background:var(--surface); border:1px solid var(--line); border-left:3px solid var(--bad-edge);
  border-radius:4px; padding:13px 15px; font-size:14px;
}
.note.warn b{color:var(--bad); font-size:14px; margin-bottom:4px}

/* #14: maker-published co-witness data — collapsed list, attributed lines */
.cwd{margin-top:16px; border:1px solid var(--line); border-radius:4px; background:var(--surface); padding:0 15px}
.cwd summary{cursor:pointer; padding:12px 0; font-weight:600; color:var(--ink)}
.cwd[open] summary{border-bottom:1px solid var(--line)}
.cwl{margin:10px 0 0}
.cwl dt{margin-top:10px; font-weight:600}
.cwl dd{margin:0}
.cw-list{margin:3px 0 0; padding-left:18px; font-size:13.5px; color:var(--ink-2)}
.cw-list li{margin:2px 0}
.cw-list b{display:inline; font:inherit; font-weight:600; letter-spacing:0; text-transform:none; margin:0; color:var(--ink)}
.cw-foot{display:block; margin:10px 0 0; font-size:12.5px; color:var(--ink-3)}
.cw-src{display:flex; flex-wrap:wrap; gap:6px; margin:8px 0 12px}
.cw-src .ext{white-space:normal}
/* A source pill in running text (a slide's thread source, a plate's source) can be
   wider than a phone: "Canik OEM M4 optic screws (Midwest Gun Works)" is. Let it wrap. */
.src .ext{white-space:normal}

/* footprint diagram */

/* link lists */
.pills{display:flex; flex-wrap:wrap; gap:7px; margin-top:12px; padding:0; list-style:none}
.pills a{
  font-size:13.5px; text-decoration:none; background:var(--surface);
  border:1px solid var(--line); border-radius:4px; padding:5px 10px; display:block;
}
.pills a:hover{border-color:var(--accent)}
.pills .b{color:var(--ink-3); font-size:12px}
/* how a pair mounts, on a pill that links to its page (/fit/, the home page) */
.tgroups{margin-top:6px}
.tgroup{margin-top:14px}
.tg-h{display:flex; align-items:center; gap:8px; margin:0}
.tg-h + .pills{margin-top:8px}
.pills .chip{margin-left:4px; font-size:12px; padding:1px 6px; vertical-align:1px}
/* "every optic on this pistol →" under a list that shows only some of them */
.more{margin:10px 0 0; font-size:13.5px}
.more a{text-decoration:none; font-weight:500}
.more a:hover{text-decoration:underline}

/* ad slot — renders only when a snippet is configured */
.adslot{margin-top:32px; text-align:center}
.adslot .lbl{
  font-family:var(--sans); font-size:12.5px; color:var(--ink-3); display:block; margin-bottom:6px;
}

/* ── site footer ─────────────────────────────────────────────────────────
   The same band as the header. The legal paragraphs are audited on every
   page (audit-legal.mjs): they move here word for word, never reworded. */
.sf{margin-top:48px; background:var(--band); color:var(--band-ink-2); border-top:1px solid var(--band-line)}
.sf-in{max-width:1200px; margin:0 auto; padding:36px 16px 28px}
@media (min-width:900px){ .sf-in{padding-inline:24px} }
.sf-cols{display:grid; grid-template-columns:1.4fr repeat(3,1fr); gap:28px}
.sf-brand{display:flex; gap:11px; align-items:flex-start; color:var(--band-ink)}
.sf-brand svg{width:32px; height:32px; color:var(--band-accent); flex:0 0 auto}
.sf-brand b{display:block; font-family:var(--disp); font-size:20px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; line-height:1}
.sf-brand p{margin:8px 0 0; font-size:13px; line-height:1.55; color:var(--band-ink-2); max-width:34ch}
.sf-h{
  margin:0 0 10px; font-family:var(--sans); font-size:14px; line-height:1.4; font-weight:600;
  letter-spacing:0; color:var(--band-ink);
}
.sf nav a{display:block; padding:3px 0; font-size:13.5px; color:var(--band-ink-2); text-decoration:none}
.sf nav a:hover{color:var(--band-ink); text-decoration:underline}
.sf a:focus-visible{outline:2px solid var(--band-accent); outline-offset:2px}
.sf-legal{margin-top:28px; padding-top:18px; border-top:1px solid var(--band-line); font-size:12.5px; line-height:1.6}
.sf-legal p{margin:0 0 9px; max-width:96ch}
.sf-legal b{color:var(--band-ink)}
.sf-legal a{color:var(--band-ink)}
/* the Verify chip in the first paragraph, legible on the band */
.sf-legal .chip-flag{background:transparent; color:var(--band-ink); border-color:var(--band-ink-2)}
@media (max-width:820px){ .sf-cols{grid-template-columns:1fr 1fr} .sf-brand{grid-column:1 / -1} }

.stamp{font-family:var(--mono); font-size:12px}
@media (prefers-reduced-motion:reduce){*{animation:none!important; transition:none!important}}

/* ── contact form ─────────────────────────────────────────────────────── */
.cform{max-width:62ch}
.cform .fld{margin:0 0 18px}
.cform label{display:block;font-weight:600;font-size:.94rem;margin:0 0 6px}
.cform .hint{display:block;font-weight:400;color:var(--ink-2);font-size:.86rem;margin:2px 0 0}
.cform input[type=text],.cform input[type=email],.cform input[type=url],
.cform select,.cform textarea{
  width:100%;box-sizing:border-box;font:inherit;font-size:.96rem;color:var(--ink);
  background:var(--surface);border:1px solid var(--line);border-radius:7px;
  padding:9px 11px;transition:border-color .12s,box-shadow .12s}
.cform textarea{min-height:8.5em;resize:vertical;line-height:1.5}
.cform input:focus-visible,.cform select:focus-visible,.cform textarea:focus-visible{
  outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.cform input:invalid:not(:placeholder-shown){border-color:var(--bad-edge)}
.cform .req{color:var(--bad);font-weight:400}
.cform .check{display:flex;gap:9px;align-items:flex-start}
.cform .check input{width:auto;margin:3px 0 0;flex:0 0 auto}
.cform .check label{font-weight:400;margin:0}
.cform .trap{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.cform button{font:inherit;font-weight:600;font-size:.98rem;cursor:pointer;
  color:var(--on-accent);background:var(--accent);border:1px solid var(--accent);
  border-radius:7px;padding:10px 20px}
.cform button:hover{filter:brightness(1.08)}
.cform button:disabled{opacity:.55;cursor:default;filter:none}
.cform .cf-turnstile{margin:0 0 18px;min-height:65px}
.cform .sending{color:var(--ink-2);font-size:.9rem;margin-left:12px}
.cstat{margin:18px 0 0;padding:13px 15px;border-radius:8px;border:1px solid;font-size:.95rem}
.cstat.ok{background:var(--ok-soft);border-color:var(--ok-edge);color:var(--ok)}
.cstat.bad{background:var(--bad-soft);border-color:var(--bad-edge);color:var(--bad)}
.cstat b{display:block;margin:0 0 3px}
.creason{border:1px solid var(--line-soft);border-radius:9px;background:var(--inset);
  padding:16px 16px 0;margin:0 0 18px}
.creason[hidden]{display:none}
.cways{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));margin:20px 0 26px}
.cway{border:1px solid var(--line);border-radius:9px;background:var(--surface);padding:14px 15px}
.cway b{display:block;font-family:var(--disp);font-size:1.06rem;letter-spacing:.01em}
.cway p{margin:5px 0 0;font-size:.9rem;color:var(--ink-2)}
.cway a{font-family:var(--mono);font-size:.88rem;word-break:break-all}
.report{margin:26px 0 0;padding:13px 15px;border-radius:8px;
  border:1px dashed var(--line);background:var(--inset);font-size:.93rem;color:var(--ink-2)}
.report a{font-weight:600}

/* ── comments (on /contact/) ──────────────────────────────────────────────
   Readers' words, set apart from the data: plain surface cards, no semantic
   colour (on this site a colour is a claim), and text kept as text —
   pre-line keeps a reader's line breaks without any markup. */
.comments{margin-top:40px;padding-top:6px;border-top:1px solid var(--line)}
.comments h3{margin:26px 0 12px}
.klist{max-width:72ch}
.kcom{border:1px solid var(--line);border-radius:9px;background:var(--surface);padding:13px 15px;margin:0 0 12px}
.kmeta{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 12px;margin:0 0 6px}
.kmeta b{font-weight:600;overflow-wrap:anywhere}
.kmeta time{font-family:var(--mono);font-size:12px;color:var(--ink-3)}
.kbody{margin:0;white-space:pre-line;overflow-wrap:anywhere}
.kreply{margin:11px 0 0;padding:10px 12px;border-left:3px solid var(--accent);background:var(--inset);border-radius:0 7px 7px 0}
.kreply b{display:block;font-size:.88rem;margin:0 0 3px}
.kempty{color:var(--ink-2);font-style:italic}
.kmore{font:inherit;font-weight:600;font-size:.94rem;cursor:pointer;color:var(--accent);background:none;
  border:1px solid var(--line);border-radius:7px;padding:8px 16px}
.kmore:disabled{opacity:.55;cursor:default}

/* ── home: the hero ──────────────────────────────────────────────────────
   The header's band carried on down: the question, the finder, the site's
   own footprint schematics (never a photograph — brand-and-legal.md), and the
   counts. The finder keeps its light panel, so the one thing to do is the
   brightest thing on the page. */
.hero{background:var(--band); color:var(--band-ink)}
.hero-terms{margin:12px 0 0; font-size:14px; color:var(--band-ink-2)}
.hero-terms a{color:var(--band-accent)}
.hero-terms + .hero-terms{margin-top:4px}
.hero-in{max-width:1200px; margin:0 auto; padding-inline:16px}
@media (min-width:900px){ .hero-in{padding-inline:24px} }
.hero-main{display:grid; grid-template-columns:minmax(0,1.3fr) minmax(0,1fr); gap:40px; align-items:center; padding-block:30px 34px}
.hero h1{
  margin:0; font-size:clamp(34px,5.8vw,60px); line-height:1.02; letter-spacing:.005em;
  color:var(--band-ink);
}
.hero .find{margin-top:20px; border:1px solid var(--band-line); border-top:3px solid var(--band-accent); box-shadow:none}

/* the stage: the optic's footprint, drawn large, with its figures beside it.
   Every mark is a number from the footprint's own data (assets/stage.js). It
   stays in the band's colours, so it needs nothing for the dark theme. */
.stage{
  margin:0; align-self:stretch; display:flex; flex-direction:column;
  border:1px solid var(--band-line); border-radius:10px; background:var(--band-2); padding:20px 24px 20px;
}
.st-draw{flex:1; display:flex; align-items:center; justify-content:center; min-height:0}
.stage[data-kind="sys"] .st-draw{flex-direction:column; align-items:stretch; justify-content:flex-start; overflow:auto}
.st-svg{display:block; width:100%; height:clamp(190px,15vw,220px)}
.st-plate{fill:var(--band); stroke:var(--band-ink-2); stroke-opacity:.55; stroke-width:1.4}
.st-lug{fill:var(--band-2); stroke:var(--band-ink-2); stroke-width:1.5}
.st-screw{fill:var(--band); stroke:var(--band-accent); stroke-width:2}
.st-x{stroke:var(--band-accent); stroke-width:1.5}
.st-acc{fill:var(--band); stroke:var(--band-accent); stroke-width:1.6}
.st-dim{stroke:var(--band-ink-2); stroke-width:.8; fill:none}
.st-ext{stroke-dasharray:2 2}
.st-lbl,.st-front{fill:var(--band-ink-2); font-family:var(--mono); font-size:9px}
.st-dimt{fill:var(--band-ink); font-family:var(--mono); font-size:10.5px}
.st-cap{margin-top:14px; display:block}
.st-title{display:block; font-family:var(--disp); font-size:25px; font-weight:700; line-height:1.15; letter-spacing:.02em; color:var(--band-ink); text-decoration:none}
a.st-title:hover{text-decoration:underline; text-decoration-color:var(--band-line); text-underline-offset:4px}
a.st-title:focus-visible{outline:2px solid var(--band-accent); outline-offset:3px; border-radius:3px}
.st-aka,.st-hint{display:block; margin-top:3px; font-size:14px; line-height:1.5; color:var(--band-ink-2)}
.st-hint{margin-top:8px}
.st-facts{margin:12px 0 0; display:grid; grid-template-columns:auto minmax(0,1fr); gap:5px 18px; font-size:14px; line-height:1.45}
.st-facts dt{color:var(--band-ink-2)}
.st-facts dd{margin:0; color:var(--band-ink)}
.st-facts dd.v{font-family:var(--mono); font-size:13px}
/* a pistol chosen alone: the footprints its slide takes, each a small drawing */
.st-set{width:100%}
.st-group{margin:0 0 12px; width:100%}
.st-gh{margin:0 0 8px; font-size:14px; color:var(--band-ink-2)}
.st-grid{list-style:none; margin:0; padding:0; display:grid; grid-template-columns:repeat(auto-fill,minmax(84px,1fr)); gap:6px 6px}
.st-grid a{display:flex; flex-direction:column; align-items:center; gap:4px; padding:6px 2px; color:var(--band-ink-2); text-decoration:none; border-radius:6px; font-family:var(--mono); font-size:11.5px; line-height:1.3; text-align:center}
.st-grid a:hover{color:var(--band-ink); background:var(--band)}
.st-grid a:focus-visible{outline:2px solid var(--band-accent); outline-offset:1px}
.st-mini{width:auto; height:52px}
.st-none{margin:0; font-size:15px; color:var(--band-ink-2)}
/* the one motion: when an optic is picked its screws seat into the new
   drawing. Answers the reader's own action, so it is kept; skipped when
   reduced motion is asked for */
@media (prefers-reduced-motion:no-preference){
  .stage.is-seating .st-screws{animation:st-seat .34s cubic-bezier(.2,.7,.2,1) both}
  .stage.is-seating .st-lugs{animation:st-fade .34s ease both}
}
@keyframes st-seat{from{opacity:0; transform:translateY(-14px)} to{opacity:1; transform:none}}
@keyframes st-fade{from{opacity:0} to{opacity:1}}
/* the same panel on a footprint's own page: the drawing beside its figures */
.stage.is-page{margin-top:22px; flex-direction:row; align-items:center; gap:32px; min-height:0; padding:24px 30px}
.stage.is-page .st-draw{flex:0 0 300px}
.stage.is-page .st-svg{height:260px}
.stage.is-page .st-cap{margin:0; flex:1 1 auto; min-width:0}
.stage.is-page .st-facts{margin-top:0}
@media (max-width:760px){
  .stage.is-page{flex-direction:column; align-items:stretch; gap:14px; padding:18px}
  .stage.is-page .st-draw{flex:none}
  .stage.is-page .st-svg{height:200px}
}
/* below the wide layout there is no room beside the form, and the finder
   must stay above the fold: the stage stays out until something is picked,
   then sits under the form as a compact answer */
@media (max-width:900px){
  .hero-main{grid-template-columns:1fr; gap:24px}
  .stage{display:none; min-height:0; padding:16px 18px}
  .stage[data-active]{display:flex}
  .st-svg{height:170px}
  .st-title{font-size:22px}
}
/* on a phone the finder has to stay above the fold: the lede goes, the
   padding tightens */
@media (max-width:620px){
  .hero-main{padding-block:22px 26px}
  .hero .find{margin-top:16px}
}

/* ── section head: a heading, its count, and where to see all of it ───── */
.shead{display:flex; align-items:baseline; flex-wrap:wrap; gap:4px 12px; margin:44px 0 16px}
.shead h2{margin:0}
.shead-n{font-family:var(--mono); font-size:12px; color:var(--ink-3)}
.shead-all{
  margin-left:auto; font-size:14px; font-weight:600;
  text-decoration:none; color:var(--accent); white-space:nowrap;
}
.shead-all:hover{text-decoration:underline}

/* ── pairing ledger ─────────────────────────────────────────────────────
   Popular pairings as rows of one ruled list, so the set can be read down
   like a table: the verdict, what to buy, the figures, the cost. The whole
   row is the link. Hover tints the row and moves nothing. */
.pledger{list-style:none; margin:0; padding:0; background:var(--surface); border:1px solid var(--line); border-radius:10px; overflow:hidden}
.pledger li + li{border-top:1px solid var(--line-soft)}
.prow{
  display:grid; grid-template-columns:132px minmax(0,1fr) auto; gap:4px 18px; align-items:start;
  padding:14px 18px; color:var(--ink); text-decoration:none;
}
.prow:hover{background:var(--inset)}
.prow:focus-visible{outline:2px solid var(--accent); outline-offset:-2px}
.pr-v{justify-self:start; padding-top:1px}
.pr-main{display:flex; flex-direction:column; gap:2px; min-width:0}
.pr-t{font-size:16px; line-height:1.4}
.pr-t b{font-weight:600}
.pr-buy{font-size:14.5px; line-height:1.45; color:var(--ink-2)}
.pr-spec{display:flex; flex-wrap:wrap; gap:0 18px; margin-top:3px; font-family:var(--mono); font-size:12px; color:var(--ink-2)}
.pr-spec i{font-family:var(--sans); font-style:normal; color:var(--ink-3); margin-right:6px}
.pr-price{font-family:var(--mono); font-size:16px; font-weight:500; font-variant-numeric:tabular-nums; white-space:nowrap; text-align:right}
@media (max-width:620px){
  .prow{grid-template-columns:minmax(0,1fr) auto; padding:13px 14px}
  .pr-v{grid-column:1; grid-row:1}
  .pr-price{grid-column:2; grid-row:1}
  .pr-main{grid-column:1 / -1; grid-row:2}
}

/* ── reach rows: a pistol or an optic in a ledger, and how far it reaches ──
   Two ledgers side by side where there is room (one under the other where
   there isn't). The bar is what fits: green needs no plate, amber needs one,
   the rest of the track does not fit. Those are the chips' own two claims, so
   the colours stay claims. The row is the link; hover tints and moves nothing. */
.rgrid{display:grid; grid-template-columns:repeat(auto-fit,minmax(340px,1fr)); gap:0 28px; align-items:start}
.rgrid .shead{margin-bottom:6px}
.rkey{display:flex; flex-wrap:wrap; gap:2px 16px; margin:0 0 10px; font-size:12.5px; color:var(--ink-2)}
.rkey span::before, .rr-c::before{content:""; display:inline-block; flex:0 0 auto; width:8px; height:8px; margin-right:6px; border-radius:50%; background:var(--line)}
.rkey .rr-free::before, .rr-c.rr-free::before{background:var(--ok)}
.rkey .rr-plate::before, .rr-c.rr-plate::before{background:var(--warn)}
.rrow{
  display:grid; grid-template-columns:minmax(0,1fr) auto auto; gap:7px 14px; align-items:baseline;
  padding:10px 16px 11px; color:var(--ink); text-decoration:none;
}
.rrow:hover{background:var(--inset)}
.rrow:focus-visible{outline:2px solid var(--accent); outline-offset:-2px}
.rr-n{font-size:15.5px; line-height:1.35}
.rr-b{color:var(--ink-3)}
.rr-n b{font-weight:600}
.rr-c{display:flex; align-items:center; justify-content:space-between; width:38px; font-family:var(--mono); font-size:13px; font-variant-numeric:tabular-nums}
.rr-c b{font-weight:500}
.rr-bar{grid-column:1 / -1; display:flex; height:5px; border-radius:3px; background:var(--line); overflow:hidden}
.rr-bar i{display:block; height:100%}
.rr-f{background:var(--ok)}
.rr-p{background:var(--warn)}

/* ── what every answer includes: four plain terms, ruled, no boxes ─────── */
.answers{margin-top:44px}
.answers h2{margin:0 0 14px}
.idl{margin:0; display:grid; grid-template-columns:repeat(auto-fit,minmax(250px,1fr)); gap:0 28px}
.idl > div{padding:12px 0 14px; border-top:2px solid var(--line)}
.idl dt{font-weight:600; font-size:15.5px; line-height:1.35}
.idl dd{margin:4px 0 0; font-size:14.5px; line-height:1.5; color:var(--ink-2); max-width:44ch}

/* ── footprints: a ruled grid of drawings, most used first ───────────────── */
.fgrid{
  list-style:none; margin:0; padding:0; display:grid; grid-template-columns:repeat(auto-fill,minmax(176px,1fr));
  background:var(--surface); border:1px solid var(--line); border-radius:10px; overflow:hidden;
}
.fcell{
  display:grid; grid-template-columns:34px minmax(0,1fr); grid-template-rows:auto auto; column-gap:12px; align-items:center;
  height:100%; padding:11px 14px; color:var(--ink); text-decoration:none; box-shadow:inset -1px -1px 0 var(--line-soft);
}
.fcell:hover{background:var(--inset)}
.fcell:focus-visible{outline:2px solid var(--accent); outline-offset:-2px}
.fc-fig{grid-row:1 / 3; display:grid; place-items:center}
.fc-fig svg{display:block; height:46px; width:auto}
.fc-n{font-size:14.5px; font-weight:600; line-height:1.3; align-self:end}
.fc-k{font-family:var(--mono); font-size:12px; color:var(--ink-2); align-self:start}
.fcell:not(:has(.fc-k)) .fc-n{grid-row:1 / 3; align-self:center}

/* ── home: main column and the latest-changes rail ───────────────────── */
.home-grid{display:grid; grid-template-columns:minmax(0,1fr) 300px; gap:32px; align-items:start}
@media (max-width:980px){ .home-grid{grid-template-columns:1fr} }
.latest{margin-top:44px; background:var(--surface); border:1px solid var(--line); border-radius:8px; overflow:hidden}
.latest h2{margin:0; padding:12px 16px 10px; font-size:19px; letter-spacing:.01em; background:var(--inset); border-bottom:1px solid var(--line)}
.latest ol{list-style:none; margin:0; padding:0}
.latest li{padding:11px 16px 12px; border-bottom:1px solid var(--line-soft)}
.latest time{display:block; font-family:var(--mono); font-size:12px; color:var(--ink-3)}
.latest li a{display:block; margin-top:2px; font-size:14px; font-weight:500; line-height:1.4; text-decoration:none; color:var(--ink)}
.latest li a:hover{color:var(--accent); text-decoration:underline}
.latest .l-d{display:block; margin-top:3px; font-family:var(--mono); font-size:12px; color:var(--ink-2)}
.latest .shead-all{display:block; margin:0; padding:10px 16px 12px}


/* ── print ────────────────────────────────────────────────────────────────
   A filtered table is a thing people print: the list for the gun counter,
   or for the gunsmith. Paper is white whatever the screen was, so the light
   tokens always apply — printed from dark mode, the text came out pale grey
   on white. The controls go, and the count line says in words what the
   table was filtered to, since the controls that said it are gone. */
@media print{
  :root, :root:not([data-theme="light"]), :root[data-theme="dark"]{
    --ground:#FFFFFF; --surface:#FFFFFF; --surface-2:#EEF1F3; --inset:#F4F6F7;
    --line:#B9C2CA; --line-soft:#D8DEE3;
    --ink:#000000; --ink-2:#333B42; --ink-3:#5A646D;
    --accent:#1A5478; --accent-soft:#D3E2EC; --on-accent:#FFFFFF;
    --ok:#1F5A3E; --ok-soft:#D1E5D9; --ok-edge:#5D9E7C;
    --warn:#6E450C; --warn-soft:#F0E3C6; --warn-edge:#C08F3C;
    --bad:#7A2721; --bad-soft:#EED7D4; --bad-edge:#C0645C;
    --flag:#4B3C74; --flag-soft:#E0DBEE;
    --shadow:none; --shadow-lift:none;
    --band:#FFFFFF; --band-2:#FFFFFF; --band-line:#B9C2CA;
    --band-ink:#000000; --band-ink-2:#333B42; --band-accent:#1A5478; --on-band-accent:#FFFFFF;
  }
  body{background:#fff; font-size:12pt}
  .sh::before, .sh-search, .sh-cta, .sh-cats, .find, .adslot, .tf-row, .tf-reset, .lfilter .field, #lf-reset,
  .stage, .latest{display:none !important}
  .sh{position:static; border-bottom:1px solid #000}
  .hero-main{display:block; padding-block:12px}
  .sf{border-color:#B9C2CA}
  .prow, .rrow{break-inside:avoid}
  .tfilter, .lfilter{background:none; border:0; padding:0; margin:6px 0 0}
  .tf-foot, .lf-foot{display:block; margin:0; color:#000; font-size:10pt}
  .tf-said{display:inline}
  .tw{overflow:visible; border-color:#B9C2CA}
  table.grid tr, .route, .note, .facts{break-inside:avoid}
  /* #14: a closed co-witness list still prints in full */
  .cwd::details-content{content-visibility:visible; display:block}
  .cwd summary{list-style:none}
  h2, h3{break-after:avoid}
  .kform, .kmore{display:none !important}
  /* navigation, not content: a printed build sheet link goes nowhere */
  table.grid a.to-build{display:none !important}
  .kcom{break-inside:avoid}
  a{color:inherit}
}

/* Touch screens: every link a thumb reaches for gets a target of about 40px
   or more. The breadcrumb measured 15px tall, the maker bar 28px, and the
   table's links were only as tall as their text. */
@media (pointer:coarse){
  .crumb a{display:inline-block; padding-block:11px}
  .azbar a{min-height:40px; padding-inline:12px}
  .pills a{padding:10px 12px}
  table.grid td a{display:inline-flex; align-items:center; min-height:44px}
  .sf nav a{padding-block:10px}
  .sh-cta, .sh-search button, .sh-search input{min-height:44px}
  .sh-cta{display:inline-flex; align-items:center}
  .sh-cats a{padding-block:14px 12px}
  .tf-fold{min-height:44px; padding-inline:14px}
}

/* /wanted/ (site/wanted.mjs): one block per slide, footprint, optic or open question */
.want{margin:14px 0; padding:12px 16px 14px; border:1px solid var(--line); border-radius:8px; background:var(--surface); scroll-margin-top:12px}
.want:target{border-color:var(--accent); box-shadow:0 0 0 2px var(--accent-soft)}
.want h3{margin:0 0 6px; font-size:17px}
.want .rq{font-family:var(--mono); font-size:12.5px; font-weight:400; color:var(--ink-3); margin-left:6px}
.want p{margin:0 0 6px; font-size:14px; color:var(--ink-2); line-height:1.55}
.want .who{font-size:13.5px}
.want ul{margin:4px 0 8px; padding-left:18px; font-size:14px; line-height:1.55}
.want li{margin:4px 0}
.want .settle{display:block; font-size:12.5px; color:var(--ink-3)}
.want .send{display:inline-flex; align-items:center; min-height:44px; font-size:14px; font-weight:600}
.want-more{margin-top:12px}
.want-more > summary{cursor:pointer; min-height:44px; display:flex; align-items:center; font-weight:600; color:var(--ink)}
@media print{ .want{border-color:#999; background:none; break-inside:avoid} .want .send{display:none} }
