/* GroupBrief — base styles + theme palettes */
/* --gb-bg is the flat palette background hex, still used as-is for
   --gb-surface (the card sitting atop the frame) and other light-
   background contexts -- it is NOT what actually paints <body>'s own
   background (see the body rule just below this comment). --gb-heading
   is the raw palette heading hex (added here specifically so
   something still holds that raw value now that --gb-frame-text no
   longer does -- see next paragraph). --gb-input-bg is a light
   near-white shared across every palette, used for input fields and
   small light-on-light accents inside cards.

   Full chrome-treatment parity with Lodge Sites Engine's own redesign:
   <body> now actually paints a background derived from --gb-heading,
   fixed at 100% strength always (see the body rule below) -- LSE's
   own equivalent fix was making its page background heading-derived
   too, and its own body stays fixed regardless of its adjustable
   panel's own intensity, same reasoning here. .gb-wrap (the outer
   container in feed.php/auth.php/invitation-gate.php, GB's closest
   structural equivalent to LSE's .lse-page panel) gets its own
   background derived from --gb-accent instead, driven by the
   admin-adjustable --gb-chrome-intensity (see GB_Settings::
   get_chrome_intensity(), a straight copy of LSE's own intensity
   setting/pattern).

   Correctness fix that comes with the above: --gb-frame-text used to
   just equal the raw heading hex, which was fine when the frame was a
   flat near-white background text never had to contend with. Now that
   the frame itself IS heading-colored (bold, saturated), text in
   --gb-frame-text color would be invisible painted on a background of
   literally the same color -- so --gb-frame-text now holds each
   palette's own on_heading value instead (chosen specifically for
   contrast against the raw heading color), and --gb-frame-text-muted
   is rederived to blend the (now on_heading) frame-text 70% toward
   --gb-heading 30% -- softening it while staying anchored to the
   actual background it sits on, rather than its old formula blending
   toward the unrelated, now-irrelevant --gb-bg.

   9 of these 10 are GroupBrief's own native copy of Lodge Sites Engine's
   curated palettes (see GB_Settings::THEMES for the raw source values;
   the 10th, usa, is GroupBrief-exclusive and not in LSE's set),
   and GB_LSE_Bridge for how a site with LSE active follows its live
   selection automatically). --gb-on-accent/--gb-on-heading are LSE's
   own contrast-pair roles, applied wherever this file uses --gb-accent/
   --gb-primary or --gb-heading/--gb-frame-text as a BACKGROUND with
   text on top: .gb-ad-premium-badge, .gb-pinned-badge, and
   .gb-section-badge (all background: var(--gb-accent))
   and .gb-button-primary (background:
   var(--gb-primary-dark), and var(--gb-primary) on :hover) were all
   previously hardcoded to color: #fff. Verified against real WCAG
   contrast math, not eyeballed: on the four badges' raw accent,
   white text failed AA (4.5:1) for Autumn Oak (2.38:1), Golden Harvest
   (2.23:1), Scarlet (2.25:1), and Charcoal & Pewter (3.28:1) -- each
   palette's own --gb-on-accent clears AA comfortably in every case
   (6.36/7.06/7.56/4.78:1). .gb-button-primary's own --gb-primary-dark
   (color-mix(in srgb, accent 80%, black) -- darker than the raw
   accent, so a separate check) passes AA with white for 7 of 9
   palettes; for the other 2, --gb-on-accent still clears AA for
   Golden Harvest (4.62:1) but NOT for Autumn Oak (4.18:1, worse than
   its own 3.62:1 with white was, though still an improvement over
   neither passing) -- flagging this one as a genuine residual gap:
   fixing it would mean changing --gb-primary-dark's own 80%-toward-
   black mix, which is explicitly out of scope for this pass (GB's
   existing derivation formulas are being preserved as-is). A follow-up
   pass swept this entire file for every background: var(--gb-accent)/
   var(--gb-primary)/var(--gb-primary-dark) declaration, not just a
   spot check: exactly 6 exist in the whole stylesheet -- these same 5
   rules (.gb-button-primary counts once, its :hover state inherits
   the fix) plus .gb-poll-result-bar (background: var(--gb-accent),
   but genuinely no text ever renders on it -- the percentage/count
   render in a separate sibling element instead, confirmed against
   class-gb-polls.php's own markup, not just the CSS). No further
   fixes were needed; this comment doubles as the record of that
   sweep having been done, not just assumed clean. */

:root {
	--gb-input-bg: #FAFAF7;
}

/* Frame background -- fixed at 100% strength always, regardless of
   the admin's own --gb-chrome-intensity setting (that only drives
   .gb-wrap's own panel background further down). Plain
   var(--gb-bg)-based fallback declared first as the color-mix()-
   unsupported fallback, same pattern LSE itself uses.
   Gated behind .gb-frontend -- this is the one rule in this file with
   no GB-specific class in its selector, so without the gate it would
   apply unconditionally to wp-admin's own <body> too, since this same
   stylesheet is legitimately also enqueued there (see
   GB_Admin::enqueue_admin_assets() -- .gb-card/.gb-button/.gb-input/
   the palette-swatch picker are reused on GB's admin screens). .gb-frontend
   is added via body_class(), a frontend-only filter WordPress never
   fires in wp-admin, so this can never match there regardless. */
body.gb-frontend {
	background-color: var(--gb-bg);
	background-color: color-mix(in srgb, var(--gb-heading) 100%, var(--gb-bg));
}

/* Sticky Save button, same treatment and reasoning as Lodge Sites
   Engine's own (see LSE's lse-admin.css) -- settings-page.php is the
   only one of GroupBrief's admin screens using WP core's standard
   submit_button() inside a plain <div class="wrap"><form> (every
   other admin/views/*.php screen -- Active Users, Ads, etc. -- has
   its own custom save UI, not this pattern), so this selector only
   ever matches there in practice; no extra scoping needed. :has(#submit)
   rather than a blanket p.submit match for the same reason as LSE's:
   #submit is the DEFAULT id WP's submit_button() gives its call when
   no explicit name/id is passed, same call this screen makes.
   Browsers without :has() support just don't match this rule, leaving
   Save Settings exactly where WP puts it by default. */
.wrap form p.submit:has( #submit ) {
	position: sticky;
	bottom: 0;
	z-index: 10;
	margin: 20px 0 0;
	padding: 12px 20px;
	background: #f0f0f1;
	border-top: 1px solid #dcdcde;
	box-shadow: 0 -2px 6px rgba( 0, 0, 0, 0.06 );
}

/* Guarantees the native `hidden` attribute always wins, no matter what
   `display` value a class sets elsewhere. Without this, any element that
   both has an explicit `display` (flex, block, etc.) AND gets toggled
   via `hidden` — as several pieces of GroupBrief's UI do, e.g. RSVP's
   "Not Going" state, the media-resize hint text, the admin
   add-Section-Moderator row — silently stops hiding, because an author
   stylesheet's `display` declaration beats the browser's own
   `[hidden] { display: none }` default at equal specificity. Setting
   this once, globally, up front means no future toggled element can
   accidentally reintroduce the same bug. */
[hidden] {
	display: none !important;
}

.gb-theme-autumn-oak {
	--gb-primary: #D4A017;
	--gb-primary-dark: color-mix(in srgb, var(--gb-primary) 80%, black);
	--gb-accent: #D4A017;
	--gb-on-accent: #2E2420;
	--gb-bg: #FAF3E8;
	--gb-surface: color-mix(in srgb, white 55%, var(--gb-bg) 45%);
	--gb-text: #2E2420;
	--gb-text-muted: #7C6B5B;
	--gb-border: color-mix(in srgb, white 70%, var(--gb-text-muted) 30%);
	--gb-heading: #5C1A1A;
	--gb-frame-text: #FAF3E8;
	--gb-frame-text-muted: color-mix(in srgb, var(--gb-frame-text) 70%, var(--gb-heading) 30%);
	--gb-on-heading: #FAF3E8;
}

.gb-theme-stone-rust {
	--gb-primary: #A35F35;
	--gb-primary-dark: color-mix(in srgb, var(--gb-primary) 80%, black);
	--gb-accent: #A35F35;
	--gb-on-accent: #FFFFFF;
	--gb-bg: #F5F3F0;
	--gb-surface: color-mix(in srgb, white 55%, var(--gb-bg) 45%);
	--gb-text: #2B2B2B;
	--gb-text-muted: #716D68;
	--gb-border: color-mix(in srgb, white 70%, var(--gb-text-muted) 30%);
	--gb-heading: #3A3A3A;
	--gb-frame-text: #FFFFFF;
	--gb-frame-text-muted: color-mix(in srgb, var(--gb-frame-text) 70%, var(--gb-heading) 30%);
	--gb-on-heading: #FFFFFF;
}

