/* ==========================================================================
   Outlaw Bullets: shared stylesheet (css/site.css)
   "Frontier Broadside": rag paper, warm ink, printer's red, wood type.

   Page agents: DO NOT EDIT THIS FILE. Page-specific CSS goes in css/pages/<page>.css.
   Need a new shared component? Build it in your page CSS and flag it in your report.
   Full guide: DESIGN.md.

   1. Tokens          5. Header + nav        9. Sheet              13. Forms + pickers
   2. Base            6. Footer + quickbar   10. Product cards     14. Photos, gallery, FAQ, shipping
   3. Type            7. Buttons + links     11. Tables, ledger    15. Contact band
   4. Layout          8. Page parts          12. Notices, badges   16. Motion + print
   ========================================================================== */

/* ==========================================================================
   1. Tokens
   ========================================================================== */
/* Metric-matched fallbacks. Until Ultra and Besley arrive from Google Fonts (display=swap), headings and
   text are set in a local face scaled to the web font's width and line metrics, so the page barely moves
   when the web fonts swap in (layout shift), and reads close to the design if they never load.
   Rockwell where it is installed (Windows with Office, macOS), else Georgia. Ratios measured in Chromium
   against the Google Fonts builds: Ultra is 127.4% the width of Rockwell Bold, 120.9% of Georgia Bold. */
@font-face { font-family: "Ultra FB Rockwell"; src: local("Rockwell Bold"), local("Rockwell-Bold"); font-weight: 400;
  size-adjust: 127.4%; ascent-override: 79.3%; descent-override: 21.2%; line-gap-override: 0%; }
@font-face { font-family: "Ultra FB Georgia"; src: local("Georgia Bold"), local("Georgia-Bold"); font-weight: 400;
  size-adjust: 120.9%; ascent-override: 83.5%; descent-override: 22.3%; line-gap-override: 0%; }
@font-face { font-family: "Besley FB Rockwell"; src: local("Rockwell"), local("Rockwell-Regular"); font-weight: 400;
  size-adjust: 106.4%; ascent-override: 117.5%; descent-override: 40.4%; line-gap-override: 0%; }
@font-face { font-family: "Besley FB Rockwell"; src: local("Rockwell Bold"), local("Rockwell-Bold"); font-weight: 700;
  size-adjust: 109%; ascent-override: 114.7%; descent-override: 39.4%; line-gap-override: 0%; }
@font-face { font-family: "Besley FB Georgia"; src: local("Georgia"); font-weight: 400;
  size-adjust: 111.2%; ascent-override: 112.4%; descent-override: 38.7%; line-gap-override: 0%; }
@font-face { font-family: "Besley FB Georgia"; src: local("Georgia Bold"), local("Georgia-Bold"); font-weight: 700;
  size-adjust: 104.1%; ascent-override: 120.1%; descent-override: 41.3%; line-gap-override: 0%; }

:root {
  /* colour: paper */
  --paper: #F1E7CF;          /* page */
  --paper-hi: #F8F1E0;       /* plates, sheets, inputs */
  --paper-deep: #E7DABB;     /* quote boxes, table stripes */
  /* colour: ink */
  --ink: #1C1814;            /* text: 14.3:1 on paper (AAA) */
  --ink-2: #3A322A;          /* secondary text: 10.2:1 on paper (AAA) */
  --rule: rgba(28, 24, 20, .3);
  --rule-strong: rgba(28, 24, 20, .62);
  /* colour: red */
  --red: #A51F16;            /* text-safe red: 6.1:1 on paper, 6.6:1 on paper-hi (AA) */
  --red-dark: #8E1A12;       /* hover / pressed red: 7.4:1 on paper */
  --red-hot: #C0281C;        /* display-size misregistration and rules only, never small text */
  --red-tint: rgba(165, 31, 22, .07);
  --red-line: rgba(165, 31, 22, .55);   /* resting underline on ink links */
  --red-wash: #FBEFE6;       /* error fields, the chosen picker card */
  --warn-bg: #F6E4D6;        /* warning notice */
  /* colour: on dark (ink) backgrounds */
  --on-dark: #F1E7CF;        /* 14.3:1 on ink */
  --on-dark-2: #D9C9A6;      /* 10.8:1 on ink */
  --on-dark-red: #E8A79E;    /* 8.8:1 on ink */
  --on-dark-line: rgba(241, 231, 207, .28);  /* dividers on ink */
  --on-dark-wash: rgba(241, 231, 207, .12);  /* hover wash on ink */
  --ink-hover: #2E2822;      /* hover on ink surfaces */
  /* colour: misc surfaces */
  --paper-veil: rgba(248, 241, 224, .55);    /* secondary button fill */
  --stripe: rgba(231, 218, 187, .45);        /* table zebra */
  --photo-mat: #FBF7EE;      /* photo mount */
  --placeholder: #6A5F52;    /* input placeholder: 5.4:1 on paper-hi */

  /* type families */
  --f-display: "Ultra", "Ultra FB Rockwell", "Ultra FB Georgia", "Rockwell Extra Bold", "Rockwell", Georgia, serif;   /* headings only */
  --f-gothic: "League Gothic", "Oswald", "Arial Narrow", "Roboto Condensed", "sans-serif-condensed", sans-serif; /* numerals, phone, labels */
  --f-text: "Besley", "Besley FB Rockwell", "Besley FB Georgia", "Clarendon", "Rockwell", Georgia, serif;            /* everything you read */

  /* type scale (px at 16px root) */
  --fs-label: 1rem;          /* 16  kickers, tags, table heads, badges: the floor for any label */
  --fs-note: 1.0625rem;      /* 17  notes, captions, help text: the floor for any running text */
  --fs-body: 1.125rem;       /* 18  body on phones; 19 from 48em (768px), set below */
  --fs-lede: 1.3125rem;      /* 21  intro paragraphs */
  --fs-h4: 1.3125rem;        /* 21  Besley 700: product names, card titles */
  --fs-h3: clamp(1.625rem, 1.2rem + 1.4vw, 2.125rem);  /* Ultra, short headings only */
  --fs-h2: clamp(2.25rem, 1.4rem + 3.4vw, 3.75rem);    /* Ultra, max ~5 words */
  --fs-h1: clamp(2.625rem, 1.5rem + 4.4vw, 4.75rem);   /* Ultra, max ~4 words per line */
  --fs-num: clamp(2.25rem, 1.8rem + 1.6vw, 2.75rem);   /* League Gothic prices */
  --lh-body: 1.6;

  /* spacing */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;
  --sp-8: 64px;
  --sp-9: 96px;
  --gutter: clamp(16px, 4vw, 48px);
  --section-y: clamp(56px, 8vw, 104px);
  --maxw: 1280px;
  --measure: 36em;

  /* radii: letterpress is square-ish; never pill buttons */
  --r-sm: 2px;
  --r: 3px;
  --r-lg: 6px;

  /* shadows: printed offsets, not soft UI shadows */
  --shadow-red: 4px 4px 0 var(--red);
  --shadow-ink: 4px 4px 0 var(--ink);
  --shadow-sm-red: 3px 3px 0 var(--red);
  --shadow-photo: 5px 6px 0 rgba(28, 24, 20, .14);
  --shadow-menu: 0 18px 30px -18px rgba(28, 24, 20, .45);

  /* rules */
  --rule-double: linear-gradient(var(--ink) 0 3px, transparent 3px 5px, var(--ink) 5px 6px, transparent 6px);

  /* sizes */
  --tap: 44px;               /* minimum tap height for any standalone link or control */
  --tap-lg: 56px;
  --quickbar-h: 4rem;        /* about the bar's height, for scroll padding; js/site.js measures the real bar */
  --header-h: 96px;          /* sticky header + room, for scroll padding; 110px from 75em. js/site.js
                                measures the real header (it grows with big text) and overwrites it */

  /* textures (toned down so small text stays crisp) */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='260'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .28 0 0 0 0 .21 0 0 0 0 .12 0 0 0 .3 -.1'/%3E%3C/filter%3E%3Crect width='260' height='260' filter='url(%23g)'/%3E%3C/svg%3E");
  --mottle: radial-gradient(ellipse 38% 30% at 22% 28%, rgba(150, 110, 50, .04), transparent 70%),
            radial-gradient(ellipse 30% 36% at 78% 70%, rgba(150, 110, 50, .035), transparent 70%);
  --star: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-50 -50 100 100'%3E%3Cpath d='M0-48 11.3-15.6 45.6-14.8 18.3 6 28.2 38.8 0 19.4-28.2 38.8-18.3 6-45.6-14.8-11.3-15.6Z'/%3E%3C/svg%3E");
  --arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M2 10.6h15.2l-5.1-5.1L14.1 3.5 22.6 12l-8.5 8.5-2-2 5.1-5.1H2z'/%3E%3C/svg%3E");

  color-scheme: light;
}

/* ==========================================================================
   2. Base
   Hover styles are wrapped in @media (hover: hover) and (pointer: fine), so on a touch screen a
   tapped button or card doesn't stay "hovered" after the tap. Touch gets :active and :focus-visible.
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 16px;
}
/* with JS the header is sticky at every width (see section 5), so focused fields and #anchors land
   below it. --header-h is measured from the real header by js/site.js (it grows with big text). */
html.js { scroll-padding-top: var(--header-h); }
/* Breakpoints are in em (1em = the reader's default text size, 16px unless they changed it), so a
   reader who sets bigger text gets the stacked phone layouts instead of clipped content.
   37.5em = 600px, 48em = 768px, 56.25em = 900px, 60em = 960px, 75em = 1200px at 16px. */
@media (max-width: 56.24em) {
  /* the quickbar sits at the bottom of the screen: keep focused fields and find-in-page hits above it */
  html { scroll-padding-bottom: calc(var(--quickbar-h) + 1.25rem + env(safe-area-inset-bottom, 0px)); }
}

