/* ============================================================
   PORTAL 2026 - m-Power portal screens (CUSTPORTAL.* + /mrcjava/docs)
   Loads AFTER page.min.css + style.css + mrc-2026.css in the shared
   m-Power template head (see marketing/portal-2026-rick-handoff.md).

   Scope: ONLY the page chrome around the app — hero band, breadcrumb
   bar, section headers. The m-Power app UI itself (tables, forms,
   mpowerapps.css) is deliberately untouched.

   Hero conversion mirrors blog-2026.css: the template's
   <header class="support-bg header text-white"> gets the 2026
   gradient instead of the photo; overlay pseudo-elements are
   disabled; H1 goes ink, weight 700 (2026 hero rule).
   ============================================================ */

/* ============================================================
   FONT PATH OVERRIDE - WORKAROUND, REMOVE WHEN /fonts/ IS MAPPED

   mrc-2026.css declares Inter Tight at /fonts/inter/. The m-Power dev
   host (:8011) serves /assets/ but has no alias for /fonts/, so every
   2026 font 404s there and the whole portal falls back to system type.
   Verified 7/30: /fonts/Roboto-Black.woff2 has been in place since June
   2024 and 404s too, so it's the path that's unmapped, not the files.

   Confirmed 7/30 that no alias is coming, so this is permanent rather
   than a stopgap. Steve copied the font files to /assets/fonts/, which
   does resolve on :8011.

   TWO sources per face, in this order, deliberately:
     1. /fonts/          canonical, and what production serves
     2. /assets/fonts/   the duplicate, which is what :8011 serves
   A browser walks the src list and moves to the next entry when one
   fails to load, so production keeps using the canonical copy and only
   the dev host pays for the fallback (two extra 404s, once, per font).

   Pointing straight at /assets/fonts/ instead would have been shorter
   but would make the portal depend on that duplicate existing on
   production too, where nothing else needs it. This way neither host
   has to match the other.

   These come after mrc-2026.css in the cascade, so the later @font-face
   wins. Descriptors are verbatim from mrc-2026.css lines 7-20; keep
   them in sync if that file changes.

   Inter Tight is the only family worth redirecting: body, headings,
   app titles, breadcrumbs and the navbar all resolve to it. Manrope and
   Open Sans appear on a few stray legacy elements and stay on fallback.
   ============================================================ */
@font-face {
	font-family: 'Inter Tight';
	src: url('/fonts/inter/InterTight-Latin-VariableFont_wght.woff2') format('woff2'),
	     url('/assets/fonts/inter/InterTight-Latin-VariableFont_wght.woff2') format('woff2');
	font-weight: 100 900;
	font-style: normal;
	font-display: swap;
}
@font-face {
	font-family: 'Inter Tight';
	src: url('/fonts/inter/InterTight-Latin-Italic-VariableFont_wght.woff2') format('woff2'),
	     url('/assets/fonts/inter/InterTight-Latin-Italic-VariableFont_wght.woff2') format('woff2');
	font-weight: 100 900;
	font-style: italic;
	font-display: swap;
}

/* ---- one FontAwesome, one URL (7/31 PM, Steve: "icons sometimes come
   across as garbled; a hard refresh fixes it") ----

   Garbled icons are the FA private-use codepoints rendering in a fallback
   font: the icon font failed to arrive for that pageview. Two causes stack
   on the portal: every app template declares FontAwesome TWICE (the
   /mrcjava vendor sheet and page.min.css point at different copies), and
   the head also preloads a third reference. Measured on M00430s: the same
   77,160-byte font downloaded 3x on one cold view. Whichever declaration
   wins the cascade decides which copy the page depends on; when that
   response arrives truncated and gets cached (the :8011 server sends no
   cache headers on fonts, so Chrome caches heuristically), the page keeps
   rendering tofu until a hard refresh bypasses the cache.

   This declaration loads last so it wins everywhere, making the choice
   deterministic: the /assets/fonts copy, at the EXACT URL the templates
   preload (?v= included — preload matching is exact), so the preloaded
   bytes are the bytes used and the other copies are never fetched.
   font-display: block keeps the garbled fallback off-screen while the font
   loads. It cannot resurrect a corrupt cached copy — if garbling recurs on
   production, check the font response's headers/size there, not this file. */
@font-face {
	font-family: 'FontAwesome';
	src: url('/assets/fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),
	     url('/assets/fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),
	     url('/assets/fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype');
	font-weight: normal;
	font-style: normal;
	font-display: block;
}

:root {
	--ink: #1a1a1c;
	--body: #5b6470;
	--muted: #8a929c;
	--line: #e8eaef;
	--accent: #006478;
	--accent-dk: #00485a;

	/* Page background behind the app, i.e. the band the white cards sit on.
	   This is the only place to change it; every page-level surface (app
	   band, sticky-footer spacer, banner band, login page) reads this token.

	   Tuned 7/30. Contrast against a white card, which is what decides
	   whether the card grids still read as cards:
	     #f4f5f8  1.090  --bg-soft from mrc-2026.css, the original
	     #f7f8fa  1.063  CURRENT, midway
	     #f8f9fb  1.053  a touch lighter again
	     #fafbfb  1.037  legacy portal value, too light: tried it and the
	                     tiles dissolved into the page, leaving only their
	                     1px border holding them together
	   If you push lighter than this, darken --line toward #dde1e8 at the same
	   time so the cards keep an edge. */
	--portal-page-bg: #f7f8fa;
}

/* ---- skip link ----
   The Login template's head uses RELATIVE css paths that resolve to
   /mrcjava/assets/css/, so the site's style.css never loads there and the
   skip link renders visible in the navbar. Copied verbatim from style.css
   (~line 1025) so the portal is self-sufficient. Harmless on the other
   screens, where style.css does load and these rules are identical. */
.skip-to-content-link {
	position: absolute;
	top: 0;
	left: 0;
	background-color: #006478;
	border: none;
	border-bottom: 2px solid white;
	font-weight: bold;
	color: #fff;
	padding: 8px 16px;
	font-size: 16px;
	text-decoration: none;
	z-index: 1000;
	transform: translateY(-100%);
	transition: transform 0.3s ease, opacity 0.3s ease;
	opacity: 0;
	width: 100%;
	text-align: center;
}
.skip-to-content-link:focus {
	transform: translateY(0);
	opacity: 1;
	color: white;
}
@media (prefers-reduced-motion: reduce) {
	.skip-to-content-link { transition: none; }
}

/* ---- hero band ----
   Matches the interior-page hero (.page-hero in mrc-2026.css): dotted grid
   + two soft corner washes over #e6edf1. Previously used the homepage-family
   teal gradient, which read as louder than the rest of the site. */
header.header.text-white,
header.support-bg.header {
	background-image:
		radial-gradient(circle, rgba(0,100,120,.09) 1px, transparent 1.5px),
		radial-gradient(900px 420px at 78% -10%, rgba(45,212,191,.16), transparent 60%),
		radial-gradient(700px 380px at 12% 0%, rgba(0,100,120,.08), transparent 55%) !important;
	background-size: 26px 26px, auto, auto !important;
	background-repeat: repeat, no-repeat, no-repeat !important;
	/* deeper than the original #e6edf1, which sat so close to white that the
	   band and the white navbar above it read as one pale slab */
	background-color: #dae5ea !important;
	border-bottom: 1px solid var(--line) !important;
	/* The /mrcjava/docs template loads mrc_default.css instead of portal.css.
	   That sheet collapses the hero's inner .container to height:0, and the
	   markup carries Bootstrap's .overflow-hidden utility — so the H1 spilled
	   out of the band and was clipped clean off (verified: forcing
	   overflow:visible took the hero 161px → 371px with the H1 back inside).
	   .overflow-hidden ships as `overflow:hidden!important`, hence the
	   !important here. The 2026 hero paints a flat gradient and disables the
	   theme's overlay pseudo-elements, so there is nothing left to clip.
	   No-op on the other portal screens. */
	overflow: visible !important;
	/* the theme's own .header rule ships 80px top / 30px bottom, which left
	   the H1 sitting ~20px below the band's centre. Needs !important to beat
	   it, and equal values so the heading is actually centred.
	   Halved from 3.5/6vw/5rem: with the logo mark retired below, the band was
	   spending ~160px of vertical space on a single line of text.
	   (7/31 PM: a duplicated comment tail here left two lines of prose outside
	   the comment, and the parser ate the padding-top below with them — the
	   hero was riding on the theme's 80px top padding. Rewrapped.) */
	padding-top: clamp(1.9rem, 3.2vw, 2.6rem) !important;
	padding-bottom: clamp(1.9rem, 3.2vw, 2.6rem) !important;
}
header.header.text-white > .container,
header.support-bg.header > .container { height: auto !important; }

/* the H1's own bottom margin would re-offset the centring */
header.header.text-white h1:last-child,
header.support-bg.header h1:last-child { margin-bottom: 0 !important; }

/* RETIRED 7/30: the m-Power mark above the hero heading.
   It was a logo4.png background on an H1 ::before, and it sat roughly 100px
   directly below the navbar's own mrc logo, so every portal screen showed two
   marks stacked in the same sightline. Killing it is also what let the hero
   padding come down (see above).
   Both the pseudo-element and the real <img> that /mrcjava/docs ships in its
   own hero are suppressed, so the two templates stay consistent. Restore by
   deleting this block and reinstating the background/size rules. */
header.header.text-white h1::before,
header.support-bg.header h1::before { content: none !important; }
header.header.text-white .container img[alt*="Logo" i],
header.support-bg.header .container img[alt*="Logo" i] {
	display: none !important;
	float: none;
}
/* the theme paints a teal overlay via pseudo-elements; disable so the
   gradient shows */
header.header[data-overlay-teal]::before,
header.header[data-overlay-teal]::after,
header.header.text-white::before,
header.header.text-white::after,
header.header.text-white > .overlay,
header.header.text-white [class*="overlay"] { display: none !important; content: none !important; }
header.header.text-white .container { position: relative; z-index: 2; }

header.header.text-white h1,
header.header.text-white .display-4 {
	color: var(--ink) !important;
	font-weight: 700 !important;
	letter-spacing: -0.035em;
	font-size: clamp(2rem, 4vw, 2.7rem);
}
header.header.text-white p,
header.header.text-white .lead-2 {
	color: #3d4750 !important;
}

/* ---- breadcrumb bar under the hero: quiet, hairline ---- */
nav[aria-label="breadcrumb"].bb-1 {
	background: #fff !important;
	border-bottom: 1px solid var(--line) !important;
}
nav[aria-label="breadcrumb"] .breadcrumb { background: transparent; font-size: .85rem; margin-bottom: 0; }
nav[aria-label="breadcrumb"] .breadcrumb-item,
nav[aria-label="breadcrumb"] .breadcrumb-item.active { color: var(--muted); }
nav[aria-label="breadcrumb"] .breadcrumb-item a { color: var(--muted); text-decoration: none; }
nav[aria-label="breadcrumb"] .breadcrumb-item a:hover { color: var(--accent); }

/* ---- "Welcome, <name>" signoff dropdown ----
   The template ships Bootstrap dropdown markup (.btn-group > a[data-toggle]
   + .dropdown-menu) but the page loads Bootstrap's CSS without its JS:
   verified on :8011 that jQuery 3.3.1 is present while jQuery.fn.dropdown
   and window.Popper are both undefined. Nothing ever adds .show, so the menu
   sat at display:none and the click looked dead. Not a regression from the
   2026 work; it has never had a handler.

   Doing it in CSS rather than adding the Bootstrap bundle: one rule here
   beats pulling a JS dependency into the portal, and it keeps the fix inside
   /Website/assets.

   Click-only, per Steve 7/30: :focus-within, no :hover. The toggle is an
   <a href="#">, so clicking focuses it and the menu opens; clicking anywhere
   else blurs it and the menu closes. Keyboard tabbing works the same way.
   An earlier version also opened on hover, which fired every time the pointer
   crossed the breadcrumb bar.

   GATED on :not([aria-expanded]), and that gate is essential. The two
   template families differ:
     menu / inquiry screens (I00001s)  no mpowerapps.js, no Bootstrap JS
                                       -> nothing toggles .show, fallback needed
     maintenance screens    (M01300s)  mpowerapps.js loads, Bootstrap present
                                       -> .show toggles natively, fallback harmful

   Ungated, this rule kept the menu visible on maintenance screens even after
   Bootstrap removed .show, and in that state .btn-group drops from block
   (231px) back to inline-flex (114px), so the menu visibly jumped sideways on
   every other click. That's the bug Steve reported 7/30.

   Neither template ships a real aria-expanded (both carry a typo'd
   `syaria-expanded`), and Bootstrap adds the real one the first time it
   toggles. So the attribute's presence is a reliable "Bootstrap is handling
   this" marker: absent forever on I00001s, set to true/false on M01300s from
   the first click. Verified both, 7/30. */
#portal-body .btn-group:focus-within > [data-toggle="dropdown"]:not([aria-expanded]) ~ .dropdown-menu {
	display: block;
}

/* ---- app section headers (the "FAQ Search" style title bars) ----
   Sits below the hero H1 in both size and weight so the page has one
   clear title. The app template renders these at the same 40px as the
   H1, which made them compete. */
.section-header h2, .section-header.portal-main-menu h2,
/* The maintenance screens don't use .section-header at all. They ship
   <div class="h2 app-title text-center"> instead, which was landing on
   Bootstrap's raw .h2 (33.75px, weight 500) while the inquiry screens got
   28px/600 from this block. Two different page titles depending on which
   app you opened. Audited 7/30: 9 screens use .app-title (I00255s, M00020s,
   M00270s, M00021s, I00014s, M00430s, M00242s, I00250s, I00016s), 16 use
   .section-header. Both routed here now.
   #portal-body to out-specify Bootstrap's .h2. */
#portal-body .app-title {
	color: var(--ink);
	letter-spacing: -0.02em;
	font-weight: 600;
	font-size: clamp(1.5rem, 2.4vw, 1.75rem);
}
/* ...but the rule above only reaches the container, and three screens wrap
   the title text in inline-styled elements that beat it (added 7/31, Steve):

     M00021s  <span style="color:#2980b9"><strong><span style="font-size:26px">
     M00500s  <span style="color:#006478; font-weight:bold;">
     M00504s  <span style="color:#006478; font-weight:bold;">

   So Submit Enhancement Request rendered blue at 26px while the other eight
   .app-title screens rendered ink at 28px/600 — Steve spotted it as "a
   different colour and doesn't look like the other headings."

   Handing the inline values back to the container makes all eleven identical.
   `strong` has to be in the selector even though it carries no style
   attribute: without it the <strong> keeps its own weight, the inner span
   inherits from that, and the title lands on 500 instead of 600. Verified
   against M00020s, which ships a bare `<div class="h2 app-title text-center">`
   with no wrappers at all: ink #1a1a1c / 28px / 600, matched exactly.

   NOTE this also drops the accent teal on the two sign-up screens, which is
   the intended trade — one heading treatment portal-wide beats a nicer colour
   on two screens. Revert by excluding [style*="#006478"] if that is wrong. */
#portal-body .app-title strong,
#portal-body .app-title [style*="color"],
#portal-body .app-title [style*="font-size"],
#portal-body .app-title [style*="font-weight"] {
	color: inherit !important;
	font-size: inherit !important;
	font-weight: inherit !important;
}
/* the app template leaves only 10px between the breadcrumb bar and the
   section title, which reads as cramped against the 2026 chrome.
   text-align/margin-bottom restate what style.css already supplies, at the
   same values, so this block survives if the legacy sheet is ever dropped. */
.section-header, .section-header.portal-main-menu,
#portal-body .app-title {
	margin-top: clamp(1.75rem, 3.5vw, 2.75rem) !important;
	margin-bottom: 30px;
	text-align: center;
}
/* ...except when the title sits INSIDE the form card. Training Evaluation
   (M00430s) is the only screen that puts .app-title inside form.form-layout
   (audited 7/31 PM, server-rendered roster of 37), so the clamp above stacked
   on the card's own 37px padding: 82px of dead space between the card edge
   and the heading (7/31 PM, Steve: "the box is too tall... closer to the
   heading"). Inside a card the card's padding IS the spacing. !important
   because the rule above carries it. */
#portal-body form.form-layout .app-title { margin-top: 0 !important; }
/* The Main Menu header was briefly hidden here (it repeats the breadcrumb's
   last crumb), but Steve wants it back 7/30: the tile grid needs a heading to
   sit under, and every other portal screen has one. Now that it's showing
   again, the app band doesn't need the full compensating top padding it got
   while the header was gone. See .section.bg-gray below. */

/* ============================================================
   APP CONTENT MODERNIZATION (added 7/20 per Steve: chrome alone
   left the app area looking legacy). Still CSS-only — no app
   markup or behavior touched. Scoped to the portal app wrappers
   (.load-content / .table-content / .section) so nothing leaks.
   ============================================================ */