.gb-theme-regatta-blue {
	--gb-primary: #186FA8;
	--gb-primary-dark: color-mix(in srgb, var(--gb-primary) 80%, black);
	--gb-accent: #186FA8;
	--gb-on-accent: #FFFFFF;
	--gb-bg: #F4F6F8;
	--gb-surface: color-mix(in srgb, white 55%, var(--gb-bg) 45%);
	--gb-text: #1F2A33;
	--gb-text-muted: #65707A;
	--gb-border: color-mix(in srgb, white 70%, var(--gb-text-muted) 30%);
	--gb-heading: #0B3D5C;
	--gb-frame-text: #FFFFFF;
	--gb-frame-text-muted: color-mix(in srgb, var(--gb-frame-text) 70%, var(--gb-heading) 30%);
	--gb-on-heading: #FFFFFF;
}

.gb-theme-royal-plum {
	--gb-primary: #8C3FA0;
	--gb-primary-dark: color-mix(in srgb, var(--gb-primary) 80%, black);
	--gb-accent: #8C3FA0;
	--gb-on-accent: #FFFFFF;
	--gb-bg: #F7F3F6;
	--gb-surface: color-mix(in srgb, white 55%, var(--gb-bg) 45%);
	--gb-text: #241521;
	--gb-text-muted: #796A76;
	--gb-border: color-mix(in srgb, white 70%, var(--gb-text-muted) 30%);
	--gb-heading: #3B1240;
	--gb-frame-text: #FFFFFF;
	--gb-frame-text-muted: color-mix(in srgb, var(--gb-frame-text) 70%, var(--gb-heading) 30%);
	--gb-on-heading: #FFFFFF;
}

.gb-theme-meadow-green {
	--gb-primary: #227A3B;
	--gb-primary-dark: color-mix(in srgb, var(--gb-primary) 80%, black);
	--gb-accent: #227A3B;
	--gb-on-accent: #FFFFFF;
	--gb-bg: #F5F7F0;
	--gb-surface: color-mix(in srgb, white 55%, var(--gb-bg) 45%);
	--gb-text: #202B1F;
	--gb-text-muted: #677364;
	--gb-border: color-mix(in srgb, white 70%, var(--gb-text-muted) 30%);
	--gb-heading: #1B4D2E;
	--gb-frame-text: #FFFFFF;
	--gb-frame-text-muted: color-mix(in srgb, var(--gb-frame-text) 70%, var(--gb-heading) 30%);
	--gb-on-heading: #FFFFFF;
}

.gb-theme-golden-harvest {
	--gb-primary: #D9A61C;
	--gb-primary-dark: color-mix(in srgb, var(--gb-primary) 80%, black);
	--gb-accent: #D9A61C;
	--gb-on-accent: #2E2015;
	--gb-bg: #FAF3E0;
	--gb-surface: color-mix(in srgb, white 55%, var(--gb-bg) 45%);
	--gb-text: #2E2015;
	--gb-text-muted: #7B6C54;
	--gb-border: color-mix(in srgb, white 70%, var(--gb-text-muted) 30%);
	--gb-heading: #5C4317;
	--gb-frame-text: #FAF3E0;
	--gb-frame-text-muted: color-mix(in srgb, var(--gb-frame-text) 70%, var(--gb-heading) 30%);
	--gb-on-heading: #FAF3E0;
}

.gb-theme-maroon {
	--gb-primary: #BF1F24;
	--gb-primary-dark: color-mix(in srgb, var(--gb-primary) 80%, black);
	--gb-accent: #BF1F24;
	--gb-on-accent: #FFFFFF;
	--gb-bg: #F7F0EE;
	--gb-surface: color-mix(in srgb, white 55%, var(--gb-bg) 45%);
	--gb-text: #241816;
	--gb-text-muted: #7C6765;
	--gb-border: color-mix(in srgb, white 70%, var(--gb-text-muted) 30%);
	--gb-heading: #2A0E10;
	--gb-frame-text: #FFFFFF;
	--gb-frame-text-muted: color-mix(in srgb, var(--gb-frame-text) 70%, var(--gb-heading) 30%);
	--gb-on-heading: #FFFFFF;
}

.gb-theme-scarlet {
	--gb-primary: #C9A876;
	--gb-primary-dark: color-mix(in srgb, var(--gb-primary) 80%, black);
	--gb-accent: #C9A876;
	--gb-on-accent: #2A1810;
	--gb-bg: #F8F0EC;
	--gb-surface: color-mix(in srgb, white 55%, var(--gb-bg) 45%);
	--gb-text: #2A1810;
	--gb-text-muted: #7B695E;
	--gb-border: color-mix(in srgb, white 70%, var(--gb-text-muted) 30%);
	--gb-heading: #8A0E2E;
	--gb-frame-text: #FFFFFF;
	--gb-frame-text-muted: color-mix(in srgb, var(--gb-frame-text) 70%, var(--gb-heading) 30%);
	--gb-on-heading: #FFFFFF;
}

.gb-theme-charcoal-steel {
	--gb-primary: #8C8E92;
	--gb-primary-dark: color-mix(in srgb, var(--gb-primary) 80%, black);
	--gb-accent: #8C8E92;
	--gb-on-accent: #232326;
	--gb-bg: #F2F3F4;
	--gb-surface: color-mix(in srgb, white 55%, var(--gb-bg) 45%);
	--gb-text: #232326;
	--gb-text-muted: #6B6E72;
	--gb-border: color-mix(in srgb, white 70%, var(--gb-text-muted) 30%);
	--gb-heading: #2B2B2E;
	--gb-frame-text: #FFFFFF;
	--gb-frame-text-muted: color-mix(in srgb, var(--gb-frame-text) 70%, var(--gb-heading) 30%);
	--gb-on-heading: #FFFFFF;
}

.gb-theme-usa {
	--gb-primary: #E1193A;
	--gb-primary-dark: color-mix(in srgb, var(--gb-primary) 80%, black);
	--gb-accent: #E1193A;
	--gb-on-accent: #FFFFFF;
	--gb-bg: #FBFAF7;
	--gb-surface: color-mix(in srgb, white 55%, var(--gb-bg) 45%);
	--gb-text: #1C1F2B;
	--gb-text-muted: #6B7282;
	--gb-border: color-mix(in srgb, white 70%, var(--gb-text-muted) 30%);
	--gb-heading: #144096;
	--gb-frame-text: #FFFFFF;
	--gb-frame-text-muted: color-mix(in srgb, var(--gb-frame-text) 70%, var(--gb-heading) 30%);
	--gb-on-heading: #FFFFFF;
}

/* System-font stacks only, no @font-face/webfont loading -- the same
   5 curated pairings as Lodge Sites Engine's LSE_Font_Pairings (see
   GB_Settings::FONT_PAIRINGS), kept as GroupBrief's own native
   typography rather than a runtime dependency on that plugin. */
.gb-typography-classic-serif {
	--gb-font-heading: Georgia, 'Times New Roman', Times, serif;
	--gb-font-body: Georgia, 'Times New Roman', Times, serif;
}

.gb-typography-modern-sans {
	--gb-font-heading: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
	--gb-font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
}

.gb-typography-traditional {
	--gb-font-heading: 'Times New Roman', Times, Georgia, serif;
	--gb-font-body: Arial, Helvetica, 'Segoe UI', sans-serif;
}

.gb-typography-friendly-humanist {
	--gb-font-heading: Verdana, Geneva, Tahoma, sans-serif;
	--gb-font-body: Verdana, Geneva, Tahoma, sans-serif;
}

.gb-typography-bold-statement {
	--gb-font-heading: 'Arial Black', 'Arial Bold', Arial, sans-serif;
	--gb-font-body: Georgia, 'Times New Roman', serif;
}

/* GB's closest structural equivalent to LSE's own .lse-page panel --
   the single outer container every front-end template (feed.php,
   auth.php, invitation-gate.php, feed-cancelled.php, feed-locked.php)
   wraps its whole page in. Background derived from --gb-accent,
   driven by the admin-adjustable --gb-chrome-intensity (unlike
   <body>'s own frame background above, which is fixed at 100% always).
   Plain var(--gb-bg) fallback declared first, same
   color-mix()-unsupported-browser pattern as everywhere else in this
   file. */
.gb-wrap {
	max-width: 720px;
	margin: 0 auto;
	background-color: var(--gb-bg);
	background-color: color-mix(in srgb, var(--gb-accent) var(--gb-chrome-intensity), var(--gb-bg));
	color: var(--gb-text);
	font-size: 16px;
	line-height: 1.5;
	font-family: var(--gb-font-body, inherit);
}

/* Panel text contrast, gb-chrome-full only (Page Background Intensity
   exactly '100') -- at that one setting .gb-wrap's background above is
   the palette's pure, unblended Accent color, so --gb-text (chosen for
   contrast against --gb-bg) can no longer be trusted; --gb-on-accent is
   the palette's own contrast-safe pairing for text directly on Accent.
   Lower intensities blend enough toward --gb-bg that --gb-text stays
   legible on its own, same reasoning as LSE's own lse-chrome-full. */
