/* UltraTech SAPPI — mobile-first styles.
   Scoped under .fa-wrap / .fa-auth-wrap so nothing here leaks onto the rest
   of the shared spillcontainment.com site. */

[x-cloak] { display: none !important; }

.fa-wrap, .fa-auth-wrap {
	--fa-primary: #016325;
	--fa-primary-dark: #014a1c;
	--fa-text: #414042;
	--fa-danger: #b3261e;
	--fa-border: #dfe1e1;
	--fa-bg: #f6f7f6;
	--fa-shadow: 0 1px 3px rgba(65,64,66,.08), 0 1px 2px rgba(65,64,66,.06);
	box-sizing: border-box;
	max-width: 900px;
	margin: 0 auto;
	padding: 16px;
	color: var(--fa-text);
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
	font-size: 16px;
	line-height: 1.5;
}
.fa-wrap *, .fa-auth-wrap * { box-sizing: border-box; }
.fa-wrap h2, .fa-wrap h3, .fa-wrap h4, .fa-auth-wrap h2 { color: var(--fa-text); letter-spacing: -.01em; }
/* Root cause (confirmed via DevTools, 2026-07-25): this plugin's own CSS
   prefix "fa-" (for "Facility Assessment") collides with Font Awesome's
   icon class naming convention — Font Awesome is loaded site-wide and
   defines a ::before rule for every icon it ships, keyed by class name
   (e.g. .fa-section, .fa-share, .fa-dashboard). Any of our own classes that
   happen to also be a real Font Awesome icon name silently inherit that
   icon's ::before content, which renders as an empty box (a private-use
   Unicode codepoint with no matching font-family applied). Not
   heading-specific — any element can collide — so this suppresses
   ::before/::after on every element in our scope, not just h1–h6. That
   includes the .fa-wrap/.fa-auth-wrap root element itself (confirmed via
   DevTools showing div.fa-wrap.fa-dashboard::before) — a plain descendant
   selector (`.fa-wrap *`) only matches elements INSIDE it, not the wrapper
   carrying both classes at once, so the wrapper needs its own explicit
   ::before/::after rule alongside the descendant one. Doubles the wrapper
   class to out-rank Font Awesome's single-class selector on specificity, in
   case both rules end up using !important.

   EXCLUDES input/label (confirmed 2026-07-26): the site's theme draws its
   checkbox/radio checkmarks via a ::before/::after pseudo-element after
   resetting the native appearance — this blanket rule was silently killing
   that too, not just phantom Font Awesome icons, which is why the
   Non-Compliance checkboxes never showed a check mark. Verified isolated
   checkbox+accent-color markup renders fine with the suppression scoped
   away from inputs/labels, so this is narrowed to the actual offenders
   (divs, headings, sections, etc.) instead of every element unconditionally. */
.fa-wrap.fa-wrap::before, .fa-wrap.fa-wrap::after,
.fa-wrap.fa-wrap *:not(input):not(label)::before, .fa-wrap.fa-wrap *:not(input):not(label)::after,
.fa-auth-wrap.fa-auth-wrap::before, .fa-auth-wrap.fa-auth-wrap::after,
.fa-auth-wrap.fa-auth-wrap *:not(input):not(label)::before, .fa-auth-wrap.fa-auth-wrap *:not(input):not(label)::after {
	content: none !important;
	display: none !important;
}

/* Buttons */
.fa-button {
	display: inline-block;
	padding: 12px 18px;
	border-radius: 8px;
	border: 1px solid transparent;
	font-size: 14px;
	font-weight: 600;
	text-decoration: none;
	cursor: pointer;
	touch-action: manipulation;
	transition: background-color .15s ease, border-color .15s ease, color .15s ease, transform .05s ease;
}
.fa-button:active { transform: translateY(1px); }
/* !important on color/background here is deliberate: these pages render
   inside the site's normal theme (Elementor/OceanWP), whose own global
   `a`/`button` styles can otherwise win on specificity or !important and
   leave button text invisible against the fill color. */