/* ---- base text size for the app band (added 7/30) ----
   The m-Power template puts .lead-1 on the section wrapper, and .lead-1 is
   `font-size: 1.2rem !important` in style.css (page.min.css also declares it
   at 1.05469rem !important). So every app screen inherits a 19.2px base, and
   anything without an explicit size rule renders oversized: the "Uploaded On"
   line on Signed Documents, "Download" labels, and similar text across the
   card screens. Steve flagged it 7/30.

   Verified on the live page that the value was pure inheritance, no rule on
   the element itself, all the way up to this section. 6 of the 7 screens I
   sampled carry .lead-1, so this is a base reset rather than a per-card patch.

   Resetting the base rather than chasing individual elements also means the
   explicit sizes set further down (card titles, tile copy, buttons) still win
   where they exist. Needs !important to beat the two legacy declarations. */
#portal-body .section.lead-1 { font-size: 1rem !important; }

/* soft page background behind the app.

   Two selectors, because the sticky-footer spacer is a separate element:
   several screens end with <div class="bg-gray push"> (class order varies,
   "push bg-gray" on others) which carries .bg-gray WITHOUT .section. The
   original .section.bg-gray selector missed it, so it kept the legacy
   #fafbfb while the content band above became #f4f5f8, leaving a ~100px
   strip of not-quite-matching grey right above the footer. Steve spotted it
   7/30 on Account Overview.

   Keyed to .push and NOT to a blanket .bg-gray, which was the first attempt
   and was wrong: .bg-gray is also on the pagination buttons (page-item
   page-link bg-gray, on the ticket lists) and on layout wrappers inside the
   white form card on M00010s (bg-gray container, bg-gray col-12). A blanket
   !important would have tinted the pagination pills and dropped a grey band
   inside a white card.

   The section padding below stays keyed to .section so the spacer, which
   should be pure empty height, doesn't inherit it. */
#portal-body .section.bg-gray,
#portal-body .push { background: var(--portal-page-bg, #f4f5f8) !important; }
/* ...and give it room. The app band shipped with almost none, so the content
   sat ~44px below the breadcrumb and ~33px above the footer.

   Bottom is .sec from mrc-2026.css verbatim. The tile grid's own row margins
   eat ~20px of it, so the measured gap to the footer lands at ~92px at a
   1250px viewport rather than the full 112px the padding implies.

   Top is deliberately smaller. The section header carries its own margin-top,
   so a symmetric value stacked to ~125px of dead space before the heading. */
#portal-body .section.bg-gray {
	padding: clamp(1.5rem, 3vw, 2.25rem) 0 clamp(4rem, 9vw, 7.5rem) !important;
}
/* ...and the same room for the two screens that ship no .section at all
   (added 7/31, Steve: "needs padding at the bottom under the cards").

   Attendee List (I00200s) and Training Evaluation (M00430s) drop a bare
   .container straight into <body id="portal-body"> with no .section and no
   .push spacer, so the rule above never reached them and the last row of
   cards sat flush against the footer — measured gap 0px. That is the same
   template shortcut the 7/28 notes record for rows dropped into <body>.

   Audited across all 41 known screens: these two are the only ones with a
   .container as a direct child of #portal-body, and the only two with
   neither .section nor .push. Every other screen already gets its room from
   the section rule, so this cannot double up.

   Same clamp as above so the two shapes end up with matching bottom room;
   I00200s measured 0 -> 115px, against the ~92-112px the section screens
   land on. Padding only, no background: these screens are white by design
   and tinting them here would introduce a band the template never had.

   Top padding added 7/31 PM (Steve: "it's kinda butted up to the nav bar" —
   the M00430s card sat 9px under the breadcrumb). Same top clamp as the
   section rule above so the two no-section screens land on the section
   screens' rhythm: gap under the breadcrumb measured 9 -> 45px. Reaches
   I00200s as well, deliberately — it has the identical 0-gap fault. */
#portal-body > .container {
	padding-top: clamp(1.5rem, 3vw, 2.25rem);
	padding-bottom: clamp(4rem, 9vw, 7.5rem);
}
/* ---- footer sticks to the viewport bottom on short screens (7/31 PM) ----

   Found when Steve wired the 2026 footer include into R00200s (e-Learning
   Participants, previously the one screen with an EMPTY footer slot): its
   content is two small cards, so the footer ended mid-viewport with the
   body's grey background showing below it. The legacy template solved short
   pages with a .push spacer; R00200s ships none.

   style.css already makes the portal <body> a flex column (the same rule the
   7/28 notes say we must not lose), so margin-top:auto is the whole fix —
   the footer takes the slack on short pages and is a no-op wherever content
   already fills the viewport. Scoped to direct children of body so a footer
   nested inside the app markup (legacy shape on some screens) keeps its
   in-flow position. */
#portal-body > footer { margin-top: auto; }

/* result tables (FAQ, Enhancements, Updates lists) → card rows */
.table-content .table,
.table-content .table-bordered {
	border: none !important;
	background: transparent !important;
	border-collapse: separate !important;
	border-spacing: 0 0.85rem;
}
.table-content .table-bordered td {
	border: 1px solid var(--line) !important;
	border-radius: 16px;
	background: #fff !important;
	transition: box-shadow .2s ease, border-color .2s ease;
}
.table-content .table-striped tbody tr:nth-of-type(odd),
tbody.stripe tr:nth-of-type(odd) td {
	background: #fff !important;
}
.table-content .table-bordered td:hover {
	box-shadow: 0 14px 32px rgba(15,30,45,.08);
	border-color: #d8dde4 !important;
}

/* item titles: ink, semibold, teal on hover (they're lightbox links) */
.question a, .question a:visited {
	color: var(--ink) !important;
	font-weight: 600;
	font-size: 1.02rem;
	line-height: 1.4;
	text-decoration: none !important;
}
.question a:hover { color: var(--accent) !important; }
.smalltext, .smalltext span { color: var(--muted) !important; }

/* tag chips (bootstrap-tagmanager) → quiet teal pills */
.tm-tag {
	background: var(--accent-tint, #e7f2f4) !important;
	color: var(--accent-dk) !important;
	border: none !important;
	border-radius: 999px !important;
	box-shadow: none !important;
	text-shadow: none !important;
	padding: .28rem .75rem !important;
	font-size: .78rem !important;
	font-weight: 600;
}

/* form fields: rounded, hairline, teal focus */
.load-content .form-control,
.load-content input[type="text"],
.load-content input[type="search"],
.load-content select {
	border: 1px solid var(--line) !important;
	border-radius: 12px !important;
	background: #fff;
	padding: .55rem .9rem;
	height: auto;
	box-shadow: none !important;
}
.load-content .form-control:focus,
.load-content input[type="text"]:focus,
.load-content input[type="search"]:focus {
	border-color: var(--accent) !important;
	outline: none;
	box-shadow: 0 0 0 3px rgba(0,100,120,.12) !important;
}

/* buttons: primary actions go m-Power blue pill (2026 button rule) */
.load-content .btn-success,
.load-content .btn_search,
.load-content button[type="submit"].btn {
	background: #2046ae !important;
	border-color: transparent !important;
	color: #fff !important;
	border-radius: 999px !important;
	padding: .55rem 1.4rem;
	font-weight: 500;
	transition: transform .18s ease, box-shadow .18s ease;
}
.load-content .btn-success:hover,
.load-content .btn_search:hover {
	transform: translateY(-2px);
	box-shadow: 0 10px 24px rgba(32,70,174,.3);
}

/* pagination → pill numbers like the 2026 pager */
.pagination .page-link {
	border-radius: 999px !important;
	border: 1px solid var(--line) !important;
	color: var(--body) !important;
	margin: 0 .18rem;
	min-width: 40px;
	text-align: center;
	background: #fff !important;
}
.pagination .page-link:hover { color: var(--accent) !important; border-color: var(--accent) !important; }
.pagination .page-item.active .page-link,
.pagination .active > .page-link {
	background: var(--ink) !important;
	border-color: var(--ink) !important;
	color: #fff !important;
}
/* the app renders the pager as <li class="page-item page-link"><a>, so size
   the link text explicitly instead of letting it inherit body size.
   NOTE: the two screens generate slightly different markup — Enhancements
   emits `page-item page-link`, FAQ emits `page-link` with no `page-item`.
   Match on `li` so both are covered. */
.pagination .page-link,
.pagination li > a {
	font-size: .85rem !important;
	line-height: 1.55;
	font-weight: 500;
}
/* the prev/next arrows: the app leaves the <a> inline on a text baseline
   inside a block <li>, so the glyph landed ~5px above centre in a box that
   was 40x34 (an ellipse, not a circle). Make the li a fixed square flex box
   and centre the anchor inside it. */
.pagination li:not(.disabled) {
	width: 40px;
	height: 40px;
	padding: 0 !important;
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
}
.pagination li:not(.disabled) > a {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	line-height: 1;
}
.pagination li > a > i.fa {
	line-height: 1;
	font-size: 1rem;
}

/* "Page 1 of 12" is a status label, not a button: no pill, no fixed width */
.pagination li.disabled,
.pagination li.disabled.page-link {
	background: transparent !important;
	border-color: transparent !important;
	box-shadow: none !important;
	min-width: 0 !important;
	padding: .35rem .55rem !important;
	/* ADDED 7/31 (Steve): the label sat 3.4px above the arrows' centre. Same
	   cause as the arrow bug described above — the app leaves the <a> inline
	   on a text baseline inside a block <li> — but the flex fix was only ever
	   applied to li:not(.disabled), so the label never got it. Its <a> is
	   16px tall inside a 40px li, so baseline positioning put it high.
	   Measured after: label centre 483.8 vs arrows 484.0.
	   Applies to all 4 screens with a pager (I00009s, I00025s, I00270s,
	   I01000s), not just FAQ. */
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
}
.pagination li.disabled > a {
	font-size: .82rem !important;
	cursor: default;
	pointer-events: none;
}
/* ...and it needs to be readable, because it's information rather than a
   greyed-out control. It was on --muted, which is 2.96:1 against the page at
   13px, under the 4.5:1 AA threshold for normal text. --body is 5.64:1.
   Steve flagged it 7/30 as blending into the background.

   :not(.page-button) keeps any genuinely disabled arrow on --muted. The two
   are distinguishable in the markup: arrows are
   <a class="page-button" data-pagetype="btn_prev"> with an icon inside, the
   label is a bare <a> with text. Worth noting that .disabled only ever
   appears on the label in the screens I checked (I00009s, I00270s), so the
   app is using it to mean "not a button" rather than to mean disabled. The
   exclusion is insurance in case a screen does disable an arrow. */
.pagination li.disabled > a:not(.page-button) { color: var(--body) !important; }
.pagination li.disabled > a.page-button { color: var(--muted) !important; }

/* "12,231 Total Items" is a bare text node sitting next to the pager nav,
   with no element of its own, so it has to be sized from the parent column.
   :has() scopes it to the column that actually contains the pager. */
.table-content .col-6:has(nav .pagination),
.load-content .col-6:has(nav .pagination) {
	font-size: .85rem;
	color: var(--body);
}

/* the "x 974" counts after each tag chip are also bare text nodes in
   .related. Size the container; .tm-tag and the h6 carry their own sizes,
   and the tag-search input is reset back to form size below. */
.load-content .related { font-size: .82rem; color: var(--body); }
.load-content .related .form-control { font-size: .95rem; }

/* sidebar mini-headings ("Popular Tags") → 2026 widget label style */
.load-content h6.text-default {
	color: var(--accent-dk) !important;
	text-transform: uppercase;
	letter-spacing: .06em;
	font-size: .74rem;
	font-weight: 700 !important;
}

/* generic cards (Roadmap/Updates screens): rounded, hairline,
   titles in ink instead of the app's muted gray */
.load-content .card { border: 1px solid var(--line) !important; border-radius: 16px !important; }
.load-content .card h1, .load-content .card h2, .load-content .card h3,
.load-content .card h4, .load-content .card h5, .load-content .card .card-title,
.load-content h5, .load-content .h5 {
	color: var(--ink) !important;
	font-weight: 600 !important;
	letter-spacing: -0.01em;
}

/* alerts: soften */
.load-content .alert { border-radius: 12px !important; }

/* ============================================================
   INQUIRY / LIST SCREENS (CUSTPORTAL.I#####s: Open Tickets, Closed
   Tickets, My Licenses, Signed Documents, Third Party Software).
   These reuse the card and pagination pieces above; what's left is the
   toolbar above the list and the per-row action links.
   ============================================================ */

/* Card titles across every portal card that isn't a menu tile: the list
   screens, the report screens (e-Learning Participants) and the catalogue
   grids (Third Party Software) all ship .card-title at 22.4px/500/grey.
   The tile rule further down handles the <a>-wrapped menu cards. */
#portal-body .card .card-title {
	font-size: 1.05rem !important;
	font-weight: 600 !important;
	color: var(--ink) !important;
	letter-spacing: -0.01em;
	margin-bottom: .5rem;
}
#portal-body .load-content .card .card-body,
#portal-body .table-content .card .card-body { padding: 1.25rem 1.4rem; }

/* the "N Total Items" count sits as a bare text node beside the pager on
   these screens too, so it has to be sized from whichever column holds
   the pager (see the .table-content rule further up for the FAQ variant) */
#portal-body .load-content [class*="col-"]:has(> nav .pagination),
#portal-body [class*="col-"]:has(> nav > ul.pagination) {
	font-size: .85rem;
	color: var(--body);
}

/* toolbar buttons above the list ("Search Tickets", "Clear Selections") */
#portal-body .load-content .btn.btn-secondary,
#portal-body .open-selections-modal.btn {
	background: #fff !important;
	border: 1px solid var(--line) !important;
	color: var(--accent-dk) !important;
	border-radius: 999px !important;
	font-size: .85rem !important;
	font-weight: 600;
	text-transform: none !important;
	letter-spacing: normal !important;
	padding: .55rem 1.2rem !important;
	box-shadow: none !important;
	transition: border-color .15s ease, color .15s ease;
}
#portal-body .load-content .btn.btn-secondary:hover,
#portal-body .open-selections-modal.btn:hover {
	border-color: var(--accent) !important;
	color: var(--accent) !important;
}

/* per-row actions (View / Edit / Close). The app renders them as italic
   links with a coloured icon; make them read as quiet controls. */
#portal-body .load-content .card a._lookup,
#portal-body .table-content .card a._lookup {
	font-style: normal;
	font-size: .88rem;
	font-weight: 600;
	color: var(--accent-dk) !important;
	text-decoration: none !important;
	margin-right: 1.1rem;
	white-space: nowrap;
}
/* the label sits in an <em> inside the anchor, so the italic has to be
   cleared there rather than on the link */
#portal-body .card a._lookup em { font-style: normal; }
/* hover is a colour shift only. The underline was removed 7/31 (Steve): these
   are row controls sitting in a line next to each other, not prose links, and
   the rule above already forces text-decoration:none in the resting state, so
   underlining on hover made them behave unlike every other control on the
   page. The base rule's `none !important` covers the hover state too, which is
   why no explicit text-decoration is needed here — it also keeps Bootstrap's
   and page.min.css's `a:hover { text-decoration: underline }` out. */
#portal-body .load-content .card a._lookup:hover { color: var(--accent) !important; }
#portal-body .load-content .card a._lookup .fa,
#portal-body .load-content .card a._lookup + .fa { font-size: .9rem; }

/* ============================================================
   MAINTENANCE FORMS (the CUSTPORTAL.M#####s family: Hotline Request,
   Enhancement Request, Consulting Request, My Info, Request Training,
   Leave Feedback, Upload Documents, Reset Password, Payment).

   Hook is m-Power's own form class, so this can't leak into the
   inquiry screens or the navbar's search form. Field recipe is
   deliberately identical to the .demo-card kit in mrc-2026.css and the
   login screen above: #fbfcfd fill, #d6dbe3 hairline, 10px radius,
   teal focus ring. Change one, change all three.
   ============================================================ */

#portal-body form.form-layout,
#portal-body form.single-row-maintainer {
	background: #fff;
	/* m-Power writes style="border: 0px" onto the <form> element itself,
	   so this only lands with !important */
	border: 1px solid var(--line) !important;
	border-radius: var(--radius, 22px);
	box-shadow: 0 24px 60px rgba(20,45,80,.10);
	padding: clamp(1.6rem, 3vw, 2.4rem);
	margin-bottom: 2rem;
}
/* the app renders these forms edge-to-edge; give them a readable measure */
#portal-body .mrc-form-width { max-width: 860px; margin-left: auto; margin-right: auto; }

/* A Bootstrap .container nested inside that 860px cap has to go fluid.

   This one is our own doing. The max-width above is a 2026 addition (it isn't
   in style.css or page.min.css), and some maintainers nest a full .container
   inside the form: New License Information (M00255s) has
   form.form-layout > .container > .row.panels > .col-lg-6 x2.
   Bootstrap resolves that .container to a fixed 1170px at this breakpoint,
   so it sat 340px wider than the 830px form that contains it. The columns
   inherited the overflow (585px each, 1170px total) and the right-hand
   "New Details" panel hung right off the edge of the card. The browser was
   papering over it with a -418px right margin.

   Fixing the nested container rather than lifting the cap, because the cap is
   what keeps single-column forms readable on wide screens.
   Padding is deliberately left alone: the .row inside relies on the
   container's 15px to cancel its own -15px gutter margins. */