body {
  margin: 0;
  min-width: 320px;
  background: var(--grain), var(--mottle), var(--paper);
  background-size: 260px 260px, 1600px 1300px, 1600px 1300px, auto;
  color: var(--ink);
  font: 400 var(--fs-body)/var(--lh-body) var(--f-text);
  font-optical-sizing: auto;
  -webkit-font-smoothing: antialiased;
}
@media (min-width: 48em) {
  :root { --fs-body: 1.1875rem; }     /* 19px */
}

[hidden] { display: none !important; }
img, svg, video { max-width: 100%; }
img { height: auto; }
p { margin: 0 0 1em; text-wrap: pretty; }
ul, ol { margin: 0 0 1em; }
a { color: inherit; text-decoration-thickness: 2px; text-underline-offset: .18em; }
@media (hover: hover) and (pointer: fine) { a:hover { color: var(--red); } }
/* email links break after the @ (<wbr> in the markup); only where "outlawbullets.com" alone is wider
   than its column (very large text on a phone) may it break inside the word instead of running out */
a[href^="mailto:"] { overflow-wrap: anywhere; }
abbr[title] { text-decoration: none; cursor: help; }
strong, b { font-weight: 700; }
em, i { font-style: italic; }
hr { border: 0; height: 6px; margin: var(--sp-7) 0; background: var(--rule-double); }
table { border-collapse: collapse; }
button, input, select, textarea { font: inherit; color: inherit; }

:focus-visible {
  outline: 3px solid var(--red);
  outline-offset: 3px;
  border-radius: 1px;
}

/* ==========================================================================
   3. Type
   ========================================================================== */
.kicker {
  margin: 0 0 .65em;
  font: 700 var(--fs-label)/1.3 var(--f-text);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--red);
}
.kicker--on-dark { color: var(--on-dark-red); }
.kicker--ink { color: var(--ink); }

.h1, .h2, .h3 {
  margin: 0 0 .45em;
  font-family: var(--f-display);
  font-weight: 400;
  letter-spacing: -.005em;
  text-wrap: balance;
}
.h1 { font-size: var(--fs-h1); line-height: 1; }
.h2 { font-size: min(var(--fs-h2), 14vw); line-height: 1.02; }   /* 14vw: very large text on a small phone */
.h3 { font-size: var(--fs-h3); line-height: 1.1; }
.h4 {
  margin: 0 0 .35em;
  font: 700 var(--fs-h4)/1.25 var(--f-text);
  text-wrap: balance;
}
/* the red "second ink pass" offset: display sizes only (>= 40px) */
.misprint { text-shadow: .03em .025em 0 var(--red-hot); }

.lede {
  font-size: var(--fs-lede);
  line-height: 1.55;
}
.note {
  font-size: var(--fs-note);
  line-height: 1.5;
  color: var(--ink);        /* notes stay in dark ink and roman */
}
.prose { max-width: var(--measure); }
.prose > * + h2, .prose > * + h3 { margin-top: 1.4em; }

.num {
  font-family: var(--f-gothic);
  font-weight: 400;
  letter-spacing: .02em;
  font-variant-numeric: lining-nums tabular-nums;
}

/* ==========================================================================
   4. Layout utilities
   ========================================================================== */
.wrap {
  width: min(100% - 2 * var(--gutter), var(--maxw));
  margin-inline: auto;
}
.wrap--narrow { width: min(100% - 2 * var(--gutter), 860px); }

.section { padding-block: var(--section-y); }
.section--tight { padding-block: calc(var(--section-y) * .6); }
.section--flush-top { padding-top: 0; }
.section--deep { background: var(--grain), var(--paper-deep); }

.stack > * { margin-block: 0; }
.stack > * + * { margin-top: var(--stack, var(--sp-4)); }

.grid { display: grid; gap: var(--grid-gap, var(--sp-6)); }
@media (min-width: 56.25em) {
  .grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .grid--7-5 { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
  .grid--5-7 { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-3) var(--sp-4);
  align-items: center;
}
.actions--center { justify-content: center; }
.actions--stack { flex-direction: column; align-items: stretch; }
/* phones: every button in a row of buttons is full width, so pairs line up */
@media (max-width: 37.49em) {
  .actions > .btn { width: 100%; }
}

.center { text-align: center; }
.nowrap { white-space: nowrap; }
/* keep a word pair together in a big display heading ("Cowboy Action", "pesky knock downs"), but only while the
   screen is at least 20em wide (320px at the normal text size): with very large default text on a phone
   the pair may wrap instead of running off the screen. Use it instead of &nbsp; in display headings. */
@media (min-width: 20em) {
  .keep { white-space: nowrap; }
}
.vh {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: 12px;
  top: -120px;
  z-index: 200;
  padding: 12px 18px;
  background: var(--ink);
  color: var(--on-dark);
  font-weight: 700;
}
.skip-link:focus { position: fixed; top: 12px; color: var(--on-dark); }   /* on screen wherever the page is scrolled */

/* star ornament: rule, three stars, rule */
.orn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  width: min(100% - 2 * var(--gutter), 420px);
  margin: 0 auto;
  color: var(--red);
}
.orn::before, .orn::after {
  content: "";
  flex: 1;
  height: 5px;
  background: linear-gradient(var(--ink) 0 1px, transparent 1px 3px, var(--ink) 3px 5px);
}
.orn i {
  width: 20px; height: 20px;
  background: currentColor;
  -webkit-mask: var(--star) center / contain no-repeat;
  mask: var(--star) center / contain no-repeat;
}
.orn i:first-child, .orn i:last-child { width: 12px; height: 12px; }

.icon { width: 1.25em; height: 1.25em; flex: none; fill: currentColor; }

/* ==========================================================================
   5. Header + nav
   ========================================================================== */
.site-header {
  position: relative;
  z-index: 50;
  background: var(--paper);
}
/* With JS the header is sticky at every width. Below 56.25em (where the quickbar rides the bottom)
   js/site.js slides it up out of the way while you scroll down the page and brings it straight back
   when you scroll up (html.header-hidden), so Menu is one flick away without the bar taking the
   screen. Without JS it scrolls away with the page: the no-JS menu is a plain list inside it. */
.js .site-header { position: sticky; top: 0; transition: transform .2s ease; }
@media (max-width: 56.24em) {
  .js.header-hidden .site-header { transform: translateY(calc(-100% - 8px)); }
}
.site-header::after {          /* thick-thin printer's rule */
  content: "";
  position: absolute;
  left: 0; right: 0;
  bottom: -6px;
  height: 6px;
  background: var(--rule-double), var(--paper);
}
/* top bar (from 48em, as on the live site): email, phone and the cart (with its count) on an ink strip above
   the logo row. Below 48em the quickbar carries Call, Email and Cart instead, so the strip stays hidden. */
.topbar { display: none; background: var(--ink); color: var(--on-dark); }
.topbar__in { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 0 var(--sp-5); }
.topbar__link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: var(--tap);
  color: var(--on-dark);
  font: 600 var(--fs-note)/1.2 var(--f-text);
  text-decoration: none;
  overflow-wrap: anywhere;
}
.topbar__phone { font: 400 1.5rem/1 var(--f-gothic); letter-spacing: .03em; white-space: nowrap; }
.topbar__link .icon { width: 20px; height: 20px; color: var(--on-dark-red); }
@media (hover: hover) and (pointer: fine) { .topbar__link:hover { color: var(--on-dark-red); text-decoration: underline; } }
.topbar :focus-visible { outline-color: var(--on-dark); outline-offset: -3px; }
.topbar__cart { font-weight: 700; }
.topbar__cart .icon { fill: currentColor; color: var(--on-dark); }
.topbar__cart .cart-link__count { margin-left: 2px; font-size: 1.125rem; }
.topbar__cart[aria-current] { color: var(--on-dark); text-decoration: underline; text-decoration-color: var(--on-dark-red); text-decoration-thickness: 3px; text-underline-offset: .3em; }
@media (min-width: 48em) {
  .topbar { display: block; }
  .header-call { display: none !important; }   /* the top bar has the number from here */
}

.site-header__in {
  display: flex;
  flex-wrap: wrap;               /* very big text on a tiny phone: Menu drops under the logo */
  align-items: center;
  gap: var(--sp-3);
  min-height: 72px;
  padding-block: 10px;
}

/* the client's logo (assets/logo/outlaw-bullets.svg, 332.5 x 131.7, about 2.5:1), unaltered: only its
   display width changes. Phones: as wide as the row allows next to the Menu button, 140px to 170px
   (about 157px at 320). 200px from 37.5em, 220px at 75em-89.99em (the row also holds the nav, Call and
   Cart), 240px from 90em. Where very large text drops the Menu button onto its own row (a 320px phone at
   150% text), the logo has the row to itself and is 200px. The link is at least 44px tall (--tap). */
.brand {
  display: flex;
  align-items: center;
  flex: none;
  min-height: var(--tap);
  margin-right: auto;
  line-height: 0;
  border-radius: var(--r);
}
.brand img {
  display: block;
  width: clamp(140px, 100vw - 2 * var(--gutter) - 76px - 3.4rem, 170px);   /* the Menu button is 62px + its word (3.3rem), plus the gap */
  height: auto;
  aspect-ratio: 332.5 / 131.7;
}
@media (max-width: 14.49em) {
  .brand { flex-basis: 100%; }
  .brand img { width: min(100%, 200px); }
}