body.gb-chrome-full .gb-wrap {
	color: var(--gb-on-accent);
}

/* The override above only reaches elements that inherit their color --
   these sit directly on .gb-wrap's background with no card of their own
   in between (confirmed by tracing every DOM branch of feed.php,
   auth.php, invitation-gate.php, feed-cancelled.php and feed-locked.php)
   but each sets its OWN explicit color for the non-chrome-full case, so
   a direct swap is needed for every one of them individually. */
body.gb-chrome-full .gb-header-text-link,
body.gb-chrome-full .gb-header-link-divider,
body.gb-chrome-full .gb-back-to-feed,
body.gb-chrome-full .gb-empty,
body.gb-chrome-full .gb-section-nav a {
	color: var(--gb-on-accent);
}

/* The rule above assumes each of these sits directly on .gb-wrap's own
   accent-tinted background. That's true for .gb-empty and for the
   feed page's own "Back to main feed" link — but three of these are
   actually nested inside a .gb-card in the real templates: the feed
   header's User Manual / My Profile / Log Out links and their dividers,
   that same card's section-nav strip (all in the .gb-feed-header card
   in feed.php), and the Profile page's own "Back to Feed" link (wrapped
   in a plain .gb-card there, unlike its un-carded sibling in feed.php).
   .gb-card is always the much lighter --gb-surface background
   regardless of palette or chrome intensity, so on-accent text painted
   there can end up with little or no contrast (confirmed invisible on
   the USA palette, whose --gb-on-accent is pure white). This is more
   specific than the rule above, so it wins only for the actually-
   card-nested instances, leaving the un-carded ones untouched. */
body.gb-chrome-full .gb-card .gb-header-text-link,
body.gb-chrome-full .gb-card .gb-header-link-divider,
body.gb-chrome-full .gb-card .gb-section-nav a,
body.gb-chrome-full .gb-card .gb-back-to-feed {
	color: var(--gb-text);
}

/* Defensive resets -- every selector below paints its own card-like
   background (--gb-surface/--gb-input-bg/etc.) but has no explicit
   color of its own today, relying on inheriting --gb-text from an
   ancestor. Without this, the gb-chrome-full override above would leak
   onto these cards and pair on-accent text with a surface background
   never designed to hold it. Unconditional and harmless outside
   gb-chrome-full, since --gb-text is already the effective inherited
   value there regardless. (.gb-reaction-btn:hover/.gb-reaction-active
   and .gb-post-pinned are deliberately omitted -- each already gets its
   color from a base rule declared directly on the same element, which
   is immune to any ancestor's color by definition.) */
body.gb-chrome-full .gb-card,
body.gb-chrome-full .gb-post,
body.gb-chrome-full .gb-rsvp-block,
body.gb-chrome-full .gb-poll-organizer-preview,
body.gb-chrome-full .gb-palette-row,
body.gb-chrome-full .gb-stat-card,
body.gb-chrome-full tr.gb-note-new,
body.gb-chrome-full .gb-avatar-form,
body.gb-chrome-full .gb-notification-prefs-form,
body.gb-chrome-full .gb-media-resizable-footer,
body.gb-chrome-full .gb-modal,
body.gb-chrome-full .gb-card-block-row,
body.gb-chrome-full .gb-manual-toc {
	color: var(--gb-text);
}

.gb-card {
	background: var(--gb-surface);
	border: 1px solid var(--gb-border);
	border-radius: 10px;
	padding: 20px;
	margin-bottom: 20px;
}

.gb-card-center {
	text-align: center;
	padding: 40px 24px;
}

.gb-input {
	width: 100%;
	padding: 10px 12px;
	margin: 4px 0 12px;
	border: 1px solid var(--gb-border);
	border-radius: 6px;
	background: var(--gb-input-bg);
	color: var(--gb-text);
	font-size: 15px;
	font-family: inherit;
	box-sizing: border-box;
}

.gb-button {
	display: inline-block;
	padding: 10px 18px;
	border-radius: 6px;
	border: 1px solid var(--gb-border);
	background: var(--gb-surface);
	color: var(--gb-text);
	cursor: pointer;
	font-size: 15px;
	font-family: inherit;
}

/* color was hardcoded #fff -- fails WCAG AA for Autumn Oak/Golden
   Harvest's own lighter, gold-toned accents (see the contrast audit
   in this file's own top comment). --gb-on-accent is chosen per
   palette specifically for legibility against --gb-primary/--gb-accent,
   and :hover inherits this same resolved value automatically (the
   custom property itself doesn't change between states, only the
   background it's paired with does), so no separate :hover color rule
   is needed. */
.gb-button-primary {
	background: var(--gb-primary-dark);
	border-color: var(--gb-primary-dark);
	color: var(--gb-on-accent);
}

.gb-button-primary:hover {
	background: var(--gb-primary);
}

.gb-post {
	background: var(--gb-surface);
	border: 1px solid var(--gb-border);
	border-radius: 10px;
	padding: 18px 20px;
	margin-bottom: 16px;
}

.gb-wrap h1,
.gb-wrap h2,
.gb-wrap h3,
.gb-post-title {
	font-family: var(--gb-font-heading, inherit);
	margin: 0 0 4px;
}

.gb-post-meta {
	display: flex;
	align-items: center;
	gap: 8px;
	color: var(--gb-text-muted);
	font-size: 13px;
	margin-bottom: 10px;
}

.gb-avatar {
	border-radius: 50%;
	object-fit: cover;
	flex-shrink: 0;
	vertical-align: middle;
	margin-right: 6px;
}

/* ---- Reactions ---- */
.gb-reaction-bar {
	display: flex;
	gap: 4px;
	margin-top: 10px;
}

.gb-reaction-btn {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	background: transparent;
	border: 1px solid var(--gb-border);
	border-radius: 20px;
	padding: 4px 10px;
	cursor: pointer;
	font-size: 14px;
	line-height: 1;
	color: var(--gb-text);
}

.gb-reaction-btn:hover {
	background: var(--gb-surface-alt, rgba(0,0,0,0.04));
}