#portal-body .mrc-form-width .container {
	width: 100% !important;
	max-width: 100% !important;
	margin-left: auto !important;
	margin-right: auto !important;
}

/* ...and a maintainer that builds its own container wants the full page
   width, not the single-column reading measure.

   860px is right for a stack of fields, but M00255s puts two side-by-side
   panels inside it, and at 860 each column came out 376px, which left the
   panels smooshed together (Steve, 7/30). Widened to the page container's
   1300px; the parent caps it at 1170 in practice, so this reads as "as wide
   as the page allows" and lines the form up with the card grids on the other
   screens. Columns go 376px -> 531px.

   Gated on :has(.container) rather than on column count, deliberately.
   Audited all 12 maintenance screens: M00255s is the only one nesting a
   container. Several others do have multi-column fields (M00010s has 6
   col-lg-6 pairs, M00242s has 18) but those are field grids inside a
   single-column form, where 860px is still the right measure. Keying off
   column count would have wrongly widened them.
   Without :has() support this falls back to 860px, i.e. today's behaviour. */
#portal-body .mrc-form-width:has(.container) { max-width: 1300px; }

/* ...and the same reasoning for a screen that lays cards out in columns
   without nesting a container (added 7/31, Steve).

   Select UI style (I00014s) puts two .col-lg-6 cards side by side, each
   holding a UI screenshot. At the 860px cap each card came out 395px and the
   screenshots were unreadable. Cards go 395px -> 598px.

   Keyed on "a .row whose LG column holds a .card", not on column count, for
   exactly the reason the block above records: M00010s has 6 col-lg-6 field
   pairs and M00242s has 18, and both want to stay at the 860px reading
   measure. Verified live — neither matches this selector, both still 860px.
   col-lg specifically, not [class*="col-"]: M00430s stacks four cards in
   col-12 inside its form and must not widen either. Also verified. */
#portal-body .mrc-form-width:has(.row > [class*="col-lg-"] > .card) { max-width: 1300px; }

/* M00506s Change Portal Password (Steve, 8/2): m-Power stamps px-1 onto this
   one form (class="... px-1 changePswd"), and Bootstrap's .px-1 carries
   !important, so the card rule's horizontal padding collapsed to 4px — fields
   sat against the card edge. Re-assert the card padding with matching
   !important; #id + two classes outranks .px-1. Vertical padding was never
   affected (py utilities weren't stamped). */
#portal-body form.form-layout.changePswd {
	padding-left: clamp(1.6rem, 3vw, 2.4rem) !important;
	padding-right: clamp(1.6rem, 3vw, 2.4rem) !important;
}
/* Same screen: the three-line intro (.text-default, <br>-separated) sits
   under the centered .section-header but stayed left-aligned. Center it to
   read as one title block. :has() guard so no other screen's .text-default
   moves (the class is m-Power boilerplate, not unique to this screen). */
#portal-body #mrcMainContent:has(form.changePswd) .text-default {
	text-align: center;
}

/* Pre-existing app bug, not introduced here: several screens drop a
   Bootstrap .row straight into <body> with no .container to absorb it, so
   the row's -15px gutters bleed past the viewport and put a horizontal
   scrollbar on the page (measured 1455px against a 1425px viewport, with or
   without this stylesheet). Seen on the maintainer forms (.ajax_content.row)
   and the report screens (a .row inside .container-fluid.px-0, where px-0
   strips the very padding that would absorb the gutters). Zeroing the
   gutters costs nothing on either. */
#portal-body > .row,
#portal-body > .container-fluid.px-0 > .row {
	margin-left: 0 !important;
	margin-right: 0 !important;
}

/* labels */
#portal-body form.form-layout .col-form-label,
#portal-body form.form-layout label:not(.btn):not(.custom-file-label) {
	display: block;
	font-size: .88rem !important;
	/* the app sets font-weight:bold inline on some labels, so this needs
	   !important to keep every label at the house weight */
	font-weight: 600 !important;
	color: var(--ink);
	margin-bottom: .35rem;
	padding-bottom: 0;
}
/* a few labels are followed by an inline helper ("(You may add up to 5
   attachments)"). Blocking the label would push that onto its own line. */
/* !important because the sibling rule above carries an extra type
   selector and would otherwise win the specificity tie */
#portal-body form.form-layout .col-form-label:has(+ .d-inline) {
	display: inline-block !important;
	margin-bottom: 0;
}
#portal-body form.form-layout .d-inline {
	font-size: .85rem;
	color: var(--body);
}
/* the required marker: keep it findable, stop it shouting */
#portal-body form.form-layout .col-form-label span,
#portal-body form.form-layout .required { color: #c2333f; font-weight: 600; }

/* text fields, selects, textareas */
#portal-body form.form-layout .form-control,
#portal-body form.form-layout select,
#portal-body form.form-layout textarea {
	width: 100%;
	box-sizing: border-box;
	font-family: inherit;
	font-size: .95rem !important;
	color: var(--ink);
	background: #fbfcfd !important;
	border: 1px solid #d6dbe3 !important;
	border-radius: 10px !important;
	padding: .68rem .9rem !important;
	height: auto !important;
	box-shadow: none !important;
	transition: border-color .15s ease, box-shadow .15s ease;
}
#portal-body form.form-layout textarea { min-height: 8rem; line-height: 1.55; resize: vertical; }
#portal-body form.form-layout .form-control:focus,
#portal-body form.form-layout select:focus,
#portal-body form.form-layout textarea:focus {
	outline: none;
	border-color: var(--accent) !important;
	box-shadow: 0 0 0 3px rgba(0,100,120,.14) !important;
}
/* native select arrow → a chevron that matches the 2026 fields */
#portal-body form.form-layout select,
#portal-body form.form-layout select.mrcselect {
	appearance: none;
	-webkit-appearance: none;
	background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%235b6470' stroke-width='2'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E") !important;
	background-repeat: no-repeat !important;
	background-position: right .85rem center !important;
	background-size: 15px 15px !important;
	padding-right: 2.4rem !important;
}
#portal-body form.form-layout .form-row { margin-bottom: .25rem; }
#portal-body form.form-layout .form-group { margin-bottom: 1.15rem; }

/* ---- read-only facts become a metadata strip (added 7/31, Steve) ----

   Edit Ticket (M00030s) opens with Submitted By / Install Name / Opened On.
   The app renders each as its own full-width .form-row with a block-level
   label, so the value dropped to a second line and three short facts ate
   ~210px, in a heavy black label with a FontAwesome glyph and a colon.
   Nothing else in the 2026 system looks like that, and they read as inputs
   you can't type in rather than as record context.

   Now three tiles across, ~80px total, stacking to full width under 768px.

   The selector is the point: "a form row carrying a label but no control" is
   what actually makes a row read-only, and it survives the app renaming
   fields or reordering them. Do NOT swap it for :nth-child — the two rows
   above these (Ticket ID, Client ID) are present but display:none, so the
   indices are not what the rendered page suggests. Audited across all 40
   screens: 3 rows, all on M00030s.

   Two things CSS cannot reach here, both needing markup from Rick:
     - the value is a bare text node with no element, so it can only be
       styled through the .form-group
     - the colon is baked into the label text ("...&nbsp;Submitted By:"),
       which is why the uppercase label still ends in one
   The background sits on the inner .form-group rather than the .form-row so
   that the inline whitespace between the rows becomes the gutter between
   tiles; there is no wrapper element to hang a grid on. */
#portal-body form.form-layout .form-row:has(> .form-group > strong > label):not(:has(input)):not(:has(select)):not(:has(textarea)) {
	display: inline-flex !important;
	width: 33%;
	vertical-align: top;
	margin: 0 0 1.4rem !important;
}
#portal-body form.form-layout .form-row:has(> .form-group > strong > label):not(:has(input)):not(:has(select)):not(:has(textarea)) > .form-group {
	flex: 1;
	margin: 0 !important;
	padding: .8rem 1rem !important;
	background: var(--bg-soft, #f4f5f8);
	border-radius: 12px;
	font-size: .95rem;
	font-weight: 500;
	color: var(--ink);
}
#portal-body form.form-layout .form-row:has(> .form-group > strong > label):not(:has(input)):not(:has(select)):not(:has(textarea)) label.col-form-label {
	display: block !important;
	padding: 0 0 .2rem !important;
	margin: 0;
	font-size: .7rem !important;
	font-weight: 600 !important;
	letter-spacing: .05em;
	text-transform: uppercase;
	color: var(--body, #5b6470) !important;
}
/* the glyphs go: three unrelated icons in a row is the same clip-art problem
   the menu tiles had on 7/30. One of them ships wrapped in an inline
   <span style="color:#3498db">, hence the second selector. */
#portal-body form.form-layout .form-row:has(> .form-group > strong > label):not(:has(input)):not(:has(select)):not(:has(textarea)) label .fa,
#portal-body form.form-layout .form-row:has(> .form-group > strong > label):not(:has(input)):not(:has(select)):not(:has(textarea)) label span[style*="color"] {
	display: none !important;
}
@media (max-width: 767px) {
	#portal-body form.form-layout .form-row:has(> .form-group > strong > label):not(:has(input)):not(:has(select)):not(:has(textarea)) {
		display: block !important;
		width: 100%;
		margin: 0 0 .5rem !important;
	}
}

/* Priority-style radio groups: the app renders them as Bootstrap button
   toggles (<label class="btn"><input type=radio>). Turn the row into a
   2026 segmented control instead of the grey pill bar. */

/* ...and pull the group back to the content edge (added 7/31, Steve).
   .btn-group ships as inline-flex, and the app emits a newline plus four
   spaces between the field's <span class="mr-3"> label and the group. As an
   inline-level box the group therefore starts one collapsed space in, so the
   pills sat 12px right of every label, textarea and input on the form
   (268.9 vs 256.9, measured on M00030s). Going block-level flex takes it out
   of inline flow and the whitespace stops counting.

   !important per the .show trap: bootstrap-grid ships
   `.show { display: block !important }` as a responsive utility and
   Bootstrap's dropdown adds the same class to an open .btn-group, so any
   .btn-group relying on a flex row has to say so with !important.

   Scoped to a .btn-group that is a direct child of a .form-group inside
   form.form-layout — the segmented-radio shape. Audited across all 40
   screens: 5 groups on 4 screens (M00010s x2, M00020s, M00030s, M00500s),
   none of them a dropdown. The .btn-group shapes that must keep an inline
   flex row (M00242s, I00255s, and the filter-container date pickers) are all
   either outside form-layout or nested in an .input-group, so none match. */
#portal-body form.form-layout .form-group > .btn-group {
	display: flex !important;
	flex-wrap: wrap;
	justify-content: flex-start;
}
/* ...and pin the pills, or going block-level backfires. Bootstrap ships
   `.btn-group > .btn { flex: 1 1 auto }`. While the group was inline-flex it
   was content-sized so that never showed; block-level it is full width, and
   High / Medium / Low stretched to a third of the form each. */
#portal-body form.form-layout .form-group > .btn-group > .btn,
#portal-body form.form-layout .form-group > .btn-group > label.btn {
	flex: 0 0 auto;
}
/* ...and close the gap the same change opened up. The app emits a bare
   newline-plus-spaces text node between the field's <span class="mr-3"> label
   and the group. While the group was inline-flex that whitespace shared the
   group's line box; block-level it becomes an anonymous line box of its own,
   inheriting the 30.4px line-height, so Priority sat 36px below its label
   while every other field on the form sits ~5.6px below its own.

   line-height:0 on the wrapper collapses that stray box; the children get a
   real line-height back immediately. The label goes block so its own margin
   controls the spacing rather than the line box. Measured after: 6.4px on
   Priority against 5.6px on Description. */
#portal-body form.form-layout .form-group:has(> .btn-group) { line-height: 0; }
#portal-body form.form-layout .form-group:has(> .btn-group) > * { line-height: 1.55; }
#portal-body form.form-layout .form-group:has(> .btn-group) > span {
	display: block;
	margin: 0 0 .4rem !important;
}

#portal-body form.form-layout .btn-group label.btn,
#portal-body form.form-layout label.btn.btn-secondary {
	background: #fff !important;
	border: 1px solid #d6dbe3 !important;
	color: var(--body) !important;
	font-size: .85rem !important;
	font-weight: 600;
	text-transform: none !important;
	letter-spacing: normal !important;
	padding: .5rem 1.15rem !important;
	box-shadow: none !important;
	margin: 0 .4rem 0 0 !important;
	border-radius: 999px !important;
	transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
#portal-body form.form-layout .btn-group label.btn:hover {
	border-color: var(--accent) !important;
	color: var(--accent) !important;
}
#portal-body form.form-layout .btn-group label.btn.active,
#portal-body form.form-layout label.btn.btn-secondary.active {
	background: var(--accent) !important;
	border-color: var(--accent) !important;
	color: #fff !important;
}
#portal-body form.form-layout .btn-group label.btn input[type="radio"] {
	position: absolute;
	opacity: 0;
	pointer-events: none;
}
/* keyboard users still need to see which segment is focused */
#portal-body form.form-layout .btn-group label.btn:focus-within {
	outline: 3px solid rgba(0,100,120,.35);
	outline-offset: 2px;
}

/* file inputs (Bootstrap custom-file: input + label, "Browse" is the
   label's ::after) */
#portal-body form.form-layout .custom-file { margin-bottom: .6rem; }
#portal-body form.form-layout .custom-file-label {
	font-size: .95rem !important;
	font-weight: 400 !important;
	color: var(--muted);
	background: #fbfcfd;
	border: 1px solid #d6dbe3;
	border-radius: 10px;
	padding: .68rem .9rem;
	height: auto;
	margin-bottom: 0;
}
#portal-body form.form-layout .custom-file-label::after {
	background: var(--accent-tint, #e7f2f4);
	color: var(--accent-dk);
	font-weight: 600;
	border: 0;
	border-radius: 0 9px 9px 0;
	padding: .68rem 1.1rem;
	height: auto;
}
#portal-body form.form-layout .custom-file-input:focus ~ .custom-file-label {
	border-color: var(--accent);
	box-shadow: 0 0 0 3px rgba(0,100,120,.14);
}

/* form actions */
/* Sized to .btn-pill in mrc-2026.css, the site's base button.

   This block previously set padding but no font-size at all, so form buttons
   inherited the legacy theme and rendered at 11px against the site's 16px.
   Steve caught it 7/30 on the Accept button.

   .btn-pill BASE, not .btn-pill + .btn-lg. btn-lg is the hero-CTA variant
   (1.05rem / 1rem 2rem) and matching it took the button from 45px to 66px,
   which is too heavy for a form submit. The base lands 16px type at 46px,
   i.e. the original height.

   line-height:1 is the load-bearing part and is easy to miss: it's what
   .btn-pill sets, and without it the legacy 31.92px line-height is what
   actually inflates the button, not the padding. */
#portal-body form.form-layout .btn:not(.btn-group .btn):not(label) {
	border-radius: 999px !important;
	font-size: 1rem !important;
	font-weight: 500;
	line-height: 1 !important;
	text-transform: none !important;
	letter-spacing: normal !important;
	padding: .85rem 1.7rem !important;
	box-shadow: none !important;
	/* inline-flex + gap is how .btn-pill spaces its icon, and it also
	   normalises the markup, which is inconsistent between buttons:
	     Back:   <i class="fa fa-arrow-left"></i>Back      (no space at all)
	     Accept: <i class="fa fa-check"></i> Accept        (one space)
	   As flex items that stray space collapses, so both get the same gap
	   instead of one button's glyph sitting flush against its label.
	   Verified this doesn't change button widths. */
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	gap: .5rem;
	transition: background-color .18s ease, transform .18s ease;
}
#portal-body form.form-layout .btn-primary,
#portal-body form.form-layout button[type="submit"] {
	background: var(--btn-ink, #2046ae) !important;
	border-color: transparent !important;
	color: #fff !important;
}
#portal-body form.form-layout .btn-primary:hover,
#portal-body form.form-layout button[type="submit"]:hover {
	background: #183a94 !important;
	transform: translateY(-1px);
}
#portal-body form.form-layout .btn-secondary:not(label),
#portal-body form.form-layout .btn-light:not(label) {
	background: #fff !important;
	border: 1px solid var(--line) !important;
	color: var(--accent-dk) !important;
}
#portal-body form.form-layout .btn-secondary:not(label):hover {
	border-color: var(--accent) !important;
	color: var(--accent) !important;
}