.nav-toggle {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 48px;
  padding: 8px 14px;
  border: 2px solid var(--ink);
  border-radius: var(--r);
  background: var(--paper-hi);
  color: var(--ink);
  font: 700 1.0625rem/1 var(--f-text);
  cursor: pointer;
  order: 2;                      /* logo | Menu | Call: the same order as the source, so Tab follows it */
}
.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  display: block;
  width: 20px;
  height: 2.5px;
  background: currentColor;
  transition: transform .2s ease, background-color .2s ease;
}
.nav-toggle__bars { position: relative; }
.nav-toggle__bars::before, .nav-toggle__bars::after { content: ""; position: absolute; left: 0; }
.nav-toggle__bars::before { top: -6.5px; }
.nav-toggle__bars::after { top: 6.5px; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars { background: transparent; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::before { transform: translateY(6.5px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::after { transform: translateY(-6.5px) rotate(-45deg); }

/* mobile: nav is a panel under the header (js), or a plain list (no js) */
.site-nav {
  position: absolute;
  top: calc(100% + 6px);
  left: 0; right: 0;
  background: var(--paper);
  border-bottom: 3px solid var(--ink);
  box-shadow: var(--shadow-menu);
}
.js .site-nav { display: none; }
/* the open menu rides with the sticky header and scrolls inside itself when it is taller than the
   screen (big text), so its links and the Menu button to close it never leave the screen */
.js .site-nav.is-open {
  display: block;
  max-height: calc(100vh - var(--header-h));
  max-height: calc(100dvh - var(--header-h));
  overflow-y: auto;
  overscroll-behavior: contain;
}
html:not(.js) .nav-toggle { display: none; }
@media (max-width: 74.99em) {      /* from 75em the normal inline nav applies, JS or not */
  html:not(.js) .site-header__in { flex-wrap: wrap; }
  html:not(.js) .site-nav { position: static; flex-basis: 100%; order: 5; box-shadow: none; border: 0; background: none; }
  html:not(.js) .site-nav__list,
  html:not(.js) .site-nav__actions { width: 100%; }
}

.site-nav__list {
  list-style: none;
  width: min(100% - 2 * var(--gutter), var(--maxw));
  margin: 0 auto;
  padding: 6px 0 0;
}
.site-nav__list li + li { border-top: 1px dotted var(--rule-strong); }
.site-nav__list a {
  display: flex;
  align-items: center;
  min-height: var(--tap-lg);
  font: 700 1.3125rem/1.2 var(--f-text);
  text-decoration: none;
}
.site-nav__list a[aria-current] { color: var(--red); }
.site-nav__list a[aria-current]::before {
  content: "";
  width: .7em; height: .7em;
  margin-right: .5em;
  background: currentColor;
  -webkit-mask: var(--star) center / contain no-repeat;
  mask: var(--star) center / contain no-repeat;
}
.site-nav__actions {
  display: grid;
  gap: var(--sp-3);
  width: min(100% - 2 * var(--gutter), var(--maxw));
  margin: 0 auto;
  padding: var(--sp-4) 0 var(--sp-5);
  border-top: 3px solid var(--ink);
}
/* red Call button in the bar (37.5em-47.99em only; from 48em the top bar has the number). It only dials,
   so it says Call. There is no texting: never add a Text control. */
.header-call {
  display: none;
  flex-direction: column;
  justify-content: center;
  min-height: 54px;
  padding: 6px 14px 6px;
  background: var(--red);
  color: var(--on-dark);
  border-radius: var(--r);
  text-decoration: none;
  line-height: 1;
  box-shadow: 3px 3px 0 var(--ink);
}
@media (hover: hover) and (pointer: fine) { .header-call:hover { background: var(--ink); color: var(--on-dark); box-shadow: var(--shadow-sm-red); } }
.header-call__label {
  font: 700 var(--fs-label)/1 var(--f-text);   /* 16px: the label floor */
  letter-spacing: .1em;
  text-transform: uppercase;
}
.header-call__num {
  margin-top: 3px;
  font: 400 1.875rem/1 var(--f-gothic);
  letter-spacing: .03em;
  white-space: nowrap;
}
@media (min-width: 37.5em) {
  .brand img { width: 200px; }
  .header-call { display: inline-flex; order: 3; }
}
@media (min-width: 75em) {
  :root { --header-h: 110px; }
  .site-header__in { min-height: 92px; gap: var(--sp-4); }
  .brand img { width: 240px; }
  .nav-toggle { display: none; }
  .js .site-nav, .site-nav, .js .site-nav.is-open {
    display: block;
    position: static;
    max-height: none;
    overflow: visible;
    background: none;
    border: 0;
    box-shadow: none;
    order: 1;
  }
  .site-nav__list {
    display: flex;
    gap: 2px;
    width: auto;
    padding: 0;
  }
  .site-nav__list li + li { border: 0; }
  .site-nav__list a {
    min-height: 48px;
    padding: 0 11px;
    font: 600 1.0625rem/1 var(--f-text);
    text-decoration: underline;
    text-decoration-color: transparent;
    text-underline-offset: .4em;
    transition: text-decoration-color .15s ease, color .15s ease;
  }
  @media (hover: hover) and (pointer: fine) { .site-nav__list a:hover { text-decoration-color: var(--red); } }
  .site-nav__list a[aria-current] { text-decoration-color: var(--red); }
  .site-nav__list a[aria-current]::before { display: none; }
  .site-nav__actions { display: none; }
  .header-call { order: 2; }
}
@media (min-width: 75em) and (max-width: 81.24em) {
  .site-nav__list a { padding-inline: 9px; }   /* 1200-1299px: logo, six links, Call and Cart fit one row */
}
@media (min-width: 75em) and (max-width: 89.99em) {
  .site-header__in { gap: var(--sp-3); }
  .brand img { width: 220px; }                 /* 1200-1439px: room for the nav and cart; 240px from 90em */
}

/* ==========================================================================
   6. Footer + quickbar
   ========================================================================== */
.site-footer {
  position: relative;
  padding: clamp(48px, 6vw, 72px) 0 var(--sp-6);
  background: var(--paper);
  font-size: var(--fs-note);
}
.site-footer::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 6px;
  background: var(--rule-double);
}
.site-footer__grid {
  display: grid;
  gap: var(--sp-6);
}
.site-footer__brand img { display: block; width: 220px; height: auto; aspect-ratio: 332.5 / 131.7; }
.site-footer__brand p { max-width: 22em; margin-top: var(--sp-4); }
.site-footer__label {
  margin: 0 0 var(--sp-1);
  font: 700 var(--fs-label)/1.3 var(--f-text);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--red);
}
.site-footer__nav ul,
.site-footer__contact ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
/* two link columns when they fit, one when they don't (narrow column or big text) */
.site-footer__nav ul { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 8em), 1fr)); gap: 0 var(--sp-5); }
.site-footer__nav a,
.site-footer__contact a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  min-width: var(--tap);
  font-weight: 600;
  text-decoration-color: var(--red-line);
}
.site-footer__nav a[aria-current] { color: var(--red); }
.site-footer__contact .site-footer__phone {
  font: 400 2.25rem/1 var(--f-gothic);
  letter-spacing: .03em;
  text-decoration: none;
  white-space: nowrap;
}
.site-footer__base {
  display: flex;
  flex-wrap: wrap;
  align-items: center;             /* the copyright sits level with the owned-by line (its link is 44px tall) */
  justify-content: space-between;
  gap: var(--sp-2) var(--sp-6);
  margin-top: var(--sp-7);
  padding-top: var(--sp-5);
  border-top: 2px solid var(--ink);
  color: var(--ink);
}
.site-footer__base p { margin: 0; }
.site-footer__base a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  font-weight: 600;
  text-decoration-color: var(--red-line);
}
.site-footer__label--policy { margin-top: var(--sp-5); }
/* 45em: brand across the top, pages and contact side by side. 62.5em: three columns. */
@media (min-width: 45em) {
  .site-footer__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .site-footer__brand { grid-column: 1 / -1; }
}
@media (min-width: 62.5em) {
  .site-footer__grid { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) minmax(0, 1fr); }
  .site-footer__brand { grid-column: auto; }
}

/* quickbar: phones and small tablets (below 56.25em): Call / Email / Cart. Call is the primary (solid
   red) and shows the number; Cart wears the cart count. It is position: sticky at the end of <body>, so it rides the bottom of the screen but takes
   its own space after the footer: it can never cover content, whatever height big text gives it. */
.quickbar {
  position: sticky;
  bottom: 0;
  z-index: 60;
  display: grid;
  grid-template-columns: auto auto auto;   /* each cell gets its label's width, spare room shared */
  padding-bottom: env(safe-area-inset-bottom, 0px);
  background: var(--ink);
  border-top: 2px solid var(--ink);
}
.quickbar a {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-width: 0;
  min-height: 64px;                        /* fixed: with big text the words set the height, not the rem */
  padding: 6px 6px;
  color: var(--on-dark);
  font: 700 1.125rem/1.1 var(--f-text);  /* 18px */
  text-align: center;
  text-decoration: none;
}
.quickbar a + a { border-left: 1px solid var(--on-dark-line); }
.quickbar .quickbar__call {
  display: grid;
  grid-template-columns: auto auto;
  align-content: center;
  justify-content: center;
  align-items: center;
  gap: 2px 6px;
  min-width: min-content;                  /* the cell is never narrower than its number */
  background: var(--red);
}
.quickbar__num {
  grid-column: 1 / -1;
  font: 400 1.375rem/1 var(--f-gothic);   /* 22px League Gothic */
  font-size: min(1.375rem, 7.4vw);         /* very large default text on a small phone: capped, so the
                                              three cells still fit across the screen */
  letter-spacing: .03em;
  white-space: nowrap;
}
@media (hover: hover) and (pointer: fine) { .quickbar a:hover { color: var(--on-dark); background: var(--ink-hover); } }
@media (hover: hover) and (pointer: fine) { .quickbar .quickbar__call:hover { background: var(--red-dark); } }
.quickbar a:focus-visible { outline: 3px solid var(--on-dark); outline-offset: -6px; }
.quickbar svg { width: 24px; height: 24px; fill: currentColor; }
.quickbar__icon { position: relative; display: inline-flex; }
.quickbar .quickbar__count {
  position: absolute;
  top: -9px;
  left: 15px;
  min-width: 24px;
  height: 24px;
  padding: 1px 5px 0;
  border-radius: 12px;
  font-size: 1.125rem;
  box-shadow: 0 0 0 2px var(--ink);
}
.quickbar__cart[aria-current] { box-shadow: inset 0 -4px 0 var(--red); }
/* very large default text on a phone (under 16.5em wide: 390px at 150%): the icons go, so the bar stays
   short; the words stay, and the cart count sits inline before "Cart". */