.gb-reaction-btn.gb-reaction-active {
	border-color: var(--gb-accent, #7a6a4f);
	background: var(--gb-surface-alt, rgba(0,0,0,0.05));
}

.gb-reaction-emoji {
	display: inline-flex;
	align-items: center;
}

.gb-reaction-emoji img {
	display: block;
}

.gb-reaction-count {
	font-size: 12px;
	color: var(--gb-text-muted);
}

/* ---- RSVP ---- */
.gb-rsvp-block {
	margin-top: 12px;
	padding: 10px 14px;
	border: 1px solid var(--gb-border);
	border-radius: 8px;
	background: var(--gb-surface-alt, rgba(0,0,0,0.02));
}

.gb-rsvp-datetime {
	font-weight: 600;
	margin-bottom: 8px;
}

.gb-rsvp-response label {
	display: block;
	margin-bottom: 8px;
	font-size: 13px;
}

.gb-rsvp-headcount-input {
	width: 60px;
	margin-left: 6px;
}

.gb-rsvp-going-status {
	display: flex;
	align-items: center;
	gap: 10px;
	margin-bottom: 8px;
}

.gb-rsvp-total {
	font-size: 13px;
	color: var(--gb-text-muted);
	margin: 4px 0;
}

.gb-rsvp-past {
	font-style: italic;
	color: var(--gb-text-muted);
}

/* ---- Shared "Organizer view" panel — used by both the RSVP breakdown
   and the poll's pre-vote results preview, so the pattern reads as one
   consistent feature ("leadership gets an extra panel here") rather than
   two differently-styled things members might interpret differently. ---- */
.gb-poll-organizer-preview {
	margin-top: 10px;
	padding: 8px 12px;
	border: 1px dashed var(--gb-accent);
	border-radius: 6px;
	background: var(--gb-surface-alt, rgba(0,0,0,0.03));
}

.gb-poll-organizer-preview summary {
	cursor: pointer;
	font-size: 13px;
	font-weight: 600;
	color: var(--gb-accent);
}

.gb-poll-organizer-preview .gb-poll-results,
.gb-rsvp-breakdown-list {
	margin-top: 8px;
}

.gb-rsvp-breakdown-list {
	padding-left: 18px;
	font-size: 13px;
}

/* ---- Polls ---- */
.gb-post-poll {
	border-left: 4px solid var(--gb-accent);
}

.gb-poll-badge {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: var(--gb-accent);
	margin-bottom: 4px;
}

/* Shared wrapper for any inline SVG icon sitting next to text (RSVP date,
   poll badge) — SVG icons are used instead of Unicode emoji throughout
   because emoji rendering depends on font availability/loading order,
   which briefly showed the right icon before a webfont swap replaced it
   with an empty glyph, even with an !important font-family override.
   SVG has no such dependency. */
.gb-icon-inline {
	display: inline-flex;
	align-items: center;
	vertical-align: middle;
}

.gb-icon-inline svg {
	display: block;
}

.gb-poll {
	margin-top: 10px;
}

.gb-poll-option-choice {
	display: block;
	padding: 6px 0;
	font-size: 14px;
}

.gb-poll-comment-input {
	display: block;
	width: 100%;
	box-sizing: border-box;
	margin: 8px 0;
}

.gb-poll-result-row {
	margin-bottom: 10px;
}

.gb-poll-result-label {
	font-size: 14px;
	margin-bottom: 3px;
}

.gb-poll-my-choice .gb-poll-result-label {
	font-weight: 600;
}

.gb-poll-result-bar-wrap {
	background: rgba(0,0,0,0.08);
	border-radius: 4px;
	height: 10px;
	overflow: hidden;
}

.gb-poll-result-bar {
	background: var(--gb-accent, #7a6a4f);
	height: 100%;
}

.gb-poll-result-count {
	font-size: 12px;
	color: var(--gb-text-muted);
	margin-top: 2px;
}

.gb-poll-comments {
	margin-top: 14px;
	border-top: 1px solid var(--gb-border);
	padding-top: 8px;
}

.gb-poll-comments-heading {
	font-size: 13px;
	font-weight: 600;
	margin: 0 0 6px;
}

.gb-poll-comment {
	font-size: 13px;
	margin-bottom: 6px;
}

/* ---- Composer: RSVP / Poll toggles ---- */
.gb-composer-toggle {
	margin-top: 10px;
}

#gb-rsvp-fields,
#gb-poll-builder {
	margin: 8px 0;
	padding: 10px 14px;
	border: 1px solid var(--gb-border);
	border-radius: 8px;
}

.gb-poll-hint {
	font-size: 12px;
	font-style: italic;
	color: var(--gb-text-muted);
	margin-top: 0;
}

.gb-poll-option-row {
	margin-bottom: 6px;
}

.gb-poll-option-row .gb-poll-option-input {
	width: 100%;
	box-sizing: border-box;
}

.gb-comments {
	margin-top: 14px;
	border-top: 1px solid var(--gb-border);
	padding-top: 10px;
}

.gb-comment {
	padding: 8px 0;
	border-bottom: 1px solid var(--gb-border);
	font-size: 14px;
}

.gb-comment:last-child {
	border-bottom: none;
}

.gb-comment-date {
	color: var(--gb-text-muted);
	font-size: 12px;
	margin-left: 6px;
}

.gb-comment-restricted {
	color: var(--gb-text-muted);
	font-style: italic;
	font-size: 13px;
}

/* Plain text-link look for the "Load N more comments" trigger (see
   GB_Feed::RECENT_COMMENTS_LIMIT/ajax_load_more_comments()) -- a real
   <button> for keyboard/click semantics, styled with no button chrome
   since it reads as an inline link sitting above the visible comments,
   not an action button like #gb-load-more's own full post-pagination
   control. */
.gb-load-more-comments {
	display: block;
	background: none;
	border: none;
	padding: 0 0 8px;
	margin: 0 0 8px;
	color: var(--gb-accent);
	font-size: 13px;
	text-decoration: underline;
	cursor: pointer;
	border-bottom: 1px solid var(--gb-border);
}

.gb-load-more-comments:disabled {
	opacity: 0.6;
	cursor: default;
}

.gb-empty {
	color: var(--gb-text-muted);
	text-align: center;
	padding: 30px 0;
}

/* Color Theme picker (Settings screen) -- full-width labeled color-bar
   rows, matching Lodge Sites Engine's own picker design exactly (see
   .lse-palette-* in lodge-sites-engine/assets/css/lse-admin.css and
   LSE_Organization_Profile::render_palette_field()) rather than
   reinventing it. Bar colors come from GB_Settings::THEMES via inline
   style (see settings-page.php), so the bars and the real theme can
   never drift out of sync with each other. */
.gb-palette-picker {
	display: flex;
	flex-direction: column;
	gap: 12px;
	max-width: 900px;
	margin-top: 8px;
}

.gb-palette-row {
	display: flex;
	align-items: center;
	gap: 16px;
	padding: 12px;
	border: 2px solid #dcdcde;
	border-radius: 6px;
	background: #fff;
	cursor: pointer;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.gb-palette-row:hover {
	border-color: #b0b0b3;
}

.gb-palette-row.is-selected,
.gb-palette-row:has( .gb-palette-radio:checked ) {
	border-color: #2271b1;
	box-shadow: 0 0 0 1px #2271b1;
}

.gb-palette-radio {
	flex: 0 0 auto;
	margin: 0;
}

.gb-palette-name {
	flex: 0 0 160px;
	font-weight: 600;
	color: #1d2327;
}

/* flex-wrap: wrap here (not just min-width:0 on the bars) is the actual
   fix for the bars collapsing into an illegible mess on GroupBrief's real
   Settings page: the .form-table <td> this sits in isn't reliably as wide
   as the 900px .gb-palette-picker max-width assumes -- measured against
   the real label text ("BACKGROUND" at this font-size/letter-spacing
   needs ~75px, +8px padding = ~83px), 5 bars with the old `flex: 1 1 0;
   min-width: 0` had NO floor at all and would silently shrink well below
   that on a narrower container, causing inconsistent per-bar text
   wrapping/overflow. Now each bar has a real 90px floor and the row wraps
   as whole, still-legible bars onto additional lines instead. */
.gb-palette-bars {
	display: flex;
	flex: 1 1 auto;
	flex-wrap: wrap;
	gap: 4px;
	min-width: 0;
}

.gb-palette-bar {
	flex: 1 1 90px;
	min-width: 90px;
	height: 64px;
	border-radius: 4px;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	text-align: center;
	font-size: 11px;
	line-height: 1.3;
	padding: 4px;
	box-sizing: border-box;
}

.gb-palette-bar-role {
	text-transform: uppercase;
	letter-spacing: 0.03em;
	opacity: 0.85;
}

.gb-palette-bar-hex {
	font-weight: 600;
	font-family: Consolas, Monaco, monospace;
}

@media ( max-width: 782px ) {
	.gb-palette-row {
		flex-wrap: wrap;
	}

	.gb-palette-name {
		flex: 1 1 100%;
	}
}

/* Same idea for the font-pairing picker: real sample text set in that
   pairing's actual heading/body stacks (via inline style, from
   GB_Settings::FONT_PAIRINGS), not just the pairing's plain label. */
.gb-font-preview {
	display: block;
	margin: 4px 0 2px;
}

.gb-font-preview-heading {
	display: block;
	font-size: 18px;
	font-weight: 700;
}

.gb-font-preview-body {
	display: block;
	font-size: 13px;
	color: #50575e;
}

.gb-theme-option {
	display: inline-flex;
	align-items: flex-start;
	margin-right: 20px;
	vertical-align: top;
}

.gb-theme-option input[type="radio"] {
	margin-top: 8px;
}

.gb-stat-cards {
	display: flex;
	gap: 16px;
	margin: 20px 0;
}

.gb-stat-card {
	background: var(--gb-surface, #fff);
	border: 1px solid var(--gb-border, #dcdcde);
	border-radius: 8px;
	padding: 16px 24px;
	text-align: center;
}

.gb-stat-number {
	display: block;
	font-size: 28px;
	font-weight: 600;
	color: var(--gb-primary, inherit);
	font-family: var(--gb-font-heading, inherit);
}

.gb-stat-label {
	color: var(--gb-text-muted, #646970);
	font-size: 13px;
}

/* Shared tab bar rendered at the top of every GroupBrief admin screen
   (see GB_Admin::render_tab_bar()) -- WP core's own nav-tab-wrapper /
   nav-tab / nav-tab-active classes already provide the active-tab
   distinction and general look, so this is just spacing on top of that. */
.gb-admin-tabs {
	margin-bottom: 0;
}

.gb-admin-advanced-link {
	margin: 8px 0 20px;
	max-width: 480px;
}

/* Ads column -- reuses the .gb-card shell (see feed-layout.php /
   GB_Ads::render_ad()), so it themes automatically like every other
   card. */
.gb-ad {
	text-align: center;
	position: relative;
}

.gb-ad-premium {
	border-color: var(--gb-accent);
}

.gb-ad-premium-badge {
	display: inline-block;
	margin-bottom: 10px;
	padding: 2px 10px;
	border-radius: 20px;
	background: var(--gb-accent);
	color: var(--gb-on-accent);
	font-size: 11px;
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

/* Fills the ad column's full width and scales proportionally via
   height:auto -- deliberately not max-width:100%, which would leave a
   wrong-sized submission (e.g. a tiny icon far off the recommended
   300x250) looking broken/undersized in the card rather than filling
   it. This is the one safety net for an honest sizing mistake, not a
   substitute for the size guidance on the Ads admin screen. */
.gb-ad-image {
	display: block;
	width: 100%;
	height: auto;
	margin: 0 auto;
	border-radius: 6px;
}

.gb-ad-text-link {
	display: block;
}

/* Click-to-expand trigger wrapping an ad's image (see GB_Ads::render_ad()
   and gbInitAdLightbox() in groupbrief.js) -- shared base for both the
   <a> variant (ad has a destination URL) and the <button> variant (no
   URL, nothing to fall back to without JS). The button reset strips its
   native chrome so it reads identically to the plain image. */
.gb-ad-lightbox-trigger {
	display: block;
	cursor: pointer;
}

button.gb-ad-lightbox-trigger {
	width: 100%;
	padding: 0;
	border: none;
	background: none;
}

/* Full-page overlay viewer -- same interaction shape as Lodge Sites
   Engine's Photo Gallery lightbox (see .lse-lightbox in
   lodge-sites-engine/assets/css/lse-frontend.css). The [hidden]
   attribute selector needs to out-rank .gb-ad-lightbox's own
   display:flex below, same reasoning as LSE's version. */
.gb-ad-lightbox {
	position: fixed;
	inset: 0;
	z-index: 1000;
	display: flex;
	align-items: center;
	justify-content: center;
	background-color: rgba( 0, 0, 0, 0.85 );
}

.gb-ad-lightbox[hidden] {
	display: none;
}

.gb-ad-lightbox-content {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 16px;
	max-width: 90vw;
	max-height: 85vh;
}

.gb-ad-lightbox-img {
	display: block;
	max-width: 90vw;
	max-height: 70vh;
	width: auto;
	height: auto;
	border-radius: 6px;
}

.gb-ad-lightbox-visit[hidden] {
	display: none;
}

.gb-ad-lightbox-close {
	position: absolute;
	top: 1rem;
	right: 1rem;
	width: 2.75rem;
	height: 2.75rem;
	border: none;
	border-radius: 50%;
	background-color: rgba( 255, 255, 255, 0.15 );
	color: #fff;
	font-size: 1.75rem;
	line-height: 1;
	cursor: pointer;
}

.gb-ad-lightbox-close:hover {
	background-color: rgba( 255, 255, 255, 0.3 );
}

/* Prevents the page behind the overlay from scrolling while it's open. */
body.gb-ad-lightbox-open {
	overflow: hidden;
}

.gb-post-pinned {
	border-color: var(--gb-accent);
	background: var(--gb-input-bg);
}

.gb-pinned-badge {
	display: inline-block;
	margin-bottom: 8px;
	padding: 3px 10px;
	border-radius: 20px;
	background: var(--gb-accent);
	color: var(--gb-on-accent);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.02em;
	text-transform: uppercase;
}

/* Same shape as .gb-pinned-badge, but a neutral muted background instead
   of the accent so "Hidden" reads as distinct from "Pinned" at a glance. */
.gb-hidden-badge {
	display: inline-block;
	margin-bottom: 8px;
	padding: 3px 10px;
	border-radius: 20px;
	background: var(--gb-text-muted);
	color: var(--gb-frame-text);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.02em;
	text-transform: uppercase;
}

.gb-page-content {
	max-width: 680px;
	margin: 40px auto;
	padding: 32px 36px;
	background: var(--gb-surface, #F6F2E7);
	border-radius: 12px;
	color: var(--gb-text, #1C2333);
	line-height: 1.6;
	font-family: var(--gb-font-body, inherit);
}

/* The two-column feed page needs much more room than the narrow
   single-column reading width above, which stays as-is for Login/Terms/
   Privacy. Matches .gb-feed-layout's own max-width so the card doesn't
   end up wider than the columns it contains. */
.gb-wide-page .gb-page-content {
	max-width: 1148px;
	padding: 24px 12px;
}

.gb-page-content h1,
.gb-page-content h2,
.gb-page-content h3 {
	color: var(--gb-text, #1C2333);
	font-family: var(--gb-font-heading, inherit);
}

.gb-page-content a {
	color: var(--gb-primary, #B08D3E);
}

/* WordPress core Button block, for whatever a site owner drops directly
   into a GB-templated page's own editable content (outside the
   [groupbrief_feed]/[groupbrief_footer] shortcode output entirely) --
   GB has no other awareness of this block, so without this it would
   render in the theme's default black/white instead of the org's own
   palette. color is --gb-on-accent specifically, not --gb-bg -- that
   pairing was a real contrast bug in an old Additional CSS workaround
   this replaces (see the WCAG audit in this file's own top comment for
   why --gb-on-accent is the correct pairing for text on --gb-primary). */
.gb-page-content .wp-block-button__link {
	background-color: var(--gb-primary);
	color: var(--gb-on-accent);
}

/* Denton's own real branded footer for groupbrief.com's own
   gb-dp-marketing pages, rendered by gbsp_render_footer() in the
   separate, non-distributed groupbrief-site-pages.php -- styled here
   since this stylesheet loads site-wide. Deliberately fixed
   white-on-dark (not theme-variable-driven like .gb-footer above):
   this footer always sits on the Autumn-Oak-locked .gb-dp-marketing
   body background, not a per-org palette, so it had no styling at all
   until now and was rendering as raw unstyled black text. */
.gb-marketing-footer {
	color: #ffffff;
	text-align: center;
}

.gb-marketing-footer-links a {
	color: #ffffff;
	text-decoration: underline;
}

/* No background of its own -- the plain background: var(--gb-bg, ...)
   line that used to live here predates the body-background chrome-parity
   work and, being a class selector, silently outranked body{}'s own
   fixed heading-derived background purely on specificity, regardless of
   source order. Confirmed live: removing the gb-blank-template class
   from <body> (eliminating just this rule) was enough on its own to let
   body{}'s real color-mix() rule take over correctly. margin:0 is
   unrelated and still needed -- it zeroes the browser's default body
   margin for this template. */
.gb-blank-template {
	margin: 0;
}

.gb-footer {
	text-align: center;
	padding: 20px;
	font-size: 13px;
	color: var(--gb-frame-text-muted, #B7BDD1);
	line-height: 1.6;
}

.gb-footer-copyright {
	font-weight: 500;
	color: var(--gb-frame-text, #F6F2E7);
}

.gb-footer-links a {
	color: inherit;
	text-decoration: none;
	opacity: 0.85;
}

.gb-footer-links a:hover {
	opacity: 1;
	text-decoration: underline;
}

.gb-footer-address {
	opacity: 0.7;
	font-size: 12px;
}

.gb-footer-powered {
	margin-top: 6px;
	font-size: 11px;
	opacity: 0.6;
}

.gb-footer-powered a {
	color: inherit;
	text-decoration: underline;
}

.gb-license-notice {
	border-color: #a02a2a;
	color: #a02a2a;
	text-align: center;
}

.gb-leadership-cta {
	text-align: center;
}

.gb-leadership-cta #gb-leadership-toggle {
	width: 100%;
}

.gb-leadership-hint {
	margin: 8px 0 0;
	font-size: 12px;
	font-style: italic;
	color: var(--gb-text-muted);
}

.gb-leadership-cta #gb-leadership-form {
	text-align: left;
	margin-top: 12px;
}

.gb-leadership-cta #gb-leadership-message {
	width: 100%;
	box-sizing: border-box;
}

tr.gb-note-new {
	font-weight: 600;
	background: #fff8e5;
}

.gb-status-pending { color: #b26a00; }
.gb-status-redeemed { color: #1a7a3c; }
.gb-status-revoked, .gb-status-expired { color: #a02a2a; }

#gb-password-strength {
	display: inline-block;
	margin-left: 8px;
	font-size: 12px;
	font-weight: 600;
	vertical-align: middle;
}

.gb-strength-weak { color: #a02a2a; }
.gb-strength-medium { color: #b26a00; }
.gb-strength-strong { color: #1a7a3c; }

.gb-password-hint {
	display: block;
	color: var(--gb-text-muted);
	font-size: 12px;
	margin-top: 4px;
}

/* Username availability check (invitation-gate + Profile page) — same
   red as .gb-strength-weak above, for the same "this needs attention"
   meaning. */
.gb-field-error {
	color: #a02a2a;
}

.gb-remember-label {
	display: flex;
	align-items: center;
	gap: 6px;
	font-size: 14px;
	font-weight: normal;
}

.gb-remember-label input {
	width: auto;
	margin: 0;
}

.gb-auth-notice {
	background: var(--gb-surface);
	border-color: var(--gb-primary);
	color: var(--gb-primary-dark);
	font-weight: 600;
	padding: 16px 24px;
}

.gb-auth a {
	color: var(--gb-primary);
	text-decoration: none;
	font-size: 14px;
}

.gb-auth a:hover {
	text-decoration: underline;
}

.gb-invitation-gate {
	/* This page builds its own bare document rather than going through
	   GB_Page_Template like the feed and login pages do, so it never
	   inherits their .gb-page-content wrapper — including its top
	   margin, which is why the card sat flush against the browser
	   window instead of having any breathing room above it. */
	margin-top: 40px;
}

.gb-two-factor-setup,
.gb-two-factor-challenge {
	/* Same fix as .gb-invitation-gate above: these build their own bare
	   document rather than going through GB_Page_Template like Feed/Login
	   do, so they never inherit .gb-page-content's top margin. */
	margin-top: 40px;
}

.gb-org-logo {
	text-align: center;
	margin-bottom: 20px;
}

/* A little extra breathing room specifically when the logo leads a
   centered auth/invitation card — scoped narrowly so it doesn't add
   unwanted space to .gb-card-center's other use (feed-locked.php's
   plain message box, which has no logo). */
.gb-card-center .gb-org-logo {
	margin-top: 10px;
}

.gb-header-row {
	position: relative;
}

.gb-header-links-row {
	text-align: center;
	margin-bottom: 10px;
	font-size: 13px;
}

.gb-header-link-divider {
	margin: 0 8px;
	color: var(--gb-border);
}

.gb-header-text-link {
	font-weight: 600;
	color: var(--gb-text);
	text-decoration: underline;
	cursor: pointer;
	background: none;
	border: none;
	font-size: 13px;
}

.gb-header-text-link:hover {
	color: var(--gb-accent);
}

/* .gb-avatar-form/.gb-notification-prefs-form used to be absolutely-
   positioned floating popovers, anchored under a header toggle link
   (.gb-my-avatar/.gb-my-notifications). Both toggle links and their
   wrapper spans are gone now (see feed.php / profile.php) -- these are
   permanent, always-visible sections of the Profile page instead, so
   they're plain in-flow blocks now, not popovers. */
.gb-avatar-form {
	max-width: 320px;
	padding: 12px 0;
}

.gb-notification-prefs-form {
	max-width: 480px;
	padding: 12px 0;
}

.gb-avatar-form input[type="file"] {
	display: block;
	font-size: 12px;
	margin-bottom: 8px;
}

.gb-avatar-form .gb-button {
	font-size: 12px;
	padding: 6px 10px;
}

#gb-avatar-status {
	display: block;
	margin-top: 6px;
	font-size: 12px;
}

.gb-notification-prefs-form select,
.gb-notification-prefs-form input[type="tel"] {
	width: 100%;
	max-width: 320px;
	font-size: 12px;
}

.gb-notification-prefs-form .gb-button {
	font-size: 12px;
	padding: 6px 10px;
}

.gb-consent-label {
	display: flex;
	align-items: flex-start;
	gap: 6px;
	font-size: 11px;
	line-height: 1.4;
}

.gb-consent-label input[type="checkbox"] {
	margin-top: 2px;
	flex-shrink: 0;
}

#gb-notification-prefs-status {
	display: block;
	margin-top: 6px;
	font-size: 12px;
}

.gb-org-logo img {
	/* max-height (not width:100%, which this rule used to have) so the
	   logo scales proportionally without distortion no matter its
	   native aspect ratio — lodge/org logos vary between round, square,
	   and rectangular. width:100% matched the post-card column's width
	   for a wide/short logo, but stretched a tall or square logo (e.g.
	   a round emblem) to a dominating, near-full-column height instead.
	   width: auto (not max-width) lets the image find its own natural
	   width under that height cap, rather than being distorted or
	   needlessly narrowed. */
	max-height: 140px;
	width: auto;
	height: auto;
}

.gb-org-logo-placeholder {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 72px;
	border: 2px dashed var(--gb-border);
	border-radius: 8px;
	color: var(--gb-text-muted);
	font-size: 13px;
	letter-spacing: 0.03em;
	text-transform: uppercase;
	background: var(--gb-surface);
	box-sizing: border-box;
}

.gb-media-hint {
	display: inline-block;
	margin-left: 8px;
	color: var(--gb-text-muted);
	font-size: 12px;
}

#gb-media-preview {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 8px 0;
}

.gb-media-thumb {
	position: relative;
	width: 70px;
	height: 70px;
	border-radius: 6px;
	overflow: hidden;
	border: 1px solid var(--gb-border);
}

.gb-media-thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.gb-media-thumb .gb-media-remove {
	position: absolute;
	top: 2px;
	right: 2px;
	width: 18px;
	height: 18px;
	border-radius: 50%;
	background: rgba(0,0,0,0.6);
	color: #fff;
	border: none;
	font-size: 13px;
	line-height: 18px;
	cursor: pointer;
	padding: 0;
}

.gb-media-resizable {
	position: relative;
	width: 100%;
	max-width: 100%;
	min-width: 80px;
	resize: horizontal;
	overflow: auto;
	border: 1px dashed var(--gb-border);
	border-radius: 6px;
	padding: 0;
	box-sizing: border-box;
}

.gb-media-resizable img {
	width: 100%;
	height: auto;
	display: block;
	pointer-events: none;
}

.gb-media-resizable-footer {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	padding: 4px 6px;
	background: var(--gb-input-bg);
	font-size: 11px;
}

.gb-media-size-label {
	color: var(--gb-text-muted);
	font-variant-numeric: tabular-nums;
}

.gb-media-resizable .gb-media-remove {
	position: static;
	width: auto;
	height: auto;
	border-radius: 4px;
	background: transparent;
	color: var(--gb-text-muted);
	font-size: 11px;
	line-height: normal;
	padding: 2px 6px;
	border: 1px solid var(--gb-border);
}

.gb-media-resizable .gb-media-remove:hover {
	color: var(--gb-text);
	border-color: var(--gb-text-muted);
}

.gb-post-media {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 8px;
	margin-top: 10px;
}

.gb-post-media-image {
	max-width: 100%;
	height: auto;
	border-radius: 8px;
	display: block;
	min-width: 0; /* without this, flex items default to min-width:auto and refuse to
	                 shrink below the image's natural size, silently overriding the
	                 saved width % from the resize feature */
}

.gb-post-media-video {
	max-width: 100%;
	border-radius: 8px;
	display: block;
}

.gb-external-link {
	display: block;
	width: fit-content;
	margin: 10px auto 0;
	padding: 6px 12px;
	border-radius: 20px;
	background: var(--gb-input-bg);
	border: 1px solid var(--gb-border);
	color: var(--gb-primary);
	font-size: 13px;
	text-decoration: none;
}

.gb-external-link:hover {
	border-color: var(--gb-primary);
}

.gb-modal-overlay {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background: rgba(0,0,0,0.5);
	display: flex;
	align-items: center;
	justify-content: center;
	z-index: 9999;
	padding: 20px;
	box-sizing: border-box;
}

.gb-modal-overlay[hidden] {
	display: none;
}

.gb-modal {
	background: var(--gb-surface);
	border-radius: 12px;
	padding: 24px;
	max-width: 380px;
	width: 100%;
}

.gb-modal h3 {
	margin: 0 0 10px;
	color: var(--gb-text);
}

.gb-modal p {
	margin: 0 0 12px;
	color: var(--gb-text-muted);
	font-size: 14px;
}

.gb-modal-domain {
	font-weight: 600;
	color: var(--gb-text) !important;
	word-break: break-all;
}

.gb-modal-actions {
	display: flex;
	gap: 10px;
	margin-top: 16px;
}

/* ==========================================================================
   Two-column layout (feed + sidebar cards) — Feature: Two-Column Layout
   ========================================================================== */

/* Panel background lives here rather than on the nested .gb-wrap --
   .gb-feed-layout is the actual outermost container on the main feed
   page (feed-col, cards-col, and the optional ads-col are all its
   direct flex children), so painting it here gives every column one
   continuous panel instead of only the feed column getting color while
   cards/ads floated on the plain page background. Same accent-derived,
   --gb-chrome-intensity-driven formula .gb-wrap itself uses, so it
   still varies with the same admin setting. The ads column is entirely
   optional (feed-layout.php only renders it when the ads module is
   enabled) -- flex naturally reflows to 2 or 3 columns either way, and
   painting the background here means that doesn't matter: it's one
   rule regardless of how many columns exist. */
.gb-feed-layout {
	display: flex;
	gap: 28px;
	align-items: flex-start;
	max-width: 1100px;
	margin: 0 auto;
	padding: 24px 16px;
	box-sizing: border-box;
	background-color: var(--gb-bg);
	background-color: color-mix(in srgb, var(--gb-accent) var(--gb-chrome-intensity), var(--gb-bg));
	/* Rounds the panel's own outer edge to match the cards inside it --
	   .gb-feed-layout is the single element painting the whole panel
	   background (see the comment above .gb-wrap's own background
	   reset below), so this is just a plain border-radius on that one
	   box, independent of however many flex columns it happens to
	   contain. Still deliberately no overflow:hidden alongside it --
	   .gb-ads-col no longer uses position:sticky (see .gb-ads-col
	   below), so that specific old objection (clipping overflow on an
	   ancestor would break a sticky descendant's own scroll-container
	   math) no longer applies -- but every child already has this
	   rule's own 16px horizontal padding as clearance from the edge,
	   so overflow:hidden still isn't actually doing anything useful
	   here; nothing currently renders past this box's edge for it to
	   clip. Revisit only if something genuinely needs clipping later. */
	border-radius: 16px;
}

.gb-feed-layout .gb-feed-col,
.gb-feed-layout .gb-cards-col,
.gb-feed-layout .gb-ads-col {
	min-width: 0; /* prevent flex children from overflowing on long content */
}

/* .gb-wrap's own background is cleared here, not just left redundant --
   .gb-feed-layout above already paints the same color for the whole
   row, so a second opaque fill on top would be pure dead weight (and
   would silently mask .gb-feed-layout's own background from ever being
   the thing actually visible here, which matters if these two formulas
   ever diverge later). Only .gb-feed-col ever has a nested .gb-wrap --
   .gb-cards-col/.gb-ads-col render plain .gb-card elements directly,
   never their own .gb-wrap, so no matching selector exists for them. */
.gb-feed-layout .gb-feed-col .gb-wrap {
	max-width: none;
	margin: 0;
	padding: 0 16px;
	background: transparent;
}

/* Independent of the feed/cards ratio system entirely (LAYOUT_RATIOS/
   LAYOUT_SIDES never touch this) — a fixed-ish width that can shrink on
   a medium-narrow viewport, ahead of the 782px full stack below. Always
   last in both DOM and visual order regardless of the feed/cards "side"
   setting. Present in the markup whenever the ads module is enabled,
   even with nothing currently active to show (see feed-layout.php), so
   a later timer-driven refresh (see GB_Ads::ajax_refresh_ads() and
   groupbrief.js's polling) has somewhere to inject into — the :has()
   rule below (keyed off the inner .gb-ads-col-inner wrapper being empty,
   since the column also holds an always-present static hint) collapses
   it to zero footprint (no reserved width, no gap) until that happens,
   and un-collapses automatically the moment real content lands since
   :has() is a live selector. No longer
   position:sticky -- ads now rotate on their own timer regardless of
   scroll position, so there's no reason to pin the column in place
   while the feed scrolls past it. */
.gb-ads-col {
	flex: 0 1 200px;
	order: 3;
}

/* Keys off the inner .gb-ads-col-inner wrapper being empty, not the
   column itself — the column now also holds the always-present static
   "Click on any ad to enlarge" hint (see feed-layout.php), so it's never
   truly :empty. Only the inner wrapper empties out when no ads are active.
   Browsers without :has() support just don't match this rule, leaving the
   column (hint included) visible even with nothing active — a harmless
   graceful degradation, same reasoning as .wrap form p.submit:has( #submit )
   and .gb-palette-row:has( .gb-palette-radio:checked ). :has() is a live
   selector, so the column collapses and un-collapses automatically as the
   polling refresh empties or repopulates .gb-ads-col-inner. */
.gb-ads-col:has( .gb-ads-col-inner:empty ) {
	display: none;
}

/* Small muted lead-in above the ad cards. Static — lives outside
   .gb-ads-col-inner so the rotation timer never replaces it. */
.gb-ads-hint {
	margin: 0 0 10px;
	font-size: 13px;
	color: var( --gb-text-muted );
}

/* Ratio presets — admin-selected, three fixed options rather than a slider. */
.gb-layout-feed60 .gb-feed-col  { flex: 6 1 0%; }
.gb-layout-feed60 .gb-cards-col { flex: 4 1 0%; }
.gb-layout-feed50 .gb-feed-col,
.gb-layout-feed50 .gb-cards-col { flex: 1 1 0%; }
.gb-layout-feed40 .gb-feed-col  { flex: 4 1 0%; }
.gb-layout-feed40 .gb-cards-col { flex: 6 1 0%; }

/* Side — independent of ratio: which column sits on which side. DOM order
   always stays feed-first (see feed-layout.php); this only ever changes
   the *visual* order via flex, so mobile can cleanly reset to source order. */
.gb-layout-feed_left .gb-feed-col   { order: 1; }
.gb-layout-feed_left .gb-cards-col  { order: 2; }
.gb-layout-feed_right .gb-feed-col  { order: 2; }
.gb-layout-feed_right .gb-cards-col { order: 1; }

.gb-load-more-wrap {
	text-align: center;
	margin: 20px 0;
}

.gb-section-title {
	margin-top: 0;
}

.gb-section-header {
	display: flex;
	align-items: center;
	gap: 14px;
	margin-bottom: 20px;
}

.gb-section-icon img {
	max-height: 56px;
	max-width: 56px;
	width: auto;
	height: auto;
	border-radius: 8px;
}

.gb-section-header .gb-section-title {
	margin: 0;
}

.gb-back-to-feed {
	display: inline-block;
	margin-bottom: 20px;
	color: var(--gb-text-muted);
	text-decoration: none;
	font-size: 13px;
}

.gb-back-to-feed:hover {
	color: var(--gb-text);
	text-decoration: underline;
}

.gb-section-mod-panel {
	margin-bottom: 20px;
}

.gb-section-mod-panel summary {
	cursor: pointer;
	font-weight: 600;
	color: var(--gb-text);
}

.gb-section-mod-table {
	width: 100%;
	margin-top: 12px;
	border-collapse: collapse;
}

.gb-section-mod-table td {
	padding: 6px 0;
	border-bottom: 1px solid var(--gb-border);
	font-size: 14px;
}

/* ==========================================================================
   Sidebar cards — Feature: Semi-permanent Sidebar Cards
   ========================================================================== */

.gb-sidebar-card {
	position: relative;
}

.gb-card-icon {
	max-width: 48px;
	max-height: 48px;
	width: auto;
	height: auto;
	margin-bottom: 10px;
	display: block;
}

.gb-card-hours-grid {
	width: 100%;
	border-collapse: collapse;
	margin-bottom: 8px;
}

.gb-card-hours-grid td {
	padding: 4px 0;
	font-size: 14px;
	vertical-align: top;
}

.gb-card-hours-day {
	font-weight: 600;
	padding-right: 12px;
	white-space: nowrap;
	color: var(--gb-text);
}

.gb-card-hours-time {
	color: var(--gb-text-muted);
}

.gb-card-hours-exceptions {
	font-size: 13px;
	color: var(--gb-text-muted);
	margin: 6px 0 0;
	font-style: italic;
}

.gb-card-contact-row {
	display: flex;
	justify-content: space-between;
	gap: 10px;
	padding: 5px 0;
	font-size: 14px;
	border-bottom: 1px solid var(--gb-border);
}

.gb-card-contact-row:last-child {
	border-bottom: none;
}

.gb-card-contact-label {
	color: var(--gb-text-muted);
}

.gb-card-contact-value {
	color: var(--gb-text);
	text-align: right;
	word-break: break-word;
}

.gb-card-block {
	margin-bottom: 12px;
}

.gb-card-block:last-child {
	margin-bottom: 0;
}

.gb-card-image img {
	max-width: 100%;
	height: auto;
	border-radius: 6px;
	display: block;
}

.gb-card-text {
	font-size: 14px;
	color: var(--gb-text);
}

.gb-card-highlight-number {
	font-size: 30px;
	font-weight: 700;
	font-family: var(--gb-font-heading, inherit);
	color: var(--gb-primary-dark);
	line-height: 1.1;
}

.gb-card-highlight-label {
	font-size: 13px;
	color: var(--gb-text-muted);
	margin-top: 2px;
}

.gb-card-status-line {
	display: inline-block;
	font-size: 13px;
	padding: 4px 10px;
	border-radius: 999px;
	background: var(--gb-input-bg);
	border: 1px solid var(--gb-border);
	color: var(--gb-text);
}

.gb-card-link-button {
	display: block;
	text-align: center;
	text-decoration: none;
}

.gb-section-nav {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	justify-content: center;
	margin-bottom: 20px;
}

.gb-section-nav a {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 4px 10px;
	border: 1px solid var(--gb-border);
	border-radius: 999px;
	color: var(--gb-primary-dark);
	text-decoration: none;
	font-size: 13px;
	font-weight: 600;
}

.gb-section-nav a img {
	max-height: 16px;
	max-width: 16px;
	width: auto;
	height: auto;
	border-radius: 3px;
	flex-shrink: 0;
}

/* ==========================================================================
   Admin: Cards builder form (GroupBrief → Cards)
   ========================================================================== */

.gb-card-block-row {
	border: 1px solid #dcdcde;
	border-radius: 4px;
	padding: 10px 12px;
	margin-bottom: 10px;
	background: #fff;
}

.gb-card-block-fields {
	margin-top: 8px;
}

.gb-card-social-row {
	margin: 4px 0;
}

.gb-moderator-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin-bottom: 8px;
}

.gb-moderator-chip {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 4px 6px 4px 10px;
	background: #f0f0f1;
	border: 1px solid #dcdcde;
	border-radius: 999px;
	font-size: 13px;
	line-height: 1.4;
}

.gb-remove-moderator {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 18px;
	height: 18px;
	padding: 0;
	border: none;
	border-radius: 50%;
	background: transparent;
	color: #646970;
	font-size: 15px;
	line-height: 1;
	cursor: pointer;
}

.gb-remove-moderator:hover {
	background: #dcdcde;
	color: #1d2327;
}

.gb-no-moderators {
	color: #646970;
	font-style: italic;
	font-size: 13px;
}

.gb-add-moderator-row {
	display: flex;
	gap: 6px;
	align-items: center;
}

.gb-max-moderators-note {
	color: #646970;
	font-size: 13px;
	font-style: italic;
	margin: 4px 0 0;
}

/* ==========================================================================
   Mobile — stacked layout. Feed always renders first regardless of the
   desktop "side" setting; membership can skew older, so tap targets stay
   generous and nothing here depends on hover or swipe gestures.
   ========================================================================== */

@media (max-width: 782px) {
	.gb-feed-layout {
		display: block;
		padding: 0 12px;
	}

	.gb-feed-layout .gb-feed-col,
	.gb-feed-layout .gb-cards-col {
		order: initial; /* undo any desktop left/right swap — feed-first always */
	}

	.gb-feed-layout .gb-cards-col {
		margin-top: 28px;
	}

	.gb-ads-col {
		order: initial;
		margin-top: 28px;
	}
}

.gb-modal-actions .gb-button {
	flex: 1;
}

/* ---- User Manual ---- */
.gb-manual h1 {
	margin-bottom: 4px;
}

.gb-manual-intro {
	color: var(--gb-text-muted);
	margin-top: 0;
}

.gb-manual-toc {
	background: var(--gb-input-bg);
	border: 1px solid var(--gb-border);
	border-radius: 8px;
	padding: 14px 18px;
	margin: 20px 0;
}

.gb-manual-toc ul {
	columns: 2;
	margin: 8px 0 0;
	padding-left: 18px;
}

.gb-manual h2 {
	margin-top: 32px;
	padding-top: 8px;
	border-top: 1px solid var(--gb-border);
}

/* Section column on the admin Posts list (admin/views/posts-page.php) —
   Section posts get the accent color so they visually stand out as the
   exception; Main Feed is deliberately muted/neutral since it's the
   default, common case and shouldn't compete for attention. Uses the
   same theme variables as the rest of the admin/front-end, so it matches
   whichever of the 4 color palettes the org picked at setup rather than
   being hardcoded to one look. */
.gb-section-badge {
	display: inline-block;
	padding: 2px 10px;
	border-radius: 999px;
	font-size: 12px;
	font-weight: 600;
	background: var(--gb-accent);
	color: var(--gb-on-accent);
}
.gb-section-badge-main {
	background: transparent;
	border: 1px solid var(--gb-border);
	color: var(--gb-text-muted);
	font-weight: 400;
}
.gb-posts-filter {
	margin: 12px 0;
}
.gb-posts-filter label {
	font-weight: 600;
	margin-right: 6px;
}

/* Printing (or "Save as PDF") should show just the manual itself —
   navigation aids and interactive controls that make no sense on paper
   are hidden via this one class rather than a growing list of specific
   selectors, so anything new added later just needs this same class.
   The wp-admin-specific selectors below cover the Admin Manual, which
   lives inside wp-admin rather than on the front end. */
@media print {
	.gb-no-print,
	.gb-footer,
	#wpadminbar,
	#adminmenumain,
	#adminmenuback,
	#adminmenuwrap,
	#wpfooter,
	#screen-meta-links,
	#screen-meta,
	.wrap > h1:first-child,
	.notice {
		display: none !important;
	}
	#wpcontent,
	#wpbody,
	#wpbody-content {
		margin: 0 !important;
		padding: 0 !important;
	}
}

/* ================================================================ *
 * Modern template treatment -- only active when the Community Feed
 * is running as part of CSE and the site has the Modern design
 * selected (see GB_Settings::get_active_site_template()). Matches
 * Modern's own soft/editorial language: flat untinted background,
 * floating near-white cards with ambient shadow, pill buttons,
 * generous line-height. Classic and standalone GroupBrief installs
 * never see any of this.
 * ================================================================ */

/* Flat background, no accent panel wash -- matches Modern's own page
   background exactly (body.lse-modern uses plain var(--lse-color-bg)
   with zero tint; only header bands get a light heading tint, and the
   feed has no equivalent header-band component to apply that to). */
body.gb-template-modern .gb-wrap,
body.gb-template-modern .gb-feed-layout {
	background-color: var(--gb-bg);
}

/* Cards float: lighter surface tint, larger radius, soft ambient
   shadow -- Modern's exact .lse-modern-card formula. */
body.gb-template-modern .gb-card,
body.gb-template-modern .gb-post {
	background: color-mix(in srgb, var(--gb-bg) 85%, #ffffff);
	border-radius: 16px;
	border-color: color-mix(in srgb, var(--gb-text-muted) 32%, transparent);
	box-shadow: 0 10px 40px -24px color-mix(in srgb, var(--gb-heading) 60%, transparent);
}

/* Pill buttons, Modern's exact shape/weight. */
body.gb-template-modern .gb-button,
body.gb-template-modern .gb-button-primary {
	border-radius: 999px;
	padding: 12px 26px;
	border-width: 2px;
}

/* Generous line-height, matching body.lse-modern. */
body.gb-template-modern .gb-wrap {
	line-height: 1.65;
}

/* Form inputs: Modern's radius/padding, plus a soft accent-tinted
   focus ring in place of the browser default outline. */
body.gb-template-modern .gb-input {
	border-radius: 9px;
	padding: 11px 14px;
}
body.gb-template-modern .gb-input:focus {
	outline: none;
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--gb-accent) 25%, transparent);
}

/* Left-border accent callouts (poll/RSVP boxes) pick up Modern's soft
   background wash instead of a bare border. */
body.gb-template-modern .gb-post-poll,
body.gb-template-modern #gb-rsvp-fields,
body.gb-template-modern #gb-poll-builder {
	background: color-mix(in srgb, var(--gb-accent) 8%, transparent);
	border-radius: 8px;
}

/* Flatten the outer page canvas too. body.gb-frontend (~top of this file)
   paints every GB frontend page with a fixed 100%-heading-color background,
   independent of template/chrome -- under Modern that outer canvas should be
   flat, matching .gb-wrap above. Two classes so it reliably outweighs
   body.gb-frontend regardless of source order (same approach as the rest of
   this block). Applies to every GB frontend page (feed, invitation gate, 2FA),
   since Modern is a whole-site choice. */
body.gb-template-modern.gb-frontend {
	background-color: var(--gb-bg);
}

/* Second layer of the same "outer canvas" flattening: .gb-page-content is a
   white reading-card wrapper (background + 12px radius) meant for plain
   single-column pages (Login, Terms, Privacy). .gb-wide-page reuses it for the
   feed but doesn't clear that card look, so under Modern the feed gets a
   redundant boxed panel between the now-flat body and the already-flat
   .gb-feed-layout. Clear it -- but only for the wide (feed) wrapper; three
   classes so it outranks the base .gb-page-content rule regardless of source
   order. Plain single-column pages keep their reading card even under Modern. */
body.gb-template-modern.gb-wide-page .gb-page-content {
	background: transparent;
	border-radius: 0;
}

/* Modern flattens .gb-wrap to a plain --gb-bg panel above, which removes the
   accent background the gb-chrome-full on-accent text swap earlier in this
   file assumes. Without this, at Page Background Intensity 100% that swap
   paints on-accent text onto a near-white panel -- measured at 1.08:1 on
   Regatta Blue, i.e. invisible. The .gb-card-nested instances are already
   repainted --gb-text earlier; these are the two that sit uncarded directly
   on the panel.

   The compound body.gb-template-modern.gb-chrome-full (both classes on the
   subject, no descendant space) is what out-specifies
   body.gb-chrome-full .gb-back-to-feed. */
body.gb-template-modern.gb-chrome-full .gb-wrap {
	color: var(--gb-text);
}
body.gb-template-modern.gb-chrome-full .gb-back-to-feed,
body.gb-template-modern.gb-chrome-full .gb-empty {
	color: var(--gb-text-muted);
}
body.gb-template-modern.gb-chrome-full .gb-back-to-feed:hover {
	color: var(--gb-text);
}

/* ================================================================ *
 * Mobile ad interleaving. On mobile the three-column feed layout
 * collapses to a single stack, which would push the whole ads column
 * below every post. Instead we interleave ads directly into the post
 * stream (.gb-inline-ad slots, placed by GB_Ads::compute_insertion_
 * plan()) and hide the now-redundant column. Desktop is untouched:
 * the inline slots stay hidden and the column shows as normal.
 * ================================================================ */
.gb-inline-ad {
	display: none;
}

@media (max-width: 782px) {
	.gb-ads-col {
		display: none;
	}
	.gb-inline-ad {
		display: block;
		margin: 20px 0; /* match .gb-post's existing vertical rhythm */
	}
}