/* ---- date fields and any other .input-group (added 7/30, Steve spotted the
   stray border) ----

   Two faults stacked on every date field, e.g. "Approximate Date Started" on
   My Contact Information:

   1. page.min.css puts `border: 1px solid #eaeff4` on .input-group, so the
      wrapper drew its own box around an input that already carries the 2026
      field border. Two borders, 1px apart.
   2. The group is display:flex / flex-wrap:wrap and the input resolves to the
      full 683px width, so .input-group-append had nowhere to go and wrapped
      onto a second line: a 15px bordered strip under the field holding just
      the calendar glyph.

   Fix drops the wrapper border and lifts the append out of flow, so the
   calendar sits inside the field's right edge the way it reads on the 2026
   demo forms. Left clickable on purpose, since that glyph opens the picker.

   Audited every form screen first, because .input-group is not one shape:
     M00010s   1x   input.form-control + div.input-group-append   (date picker)
     M00430s   3x   div.input-group-prepend + input.form-control
     M00242s  16x   div.btn-group + input + input.hidden-rls   (outside form-layout)
     I00255s  17x   same as M00242s                            (outside form-layout)

   So the two halves are scoped differently on purpose:

   (a) The doubled border is universal, and it's the fault Steve actually saw.
       Killed on every .input-group in the portal, whatever the shape.
   (b) The out-of-flow append is ONLY right for the date-picker shape. Forcing
       display:block on a prepend group would stack the prepend above the
       field instead of beside it, and the btn-group shape needs its flex row
       intact. :has() pins it to input-followed-by-append. On a browser
       without :has() support the rule is skipped, the date field falls back
       to the old wrapping layout, and nothing else is affected. */
#portal-body .input-group { border: 0 !important; }

#portal-body form.form-layout .input-group:has(> .form-control + .input-group-append) {
	position: relative;
	display: block;
}
#portal-body form.form-layout .input-group:has(> .form-control + .input-group-append) > .form-control {
	width: 100%;
	/* room for the glyph so a long value doesn't run under it */
	padding-right: 2.75rem;
}
/* same :has() gate: only take the append out of flow inside a group that was
   actually made relative above, otherwise it would position against whatever
   ancestor happens to be positioned and fly off the field */
#portal-body form.form-layout .input-group:has(> .form-control + .input-group-append) .input-group-append {
	position: absolute;
	top: 1px;
	right: 1px;
	bottom: 1px;
	display: flex;
	align-items: center;
	margin: 0;
	/* z-index 4, above Bootstrap's focus raise: .input-group .form-control:focus
	   gets z-index 3, and the input is a positioned box, so on focus its opaque
	   background painted OVER this glyph and it vanished (7/31 PM, Steve —
	   reported on the M00430s prepend; same mechanism verified here). */
	z-index: 4;
}
/* ---- the date PREPEND shape (added 7/31, Steve: "these calendar icons
   should be in the input, right?") ----

   Fourth variant of the input-group wrap bug, and the same root cause as the
   append above and the "?" prepend below: the 2026 recipe's `width: 100%` on
   .form-control beats Bootstrap's `flex: 1 1 auto; width: 1%`, the field eats
   the whole row, and .input-group-prepend wraps onto its own line. Measured on
   Training Evaluation (M00430s): prepend 45x15 at the top, input 700px
   directly beneath it, group 68px tall instead of 53px.

   Same out-of-flow treatment the date append gets, mirrored to the leading
   edge. Icon goes transparent and borderless so it reads as part of the field
   rather than as Bootstrap's grey chip, and the field gains left padding so a
   typed value can't run under it.

   TWO EXCLUSIONS, both load-bearing:

   1. `:not(.mrc-tooltip)`. M00255s has three
      `div.input-group-prepend.mrc-tooltip + input.form-control` groups, which
      match this shape exactly — and the block below deliberately moved those
      "?" icons OUT of the field onto the label row after Steve pushed back on
      leading-edge icons meaning input TYPE. Without the exclusion this rule
      silently reverses that decision.
   2. `+ .form-control` as a direct adjacency. M00430s's instructor row is
      `prepend + span[mrcdropdown] > select`. Widening the selector to reach it
      was tried and **broke the control** — the select collapsed to ~63px and
      lost its displayed value, because the mrcdropdown wrapper does its own
      sizing. Left alone: its icon still sits beside the field rather than
      inside, which is inconsistent with the two dates above it but working.
      Fixing that properly needs the wrapper handled, not a wider selector.

   Audited across all 41 known screens: prepend groups inside form.form-layout
   exist only on M00430s and M00255s, so this rule reaches exactly the two date
   fields. */
#portal-body form.form-layout .input-group:has(> .input-group-prepend:not(.mrc-tooltip) + .form-control) {
	position: relative;
	display: block;
}
#portal-body form.form-layout .input-group:has(> .input-group-prepend:not(.mrc-tooltip) + .form-control) > .input-group-prepend {
	position: absolute;
	left: 0;
	top: 0;
	bottom: 0;
	/* was 3 — exactly ties Bootstrap's focus raise (.input-group
	   .form-control:focus { z-index: 3 }), and the input is later in the DOM,
	   so the tie broke toward the field: click into a date and the calendar
	   glyph vanished under the field's opaque background (7/31 PM, Steve). */
	z-index: 4;
	align-items: center;
	/* the glyph is decorative here, unlike the append on M00010s which opens
	   the picker; let clicks fall through to the field, which opens it */
	pointer-events: none;
}
#portal-body form.form-layout .input-group:has(> .input-group-prepend:not(.mrc-tooltip) + .form-control) > .input-group-prepend .input-group-text {
	background: transparent !important;
	border: 0 !important;
	padding: 0 0 0 .95rem !important;
	color: var(--accent) !important;
}
#portal-body form.form-layout .input-group:has(> .input-group-prepend:not(.mrc-tooltip) + .form-control) > .form-control {
	width: 100% !important;
	padding-left: 2.75rem !important;
}
/* ---- the instructor dropdown prepend: icon REMOVED (7/31 PM, Steve) ----

   M00430s's third prepend group is prepend + span[mrcdropdown] > select — the
   shape the exclusion note above records as unfixable by widening the date
   selector (the mrcdropdown wrapper does its own sizing; pulling the icon
   into the field collapsed the select to 63px and lost its value). Steve's
   call closes that open item from the other direction: a person glyph next
   to a labelled dropdown carries no information, so it goes.

   display:none rather than visibility/opacity so the flex row closes up and
   the select starts on the field edge like every other control (verified
   live: select 680px wide, value intact, left edge aligned with the dates).
   Audited 7/31 PM across the 37-screen server-rendered roster:
   prepend + [mrcdropdown] exists on M00430s only. */
#portal-body form.form-layout .input-group:has(> .input-group-prepend + [mrcdropdown]) > .input-group-prepend {
	display: none;
}
/* ---- rating sliders (7/31 PM, Steve: "don't really look like the style of
   this new design") ----

   Course Rating on M00430s drives five sliders through the jQuery
   simple-slider plugin: div.slider-volume > .track + .dragger, bound to
   data-slider inputs. The plugin's own look is 2011-era — 11px grey-gradient
   track, 16px glossy radial knob under a heavy double drop shadow.

   Restyled to the 2026 vocabulary: 6px hairline-grey track (--line, the card
   border colour), 18px solid accent knob with a 2px white ring and a soft
   shadow. There is no .highlight/fill element in this build, so the track is
   one bar and the knob alone shows the value.

   The plugin positions both parts with INLINE styles (top:50% plus negative
   margins hardcoded to its own dimensions), so the geometry overrides carry
   !important and re-centre for the new sizes: -3px for the 6px track, -9px
   for the 18px knob. Audited 7/31 PM across the 37-screen server-rendered
   roster: .slider-volume / [data-slider] exist on M00430s only. */
#portal-body form.form-layout .slider-volume .track {
	height: 6px !important;
	margin-top: -3px !important;
	background: var(--line, #e8eaee) !important;
	border: 0 !important;
	border-radius: 999px !important;
	box-shadow: none !important;
}
#portal-body form.form-layout .slider-volume .dragger {
	width: 18px !important;
	height: 18px !important;
	margin-top: -9px !important;
	margin-left: -9px !important;
	background: var(--accent, #006478) !important;
	border: 2px solid #fff !important;
	border-radius: 50% !important;
	box-shadow: 0 1px 4px rgba(20, 45, 80, .35) !important;
}

/* ---- the "?" tooltip prepend (added 7/30, Steve compared against prod) ----

   Same root cause as the date append above, different shape. The 2026 field
   recipe sets `width: 100%` on .form-control (see the block further down),
   which overrides Bootstrap's `flex: 1 1 auto; width: 1%` for fields inside
   an input-group. The field then eats the whole row and
   <div class="input-group-prepend mrc-tooltip"> wraps onto its own line, so
   the "?" floated above the field instead of sitting inside it. On the
   pre-2026 portal the icon reads as part of the field.

   Restoring that means moving the visible field onto the GROUP: the group
   draws the border, background and focus ring (values copied from the field
   recipe: #fbfcfd / #d6dbe3 / 10px / teal ring), the inner control goes
   transparent and borderless, and the icon ends up inside that one box.

   REVISED 7/30 after Steve pushed back: an icon at the leading edge of a
   text field conventionally means input TYPE (search glass, currency symbol)
   or something that acts on the value. It doesn't mean "help", and the help
   here describes what the field means, which is the label's job. So the icon
   moves out of the field and onto the label row instead.

   Interim, not the destination. The real fix is markup: drop the tooltip and
   emit the text as <small class="form-text" id="x-help"> with
   aria-describedby on the input, so it's visible while typing and works on
   touch, where hover doesn't exist. That's Rick's; only 3 fields portal-wide
   (all on M00255s, max 78 chars) so it's a small job.

   Taking the tooltip out of flow also solves the original wrap: it stops
   being a flex item, so the field is the only one left and fills the row on
   its own. The field keeps the normal 2026 recipe (its own border and
   background) because it's a plain field again.

   Right-aligned on the label row rather than tucked after the label text:
   CSS can't measure the label's width, so "immediately after the words" is
   not reachable without markup or display:contents on the group.

   Anchored to .input-group with bottom:100%, NOT to .form-group with top:0.
   Bootstrap already sets position:relative on .input-group, and that box's
   right edge is exactly the field's right edge, so right:0 self-aligns with
   no magic number. Going via .form-group meant overriding .input-group to
   static AND hardcoding right:5px to cancel the form-group's `0 5px` padding,
   which would silently drift the day that padding changes.

   Keyed to .mrc-tooltip, not `> .input-group-prepend + .form-control`. One of
   the three fields wraps its <select> in a bare <span>, so a child combinator
   on .form-control silently misses it. Hence the `> span` rule. */
#portal-body form.form-layout .input-group-prepend.mrc-tooltip {
	position: absolute;
	bottom: 100%;
	right: 0;
	z-index: 2;
	margin: 0 0 .25rem;
	cursor: help;
}
#portal-body form.form-layout .mrc-tooltip .input-group-text {
	padding: 0 !important;
	background: transparent !important;
	border: 0 !important;
	height: auto;
}
#portal-body form.form-layout .mrc-tooltip .fa-question-circle {
	color: var(--muted) !important;
	font-size: .95rem;
	transition: color .15s ease;
}
#portal-body form.form-layout .mrc-tooltip:hover .fa-question-circle,
#portal-body form.form-layout .mrc-tooltip:focus-within .fa-question-circle {
	color: var(--accent) !important;
}
/* the <span> wrapping the select is the only in-flow item left, and a flex
   item doesn't fill the main axis without being told to */
#portal-body form.form-layout .input-group:has(> .mrc-tooltip) > span {
	flex: 1 1 auto;
	width: 100%;
	min-width: 0;
}

#portal-body form.form-layout .input-group .input-group-text {
	background: transparent !important;
	border: 0 !important;
	color: var(--muted) !important;
	padding: 0 .95rem !important;
	height: 100%;
	display: flex;
	align-items: center;
}

/* ============================================================
   THE "SELECTIONS" FILTER PANEL (.filter-container)
   Added 7/30. Ajax-injected on the list screens (m-Power Updates, ticket
   lists) and collapsed until you click Selections, which is why it escaped
   the earlier walkthrough and why the 7/28 notes had it as untested.

   It is NOT inside a <form> at all: verified on the live page that the panel
   has no form ancestor, let alone form.form-layout. So every field and button
   rule above misses it completely and it was still rendering the legacy look,
   borderless inputs and 2px-radius grey buttons.

   Everything below mirrors the form recipe rather than inventing values, so
   the panel can't drift from the real forms. If that recipe changes, these
   need the same change; they're deliberately identical, not merely similar.
   ============================================================ */
/* ---- panel width, and the open/close jump it was causing ----
   The panel wraps its form in .mrc-form-width, which caps at 860px and
   centres with auto margins. That produced a jump on every open and close:
   the panel is <div class="row filter-container collapse">, so its own .row
   makes it flex mid-animation, but Bootstrap's `.collapse.show { display:
   block }` takes over the moment the transition ends. Measured through one
   open: 513px while collapsing (centred, margin-left 155px), snapping to
   358px once settled (margin-left 0). Closing ran it in reverse, which is why
   it slid back to centre just before disappearing.

   Steve's call, and it's the better one: span the section instead. A filter
   bar narrower than the list it filters looked wrong regardless of the jump.
   Full width also makes the flip harmless, since there are no auto margins
   left to resolve differently, so this replaces the display:flex override I
   first reached for rather than sitting alongside it.
   Verified the visible panel now lands at 373-1513, the same box as the
   cards below it, and holds through opening, open and closing. */
#portal-body .filter-container .mrc-form-width {
	max-width: 100% !important;
	margin-left: 0 !important;
	margin-right: 0 !important;
}
/* ...and now that it's the same box as the cards and sits directly above
   them, it should look like one. It was square-cornered with a 2px #f7f7f9
   border against the cards' 22px / 1px --line. */
#portal-body .filter-container .form-layout.bg-white {
	border-radius: var(--radius, 22px) !important;
	border: 1px solid var(--line) !important;
}

#portal-body .filter-container .form-control,
#portal-body .filter-container select,
#portal-body .filter-container textarea {
	width: 100%;
	box-sizing: border-box;
	font-family: inherit;
	font-size: .95rem !important;
	color: var(--ink);
	background-color: #fbfcfd !important;
	border: 1px solid #d6dbe3 !important;
	border-radius: 10px !important;
	padding: .68rem .9rem !important;
	height: auto !important;
	box-shadow: none !important;
}
#portal-body .filter-container .form-control:focus,
#portal-body .filter-container select:focus,
#portal-body .filter-container textarea:focus {
	outline: none;
	border-color: var(--accent) !important;
	box-shadow: 0 0 0 3px rgba(0,100,120,.14) !important;
}
/* same chevron the form selects get */
#portal-body .filter-container select,
#portal-body .filter-container select.mrcselect {
	appearance: none;
	-webkit-appearance: none;
	background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%235b6470' stroke-width='2'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E") !important;
	background-repeat: no-repeat !important;
	background-position: right .85rem center !important;
	background-size: 15px 15px !important;
	padding-right: 2.4rem !important;
}
#portal-body .filter-container label {
	font-size: .82rem;
	font-weight: 600;
	color: var(--ink);
	margin-bottom: .35rem;
}
/* Clear Selections, and the EQ / relationship toggle that sits beside the
   date field. Both are .btn-secondary and both were legacy grey at 2px.
   Slightly tighter padding than the form buttons on purpose: these are
   compact filter controls, not the primary action of a page. */
#portal-body .filter-container .btn-secondary,
#portal-body .filter-container .btn-group > .dropdown-toggle {
	background: #fff !important;
	border: 1px solid var(--line) !important;
	color: var(--accent-dk) !important;
	border-radius: 999px !important;
	font-size: .9rem !important;
	font-weight: 500;
	line-height: 1 !important;
	text-transform: none !important;
	letter-spacing: normal !important;
	padding: .6rem 1.15rem !important;
	box-shadow: none !important;
}
#portal-body .filter-container .btn-secondary:hover,
#portal-body .filter-container .btn-group > .dropdown-toggle:hover {
	border-color: var(--accent) !important;
	color: var(--accent) !important;
}
/* the operator toggle and the date field are separate controls now that both
   are rounded, so give them air instead of the old butted-together look */
#portal-body .filter-container .btn-group { margin-right: .5rem; }

/* The date row is an .input-group holding
     div.btn-group (EQ) + input.date-input + input.hidden-rls + .input-group-append
   and it was breaking into THREE rows: the field resolves to the group's full
   width, so with flex-wrap:wrap the operator landed above it and the calendar
   glyph below it. Measured 103px tall for what should be one 47px control.

   Same shape as the date field on the maintenance forms, but that fix was
   scoped to form.form-layout and this panel has no form at all, so it needed
   repeating here rather than being inherited. */