@media (max-width: 16.49em) {
  .quickbar svg { display: none; }
  .quickbar .quickbar__count { position: static; margin-bottom: 2px; }
}
/* out of the way while the menu is open (the menu has its own Cart, Call and Email) or a form field has focus */
.menu-open .quickbar { display: none; }
body:has(:is(input:not([type="radio"], [type="checkbox"]), select, textarea):focus) .quickbar { display: none; }
@media (min-width: 56.25em) {
  .quickbar { display: none; }
}

/* ==========================================================================
   7. Buttons + links
   ========================================================================== */
.btn {
  --btn-h: 54px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55em;
  min-height: var(--btn-h);
  padding: 10px 22px;
  border: 2px solid var(--ink);
  border-radius: var(--r);
  background: transparent;
  color: var(--ink);
  font: 700 1.0625rem/1.2 var(--f-text);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  overflow-wrap: anywhere;
  transition: background-color .15s ease, color .15s ease, box-shadow .15s ease, transform .1s ease;
}
.btn:active { transform: translate(2px, 2px); }
.btn .icon { width: 1.3em; height: 1.3em; }

/* primary: ink with the red offset */
.btn--primary { background: var(--ink); color: var(--on-dark); box-shadow: var(--shadow-red); }
@media (hover: hover) and (pointer: fine) { .btn--primary:hover { background: var(--red); border-color: var(--red); color: var(--on-dark); box-shadow: var(--shadow-ink); } }
.btn--primary:active { box-shadow: 2px 2px 0 var(--red); }
/* red: calls */
.btn--red { background: var(--red); border-color: var(--red); color: var(--on-dark); box-shadow: var(--shadow-ink); }
@media (hover: hover) and (pointer: fine) { .btn--red:hover { background: var(--red-dark); border-color: var(--red-dark); color: var(--on-dark); } }
/* secondary: ink outline */
.btn--secondary { background: var(--paper-veil); }
@media (hover: hover) and (pointer: fine) { .btn--secondary:hover { background: var(--ink); color: var(--on-dark); } }
/* ghost: text button with a tap-sized box */
.btn--ghost {
  border-color: transparent;
  padding-inline: 8px;
  text-decoration: underline;
  text-decoration-color: var(--red);
  text-underline-offset: .25em;
}
@media (hover: hover) and (pointer: fine) { .btn--ghost:hover { background: var(--red-tint); color: var(--red); } }
/* on dark backgrounds */
.btn--paper { background: var(--on-dark); border-color: var(--on-dark); color: var(--ink); box-shadow: 4px 4px 0 var(--red-hot); }
@media (hover: hover) and (pointer: fine) { .btn--paper:hover { background: var(--on-dark-red); border-color: var(--on-dark-red); color: var(--ink); } }
.btn--outline-light { border-color: var(--on-dark); color: var(--on-dark); }
@media (hover: hover) and (pointer: fine) { .btn--outline-light:hover { background: var(--on-dark-wash); color: var(--on-dark); } }

/* sizes */
.btn--sm { --btn-h: var(--tap); padding: 6px 16px; font-size: 1rem; }
.btn--lg { --btn-h: 62px; padding: 12px 28px; font-size: 1.1875rem; }
.btn--block { display: flex; width: 100%; }
@media (max-width: 29.99em) {
  .btn--lg { padding-inline: 14px; font-size: 1.0625rem; }
}
.btn__stack { display: flex; flex-direction: column; align-items: flex-start; text-align: left; }
.btn__sub { font-size: var(--fs-note); font-weight: 600; overflow-wrap: anywhere; }

/* inline links that must be tap-sized: Call / email in running text */
.tap {
  display: inline;
  padding-block: .55em;      /* grows the hit box to >= 44px without stretching the line */
  overflow-wrap: anywhere;   /* a bare domain (thecastbulletshop.com) may break rather than run off a phone */
  font-weight: 700;
  color: var(--red);
  text-decoration: underline;
  text-decoration-thickness: 2px;
}
.ask .tap { display: inline-flex; align-items: center; min-height: var(--tap); padding-block: 0; }
@media (hover: hover) and (pointer: fine) { .tap:hover { color: var(--red-dark); } }

/* a standalone "more" link with an arrow */
.textlink {
  display: inline-block;          /* the arrow follows the last word when the link wraps */
  padding-block: 8px;             /* >= 44px tall with the line height */
  font-weight: 700;
  color: var(--red);
  text-decoration: underline;
  text-decoration-thickness: 2px;
}
.textlink::after {
  content: "";
  display: inline-block;
  vertical-align: -.08em;
  width: .85em; height: .85em;
  margin-left: .4em;
  background: currentColor;
  -webkit-mask: var(--arrow) center / contain no-repeat;
  mask: var(--arrow) center / contain no-repeat;
}

/* "Questions? Call (770) 735-4453 or email us" */
.ask {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 .4em;
  margin: var(--sp-4) 0 0;
  font-size: var(--fs-body);
  font-weight: 600;
}
.ask__num {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  font: 400 2rem/1 var(--f-gothic);
  letter-spacing: .03em;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
  border-bottom: 3px solid var(--red);
}
@media (hover: hover) and (pointer: fine) { .ask__num:hover { color: var(--red); } }

/* ==========================================================================
   8. Page parts: section heads, page header, breadcrumbs, fact strip, plate
   ========================================================================== */
.sec-head { max-width: 46rem; margin-bottom: var(--sp-6); }
.sec-head > :last-child { margin-bottom: 0; }
.sec-head--center { margin-inline: auto; text-align: center; }
.sec-head__intro { font-size: var(--fs-lede); line-height: 1.5; max-width: 34em; }
.sec-head--center .sec-head__intro { margin-inline: auto; }

/* interior page header: shop, about, gallery, faq, contact, cart pages, product pages */
.page-head {
  position: relative;
  padding: var(--sp-5) 0 var(--sp-7);
}
.page-head .wrap > :last-child { margin-bottom: 0; }   /* one bottom space, with or without a lede */
.page-head::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 6px;
  background: var(--rule-double);
  width: min(100% - 2 * var(--gutter), var(--maxw));
  margin-inline: auto;
}
.page-head__title {
  margin: 0 0 .3em;
  font: 400 var(--fs-h1)/1 var(--f-display);
  font-size: min(var(--fs-h1), 12.5vw); /* only bites with very large default text on a small phone,
                                           where one long word would otherwise be wider than the screen */
  text-wrap: balance;
}
.page-head__lede {
  max-width: 34em;
  margin: 0;
  font-size: var(--fs-lede);
  line-height: 1.5;
}
.page-head .ask { margin-top: var(--sp-3); }

.crumbs { margin: 0 0 var(--sp-4); font-size: var(--fs-note); }
.crumbs ol {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 .35em;
  margin: 0;
  padding: 0;
}
.crumbs li { display: inline-flex; align-items: center; gap: .35em; }
.crumbs li + li::before {           /* a plain chevron: "Home > Shop > ..." */
  content: "\203A";
  content: "\203A" / "";
  font-weight: 700;
  font-size: 1.25em;
  line-height: 1;
  color: var(--red);
}
.crumbs a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  font-weight: 600;
  text-decoration-color: var(--red-line);
}
.crumbs [aria-current] { font-weight: 400; color: var(--ink-2); }

/* fact strip */
.facts {
  list-style: none;
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-3) var(--sp-5);
  margin: 0;
  padding: 16px 0 15px;
  border-top: 3px solid var(--ink);
  border-bottom: 3px solid var(--ink);
  font-size: var(--fs-body);
  line-height: 1.35;
}
.facts::before, .facts::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  height: 1px;
  background: var(--ink);
}
.facts::before { top: 2px; }
.facts::after { bottom: 2px; }
.facts li { display: flex; align-items: baseline; gap: .55em; min-width: 0; }
.facts li::before {
  content: "";
  flex: none;
  align-self: flex-start;            /* sits on the first line when a fact wraps */
  margin-top: .28em;
  width: .8em; height: .8em;
  background: var(--red);
  -webkit-mask: var(--star) center / contain no-repeat;
  mask: var(--star) center / contain no-repeat;
}
@media (min-width: 37.5em) {
  .facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 68.75em) {
  .facts { display: flex; justify-content: space-between; }
}

/* plate: the framed print (3px rule plus a fine inner rule). Holds a product photo (figure.plate), or
   anything that should read as a framed plate. Optional tab on top: <p class="plate__tab">Pictured</p>. */
.plate {
  position: relative;
  margin: 0;
  padding: clamp(16px, 2.4vw, 24px);
  background: var(--paper-hi);
  border: 3px solid var(--ink);
  outline: 1px solid var(--ink);
  outline-offset: -9px;
}
.plate:has(> .plate__tab) { padding-top: 34px; }
.plate__tab {
  position: absolute;
  top: -15px;
  left: 50%;
  transform: translateX(-50%);
  margin: 0;
  padding: 4px 14px 3px;
  background: var(--ink);
  color: var(--on-dark);
  font: 700 var(--fs-label)/1.3 var(--f-text);
  letter-spacing: .2em;
  text-transform: uppercase;
  white-space: nowrap;
}
.plate > img { display: block; width: 100%; height: auto; border: 1px solid var(--rule-strong); }
.plate__cap {
  margin-top: var(--sp-3);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--ink);
  font-size: var(--fs-note);
  color: var(--ink-2);
  text-align: center;
}

/* ==========================================================================
   9. Sheet (ruled frame)
   ========================================================================== */