.fa-button-primary { background: var(--fa-primary) !important; color: #fff !important; box-shadow: var(--fa-shadow); border-color: var(--fa-primary) !important; }
/* :focus-visible, not plain :focus — clicking the button (mouse, not
   keyboard) leaves it focused until something else is clicked, and plain
   :focus would keep it gray even after the mouse moves away. :focus-visible
   only matches keyboard-driven focus, so a click-then-move-away correctly
   falls back to green, while tabbing to it with the keyboard still shows
   the gray as a focus indicator. */
.fa-button-primary:hover, .fa-button-primary:focus-visible { background: var(--fa-text) !important; color: #fff !important; }
.fa-button-primary:disabled { opacity: .6; cursor: default; }
.fa-button-secondary { background: #fff !important; color: var(--fa-primary) !important; border-color: var(--fa-primary) !important; transition: background-color .5s ease, color .5s ease, border-color .5s ease; }
/* Stays unfilled on hover (background stays white) — only the border/text
   shift to the same muted gray used elsewhere for secondary/quiet text.
   :focus-visible, not plain :focus — same reasoning as .fa-button-primary
   above. */
.fa-button-secondary:hover, .fa-button-secondary:focus-visible { border-color: var(--fa-text) !important; color: var(--fa-text) !important; }
/* "Empty Trash" (Reports page's Deleted view only — see templates/reports.php)
   — a full boxy button rather than the small .fa-delete-chip used per-card,
   since it acts on every trashed assessment at once and sits where the
   Export to CSV button normally does; same red as .fa-delete-chip so it
   still reads as destructive at a glance. */
.fa-button-danger { background: var(--fa-danger) !important; color: #fff !important; border-color: var(--fa-danger) !important; }
.fa-button-danger:hover, .fa-button-danger:focus-visible { background: var(--fa-text) !important; border-color: var(--fa-text) !important; color: #fff !important; }
.fa-button-danger:focus { background: var(--fa-danger) !important; border-color: var(--fa-danger) !important; outline: none; }
/* Plain nav/menu item (Back to Dashboard, Log Out, Edit, Copy Share Link) —
   deliberately not a boxy .fa-button: only one true call-to-action per
   screen (Download PDF, + New Assessment) should read as a filled button;
   everything else stays text so the toolbar reads as a menu, not a stack
   of same-weight pills. */
.fa-nav-link { display: inline-flex; align-items: center; gap: 4px; background: none !important; border: none !important; color: var(--fa-primary) !important; text-decoration: none; cursor: pointer; padding: 6px 2px; font-size: 14px; font-weight: 600; }
/* :focus-visible, not plain :focus — same "don't stay highlighted after a
   mouse click" reasoning as the button fixes elsewhere in this file. */
.fa-nav-link:hover, .fa-nav-link:focus-visible { text-decoration: underline !important; color: var(--fa-text) !important; }
.fa-nav-link.fa-copied { color: var(--fa-primary-dark) !important; text-decoration: underline; }
/* Deliberately filled + white text (not the plain-link style above) so a
   destructive action reads as visually distinct from View/Edit/PDF, and so
   it can't end up "invisible" again from a theme background collision the
   way the plain button did — background is forced here too, not just color. */
.fa-delete-chip {
	display: inline-block;
	background: var(--fa-danger) !important;
	color: #fff !important;
	border: none !important;
	border-radius: 6px;
	padding: 4px 12px;
	font-size: 14px;
	font-weight: 600;
	cursor: pointer;
}
.fa-delete-chip:hover, .fa-delete-chip:focus-visible { background: var(--fa-text) !important; }
.fa-delete-chip:focus { background: var(--fa-danger) !important; outline: none; }
/* Green-filled, same shape/sizing as .fa-delete-chip — the un-doing of a
   destructive action reads as the opposite color for the same "unmistakable
   at a glance" reason, on a trashed card that's already red-tinted (see
   .fa-card-deleted below). */
.fa-restore-chip {
	display: inline-block;
	background: var(--fa-primary) !important;
	color: #fff !important;
	border: none !important;
	border-radius: 6px;
	padding: 4px 12px;
	font-size: 14px;
	font-weight: 600;
	cursor: pointer;
}
.fa-restore-chip:hover, .fa-restore-chip:focus-visible { background: var(--fa-text) !important; }
.fa-restore-chip:focus { background: var(--fa-primary) !important; outline: none; }
/* Red-filled + white × — same "force it, don't just set it" reasoning as
   .fa-delete-chip above: anything that removes/deletes something reads as
   red so it's unmistakable at a glance, and !important stops the
   surrounding site theme's own button styling from bleeding through. */
.fa-remove-btn {
	flex: 0 0 auto;
	width: 40px; height: 40px;
	border-radius: 50%;
	border: none !important;
	background: var(--fa-danger) !important;
	color: #fff !important;
	font-size: 18px;
	line-height: 1;
	cursor: pointer;
}
.fa-remove-btn:hover, .fa-remove-btn:focus-visible { background: var(--fa-text) !important; }

/* Notices */
.fa-notice { padding: 12px 14px; border-radius: 6px; margin: 0 0 16px; }
.fa-notice-error { background: #fdecea; color: var(--fa-danger); }
/* Multiple form-validation problems at once (templates/form.php) render as
   this list instead of the single-line .fa-notice-error paragraph. */
ul.fa-notice-error { list-style-position: inside; }
ul.fa-notice-error li + li { margin-top: 4px; }
.fa-notice-success { background: #eaf6ec; color: var(--fa-primary-dark); }
/* "Try the New SAPPI" page (includes/class-beta-welcome.php) — a short,
   narrow read for people coming over from the old tool. !important on the
   disabled button because .fa-button-primary's own background/color are
   !important too, so a plain :disabled rule wouldn't visibly dim it. */
.fa-beta-welcome { max-width: 560px; }
.fa-beta-welcome p { margin: 0 0 14px; }
.fa-beta-agree { display: flex; align-items: flex-start; gap: 10px; margin: 22px 0 18px; cursor: pointer; }
.fa-beta-agree input { margin-top: 4px; flex-shrink: 0; cursor: pointer; }
.fa-beta-welcome .fa-button:disabled { opacity: .5 !important; cursor: default; }
.fa-beta-welcome .fa-beta-hint { margin: 10px 0 0; font-size: 13px; color: #888; }
/* General-purpose amber notice — the registration page's own "pending
   approval" notice, the Users page's pending-count banner, and the
   product-search "there's more, keep typing" hint all use this. */
.fa-notice-warning { background: #fff6e0; color: #8a6100; font-size: 14px; line-height: 1.5; }
.fa-notice-warning a { color: #8a6100; font-weight: 600; text-decoration: underline; }
/* Site Announcement banner (templates/site-announcement.php, every
   logged-in/out SAPPI page except the PDF/public share link) — light
   red per Michael, 2026-08-12, same palette as .fa-notice-error/
   .fa-abandoned-notice elsewhere, not the amber .fa-notice-warning above
   (that stays reserved for the unrelated notices it already covers). */
/* Extra margin-bottom (on top of .fa-notice's own 16px) — per Michael,
   2026-08-17: this is the very first thing on every page, sitting directly
   above the "Logged in as" account line, and 16px alone read as too tight
   between them. */
.fa-notice-announcement { background: #fdecea; color: var(--fa-danger); font-size: 14px; line-height: 1.5; margin-bottom: 28px; }
.fa-notice-announcement a { color: var(--fa-danger); font-weight: 600; text-decoration: underline; }
.fa-saved-toast-wrap {
	position: fixed; inset: 0; z-index: 9999; display: flex; align-items: center; justify-content: center; pointer-events: none;
}
.fa-saved-toast {
	background: rgba(0, 0, 0, 0.82); color: #fff; padding: 18px 32px; border-radius: 10px;
	font-size: 18px; font-weight: 600; box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
	/* Literal value, not inherited — showToast() (app.js) appends this
	   straight to document.body, outside .fa-wrap/.fa-auth-wrap's own
	   scope where font-family is actually declared, so without this it
	   silently fell back to the surrounding theme's font (confirmed
	   2026-08-11) — same root cause already fixed once for the auth tab
	   bar's own out-of-scope placement. */
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
/* showNavigatingToast() (app.js) — the "Loading…" pill shown the instant a
   chart bar/breakdown row is clicked, while the page reloads to apply that
   filter. Same dark pill as .fa-saved-toast, just with a spinner alongside
   the text instead of standing alone. */
.fa-saved-toast-loading { display: flex; align-items: center; gap: 12px; }
.fa-saved-toast-spinner {
	width: 18px; height: 18px; flex: 0 0 auto; border-radius: 50%;
	border: 2.5px solid rgba(255, 255, 255, .35); border-top-color: #fff;
	animation: fa-toast-spin .7s linear infinite;
}
@keyframes fa-toast-spin { to { transform: rotate(360deg); } }
.fa-empty { color: #666; }
/* Reports list with zero results (templates/reports.php) — amber notice
   naming the date range/filters responsible, plus the way out of each. */
.fa-no-results p { margin: 0; }
.fa-no-results p + p { margin-top: 6px; }
.fa-no-results .fa-no-results-actions { display: flex; flex-wrap: wrap; gap: 18px; margin-top: 10px; }

/* Back to top — every SAPPI page (see app.js), lower-right per Michael,
   2026-08-12 (moved from an initial lower-left placement same day). Hidden
   (not just transparent) until scrolled, both so it's never in the way
   near the top of a page and so it can't be tabbed to or clicked while
   invisible. Literal colors, not var(--fa-primary) etc. — those are scoped
   to .fa-wrap/.fa-auth-wrap (see that rule's own comment), but app.js
   appends this button straight to <body>, outside that scope, same root
   cause already documented (and fixed the same way) for .fa-saved-toast's
   font-family above. Confirmed 2026-08-12 (Michael): the var()-based
   version rendered with no visible background at all. */
.fa-back-to-top {
	position: fixed; right: 20px; bottom: 20px; z-index: 9999;
	width: 44px; height: 44px; border-radius: 50%; border: none;
	background: #016325; color: #fff; cursor: pointer;
	display: flex; align-items: center; justify-content: center;
	box-shadow: 0 2px 10px rgba(0, 0, 0, 0.25);
	opacity: 0; visibility: hidden; transform: translateY(8px);
	transition: opacity .2s ease, transform .2s ease, visibility .2s;
}
.fa-back-to-top-visible { opacity: 1; visibility: visible; transform: translateY(0); }
.fa-back-to-top:hover, .fa-back-to-top:focus-visible { background: #014a1c; }

/* Fields */
.fa-field { display: flex; flex-direction: column; gap: 4px; margin-bottom: 14px; }
.fa-field span { font-weight: 600; font-size: 14px; }
.fa-field input[type="text"], .fa-field input[type="email"], .fa-field input[type="password"],
.fa-field input[type="date"], .fa-field input[type="url"], .fa-field textarea, .fa-field select {
	width: 100%;
	padding: 12px;
	border: 1px solid var(--fa-border);
	border-radius: 8px;
	font-size: 16px; /* 16px prevents iOS Safari zoom-on-focus */
	font-family: inherit;
	transition: border-color .15s ease, box-shadow .15s ease;
}
.fa-wrap input:focus, .fa-wrap textarea:focus, .fa-wrap select:focus,
.fa-auth-wrap input:focus {
	outline: none;
	border-color: var(--fa-primary);
	box-shadow: 0 0 0 3px rgba(1,99,37,.15);
}
.fa-field-checkbox { flex-direction: row; align-items: center; }
.fa-checkbox-list { display: flex; flex-direction: column; gap: 10px; padding: 12px; border: 1px solid var(--fa-border); border-radius: 8px; }
.fa-checkbox-option { display: flex; align-items: center; gap: 10px; font-size: 15px; cursor: pointer; }
.fa-checkbox-option input[type="checkbox"] { flex: 0 0 auto; width: 18px; height: 18px; accent-color: var(--fa-primary); cursor: pointer; }
.fa-checkbox-other-input {
	margin-left: 28px;
	padding: 10px;
	border: 1px solid var(--fa-border);
	border-radius: 6px;
	font-size: 16px; /* 16px prevents iOS Safari zoom-on-focus */
	font-family: inherit;
	width: calc(100% - 28px);
}
.fa-field-grid { display: grid; grid-template-columns: 1fr; gap: 8px 16px; margin-bottom: 8px; }
.fa-auth-form .fa-combo-input { width: 100%; padding: 12px; font-size: 16px; border-radius: 8px; color: inherit; }

/* Auth forms */
.fa-auth-wrap { max-width: 420px; padding-top: 24px; }
.fa-auth-logo { display: block; height: 50px; width: auto; margin: 0 auto 6px; }
.fa-auth-version { margin: 0 0 20px; text-align: center; font-size: 12px; color: #8a8f98; }
.fa-form-help { color: #666; font-size: 14px; margin-top: -8px; }
/* Login + Create Account start as two separately-rendered shortcodes
   stacked one after another — reads as an oddly tall, narrow page on a wide
   screen. app.js collapses them into tabs (only one .fa-auth-wrap visible
   at a time) when it finds both on the same page, inserting this nav bar
   as their new sibling; sized/centered to match .fa-auth-wrap's own
   max-width rather than spanning the surrounding theme content area. */
/* Literal values, not var(--fa-border)/inherited font-family — this nav
   sits OUTSIDE .fa-wrap/.fa-auth-wrap's own scope (see the comment below),
   so those custom properties are simply undefined here and font-family
   would otherwise inherit the surrounding theme's own font instead of
   SAPPI's (confirmed 2026-08-11: the tabs visibly used a different font
   than the rest of the app). Same "needs its own copy" fix already applied
   to the ::before/::after rule further down — kept in sync BY HAND with
   .fa-wrap/.fa-auth-wrap's own --fa-border/font-family values above. */
.fa-auth-tabs-nav { max-width: 420px; margin: 40px auto 0; display: flex; border-bottom: 2px solid #dfe1e1; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }
/* !important throughout, on every state (not just resting) — for the same
   reason .fa-button-primary needs it above: this renders inside the site's
   normal theme, whose own button/hover styling can otherwise win. Confirmed
   2026-07-28: the theme's default button look (dark green fill) only lost
   to a plain, un-!important color rule while :hover was active, then
   reverted the instant the tab lost hover/focus — forcing every state
   (rest, hover, focus) to the exact same look here removes that
   inconsistency instead of just patching the one state that showed it. */
.fa-auth-tab, .fa-auth-tab:hover, .fa-auth-tab:focus {
	flex: 1 1 50%; padding: 12px;
	background: none !important;
	border: none !important;
	border-bottom: 2px solid transparent !important;
	margin-bottom: -2px;
	font-family: inherit; font-size: 15px; font-weight: 600;
	color: #666 !important;
	cursor: pointer;
}
.fa-auth-tab.fa-auth-tab-active,
.fa-auth-tab.fa-auth-tab-active:hover,
.fa-auth-tab.fa-auth-tab-active:focus {
	color: #333 !important;
	/* Literal value, not var(--fa-primary) — same out-of-scope reason as
	   .fa-auth-tabs-nav's own border-color/font-family fix above. */
	border-bottom-color: #016325 !important;
}
/* This nav is inserted as a sibling of .fa-auth-wrap, not a descendant of
   it (see app.js) — outside the .fa-wrap::before/::after Font Awesome
   collision guard near the top of this file, so it needs its own copy
   rather than relying on that one. */
.fa-auth-tabs-nav::before, .fa-auth-tabs-nav::after,
.fa-auth-tabs-nav *::before, .fa-auth-tabs-nav *::after { content: none !important; display: none !important; }

/* Site header — account status its own row up top, right-aligned. Below
   that, the UltraTech logo (left) and customer logo (right, when the
   assessment has one) share one row, vertically centered against each
   other via align-items on that row rather than each sitting in its own
   differently-sized box — they're on opposite ends of the same row, not
   adjacent to each other, just level with each other. Shared across the
   three authenticated views (dashboard/form/report) via
   templates/site-header.php — never shown on the public share page or PDF,
   which have no logged-in user. Global navigation lives page-side, not
   here: see templates/dashboard.php (+ New Assessment) and
   templates/report.php (the My Assessments / Edit / Download PDF / Copy
   Share Link toolbar) — the only thing this header ever renders below the
   logo row is a plain "My Assessments" back-link, and only on the
   form/edit page. */
.fa-site-header { margin-bottom: 24px; }
/* Divider + real padding (not just a small margin) between the account/nav
   row and the logo row below it — per Michael, 2026-08-17: nav is page
   chrome, the logo row is this specific assessment's own identity, and the
   two sat close enough to read as one crowded block. The line marks that
   boundary explicitly; the padding above/below it is what actually gives
   both rows room to breathe. */
.fa-site-account { margin: 0 0 20px; padding-bottom: 16px; border-bottom: 1px solid var(--fa-border); font-size: 13px; color: #666; text-align: right; }
/* "Logged in as X." on its own line, the My Assessments/Reports/Users/
   Support/Log Out menu on the one below it — per Michael, 2026-08-12,
   split out of what used to be one wrapping line/paragraph. */
.fa-site-account-greeting { margin: 0 0 4px; }
.fa-site-version { color: #8a8f98; font-size: 0.85em; margin-left: 2px; }
.fa-site-account-menu { margin: 0; }
.fa-site-header-top { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 14px; margin-bottom: 14px; }
/* !important guards against theme rules like ".entry-content img { height:
   auto; }" — a class+element selector that outranks our own bare class
   selector on specificity alone, so a plain override here isn't enough on
   themes that ship that kind of generic content-image reset. */
.fa-site-logo-ultratech { display: block !important; height: 50px !important; width: 166px !important; max-width: 166px !important; }
.fa-site-logo-customer { display: block; max-height: 50px; width: auto; }
/* Form page only — the customer logo's one add/change/remove control, right
   where the logo itself ends up, instead of a separate upload field further
   down the page duplicating the same image. Edit/remove buttons are always
   visible (not hover-only) since a hover state doesn't exist on touch
   devices, which assessors may well be using in the field. */
.fa-site-logo-customer-slot { display: flex; align-items: center; }
.fa-site-logo-customer-editable { position: relative; display: inline-flex; }
.fa-site-logo-edit-btn, .fa-site-logo-remove-btn {
	position: absolute;
	width: 20px; height: 20px; border-radius: 50%;
	cursor: pointer;
	display: flex; align-items: center; justify-content: center; padding: 0;
}
.fa-site-logo-edit-btn.fa-site-logo-edit-btn { bottom: -7px; right: -7px; border: 1px solid var(--fa-primary) !important; background: var(--fa-primary) !important; color: #fff !important; }
.fa-site-logo-edit-btn.fa-site-logo-edit-btn:hover, .fa-site-logo-edit-btn.fa-site-logo-edit-btn:focus-visible { background: var(--fa-text) !important; border-color: var(--fa-text) !important; }
.fa-site-logo-edit-btn.fa-site-logo-edit-btn:focus { background: var(--fa-primary) !important; border-color: var(--fa-primary) !important; outline: none; }
.fa-site-logo-remove-btn { top: -7px; right: -7px; border: none !important; background: var(--fa-danger) !important; color: #fff !important; font-size: 13px; line-height: 1; }
.fa-site-logo-remove-btn:hover, .fa-site-logo-remove-btn:focus-visible { background: var(--fa-text) !important; }
/* Wraps the Add button + its own size hint — per Michael, 2026-08-14:
   people assumed the logo was resized by WIDTH (it's actually a fixed
   HEIGHT, see FA_Assessment::LOGO_MAX_HEIGHT), so a tall/narrow upload
   shrinks down to a sliver rather than looking reasonably sized. Only
   shown before a logo's picked — x-show="!customerLogo" on this
   wrapper now, moved off the button itself, so the hint disappears the
   instant one's uploaded rather than lingering as dead advice once
   it's moot.
   The hint is absolutely positioned, not stacked in normal flow —
   deliberately, so this wrap's own in-flow height stays exactly the
   button's height (matching .fa-site-logo-ultratech's fixed 50px)
   instead of growing to fit two lines. .fa-site-header-top centers
   every child on that shared 50px, so a taller in-flow wrap would push
   the button up off that row entirely; this way it stays put and the
   hint just hangs below it, out of the way. */
.fa-site-logo-add-wrap { position: relative; display: inline-block; }
.fa-site-logo-hint { position: absolute; top: 100%; left: 0; margin: 5px 0 0; max-width: 190px; font-size: 11px; line-height: 1.35; color: #666; }
.fa-site-logo-add-btn.fa-site-logo-add-btn {
	display: inline-flex; align-items: center; justify-content: center;
	height: 50px; padding: 0 14px;
	border: 1px solid var(--fa-primary) !important; border-radius: 8px;
	background: var(--fa-primary) !important; color: #fff !important; font-size: 13px; font-weight: 600; cursor: pointer;
}
.fa-site-logo-add-btn.fa-site-logo-add-btn:hover, .fa-site-logo-add-btn.fa-site-logo-add-btn:focus-visible { background: var(--fa-text) !important; border-color: var(--fa-text) !important; }
.fa-site-logo-add-btn.fa-site-logo-add-btn:focus { background: var(--fa-primary) !important; border-color: var(--fa-primary) !important; outline: none; }
.fa-site-logo-add-btn:disabled { opacity: .6; cursor: default; }
.fa-visually-hidden {
	position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
	overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
/* Report page's one action row: View/Edit/Share/Download PDF/Copy Share
   Link, which only exist in the context of this one specific assessment —
   "My Assessments" itself now lives in the persistent site-header menu
   instead of being duplicated here. Deliberately a single row rather than
   splitting anything into the shared site-header above it — two
   stacked rows of near-identical-looking plain-text links read as much
   busier than one. See templates/report.php. */
.fa-report-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 20px; margin-bottom: 20px; padding-bottom: 14px; border-bottom: 1px solid var(--fa-border); }
/* Pushes the View/Edit/Share/PDF/Products link group to the right —
   same set, same order, same right alignment as the card action rows on
   Dashboard/Reports (see .fa-card-links there). margin-left:auto rather
   than justify-content:space-between on the parent — this row is always
   just this one group now, but margin-left:auto still keeps it right-
   aligned regardless. */
.fa-card-links { margin-left: auto; }
/* The link matching whichever page you're already on — a plain, inert
   <span> rather than an <a> with no real destination, styled to look
   deliberately disabled instead of just another clickable action. */
.fa-card-link-current { color: #999; font-weight: 600; cursor: default; }

/* Reports page's activity chart — hand-rolled plain HTML/CSS bars rather
   than a charting library, matching this plugin's no-third-party-JS-
   dependency approach everywhere else (self-hosted Alpine, vendored
   Dompdf). See templates/reports.php and FA_Reports::stats(). */
.fa-stats { margin-bottom: 28px; padding: 18px 20px; background: #fff; border: 1px solid var(--fa-border); border-radius: 10px; }
.fa-stats-header { display: flex; align-items: center; gap: 10px; }
/* No font-size override — per Michael, 2026-08-12, "Activity" should read
   at the same size as "All Assessments" below it, so this just inherits
   the same plain h2 sizing .fa-section-header-row's own h2 gets (no
   override there either), rather than the smaller 15px this used to be
   set to back when it was still a subordinate h3 inside a bigger
   "Analytics" heading. */
.fa-stats-header h2 { margin: 0; }
/* Chart + Distributor/Rep Group/Top Users breakdown were two separate
   cards until merged into this one 2026-08-12 (Michael: "let's just
   combine the reports at the top of reports into one section") — this is
   the one visual seam left standing in for that old card boundary, so the
   breakdown grid doesn't run straight into the chart above it with
   nothing marking where one dataset ends and the other begins. Only
   rendered when both are actually present (see templates/reports.php) —
   the breakdown sits flush at the top of the body on its own otherwise. */
.fa-activity-section { margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--fa-border); }
/* Always visible now — per Michael, 2026-08-17, the collapse-to-hide
   toggle this card used to have (and the button that drove it) is gone
   entirely: the range tabs directly below double as a real filter for the
   assessment list, and hiding them behind a collapsed chart card made
   that connection genuinely confusing ("clicking a range tab to filter
   results shouldn't also expand a chart section"). Simplest fix was
   removing the option to hide any of it — chart, breakdown, and range
   tabs are now just always on screen together. */
.fa-stats-ranges { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; margin-bottom: 20px; }
.fa-stats-range { display: flex; flex-direction: column; align-items: center; gap: 1px; padding: 6px 14px; border-radius: 8px; border: 1px solid var(--fa-border); text-decoration: none; transition: border-color .15s ease, background-color .15s ease; }
.fa-stats-range:hover { border-color: var(--fa-primary); background: var(--fa-bg); }
.fa-stats-range-count { font-size: 17px; font-weight: 700; color: var(--fa-primary-dark); }
.fa-stats-range-label { font-size: 11px; color: #666; }
.fa-stats-range-active { border-color: var(--fa-primary); background: var(--fa-bg); }
/* "Custom" is a <button>, not a link like the other range tabs — reset the
   bits a button brings along so it lines up with them. */
button.fa-stats-range-custom { background: #fff; font: inherit; color: inherit; cursor: pointer; }
button.fa-stats-range-custom.fa-stats-range-active { background: var(--fa-bg); }
.fa-stats-range-custom .fa-stats-range-count { display: flex; align-items: center; height: 26px; }
/* The Start/End form the Custom button opens (templates/reports.php). The
   [hidden] rule is needed because display: flex here would otherwise win
   over the hidden attribute — same trap noted elsewhere in this file. */
.fa-custom-range { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; margin: -6px 0 20px; padding: 12px 14px; border: 1px solid var(--fa-border); border-radius: 8px; background: var(--fa-bg); }
.fa-custom-range[hidden] { display: none; }
.fa-custom-range label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; font-weight: 600; }
.fa-custom-range input[type="date"] { font: inherit; font-size: 14px; font-weight: 400; color: #444; border: 1px solid var(--fa-border); border-radius: 4px; padding: 5px 8px; background: #fff; }
.fa-custom-range input[type="date"].fa-invalid { border-color: var(--fa-danger); box-shadow: 0 0 0 1px var(--fa-danger); }
.fa-custom-range .fa-button { padding: 8px 16px; font-size: 14px; }
.fa-custom-range-error { flex: 1 1 100%; margin: 0; font-size: 13px; color: var(--fa-danger); }
/* padding-top reserves headroom for .fa-stats-bar-value, which sits 18px
   above its own bar via absolute positioning — without this, a bar at (or
   near) 100% height pushes its count number above the chart's own box
   entirely, colliding with the "Weekly/Monthly totals" caption sitting
   right above it. */
.fa-stats-chart { display: flex; align-items: flex-end; gap: 10px; height: 140px; padding-top: 22px; background-image: repeating-linear-gradient(to top, var(--fa-border) 0, var(--fa-border) 1px, transparent 1px, transparent 35px); background-position: bottom; }
.fa-stats-granularity { margin: 0 0 8px; font-size: 12px; color: #888; }
/* A <button>, not a plain <div>, so a bar is a real clickable/keyboard-
   focusable control (click a bar to filter the list below to that bucket's
   date range — see app.js) — background/border/padding/font all reset
   !important since browsers apply their own default button chrome
   otherwise, same reasoning as every other custom-styled button in this
   file. */
.fa-stats-bar-col { flex: 1 1 0; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; min-width: 0; background: none !important; border: none !important; padding: 0 !important; margin: 0; font: inherit; cursor: pointer; }
.fa-stats-bar { width: 100%; max-width: 48px; background: var(--fa-primary); border-radius: 4px 4px 0 0; min-height: 3px; position: relative; transition: background-color .15s ease; }
/* :focus-visible, not plain :focus — same "don't stay highlighted after a
   mouse click" reasoning as the button fixes elsewhere in this file. */
.fa-stats-bar-col:hover .fa-stats-bar, .fa-stats-bar-col:focus-visible .fa-stats-bar { background: var(--fa-text); }
.fa-stats-bar-col-active .fa-stats-bar { background: var(--fa-text); }
.fa-stats-bar-value { position: absolute; left: 0; right: 0; top: -18px; text-align: center; font-size: 12px; color: #666; }
.fa-stats-bar-label { margin-top: 6px; font-size: 11px; color: #666; text-align: center; }

/* Reports page's Distributor/Rep Group/Top Users breakdown (see
   templates/reports.php) — reuses .fa-stats/.fa-stats-header wholesale for
   the outer card/header (identical look to the Activity chart above it,
   both always visible now — see that rule's own comment), just its own
   body/grid/table styling below. */
/* align-items: stretch is grid's own default, but declared explicitly here
   since it's load-bearing for .fa-breakdown-panel's equal-height borders
   below — without it, three panels with very different row counts
   (Distributor: 46+, capped by .fa-breakdown-scroll; Rep Group: ~7; Top
   Users: 10) would each border-box just to their own content's height
   instead of all three matching the tallest one's. */
.fa-breakdown-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); align-items: stretch; gap: 24px; margin-top: 16px; }
/* Light border around each of the three panels — per Michael, 2026-08-17 —
   same border color/radius as the app's other boxed sections (see
   .fa-product-recs-box) so By Distributor/By Rep Group/Top Users each read
   as its own distinct card within the grid instead of just floating text. */
.fa-breakdown-panel { border: 1px solid var(--fa-border); border-radius: 8px; padding: 14px 16px; }
.fa-breakdown-panel h4 { margin: 0 0 8px; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--fa-primary-dark); }
/* Distributor panel only (46+ rows) gets its own scroll cap so it can't
   dominate the card even while expanded — Rep Group (~7 rows) and Top
   Users (10 rows, by definition) are already short enough not to need one. */
.fa-breakdown-scroll { max-height: 280px; overflow-y: auto; }
.fa-breakdown-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.fa-breakdown-table td { padding: 5px 4px; border-bottom: 1px solid var(--fa-border); }
.fa-breakdown-table tr:last-child td { border-bottom: none; }
.fa-breakdown-table td:last-child { text-align: right; font-weight: 700; color: var(--fa-text); white-space: nowrap; padding-left: 10px; }
/* Clickable rows (has a filter to jump to — see data-fa-breakdown-filter-key
   in reports.php/app.js) — same light-gray hover the Activity chart's own
   collapsed-card affordance uses, for a consistent "this does something"
   signal across the page. The synthetic "(No Rep Group)" row never gets
   this attribute (nothing to filter to), so it's left as plain, inert text. */
.fa-breakdown-table tr[data-fa-breakdown-filter-key] { cursor: pointer; }
.fa-breakdown-table tr[data-fa-breakdown-filter-key]:hover td { background: var(--fa-bg); }
.fa-breakdown-table tr[data-fa-breakdown-filter-key]:focus-visible td { background: var(--fa-bg); outline: 2px solid var(--fa-primary); outline-offset: -2px; }
/* Users page's "Recent Logins" box — same .fa-stats card as the Reports
   page's Activity card, but its own table (4 columns with a header row,
   vs. .fa-breakdown-table's plain 2-column label/count) and its own scroll
   cap (below) sized for ~5 data rows before scrolling, not
   .fa-breakdown-scroll's taller 280px — per Michael, 2026-08-17, this list
   can get long fast (every login, not just distinct values) and didn't
   need nearly that much vertical room by default. */
.fa-login-history-scroll { max-height: 188px; overflow-y: auto; margin-top: 16px; }
.fa-login-history-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.fa-login-history-table th { text-align: left; padding: 4px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: #888; border-bottom: 1px solid var(--fa-border); }
.fa-login-history-table td { padding: 6px 4px; border-bottom: 1px solid var(--fa-border); }
.fa-login-history-table tr:last-child td { border-bottom: none; }
.fa-login-history-table th:last-child, .fa-login-history-table th:nth-last-child(2), .fa-login-history-table td:last-child, .fa-login-history-table td:nth-last-child(2) { text-align: right; white-space: nowrap; }
/* Name column links to this same page, filtered to that person (see
   FA_Users::login_history()'s own 'user_url') — plain .fa-nav-link text,
   not styled any differently from a normal table cell, since a whole
   table of link-colored names would be visual noise this list doesn't need. */
.fa-login-history-table td:first-child a { color: inherit; text-decoration: none; }
.fa-login-history-table td:first-child a:hover { text-decoration: underline; }
/* Dashboard */
.fa-dashboard h2 { margin-bottom: 14px; }
.fa-dashboard-header-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.fa-dashboard-sort { display: flex; align-items: center; flex-wrap: nowrap; gap: 8px; font-size: 14px; color: #666; }
.fa-dashboard-sort label { flex: 0 0 auto; white-space: nowrap; font-weight: 700; }
/* A plain native <select> (not the searchable .fa-combo used everywhere
   else) is still the right call here — a fixed 6-option list doesn't need
   search-as-you-type — but it's restyled to be PIXEL-CONSISTENT with the
   rest of the app's dropdowns (border/radius/font/color/box-height all
   shared with .fa-combo-input, chevron shared with .fa-combo-chevron —
   see both below), since the two sit directly next to each other in
   Reports' filter row and a mismatch there was reported directly, per
   Michael, 2026-08-12: "I think you are simulating a dropdown for some
   of these but they should match style." Custom chevron in place of the
   browser's own via appearance:none + a background-image SVG, since a
   ::after pseudo-element would be suppressed by this file's global Font
   Awesome icon-collision guard near the top. */
.fa-dashboard-sort select {
	flex: 0 1 auto; width: auto; max-width: 200px; font-size: 14px; font-family: inherit; color: #666;
	border: 1px solid var(--fa-border); border-radius: 4px; padding: 5px 26px 5px 8px;
	appearance: none; -webkit-appearance: none;
	background-color: #fff;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23666' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 8px center;
}

/* Reports page's Assessor/Distributor filters + Export button — stacked and
   centered by default (mobile-safe: each filter's label sits above its own
   combobox rather than beside it, so a long label like "Distributor/Rep
   Group:" next to a fixed-width combobox never has to fit on one line on a
   narrow phone). Reflows to the familiar side-by-side row, still centered
   as a whole, once there's enough width — see the min-width:640px block
   below. */
/* margin-bottom needed here specifically because this row now sits on its
   own, after .fa-section-header-row rather than inside it (see
   templates/reports.php — the Sort by control moved up into the heading
   row alongside the "View Deleted" link) — .fa-section-header-row's own
   margin-bottom no longer runs after this row the way it used to.
   Shaded as one panel (background/border/radius, same idea as
   .fa-product-recs-box below) so the Assessor/Distributor filters visibly
   read as belonging to the Export button next to them — without this, nothing
   ties the three together as "this button exports THIS filtered view". */
.fa-report-filters-row { flex: 1 1 100%; flex-direction: column; align-items: center; gap: 16px; margin-bottom: 20px; background: var(--fa-bg); border: 1px solid var(--fa-border); border-radius: 10px; padding: 16px 20px; }
/* Two groups, not one flat list of siblings — per Michael, 2026-08-12:
   filters and Export CSV used to be flex siblings in one centered row, so
   whenever they didn't all fit on one line, Export CSV wrapped onto its
   own line and sat centered by itself, visibly disconnected from the
   filters above it. .fa-report-filters-actions is now always its own
   full-width row below the filters (see its own rule, just below) with
   Clear Filters and Export CSV spread to ITS left/right edges — a
   consistent, predictable spot regardless of how much room the filter
   dropdowns above happen to take up. */
/* Two explicit rows of two (.fa-report-filters-row-top: Assessor/Rep
   Group, -bottom: Distributor/End-User) — a real 2x2, not one single grid
   auto-placing everything, and not three-across either (tried both, per
   Michael, 2026-08-17: a single CSS Grid auto-placed all 5, and its 1fr
   tracks still respected each COLUMN's own min-content floor, inflating
   whichever column Rep Group or Company happened to land in; three-across
   fixed that but then left Rep Group's own <select> too squeezed to show
   its own value even after shortening its wording). Product moved OUT of
   this grid entirely, down into .fa-report-filters-actions below (see its
   own rule) — five filters just never fit two-per-row cleanly, so the
   fifth now shares a row with Clear Filters/Export instead, which have
   space to spare. Both rows stack as single columns on mobile (below);
   each becomes its own horizontal row from 640px up (see that breakpoint
   further down). */
.fa-report-filters-group { display: flex; flex-direction: column; gap: 12px; width: 100%; }
.fa-report-filters-row-top, .fa-report-filters-row-bottom { display: flex; flex-direction: column; gap: 12px; }
/* Always its own full-width row (flex: 1 1 100% — not just "however much
   space is left after the filters"). Two stacked rows (flex-direction:
   column) as of 2026-08-17, per Michael — Products Mentioned on its own
   line, Clear Filters/Export on the line below it, rather than all
   four controls (link, search box, checkbox, button) crammed onto one
   line together (tried first as a single row split by a divider — see git
   history — still read as too busy once that divider's own gap was
   tightened up). Products Mentioned gets room to breathe same as every
   filter above it; Clear Filters/Export keep spreading to their own
   row's left/right edges (see .fa-report-filters-actions-bottom below)
   same as before. */
.fa-report-filters-actions { display: flex; flex-direction: column; flex: 1 1 100%; gap: 14px; }
/* Exactly two children always (Clear Filters — active link or inert
   span, never absent — and Export/Empty Trash), so space-between never
   has to handle a lone child collapsing to one edge. */
.fa-report-filters-actions-bottom { display: flex; align-items: center; flex-wrap: wrap; justify-content: space-between; gap: 12px; }
.fa-report-filters-row .fa-dashboard-sort { flex-direction: column; align-items: center; gap: 4px; width: 100%; }
/* Fills its own row's share (see .fa-report-filters-row-top/-bottom above)
   rather than a fixed 170px — per Michael, 2026-08-17: at 170px, the
   longer option text ("All Rep Groups/Companies", "All End-Users/
   Customers") clipped. */
.fa-report-filters-row .fa-combo { display: block; width: 100%; }
.fa-report-filters-row .fa-combo-input { width: 100%; max-width: 100%; }
/* Rep Group or Company (a plain <select>, unlike its Assessor/Distributor/
   End-User neighbors — see .fa-dashboard-sort select's own comment) needs
   its own explicit width to match theirs here specifically, since its
   default auto/200px sizing elsewhere doesn't line up against the others. */
.fa-report-filters-row .fa-dashboard-sort select { width: 100%; max-width: 100%; }
/* End-User/Customer only (see templates/reports.php) — no chevron there, so
   the right padding .fa-combo-input normally reserves for one would just be
   dead space; this reclaims it instead of leaving typed text looking
   off-center in a wider box. */
.fa-report-filters-row .fa-combo-nochevron .fa-combo-input { padding-right: 8px; }
/* Product filter's "Expand Part Numbers" checkbox (see templates/
   reports.php) — overrides .fa-dashboard-sort label's own bold/nowrap
   (meant for the Assessor/Distributor-style FIELD labels, not a secondary
   checkbox caption sitting after the search box) to read as a lighter,
   clearly optional refinement rather than another required field.
   flex-shrink: 0 keeps "Expand Part Numbers" from wrapping mid-phrase if
   the row gets tight. */
.fa-product-include-partno { display: flex; align-items: center; gap: 5px; flex: 0 0 auto; font-weight: 400; font-size: 13px; color: #666; cursor: pointer; white-space: nowrap; }
.fa-product-include-partno input { margin: 0; cursor: pointer; }
/* Search products… box — per Michael, needs room for longer product names.
   .fa-combo itself has no default width (see its own rule below, shared with
   every other combo on the page) so it just wraps its input tightly; flex: 1
   here is what makes it claim whatever room this row has left over from the
   fixed-width "Products Mentioned" label and "Expand Part Numbers" checkbox
   next to it, on every screen size (not just the desktop media query, since
   flex-direction: column's default align-items: stretch already gives this
   whole row the full filter box width on mobile too). */
.fa-report-filters-actions-product .fa-combo { flex: 1 1 auto; min-width: 0; }
.fa-report-filters-actions-product .fa-combo-input { width: 100%; }
/* Help icon + custom tooltip (see templates/reports.php) — a small round "?"
   badge, opens on hover or click/tap/Enter, closes on mouseleave, Escape, or
   a click anywhere else (Alpine's @click.outside). position: relative here
   is what .fa-help-tooltip's position: absolute anchors against. */
.fa-help-icon { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: 50%; background: var(--fa-text); color: #fff; font-size: 11px; font-weight: 700; line-height: 1; cursor: pointer; flex-shrink: 0; }
/* White + shadow so it reads as its own surface against .fa-report-filters-row's
   var(--fa-bg) light-gray background (see that rule above) rather than
   blending into it. Anchored above the badge by default; width is capped so
   the explanation wraps into a short block instead of one long line. */
.fa-help-tooltip { position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%); width: max-content; max-width: 220px; background: #fff; color: var(--fa-text); border: 1px solid var(--fa-border); border-radius: 6px; box-shadow: var(--fa-shadow); padding: 8px 10px; font-size: 12px; font-weight: 400; line-height: 1.4; white-space: normal; text-align: left; z-index: 20; cursor: auto; }
/* Own link style, not .fa-button — a plain text link reads as "reset,"
   secondary to the filters/Export CSV around it, matching how "Clear" next
   to the Activity chart's own date-range banner already looks. */
.fa-report-clear-filters { font-size: 13px; }
/* Inert state — shown instead of removing the element outright when there's
   nothing to clear, so Export CSV never loses its right-aligned partner
   (see the "always rendered" comment in templates/reports.php for why). */
/* !important — .fa-nav-link itself sets color: var(--fa-primary) !important,
   which otherwise wins regardless of selector specificity. */
.fa-report-clear-filters-disabled { color: #9a9b9d !important; cursor: default; pointer-events: none; text-decoration: none; }
/* Export to CSV reads as a secondary, in-context action here (this whole
   row is a filter toolbar, not a page-level call to action the way "+ New
   Assessment" is on the Dashboard) — smaller than .fa-button's own sitewide
   default, scoped to just this row so nothing else changes size. */
.fa-report-filters-row .fa-button { padding: 8px 14px; font-size: 13px; }
.fa-card-list { display: flex; flex-direction: column; gap: 20px; }
.fa-product-recs-box { border: 1px solid var(--fa-border); border-radius: 8px; padding: 14px 16px; margin: 10px 0 20px; background: var(--fa-bg); }
.fa-product-recs-header { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 10px; }
.fa-product-recs-actions { display: flex; gap: 16px; }
/* display:block (not the table's own default display:table) is what makes
   overflow-y actually scroll here — the browser still lays out the
   thead/tbody/tr/td descendants as a normal table internally, this only
   changes how the outer <table> element itself participates in scrolling,
   a standard, widely-supported technique for a scrollable table body. */
.fa-product-recs-list { width: 100%; max-height: 320px; overflow-y: auto; display: block; border-collapse: collapse; font-size: 14px; }
.fa-product-recs-list th { text-align: left; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: #777; padding: 4px 8px 6px; border-bottom: 1px solid var(--fa-border); }
.fa-product-recs-list td { padding: 5px 8px; border-bottom: 1px solid var(--fa-border); line-height: 1.3; }
.fa-product-recs-list tbody tr:last-child td { border-bottom: none; }
.fa-product-recs-list th:last-child, .fa-product-recs-list td:last-child { text-align: right; }
.fa-card {
	border: 1px solid var(--fa-border);
	border-radius: 10px;
	padding: 16px;
	background: #fff;
	box-shadow: var(--fa-shadow);
	display: flex;
	flex-direction: column;
	gap: 10px;
	transition: box-shadow .15s ease;
}
.fa-card:hover { box-shadow: 0 4px 10px rgba(65,64,66,.12); }
/* Reports page's admin-only Deleted view (see FA_Reports::render() and
   templates/reports.php) — same pale-red as .fa-notice-error, just a tint
   rather than a border/badge, so a whole list of trashed cards reads as
   "these are all in the trash" at a glance without competing with the
   Restore button (still the only saturated red-adjacent color on the card). */
.fa-card-deleted { background: #fdecea; border-color: #f3c8c4; }
/* Delete/Restore fade-and-collapse (see removeCardAnimated() in app.js) —
   two stages: first a quick fade + color tint (red for delete, green for
   restore) with the card still taking up its normal space, then a second
   transition collapses its height/margin/padding to 0 so the gap closes
   smoothly instead of the list just snapping shut once the card's actually
   removed from the DOM. */
.fa-card-removing { transition: opacity .3s ease, background-color .3s ease; opacity: 0; pointer-events: none; }
.fa-card-removing-delete { background: #fbdedb !important; }
.fa-card-removing-restore { background: #d9ecdd !important; }
.fa-card-collapsing { transition: max-height .25s ease, margin .25s ease, padding .25s ease, border-width .25s ease; max-height: 0 !important; margin: 0 !important; padding: 0 !important; border-width: 0 !important; }
/* Always a column (actions on their own full-width row up top, right-
   aligned, then the fields list below) — a side-by-side row layout with
   actions in a narrow right column left a large empty gap next to/under
   the buttons whenever the fields table was taller than the action links,
   since the two columns don't share height. Stacking avoids that
   entirely, and putting actions first keeps them in a consistent spot
   regardless of how many field rows a given card ends up with. */
.fa-card-top { display: flex; flex-direction: column; gap: 10px; }
/* No separate title/heading — every field, including End-User/Customer and
   Facility/Location, is just another labeled row here, same label-left/
   value-right idea as the full report/PDF's meta table (.fa-report-meta
   below), just sized down for this denser, many-cards-on-screen context.
   The Assessor row is skipped entirely when the assessor IS the person
   viewing the page (redundant — you already know it's you); when shown,
   its value cell holds either plain text or the reassignment combobox
   depending on who's viewing, so there's no separate "Assigned to:" label
   needed alongside it. */
/* No explicit width — a <table> with none defaults to sizing around its
   own content (unlike a block-level div, which would stretch to fill the
   card). That naturally keeps short values from stretching out with dead
   space beside them, while still leaving long values room to run the
   full width of the card rather than being force-wrapped by an earlier
   fixed max-width this had. */
/* Every box-model property forced with !important — same reasoning as
   .fa-delete-chip/.fa-remove-btn elsewhere in this file: the surrounding
   site theme applies its own default spacing/line-height to bare <table>/
   <td> elements (a formal content table gets that treatment on this site
   normally), and without forcing it here that bled through as extra row
   height, padding, and line-height well beyond what's set below —
   visually showing up as a big gap under the last row. */
.fa-card-fields { border-collapse: collapse !important; margin: 0 !important; font-size: 14px; }
.fa-card-fields td { padding: 4px 0 !important; margin: 0 !important; border: none !important; line-height: 1.3 !important; vertical-align: top !important; }
/* padding-right needs !important too — otherwise the generic td rule right
   above (same !important tier) wins on specificity ties by declaration
   order, zeroing this back out and jamming the value right up against the
   label with no gap. */
.fa-card-fields td.fa-card-fields-label { font-weight: 700; color: #777; padding-right: 14px !important; white-space: nowrap; width: 1%; }
/* inline-block, not the div default of block — inside the fields table's
   value cell (stretched wide by the label column's width:1% trick), a
   block-level wrapper stretches to fill that whole cell, dragging the
   chevron (positioned relative to THIS element, not the input) far off to
   the right of the actual visible input box. Shrinking to fit the input's
   own width keeps the chevron anchored right where it visually belongs. */
.fa-combo { position: relative; display: inline-block; }
/* Padding matches .fa-dashboard-sort select's exactly (same box-height,
   same right-hand room for a chevron) — see that rule's own comment. */
.fa-combo-input { font-size: 14px; font-family: inherit; color: #666; border: 1px solid var(--fa-border); border-radius: 4px; padding: 5px 26px 5px 8px; width: 160px; }
/* A real element, not a ::before/::after pseudo-element — this app's global
   Font Awesome icon-collision guard (near the top of this file) suppresses
   generated content on every non-input/label element inside .fa-wrap, and
   <input> itself doesn't reliably render ::before/::after in most browsers
   regardless. Purely decorative (the input is what's actually clickable),
   so it's inert to clicks/typing.
   Renders the SAME chevron graphic as .fa-dashboard-sort select's own
   background-image (identical SVG/size/position) rather than the &#9662;
   text character this used to hold — font-size:0 collapses that character
   down to nothing so only the background-image shows, so a combo and a
   plain <select> sitting side by side (Reports' filter row) are visually
   indistinguishable apart from the search-as-you-type behavior itself. */
.fa-combo-chevron {
	position: absolute; top: 50%; right: 8px; transform: translateY(-50%);
	width: 12px; height: 8px; font-size: 0; pointer-events: none;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23666' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: center;
}
.fa-combo-list {
	position: absolute; z-index: 5; left: 0; top: 100%;
	margin: 2px 0 0; padding: 0; list-style: none; min-width: 180px;
	max-height: 220px; overflow-y: auto;
	background: #fff; border: 1px solid var(--fa-border); border-radius: 6px;
	box-shadow: 0 6px 16px rgba(0,0,0,.12); font-size: 13px;
}
.fa-combo-list li { padding: 6px 10px; cursor: pointer; }
.fa-combo-list li:hover { background: var(--fa-bg); }
/* Reports Product filter's unchecked rows (app.js renderResults()): gray
   " · all part numbers" after the name, saying what picking the row does. */
.fa-combo-suffix { color: #8a8b8d; font-size: 0.9em; }
.fa-combo-empty { color: #999; font-style: italic; cursor: default !important; }
.fa-combo-empty:hover { background: none !important; }
.fa-combo-truncated { color: #8a6100; background: #fff6e0; font-weight: 600; font-size: 12px; cursor: default !important; padding: 8px 10px; border-bottom: 1px solid #f0e0b0; }
.fa-combo-truncated:hover { background: #fff6e0 !important; }
/* Distributor field's own suggestion combo (templates/form.php) — a full-
   width data-entry field, not a small filter control, so it needs its own
   override of .fa-combo's default inline-block/shrink-to-fit sizing (the
   inner input's own width:100% — already won via .fa-field input[type="text"]'s
   higher specificity — can't stretch a parent that's only as wide as its
   content to begin with). */
.fa-distributor-combo { display: block; width: 100%; }
.fa-distributor-combo .fa-combo-list { width: 100%; }
/* Heading on top, action links below — stacked by default (mobile-first;
   see the row layout in the min-width: 640px breakpoint further down) —
   per Michael, 2026-08-24's mobile audit: with these on one row relying
   on plain flex-wrap, whether a card's title+links actually fit on one
   line depended entirely on incidental title length (a short name like
   "Vector" stayed on one line, "Flowchem" — barely one character longer
   — wrapped, with a visually oversized gap before the dropped-down
   links). Stacking unconditionally on mobile makes every card look the
   same regardless of its own title length, instead of some wrapping and
   some not for no reason a user could see. End-User/Customer is the
   heading here (pulled out of .fa-card-fields below, not repeated). */
.fa-card-actions { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; margin-bottom: 4px; padding-bottom: 10px; border-bottom: 1px solid var(--fa-border); }
.fa-card-heading { font-weight: 700; font-size: 16px; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.fa-badge { display: inline-block; font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 20px; vertical-align: middle; }
/* Same warning color convention as .fa-notice-warning elsewhere in the
   app (e.g. the registration page's "pending approval" notice) — sits
   at the bottom of the card, full width, rather than as a chip up in
   the heading, so it doesn't compete with the End-User name for
   attention but is still clearly visible on the card as a whole. */
.fa-formidable-notice, .fa-abandoned-notice { margin: 10px -16px -16px; padding: 8px 16px; font-size: 12px; }
.fa-formidable-notice { background: #fff6e0; color: #8a6100; border-top: 1px solid #f0e0b0; }
/* Deliberately kept in the danger/red palette (same as the old chip
   version) rather than matching the yellow notice above it — this one
   means "nobody's actually assigned," a step more urgent than "please
   double-check this", so it stays visually distinct even though both
   are now bottom banners instead of chips. */
.fa-abandoned-notice { background: #fdecea; color: var(--fa-danger); border-top: 1px solid #f3c6c2; }
/* :last-of-type, not :last-child — these are the only two <p> elements
   ever placed directly in .fa-card (everything else in here is a div),
   so this cleanly rounds whichever ONE actually ends up last, whether
   that's the yellow notice alone, the red one alone, or the red one
   stacked directly under the yellow one. */
.fa-card > .fa-formidable-notice:last-of-type, .fa-card > .fa-abandoned-notice:last-of-type { border-radius: 0 0 8px 8px; }
/* Stacked flush against each other, no doubled gap/border, when both
   show on the same card. */
.fa-formidable-notice + .fa-abandoned-notice { margin-top: 0; }
/* Same red notice reused inline on the edit form's End-User field
   (templates/form.php) — overrides the card-bottom bleed/border-radius
   above with plain spacing on all sides instead, since this one sits
   inside a form field, not bled to a card's own edges. */
.fa-field-notice { margin: 8px 0; padding: 8px 12px; border-radius: 6px; border: 1px solid #f3c6c2; }
.fa-card-links { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; font-size: 14px; }
.fa-card-links a { color: var(--fa-primary) !important; text-decoration: none !important; font-weight: 600 !important; }
/* :focus-visible, not plain :focus — same "don't stay highlighted after a
   mouse click" reasoning as the button fixes elsewhere in this file. */
.fa-card-links a:hover, .fa-card-links a:focus-visible { text-decoration: underline !important; color: var(--fa-text) !important; }
.fa-share-btn { background: none !important; border: none !important; padding: 0 !important; margin: 0 !important; font: inherit; color: var(--fa-primary) !important; font-weight: 600; cursor: pointer; text-decoration: none; }
.fa-share-btn:hover, .fa-share-btn:focus-visible { text-decoration: underline !important; color: var(--fa-text) !important; }
.fa-share-btn.fa-copied { color: var(--fa-primary-dark) !important; text-decoration: underline; }
/* Small caret next to Share (Dashboard/Reports cards) opening a two-item
   menu (Copy Existing Link / Generate New Link) — click-triggered, not
   hover, so it works the same on the touch devices assessors are actually
   using in the field, not just desktop mouse users. Modeled on .fa-combo/
   .fa-combo-list's own look (position:relative wrapper + absolute panel)
   for visual consistency with the rest of the app's dropdowns. */
.fa-share-menu-wrap { position: relative; display: inline-flex; align-items: center; gap: 2px; }
.fa-share-menu-toggle {
	/* No right-side padding — this sits at the wrap's right edge, and
	   .fa-card-links' own 14px flex gap to the NEXT link (PDF) already
	   provides spacing there; padding on both sides made that gap read as
	   noticeably wider than the plain-14px gaps between every other pair
	   of links (View/Edit/PDF/Products/etc). */
	background: none !important; border: none !important; padding: 0 0 0 2px !important; margin: 0 !important;
	color: var(--fa-primary) !important; cursor: pointer; font-size: 12px; line-height: 1;
}
.fa-share-menu-toggle:hover, .fa-share-menu-toggle:focus-visible { color: var(--fa-text) !important; }
.fa-share-menu-list {
	position: absolute; z-index: 5; right: 0; top: 100%;
	margin: 4px 0 0; padding: 4px 0; list-style: none; min-width: 190px;
	background: #fff; border: 1px solid var(--fa-border); border-radius: 8px;
	box-shadow: 0 6px 16px rgba(0,0,0,.15); font-size: 13px;
}
.fa-share-menu-list button {
	display: block; width: 100%; text-align: left;
	background: none !important; border: none !important; padding: 8px 12px !important; margin: 0 !important;
	color: var(--fa-text) !important; font: inherit; font-weight: 600; cursor: pointer;
}
.fa-share-menu-list button:hover, .fa-share-menu-list button:focus-visible { background: var(--fa-bg) !important; }
.fa-share-menu-list [data-fa-share-regenerate] { color: var(--fa-danger) !important; }

/* Repeaters */
.fa-section { margin: 28px 0; padding-top: 20px; border-top: 1px solid var(--fa-border); }
.fa-section h3 { margin-bottom: 12px; }
.fa-repeater-row { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; padding: 10px; background: var(--fa-bg); border-radius: 6px; }
.fa-repeater-row input { padding: 10px; border: 1px solid var(--fa-border); border-radius: 6px; font-size: 16px; }
.fa-attendee-row { flex-direction: row; flex-wrap: wrap; align-items: center; }
.fa-attendee-row input { flex: 1 1 140px; }
/* Column-header labels shown once above the repeating attendee rows, on
   screens wide enough that the row below actually stays on one line (see
   the min-width:640px override two rules down) — hidden by default because
   an <input>'s default min-width:auto refuses to shrink as small as a
   <span>'s, so on a narrow screen the header and its row wrap at different
   points no matter how closely their flex-basis values are kept in sync
   (confirmed via screenshot, 2026-07-27: header wrapped Name+Title onto one
   line and Company onto the next, while the actual inputs below it each
   wrapped onto their own separate line). Each attendee input now carries
   its own placeholder instead, so the fields stay self-labeling below that
   width regardless of how they wrap. */
.fa-repeater-header { display: none; gap: 8px; padding: 0 10px; margin-bottom: 4px; }
.fa-repeater-header span { flex: 1 1 140px; font-weight: 600; font-size: 13px; color: #666; }
/* Matches the reorder-btns (30px) and remove-btn (40px) columns in the
   actual rows below, item-for-item — without these, the header only has 3
   flex-grow items to the row's 5, so flex-grow hands each header span more
   leftover space than its corresponding input gets, and the mismatch
   compounds column over column (Title and Company drift right). */
/* Higher specificity than ".fa-repeater-header span" (type+class) is
   required here, or that more general rule's flex:1 1 140px silently wins
   over this one's flex:0 0 ..., since both selectors otherwise match the
   same span and a single class alone doesn't out-rank a type+class rule. */
.fa-repeater-header span.fa-repeater-header-spacer { flex: 0 0 30px; }
.fa-repeater-header span.fa-repeater-header-spacer.fa-repeater-header-spacer-remove { flex-basis: 40px; }

.fa-area-block { border: 1px solid var(--fa-border); border-radius: 10px; padding: 16px; margin-bottom: 32px; background: var(--fa-bg); box-shadow: var(--fa-shadow); }
/* Sort by, on its own row directly above the list it sorts (Reports/
   Dashboard/Users — see each template's own comment on why) — per
   Michael, 2026-08-17: left-aligned (the default block flow already does
   that; no extra rule needed for it), with breathing room on both sides
   so it doesn't read as glued to whatever's directly above it, whether
   that's a filters box, a heading row, or nothing at all. */
.fa-list-sort-standalone { margin: 4px 0 16px; }
/* Row holding Sort by (left) and the admin-only View Deleted link (right) —
   templates/reports.php. Margin moves up to the row so Sort by can sit flush. */
.fa-list-toolbar { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px 16px; margin: 4px 0 16px; }
.fa-list-toolbar .fa-list-sort-standalone { margin: 0; }
a.fa-list-view-deleted { margin-left: auto; font-size: 14px; color: #666; }
a.fa-list-view-deleted:hover, a.fa-list-view-deleted:focus { color: var(--fa-primary); }
.fa-section-header-row { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 12px; }
.fa-section-header-row h2, .fa-section-header-row h3 { margin-bottom: 0; }
/* Wraps the Reports page's h2 + its "Back to All Assessments" link (Deleted
   view only — see templates/reports.php) so the two sit inline together
   without the link getting pushed onto its own baseline. */
.fa-section-header-heading { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.fa-section-header-count { font-size: 15px; font-weight: 400; color: #666; }
/* Reports page's "Filtered by ..." sentence, added 2026-08-17 per
   Michael — its own line right under the heading rather than folded into
   the giant bold h2 text (where it used to live, as one long run of
   heading text that was easy to miss entirely), so it reads as its own
   plain-English statement of what's currently narrowing the list. */
/* "Filtered by" chips (templates/reports.php) — one per active Reports
   search filter, each with an x link that removes just that filter. */
.fa-list-filtered-by { margin: 6px 0 0; font-size: 14px; color: #666; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.fa-filter-chip { display: inline-flex; align-items: center; gap: 6px; background: var(--fa-bg); border: 1px solid var(--fa-border); border-radius: 999px; padding: 3px 6px 3px 12px; color: var(--fa-text); line-height: 1.3; }
.fa-filter-chip-label { color: #666; }
.fa-filter-chip-x { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 50%; font-size: 17px; line-height: 1; color: #666; text-decoration: none; }
a.fa-filter-chip-x:hover, a.fa-filter-chip-x:focus { background: #e3e4e6; color: var(--fa-text); }
/* "Clear dates" beside the Reports list heading — the same chip as the filter
   chips above (one look for every removable thing on this page), the whole
   pill being the link. font-weight reset because it sits inside the bold h2. */
a.fa-clear-dates { color: var(--fa-text); vertical-align: middle; margin-left: 10px; padding-right: 6px; font-size: 14px; font-weight: 400; text-decoration: none; }
a.fa-clear-dates:hover, a.fa-clear-dates:focus { background: #e3e4e6; }
/* Product filter's "Exact Part Number Only" box once a product is applied —
   grayed out, state still readable. */
.fa-product-include-partno-locked { color: #9a9b9d; cursor: default; }
.fa-product-include-partno-locked input { cursor: default; }
/* margin-left: auto — per Michael, 2026-08-17: justify-content:
   space-between above only right-aligns Sort by/View Deleted while they
   fit on the SAME line as the heading; once the Reports page's heading
   grew long enough to force a wrap ("Showing Assessments for This Year
   (107 total)" and up, or the same plus "— filtered by ..."), the wrapped
   actions block had nothing left to space itself away from and fell back
   to sitting flush left — "sometimes floats left, other times doesn't,
   depending on heading size." An auto left margin keeps it pinned to the
   right edge either way, on its own line or sharing one with the heading,
   since auto margins in a flex row always claim any leftover space on
   their own side regardless of how the line wrapped. */
.fa-section-header-row .fa-dashboard-header-actions { margin-left: auto; }

/* Users page (templates/users.php) — reuses the same .fa-card-list/.fa-card
   markup Dashboard/Reports use, for the same "one card per record" reason
   and visual consistency, not a table. */
/* Every card starts LOCKED — data-fa-user-view spans shown, inputs/selects
   hidden — and only swaps to editable once the pencil button (top-right,
   .fa-users-edit-toggle) is clicked, adding .fa-users-card-editing to this
   specific card (see app.js). Scoped to that one card's own .fa-card-fields
   table, not globally, so editing one user's card never affects any other
   card already open on the same page. */
.fa-card .fa-users-edit-input { display: none; }
.fa-card.fa-users-card-editing .fa-users-edit-input { display: inline-block; }
.fa-card.fa-users-card-editing [data-fa-user-view] { display: none; }
/* Email → wp-admin's own Edit User screen, admin-only (see templates/
   users.php's own $can_act gate) — same color/hover convention as
   .fa-nav-link/.fa-card-links a elsewhere, just without their padding/
   bold weight, since this sits inline as a plain data value rather than
   a standalone action link. */
.fa-users-email-link { color: var(--fa-primary); text-decoration: none; }
.fa-users-email-link:hover, .fa-users-email-link:focus-visible { text-decoration: underline; color: var(--fa-text); }
.fa-users-edit-input { width: 100%; min-width: 100px; border: 1px solid var(--fa-border); background: #fff; padding: 4px 6px; border-radius: 4px; font: inherit; color: inherit; }
.fa-users-edit-input:focus { outline: none; border-color: var(--fa-primary); box-shadow: 0 0 0 3px rgba(1,99,37,.15); }
/* Role/Status here are the only other <select>s in the app besides
   .fa-dashboard-sort's — same custom chevron as those (and as
   .fa-combo-chevron) in place of the browser's own, so every dropdown-
   style control looks the same regardless of which page or which of the
   three underlying implementations (native select restyled, native select
   restyled+edit-input, or the JS-driven .fa-combo) renders it. */
select.fa-users-edit-input {
	appearance: none; -webkit-appearance: none;
	padding-right: 24px;
	background-color: #fff;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23666' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 8px center;
}
.fa-card-heading .fa-users-edit-input { font-size: 16px; font-weight: 700; padding: 4px 8px; }
/* Filled green/white icon/gray hover, same treatment as every other icon
   button in the app (e.g. .fa-area-collapse-btn) — doubled class
   (.fa-users-edit-toggle.fa-users-edit-toggle) since a plain button
   selector alone doesn't out-rank the site theme's own button styling. */
.fa-users-edit-toggle.fa-users-edit-toggle {
	display: inline-flex; align-items: center; justify-content: center;
	width: 26px; height: 26px; flex: 0 0 auto; padding: 0; margin: 0;
	border: none !important; border-radius: 50%;
	background: var(--fa-primary) !important; color: #fff !important; cursor: pointer;
}
.fa-users-edit-toggle.fa-users-edit-toggle:hover, .fa-users-edit-toggle.fa-users-edit-toggle:focus-visible { background: var(--fa-text) !important; }
.fa-users-edit-toggle.fa-users-edit-toggle:focus { background: var(--fa-primary) !important; outline: none; }

/* Prev/Next + "Page X of Y" for the Dashboard and Reports listings (see
   templates/pagination.php) — every click is a full navigation (add_query_arg
   preserves whatever sort/filter is already active), not client-side, so
   there's nothing for app.js to wire up here. */
.fa-pagination { display: flex; align-items: center; justify-content: center; gap: 16px; margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--fa-border); }
.fa-pagination-link { display: inline-flex; align-items: center; padding: 8px 16px; border: 1px solid var(--fa-primary) !important; border-radius: 6px; background: var(--fa-primary) !important; color: #fff !important; text-decoration: none; font-size: 14px; font-weight: 600; transition: background-color .15s ease, border-color .15s ease; }
/* :focus-visible, not plain :focus, for the same reason as .fa-button-primary
   above — but forced back explicitly on plain :focus too (see the doubled
   class + outline:none below), since a clicked link otherwise stays visually
   "stuck" gray once the mouse moves away, the same theme-CSS-bleed-through
   .fa-restore-chip/.fa-delete-chip already work around. */
.fa-pagination-link:hover, .fa-pagination-link:focus-visible { background: var(--fa-text) !important; border-color: var(--fa-text) !important; color: #fff !important; }
.fa-pagination-link.fa-pagination-link:focus { background: var(--fa-primary) !important; border-color: var(--fa-primary) !important; color: #fff !important; outline: none; }
.fa-pagination-link.fa-pagination-disabled { border-color: var(--fa-border) !important; background: #fff !important; color: #aaa !important; cursor: default; pointer-events: none; }
.fa-pagination-status { font-size: 14px; color: var(--fa-text); font-weight: 600; }
.fa-area-header { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 12px; }
.fa-area-name { flex: 1 1 220px; padding: 10px; border: 1px solid var(--fa-border); border-radius: 6px; font-size: 16px; font-weight: 600; }
/* Filled green with white icon, same as .fa-button-primary —
   class doubled up (.fa-area-collapse-btn.fa-area-collapse-btn) since plain
   !important at normal specificity was still losing to the theme's own
   button color, and the inner icon span gets its own explicit color rule
   for the same reason (the glyph's color, not the button's own box, was
   what was actually losing that fight). Hover/keyboard-focus turns the fill
   gray, same as every other primary-style button — icon stays white
   throughout, only the fill changes. */
.fa-area-collapse-btn.fa-area-collapse-btn,
.fa-area-collapse-btn.fa-area-collapse-btn span {
	color: #fff !important;
}
.fa-area-collapse-btn.fa-area-collapse-btn {
	flex: 0 0 auto;
	width: 36px; height: 36px;
	border: 1px solid var(--fa-primary) !important;
	background: var(--fa-primary) !important;
	border-radius: 6px;
	font-size: 20px;
	line-height: 1;
	cursor: pointer;
}
.fa-area-collapse-btn.fa-area-collapse-btn:hover,
.fa-area-collapse-btn.fa-area-collapse-btn:focus-visible {
	background: var(--fa-text) !important;
	border-color: var(--fa-text) !important;
}
.fa-area-summary { margin: -4px 0 12px; font-size: 13px; font-style: italic; color: #777; }

.fa-reorder-btns { display: flex; flex-direction: column; gap: 3px; flex: 0 0 auto; }
/* Filled green with a white glyph — sitewide button convention (2026-08-04:
   every arrow/button green-filled + white text, gray fill on hover; the
   only exceptions are Add Product/Add Area, which stay the outlined
   .fa-button-secondary style). Class doubled up for specificity: plain
   !important at normal specificity was still losing to the theme's own
   button color. */
.fa-reorder-btns.fa-reorder-btns button {
	width: 30px; height: 22px;
	border: 1px solid var(--fa-primary) !important;
	background: var(--fa-primary) !important;
	border-radius: 4px;
	font-size: 10px;
	line-height: 1;
	cursor: pointer;
	padding: 0;
	color: #fff !important;
}
.fa-reorder-btns button:disabled { opacity: .3; cursor: default; }
.fa-reorder-btns.fa-reorder-btns button:hover,
.fa-reorder-btns.fa-reorder-btns button:focus-visible {
	background: var(--fa-text) !important;
	border-color: var(--fa-text) !important;
	color: #fff !important;
}
/* Forces the resting fill back on plain :focus — without it, the site
   theme's own styling (which highlights :focus the same as :hover) stays
   visibly "stuck" gray after a click, since focus persists until something
   else is clicked. :focus-visible (keyboard nav only) keeps the gray hover
   look above instead, plus its own outline so keyboard focus stays
   indicated. */
.fa-area-collapse-btn.fa-area-collapse-btn:focus {
	background: var(--fa-primary) !important;
	border-color: var(--fa-primary) !important;
	outline: none;
}
.fa-area-collapse-btn.fa-area-collapse-btn:focus-visible {
	outline: 2px solid var(--fa-primary) !important;
	outline-offset: 1px;
}
.fa-reorder-btns.fa-reorder-btns button:focus { background: var(--fa-primary) !important; border-color: var(--fa-primary) !important; color: #fff !important; outline: none; }
.fa-reorder-btns.fa-reorder-btns button:focus-visible { outline: 2px solid var(--fa-primary) !important; outline-offset: 1px; }
.fa-product-row-actions { display: flex; align-items: center; justify-content: flex-end; gap: 12px; margin-top: 10px; }

/* Photos */
.fa-photo-list { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 8px; }
.fa-photo-thumb { position: relative; width: 84px; height: 84px; }
.fa-photo-thumb a { display: block; width: 100%; height: 100%; }
.fa-photo-thumb img { width: 100%; height: 100%; object-fit: cover; border-radius: 6px; border: 1px solid var(--fa-border); }
.fa-photo-remove-btn {
	position: absolute; top: -8px; right: -8px;
	width: 24px; height: 24px; border-radius: 50%;
	border: none !important; background: var(--fa-danger) !important; color: #fff !important;
	line-height: 1; cursor: pointer;
}
.fa-photo-remove-btn:hover, .fa-photo-remove-btn:focus-visible { background: var(--fa-text) !important; }
.fa-photo-reorder { position: absolute; left: 0; right: 0; bottom: 0; display: flex; }
/* Filled green with white text, same sitewide button treatment as
   everywhere else — this used to be a semi-transparent black overlay bar
   instead, which had fine contrast on its own but didn't match. Class
   doubled up for specificity, same reasoning as every other button fix in
   this file: plain !important at normal specificity has repeatedly lost to
   the theme's own button color here. */
.fa-photo-reorder.fa-photo-reorder button {
	flex: 1 1 0; border: none !important; background: var(--fa-primary) !important; color: #fff !important;
	font-size: 14px; line-height: 1; padding: 3px 0; cursor: pointer;
}
.fa-photo-reorder button:first-child { border-radius: 0 0 0 5px; }
.fa-photo-reorder button:last-child { border-radius: 0 0 5px 0; }
.fa-photo-reorder button:disabled { opacity: .3; cursor: default; }
.fa-photo-reorder.fa-photo-reorder button:hover,
.fa-photo-reorder.fa-photo-reorder button:focus-visible { background: var(--fa-text) !important; }
/* Same "force the resting background back on :focus" fix used elsewhere
   in this file (see .fa-pagination-link.fa-pagination-link:focus above)
   — :focus persists after a click and would otherwise stay visibly
   "stuck" on the theme's own hover-tinted fill; :focus-visible (keyboard
   nav only) keeps that hover look instead, plus its own outline so
   keyboard focus stays indicated. */
.fa-photo-reorder.fa-photo-reorder button:focus { background: var(--fa-primary) !important; outline: none; }
.fa-photo-reorder.fa-photo-reorder button:focus-visible { outline: 2px solid #fff !important; outline-offset: -2px; }
.fa-uploading { font-size: 13px; color: #666; }


/* Products */
.fa-products { margin-top: 16px; padding-top: 14px; border-top: 1px dashed var(--fa-border); }
.fa-product-row { border: 1px solid var(--fa-border); border-radius: 6px; padding: 12px; margin-bottom: 10px; background: #fff; }
.fa-product-search { position: relative; margin-bottom: 10px; }
.fa-product-search input { width: 100%; padding: 10px; border: 1px solid var(--fa-border); border-radius: 6px; font-size: 16px; }
.fa-product-results {
	position: absolute; z-index: 5; left: 0; right: 0; top: 100%;
	background: #fff; border: 1px solid var(--fa-border); border-radius: 0 0 6px 6px;
	max-height: 320px; overflow-y: auto; box-shadow: 0 6px 16px rgba(0,0,0,.12);
}
.fa-product-result { display: flex; gap: 10px; padding: 10px; cursor: pointer; border-bottom: 1px solid var(--fa-border); }
.fa-product-result:hover { background: var(--fa-bg); }
.fa-product-result img { width: 56px; height: 56px; object-fit: cover; border-radius: 4px; flex: none; }
.fa-product-result-thumb-placeholder {
	width: 56px; height: 56px; flex: none; display: flex; align-items: center; justify-content: center;
	font-size: 8px; text-align: center; color: #999; background: var(--fa-bg); border: 1px dashed var(--fa-border); border-radius: 4px;
}
.fa-product-result-name { font-weight: 600; font-size: 14px; }
.fa-product-result-part { font-size: 12px; color: var(--fa-primary-dark); font-weight: 600; }
.fa-product-result-desc { font-size: 12px; color: #666; }
/* Plain gray/italic, not the amber "heads up" treatment below — this is
   a neutral "nothing to show," not a warning, same tone as the
   Assessor/Distributor comboboxes' own .fa-combo-empty "No match" —
   per Michael, 2026-08-14: typing a search that matches nothing used
   to just leave the results box empty/invisible, with no indication
   whether it was still searching, broken, or genuinely no matches. */
.fa-product-results-empty { margin: 0; padding: 10px; font-size: 13px; font-style: italic; color: #999; }
/* Same amber as .fa-notice-warning elsewhere (the registration page's
   pending-approval notice, the Users page's pending-count banner) — per
   Michael, 2026-08-12, so a "there's more, keep typing" hint reads as the
   same kind of "heads up" as everywhere else in the app rather than a
   plain gray note. */
.fa-product-results-truncated { margin: 0; padding: 8px 10px; font-size: 12px; font-style: italic; color: #8a6100; background: #fff6e0; }
/* Same amber, explaining why a search matching only an already-picked part
   number shows an otherwise-empty results box instead of nothing at all. */
.fa-product-results-duplicate { margin: 0; padding: 8px 10px; font-size: 12px; font-style: italic; color: #8a6100; background: #fff6e0; }
.fa-product-thumb-link { display: block; }
.fa-product-thumb { width: 80px; height: 80px; object-fit: cover; border-radius: 6px; border: 1px solid var(--fa-border); }
.fa-product-thumb-placeholder {
	width: 80px; height: 80px;
	display: flex; align-items: center; justify-content: center; text-align: center;
	font-size: 9px; line-height: 1.2; color: #999; background: var(--fa-bg);
	border: 1px dashed var(--fa-border); padding: 4px;
}
/* Once a product is picked from search, its info just prints — no editable
   fields at all, since there's nothing left to fill in. Stacked (image on
   its own row, text below) by default: side-by-side on a narrow phone
   screen squeezes the text into a column so tight that a long product
   name/description/URL wraps across many lines, while the fixed-size image
   next to it stays short — leaving a tall blank gap under the image for as
   long as the text keeps wrapping past it (confirmed via screenshot,
   2026-07-27). Full width for the text removes that gap; see the
   min-width:640px override below for where there's enough room to go back
   to side-by-side without the same problem. */
.fa-product-picked { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: 10px; padding: 12px; background: #fff; border-radius: 8px; }
.fa-product-picked .fa-product-thumb-link, .fa-product-picked .fa-product-thumb-placeholder { flex: 0 0 auto; }
.fa-product-picked-text { flex: 1 1 auto; min-width: 0; }
.fa-product-picked-text strong { display: block; font-size: 15px; }
.fa-product-picked-text p { margin: 4px 0 0; color: #555; font-size: 14px; }
.fa-product-picked-text a { display: inline-block; margin-top: 4px; color: var(--fa-primary); font-size: 13px; word-break: break-all; }
.fa-product-picked-text a:hover, .fa-product-picked-text a:focus-visible { color: var(--fa-text) !important; text-decoration: underline; }
.fa-product-picked-text p.fa-part-required-warning { color: #b45309; font-weight: 600; }
.fa-product-qty-wrap { position: absolute; top: 10px; right: 10px; display: flex; flex-direction: column; align-items: center; gap: 3px; }
.fa-product-qty { display: flex; align-items: center; gap: 2px; background: #fff; border: 1px solid var(--fa-border); border-radius: 6px; padding: 2px; }
.fa-product-qty.fa-product-qty button { width: 24px; height: 24px; border: none !important; background: var(--fa-primary) !important; border-radius: 4px; font-size: 15px; line-height: 1; cursor: pointer; color: #fff !important; }
.fa-product-qty.fa-product-qty button:hover,
.fa-product-qty.fa-product-qty button:focus-visible { background: var(--fa-text) !important; }
.fa-product-qty.fa-product-qty button:focus { background: var(--fa-primary) !important; outline: none; }
.fa-product-qty-label { font-size: 11px; color: #777; }
.fa-product-qty input {
	width: 36px; text-align: center; border: none; background: none;
	font-size: 14px; padding: 4px 0; -moz-appearance: textfield;
}
.fa-product-qty input::-webkit-outer-spin-button, .fa-product-qty input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.fa-form-actions { position: sticky; bottom: 0; background: #fff; padding: 14px 0; border-top: 1px solid var(--fa-border); margin-top: 20px; }

/* Badges (wp-admin Users list) */
.fa-badge { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 12px; font-weight: 600; }
.fa-badge-approved { background: #eaf6ec; color: #044a1a; }
.fa-badge-pending { background: #fff6e0; color: #8a6100; }
.fa-badge-rejected { background: #fdecea; color: #b3261e; }

/* Report view */
.fa-report .fa-report-header { margin-bottom: 24px; }
/* Float-based (not flexbox) so this lays out identically in the Dompdf PDF
   render, which doesn't support flexbox or object-fit — the actual fixed
   size comes from explicit width/height attributes computed server-side in
   FA_Assessment::contain_fit(), not CSS, so it can't come out different
   between the on-screen view and the PDF. */
.fa-report-logos { margin-bottom: 18px; }
/* The float lives on the <a> wrapper, not the <img> itself — a floated
   element nested inside a plain inline anchor is what caused Dompdf's PDF
   renderer to collapse the anchor's box elsewhere in this app (see the
   product-photo note in report-content.php's doc comment); floating the
   anchor directly sidesteps that. */
.fa-report-logo-ultratech-link { float: left; }
.fa-report-logo-customer { float: right; }
.fa-report-logos-clear { clear: both; }
.fa-report .fa-report-title { font-size: 24px; font-weight: 700; text-align: center; margin-bottom: 18px; }
.fa-report-meta { border-collapse: collapse !important; margin: 0 auto 8px !important; }
.fa-report-meta td { padding: 3px 0 !important; margin: 0 !important; border: none !important; line-height: 1.3 !important; font-size: 15px; }
/* .fa-report-meta-label needs the td qualifier too, not just the class alone
   — otherwise .fa-report-meta td's own padding shorthand (equal specificity
   otherwise) wins and silently zeroes out padding-right, crushing the label
   right up against the value with no gap. */
.fa-report-meta td.fa-report-meta-label { font-weight: 700; color: #777; padding-right: 16px !important; white-space: nowrap; }
/* Icon-only mailto link (see report-content.php) — the address itself is
   still available as a tooltip/aria-label, but isn't printed inline
   anymore now that the icon is the click target. */
.fa-report-email-link { display: inline-flex; vertical-align: -3px; margin-left: 6px; color: var(--fa-primary); }
.fa-report-email-link:hover, .fa-report-email-link:focus-visible { color: var(--fa-text) !important; }
.fa-report .fa-report-head { font-size: 18px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--fa-primary-dark); margin: 20px 0 8px; padding-bottom: 4px; border-bottom: 2px solid var(--fa-primary); }
/* Area name gets its own larger heading, distinct from the Current
   State/Compliance/Recommendations/Products sub-headings within it — those
   keep .fa-report-head's size/color/uppercase but lose the underline below,
   so only the area title reads as the "main" heading of the block. */
.fa-report .fa-report-area-title { font-size: 22px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--fa-primary-dark); margin: 0 0 12px; padding-bottom: 6px; border-bottom: 2px solid var(--fa-primary); }
.fa-report .fa-report-area .fa-report-head { border-bottom: none; padding-bottom: 0; }
.fa-report .fa-report-area { margin-bottom: 36px; padding: 18px 20px; border-radius: 10px; border: 1px solid var(--fa-border); background: var(--fa-bg); }
.fa-report .fa-report-images { display: flex; flex-wrap: wrap; gap: 10px; margin: 10px 0; }
.fa-report .fa-report-images img { width: 140px; height: 140px; object-fit: cover; border-radius: 6px; border: 1px solid var(--fa-border); }
.fa-report-compliance-list { margin: 0; padding-left: 20px; }
.fa-report-compliance-list li { margin-bottom: 4px; }
.fa-report-no-products { color: #777; font-style: italic; }
.fa-report .fa-report-product { margin: 10px 0; padding: 12px; background: #fff; border: 1px solid var(--fa-border); border-radius: 6px; overflow: hidden; }
.fa-report-product-img, .fa-report-product-noimg { width: 110px; height: 110px; float: left; margin-right: 14px; }
.fa-report-product-img { object-fit: cover; border-radius: 6px; border: 1px solid var(--fa-border); }
.fa-report-product-noimg { display: flex; align-items: center; justify-content: center; text-align: center; font-size: 10px; color: #999; background: var(--fa-bg); border: 1px dashed var(--fa-border); border-radius: 6px; box-sizing: border-box; padding: 4px; }
.fa-report-product-text { overflow: hidden; }
.fa-report-product-clear { clear: both; }
/* Public share page only (a single, prominent "Download PDF" button) — the
   private report view folds Edit/Download PDF/Copy Share Link into its own
   .fa-report-toolbar instead (see templates/report.php). */
.fa-report-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-bottom: 24px; }
.fa-report-actions .fa-button { min-width: 190px; text-align: center; }
.fa-report-actions-center { justify-content: center; margin-top: 28px; margin-bottom: 0; padding-top: 20px; border-top: 1px solid var(--fa-border); }

/* Lightbox — click a report photo to view it full-size in an overlay
   instead of opening a new tab. Vanilla JS/CSS only, no dependency. */
.fa-lightbox { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.85); z-index: 9999; align-items: center; justify-content: center; padding: 30px; }
.fa-lightbox.fa-lightbox-open { display: flex; }
.fa-lightbox img { max-width: 100%; max-height: 100%; border-radius: 6px; box-shadow: 0 8px 30px rgba(0,0,0,.5); }
.fa-lightbox-close { position: absolute; top: 14px; right: 18px; background: none; border: none; color: #fff; font-size: 32px; line-height: 1; cursor: pointer; padding: 4px 10px; }

/* Larger screens */
@media (min-width: 640px) {
	.fa-wrap, .fa-auth-wrap { padding: 24px; }
	/* Restores the side-by-side heading/action-links row (see
	   .fa-card-actions' own base-rule comment) — there's enough width here
	   for title + links to comfortably share one line regardless of title
	   length, so the stacked mobile layout isn't needed. */
	.fa-card-actions { flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px; }
	.fa-field-grid { grid-template-columns: 1fr 1fr; }
	.fa-repeater-row.fa-attendee-row { flex-direction: row; }
	.fa-repeater-header { display: flex; }
	.fa-product-picked { flex-direction: row; gap: 14px; }
	.fa-product-picked-text { padding-right: 90px; }
	.fa-report-filters-row { flex-direction: row; flex-wrap: wrap; }
	.fa-report-filters-group { flex: 1 1 auto; }
	.fa-report-filters-row-top, .fa-report-filters-row-bottom { flex-direction: row; gap: 20px; }
	/* flex: 1 1 0 (not auto) + min-width: 0 is what actually makes every
	   item in a row equal width regardless of its own content — per
	   Michael, 2026-08-17. flex-basis: 0 means each item's PREFERRED size
	   ignores its own content entirely, splitting purely by the 1:1:1 (or
	   1:1) ratio; min-width: 0 is needed alongside it because a flex item's
	   own automatic minimum size still defaults to its content's min-content
	   width otherwise (browsers enforce that floor even with basis: 0),
	   which is exactly what broke the single-grid version this replaced —
	   "Rep Group or Company"'s own long label + <select> refused to shrink
	   below their combined min-content size, inflating the column they sat
	   in wider than the others. */
	.fa-report-filters-row .fa-dashboard-sort { flex: 1 1 0; min-width: 0; flex-direction: row; align-items: center; width: auto; }
	.fa-report-filters-row .fa-combo { flex: 1 1 auto; width: auto; min-width: 0; }
	.fa-report-filters-row .fa-dashboard-sort select { flex: 1 1 auto; width: auto; min-width: 0; }
	/* Overrides the flex: 1 1 0 above (needs the extra .fa-report-filters-
	   actions class to out-specificity it) — Product sits on its own row
	   now (see templates/reports.php + this file's own comment on
	   .fa-report-filters-actions) rather than sharing one with Clear All
	   Filters/Export, but still shouldn't stretch to the full row width the
	   way flex: 1 1 0 (a rule meant for the equal-width 2-up grids above)
	   would leave it. max-width (not flex-basis) is what actually caps it
	   here — .fa-report-filters-actions became flex-direction: column
	   2026-08-17, and flex-basis governs the MAIN axis (height, in a column
	   container), not the cross axis (width) the way it did back when this
	   row was flex-direction: row; a flex-basis-only version of this rule
	   was confirmed locally to squash the row to 440px tall instead of
	   440px wide. Widened three times now — 280px to 380px to fit the
	   "Include Part#" checkbox, to 440px once that became "Expand Part
	   Numbers", to 620px per Michael, 2026-09-17: longer product names were
	   still getting clipped in the search box itself once picked. */
	.fa-report-filters-actions .fa-report-filters-actions-product { flex: 0 0 auto; width: 100%; max-width: 620px; }
}

@media print {
	.fa-report-actions, .fa-site-header, [data-fa-delete], [data-fa-restore], [data-fa-delete-permanent], [data-fa-empty-trash] { display: none !important; }
}