#portal-body .filter-container .input-group {
	position: relative;
	flex-wrap: nowrap;
	/* stretch, not center: the EQ operator is joined to the field below and
	   has to match its height exactly. Matching padding and font instead left
	   it 47px against the field's 53px, because the two resolve different
	   line-heights. Letting flex size it removes that arithmetic entirely. */
	align-items: stretch;
}
#portal-body .filter-container .input-group > .form-control {
	flex: 1 1 auto;
	width: 1%;
	min-width: 0;
	/* room for the glyph so a typed date doesn't run under it */
	padding-right: 2.6rem !important;
}
#portal-body .filter-container .input-group > .input-group-append {
	position: absolute;
	top: 0;
	bottom: 0;
	right: 0;
	display: flex;
	align-items: center;
	margin: 0;
}
#portal-body .filter-container .input-group .input-group-text {
	background: transparent !important;
	border: 0 !important;
	color: var(--muted) !important;
	padding: 0 .85rem !important;
	height: auto;
}

/* ---- the EQ operator joined to the date field ----
   Steve, 7/30: these are one control conceptually (operator + value), so they
   should read as one. The pill treatment further up is right for the
   standalone secondary buttons in this panel (Clear Selections) but wrong
   here, where it left a rounded lozenge floating beside a rounded box.

   Squared off on the facing edges, same border/background/padding/font as the
   field so the two halves match in height, and the operator drops its right
   border so the join is a single 1px divider rather than a double line.
   The .5rem gap set on .btn-group above is cancelled for this case only. */
#portal-body .filter-container .input-group > .btn-group {
	margin-right: 0;
	/* !important because bootstrap-grid.css ships `.show { display: block
	   !important }` as a responsive display utility, and that class name
	   collides with the one Bootstrap's dropdown adds to the .btn-group while
	   the menu is open. Without this the group stops being a flex container
	   the moment you click EQ, the toggle loses its stretch, and it visibly
	   shrinks from 53px to 46px mid-interaction. */
	display: flex !important;
}
#portal-body .filter-container .input-group > .btn-group > .dropdown-toggle {
	/* flex-centred rather than padded to a guessed height, so it tracks the
	   field whatever the field's line-height resolves to */
	display: flex;
	align-items: center;
	background: #fbfcfd !important;
	border: 1px solid #d6dbe3 !important;
	border-right: 0 !important;
	border-radius: 10px 0 0 10px !important;
	color: var(--ink) !important;
	font-size: .95rem !important;
	font-weight: 500;
	padding: 0 .9rem !important;
	height: auto;
}
#portal-body .filter-container .input-group > .btn-group > .dropdown-toggle:hover {
	background: #f2f5f7 !important;
	color: var(--accent-dk) !important;
	border-color: #d6dbe3 !important;
}
/* The legacy theme puts a scale(0.98) press effect on buttons via :focus /
   :active. On a standalone button that's fine, but this one is welded to the
   date field, so pressing it shrank it 2% and visibly broke the seam: the
   rendered box went 51.57px against the field's 52.63px while the computed
   height still read 52.63px, which is why it only showed up in
   getBoundingClientRect and not in the styles. Steve reported it as "gets
   small when I click it". */
#portal-body .filter-container .input-group > .btn-group > .dropdown-toggle,
#portal-body .filter-container .input-group > .btn-group > .dropdown-toggle:focus,
#portal-body .filter-container .input-group > .btn-group > .dropdown-toggle:active {
	transform: none !important;
}
/* stretch has to be explicit here: the toggle sits inside .btn-group, so it
   takes its height from that, not from the input-group */
#portal-body .filter-container .input-group > .btn-group { align-items: stretch !important; }
#portal-body .filter-container .input-group > .btn-group > .dropdown-toggle {
	align-self: stretch;
	margin: 0 !important;
}
#portal-body .filter-container .input-group > .btn-group ~ .form-control {
	border-radius: 0 10px 10px 0 !important;
}
/* focus ring belongs to the joined pair, not half of it */
#portal-body .filter-container .input-group:focus-within > .btn-group > .dropdown-toggle {
	border-color: var(--accent) !important;
}

/* the operator menu itself: items were #999 at 14px, about 2.85:1 on white,
   under the 4.5:1 AA threshold and the reason the options read as disabled */
#portal-body .filter-container .dropdown-menu {
	border: 1px solid var(--line) !important;
	border-radius: 12px !important;
	box-shadow: 0 14px 32px rgba(15,30,45,.10);
	padding: .35rem;
	margin-top: .3rem;
}
#portal-body .filter-container .dropdown-item {
	color: var(--body) !important;
	font-size: .92rem;
	border-radius: 8px;
	padding: .5rem .75rem;
}
#portal-body .filter-container .dropdown-item:hover,
#portal-body .filter-container .dropdown-item:focus {
	background: var(--accent-tint, #e7f2f4) !important;
	color: var(--accent-dk) !important;
}

/* ---- content cards and buttons OUTSIDE the tile grids and form.form-layout
   (added 7/30 after walking the whole portal) ----

   Several screens hand-build a plain Bootstrap card with a header band, e.g.
   e-Learning (I00014s): <div class="card" style="border:1px solid #e9ecf0">
   with <h5 class="card-header bg-pale-primary">. None of the existing rules
   reached it, so those screens still showed the legacy look: 3px corners and
   a pale blue header. The inline border on the markup is why the border here
   needs !important.

   The header gets an explicit top radius rather than overflow:hidden on the
   card, which would clip any dropdown or tooltip a card might contain. */
#portal-body .card:not(.card-hover) {
	border-radius: var(--radius, 22px) !important;
	border: 1px solid var(--line) !important;
}

/* ---- m-Power panel wrappers are NOT cards (added 7/31, Steve) ----

   Edit Ticket (M00030s) wraps its whole field set in
   <div class="row panels"><div class="col"><div class="card bg-gray">.
   That's a layout wrapper, but the rule above turned it into a visible
   second card sitting inside the form's own 2026 card — a box inside a box.

   The discriminator is content, not class. A real panel announces itself
   with a .card-header or .card-body; the wrapper has neither:

     M00030s  .card.bg-gray  in .row.panels  no header, no body  → wrapper
     M00255s  .card.w-100    in .row.panels  HAS .card-header    → real panel
     M00430s  .card x4       not in .panels  header AND body     → real panel

   So do not simplify this to `form .card` or to `.card.bg-gray` — the first
   flattens M00255s's two titled licence panels, the second is a colour class
   that any screen could pick up. Verified across all 40 screens: exactly one
   element matches, the M00030s wrapper. */
#portal-body form.form-layout .row.panels > [class*="col"] > .card:not(:has(.card-header)):not(:has(.card-body)) {
	background: transparent !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
}
/* ---- card footers (added 7/30) ----
   m-Power Update Details (I00090s) ends each card with
   <div class="card-footer bg-pale-primary py-1"> holding the "Special
   Instructions" line. 26 of them on that screen; it's the only screen using
   footers, but the rule is written for the component, not the page.

   Two faults, both measured on the live page:
   1. The footer's radius was `0 0 3px 3px` inside a card at 22px, so square
      corners sat where the card's rounded ones should be and the bottom of
      the card looked like it had no edge.
   2. bg-pale-primary is rgb(238,244,252) and the page band is
      rgb(244,245,248). Near-identical, so the footer bled into the page and
      the card's 1px bottom border was the only thing separating them.

   Not --bg-soft (which the card header above uses) and no longer
   --accent-tint either. A header sits against the white card body below it,
   so a soft grey reads fine there, but a footer sits against the PAGE, and
   it has to clear the page colour by a visible margin.

   Deepened twice, both times because it read as blending:
     #eef4fc  bg-pale-primary, the legacy value    1.011 vs page
     #e7f2f4  --accent-tint                        1.074 vs page
     #d2e9ee  CURRENT                              1.188 vs page
   For reference the page itself only clears a white card by 1.063, so
   anything near that was always going to disappear. Hardcoded rather than
   using --accent-tint because that token is correct where it is used
   elsewhere (icon discs, success banners) and shouldn't be dragged darker
   just to serve this one band. */
#portal-body .card > .card-footer {
	background: #d2e9ee !important;
	border-top: 1px solid var(--line) !important;
	border-radius: 0 0 calc(var(--radius, 22px) - 1px) calc(var(--radius, 22px) - 1px) !important;
	color: var(--ink) !important;
}

#portal-body .card > .card-header {
	/* DEEPENED 7/31 (Steve, second report of a header blending). Was
	   --bg-soft #f4f5f8, which is 1.026 against the #f7f8fa page band — a
	   header sits at the TOP of a card, so its neighbour is the page, not the
	   white body below it, and at that distance only the 1px border separated
	   them. #e8eaee is 1.133. Deliberately a neutral grey and not the
	   accordion's blue: those headers are role="button", these are not.
	   Reaches I00014s, M00255s, M00430s and the nested Stable Release /
	   Release Candidate cards on I00350s; all checked. */
	background: #e8eaee !important;
	border-bottom: 1px solid var(--line) !important;
	border-radius: calc(var(--radius, 22px) - 1px) calc(var(--radius, 22px) - 1px) 0 0 !important;
	color: var(--ink) !important;
	font-size: 1.02rem;
	font-weight: 600;
	letter-spacing: -0.01em;
	padding: 1rem 1.35rem !important;
	margin: 0;
}

/* ---- card screenshots (added 7/31, Steve) ----

   Select UI style (I00014s) ships a page-level <style> block:
     img.card-img-top { object-fit: fill; height: 300px !important; }
   A page <style> loads after our sheets, so this needs both !important and
   more specificity than the app's bare `img.card-img-top`.

   `object-fit: fill` plus a locked 300px height DISTORTS rather than crops:
   the two screenshots are 971x564 and 1068x591 (ratios 1.72 and 1.81) and
   were being squeezed into 1.16. Steve read it as the images looking
   scrunched. Restored to natural ratio: 1.717 and 1.802 measured after, the
   0.005 delta being the app's own 2px border.

   The wrapper <a> is inline, so it collapsed to a 20px line box while the
   300px image overflowed it, and the "Begin e-Learning" button rendered
   against the bottom of the image with a 0px gap. Making the anchor a block
   gives it the image's real height; margin then does what it looks like it
   should. Same inline-vs-block trap as the Priority group and the metadata
   strip — worth assuming it, not discovering it, on this app. */
#portal-body .card img.card-img-top {
	height: auto !important;
	object-fit: contain !important;
	display: block;
	width: 100%;
}
#portal-body .card .card-body > a:has(> img.card-img-top) {
	display: block;
	margin-bottom: 1.1rem;
}

/* ---- equal-height card columns (added 7/31, Steve) ----

   Letting the screenshots keep their own aspect ratios means their heights
   differ: 971x564 renders 321px tall while 1068x591 renders 306px at the same
   551px width. The cards inherited that 15px difference and the two
   "Begin e-Learning" buttons sat on different lines.

   height:100% resolves against the column, and the .row is flex, so the
   columns already stretch to the tallest — the card just has to take it. This
   is bounded, unlike the ticket-card case the 7/28 note records where the
   parent was full-page height. Scoped to a .card that is the direct child of
   an LG column inside .mrc-form-width, i.e. the same card-row shape the width
   rule above targets, so it cannot reach the menu tiles.

   margin-top:auto on the action pins the buttons to the bottom, which is what
   actually makes the pair read as level. Measured after: both cards 497px,
   both buttons at y=977, images still at 1.717 / 1.802 against natural
   1.722 / 1.807.

   M00255s also matches this selector and could not be re-checked live (New
   License Information is only reachable by starting a real licence transfer).
   It should be a no-op there: its columns already carry
   `d-flex align-items-stretch` and its cards `w-100`, so they were stretching
   before this rule existed. Worth an eye on the next pass through that screen. */
#portal-body .mrc-form-width .row > [class*="col-lg-"] > .card { height: 100%; }
#portal-body .mrc-form-width .row > [class*="col-lg-"] > .card > .card-body {
	display: flex;
	flex-direction: column;
}
#portal-body .mrc-form-width .row > [class*="col-lg-"] > .card > .card-body > a.btn {
	margin-top: auto;
}

/* ============================================================
   e-LEARNING TOPIC LIST (I00010s) — added 7/31, Steve

   The right rail is a list of course topics, each a collapse card whose
   header opens a set of lesson links. It arrived with raw CSS keyword glows
   from a page-level <style>:

     .card-header.border-success { box-shadow: green  0 0 10px }
     .card-header.border-warning { box-shadow: orange 0 0 10px }
     .border-congrats            { box-shadow: gold   0 0 20px; border-color: gold }

   plus Bootstrap's #3cd458 on .border-success itself, green lesson links and
   green ticks. Steve read the glow as a stray hover outline; it is actually
   the progress model, so it could not simply be deleted:

     .border-success  topic complete
     .border-warning  topic in progress
     .not_started     topic untouched
     .border-congrats certificate earned (hidden until then)

   Translated into system colours rather than removed. There is no green in
   mrc-2026.css — the same reasoning already recorded at .alert-success, where
   a green would have been "a colour invented for one component". Complete is
   the accent teal, in-progress the #b87500 amber introduced for the I00025s
   demo icon, not-started a neutral line.

   State now reads twice, on a 3px left rule and on the topic icon, instead of
   a halo.

   THE HEADERS ARE DELIBERATELY NOT THE BLUE ACCORDION BAND. They are
   data-toggle="collapse", so they inherited it automatically, and that was
   tried first and rejected on sight (Steve, 7/31): the blue band works on
   I00350s where three panels ARE the page's primary control, but five of them
   stacked in a 412px rail read as heavy slabs. These are a course syllabus,
   not five buttons, so they are quiet white rows with a hover tint and the
   weight carried by the title. `.card-cat` is the discriminator — it is on the
   e-learning topic headers and nowhere else, so I00350s keeps its blue.

   Lessons were centred, because the app puts .text-center on the wrapping
   row, which left them reading as loose text rather than a list. Left-aligned
   with the tick pinned right, so a column of ticks scans as progress.

   Audited across all 41 known screens: every selector here matches I00010s
   and nothing else. Note I00010s was itself missing from the 40-screen
   roster — it hangs off the Training menu / "Begin e-Learning", not the six
   menus the crawler walks. Treat the roster as a floor.
   ============================================================ */
/* quiet the topic rows — overrides the blue band they inherit from the
   accordion rule, for .card-cat only */
#portal-body .card-header.card-cat,
#portal-body .card-header.card-cat[data-toggle="collapse"] {
	background: #fff !important;
	padding: .95rem 1.15rem !important;
}
#portal-body .card-header.card-cat[data-toggle="collapse"]:hover {
	background: var(--bg-soft, #f4f5f8) !important;
}
#portal-body .card-header.card-cat .card-title {
	font-size: 1rem !important;
	font-weight: 600;
	color: var(--ink) !important;
}
#portal-body .card-header.card-cat i { font-size: 1.35rem !important; opacity: .85; }
/* the app pads this inner flex row by .px-2/.px-4; the header owns the inset */
#portal-body .card-header.card-cat .d-flex { padding: 0 !important; }

#portal-body .card-header.border-success,
#portal-body .card-header.border-warning,
#portal-body .card-header.not_started,
#portal-body .border-congrats { box-shadow: none !important; }

#portal-body .card.border-success,
#portal-body .card.border-warning,
#portal-body .card.not_started,
#portal-body .card-header.border-success,
#portal-body .card-header.border-warning,
#portal-body .card-header.not_started,
#portal-body .card-header.border-congrats { border-color: var(--line) !important; }

/* NO left state bar. A 3px accent rule was tried and rejected (Steve, 7/31):
   #006478 at 3px reads as a stray green line rather than as progress, and it
   is the third thing on this screen he has called out as a colour artifact.
   State lives on the icon alone now — one signal, in the topic's own glyph,
   which is where the eye already goes. */
#portal-body .card.border-success .card-header i { color: var(--accent) !important; }
#portal-body .card.border-warning .card-header i { color: #b87500 !important; }
#portal-body .card.not_started .card-header i { color: #9aa3ae !important; }
#portal-body .card-header.border-congrats i { color: var(--accent-dk, #00485a) !important; }

/* ---- group the five topics into ONE list ----

   Each topic is its own `.row.gap-y > .col-12 > .card`, so the stack arrived
   as five separately-rounded pills with 24px between them. Steve's objection
   was the rounded top corners specifically, and a smaller radius would not
   have fixed it: five rounded tops in a 412px rail is the same
   stacked-pills problem as the I00350s accordion, and it gets the same
   answer — round the GROUP, square every internal edge, collapse the gaps.

   Done with :first-child / :last-child on the .row.gap-y wrappers rather than
   overflow:hidden on the rail, because the rail is a grid column carrying its
   own padding and clipping it would cut the shadows. Verified the rail holds
   exactly five .row.gap-y siblings, all visible, in order — the certificate
   card lives outside this rail and is hidden until earned, so it cannot
   steal :first-child. */