.sheet {
  position: relative;
  margin-inline: calc(-1 * var(--gutter));
  padding: var(--sp-6) var(--gutter);
  background: var(--paper-hi);
  border-top: 5px solid var(--ink);
  border-bottom: 5px solid var(--ink);
}
.sheet::before, .sheet::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  height: 1.5px;
  background: var(--ink);
}
.sheet::before { top: 4px; }
.sheet::after { bottom: 4px; }
@media (min-width: 40em) {
  .sheet {
    margin-inline: 0;
    padding: clamp(36px, 5vw, 64px) clamp(24px, 5vw, 64px);
    border: 4px solid var(--ink);
    outline: 1.5px solid var(--ink);
    outline-offset: -12px;
  }
  .sheet::before, .sheet::after { display: none; }
}

.sheet__head { text-align: center; margin-bottom: var(--sp-6); }
.sheet__title {
  margin: 0 0 .1em;
  font: 400 clamp(3rem, 1.6rem + 6vw, 6.25rem)/.95 var(--f-display);
  text-shadow: .03em .025em 0 var(--red-hot);
}
.sheet__sub { margin: 0; font-size: var(--fs-lede); line-height: 1.4; }
/* ==========================================================================
   10. Product photo cards (WooCommerce loop shape)
   ul.products > li.product > a.product__link [span.product__photo > img, h3, spec, meta, .price]
   Cards are GENERATED by tools/build_products.py between <!-- product-cards:<which> --> markers.
   ========================================================================== */
.products {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
  gap: var(--sp-5);
  margin: 0;
  padding: 0;
}
.product {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--paper-hi);
  border: 2px solid var(--ink);
  border-radius: var(--r-sm);
}
.product__link {
  display: flex;
  flex: 1;
  flex-direction: column;
  padding: var(--sp-3) var(--sp-3) var(--sp-4);
  color: var(--ink);
  text-decoration: none;
}
@media (hover: hover) and (pointer: fine) { .product__link:hover { color: var(--ink); background: var(--red-tint); } }
.product__link:focus-visible { outline-offset: -5px; }
/* the square photo on paper, in a fine double rule (the plate's frame, small) */
.product__photo {
  display: block;
  margin-bottom: var(--sp-3);
  padding: 4px;
  background: var(--paper-hi);
  border: 1px solid var(--ink);
}
.product__photo img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  border: 1px solid var(--rule-strong);
}
.product__badges {
  position: absolute;
  top: 12px; left: 12px;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 6px;
}
/* the client's code is numerals: League Gothic, big */
.product__title {
  margin: 0 0 var(--sp-1);
  font: 400 2rem/1.02 var(--f-gothic);
  letter-spacing: .02em;
  overflow-wrap: break-word;
}
@media (hover: hover) and (pointer: fine) { .product__link:hover .product__title { color: var(--red); } }
.product__spec { margin: 0; font-size: var(--fs-note); font-weight: 700; line-height: 1.4; }
.product__meta { margin: 0 0 var(--sp-3); font-size: var(--fs-note); line-height: 1.4; }
.product .price { margin-top: auto; }
/* featured cards (a slug-list marker): the client's blurb and an "Order Now" cue under the price */
.product__note { display: block; margin: var(--sp-3) 0 0; padding-top: var(--sp-3); border-top: 1px dotted var(--rule-strong); font-size: var(--fs-note); line-height: 1.45; }
.product__cta {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tap);
  margin-top: var(--sp-3);
  background: var(--ink);
  color: var(--on-dark);
  font: 700 1.0625rem/1.2 var(--f-text);
  border-radius: var(--r);
  box-shadow: var(--shadow-sm-red);
}
@media (hover: hover) and (pointer: fine) { .product__link:hover .product__cta { background: var(--red); } }
.product__actions { padding: 0 var(--sp-3) var(--sp-4); }

/* Phones (under 37.5em), and .products--rows at any width: each card is a row, photo on the left
   (40% of the card, so the bullet stays the biggest thing on it), name, spec, meta and price beside it. */
@media (max-width: 37.49em) {
  .products { gap: var(--sp-3); }
  .products .product__link {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    grid-template-areas: "photo title" "photo spec" "photo meta" "photo price" "note note" "cta cta";
    grid-template-rows: auto auto auto 1fr;
    align-items: start;
    column-gap: var(--sp-3);
    padding: var(--sp-3);
  }
  .products .product__note { grid-area: note; }
  .products .product__cta { grid-area: cta; }
  .products .product__photo { grid-area: photo; margin: 0; padding: 3px; }
  .products .product__title { grid-area: title; font-size: min(1.75rem, 8.5vw); }
  .products .product__spec { grid-area: spec; }
  .products .product__meta { grid-area: meta; margin-bottom: 0; }
  .products .price { grid-area: price; align-self: end; margin-top: var(--sp-2); }
}
@media (min-width: 37.5em) {
  .products--rows { grid-template-columns: minmax(0, 1fr); }
  .products--rows .product__link {
    display: grid;
    grid-template-columns: 160px minmax(0, 1fr);
    grid-template-areas: "photo title" "photo spec" "photo meta" "photo price";
    grid-template-rows: auto auto auto 1fr;
    align-items: start;
    column-gap: var(--sp-4);
  }
  .products--rows .product__photo { grid-area: photo; margin: 0; }
  .products--rows .product__title { grid-area: title; }
  .products--rows .product__spec { grid-area: spec; }
  .products--rows .product__meta { grid-area: meta; }
  .products--rows .price { grid-area: price; align-self: end; }
}

/* price element: one place, one look */
.price {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0 .4em;
  margin: 0;
}
.price .amount {
  font: 400 var(--fs-num)/1 var(--f-gothic);
  letter-spacing: .01em;
}
.price__unit,
.price__from { font-size: var(--fs-note); font-weight: 600; }

/* ==========================================================================
   10b. Product page: code title, two-column layout, spec list, buy box, cart link
   ========================================================================== */
/* product names are the client's codes (38-125-TC, BPXL 4440-205-RF): numerals, so League Gothic */
.page-head__title--product {
  font: 400 clamp(3.25rem, 2.2rem + 4.4vw, 5.5rem)/.95 var(--f-gothic);
  font-size: min(clamp(3.25rem, 2.2rem + 4.4vw, 5.5rem), 15vw);
  letter-spacing: .015em;
}
.product-main {
  display: grid;
  gap: var(--sp-7);
  padding-block: var(--sp-7) var(--section-y);
}
@media (min-width: 60em) {
  .product-main { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); gap: clamp(32px, 4vw, 72px); align-items: start; }
}

/* spec list: dl, one dt + dd pair per fact */
.spec-list {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  margin: 0 0 var(--sp-6);
  border-top: 3px solid var(--ink);
}
.spec-list dt,
.spec-list dd {
  margin: 0;
  padding: 10px 0;
  border-bottom: 1px dotted var(--rule-strong);
  line-height: calc(var(--fs-body) * var(--lh-body));
}
.spec-list dt {
  padding-right: var(--sp-5);
  font: 700 var(--fs-label)/calc(var(--fs-body) * var(--lh-body)) var(--f-text);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.spec-list dd { font-weight: 600; }
/* narrow: each label sits above its value. On any screen under 16em (only reached with very large
   default text on a small phone) and inside any container (an ancestor with container-type:
   inline-size) narrower than 25rem. */
@media (max-width: 15.99em) {
  .spec-list { grid-template-columns: minmax(0, 1fr); }
  .spec-list dt { padding: 10px 0 0; border-bottom: 0; }
  .spec-list dd { padding-top: 0; }
}
@container (max-width: 25rem) {
  .spec-list { grid-template-columns: minmax(0, 1fr); }
  .spec-list dt { padding: 10px 0 0; border-bottom: 0; }
  .spec-list dd { padding-top: 0; }
}

/* buy box (WooCommerce form.cart): Pieces picker, quantity, total, Add to cart, #added */
.buybox {
  display: grid;
  gap: var(--sp-5);
  margin: 0;
  padding: var(--sp-5) var(--sp-4);
  background: var(--paper-hi);
  border: 3px solid var(--ink);
  box-shadow: var(--shadow-red);
}
@media (min-width: 37.5em) { .buybox { padding: var(--sp-6); } }
.buybox__qty {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2) var(--sp-4);
}
.buybox__total {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0 var(--sp-3);
  margin: 0;
  padding-top: var(--sp-3);
  border-top: 2px solid var(--ink);
  font-weight: 700;
}
.buybox__total-num { font: 400 2.5rem/1 var(--f-gothic); letter-spacing: .02em; }
.buybox__bullets { flex-basis: 100%; font-size: var(--fs-note); font-weight: 600; text-align: right; }
html:not(.js) .buybox__total { display: none; }   /* the total is worked out by js/site.js */
/* the add-to-cart message (WooCommerce's "added to your cart" notice), under Add to cart: js/product.js
   fills it in ("2 × 38-125-TC, 1,000 pieces — $160"), shows it and focuses it */
.buybox__added { margin: 0; }
.buybox__added:focus { outline: 3px solid var(--red); outline-offset: 3px; }
.buybox__added-what { margin: 0; font-size: var(--fs-body); font-weight: 600; }
.buybox__added-more { margin: var(--sp-2) 0 0; }
.buybox__added-actions { margin-top: var(--sp-4); }
.buybox__added-actions .btn { flex: 1 1 10rem; }

/* cart link (partials/header.html): the last thing in the header row, after Call, so Tab follows what
   you see: logo | Menu | Call | Cart (48em-74.99em), logo | nav | Call | Cart (from 75em). Below 48em
   there is no room beside the logo, so the cart is the first row of the open menu (.site-nav__cart) and
   the third cell of the quickbar. The count is the sum of the quantities in the cart (js/cart.js), a red
   badge on the cart's corner; it hides while the cart is empty. 75em-89.99em, where the row is full,
   the word "Cart" is visually hidden (still read out) and the logo is 220px. */
