/* Applied sitewide (this file loads on every page) -- --bg is the design system's
   primary PAGE background, but GeneratePress defaults body to white. Without this,
   centered/max-width content leaves the outer gutters showing white on wide
   viewports instead of the dark canvas the rest of the site assumes. */
html, body { background: #121212; }

:root{
  --bg:#121212;
  --bg-alt:#1a1a1a;
  --surface:#1f1f1f;
  --ink:#F2F1EE;
  --ink-soft:#a8a6a1;
  --accent:#c92a2a;
  --accent-hover:#a82323;
  --accent2:#2f9e44;
  --card-white:#ffffff;
  --interrupt-bg:#d8d8d8;
  --interrupt-text:#1a1a1a;
  --line:#333333;
  --line-soft:#2a2a2a;

  --font-heading:'Big Shoulders Display',sans-serif;
  --font-body:'Work Sans',sans-serif;

  --space-sm:8px;
  --space-md:16px;
  --space-lg:32px;
  --space-xl:56px;

  --radius-sm:4px;
  --radius-md:8px;
}

/* Shared components below -- moved out of gun-store.css 2026-09-10 so any page can
   use mg_nav_pills_html() or the [mg_cta_*] shortcodes and render correctly, not just
   /gun-store/ (the first consumer, where these were originally written). tokens.css
   loads sitewide, gun-store.css only loads on page-gun-store.php -- a second template
   (page-security-guard.php) needing these surfaced the gap. Verbatim move, no rule
   changes, so /gun-store/ itself is unaffected. Page-specific CTA variants that no
   other page uses yet (.mg-cta-dominant, .mg-cta-photo-lg, .mg-cta-quarter, the
   .mg-cta-block-* grid wiring) stay in gun-store.css until another page needs them too. */

/* Nav pills -- mobile only, see functions.php mg_nav_pills_html(). Desktop uses
   the standard header nav, no duplicate pill row. */
.mg-nav-pills {
	display: flex;
	gap: var(--space-sm);
	overflow-x: auto;
	padding: var(--space-sm) var(--space-md);
	background: var(--bg-alt);
	-webkit-overflow-scrolling: touch;
}
.mg-nav-pill {
	flex: 0 0 auto;
	padding: 8px 14px;
	border: 1px solid var(--ink-soft); /* was --line (#333), near-invisible on the dark page; now matches .mg-svc-jump a */
	border-radius: 999px;
	color: var(--ink);
	text-decoration: none;
	font-family: var(--font-body);
	font-weight: 600;
	font-size: 13px;
	white-space: nowrap;
}
/* No hover/tap state change: GeneratePress's global a:hover (0,1,1) out-ranks the class-only color above (0,1,0), which turned the pill text #222 on the dark page and made it vanish. Pin the color in every link state. (2026-09-19) */
.mg-nav-pill:hover,
.mg-nav-pill:focus,
.mg-nav-pill:active,
.mg-nav-pill:visited { color: var(--ink); }
@media (min-width: 1024px) {
	.mg-nav-pills { display: none; }
}

/* Placeholder image slots -- shared base, composed with layout classes below. */
.mg-img-slot {
	position: relative;
	background: var(--surface);
	border: 1px dashed var(--line);
}
.mg-img-slot::after {
	content: "PLACEHOLDER \2014 " attr(data-dims);
	position: absolute;
	left: var(--space-sm);
	bottom: 6px;
	font-family: var(--font-body);
	font-size: 10px;
	color: var(--ink-soft);
	opacity: 0.75;
	max-width: calc(100% - 16px);
}

/* CTA tiles -- shared base, used by the [mg_cta_*] shortcodes (functions.php) and
   their gp_elements markup. Photo-vs-scrim treatment per tile lives on the tile's own
   Hook Element content, not here. */
.mg-cta {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	justify-content: flex-start;
	border-radius: var(--radius-md);
	overflow: hidden;
	text-decoration: none;
	color: var(--ink);
	padding: var(--space-md);
	box-sizing: border-box;
	border: 1px solid transparent;
	transition: border-color 0.15s ease;
}
.mg-cta-content { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; max-width: 80%; height: 100%; }
.mg-cta-content h2 { font-family: var(--font-heading); font-weight: 700; font-size: 22px; margin: 0; line-height: 1.05; text-transform: uppercase; letter-spacing: 0.02em; }
.mg-cta:hover, .mg-cta:focus, .mg-cta:active { color: var(--ink); border-color: var(--accent); }
.mg-cta-content p { font-family: var(--font-body); font-size: 13px; margin: 0; color: var(--ink-soft); }
.mg-cta-btn {
	display: inline-block;
	margin-top: auto;
	background: var(--accent);
	color: #fff;
	font-family: var(--font-body);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	font-size: 12px;
	padding: 8px 14px;
	/* Without this, a narrow .mg-cta-content column (e.g. a .mg-cta-side-tile at a
	   narrow mobile width) silently wraps "LEARN MORE" onto 2 lines instead of
	   staying a normal button shape -- caught 2026-09-11 on the Range Packages page's
	   Carry Permit/Gun Safety tiles. Sitewide fix since any other narrow instance of
	   this button would hit the same issue. */
	white-space: nowrap;
	border-radius: var(--radius-sm);
	/* Border reserved (transparent) at all times so it appearing on hover doesn't shift
	   layout -- same pattern as .mg-cta/.mg-brand-card/.mg-gun-card elsewhere. */
	border: 1px solid transparent;
	box-sizing: border-box;
	transition: border-color 0.15s ease, transform 0.15s ease;
}
/* Text explicitly pinned to white on hover -- GeneratePress's own
   a:hover,a:focus,a:active{color:var(--contrast)} otherwise wins (this is an <a>),
   which was turning "Buy Now"/"Learn More"/etc. dark on hover. Per Chris 2026-09-11:
   keep the text unchanged, add a dark 1px border instead, plus a small smooth scale-up
   (transform doesn't affect layout, so nothing around the button shifts). */
.mg-cta-btn:hover,
.mg-cta-btn:focus,
.mg-cta-btn:active {
	color: #fff;
	border-color: var(--interrupt-text);
	transform: scale(1.06);
}

.mg-cta-has-photo { padding: 0; position: relative; }
.mg-cta-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.mg-cta-scrim { position: absolute; inset: 0; background: linear-gradient(100deg, rgba(18,18,18,0.82) 0%, rgba(18,18,18,0.5) 38%, rgba(18,18,18,0.05) 62%); }
.mg-cta-has-photo .mg-cta-content { position: relative; z-index: 1; padding: var(--space-md); max-width: 65%; }
.mg-cta-has-photo .mg-cta-content p { color: #fff; }
/* Mobile-only widen (2026-09-23): 65% reads cramped on narrow phone widths
   for cards using the plain (non -photo-lg) text treatment -- desktop keeps
   65%, only this max-width media query's value changes. Placed here, right
   after the base rule, so .mg-cta-photo-lg's own more specific mobile width
   (50%, its own "big headline" look) still wins where that class is also
   present -- this only widens the smaller-text cards Chris flagged. */
@media (max-width: 1023px) {
	.mg-cta-has-photo .mg-cta-content { max-width: 85%; }
}

.mg-cta-side-tile { aspect-ratio: 2 / 1; }

.mg-cta-side-heading-lg .mg-cta-content h2 { font-size: 27px; }
@media (min-width: 1024px) {
	.mg-cta-side-heading-lg .mg-cta-content h2 { font-size: 30px; }
}

/* Narrow portrait "quarter" tile -- two of these share half a row against one
   .mg-cta-dominant elsewhere (gun-store's CTA Block 3, and the Security Guard page's
   Range Package pair). 41/60 (0.683) was tuned on gun-store so this tile's height
   matches a full-width dominant tile's mobile height exactly. */
.mg-cta-quarter { aspect-ratio: 41 / 60; flex: 1; min-width: 0; }
.mg-cta-quarter .mg-cta-content { max-width: 100%; }

/* Bigger-headline treatment for a .mg-cta-has-photo tile -- started as a Shop-Online-
   only test on gun-store, promoted to a shared class (.mg-cta-photo-lg) once Indoor
   Range adopted the same look, moved here 2026-09-11 as a second page (Security
   Guard's Concealed Carry/Shop Online/Indoor Range cards) needed it too. Bottom-left
   button positioning is a base .mg-cta-content/.mg-cta-btn rule (tokens.css, above),
   so this class only owns text sizing. */
.mg-cta-photo-lg .mg-cta-content { width: 75%; }
.mg-cta-photo-lg .mg-cta-content p { font-size: 16px; max-width: 100%; }
.mg-cta-photo-lg .mg-cta-content h2 { font-size: 27px; }
@media (min-width: 1024px) {
	.mg-cta-photo-lg .mg-cta-content { width: auto; max-width: 65%; }
	.mg-cta-photo-lg .mg-cta-content p { max-width: 300px; }
	.mg-cta-photo-lg .mg-cta-content h2 { font-size: 42px; }
}

/* Ken Burns crossfade slider -- shared component (first: /gun-store/'s hero slider,
   second: the Security Guard page's intro). Each .mg-hero-slide is absolutely
   stacked, crossfading via opacity; the page's own JS toggles .active every 3s.
   Ken Burns is a slow zoom on the img itself (not the slide wrapper), timed to
   exactly the 3s a slide is visible, and restarts cleanly each cycle because adding
   the .active class fresh re-triggers the CSS animation from its 0% state.
   transform-origin defaults to center (50% 50%) but is commonly overridden per-<img>
   (inline style) so the zoom pulls toward a subject -- e.g. a face -- instead of
   cropping it out as the frame scales up. */
.mg-hero-slider {
	width: 100%;
	aspect-ratio: 10 / 7;
	border-radius: var(--radius-md);
	position: relative;
	overflow: hidden;
	background: var(--surface);
}
.mg-hero-slide {
	position: absolute;
	inset: 0;
	opacity: 0;
	transition: opacity 1s ease;
}
/* z-index bumps only the incoming slide above the outgoing one during their 1s
   overlap -- the outgoing slide keeps .active, and therefore its zoomed frame,
   until it's fully covered, so its animation-removal snap-back happens invisibly
   underneath instead of visibly popping back to scale(1) mid-crossfade. */
.mg-hero-slide.active { opacity: 1; z-index: 2; }
.mg-hero-slide img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
	transform: scale(1);
	transform-origin: 50% 50%;
}
.mg-hero-slide.active img { animation: mgHeroKenBurns 3s linear forwards; }
@keyframes mgHeroKenBurns {
	from { transform: scale(1); }
	to { transform: scale(1.08); }
}

/* FAQ accordion -- shared component (first: single-guns.php, second: the Security
   Guard page). Single-open: clicking a closed item closes any other open one first.
   Content stays in the DOM either way (display:none only), so nothing here is
   hidden from crawlers, only visually collapsed -- toggle JS lives per-page
   (product.js / security-guard.js), not here. */
.mg-faq-accordion .mg-faq-item{border-bottom:1px solid var(--line-soft);margin-bottom:0;padding-bottom:0;}
.mg-faq-q{
  width:100%;display:flex;align-items:center;justify-content:space-between;gap:var(--space-md);
  background:none;border:none;padding:var(--space-md) 0;cursor:pointer;text-align:left;
  font-family:var(--font-body);font-size:16px;font-weight:700;color:var(--ink);
}
.mg-faq-icon{flex-shrink:0;font-size:20px;color:var(--accent);line-height:1;}
.mg-faq-item.open .mg-faq-icon{transform:rotate(45deg);}
.mg-faq-a{display:none;padding:0 0 var(--space-md);}
.mg-faq-item.open .mg-faq-a{display:block;}
.mg-faq-a p{font-size:14px;color:var(--ink-soft);margin:0;}

/* Reviews -- real 5-star Google reviews (GBP export). White cards. */
.mg-reviews { margin-bottom: var(--space-lg); }
/* 27px/30px matches the CTA tiles' .mg-cta-side-heading-lg heading size (e.g. "Range
   Package for 2") -- was a flat 22px, same fix as .mg-svc-body h2 above, 2026-09-11. */
.mg-reviews h2 { font-family: var(--font-heading); font-size: 27px; margin: 0 0 var(--space-md); text-align: center; }
@media (min-width: 1024px) {
	.mg-reviews h2 { font-size: 30px; }
}
.mg-review-grid { display: grid; grid-template-columns: 1fr; gap: var(--space-md); }
.mg-review { background: var(--card-white); color: var(--interrupt-text); border-radius: var(--radius-md); padding: var(--space-md); margin: 0; }
.mg-review-stars { color: #e8a33d; font-size: 14px; letter-spacing: 2px; margin-bottom: 6px; display: flex; align-items: center; gap: 6px; }
.mg-review p { font-family: var(--font-body); font-size: 14px; line-height: 1.5; margin: 0 0 var(--space-sm); }
.mg-review cite { font-family: var(--font-body); font-weight: 700; font-size: 13px; font-style: normal; }
.mg-review-source { font-family: var(--font-body); font-weight: 700; font-size: 12px; letter-spacing: normal; font-style: normal; color: var(--interrupt-text); }
@media (min-width: 1024px) {
	.mg-review-grid { grid-template-columns: repeat(3, 1fr); }
}

/* Gun store H1/intro + hero (slider/map/NAP) -- moved here from gun-store.css
   2026-09-11, second consumer: the Range Packages page reuses these classes
   verbatim (same 843/300px desktop hero split, same H1/intro-paragraph pattern),
   per Chris's "hero same as gun store" call for that page. Not renamed despite
   the mg-gunstore-* prefix -- reused as-is to avoid touching gun-store.php. */
/* Intro / H1 */
.mg-gunstore-intro { text-align: center; padding: var(--space-lg) 0 var(--space-xl); }
.mg-gunstore-h1 { font-family: var(--font-heading); font-weight: 700; font-size: 32px; margin: 0; text-transform: uppercase; }
@media (min-width: 1024px) {
	.mg-gunstore-h1 { font-size: 50px; }
}
/* max-width added 2026-09-08 when this became a real 2-sentence paragraph (was a
   short one-liner) -- matches the sitewide "centered intro text, ~640px" pattern
   used elsewhere on the site, otherwise it stretches edge-to-edge at 1168px. */
.mg-gunstore-sub { font-family: var(--font-body); color: var(--ink); margin: 4px auto 0; max-width: 640px; }

/* Hero: slider + map/info column. Mobile stacks map below the slider with the
   NAP block ABOVE the map (column-reverse flips the two mg-hero-side children;
   desktop restores normal order, map first). */
.mg-hero { display: flex; flex-direction: column; gap: var(--space-md); margin-bottom: var(--space-xl); scroll-margin-top: 90px; }
/* .mg-hero-slider/.mg-hero-slide/@keyframes mgHeroKenBurns -- moved to tokens.css
   2026-09-10 (shared Ken Burns crossfade slider, second consumer: the Security
   Guard page's intro). Same class names reused verbatim, no markup changes needed
   here. Width/aspect-ratio for THIS page's usage stay below (843px desktop etc). */
.mg-hero-side { display: flex; flex-direction: column-reverse; gap: var(--space-md); }
.mg-hero-map { border-radius: var(--radius-md); overflow: hidden; }
.mg-hero-map iframe { width: 100%; height: 220px; display: block; border: 0; }
.mg-hero-nap { background: var(--surface); border-radius: var(--radius-md); padding: var(--space-md); }
.mg-nap-heading { font-family: var(--font-heading); font-weight: 700; font-size: 27px; margin: 0 0 6px; line-height: 1.2; }
.mg-nap-address, .mg-nap-hours { font-family: var(--font-body); color: var(--ink-soft); margin: 4px 0; }
.mg-nap-phone a { color: var(--ink); font-weight: 700; text-decoration: none; font-size: 18px; }

/* Every flex/grid item below gets min-width:0 + min-height:0 -- flex and grid items
   default to min-width/min-height:auto, which lets a child's CONTENT (a heading
   string, an aspect-ratio'd image) win over the explicit size this layout is trying
   to enforce. Without this, columns don't split evenly and rows/columns overflow
   their container -- the root cause behind three separate alignment bugs found
   2026-09-07 (hero NAP block, brand-grid rows, and the block-1/block-2 divide not
   lining up). Applying it broadly here instead of patching one selector at a time. */
.mg-hero-slider, .mg-hero-map, .mg-hero-nap, .mg-hero-side,
.mg-cta, .mg-cta-side, .mg-brand-grid, .mg-brand-card {
	min-width: 0;
	min-height: 0;
}

@media (min-width: 1024px) {
	.mg-hero { flex-direction: row; height: 480px; }
	.mg-hero-slider { flex: 0 0 843px; width: 843px; aspect-ratio: auto; height: 100%; }
	.mg-hero-side { flex: 1; flex-direction: column; height: 100%; }
	.mg-hero-map { flex: 0 0 300px; }
	.mg-hero-map iframe { height: 100%; }
	.mg-hero-nap { flex: 1; display: flex; flex-direction: column; justify-content: center; padding: var(--space-sm) var(--space-md); }
}

/* NAP block content tightened so 3 lines + padding comfortably fit the ~164px this
   column gets once the map (300px) + gap take the rest of the hero's 480px height. */
.mg-hero-nap p { margin: 3px 0; line-height: 1.3; }
.mg-hero-nap .mg-nap-phone a { font-size: 16px; }

/* Services-page skeleton (crumb/jump-pills/service-cards/note/cross-page-cta-row)
   -- moved here from security-guard.css 2026-09-11, second consumer: the Range
   Packages page. Verbatim move, no rule changes -- /security-guard-training/
   itself unaffected. */
/* width:100% is required here, not cosmetic -- .mg-svc is a direct child of GP's
   .site-content, which is display:flex. A flex item with no explicit width sizes to
   its own content's max-content width (shrink-to-fit) rather than filling the row;
   gun-store.css's .mg-gunstore "works" without this only because ITS content (a
   1280px hero/grid) happens to be wider than the viewport and gets flex-shrunk down
   to fill it -- an accident of wide content, not a real fix. This page's narrower
   content (1120px wrap) has no such accident, so without width:100% the whole page
   renders shrink-wrapped and flush-left instead of centered (bug reported 2026-09-11). */
.mg-svc { background: var(--bg); color: var(--ink); width: 100%; }
/* Widened to 1280px to match gun-store/catalog, per Chris 2026-09-11 -- was 1120px
   (matching single-guns.php's reading-focused width instead). Chris's call: no good
   reason for two different page widths on the same site: single-guns.php still uses
   1120px, flagged separately as an open question rather than changed here. */
.mg-svc-wrap { max-width: 1280px; margin: 0 auto; padding: 0 var(--space-md) var(--space-xl); }

.mg-svc-crumb { font-family: var(--font-body); font-size: 13px; color: var(--ink-soft); padding: var(--space-md) 0 var(--space-sm); }
.mg-svc-crumb a { color: var(--ink-soft); }

/* Jump-link pills -- same pill visual as .mg-nav-pill (tokens.css) but these are real
   in-page anchors and stay visible on every breakpoint, not a mobile-only nav row. */
/* padding-bottom bumped to --space-xl (from --space-md) 2026-09-11 -- was only 16px
   of breathing room above the hero vs. the hero's own 56px margin-bottom below it;
   Chris asked for the two to match. */
.mg-svc-jump { display: flex; gap: var(--space-sm); overflow-x: auto; padding-bottom: var(--space-xl); -webkit-overflow-scrolling: touch; }
/* --ink-soft (light grey) instead of --line (near-black, barely visible against the
   dark page) -- same fix already applied to the FAQ item borders this session, per
   Chris 2026-09-11 ("boarder on the pills is too hard to see"). */
.mg-svc-jump a {
	flex: 0 0 auto;
	padding: 8px 14px;
	border: 1px solid var(--ink-soft);
	border-radius: 999px;
	color: var(--ink);
	text-decoration: none;
	font-family: var(--font-body);
	font-weight: 600;
	font-size: 13px;
	white-space: nowrap;
}
.mg-svc-jump a:hover { border-color: var(--accent); }

/* Anchor targets sit under the sticky admin bar / any future sticky header --
   scroll-margin-top keeps the jump landing spot from tucking under it. */
.mg-svc-anchor { scroll-margin-top: 90px; }

/* .mg-svc-intro* -- 50/50 image/text hero (slider left, copy right on desktop,
   stacked on mobile). Moved here from security-guard.css 2026-09-11, second
   consumer: the Concealed Carry page reuses this exact layout. Verbatim move --
   /security-guard-training/ itself unaffected. Image column uses the shared Ken
   Burns slider (.mg-hero-slider, above), sized to fill this 50% column instead of
   gun-store's fixed 843px. */
.mg-svc-intro { display: flex; flex-direction: column; gap: var(--space-md); margin-bottom: var(--space-xl); }
.mg-svc-intro-img { border-radius: var(--radius-md); }
.mg-svc-intro-copy { font-family: var(--font-body); font-size: 21px; line-height: 1.5; }
@media (min-width: 1024px) {
	.mg-svc-intro-copy { font-size: 24px; }
}
.mg-svc-intro-copy p { margin: 0 0 var(--space-sm); }
.mg-svc-intro-copy p:last-child { margin-bottom: 0; }
.mg-svc-intro-copy strong { color: var(--ink); }
.mg-svc-intro-age { font-size: 14px; color: var(--ink-soft); }
@media (min-width: 1024px) {
	.mg-svc-intro { flex-direction: row; align-items: center; gap: var(--space-lg); }
	.mg-svc-intro-img { flex: 1 1 0; width: auto; min-width: 0; } /* equal halves that already account for the 32px gap (was 50% + 50% + gap = 32px too wide, 2026-09-21) */
	.mg-svc-intro-copy { flex: 1 1 0; width: auto; min-width: 0; }
	/* This file's own 1024px+ rule for .mg-hero-slider (above) assumes gun-store's
	   .mg-hero layout (fixed 843px column inside a 480px-tall flex row) and switches
	   the slider to aspect-ratio:auto; height:100% -- with no explicit height on
	   .mg-svc-intro-img to resolve that percentage against, the slider collapses to
	   0px tall on desktop only (mobile never hits this media query). Restore
	   aspect-ratio-driven sizing for this 50%-column context specifically -- first
	   found/fixed on Security Guard 2026-09-11, generalized here for its second
	   consumer rather than re-copied per page. */
	.mg-svc-intro-img .mg-hero-slider { flex: none; width: 100%; aspect-ratio: 10 / 7; height: auto; }
}

.mg-svc-cards { display: flex; flex-direction: column; gap: var(--space-md); margin-bottom: var(--space-sm); }
/* Reversed to a white card on the dark page, per Chris 2026-09-11 ("courses should
   stand out more") -- reuses --card-white/--interrupt-text, the same white-card
   pattern already used by .mg-review/.mg-gun-card/.mg-brand-card, not a new color
   pair. No border, same reasoning as .mg-review: the white-on-dark-page contrast
   already separates the card, a border would be redundant. Image column removed
   (no service photography exists for these courses) -- body content is now the
   whole card, not a row split. */
.mg-svc-card {
	background: var(--card-white);
	color: var(--interrupt-text);
	border-radius: var(--radius-md);
	padding: var(--space-md);
	display: flex;
	flex-direction: column;
	gap: var(--space-md);
}
/* .mg-svc-card-img -- moved here from range-packages.css 2026-09-11, second
   consumer: the Concealed Carry page's one photographed course card. Mobile:
   top-bleed photo above the card content, negative margin cancelling the card's
   own padding so the photo reaches the rounded corners (.mg-cta-has-photo uses the
   same bleed technique). Desktop switches to image-left/details-right, see the
   768px block below. Cards with no image (Security Guard's courses -- no
   photography exists for those) are unaffected, this class simply isn't present. */
.mg-svc-card-img {
	margin: calc(-1 * var(--space-md)) calc(-1 * var(--space-md)) 0;
	border-radius: var(--radius-md) var(--radius-md) 0 0;
	overflow: hidden;
}
.mg-svc-card-img img {
	width: 100%;
	aspect-ratio: 16 / 9;
	object-fit: cover;
	display: block;
}
/* 80/20 split, per Chris 2026-09-11 -- text column doesn't run the full card width;
   price + Buy Now reserve their own narrow column on the right, button pinned to its
   bottom-right corner (justify-content:space-between + align-items:flex-end pushes
   the button down and right within that column). Stacked full-width on mobile
   (<768px, matching the breakpoint the old image-row layout used) -- a 20%-wide
   column has no room for a button at phone widths. */
.mg-svc-card-row { display: flex; flex-direction: column; gap: var(--space-md); }
.mg-svc-card-main { display: flex; flex-direction: column; gap: 6px; }
.mg-svc-card-side { display: flex; flex-direction: row; align-items: center; justify-content: space-between; gap: var(--space-md); }
/* 24px reuses the intro paragraph / brand-grid-filler size (up from 20px) -- a real
   step up without colliding with the 22px used for true section H2s elsewhere on
   this page. */
/* Extra breathing room below the title, on top of .mg-svc-card-main's shared 6px
   gap, per Chris 2026-09-11 -- title needed more separation from the description
   than the description's own paragraphs need from each other. */
.mg-svc-card-name { font-family: var(--font-heading); font-weight: 700; font-size: 24px; text-transform: uppercase; margin: 0 0 var(--space-sm); }
.mg-svc-card-price { font-family: var(--font-body); font-weight: 700; font-size: 18px; white-space: nowrap; }
/* 17px matches .mg-gunstore-sub (gun-store.css's own intro paragraph, inherited from
   GP's default body size -- confirmed via computed style, not a value set in that
   file). Weight 500 is a deliberate trial, not yet used elsewhere for body copy on
   this site (everywhere else -- .mg-gunstore-sub, .mg-review p, .mg-nap-address --
   renders at regular/400); Chris asked to try it here for readability, 2026-09-11. */
.mg-svc-card-desc { font-family: var(--font-body); font-size: 17px; font-weight: 500; line-height: 1.5; margin: 0; }
/* Moved to its own full-width row below .mg-svc-card-row, per Chris 2026-09-11 --
   was inside .mg-svc-card-main (competing with the title/description for the 80%
   column). text-align:right makes it land under the Buy Now button on desktop
   (both sit at the card's right edge); on mobile it just reads as the last, bottom
   row of the card since .mg-svc-card-row now comes before it in source order.
   Still 14px/400 -- lighter/smaller than .mg-svc-card-desc's 17px/500. */
.mg-svc-card-age { font-family: var(--font-body); font-size: 14px; font-weight: 400; line-height: 1.5; margin: 0; text-align: right; }
.mg-svc-card-buy { white-space: nowrap; }
@media (min-width: 768px) {
	.mg-svc-card-row { flex-direction: row; align-items: stretch; }
	/* flex-grow ratios (4:1) with flex-basis:0, not width:80%/width:20% -- percentage
	   widths ignore the row's own `gap`, so 80%+20%+16px gap overflowed the card by
	   exactly the gap width, pushing the price/button column flush against the card's
	   right edge with zero padding (bug caught from a screenshot, 2026-09-11). Ratio-
	   based flex-basis:0 correctly subtracts the gap from available space first. */
	.mg-svc-card-main { flex: 4 1 0%; }
	.mg-svc-card-side { flex: 1 1 0%; flex-direction: column; align-items: flex-end; justify-content: space-between; }
	/* Image-left/details-right -- only cards with a .mg-svc-card-img child, scoped via
	   :has() so imageless cards (Security Guard's) are untouched and keep the plain
	   single-column .mg-svc-card default (flex-direction:column from the base rule
	   above), stacking .mg-svc-card-row then the optional .mg-svc-card-age normally.
	   CSS Grid instead of flex here specifically so the image can span the FULL card
	   height (content row + the optional age-line row below it), not just the first
	   row's height -- flexbox's per-line align-items:stretch (an earlier attempt at
	   this) only stretched the image to the first flex line, leaving a visible gap
	   below it once the age line wrapped onto its own second line (caught by Chris,
	   2026-09-11: "images ... come all the way to the bottom of the box"). grid-row:
	   1/-1 (not a hardcoded 1/3) spans however many rows actually exist -- works
	   whether the card has an age line (2 rows) or not (1 row), no separate CSS
	   needed per case. Mobile is untouched (this is all inside the 768px+ block) --
	   top-bleed image above stacked content stays exactly as before. */
	.mg-svc-card:has(.mg-svc-card-img) {
		display: grid;
		grid-template-columns: 320px 1fr;
		column-gap: var(--space-md);
	}
	/* `grid-row: 1 / -1` alone doesn't work here -- `-1` only resolves against the
	   EXPLICIT grid (grid-template-rows), and this container has none (rows are
	   implicit, created by .mg-svc-card-row/.mg-svc-card-age's own placement) -- so
	   `-1` collapsed back to line 1, same as row 1 alone (measured img height matched
	   row 1's height exactly, not the full card). Declaring 2 explicit rows, scoped to
	   only the cards that actually have BOTH an image and an age line (Concealed
	   Carry -- Range Packages' image cards have no age line at all), makes `1 / 3` a
	   real explicit span without adding a phantom empty row/gap to cards that don't
	   have a 2nd row's worth of content. */
	.mg-svc-card:has(.mg-svc-card-img):has(.mg-svc-card-age) { grid-template-rows: auto auto; }
	.mg-svc-card-img {
		grid-column: 1;
		grid-row: 1;
		margin: calc(-1 * var(--space-md)) 0 calc(-1 * var(--space-md)) calc(-1 * var(--space-md));
		border-radius: var(--radius-md) 0 0 var(--radius-md);
	}
	.mg-svc-card:has(.mg-svc-card-age) .mg-svc-card-img { grid-row: 1 / 3; }
	.mg-svc-card-img img { height: 100%; aspect-ratio: auto; }
	.mg-svc-card:has(.mg-svc-card-img) .mg-svc-card-row { grid-column: 2; grid-row: 1; min-width: 0; }
	.mg-svc-card:has(.mg-svc-card-img) .mg-svc-card-age { grid-column: 2; grid-row: 2; }
}

/* Matches .mg-svc-intro-age ("Must be 18 or older." in the hero) exactly, per Chris
   2026-09-11 -- was 13px italic, now 14px non-italic to align the two caveat lines. */
/* Bumped to full --ink (near-white) from --ink-soft, per Chris 2026-09-11 -- same
   contrast fix already applied to the FAQ answer text and SEO copy blocks elsewhere
   on this site (muted grey was flagged as harder to read against the dark page). */
.mg-svc-note { font-family: var(--font-body); font-size: 14px; color: var(--ink); margin: 0 0 var(--space-lg); }

/* Cross-page CTA rows, per Chris 2026-09-11: Row 1 = Concealed Carry (new) + Shop
   Online, Row 2 = Gun Range (Indoor Range) + a Range Package pair sharing the other
   half. Both rows' dominant tiles use .mg-cta-dominant (tokens.css/gun-store.css),
   which is a FIXED 600px at >=1024px on gun-store's own 1280px-wide layout -- two of
   those plus a gap would overflow this page's narrower 1120px .mg-svc-wrap, so these
   rows override them to flex:1 (evenly split) instead, same technique gun-store.css's
   own .mg-cta-block-3 already uses for its own row-specific override. */
.mg-svc-cta-row { display: flex; flex-direction: column; gap: var(--space-md); margin-bottom: var(--space-md); }
.mg-svc-cta-row:last-of-type { margin-bottom: var(--space-lg); }
@media (min-width: 1024px) {
	.mg-svc-cta-row { flex-direction: row; height: 420px; }
	/* min-width:0 on both -- without it, a flex item's default min-width:auto lets its
	   CONTENT's natural minimum (e.g. an unbreakable heading word) win over the flex:1
	   ratio, which is exactly what produced an uneven 490/582 split here instead of an
	   even 536/536 (caught live, 2026-09-11) -- Indoor Range vs. the Range Package pair
	   have different text, so their natural minimums differ. gun-store.css has its own
	   sitewide fix for this same class of bug on .mg-cta, but that file isn't loaded on
	   this page template, hence a local copy here. */
	.mg-svc-cta-row .mg-cta-dominant { flex: 1; width: auto; min-width: 0; }
	/* Fixed 600px, not flex:1, per Chris 2026-09-11 -- matches gun-store.css's own
	   .mg-cta-block-3 .mg-cta-quarters exactly ("Fixed 600px here... not a 50/50 flex
	   split"), now that this page's container is also 1280px. With this fixed, the two
	   .mg-cta-quarter cards inside split ~292px each -- the same width they measure on
	   gun-store, which is what let the 26px heading-size hack below become unnecessary. */
	.mg-svc-cta-row .mg-svc-cta-quarters { flex: 1; width: auto; height: 100%; min-width: 0; }
	/* Missing override, found 2026-09-11 comparing against /gun-store/'s own CTA Block 3
	   (gun-store.css .mg-cta-block-3 .mg-cta-quarter) -- without this, .mg-cta-quarter's
	   base aspect-ratio:41/60 (tokens.css) governed sizing instead of the row's fixed
	   420px height, so these two cards came out visibly smaller/differently
	   proportioned than the same shortcode pair renders on gun-store. */
	.mg-svc-cta-quarters .mg-cta-quarter { aspect-ratio: auto; height: 100%; }
}

/* Range Package pair -- two portrait .mg-cta-quarter tiles (tokens.css) side by side
   inside their half of the row, same as gun-store's own .mg-cta-quarters wrapper but
   without its fixed 600px (this page's row math is flex:1-based, not fixed-width --
   see .mg-svc-cta-row above). Side by side on mobile too, not just desktop, matching
   gun-store's own call on the same pair. */
/* No longer needs its own width math (font-size hack removed 2026-09-11) -- now that
   the row above fixes this wrapper's own width at 600px (matching gun-store), the
   30px shared heading size (tokens.css .mg-cta-side-heading-lg) fits without wrapping,
   same as it does on gun-store's identical 600px-wide .mg-cta-quarters. */
.mg-svc-cta-quarters { display: flex; flex-direction: row; gap: var(--space-sm); }

/* Reviews "See More" toggle -- moved here from security-guard.css 2026-09-11,
   second consumer: the Range Packages page. Verbatim move, no rule changes --
   /security-guard-training/ itself unaffected. */
/* Reviews 4-6 stay hidden until "See More" is clicked (security-guard.js) -- still
   in the DOM either way, same crawlability-preserving pattern used for the catalog's
   caliber pills and config-card filters (product.js/catalog.js). */
.mg-svc-review-extra { display: none; }
.mg-review-grid.mg-svc-expanded .mg-svc-review-extra { display: block; }
/* appearance:none strips the browser's native button chrome (a light grey/white
   default background some browsers still paint even with background:none) so the
   explicit --bg match below is what actually shows, unchanged whether the label
   reads "See More" or "See Less" -- both states use this same rule. */
.mg-svc-see-more {
	display: block;
	text-align: center;
	margin-top: var(--space-md);
	font-family: var(--font-body);
	font-weight: 600;
	font-size: 14px;
	color: var(--ink-soft);
	text-decoration: underline;
	appearance: none;
	-webkit-appearance: none;
	background: var(--bg);
	border: none;
	cursor: pointer;
	width: 100%;
}
/* Explicit background pin on every interactive state -- appearance:none alone didn't
   fully stop a hover/active background flash Chris caught live, 2026-09-11. */
.mg-svc-see-more:hover,
.mg-svc-see-more:focus,
.mg-svc-see-more:active { background: var(--bg); color: var(--ink); }

/* Services-page FAQ body (.mg-svc-body) + Reviews spacing -- moved here from
   security-guard.css 2026-09-11, second consumer: the Range Packages page's FAQ/
   Reviews (added same day). Verbatim move, no rule changes --
   /security-guard-training/ itself unaffected. */
/* Plain wrapper again, per Chris 2026-09-11 -- the --surface background moved to just
   .mg-faq-q below (the question row only), not the section or the answer panel. */
/* margin-top added 2026-09-11 -- this rule previously only set margin-bottom, so
   the gap above the FAQ heading was just .mg-svc-note's own margin-bottom
   (--space-lg, 32px). Range Packages already had a page-local override for this
   exact gap (range-packages.css .mg-svc-wrap .mg-svc-body); moved to the shared
   rule here since Concealed Carry needs the same extra space and Security Guard
   never got the fix at all. */
.mg-svc-body { margin-top: var(--space-xl); margin-bottom: var(--space-lg); }
/* 27px/30px matches the CTA tiles' .mg-cta-side-heading-lg heading size (e.g. "Range
   Package for 2") -- was a flat 22px, which read noticeably smaller than the CTA
   text right below this section, per Chris 2026-09-11. */
.mg-svc-body h2 { font-family: var(--font-heading); font-weight: 700; font-size: 27px; text-transform: uppercase; margin: 0 0 var(--space-sm); }
@media (min-width: 1024px) {
	.mg-svc-body h2 { font-size: 30px; }
}
.mg-svc-body p { font-family: var(--font-body); font-size: 15px; line-height: 1.6; margin: 0 0 var(--space-sm); }
/* Each item is its own light-grey (--ink-soft) bordered box; overflow:hidden clips
   the question row's background to the item's rounded corners. Padding moved off the
   item and onto .mg-faq-q/.mg-faq-a individually so the question's --surface fill can
   reach the item's edges (an item-level padding would leave a gap around it instead). */
.mg-svc-body .mg-faq-item {
	border: 1px solid var(--ink-soft);
	border-radius: var(--radius-sm);
	margin-bottom: var(--space-sm);
	overflow: hidden;
	transition: border-color 0.15s ease;
}
.mg-svc-body .mg-faq-item:last-child { margin-bottom: 0; }
/* Red on hover, and stays red once expanded (.open, toggled by security-guard.js) --
   per Chris 2026-09-11. */
.mg-svc-body .mg-faq-item:hover,
.mg-svc-body .mg-faq-item.open { border-color: var(--accent); }
.mg-svc-body .mg-faq-q { background: var(--surface); padding: var(--space-md); }
.mg-svc-body .mg-faq-a { padding: 0 var(--space-md) var(--space-md); }
/* Answer text bumped to full --ink (near-white) instead of the shared component's
   default --ink-soft, per Chris 2026-09-11 ("make the answer text white so it's
   easier to read") -- scoped to this page, single-guns.php's own FAQ keeps the
   muted default. */
.mg-svc-body .mg-faq-a p { margin: 0; color: var(--ink); }

/* Extra breathing room around Reviews, per Chris 2026-09-11 -- especially below,
   where the CTA row right after it was competing for attention. Overrides the
   shared .mg-reviews margin-bottom (tokens.css, --space-lg) with more room on both
   sides, scoped to this page only. */
.mg-svc-wrap .mg-reviews { margin-top: var(--space-xl); margin-bottom: var(--space-xl); }

/* .mg-cta-dominant -- moved here from gun-store.css 2026-09-11, second consumer:
   the Range Packages page. Verbatim move, no rule changes -- /gun-store/ itself
   unaffected. */
/* Shop Online / Indoor Range / Become a Security Guard share ONE fixed size on
   desktop -- Chris wants these three specifically interchangeable (same photo
   dimensions could drop into any of the three), not just proportionally similar.
   Mobile: same 2:1 landscape stack shape as every other full-width CTA. */
/* 10/7 matches the desktop container's exact 600x420 ratio -- mobile previously used
   a flatter 2:1, which cropped these real photos noticeably differently than desktop
   once real images (not empty placeholders) were in place (2026-09-08 fix). */
.mg-cta-dominant { aspect-ratio: 10 / 7; }
@media (min-width: 1024px) {
	.mg-cta-dominant { flex: 0 0 600px; width: 600px; height: 420px; aspect-ratio: auto; }
}

/* .mg-svc-seo -- moved here from security-guard.css 2026-09-11. Only ever lived in
   that page-specific file even though Range Packages and Concealed Carry both
   already used this exact class for their own SEO copy blocks -- both were
   rendering it completely unstyled (transparent background, 0 padding, 0 margin)
   the whole time, never caught since a plain text block reads as "fine" at a
   glance. margin-top added (the original rule only had margin-bottom) per Chris's
   ask for more breathing room above this section, 2026-09-11. */
.mg-svc-seo { background: var(--bg-alt); border-radius: var(--radius-md); padding: var(--space-md); margin-top: var(--space-xl); margin-bottom: var(--space-lg); }
.mg-svc-seo h3 { font-family: var(--font-heading); font-size: 18px; margin: 0 0 var(--space-sm); }
.mg-svc-seo p { font-family: var(--font-body); font-size: 14px; color: var(--ink); margin: 0 0 var(--space-sm); }
.mg-svc-seo p:last-child { margin-bottom: 0; }

/* ===== Promoted to shared 2026-09-14: homepage is the 2nd consumer of these
   components (brand grid, featured guns, shop banner), previously gun-store.css
   only -- same "move on 2nd use" convention as every other shared component in
   this project. Base rules moved verbatim from gun-store.css; the .mg-svc-cta-row
   scoped overrides below (.mg-cta-side, .mg-brand-grid) are NEW -- these two
   components had never been combined with .mg-svc-cta-row before (gun-store used
   its own .mg-cta-block-1/.mg-cta-block-2 wrappers with equivalent but separately-
   defined row math), so they need the same flex:1/height:100% treatment
   .mg-svc-cta-row already gives .mg-cta-dominant and .mg-svc-cta-quarters. */

.mg-cta-side { display: flex; flex-direction: column; gap: var(--space-md); }
.mg-svc-cta-row .mg-cta-side { flex: 1; width: auto; height: 100%; min-width: 0; }

.mg-brand-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-sm); }
.mg-brand-card {
	background: var(--card-white);
	border-radius: var(--radius-md);
	display: flex;
	align-items: center;
	justify-content: center;
	padding: var(--space-md);
	aspect-ratio: 1 / 1;
	text-decoration: none;
	min-width: 0;
	box-sizing: border-box;
	border: 1px solid transparent;
	transition: border-color 0.15s ease;
}
.mg-brand-card img { max-width: 100%; max-height: 100%; object-fit: contain; }
.mg-brand-card:hover { border-color: var(--accent); }
.mg-brand-card-more {
	position: relative;
	background: var(--accent);
	color: #fff;
	font-family: var(--font-body);
	border: 1px solid transparent;
	transition: border-color 0.15s ease;
	grid-column: span 2;
	aspect-ratio: auto;
}
.mg-brand-card-more:hover, .mg-brand-card-more:focus, .mg-brand-card-more:active { border-color: #fff; color: #fff; }
.mg-brand-card-more span {
	position: absolute;
	top: var(--space-sm);
	left: var(--space-sm);
	right: var(--space-sm);
	font-family: var(--font-heading);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	font-size: 24px;
	line-height: 1.15;
	text-align: left;
}
.mg-brand-card-more strong {
	position: absolute;
	bottom: var(--space-sm);
	right: var(--space-sm);
	font-size: 14px;
	text-transform: uppercase;
	letter-spacing: 0.03em;
	text-decoration: underline;
}
.mg-svc-cta-row .mg-brand-grid { flex: 1; grid-template-rows: repeat(3, 1fr); height: 100%; }
.mg-svc-cta-row .mg-brand-card { aspect-ratio: auto; }

.mg-featured-guns { margin-bottom: var(--space-lg); }
.mg-featured-guns h2 { font-family: var(--font-heading); font-size: 22px; margin: 0 0 var(--space-md); }
.mg-guns-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-sm); }
@media (min-width: 768px) and (max-width: 1023px) {
	.mg-guns-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 1024px) {
	.mg-guns-grid { grid-template-columns: repeat(6, 1fr); }
}
.mg-gun-card {
	background: var(--card-white);
	border-radius: var(--radius-md);
	overflow: hidden;
	color: var(--interrupt-text);
	display: flex;
	flex-direction: column;
	box-sizing: border-box;
	border: 1px solid transparent;
	transition: border-color 0.15s ease;
	position: relative;
}
.mg-gun-card:hover, .mg-gun-card:focus-within { border-color: var(--accent); }
/* Whole card is tappable: the View / Call link stretches over the card (one link per card for screen readers). */
.mg-gun-card-link::after { content: ''; position: absolute; inset: 0; }
.mg-gun-card-img { aspect-ratio: 3 / 4; display: flex; align-items: center; justify-content: center; padding: var(--space-sm); }
.mg-gun-card-img img { max-width: 100%; max-height: 100%; object-fit: contain; }
.mg-gun-card-cutout .mg-gun-card-img img { filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.25)); }
.mg-gun-card-brand { font-family: var(--font-body); font-weight: 400; font-size: 14px; color: var(--interrupt-text); padding: 0 var(--space-sm); text-transform: uppercase; letter-spacing: 0.03em; }
.mg-gun-card-title { font-family: var(--font-body); font-weight: 700; font-size: 15px; padding: 0 var(--space-sm); }
.mg-gun-card-link { font-family: var(--font-body); font-weight: 700; font-size: 19px; color: var(--accent); text-decoration: none; padding: var(--space-sm); margin-top: auto; }
.mg-gun-card-link:hover, .mg-gun-card-link:focus { text-decoration: none; }
.mg-gun-card-view { text-decoration: underline; text-underline-offset: 3px; }

.mg-shop-banner {
	display: flex;
	flex-direction: column;
	gap: var(--space-md);
	align-items: flex-start;
	background: var(--accent);
	text-decoration: none;
	border-radius: var(--radius-md);
	padding: var(--space-lg) var(--space-md);
	margin-bottom: var(--space-lg);
	box-sizing: border-box;
	border: 1px solid transparent;
	transition: border-color 0.15s ease;
}
.mg-shop-banner:hover, .mg-shop-banner:focus, .mg-shop-banner:active { border-color: #fff; color: #fff; }
.mg-shop-banner-text { font-family: var(--font-heading); font-weight: 700; font-size: 20px; color: #fff; }
.mg-shop-banner-btn {
	background: var(--card-white);
	color: var(--interrupt-text);
	border-radius: var(--radius-sm);
	padding: 10px 20px;
	font-family: var(--font-body);
	font-weight: 700;
	font-size: 13px;
	white-space: nowrap;
	transition: background-color 0.15s ease;
}
.mg-shop-banner:hover .mg-shop-banner-btn { background: var(--interrupt-bg); }
@media (min-width: 1024px) {
	.mg-shop-banner { flex-direction: row; align-items: center; justify-content: space-between; }
}