#portal-body .row.gap-y:has(> [class*="col-"] > .card > .card-header.card-cat) > [class*="col-"] {
	padding-bottom: 0 !important;
}
#portal-body .row.gap-y:has(> [class*="col-"] > .card > .card-header.card-cat) > [class*="col-"] > .card,
#portal-body .row.gap-y:has(> [class*="col-"] > .card > .card-header.card-cat) > [class*="col-"] > .card > .card-header {
	border-radius: 0 !important;
}
/* one hairline between neighbours, not two */
#portal-body .row.gap-y:has(> [class*="col-"] > .card > .card-header.card-cat):not(:first-child) > [class*="col-"] > .card {
	border-top: 0 !important;
}
#portal-body .row.gap-y:has(> [class*="col-"] > .card > .card-header.card-cat):first-child > [class*="col-"] > .card {
	border-top-left-radius: var(--radius, 22px) !important;
	border-top-right-radius: var(--radius, 22px) !important;
}
#portal-body .row.gap-y:has(> [class*="col-"] > .card > .card-header.card-cat):first-child > [class*="col-"] > .card > .card-header {
	border-top-left-radius: calc(var(--radius, 22px) - 1px) !important;
	border-top-right-radius: calc(var(--radius, 22px) - 1px) !important;
}
#portal-body .row.gap-y:has(> [class*="col-"] > .card > .card-header.card-cat):last-child > [class*="col-"] > .card {
	border-bottom-left-radius: var(--radius, 22px) !important;
	border-bottom-right-radius: var(--radius, 22px) !important;
}
#portal-body .row.gap-y:has(> [class*="col-"] > .card > .card-header.card-cat):last-child > [class*="col-"] > .card > .card-body {
	border-bottom-left-radius: calc(var(--radius, 22px) - 1px) !important;
	border-bottom-right-radius: calc(var(--radius, 22px) - 1px) !important;
}

/* ---- lessons sit on a tint so the open topic reads as one block ----

   EVERY selector here must match `.collapsing` as well as `.collapse`, and
   that is not cosmetic. Bootstrap swaps the class for the duration of the
   animation: `.collapse` → `.collapsing` → `.collapse.show`. Keyed on
   `.collapse` alone, all of this dropped off mid-flight and the app's own
   styling showed through, so a topic opened grey-and-centred and then snapped
   to teal-and-left at the end (Steve, 7/31).

   The padding is the part that actually made it lurch rather than just
   flicker. Measured mid-transition: 20px 22.4px 20px 32px under `.collapsing`
   against 8px 18.4px 11.2px under `.collapse`. Bootstrap animates height to
   the scrollHeight it measures in one state and the element settles into the
   other, so the last frame jumps. Keeping the box identical across both
   classes is what makes the motion smooth — the colour fix is a side effect.

   :is() rather than repeating each selector twice. The file already depends
   on :has(), which has the narrower support of the two. */
#portal-body .card-body:is(.collapse, .collapsing) {
	background: var(--bg-soft, #f4f5f8) !important;
	padding: .5rem 1.15rem .7rem !important;
}
#portal-body .card-body:is(.collapse, .collapsing),
#portal-body .card-body:is(.collapse, .collapsing) .text-default { text-align: left !important; }
#portal-body .card-body:is(.collapse, .collapsing) > .text-default > div > div { padding: .4rem 0; }
#portal-body .card-body:is(.collapse, .collapsing) a[class*="text-"] {
	color: var(--accent-dk, #00485a) !important;
	font-size: .92rem;
}
#portal-body .card-body:is(.collapse, .collapsing) .fa-check {
	color: var(--accent) !important;
	float: right;
	font-size: .85rem;
	margin-top: .25rem;
}

/* ---- accordion (added 7/31) ----

   Download m-Power Update (I00350s): #accordion > .card x3, each with
   <div class="card-header bg-pale-primary" data-toggle="collapse" role="button">.
   The screens carrying a collapse toggle elsewhere (I00009s, I00270s,
   I01300s, all the Selections filter panel) do NOT put it on a .card-header,
   so the attribute selector below reaches these three headers and nothing else.

   ⚠️ THE :has() GATE ON THE CONTAINER IS LOAD-BEARING. #accordion is NOT
   unique — Training Evaluation (M00430s) uses the same id for a different
   markup shape: <div class="card-header"><h5><button data-toggle="collapse">,
   i.e. the toggle is on a BUTTON INSIDE the header, not on the header itself.
   An ungated `#accordion > .card { border-radius: 0 }` squared M00430s's two
   section cards while leaving their 20px margins intact, so they rendered as
   square blocks with gaps — worse than before. The gate matches only the
   header-is-the-toggle shape, which is I00350s. (7/31 PM: Steve has since
   asked for square corners on M00430s's sections — that now lives in its own
   gated rule below, "Training Evaluation section cards". The gate here is
   still load-bearing: the two screens get different treatments.)

   Two faults, both reported from the rendered page:

   1. Every panel carried the full 22px card radius while stacking flush
      against its neighbours, so three rounded pills sat corner-to-corner
      instead of reading as one control. Fixed by moving the radius up to the
      container and squaring the panels. overflow:hidden is safe HERE (unlike
      on .card, see the note at the .card-header rule above) because the
      accordion holds only its own panels — no dropdown or tooltip to clip.

   2. The header inherited --bg-soft (#f4f5f8) against a #f7f8fa page band:
      1.026 contrast. For scale, a plain white card clears the same page by
      1.063, so the band was less distinct than white and read as unstyled.
      Same failure the card-footer comment above documents.

      Depth is set at 1.188 vs the page, the value the card footers landed on
      after being deepened twice. Colour is Steve's call (7/31): shipped teal
      #d2e9ee first, then swapped to blue at the same depth. Candidates, all
      measured against #f7f8fa:

        #eef4fc  1.041  bg-pale-primary, the legacy value, far too close
        #e2ecfa  1.122  still reads as blending
        #d9e6f9  1.188  CURRENT, same separation as the footer band
        #d5e3f8  1.222  next step deeper
        #d0e0f7  1.260  deeper still

      Not a grey at any depth: these headers are role="button", and a grey
      band on a grey page reads as disabled. Body text is 13.8:1 here.

   The headers had no cursor or hover feedback at all despite being the only
   interactive thing on the page. */
#portal-body #accordion:has(> .card > .card-header[data-toggle="collapse"]) {
	border-radius: var(--radius, 22px);
	overflow: hidden;
}
#portal-body #accordion:has(> .card > .card-header[data-toggle="collapse"]) > .card,
#portal-body #accordion:has(> .card > .card-header[data-toggle="collapse"]) > .card > .card-header {
	border-radius: 0 !important;
}
/* collapse the doubled 1px line between adjacent panels */
#portal-body #accordion:has(> .card > .card-header[data-toggle="collapse"]) > .card + .card {
	border-top: 0 !important;
}

#portal-body .card > .card-header[data-toggle="collapse"] {
	background: #d9e6f9 !important;
	cursor: pointer;
}
#portal-body .card > .card-header[data-toggle="collapse"]:hover {
	background: #c9dbf4 !important;
}
/* ---- Training Evaluation section cards go square (7/31 PM, Steve) ----

   M00430s's four collapsible sections use the OTHER toggle shape — the
   button sits inside the header (<div class="card-header"><h5><button
   data-toggle="collapse">), which is exactly what the I00350s gate above
   excludes. Steve asked for no rounding on these after seeing four rounded
   pills stacked down the page.

   Square boxes WITH their 20px gaps, deliberately — the opposite call from
   the I00350s regression note above. There the panels were flush and could
   group into one rounded control; here the four cards can't group at all:
   two sit inside a (duplicated) #accordion, the other two in bare .col-12s,
   so they aren't even siblings. Independent square sections is the design,
   not a compromise.

   The generic .card > .card-header rule rounds the top corners with
   !important, so both rules here need it too. Audited 7/31 PM across the
   37-screen server-rendered roster: the button-in-header shape exists on
   M00430s only. */
#portal-body .card:has(> .card-header button[data-toggle="collapse"]) {
	border-radius: 0 !important;
}
#portal-body .card:has(> .card-header button[data-toggle="collapse"]) > .card-header {
	border-radius: 0 !important;
}

/* Same pill treatment the form buttons get, for buttons that sit outside
   form.form-layout: "Begin e-Learning" is .btn.btn-primary.w-100 in a bare
   card, and the license-transfer cards use .btn.btn-success.w-100. Both were
   still rendering at 11px uppercase.

   :not(.btn-xs) is doing real work. The navbar's "Get a Demo" CTA is
   `btn btn-xs btn-round btn-success`, so an unqualified .btn-success here
   captures it and blows it from its designed navbar size to 45px tall.
   Verified 7/30. .btn-xs is the only thing separating the two, since both
   are .btn-success. */
#portal-body .btn-primary,
#portal-body .btn-success:not(.btn-xs) {
	border-radius: 999px !important;
	background: var(--btn-ink, #2046ae) !important;
	border-color: transparent !important;
	color: #fff !important;
	/* the legacy theme renders these at 11px uppercase. Same .btn-pill base
	   sizing as the form buttons above, line-height included, so the two
	   can't drift apart. */
	font-size: 1rem !important;
	font-weight: 500;
	line-height: 1 !important;
	text-transform: none !important;
	letter-spacing: normal !important;
	padding: .85rem 1.7rem !important;
	box-shadow: none !important;
	/* same icon gap as the form buttons above */
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	gap: .5rem;
	transition: background-color .18s ease, transform .18s ease;
}

/* ---- a button sitting in a field row matches the field box (added 7/31) ----

   FAQ Search (I01000s) puts Submit in the same .row.align-items-center as the
   Search Criteria and Tag Search inputs. Measured, the three came out 45.2 /
   48.1 / 48.5 — the button is the SHORT one, though a solid blue pill next to
   a pale outlined field reads as the opposite.

   The button box is .85rem padding + 1rem line-height + 2px border = 45.2px
   while the field recipe lands at 48.1px, so they were never going to agree.
   min-height rather than more padding, so the label stays optically centred
   and the pill can still grow if it ever wraps.

   Audited 7/31 across all 40 CUSTPORTAL screens: this selector matches
   exactly one element portal-wide, the FAQ Submit button. The .btn-success
   buttons on I00255s sit in a card, not a field row, and are untouched.
   :not(.btn-xs) is the same navbar-CTA guard as above. */
#portal-body .row.align-items-center > [class*="col-"] > .btn:not(.btn-xs) {
	min-height: 48px;
}

/* Glyphs inside our buttons sit slightly below the label size, matching how
   an icon reads next to text on the marketing pages.
   Deliberately NOT a blanket `#portal-body .btn > .fa`: the navbar's dropdown
   toggles are .nav-link.btn.btn-link and carry fa-angle-down chevrons, and
   the mobile search control is a .btn too, so a blanket rule shrinks navbar
   furniture that mrc-2026.css already sizes. */
#portal-body form.form-layout .btn:not(.btn-group .btn):not(label) > .fa,
#portal-body .btn-primary > .fa,
#portal-body .btn-success:not(.btn-xs) > .fa {
	font-size: .85em;
}

#portal-body .btn-primary:hover,
#portal-body .btn-success:not(.btn-xs):hover {
	background: #183a94 !important;
	transform: translateY(-1px);
}

/* ---- trailing divider above a card's action button ----
   The license-transfer cards (I00255s) end with:
     <ul class="list-group list-group-flush"> ...items... </ul>
     <a class="btn btn-success w-100">Transfer</a>
   Bootstrap only zeroes the last flush item's bottom border when the <ul> is
   itself the last child. The <a> after it means that rule never fires, so a
   divider is left stranded. It read as an edge while the button was a square
   full-width block sitting flush against it; once the button became a pill,
   the line was suddenly floating above a rounded shape. Steve spotted it
   7/30.
   Second rule gives the button back the breathing room the divider was
   providing. */
#portal-body .card .list-group-flush > .list-group-item:last-child {
	border-bottom: 0 !important;
}
#portal-body .card .list-group + .btn { margin-top: .9rem; }

/* ---- list-row icons and body size (Open/Closed Tickets, and every other
   .table-content list) ----

   The app hard-codes a hex colour inline around each row icon:
     <span style="color:#2ecc71"><i class="fa fa-search"></i></span> View
     ...#f1c40f Edit, #e74c3c Close, #9b59b6 on the ticket glyph
   42 of them on the Open Tickets screen alone. Same six-unrelated-hues
   problem the menu tiles had, so the same answer: one accent colour.

   Two markup shapes, both needed:
     <span style="color:#2ecc71"><i class="fa fa-search"></i></span>  View
     <i class="fa fa-thumbs-up" style="color: rgb(231,76,60)">        Close
   The first keys on `color:#` deliberately. The row meta spans carry
   style="color: inherit; font-family: inherit; font-size:16px" and a looser
   match would turn the dates and ticket types teal too. Only the hex ones are
   icon wrappers. The second catches inline colour set straight on the glyph,
   which is how the Close action ships. An author !important beats a
   non-important inline declaration, which is what makes this reachable. */
#portal-body .table-content span[style*="color:#"],
#portal-body .table-content .fa[style*="color"] { color: var(--accent) !important; }

/* Same treatment outside .table-content. The Enhancement Request screen
   (M00021s) has one stray <span style="color:#2980b9"> and others will turn
   up as apps change, so this catches the pattern rather than the instance.
   Kept as its own rule, NOT grouped with the :has() selectors below: a
   browser that doesn't understand :has() drops the entire rule it appears in,
   which would take this selector down with it for no reason.
   (7/31 PM: a stray duplicated comment tail here left three lines of prose
   OUTSIDE the comment, which made the parser eat this whole rule — it was
   dead in the pending file. Comment rewrapped; nothing shipped broken.) */
#portal-body .fa[style*="color"] { color: var(--accent) !important; }
/* :has() keeps this to spans that actually wrap an icon, so a hex colour used
   on real copy somewhere is left alone. Degrades to no-op on old browsers. */
#portal-body span[style*="color:#"]:has(> .fa),
#portal-body span[style*="color:#"]:has(> i[class*="icon-"]) { color: var(--accent) !important; }

/* ---- icons in content cards that are NOT menu tiles ----
   My Licenses (I00250s), Third Party Software (I00016s) and similar build
   plain (non-link) cards with an icon above the data. They fell outside the
   tile rules and kept the theme's grey. Colour only, no tinted disc: the disc
   belongs to the tile grids where the icon is the main visual, and it would
   overpower a dense card of licence data. The tile rules out-specify this. */
#portal-body .card .card-body .fa,
#portal-body .card .card-body i[class*="icon-"] { color: var(--accent); }
/* ...but icons inside BUTTONS take the button's own text colour. Found
   7/31 PM on M00430s: the rule above painted the Submit Evaluation check
   teal on the blue pill (Steve read it as green). 18 screens put a .fa
   inside a .btn (accept checks, clear/filter icons); on a solid pill
   inherit = white, on an outline button inherit = the label colour — both
   what a button glyph should have been doing all along. Out-specifies the
   rule above via .btn; no !important needed, neither has one. */
#portal-body .card .card-body .btn .fa,
#portal-body .card .card-body .btn i[class*="icon-"] { color: inherit; }

/* ---- link-type icons keep their colour coding (added 7/31) ----

   Recent Enhancements (I00025s) ends each row with up to three links, and the
   app already codes them on the anchor:
     <a class="text-primary">  <i class="fa fa-file">           documentation
     <a class="text-warning">  <i class="fa fa-desktop">        live demo
     <a class="text-danger">   <i class="fa fa-youtube-square"> video
   The rule above was flattening all three to teal, so three different
   destinations looked identical.

   This is NOT a reversal of the 7/30 decision to unify the menu-tile icons.
   That change removed six hues that carried no meaning; here the colour IS
   the meaning — it's the only thing distinguishing the three link types, and
   the icons sit in a row with no labels. The structures don't overlap either:
   menu tiles put the <a> around the card, these sit inside .card-body.

   Audited 7/31 across all 40 CUSTPORTAL screens — I00025s is the only screen
   with a coloured anchor wrapping an icon (20 of them), so this reaches
   nothing else.

   Amber is NOT the theme's .text-warning. That value is #ffbf00, which is
   1.65:1 on a white card — under the 3:1 WCAG floor for a meaningful icon,
   and visibly washed out at 35px. #b87500 is 3.76:1 and still reads amber.
   Teal (6.79:1) and the theme's .text-danger #bf0603 (6.48:1) both already
   passed and are used as-is. */
#portal-body .card-body a.text-primary > .fa { color: var(--accent); }
#portal-body .card-body a.text-warning > .fa { color: #b87500; }
#portal-body .card-body a.text-danger > .fa { color: #bf0603; }