.cart-link {
  position: relative;
  display: none;
  align-items: center;
  gap: 8px;
  order: 4;
  min-height: 48px;
  padding: 6px 14px 6px 12px;
  border: 2px solid var(--ink);
  border-radius: var(--r);
  background: var(--paper-hi);
  color: var(--ink);
  font: 700 1.0625rem/1 var(--f-text);
  text-decoration: none;
}
@media (hover: hover) and (pointer: fine) { .cart-link:hover { background: var(--paper-deep); color: var(--ink); } }
.cart-link .icon { flex: none; width: 24px; height: 24px; fill: currentColor; }
.cart-link[aria-current] { border-color: var(--red); box-shadow: inset 0 -3px 0 var(--red); }
.cart-link__count {
  display: inline-grid;
  place-items: center;
  min-width: 1.5em;
  height: 1.5em;
  padding: 0 .3em;
  border-radius: .75em;
  background: var(--red);
  color: var(--on-dark);
  font: 400 1.25rem/1 var(--f-gothic);
  letter-spacing: .02em;
}
.cart-link__count[hidden] { display: none; }
/* in the bar the count sits on the link's top right corner, so it adds no width and covers no text.
   Under 48em the bar has no cart link, so the Menu button wears the same badge ("Menu, 3 items in your
   cart"): a phone shows what is in the cart without opening the menu, whose first row is the cart */
.nav-toggle { position: relative; }
.cart-link .cart-link__count,
.nav-toggle .nav-toggle__count {
  position: absolute;
  top: -11px;
  right: -11px;
  min-width: 26px;
  height: 26px;
  padding: 1px 6px 0;
  border-radius: 13px;
  font-size: 1.1875rem;
  box-shadow: 0 0 0 2px var(--paper);
}
.cart-link__label { line-height: 1; }
/* the menu row (phones): a secondary button with the count after the word */
.site-nav__cart .icon { fill: currentColor; }
.site-nav__cart[aria-current] { border-color: var(--red); }
@media (min-width: 37.5em) and (max-width: 47.99em) {
  .nav-toggle { margin-right: 6px; }   /* Call follows Menu here: keep its badge clear of the Call button */
}
@media (min-width: 48em) {
  .cart-link { display: inline-flex; }
  .site-nav__cart,
  .nav-toggle .nav-toggle__count { display: none; }
}
@media (min-width: 75em) and (max-width: 89.99em) {
  .cart-link { padding-inline: 10px; }
  .cart-link__label {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
}

/* ==========================================================================
   11. Tables, ledger rows, steps
   ========================================================================== */
.data-table {
  width: 100%;
  font-size: var(--fs-body);
}
.data-table caption {
  margin-bottom: var(--sp-2);
  font-size: var(--fs-note);
  text-align: left;
}
.data-table thead th {
  padding: 10px 12px;
  background: var(--ink);
  color: var(--on-dark);
  font: 700 var(--fs-label)/1.25 var(--f-text);
  letter-spacing: .1em;
  text-transform: uppercase;
  text-align: left;
  vertical-align: bottom;
}
.data-table tbody th,
.data-table td {
  padding: 12px;
  border-bottom: 1px dotted var(--rule-strong);
  text-align: left;
  vertical-align: baseline;
}
.data-table tbody th { font-weight: 700; }
.data-table tbody th a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  text-decoration-color: var(--red-line);
}
.data-table tbody tr:nth-child(even) { background: var(--stripe); }
.data-table .num { text-align: right; white-space: nowrap; }
.data-table thead th.num { white-space: normal; max-width: 6.5em; }
.data-table td.num { font: 400 1.75rem/1 var(--f-gothic); letter-spacing: .02em; }
/* phones (and big text): rows become labelled blocks */
@media (max-width: 39.99em) {
  .data-table--stack caption { display: block; }
  .data-table--stack thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .data-table--stack,
  .data-table--stack tbody,
  .data-table--stack tr,
  .data-table--stack th,
  .data-table--stack td { display: block; }
  .data-table--stack tr {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    padding: var(--sp-3) 0;
    border-bottom: 1px dotted var(--rule-strong);
  }
  .data-table--stack tbody tr:nth-child(even) { background: none; }
  .data-table--stack tbody th { grid-column: 1 / -1; padding: 0 0 var(--sp-1); border: 0; }
  .data-table--stack td,
  .data-table--stack td.num { padding: 0; border: 0; text-align: left; }
  .data-table--stack td::before {
    content: attr(data-label);
    display: block;
    margin-bottom: 2px;
    font: 700 var(--fs-label)/1.2 var(--f-text);
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--ink-2);
  }
}
/* very narrow in em (only with very large default text on a phone): two figures to a row, so a price
   like $111.25 and its label still fit */
@media (max-width: 17.49em) {
  .data-table--stack tr { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: var(--sp-2); }
}

/* ledger row with dotted leaders: "Boxes of 400 or 500 ........ $27-$40" */
.ledger {
  list-style: none;
  width: 100%;
  margin: 0 0 var(--sp-5);
  padding: 0;
  border-top: 1px solid var(--ink);
}
.ledger li {
  display: flex;
  align-items: flex-end;
  align-items: last baseline;
  gap: 10px;
  padding: 10px 0;
  border-bottom: 1px solid var(--rule);
}
.ledger__what { font-weight: 600; min-width: 0; }
.ledger__dots {
  flex: 1;
  min-width: 16px;
  border-bottom: 3px dotted var(--rule-strong);
  transform: translateY(-.3em);
}
.ledger__price {
  font: 400 clamp(1.625rem, 1.4rem + .8vw, 1.875rem)/1 var(--f-gothic);
  letter-spacing: .02em;
  white-space: nowrap;
}

/* numbered steps: real sequences only */
.steps {
  list-style: none;
  counter-reset: step;
  margin: 0 0 var(--sp-5);
  padding: 0;
}
.steps li {
  counter-increment: step;
  position: relative;
  min-height: 44px;
  padding: 6px 0 var(--sp-3) 60px;
}
.steps li + li { border-top: 1px dotted var(--rule-strong); padding-top: var(--sp-3); }
.steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 2px;
  display: grid;
  place-items: center;
  width: 44px; height: 44px;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: var(--paper-hi);
  font: 400 1.75rem/1 var(--f-gothic);
}
.steps li + li::before { top: calc(var(--sp-3) - 4px); }

/* ==========================================================================
   12. Notices + badges + chips + quotes
   ========================================================================== */
.notice {
  margin: var(--sp-5) 0 0;
  padding: var(--sp-3) var(--sp-4);
  border: 2px solid var(--ink);
  border-left-width: 8px;
  background: var(--paper-deep);
  font-size: var(--fs-note);
  line-height: 1.5;
}
.notice > :last-child { margin-bottom: 0; }
.notice__title {
  margin: 0 0 .3em;
  font: 700 1.1875rem/1.3 var(--f-text);
}
.notice--info { border-color: var(--ink); }
.notice--warning { border-color: var(--red); background: var(--warn-bg); }
/* success: the add-to-cart message, a sent form. Put focus on it (tabindex="-1"). */
.notice--success { border-color: var(--ink); background: var(--paper-hi); box-shadow: var(--shadow-sm-red); }
.notice--success .notice__title { display: flex; align-items: center; gap: .5em; }
.notice--success .notice__title::before {
  content: "";
  flex: none;
  width: 1.3em; height: 1.3em;
  border-radius: 50%;
  background: var(--ink) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9.5 16.2 5.3 12l-1.6 1.6 5.8 5.8L20.3 8.6 18.7 7z' fill='%23F1E7CF'/%3E%3C/svg%3E") center / 70% no-repeat;
}
@media (min-width: 37.5em) { .notice { padding: var(--sp-4) var(--sp-5); } }
.notice--warning .notice__title { color: var(--red); }
.notice a:not(.btn) { font-weight: 700; color: var(--red); }   /* write emails as tony@<wbr>outlawbullets.com */

.badge {
  display: inline-flex;
  align-items: center;
  gap: .4em;
  padding: 4px 9px 3px;
  border: 2px solid var(--red);
  border-radius: var(--r-sm);
  background: var(--paper-hi);
  color: var(--red);
  font: 700 var(--fs-label)/1.2 var(--f-text);   /* 16px: the label floor */
  letter-spacing: .1em;
  text-transform: uppercase;
}
@media (min-width: 20em) { .badge { white-space: nowrap; } }   /* as .keep: may wrap only with very large text on a phone */
.badge--solid { background: var(--red); color: var(--on-dark); }
.badge--ink { border-color: var(--ink); color: var(--ink); }
.badge--stamp { transform: rotate(-3deg); background: var(--red); color: var(--on-dark); box-shadow: 2px 2px 0 var(--ink); }

/* filter chips (caliber or line filter). Buttons with aria-pressed. */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin: 0;
  padding: 0;
}
.chips__label { flex-basis: 100%; margin: 0 0 var(--sp-1); }
.chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tap);
  min-width: var(--tap);
  padding: 4px 16px;
  border: 2px solid var(--ink);
  border-radius: var(--r);
  background: var(--paper-hi);
  color: var(--ink);
  font: 400 1.5rem/1 var(--f-gothic);
  letter-spacing: .04em;
  white-space: nowrap;           /* ".44-40" never breaks at its hyphen */
  cursor: pointer;
}
@media (hover: hover) and (pointer: fine) { .chip:hover { background: var(--paper-deep); } }
.chip:active { background: var(--paper-deep); }
.chip[aria-pressed="true"] { background: var(--ink); color: var(--on-dark); box-shadow: var(--shadow-sm-red); }
.chip--text { font: 700 1.0625rem/1 var(--f-text); letter-spacing: 0; }

/* pull quote */
.pull-quote {
  margin: 0;
  padding: clamp(24px, 4vw, 44px);
  background: var(--grain), var(--paper-deep);
  border-top: 6px solid var(--ink);
}
.pull-quote blockquote { margin: 0; }
.pull-quote__ask { font-size: var(--fs-lede); line-height: 1.45; }
.pull-quote__label {
  display: block;
  margin-bottom: .35em;
  font: 700 var(--fs-label)/1.3 var(--f-text);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--red);
}
.pull-quote__answer {
  margin: .5em 0 .5em;
  font: 400 clamp(1.875rem, 1.2rem + 2.4vw, 2.875rem)/1.08 var(--f-display);
  font-size: min(clamp(1.875rem, 1.2rem + 2.4vw, 2.875rem), 9vw);
  color: var(--red);
  text-wrap: balance;
}
.pull-quote__after { font-size: var(--fs-lede); line-height: 1.5; }
.pull-quote__sig {
  display: flex;
  align-items: center;
  gap: .7em;
  margin-top: var(--sp-4);
  font: 700 var(--fs-body)/1.3 var(--f-text);
}
.pull-quote__sig::before { content: ""; width: 44px; height: 2px; background: var(--ink); }