/* ---- ticket row actions keep their colour coding too (added 7/31) ----

   Open Issue Listing (I00270s) ends each ticket with View / Edit / Close.
   Same reasoning as the block above: three different actions, one of them
   destructive, all rendered in the same teal. Colour is the fastest way to
   tell them apart at a glance, and Close deserves to look different from a
   read-only View.

   THREE m-Power markup traps here, all of them load-bearing:

   1. View and Close carry IDENTICAL classes — both are a bare `a._lookup`.
      Only .edit distinguishes Edit. So the icon class is the discriminator,
      not the anchor.
   2. NO child combinator. View wraps its <i> in a bare <span> while Close
      puts the <i> straight in the <a> — the same inconsistency the 7/28
      notes record for the Consulting Request tile. `a._lookup > .fa-search`
      silently matches nothing.
   3. !important is required. Close ships an inline style="color:#e74c3c",
      which the `.table-content .fa[style*="color"]` normaliser above catches
      with !important. Without !important here, Close stays teal and the
      other two change, which looks like a partly-broken rule.

   Worth recording: the app's own inline colour for Close is #e74c3c, so it
   already intended red — our normalisation was overriding the app's intent.
   #bf0603 is used instead because #e74c3c is 3.66:1 on white against 6.48:1.

   Audited 7/31 across all 40 screens: `a._lookup` is on I00270s (12 links,
   the three combos above) and I00280s Closed Issue Listing (10 links: View
   plus Re-Open, `fa-folder-open`). View correctly picks up teal on both.
   Re-Open is deliberately left on the default accent — it has no obvious
   colour in this scheme and nobody has asked for one; revisit if it should
   read as a distinct action. All contrasts on a white card: teal 6.79:1,
   blue 8.24:1, red 6.48:1. */
#portal-body .card-body a._lookup .fa-search { color: var(--accent) !important; }
#portal-body .card-body a._lookup .fa-pencil-square { color: var(--btn-ink, #2046ae) !important; }
#portal-body .card-body a._lookup .fa-thumbs-up { color: #bf0603 !important; }

/* ---- legacy Bootstrap button variants (I00020s, I01300s, I00255s) ----
   btn-info / btn-warning / btn-danger were still rendering in the theme's
   cyan, amber and red. These are all secondary actions in practice, so they
   get the same quiet outline treatment as .btn-secondary in the forms. */
#portal-body .btn-info,
#portal-body .btn-warning,
#portal-body .btn-danger {
	background: #fff !important;
	border: 1px solid var(--line) !important;
	color: var(--accent-dk) !important;
	border-radius: 999px !important;
	font-weight: 600;
	text-transform: none !important;
	letter-spacing: normal !important;
	box-shadow: none !important;
}
#portal-body .btn-info:hover,
#portal-body .btn-warning:hover,
#portal-body .btn-danger:hover {
	border-color: var(--accent) !important;
	color: var(--accent) !important;
}

/* ---- runtime message banner ----
   Every app screen carries <div class="errortext1 alert alert-primary d-none">
   and reveals it on a validation or runtime error. It's hidden in the happy
   path, which is why it never showed up in a visual pass, but unstyled it
   would appear as Bootstrap's legacy blue panel the one time a customer
   actually hits an error. */
#portal-body .alert {
	border-radius: 14px !important;
	border: 1px solid var(--line) !important;
	background: var(--bg-soft, #f4f5f8) !important;
	color: var(--ink) !important;
	padding: 1rem 1.25rem !important;
}
#portal-body .alert-danger,
#portal-body .alert.errortext1 {
	border-color: #e8c4c0 !important;
	background: #fdf5f4 !important;
	color: #8a3730 !important;
}
/* Confirmation banners. Account Overview shows four of these depending on
   where you came from (?flag=profile, ?flag=cc, ?rvi_request=y, ?upload=y),
   and the neutral .alert base above rendered them as a flat grey bar you'd
   scroll straight past: bg #f4f5f8 against a #f4f5f8 page.

   Teal rather than green on purpose. mrc-2026.css has no success/positive
   token at all (the palette is ink / body / muted / line / accent / cyan /
   btn-ink), so a green here would be a colour invented for one component.
   The accent tokens read as affirmative, stay on-brand, and keep this
   clearly distinct from both the neutral base and the red error variant. */
#portal-body .alert-success {
	border-color: var(--accent, #006478) !important;
	background: var(--accent-tint, #e7f2f4) !important;
	color: var(--accent-dk, #00485a) !important;
}

/* The band these sit in is <div class="bg-gray text-center">, which kept the
   legacy #fafbfb while the page around it is #f4f5f8, leaving a faint seam
   above and below the banner. Same near-miss grey as the .push spacer.
   Keyed to .bg-gray.text-center, not bare .bg-gray: that class is also on the
   pagination buttons and on wrappers inside the white form card, and none of
   those carry .text-center.

   The band stays full-bleed (it only carries the background now, which
   matches the page) but gets a top pad so the banner isn't jammed against
   the breadcrumb bar, and 15px sides so the banner inside can line up with
   the content.

   The banner itself is capped at 1270px = the .container max-width of 1300px
   (set in style.css) minus its 2 x 15px padding. That is exactly the box the
   card grid occupies, so the banner's edges land on the outer card edges at
   any width: verified 15..1248 against cards 15..1248 at a 1278px viewport,
   and 308..1578 against 308..1577 at 1900px, where the 1px is sub-pixel
   rounding from dividing the 3-column grid. Without the cap the banner ran
   the full window width while the cards stayed centred at 1300. */
#portal-body .bg-gray.text-center {
	background: var(--portal-page-bg, #f4f5f8) !important;
	padding: 1.5rem 15px 0 !important;
}
#portal-body .bg-gray.text-center > .alert {
	max-width: 1270px;
	margin-left: auto;
	margin-right: auto;
}

/* the row summary ships inline font-size:20px, which ran well above the 16px
   meta line right above it and made the lists feel unfinished. Down to the
   1rem the rest of the portal body text uses. */
#portal-body .table-content span[style*="font-size:20px"] { font-size: 1rem !important; }

/* ============================================================
   MENU CARD GRIDS (CUSTPORTAL.I00001s-I00007s and the card grids on
   the inquiry screens). Each card is wrapped in an <a>, so the whole
   tile is the link.

   The legacy theme ships these as a flip card: a .card-body front plus
   an absolutely-positioned .card-hover panel (solid blue, opacity 0)
   that fades in over the top on hover. That effect reads as dated next
   to the 2026 pages, so it's retired here in favour of a lift + shadow,
   the same hover language the static site uses.
   ============================================================ */

/* the tile link itself: no underline, no inherited link colour */
#portal-body a:has(> .card) {
	display: block;
	text-decoration: none !important;
	color: inherit;
	border-radius: var(--radius, 22px);
}
#portal-body a:has(> .card):focus-visible {
	outline: 3px solid var(--accent);
	outline-offset: 3px;
}

/* height:100% belongs ONLY to the menu tiles, where equal-height cards in a
   row is the point. The inquiry screens reuse .hover-shadow-4 on content
   cards whose parent is full-page height, so stretching them there blew one
   ticket card up to ~2000px for ~90px of content. */
#portal-body a > .card { height: 100%; }
/* ...but height:100% resolves against the <a>, and the anchor ships inline
   with auto height, so it hugged its content and the cards in a row came out
   uneven (Main Menu: "Updates & Enhancements" and "Training" ran taller than
   their row-mates). Bootstrap's .row already stretches the columns; this just
   passes that height down through the anchor to the card. */
#portal-body [class*="col-"] > a:has(> .card) {
	display: block;
	height: 100%;
}
/* ...and the download tiles on I00350s are the exception the note above
   predicts. "Stable Release" is <a class="text-default"><div class="card
   border hover-shadow-5">, so height:100% stretched it to its column while
   its row-mate "Release Candidate" (not inside an <a>) stayed content-sized:
   250px against 175px for an icon and a date, which read as a layout bug.

   `a >` is what makes this safe. .hover-shadow-5 is also used on I00090s
   (999 cards) and I00140s (27), but on both the parent is a plain DIV, so
   this rule cannot reach them. Verified by DOM audit 7/31; only the 3
   download tiles match. Card is 202px after this. */
#portal-body a > .card.hover-shadow-5 { height: auto; }
/* the tile recipe's 1.9rem body padding and 1.2rem icon margin are tuned for
   a menu tile carrying a title and a description. These hold an icon and one
   date, so the same values left a band of dead space under the date. The
   icon goes display:block because as an inline-flex box it also picked up the
   line box's leading. */
#portal-body a > .card.hover-shadow-5 > .card-body { padding: 1.5rem 1.4rem; }
#portal-body a > .card.hover-shadow-5 > .card-body .fa {
	display: block;
	margin: 0 auto .5rem;
	line-height: 50px;
}
#portal-body a > .card.hover-shadow-5 > .card-body .row.mb-1 { margin-bottom: 0 !important; }

/* geometry and hover physics copied from .card-soft / .card-soft:hover in
   mrc-2026.css (the components-2026 reference card), so the portal tiles and
   the marketing site's cards behave identically. Was 16px / -3px / .18s /
   a shallower shadow, which read as a slightly different component. */
#portal-body a > .card,
#portal-body .card.hover-shadow-4 {
	background: #fff !important;
	border: 1px solid var(--line) !important;
	border-radius: var(--radius, 22px) !important;
	box-shadow: none !important;
	transition: transform .26s ease, box-shadow .26s ease, border-color .26s ease;
}
#portal-body a:hover > .card,
#portal-body a:focus-visible > .card {
	transform: translateY(-5px);
	box-shadow: 0 22px 46px rgba(15,30,45,.1) !important;
	border-color: #d8dde4 !important;
}

/* retire the legacy flip panel */
#portal-body .card .card-hover { display: none !important; }

/* tile contents */
#portal-body a > .card .card-body {
	padding: 1.9rem 1.4rem;
}
#portal-body a > .card .card-title,
#portal-body a > .card h5 {
	font-size: 1.05rem !important;
	font-weight: 600 !important;
	color: var(--ink) !important;
	letter-spacing: -0.01em;
	margin: 0 0 .4rem;
}
#portal-body a > .card p {
	font-size: .9rem;
	line-height: 1.5;
	color: var(--body) !important;
	margin: 0;
}
#portal-body a:hover > .card .card-title { color: var(--accent-dk) !important; }

/* the icon: normalise the size and sit it on a tinted disc.
   Descendant, not direct child: most tiles put the <i> straight in
   .card-body, but at least one (Consulting Request) wraps it in a bare
   <span>.

   REVISED 7/30: was keeping the app's own per-icon colour coding on a
   near-white #f4f5f8 disc. Two problems on screen: six unrelated hues (blue,
   green, grey, yellow, red, purple) against a teal design system read as clip
   art, and the disc was so close to the card's white that the icons looked
   like they were floating loose. Now one accent colour on a visible teal
   tint. The colour-coding argument was that it aids scanning, but the tiles
   are already distinguished by title and description, and the hues carried no
   consistent meaning.

   FIXED 7/30: this block was matching .fa only, so on the Main Menu it hit
   nothing. Those tiles use et-line, not Font Awesome:
   <i class="icon-adjustments lead-6 py-5">. Both families are matched now.
   The app's own .lead-6 (size) and .py-5 (padding) utilities are overridden
   below, which is why font-size and padding carry !important. */
#portal-body a > .card .card-body .fa,
#portal-body a > .card .card-body i[class*="icon-"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	/* size/shape/tint copied from .card-ico in mrc-2026.css: 50px, 14px
	   rounded square, not a circle. Only divergence is `margin: 0 auto`,
	   because the m-Power tile markup centres its contents while the
	   marketing cards are left-aligned. */
	width: 50px;
	height: 50px;
	margin: 0 auto 1.2rem;
	border-radius: 14px;
	background: var(--accent-tint, #e7f2f4);
	font-size: 1.3rem !important;
	padding: 0 !important;
	line-height: 1;
}
/* beats the app's text-primary / text-success / text-warning etc. utilities,
   which is the whole point of the revision. Covers the one tile that ships
   class="text" (app-side typo) as a side effect. */
#portal-body a > .card .card-body .fa,
#portal-body a > .card .card-body .fa.text,
#portal-body a > .card .card-body i[class*="icon-"] { color: var(--accent) !important; }
/* no icon hover state: .card-ico in the design system doesn't have one, and
   the card's own lift already answers the hover. */

/* the small italic group labels above each grid ("Find Answers",
   "Get Help") → the 2026 eyebrow treatment. They ship as a bare <em>
   inside a full-width column.

   :only-child is load-bearing, do NOT drop it. m-Power also emits prose
   in a bare <em> — the app description under .app-title, and the
   "Already signed up…" / "New to the Customer Portal?" lines on the two
   sign-up screens. Without the guard those matched too, and a 265-char
   instruction paragraph rendered as an 11.84px uppercase micro-label.
   Audited 2026-07-31 across all 40 CUSTPORTAL screens: the only real
   targets are the two labels on I00007s (Support Menu) and both are
   sole children of their column. Every false positive had siblings —
   including 10 on I00280s (Closed Issue Listing), a screen missing from the
   first pass, whose View / Re-Open action labels the ungated rule would have
   rendered as uppercase micro-labels. */
#portal-body .section .col-12 > em:only-child,
#portal-body .section [class*="col-"] > em:only-child {
	display: block;
	font-style: normal;
	text-transform: uppercase;
	letter-spacing: .06em;
	font-size: .74rem;
	font-weight: 700;
	color: var(--accent-dk);
	/* the top margin separates a group label from the grid above it;
	   .row.gap-y alone left them almost touching */
	margin: 1.75rem 0 .35rem;
}

/* the app description: m-Power emits it as a bare <em> immediately after
   .app-title, so it's a sibling, not an only child. Reads as the lead
   paragraph it actually is. 60ch keeps the 265-char sign-up copy off the
   full page width — it was running edge to edge outside the card. */
#portal-body .section .app-title ~ em {
	display: block;
	font-style: normal;
	max-width: 60ch;
	margin: .35rem auto 1.25rem;
	font-size: 1rem;
	line-height: 1.6;
	color: var(--body, #5b6470);
	text-align: center;
}

/* ============================================================
   DOCUMENTATION LAUNCHER (/mrcjava/docs, /mrcjava/docs/details)

   Portal-family page (body#portal-body + support-bg hero), but its own
   content markup: a .docbutton grid of .subdiv tiles, each an <a> with a
   fa-5x icon and a bare text label after a <br>, then a search band that
   posts through to the WordPress KnowAll manual at /docs/.

   NOTE: the articles themselves live at /docs/ on a separate WordPress +
   KnowAll install with no site navbar and no hero. Nothing in this file
   reaches them; skinning that KB is its own job.
   ============================================================ */

/* Deliberately do NOT change .docbutton's display. It is natively `inline`
   with `inline-block` .subdiv children; switching it to flex (and flattening
   its wrapper with display:contents) rewrote the layout model and left the
   search band overlapping the "Additional Documentation" lists below it.
   Styling the tiles alone leaves the surrounding flow untouched. */
#portal-body .subdiv {
	display: inline-block;
	vertical-align: top;
	width: 152px;
	margin: .5rem;
	/* the label is a bare text node after a <br>, so it can only be sized
	   from this container */
	font-size: .9rem;
	font-weight: 600;
	line-height: 1.35;
	color: var(--ink);
	text-align: center;
	background: #fff;
	border: 1px solid var(--line);
	border-radius: 16px;
	padding: 1.4rem .75rem 1.15rem;
	transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
#portal-body .subdiv:hover {
	transform: translateY(-3px);
	box-shadow: 0 14px 32px rgba(15,30,45,.10);
	border-color: #d8dde4;
}
/* the grid ships one genuinely empty <div class="subdiv"></div>, which would
   otherwise render as a blank tile */
#portal-body .subdiv:empty { display: none; }
#portal-body .subdiv a { display: block; text-decoration: none !important; }
#portal-body .subdiv a:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; border-radius: 12px; }

/* fa-5x is 5em; bring it back to the portal's icon-on-a-disc language */
#portal-body .subdiv .fa {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	margin-bottom: .8rem;
	border-radius: 50%;
	background: var(--bg-soft, #f4f5f8);
	color: var(--accent);
	font-size: 1.6rem !important;
	line-height: 1;
	transition: background-color .18s ease;
}
#portal-body .subdiv:hover .fa { background: var(--accent-tint, #e7f2f4); }
/* the <br> after the icon just adds dead space once the icon is a block */
#portal-body .subdiv br { display: none; }

/* search band. DEEPENED 7/31 PM (Steve: "the search bar kinda blends in
   with the background"): --bg-soft is 1.026 against the page, the same
   blend-failure value as the two card-header reports, so the white field
   had nothing to stand against. #e8eaee is the card-header neutral, 1.133
   vs the page, and a white field on it reads as a control. Reaches the
   same band on /mrcjava/docs/details.

   CONSTRAINED same session (Steve: "shouldn't span the entire window —
   same width as the section above it, same colour, rounded corners").
   The markup is .container-fluid, so full-bleed. NOT the Bootstrap 1140
   ladder: this template's .container caps at 1300px (style.css), and the
   visible content edges — the tile cards below, the text measure above —
   sit 15px inside it. 1270 centred lines the band's edges up with the
   tile edges at every width (verified at 1280 and 2560); calc(100% - 30px)
   keeps 15px side margins when the viewport is narrower than the cap.
   Radius on the 22px system. The border-top went with the full-bleed
   shape — a floating band separates by its own edge, and at 1.133 vs the
   page it needs no line. */
#portal-body .container-fluid.bg-secondary {
	background: #e8eaee !important;
	border-top: 0;
	border-radius: var(--radius, 22px);
	width: calc(100% - 30px);
	max-width: 1270px;
	margin-left: auto;
	margin-right: auto;
}
#portal-body #searchform .form-group.input-group {
	background: transparent !important;
	border: 0 !important;
	border-radius: 0 !important;
	box-shadow: none !important;
}
#portal-body #searchform input[type="text"],
#portal-body #searchform #s {
	font-size: .95rem !important;
	color: var(--ink);
	background: #fff !important;
	border: 1px solid #d6dbe3 !important;
	border-radius: 999px 0 0 999px !important;
	padding: .7rem 1.1rem !important;
	height: auto !important;
	box-shadow: none !important;
}
#portal-body #searchform input[type="text"]:focus,
#portal-body #searchform #s:focus {
	outline: none;
	border-color: var(--accent) !important;
	box-shadow: 0 0 0 3px rgba(0,100,120,.14) !important;
	position: relative;
	z-index: 2;
}
#portal-body #searchform .btn,
#portal-body #searchform button {
	background: var(--btn-ink, #2046ae) !important;
	border: 0 !important;
	color: #fff !important;
	border-radius: 0 999px 999px 0 !important;
	font-size: .9rem !important;
	font-weight: 600;
	text-transform: none !important;
	letter-spacing: normal !important;
	padding: .7rem 1.6rem !important;
	box-shadow: none !important;
}
#portal-body #searchform .btn:hover,
#portal-body #searchform button:hover { background: #183a94 !important; }
/* the markup splits the pill: <div class="input-group-append ml-4"> holds the
   Search button 16px off the field while both halves carry flat mating edges
   (999px 0 0 999px / 0 999px 999px 0). Bootstrap's .ml-4 utility ships
   !important, hence !important here. Same shape on /mrcjava/docs/details.
   (7/31 PM, Steve: "the search button should be attached to the bar") */
#portal-body #searchform .input-group-append {
	margin-left: 0 !important;
}
/* with the halves joined, the field's right border would double against the
   button's left edge; the button is borderless, so drop the field's */
#portal-body #searchform input[type="text"],
#portal-body #searchform #s { border-right: 0 !important; }

/* ---- docs HOME page (/mrcjava/docs) extras (7/31 PM, Steve) ----

   The "Documentation Listing" jump to the full manual rendered as the legacy
   grey slab (2px corners, uppercase). Quiet white outline pill, same recipe
   as the list-toolbar buttons: it's the secondary route on the page, the
   blue Search is the primary. The d-block.mx-auto pair is the gate — audited
   7/31 PM across both docs pages + the 35-screen CUSTPORTAL roster: this
   shape exists on the docs home page only. */
#portal-body a.btn-secondary.d-block.mx-auto {
	background: #fff !important;
	border: 1px solid var(--line) !important;
	color: var(--accent-dk, #00485a) !important;
	border-radius: 999px !important;
	font-size: .9rem !important;
	font-weight: 600;
	text-transform: none !important;
	letter-spacing: normal !important;
	padding: .8rem 1.4rem !important;
	box-shadow: none !important;
	transition: border-color .15s ease, color .15s ease;
}
#portal-body a.btn-secondary.d-block.mx-auto:hover,
#portal-body a.btn-secondary.d-block.mx-auto:focus {
	border-color: var(--accent) !important;
	color: var(--accent) !important;
}

/* ---- docs HOME page category tiles (7/31 PM, Steve: "the icon buttons
   don't really look like they're part of the interface") ----

   18 tiles of .card.b-1.hover-shadow-4 > .card-body > <a><i class="fa fa-5x">
   </a><br><strong>label</strong>. Same 64px flat-clipart problem the details
   page's .subdiv grid had; this is the .subdiv treatment (above) transplanted
   — 56px disc, --bg-soft fill, 1.6rem glyph, tint on hover, <br> dropped.
   Keep the two in sync.

   THE :has() GATE IS LOAD-BEARING: .card.hover-shadow-4 appears on 18
   CUSTPORTAL screens (menus, ticket lists, licence cards). Only the docs
   home tiles put a bare <a> around a bare icon as the card-body's first
   child (audited 7/31 PM, both docs pages + the roster).

   The anchor wraps ONLY the icon in the markup, so the label was dead space
   — the ::after overlay stretches the link across the whole card (the card
   is the positioning context). Focus ring drawn on the overlay so keyboard
   users see the whole tile ring, not just the icon. */
#portal-body .card.hover-shadow-4:has(> .card-body > a > .fa) {
	position: relative;
	transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
#portal-body .card.hover-shadow-4:has(> .card-body > a > .fa):hover {
	transform: translateY(-3px);
	box-shadow: 0 14px 32px rgba(15, 30, 45, .10);
	border-color: #d8dde4;
}
/* block, like .subdiv's anchor — inline, the disc sat on the same line as
   the label once the <br> was dropped. text-center on the row centres the
   inline-flex disc inside the block. */
#portal-body .card.hover-shadow-4 > .card-body > a:has(> .fa) { display: block; }
#portal-body .card.hover-shadow-4 > .card-body > a:has(> .fa)::after {
	content: "";
	position: absolute;
	inset: 0;
	border-radius: var(--radius, 22px);
}
#portal-body .card.hover-shadow-4 > .card-body > a:has(> .fa):focus-visible {
	outline: none;
}
#portal-body .card.hover-shadow-4 > .card-body > a:has(> .fa):focus-visible::after {
	outline: 3px solid var(--accent);
	outline-offset: 3px;
}
#portal-body .card.hover-shadow-4 > .card-body > a > .fa {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	margin-bottom: .8rem;
	border-radius: 50%;
	background: var(--bg-soft, #f4f5f8);
	color: var(--accent);
	font-size: 1.6rem !important;
	line-height: 1;
	transition: background-color .18s ease;
}
#portal-body .card.hover-shadow-4:has(> .card-body > a > .fa):hover .fa {
	background: var(--accent-tint, #e7f2f4);
}
#portal-body .card.hover-shadow-4 > .card-body > a:has(> .fa) + br { display: none; }
#portal-body .card.hover-shadow-4:has(> .card-body > a > .fa) .card-body strong {
	font-weight: 600;
	color: var(--ink);
}

/* ---- docs DETAILS page: "Additional Documentation" link columns (7/31 PM,
   Steve: "these pages don't really look like the new style at the bottom") ----

   Each category page ends in .feature-1 columns ("Basic Docs" / "Advanced
   Docs"): an h3 with a legacy-palette icon, then a <ul> carrying inline
   `list-style:disc` whose anchors WRAP the <li>s — invalid markup the
   parser keeps as ul > a > li, so the row styles ride on the anchor.
   Bullets + 30px indent + default blue links; now flush rows, accent-dk
   links, accent hover.

   Gate is .feature-1 (the docs template's column class) AND the inline
   list-style signature. ⚠️ The roster half of the 7/31 PM audit for this
   rule is VOID — the server restart killed the session and every CUSTPORTAL
   fetch bounced to the login page. The double gate is what makes shipping
   anyway acceptable: no CUSTPORTAL screen across three sessions of notes
   emits anchors-wrapping-bulleted-lis inside .feature-1. Re-run the audit
   next authenticated session.

   Data faults visible while styling, NOT fixable here (Rick/content list):
   several anchors ship href=" " (Messaging & Scheduled Tasks, General
   Troubleshooting on the landing state) and the list has duplicate rows. */
#portal-body .feature-1 > h3 .fa {
	color: var(--accent) !important;
	margin-right: .4rem;
}
#portal-body .feature-1 ul[style*="list-style"] {
	list-style: none !important;
	padding-left: 0 !important;
	margin: 0;
}
#portal-body .feature-1 ul[style*="list-style"] a {
	display: block;
	text-decoration: none !important;
	color: var(--accent-dk, #00485a);
	font-weight: 500;
}
#portal-body .feature-1 ul[style*="list-style"] li {
	display: block;
	padding: .4rem 0;
	color: inherit;
}
#portal-body .feature-1 ul[style*="list-style"] a:hover li,
#portal-body .feature-1 ul[style*="list-style"] a:focus li {
	color: var(--accent);
	text-decoration: underline;
}

/* ---- docs DETAILS page: video cards ----
   .card.b-1.d-block.text-center > iframe[200x200] + .card-body.bg-gray —
   a square 200px YouTube embed floating in a wider card over a grey title
   strip. The embed takes the card's full width at 16:9 (CSS beats the
   width/height attributes; display:block kills the inline gap under it),
   overflow:hidden rounds it into the card's 22px corners (safe here for
   the same reason as the I00350s accordion: the card holds only the embed
   and its title, nothing to clip), and the title strip goes white with
   the standard 600 title. Gate: d-block.text-center on a card with a
   DIRECT iframe child is this template's shape alone (same session-void
   caveat as above — the known iframe elsewhere, I00010s's e-learning
   video, sits in a rail column, not as a card's first child; verify next
   authenticated session). */
#portal-body .card.d-block.text-center:has(> iframe) { overflow: hidden; }
#portal-body .card.d-block.text-center > iframe {
	display: block;
	width: 100% !important;
	height: auto !important;
	aspect-ratio: 16 / 9;
	border: 0;
}
#portal-body .card.d-block.text-center:has(> iframe) > .card-body.bg-gray {
	background: #fff !important;
	border-top: 1px solid var(--line);
	padding: .9rem 1rem;
}
#portal-body .card.d-block.text-center:has(> iframe) .card-title {
	font-size: .98rem;
	font-weight: 600;
	color: var(--ink);
	margin: 0;
}

/* ============================================================
   LOGIN SCREEN (CUSTPORTAL.Login, body.login-page)
   Mirrors the .demo-card form kit in mrc-2026.css (the aw/trial-2026
   + aw/mpower-demo styling) so the portal sign-in matches the rest of
   the 2026 forms: white card, hairline border, float labels, blue
   pill submit. Values are copied from that kit deliberately — if it
   changes there, change it here too.

   !important appears where Bootstrap spacing utilities on the markup
   (.p-3, .p-2, .btn-lg) set their padding with !important, and where
   the login template's own inline <style> block loads after this file.
   ============================================================ */

/* same page-background token as the app screens, so login doesn't drift from
   the rest of the portal when that value is tuned */
body.login-page { background: var(--portal-page-bg, #f4f5f8) !important; }

/* the template's .py-5 computes to only 24px here, which crowded the card
   against the breadcrumb bar and left the footer riding up under the
   secondary buttons */
body.login-page .container.py-5 {
	padding-top: clamp(3rem, 6vw, 5rem) !important;
	/* +20px: the markup carries ~20px of its own offset above the card (the
	   anchor span + row), so equal padding leaves the block sitting high.
	   Matching the visual gap top and bottom is what centres it. */
	padding-bottom: calc(clamp(3rem, 6vw, 5rem) + 20px) !important;
}

/* the legacy sheet paints .login-box itself white with a gray glow, which
   renders as a second square panel behind the card. The card is the only
   surface we want. */
.login-box {
	background: transparent !important;
	box-shadow: none !important;
	padding: 0 !important;
}

/* the card */
.login-box .card {
	background: #fff !important;
	border: 1px solid var(--line) !important;
	border-radius: var(--radius, 22px) !important;
	box-shadow: 0 24px 60px rgba(20,45,80,.10) !important;
	padding: clamp(1.6rem, 3vw, 2.4rem);
}
.login-box .card-header,
.login-box .card-body {
	background: transparent !important;
	border: 0 !important;
	padding: 0 !important;
}
/* Restated WITH the #portal-body id: the generic card-header band rule above
   (`#portal-body .card > .card-header`, deepened to #e8aee-grey 7/31 PM)
   out-specifies the class-only rules and both painted the Welcome copy as a
   grey rounded band AND zeroed the 1.9rem margin that keeps the float-label
   chip clear of the subhead. This header is prose, not a band. Same
   declarations as the class-only rules; only the specificity is the point. */
#portal-body .login-box .card > .card-header {
	background: transparent !important;
	border: 0 !important;
	border-radius: 0 !important;
	padding: 0 !important;
	margin: 0 0 1.9rem !important;
}
/* a little more than the .demo-card's 1.4rem: the float-label chip sits
   ~9px above the first field and needs clearance from the subhead */
.login-box .card-header { margin-bottom: 1.9rem; text-align: left; }
.login-box .card-header h2 {
	font-size: 1.35rem !important;
	font-weight: 700;
	letter-spacing: -0.02em;
	color: var(--ink);
	margin: 0 0 .4rem !important;
}
.login-box .card-header h5 {
	font-size: .95rem;
	font-weight: 400;
	color: var(--body);
	margin: 0;
}

/* fields */
.mrc-login-form .form-group { position: relative; margin-bottom: 1.05rem; }
/* the legacy sheet gives .input-group its own 1px border at radius 2px, which
   drew a squared-off outline 1px outside each rounded field */
.mrc-login-form .input-group {
	display: block;
	position: relative;
	border: 0 !important;
	border-radius: 0 !important;
	background: transparent !important;
	box-shadow: none !important;
}
.mrc-login-form .form-control {
	width: 100%;
	box-sizing: border-box;
	font-family: inherit;
	font-size: .95rem !important;
	color: var(--ink);
	background: #fbfcfd !important;
	border: 1px solid #d6dbe3 !important;
	border-radius: 10px !important;
	padding: .68rem 2.6rem .68rem .9rem !important;
	height: auto !important;
	box-shadow: none !important;
	transition: border-color .15s ease, box-shadow .15s ease;
}
.mrc-login-form .form-control:focus {
	outline: none;
	border-color: var(--accent) !important;
	box-shadow: 0 0 0 3px rgba(0,100,120,.14) !important;
}
/* the template's trailing <i class="fa fa-2x"> sits inside the field */
.mrc-login-form .input-group > .fa {
	position: absolute;
	right: 14px;
	top: 50%;
	transform: translateY(-50%);
	font-size: 1rem !important;
	color: var(--muted);
	pointer-events: none;
}

/* Float labels. The template ships EMPTY <label> elements, so the caption
   comes from generated content keyed off the input id. Generated content is
   not a reliable accessible name — the field's accessible name still comes
   from its placeholder. Adding aria-label in the template would fix that
   properly; see the handoff notes. */
.mrc-login-form .form-group > label {
	position: absolute;
	top: -.55rem;
	left: 14px;
	/* must beat Bootstrap's .input-group .form-control:focus { z-index: 3 },
	   otherwise the focused field paints over the chip and shears it */
	z-index: 5;
	margin: 0;
	padding: 0 .4rem;
	background: #fff;
	border-radius: 4px;
	font-size: .72rem;
	font-weight: 600;
	line-height: 1.45;
	color: var(--accent-dk);
	opacity: 0;
	transform: translateY(4px);
	pointer-events: none;
	transition: opacity .15s ease, transform .15s ease;
}
.mrc-login-form .form-group:has(#mrcuser) > label::after { content: "Username"; }
.mrc-login-form .form-group:has(#mrcpswd) > label::after { content: "Password"; }
.mrc-login-form .form-group:has(:focus) > label,
.mrc-login-form .form-group:has(.form-control:not(:placeholder-shown)) > label {
	opacity: 1;
	transform: none;
}
@media (prefers-reduced-motion: reduce) {
	.mrc-login-form .form-group > label,
	.mrc-login-form .form-control { transition: none; }
}

/* validation message */
.mrc-login-form .errortext {
	display: block;
	color: #c2333f;
	font-size: .82rem;
	margin: 0 0 .6rem;
}
.mrc-login-form .errortext:empty { margin: 0; }

/* submit */
.mrc-login-form .btn.btn-success {
	display: block;
	width: 100%;
	font-family: inherit;
	font-size: 1rem;
	font-weight: 600;
	color: #fff !important;
	text-transform: none;
	letter-spacing: normal;
	background: var(--btn-ink, #2046ae) !important;
	border: 0 !important;
	border-radius: 999px !important;
	padding: .85rem 1.5rem !important;
	margin-top: .4rem !important;
	box-shadow: none !important;
	cursor: pointer;
	transition: background-color .18s ease, transform .18s ease;
}
.mrc-login-form .btn.btn-success:hover,
.mrc-login-form .btn.btn-success:focus {
	background: #183a94 !important;
	transform: translateY(-1px);
}

/* secondary actions under the card: quiet outline pills, not solid blocks */
.bot-btns .btn-mrc {
	background: #fff !important;
	color: var(--accent-dk) !important;
	border: 1px solid var(--line) !important;
	border-radius: 999px !important;
	box-shadow: none !important;
	font-size: .9rem;
	font-weight: 600;
	text-transform: none;
	letter-spacing: normal;
	padding: .7rem 1.2rem !important;
	transition: border-color .18s ease, color .18s ease;
}
.bot-btns .btn-mrc:hover,
.bot-btns .btn-mrc:focus {
	background: #fff !important;
	border-color: var(--accent) !important;
	color: var(--accent) !important;
}