/* photo: a real photo on a mount, with an optional caption and credit line.
   figure.photo > img + figcaption.photo__cap (+ span.photo__credit). --tilt leans it a little. */
.photo {
  margin: 0;
  padding: 10px 10px 12px;
  background: var(--photo-mat);
  border: 1px solid var(--rule);
  box-shadow: var(--shadow-photo);
}
.photo img { display: block; width: 100%; height: auto; }
.photo__cap { margin-top: 10px; font-size: var(--fs-note); line-height: 1.4; }
.photo__credit { display: block; margin-top: 2px; font-size: var(--fs-note); color: var(--ink-2); }
.photo--tilt { transform: rotate(-1.2deg); }
@media (max-width: 22.49em) {        /* narrow phones: a rotated mount would reach into the gutter */
  .photo--tilt { transform: none; }
}

/* ==========================================================================
   13. Forms
   ========================================================================== */
.form { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-5); max-width: 40rem; }
.form__legend-note { margin: 0; font-size: var(--fs-note); }
.field { display: grid; gap: 6px; min-width: 0; }
.field__label {
  font: 700 1.125rem/1.3 var(--f-text);
}
.field__req {
  margin-left: .35em;
  font: 700 var(--fs-label)/1 var(--f-text);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--red);
}
.field__help { margin: 0; font-size: var(--fs-note); line-height: 1.45; color: var(--ink-2); }
.field__error {
  display: flex;
  align-items: flex-start;
  gap: .45em;
  margin: 0;
  font: 700 var(--fs-note)/1.4 var(--f-text);
  color: var(--red);
  overflow-wrap: anywhere;   /* "name@example.com," may break rather than run off a narrow screen */
}
.field__error::before,
.error-summary__title::before {
  content: "!";
  flex: none;
  display: grid;
  place-items: center;
  width: 1.3em; height: 1.3em;
  margin-top: .05em;
  border-radius: 50%;
  background: var(--red);
  color: var(--on-dark);
  font-size: .85em;
}

/* error summary: above the fields when a send fails, one link per problem; focus moves to it.
   div.error-summary[role=group][tabindex=-1][aria-labelledby] > .error-summary__title + ul.error-summary__list */
.error-summary {
  padding: var(--sp-4);
  border: 3px solid var(--red);
  border-left-width: 8px;
  background: var(--red-wash);
}
.error-summary:focus { outline: 3px solid var(--ink); outline-offset: 3px; }
.error-summary__title {
  display: flex;
  align-items: flex-start;
  gap: .5em;
  margin: 0 0 var(--sp-2);
  font: 700 var(--fs-h4)/1.3 var(--f-text);
  color: var(--red);
}
.error-summary__title::before { margin-top: .02em; }
.error-summary__list { list-style: none; margin: 0; padding: 0; }
.error-summary__list li + li { border-top: 1px dotted var(--rule-strong); }
.error-summary__list a {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding-block: 6px;
  font-weight: 700;
  color: var(--red);
  text-decoration-thickness: 2px;
  overflow-wrap: anywhere;
}
@media (hover: hover) and (pointer: fine) { .error-summary__list a:hover { color: var(--red-dark); } }
@media (min-width: 37.5em) { .error-summary { padding: var(--sp-4) var(--sp-5); } }
.input, .select, .textarea {
  width: 100%;
  min-width: 0;
  min-height: var(--tap-lg);
  padding: 12px 14px;
  border: 2px solid var(--ink);
  border-radius: var(--r);
  background: var(--paper-hi);
  color: var(--ink);
  font-size: 1.1875rem;   /* >= 16px so phones do not zoom */
  line-height: 1.3;
}
.textarea { min-height: 150px; resize: vertical; }
.select {
  appearance: none;
  padding-right: 48px;
  background:
    linear-gradient(45deg, transparent 50%, var(--ink) 50%) right 22px center / 8px 8px no-repeat,
    linear-gradient(-45deg, transparent 50%, var(--ink) 50%) right 14px center / 8px 8px no-repeat,
    var(--paper-hi);
}
.input:focus, .select:focus, .textarea:focus { outline: 3px solid var(--red); outline-offset: 2px; }
.input::placeholder, .textarea::placeholder { color: var(--placeholder); }
.field--error .input,
.field--error .select,
.field--error .textarea,
[aria-invalid="true"] { border-color: var(--red); border-width: 3px; background: var(--red-wash); }

/* number stepper: [-] [ 2 ] [+] */
.stepper {
  display: inline-flex;
  align-items: stretch;
  width: max-content;
  border: 2px solid var(--ink);
  border-radius: var(--r);
  background: var(--paper-hi);
}
.stepper__btn {
  display: grid;
  place-items: center;
  width: var(--tap-lg);
  min-height: var(--tap-lg);
  padding: 0;
  border: 0;
  background: var(--paper-deep);
  color: var(--ink);
  cursor: pointer;
}
@media (hover: hover) and (pointer: fine) { .stepper__btn:hover { background: var(--ink); color: var(--on-dark); } }
.stepper__btn:active { background: var(--ink); color: var(--on-dark); }
.stepper__btn svg { width: 20px; height: 20px; fill: currentColor; }
.stepper__btn:first-child { border-right: 2px solid var(--ink); }
.stepper__btn:last-child { border-left: 2px solid var(--ink); }
.stepper__input {
  width: 4.2ch;
  min-width: 64px;
  min-height: var(--tap-lg);       /* without JS the buttons are hidden: the field alone stays 56px tall */
  padding: 0 4px;
  border: 0;
  background: transparent;
  font: 400 2rem/1 var(--f-gothic);
  text-align: center;
  -moz-appearance: textfield;
  appearance: textfield;
}
.stepper__input::-webkit-outer-spin-button,
.stepper__input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.stepper__input:focus { outline: 3px solid var(--red); outline-offset: 0; }
html:not(.js) .stepper__btn { display: none; }

/* checkbox + radio */
.check {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  min-height: var(--tap);
  padding: 8px 0;
  font-weight: 600;
  cursor: pointer;
}
.check input {
  flex: none;
  width: 28px; height: 28px;
  margin: 0;
  accent-color: var(--red);
  cursor: pointer;
}

/* pickers: radio cards. fieldset.picker > legend.picker__legend + .picker__opts > label.choice >
   input[type=radio] + span.choice__body. The buy box's Pieces picker (.picker--tiers: "1,000 pieces / $80"). */
.picker { margin: 0; padding: 0; border: 0; min-width: 0; }
.picker__legend { padding: 0; margin-bottom: var(--sp-2); font: 700 1.125rem/1.3 var(--f-text); }
.picker__help { margin: calc(var(--sp-1) * -1) 0 var(--sp-3); }
.picker__opts { display: grid; gap: var(--sp-2); grid-template-columns: repeat(auto-fill, minmax(min(100%, 10.5rem), 1fr)); }
.choice__name { white-space: nowrap; }
.choice { position: relative; display: grid; cursor: pointer; }   /* grid: the card fills the row height */
.choice input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.choice__body {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 0 10px;
  min-height: 68px;
  padding: 10px 12px;
  border: 2px solid var(--ink);
  border-radius: var(--r);
  background: var(--paper-hi);
}
.choice__body::before {   /* the radio dot */
  content: "";
  grid-row: span 2;
  width: 24px; height: 24px;
  border: 2px solid var(--ink);
  border-radius: 50%;
  background: var(--paper-hi);
}
.choice__name { font-weight: 700; line-height: 1.25; }
.choice__price { font: 400 2rem/1 var(--f-gothic); letter-spacing: .02em; }
@media (hover: hover) and (pointer: fine) { .choice:hover .choice__body { background: var(--paper-deep); } }
.choice input:checked + .choice__body { border-width: 3px; padding: 9px 11px; border-color: var(--red); background: var(--red-wash); box-shadow: var(--shadow-sm-red); }
.choice input:checked + .choice__body::before { border-color: var(--red); background: radial-gradient(circle, var(--red) 0 45%, var(--paper-hi) 50%); }
.choice input:focus-visible + .choice__body { outline: 3px solid var(--red); outline-offset: 3px; }

/* ==========================================================================
   14. Team block, gallery + lightbox, FAQ accordion, shipping callout
   ========================================================================== */
/* team block: the team photo (figure.photo) beside its words. section.team > figure.photo.team__photo + div.team__text */
.team { display: grid; gap: var(--sp-6); align-items: center; }
.team__photo { width: min(100%, 30rem); }
.team__text > :last-child { margin-bottom: 0; }
@media (min-width: 56.25em) {
  .team { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--sp-7); }
  .team--flip .team__photo { order: 2; justify-self: end; }
}

/* gallery: ul.gallery > li.gallery__item > button.gallery__btn[data-lightbox-src] > img. Two columns on
   phones, more as the screen grows; thumbnails are cropped 3:4 (the lightbox shows the whole photo).
   js/lightbox.js opens the lightbox; without JS the thumbnails are just photos. */
.gallery {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 8.5rem), 1fr));
  gap: var(--sp-3);
  margin: 0;
  padding: 0;
}
@media (min-width: 48em) {
  .gallery { grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); gap: var(--sp-5); }
  .gallery__item--wide { grid-column: span 2; }
  .gallery__item--wide .gallery__btn img { aspect-ratio: 3 / 2; height: 100%; }
}
.gallery__item { min-width: 0; }
.gallery__btn {
  display: block;
  width: 100%;
  height: 100%;
  padding: 6px;
  border: 1px solid var(--rule);
  border-radius: 0;
  background: var(--photo-mat);
  box-shadow: var(--shadow-photo);
  color: inherit;
  cursor: zoom-in;
}
.gallery__btn img { display: block; width: 100%; height: auto; aspect-ratio: 3 / 4; object-fit: cover; }
@media (hover: hover) and (pointer: fine) { .gallery__btn:hover { border-color: var(--ink); box-shadow: var(--shadow-sm-red); } }
html:not(.js) .gallery__btn { cursor: default; }

/* lightbox: one <dialog class="lightbox"> built by js/lightbox.js (showModal: the page behind is inert,
   Escape closes, focus returns to the thumbnail). Arrow keys and the side buttons step through the group. */
.lightbox {
  width: 100%;
  max-width: none;
  height: 100%;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: #14110E;
  color: var(--on-dark);
}
.lightbox::backdrop { background: rgba(20, 17, 14, .92); }
.lightbox[open] {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto 1fr auto;   /* 1fr = minmax(auto, 1fr): the photo row never shrinks below the
                                          photo's floor plus its caption, so nothing overlaps the buttons */
  overflow-y: auto;                 /* with very large text on a small or landscape phone the dialog scrolls,
                                       rather than squeezing the photo to nothing */
  overscroll-behavior: contain;
}
.lightbox__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--gutter);
}
.lightbox__count { margin: 0; font: 400 1.5rem/1 var(--f-gothic); letter-spacing: .04em; color: var(--on-dark-2); }
.lightbox__fig {
  display: grid;
  grid-template-rows: minmax(min(60dvh, 20rem), 1fr) auto;
  justify-items: center;
  margin: 0;
  padding: 0 var(--gutter);
  touch-action: pan-y pinch-zoom;   /* a sideways swipe steps through the photos (js/lightbox.js) */
}
.lightbox__img {
  display: block;
  max-width: 100%;
  max-height: max(min(60dvh, 20rem), calc(100dvh - 12rem));   /* fits the screen beside the bar, caption and
                                                                buttons, but never below the floor */
  width: auto;
  height: auto;
  min-height: min(60dvh, 20rem);
  object-fit: contain;
  align-self: center;
  background: var(--paper-deep);
}
.lightbox__cap {
  max-width: 44em;
  margin: var(--sp-3) 0 0;
  font-size: var(--fs-note);
  line-height: 1.45;
  color: var(--on-dark);
  text-align: center;
}
.lightbox__cap .photo__credit { color: var(--on-dark-2); }
.lightbox__nav {
  display: flex;
  justify-content: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--gutter) calc(var(--sp-3) + env(safe-area-inset-bottom, 0px));
}
.lightbox__nav .btn { flex: 1 1 0; max-width: 14rem; }
.lightbox .btn { overflow-wrap: normal; white-space: nowrap; }
@media (max-width: 16.49em) {       /* very large text on a small phone: Previous / Next become arrows */
  .lightbox__nav .btn { padding-inline: 0; }
  .lightbox__nav .btn .lightbox__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}
.lightbox :focus-visible { outline-color: var(--on-dark); }

/* FAQ accordion: div.faq > details.faq__item[id] > summary.faq__q + div.faq__a. Big tap targets; the
   +/- mark is drawn by CSS. js/site.js opens a details when the address points into it (faq.html#shipping). */
.faq { border-top: 3px solid var(--ink); }
.faq__item { border-bottom: 1px solid var(--ink); }
.faq__q {
  position: relative;
  display: flex;
  align-items: center;
  min-height: var(--tap-lg);
  padding: var(--sp-3) 56px var(--sp-3) 0;
  font: 700 1.25rem/1.3 var(--f-text);
  list-style: none;
  cursor: pointer;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::after {          /* the +/- in a square */
  content: "";
  position: absolute;
  right: 4px;
  top: 50%;
  width: 36px; height: 36px;
  margin-top: -18px;
  border: 2px solid var(--ink);
  border-radius: var(--r);
  background:
    linear-gradient(var(--ink), var(--ink)) center / 16px 3px no-repeat,
    linear-gradient(var(--ink), var(--ink)) center / 3px 16px no-repeat,
    var(--paper-hi);
}
.faq__item[open] > .faq__q::after {
  background: linear-gradient(var(--on-dark), var(--on-dark)) center / 16px 3px no-repeat, var(--ink);
  border-color: var(--ink);
}
@media (hover: hover) and (pointer: fine) { .faq__q:hover { color: var(--red); } }
.faq__q:focus-visible { outline-offset: 4px; }
.faq__a { max-width: var(--measure); padding: 0 0 var(--sp-5); }
.faq__a > :last-child { margin-bottom: 0; }

/* shipping callout (partials/shipping.html, GENERATED from tools/catalog.py SHIPPING): small vs medium box */
.ship-box {
  padding: var(--sp-5) clamp(20px, 3vw, 32px);
  background: var(--paper-hi);
  border: 3px solid var(--ink);
  outline: 1px solid var(--ink);
  outline-offset: -9px;
  container-type: inline-size;     /* the two boxes go side by side when the CALLOUT is wide enough */
}
.ship-box__kicker { margin-bottom: .3em; }
.ship-box__title { margin: 0 0 var(--sp-4); font: 700 var(--fs-h4)/1.3 var(--f-text); text-wrap: balance; }
.ship-box__boxes { list-style: none; display: grid; gap: var(--sp-3); margin: 0; padding: 0; }
@container (min-width: 34rem) { .ship-box__boxes { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: stretch; } }
.ship-box__box {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "name price" "fits fits" "holds holds";
  grid-template-rows: auto auto 1fr;
  align-content: start;
  gap: 2px var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  border: 2px solid var(--ink);
  background: var(--paper);
}
.ship-box__name { grid-area: name; align-self: center; font-weight: 700; line-height: 1.25; }
.ship-box__price { grid-area: price; font: 400 2.5rem/1 var(--f-gothic); letter-spacing: .02em; }
.ship-box__fits { grid-area: fits; font-size: var(--fs-note); }
.ship-box__holds {
  grid-area: holds;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 8.5rem), 1fr));
  gap: 0 var(--sp-3);
  margin: var(--sp-2) 0 0;
  padding: var(--sp-2) 0 0;
  border-top: 1px dotted var(--rule-strong);
  font-size: var(--fs-note);
  font-weight: 600;
}
.ship-box__holds .num { font-size: 1.375rem; }
.ship-box__note { margin: var(--sp-4) 0 0; font-size: var(--fs-note); }

/* ==========================================================================
   15. Contact band (partials/contact-band.html)
   ========================================================================== */
.contact-band {
  position: relative;
  padding: clamp(56px, 8vw, 104px) 0;
  background: var(--ink);
  color: var(--on-dark);
}
.contact-band::before {           /* thin red rule: second ink pass */
  content: "";
  position: absolute;
  left: 0; right: 0; top: 10px;
  height: 2px;
  background: var(--red-hot);
}
@media (hover: hover) and (pointer: fine) { .contact-band a:hover { color: var(--on-dark-red); } }
.contact-band :focus-visible { outline-color: var(--on-dark); }
.contact-band__grid { display: grid; gap: var(--sp-6); }
.contact-band__title {
  margin: 0 0 .2em;
  font: 400 clamp(2.25rem, 1.5rem + 3vw, 3.5rem)/1 var(--f-display);
}
/* the big number never outgrows its column (cqi = % of the column), even with big text. No misprint offset. */
.contact-band__num { margin: 0 0 .25em; container-type: inline-size; }
.contact-band__num a {
  display: inline-flex;
  min-height: var(--tap);
  font: 400 clamp(4rem, 1.5rem + 11vw, 9.5rem)/.9 var(--f-gothic);
  font-size: min(clamp(2.5rem, 1.5rem + 9vw, 8rem), 17cqi);
  letter-spacing: .015em;
  color: var(--on-dark);
  text-decoration: none;
  white-space: nowrap;
}
.contact-band__note { max-width: 28em; margin: 0; font-size: var(--fs-lede); line-height: 1.45; color: var(--on-dark-2); }
.contact-band__actions { display: grid; gap: var(--sp-3); align-content: end; }
.contact-band__more { margin: var(--sp-2) 0 0; color: var(--on-dark-2); font-size: var(--fs-note); }
.contact-band__more a { font-weight: 700; color: var(--on-dark); text-decoration-color: var(--on-dark-red); overflow-wrap: anywhere; }
@media (min-width: 60em) {
  .contact-band__grid { grid-template-columns: minmax(0, 7fr) minmax(0, 4fr); gap: var(--sp-8); align-items: end; }
}

/* ==========================================================================
   16. Motion + print
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
  }
}
/* print: plain black on white: no buttons, no quickbar or menu, no dark bands (browsers print without
   background colours, so anything light-on-dark is set black here), and framed blocks are kept whole.
   Page CSS adds only "hide this screen control" rules. */
@media print {
  body { background: #fff; }
  .site-nav, .nav-toggle, .header-call, .cart-link, .quickbar, .skip-link, .lightbox,
  .btn, .actions, .contact-band__actions, .buybox { display: none !important; }
  .site-header { position: static; transform: none !important; }
  .data-table thead th, .contact-band, .contact-band *,
  .badge--solid, .badge--stamp, .plate__tab, .chip[aria-pressed="true"], .kicker--on-dark {
    color: #000 !important;
    background: none !important;
    box-shadow: none !important;
    text-shadow: none !important;
  }
  .badge--solid, .badge--stamp, .plate__tab { border: 1px solid #000; }
  .data-table thead th { border-bottom: 2px solid #000; }
  .sheet__head { break-after: avoid; }
  .data-table tr, .notice, .plate, .product, .spec-list, .steps li, .photo,
  .ship-box, .faq__item, .team, .gallery__item { break-inside: avoid; }
  .faq__item:not([open]) > .faq__a { display: block; }
  a { text-decoration: none; }
}
