/* ==========================================================================
   utmTheme.css — UT Martin theme for Banner Extensibility / Page Builder
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
	/* --- Brand, identical to utm.edu ------------------------------------- */
	--utm-navy: #0b2341; /* site --utm-blue; PMS 289 */
	--utm-navy-rgb: 11, 35, 65; /* site --utm-blue-rgb */
	--utm-blue: var(--utm-navy); /* site's name, for portability */

	--utm-orange: #ff8200; /* site --utm-orange; PMS 151 */
	/* utm.edu declares 255,130,4 here and hard-codes #ff8204 / #ff8400 in a few
	   rules. That is drift -- #FF8200 is the published PMS 151 value. */
	--utm-orange-rgb: 255, 130, 0;

	/* Navy ramp -- local to this repo, no website equivalent */
	--utm-navy-700: #14355e; /* hover / pressed */
	--utm-navy-500: #1f497d; /* focus ring, info text */
	--utm-navy-100: #d9dee8; /* opaque border where alpha won't do */
	--utm-navy-050: #f0f4fb; /* callout fill */

	--utm-orange-600: #d66e00; /* hover on orange fills */
	--utm-orange-ink: #9a4600; /* site --utm-orange-on-light-aa, 6.5:1 */
	--utm-orange-on-light-aa: var(--utm-orange-ink); /* site's name */
	--utm-orange-050: #fff4e6; /* accent fill */

	/* --- Typography, from utm.edu ---------------------------------------- */
	--utm-body-font: "Montserrat", "Avenir Next", "Segoe UI", Arial, sans-serif;
	--utm-title-font: "Rokkitt", Georgia, serif;
	--utm-heading-font: var(--utm-body-font); /* utm.edu sets h1-h5 in the body font */
	--utm-letter-spacing: 0.04em; /* site body letter-spacing */
	--utm-web-font-size: 18px; /* site body font-size, opt-in -- see .utm-page--web-scale */
	--utm-web-line-height: 27px; /* site body line-height */

	/* --- Surfaces and text, from utm.edu --------------------------------- */
	--utm-surface: #ffffff; /* site --utm-surface */
	--utm-surface-soft: #f4f6f8; /* site --utm-surface-soft */
	--utm-text: var(--utm-navy); /* site --utm-text: body copy is navy */
	--utm-ink: var(--utm-text); /* this repo's earlier name */
	--utm-muted: #53657d; /* site --utm-muted, 6.0:1 on white */
	--utm-text-on-light: #1f1f1f; /* site --utm-text-on-light */
	--utm-text-on-dark: #ffffff; /* site --utm-text-on-dark */
	--utm-border: rgba(11, 35, 65, 0.12); /* site --utm-border, navy at 12% */

	/* --- Neutrals, from utm.edu ------------------------------------------ */
	--utm-smokey: #58595b; /* UT system Smokey, PMS 426 */
	--utm-smokey-dark: #333333;
	--utm-gray: #a7a9ac;
	--utm-gray-light: #f1f1f1;
	--utm-gray-ultralight: #fafafa;
	--utm-gray1: #f6f6f6;
	--utm-gray2: #e0e0e0;
	--utm-gray3: #cacaca;
	--utm-gray4: #b6b6b6;

	/* --- Links, from utm.edu --------------------------------------------- */
	--utm-globe: #006c93; /* site --utm-newblue / --utm-globe */
	--utm-link: var(--utm-globe); /* site --utm-text-blue, 5.9:1 on white */

	/* --- UT system secondary palette, from utm.edu -----------------------
	   Named accents, for charts, category chips and status variety on data
	   pages. Most are mid-tone: treat them as FILL colors and put navy or
	   white text on them -- do not assume any is safe as text on white. */
	--utm-limestone: #f0ede3;
	--utm-torch: #e65933;
	--utm-sunsphere: #fed535;
	--utm-eureka: #ebea64;
	--utm-switchgrass: #abc178;
	--utm-legacy: #579584;
	--utm-valley: #00746f;
	--utm-river: #517c96;
	--utm-summitt: #b9e1e2;
	--utm-robinegg: var(--utm-summitt); /* site declares both names */
	--utm-fountain: #2197a9;
	--utm-regalia: #754a7e;
	--utm-leconte: #8d2048;
	--utm-energy: #ee3e80;
	--utm-rock: var(--utm-gray);
	--utm-buckskin: #705550;

	/* --- Focus ------------------------------------------------------------
	   DEVIATION: utm.edu sets --a11y-focus-color to --utm-orange. On white
	   that ring is 2.5:1 and fails WCAG 2.2 SC 1.4.11 (3:1 for non-text).
	   The site itself swaps away from orange when the background demands it
	   (its dark-mode ring is #8ac8ff), so this keeps the site's geometry --
	   3px solid, 2px offset -- with a navy ring at 9.1:1 plus an orange halo
	   for brand. Override --utm-focus-color in one line to match the site
	   exactly if that is preferred. */
	--utm-focus-color: var(--utm-navy-500);
	--utm-focus-halo: rgba(var(--utm-orange-rgb), 0.35);
	--utm-focus-outline: 3px solid var(--utm-focus-color);
	--utm-focus-offset: 2px; /* site --a11y-focus-offset */

	/* --- Semantic --------------------------------------------------------
	   No website equivalent -- utm.edu has no form-status system. These are
	   the colors PBUI.showStatus already emits, kept so the classes and the
	   existing JS agree. */
	--utm-success-ink: #125a2a;
	--utm-success-bg: #eaf6ea;
	--utm-success-border: #b7d9b0;

	--utm-danger-ink: #8a1c1c;
	--utm-danger-bg: #fff5f5;
	--utm-danger-border: #f5c6cb;

	--utm-warning-ink: #856404;
	--utm-warning-bg: #fff3cd;
	--utm-warning-border: #ffc107;

	--utm-info-ink: var(--utm-navy-500);
	--utm-info-bg: var(--utm-navy-050);
	--utm-info-border: var(--utm-navy-100);

	/* --- Shape and rhythm ------------------------------------------------- */
	--utm-radius: 6px; /* containers; kept from this repo's inline styles */
	--utm-radius-btn: 2px; /* site button radius */
	--utm-radius-pill: 14px;
	/* Distance from the top of the viewport to the notice stack. Raise it
	   if Banner's application header overlaps the notices. */
	--utm-notice-top: 84px;
	--utm-gap: 16px;
	--utm-gap-sm: 10px;
	--utm-rule: 1px solid var(--utm-border);
}

/* --------------------------------------------------------------------------
   2. Typography

   DEVIATION: utm.edu loads Montserrat and Rokkitt as webfonts. This file does
   NOT fetch them. A Page Builder page runs inside authenticated Banner, where
   an external font request is an extra dependency that CSP or the network may
   block, and a blocked font means a silent fallback anyway. The stack below is
   the site's own declared fallback chain, so on a machine that already has
   Montserrat it matches exactly, and on a stock Windows box it renders in
   Segoe UI -- which is what Banner users see today. To opt in, either add
   `@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600&display=swap");`
   as the FIRST line of this file, or self-host the woff2 on the theme server
   and add an @font-face here. Do that only after checking Banner's CSP.

   DEVIATION: the site's 18px/27px body size is not applied by default. Banner
   pages are dense forms and tables, and scaling every existing page up 20%
   risks breaking table layouts. Add `.utm-page--web-scale` to opt a page in.
   -------------------------------------------------------------------------- */

.utm-page {
	font-family: var(--utm-body-font);
	letter-spacing: var(--utm-letter-spacing);
	line-height: 1.5; /* matches the site's 27/18 ratio */
	color: var(--utm-text);
}

.utm-page--web-scale {
	font-size: var(--utm-web-font-size);
	line-height: var(--utm-web-line-height);
}

/* Headings, matching utm.edu: body font, navy, 110% line-height, 600 weight
   (h1 is 400 on the site). Scoped to .utm-page so Banner's chrome is safe. */
.utm-page h1,
.utm-page h2,
.utm-page h3,
.utm-page h4,
.utm-page h5 {
	font-family: var(--utm-heading-font);
	color: var(--utm-navy);
	line-height: 110%;
	font-style: normal;
}

.utm-page h1 {
	font-size: 38px;
	font-weight: 400;
	margin: 34px 0;
}

.utm-page h2 {
	font-size: 34px;
	font-weight: 600;
	margin: 34px 0;
}

.utm-page h3 {
	font-size: 24px;
	font-weight: 600;
}

.utm-page h4 {
	font-size: 20px;
	font-weight: 600;
	margin: 27px 0;
}

.utm-page h5 {
	font-size: 18px;
	font-weight: 600;
	line-height: 22px;
	letter-spacing: var(--utm-letter-spacing);
}

/* The site's display face. Decorative only -- never for body copy or labels,
   and it falls back to Georgia unless Rokkitt is actually loaded. */
.utm-title-font {
	font-family: var(--utm-title-font);
}

/* Links, matching utm.edu's [role="main"] a treatment. */
.utm-page a,
.utm-link {
	color: var(--utm-link);
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 3px;
	word-break: break-word;
}

.utm-page a:hover,
.utm-link:hover {
	color: var(--utm-navy);
}

/* --------------------------------------------------------------------------
   3. Focus — site geometry, contrast-safe color. See the token note above.
   -------------------------------------------------------------------------- */

.utm-page :focus-visible,
.utm-input:focus-visible,
.utm-select:focus-visible,
.utm-textarea:focus-visible {
	outline: var(--utm-focus-outline);
	outline-offset: var(--utm-focus-offset);
	box-shadow: 0 0 0 5px var(--utm-focus-halo);
}

/* --------------------------------------------------------------------------
   4. Page shell
   -------------------------------------------------------------------------- */

/* Navy banner with the orange rule under it — the UTM signature. */
.utm-page-header {
	background: var(--utm-navy);
	color: var(--utm-text-on-dark);
	border-bottom: 4px solid var(--utm-orange);
	padding: 18px 20px;
	margin-bottom: var(--utm-gap);
}

.utm-page .utm-page-header h1,
.utm-page .utm-page-header h2,
.utm-page-header .utm-page-title {
	color: var(--utm-text-on-dark);
	margin: 0;
	font-size: 1.35em;
	line-height: 1.3;
	font-weight: 600;
}

.utm-page-header .utm-page-subtitle {
	margin: 6px 0 0;
	font-size: 0.95em;
	color: #d9dee8;
}

/* Lighter alternative: title over an orange rule, no navy block. */
.utm-page .utm-section-title,
.utm-section-title {
	margin: 0 0 var(--utm-gap-sm);
	padding-bottom: 6px;
	border-bottom: 3px solid var(--utm-orange);
	color: var(--utm-navy);
	font-size: 1.1em;
	font-weight: 600;
	line-height: 1.3;
}

.utm-card {
	background: var(--utm-surface);
	border: var(--utm-rule);
	border-radius: var(--utm-radius);
	padding: var(--utm-gap) 20px;
	margin-bottom: var(--utm-gap);
}

/* --------------------------------------------------------------------------
   5. PBUI helper equivalents
   Each class reproduces the inline style the matching window.PBUI method emits
   today, so a page can drop the inline style attribute and use the class.
   -------------------------------------------------------------------------- */

/* PBUI.callout(title, body) */
.utm-callout {
	background: var(--utm-navy-050);
	border-left: 4px solid var(--utm-navy-500);
	padding: var(--utm-gap) 20px;
	margin-bottom: var(--utm-gap);
}

.utm-callout > p {
	margin: 0 0 8px;
}

.utm-callout > p:last-child {
	margin-bottom: 0;
}

.utm-callout__title {
	margin: 0 0 8px;
	font-weight: 600;
}

/* Orange-edged variant for "read this first" content. */
.utm-callout--accent {
	background: var(--utm-orange-050);
	border-left-color: var(--utm-orange);
}

/* PBUI.sectionInfo(content) */
.utm-section-info {
	margin-bottom: var(--utm-gap-sm);
	font-size: 0.95em;
}

/* PBUI.footer(lines) */
.utm-footer {
	margin-top: var(--utm-gap);
	padding: 12px var(--utm-gap);
	border-top: var(--utm-rule);
	font-size: 0.9em;
	color: var(--utm-muted);
}

.utm-footer p {
	margin: 0 0 4px;
}

.utm-footer p:last-child {
	margin-bottom: 0;
}

/* PBUI.errorBlock(message) — amber load-failure box, the noData_BLOCK look */
.utm-error-block {
	background: var(--utm-warning-bg);
	border: 1px solid var(--utm-warning-border);
	border-radius: var(--utm-radius);
	padding: var(--utm-gap) 20px;
	color: var(--utm-warning-ink);
	margin: var(--utm-gap) 0;
}

/* PBUI.showStatus(type, message) — target is #pbid-statusNotice span.
   The :empty rule collapses the bar before the first message, which removes
   the need for the inline display:block / removeAttribute('style') dance. */
.utm-status {
	display: block;
	padding: var(--utm-gap-sm) 12px;
	border-radius: var(--utm-radius);
	background: var(--utm-surface-soft);
	border: var(--utm-rule);
	color: var(--utm-info-ink);
	/* Legacy inline status box. PBUI's own messages now go to the fixed notice
	   stack (.utm-notice-area, below); this class stays for pages that keep an
	   inline #pbid-statusNotice span -- every page not yet migrated. These resets
	   stop it inheriting typography from whatever wrapper it sits in -- Page
	   Builder puts a component's `style` classes on #pbid-<name>-container. */
	text-transform: none;
	letter-spacing: var(--utm-letter-spacing);
	font-weight: 400;
	font-size: 0.95em;
	text-align: left;
	line-height: 1.5;
	cursor: auto;
}

.utm-status:empty {
	display: none;
}

.utm-status--success {
	color: var(--utm-success-ink);
}
.utm-status--error {
	color: var(--utm-danger-ink);
}
.utm-status--warning {
	color: #6b4f00;
}
.utm-status--info {
	color: var(--utm-info-ink);
}

/* Filled variants, when an inline message needs more weight than coloured text
   on a grey bar. */
.utm-status--filled.utm-status--success {
	background: var(--utm-success-bg);
	border-color: var(--utm-success-border);
}
.utm-status--filled.utm-status--error {
	background: var(--utm-danger-bg);
	border-color: var(--utm-danger-border);
}
.utm-status--filled.utm-status--warning {
	background: var(--utm-warning-bg);
	border-color: var(--utm-warning-border);
}
.utm-status--filled.utm-status--info {
	background: var(--utm-info-bg);
	border-color: var(--utm-info-border);
}

/* --------------------------------------------------------------------------
   Notice area — a fixed, page-independent stack of dismissible messages.

   PBUI creates #utmNoticeArea on first use and appends it to <body>, so a page
   needs NO markup for this: copy this block plus the notice/dismiss functions
   from JSUTILS into any project and it works.

   It replaced an inline status bar that lived in the page flow near the top of
   the page. A message raised by a form further down was simply never seen, and
   both attempts to fix that in place (scrolling the page to the bar, then
   moving the bar next to the clicked component) were working around a notice
   that was in the wrong place to begin with.

   The area sits OUTSIDE .utm-page, so it sets its own font and focus ring
   rather than inheriting the theme's.
   -------------------------------------------------------------------------- */

.utm-notice-area {
	position: fixed;
	top: var(--utm-notice-top);
	left: 50%;
	transform: translateX(-50%);
	z-index: 2000;
	display: flex;
	/* column-reverse: the first notice sits at the bottom and later ones stack
	   above it, nearest the top of the screen. Change to `column` to put the
	   newest at the bottom instead -- it is the only line that decides. */
	flex-direction: column-reverse;
	gap: 8px;
	width: max-content;
	max-width: min(560px, calc(100vw - 32px));
	max-height: calc(100vh - var(--utm-notice-top) - 24px);
	overflow-y: auto;
	/* The area is as wide as its widest notice, but must never swallow clicks
	   on the page behind it -- only the notices themselves are interactive. */
	pointer-events: none;
	font-family: var(--utm-body-font);
	letter-spacing: var(--utm-letter-spacing);
	line-height: 1.5;
	text-align: left;
}

.utm-notice {
	pointer-events: auto;
	display: flex;
	align-items: flex-start;
	gap: 10px;
	padding: 10px 12px;
	border: 1px solid var(--utm-border);
	border-left-width: 4px;
	border-radius: var(--utm-radius);
	background: var(--utm-surface);
	color: var(--utm-text);
	box-shadow: 0 12px 32px rgba(var(--utm-navy-rgb), 0.28);
	font-size: 0.95em;
	font-weight: 400;
	text-transform: none;
}

.utm-notice__body {
	flex: 1 1 auto;
	min-width: 0;
}

.utm-notice__body p:first-child {
	margin-top: 0;
}

.utm-notice__body p:last-child {
	margin-bottom: 0;
}

.utm-notice__close {
	flex: 0 0 auto;
	appearance: none;
	background: transparent;
	border: 0;
	margin: 0;
	padding: 0 2px;
	font: inherit;
	line-height: 1.2;
	color: inherit;
	opacity: 0.6;
	cursor: pointer;
}

.utm-notice__close:hover {
	opacity: 1;
}

/* The area is outside .utm-page, so the theme's focus rule does not reach it. */
.utm-notice__close:focus-visible {
	outline: var(--utm-focus-outline);
	outline-offset: 2px;
	opacity: 1;
}

.utm-notice--success {
	background: var(--utm-success-bg);
	border-color: var(--utm-success-border);
	border-left-color: var(--utm-success-ink);
	color: var(--utm-success-ink);
}

.utm-notice--error {
	background: var(--utm-danger-bg);
	border-color: var(--utm-danger-border);
	border-left-color: var(--utm-danger-ink);
	color: var(--utm-danger-ink);
}

.utm-notice--warning {
	background: var(--utm-warning-bg);
	border-color: var(--utm-warning-border);
	border-left-color: var(--utm-warning-ink);
	color: var(--utm-warning-ink);
}

.utm-notice--info {
	background: var(--utm-info-bg);
	border-color: var(--utm-info-border);
	border-left-color: var(--utm-navy-500);
	color: var(--utm-info-ink);
}

/* Opt IN to motion: the reduced-motion guard further down is scoped to
   .utm-page, which this area sits outside of. */
@media (prefers-reduced-motion: no-preference) {
	.utm-notice {
		animation: utm-notice-in 140ms ease-out;
	}
}

@keyframes utm-notice-in {
	from {
		opacity: 0;
		transform: translateY(-4px);
	}
	to {
		opacity: 1;
		transform: none;
	}
}

@media print {
	.utm-notice-area {
		display: none !important;
	}
}

/* PBUI.authBadge(authorized, dateExpr) */
.utm-badge-row {
	padding: 8px 0 6px;
}

.utm-badge {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 4px 12px;
	border-radius: var(--utm-radius-pill);
	font-size: 0.9em;
	border: 1px solid transparent;
}

.utm-badge__icon {
	font-weight: bold;
}

.utm-badge--yes {
	background: var(--utm-success-bg);
	border-color: var(--utm-success-border);
	color: var(--utm-success-ink);
}

.utm-badge--yes .utm-badge__icon {
	color: var(--utm-success-ink);
}

.utm-badge--no {
	background: var(--utm-danger-bg);
	border-color: var(--utm-danger-border);
	color: var(--utm-danger-ink);
}

.utm-badge--no .utm-badge__icon {
	color: var(--utm-danger-ink);
}

.utm-badge--pending {
	background: var(--utm-warning-bg);
	border-color: var(--utm-warning-border);
	color: var(--utm-warning-ink);
}

.utm-badge--neutral {
	background: var(--utm-navy-050);
	border-color: var(--utm-navy-100);
	color: var(--utm-navy-500);
}

/* Running tally / inline count line (the utmNoShow rosterTally pattern) */
.utm-tally {
	padding: var(--utm-gap-sm) 12px;
	border-radius: var(--utm-radius);
	margin: 12px 0;
	background: #eef6ef;
	border: 1px solid #cfe3d2;
	color: var(--utm-success-ink);
}

.utm-tally--flagged {
	background: var(--utm-warning-bg);
	border-color: var(--utm-warning-border);
	color: var(--utm-warning-ink);
}

/* --------------------------------------------------------------------------
   6. Tables

   DEVIATION: utm.edu has no data-table styling to align with -- it is a
   marketing site. These follow the brand (navy header, orange rule) but the
   density is this repo's, sized for Banner rosters rather than web content.
   -------------------------------------------------------------------------- */

.utm-table {
	width: 100%;
	border-collapse: collapse;
	font-size: 0.95em;
	margin-bottom: var(--utm-gap);
}

.utm-table caption {
	text-align: left;
	font-weight: 600;
	color: var(--utm-navy);
	padding-bottom: 6px;
}

.utm-table th {
	text-align: left;
	padding: 8px var(--utm-gap-sm);
	background: var(--utm-navy);
	color: var(--utm-text-on-dark);
	font-weight: 600;
	border-bottom: 3px solid var(--utm-orange);
}

.utm-table td {
	padding: 8px var(--utm-gap-sm);
	border-bottom: var(--utm-rule);
	vertical-align: top;
}

.utm-table tbody tr:nth-child(even) td {
	background: var(--utm-surface-soft);
}

.utm-table--plain th {
	background: transparent;
	color: var(--utm-navy);
	border-bottom: 2px solid var(--utm-border);
}

.utm-table--plain tbody tr:nth-child(even) td {
	background: transparent;
}

.utm-table__num {
	text-align: right;
	font-variant-numeric: tabular-nums;
}

/* Borderless label/value list — the "padding:4px 0" detail tables in
   titleivauth, utmLostCard and CPOS. */
.utm-kv {
	width: 100%;
	border-collapse: collapse;
}

.utm-kv th {
	text-align: left;
	padding: 4px 0;
	font-weight: 600;
	width: 40%;
	background: transparent;
	color: inherit;
	border: 0;
}

.utm-kv td {
	padding: 4px 0;
	color: var(--utm-muted);
	border: 0;
}

/* --------------------------------------------------------------------------
   7. Buttons

   Aligned to utm.edu's button treatment: body font, 600 weight, uppercase,
   letter-spaced, 2px radius. The site's own `a.button` also forces
   min-width:300px and 2.5em padding -- those are hero-CTA dimensions and are
   deliberately not copied into a form app.

   Two ways these classes reach a button, and both are handled:

     * on the element itself -- <button class='utm-btn utm-btn--primary'> in a
       literal's HTML, or in preview.html;
     * on a Page Builder BUTTON COMPONENT's `style`. There Page Builder puts the
       classes on the wrapper #pbid-<name>-container, NOT on the <button>. Styling
       `.utm-btn` directly painted that wrapper navy while the real button inside
       kept Page Builder's own grey look -- a grey button on a navy slab, which is
       what shipped first. So every rule below targets the element form
       (button.X, a.X) or the button INSIDE the wrapper (.X > button), and the
       wrapper itself is never painted.

   `:not(#\#)` matches every element (nothing has the id "#") but counts as an
   ID selector for specificity. It lets the wrapped-button rules beat pbDefault's
   own button rules -- which live in Banner and cannot be read from here --
   without resorting to !important.

   The [disabled] rules cover PBUI.acquire()/release(), which sets the disabled
   property on every button on the page.
   -------------------------------------------------------------------------- */

button.utm-btn,
a.utm-btn,
.utm-btn:not(#\#) > button {
	display: inline-block;
	padding: 9px 18px;
	border-radius: var(--utm-radius-btn);
	border: 2px solid transparent;
	background: var(--utm-surface);
	color: var(--utm-navy);
	box-shadow: none;
	font-family: var(--utm-body-font);
	font-size: 13px;
	font-weight: 600;
	letter-spacing: var(--utm-letter-spacing);
	text-transform: uppercase;
	line-height: 1.4;
	cursor: pointer;
	text-decoration: none;
}

/* Opt out of uppercase where a label is long or contains a name or ID that
   must stay readable — uppercase hurts legibility past a few words. */
button.utm-btn--sentence,
a.utm-btn--sentence,
.utm-btn--sentence:not(#\#) > button {
	text-transform: none;
	font-size: 0.95em;
	letter-spacing: normal;
}

.utm-btn + .utm-btn {
	margin-left: 8px;
}

/* Navy with white text: 15.8:1. */
button.utm-btn--primary,
a.utm-btn--primary,
.utm-btn--primary:not(#\#) > button {
	background: var(--utm-navy);
	border-color: var(--utm-navy);
	color: var(--utm-text-on-dark);
}

button.utm-btn--primary:hover,
a.utm-btn--primary:hover,
.utm-btn--primary:not(#\#) > button:hover {
	background: var(--utm-navy-700);
	border-color: var(--utm-navy-700);
	color: var(--utm-text-on-dark);
}

/* The site's "clear" button: transparent, navy outline, fills navy on hover. */
button.utm-btn--secondary,
a.utm-btn--secondary,
.utm-btn--secondary:not(#\#) > button {
	background: var(--utm-surface);
	border-color: var(--utm-navy);
	color: var(--utm-navy);
}

button.utm-btn--secondary:hover,
a.utm-btn--secondary:hover,
.utm-btn--secondary:not(#\#) > button:hover {
	background: var(--utm-navy);
	border-color: var(--utm-navy);
	color: var(--utm-text-on-dark);
}

/* Orange on navy is 6.3:1. Never orange background with white text. */
button.utm-btn--accent,
a.utm-btn--accent,
.utm-btn--accent:not(#\#) > button {
	background: var(--utm-orange);
	border-color: var(--utm-orange);
	color: var(--utm-navy);
}

button.utm-btn--accent:hover,
a.utm-btn--accent:hover,
.utm-btn--accent:not(#\#) > button:hover {
	background: var(--utm-orange-600);
	border-color: var(--utm-orange-600);
	color: var(--utm-navy);
}

/* White on #8a1c1c: 9.3:1. */
button.utm-btn--danger,
a.utm-btn--danger,
.utm-btn--danger:not(#\#) > button {
	background: var(--utm-danger-ink);
	border-color: var(--utm-danger-ink);
	color: var(--utm-text-on-dark);
}

button.utm-btn--link,
a.utm-btn--link,
.utm-btn--link:not(#\#) > button {
	background: transparent;
	border-color: transparent;
	color: var(--utm-link);
	text-transform: none;
	letter-spacing: normal;
	font-size: 0.95em;
	text-decoration: underline;
	text-decoration-thickness: 2px;
	text-underline-offset: 3px;
	padding-left: 4px;
	padding-right: 4px;
}

button.utm-btn:focus-visible,
a.utm-btn:focus-visible,
.utm-btn:not(#\#) > button:focus-visible {
	outline: var(--utm-focus-outline);
	outline-offset: var(--utm-focus-offset);
	box-shadow: 0 0 0 5px var(--utm-focus-halo);
}

/* Disabled: muted, but still 6.5:1 (#3f4c5e on --utm-navy-100) so the
   label stays readable. No opacity -- opacity took the text below AA. */
button.utm-btn[disabled],
a.utm-btn[disabled],
.utm-btn:not(#\#) > button[disabled],
button.utm-btn[disabled]:hover,
a.utm-btn[disabled]:hover,
.utm-btn:not(#\#) > button[disabled]:hover {
	cursor: not-allowed;
	background: var(--utm-navy-100);
	border-color: var(--utm-navy-100);
	color: #3f4c5e;
}

.utm-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: center;
	margin: var(--utm-gap) 0;
}

/* --------------------------------------------------------------------------
   8. Form controls
   -------------------------------------------------------------------------- */

.utm-field {
	margin-bottom: 12px;
}

/* Page Builder field components (text, number, email, tel, datetime, textArea,
   select, radio, boolean, display) carry style: "utm-field" on the component
   itself, and the theme reaches their label and control from here.

   The `style` attribute is the only class hook used. Page Builder also
   documents labelStyle and valueStyle, but no page in this repo ships either,
   and using them coincided with a page failing to render at all. A descendant
   selector needs no unproven attribute and does the same job. Everything below
   is scoped under .utm-field, so none of it can reach Banner's own chrome. */
.utm-field label {
	display: block;
	margin-bottom: 4px;
	font-weight: 600;
	color: var(--utm-navy);
}

.utm-field input[type="text"],
.utm-field input[type="email"],
.utm-field input[type="tel"],
.utm-field input[type="number"],
.utm-field input[type="date"],
.utm-field input[type="datetime-local"],
.utm-field input:not([type]),
.utm-field select,
.utm-field textarea {
	padding: 7px 10px;
	border: 1px solid var(--utm-gray3);
	border-radius: var(--utm-radius-btn);
	background: var(--utm-surface);
	color: var(--utm-text);
	font-family: var(--utm-body-font);
	font-size: 0.95em;
	max-width: 100%;
}

.utm-field textarea {
	width: 100%;
	min-height: 90px;
}

.utm-field input[disabled],
.utm-field select[disabled],
.utm-field textarea[disabled],
.utm-field input[readonly],
.utm-field textarea[readonly] {
	background: var(--utm-surface-soft);
	color: var(--utm-muted);
	cursor: not-allowed;
}

/* Checkboxes and radios keep their native box; only the spacing is ours. */
.utm-field input[type="checkbox"],
.utm-field input[type="radio"] {
	margin-right: 6px;
}

.utm-field input[type="checkbox"] + label,
.utm-field input[type="radio"] + label,
.utm-field label input[type="checkbox"],
.utm-field label input[type="radio"] {
	display: inline-block;
	font-weight: 400;
	color: inherit;
}

.utm-label {
	display: block;
	margin-bottom: 4px;
	font-weight: 600;
	color: var(--utm-navy);
}

.utm-input,
.utm-select,
.utm-textarea {
	padding: 7px 10px;
	border: 1px solid var(--utm-gray3);
	border-radius: var(--utm-radius-btn);
	background: var(--utm-surface);
	color: var(--utm-text);
	font-family: var(--utm-body-font);
	font-size: 0.95em;
	max-width: 100%;
}

.utm-textarea {
	width: 100%;
	min-height: 90px;
}

.utm-input[disabled],
.utm-select[disabled],
.utm-textarea[disabled] {
	background: var(--utm-surface-soft);
	color: var(--utm-muted);
	cursor: not-allowed;
}

.utm-input--invalid,
.utm-select--invalid {
	border-color: var(--utm-danger-ink);
	background: var(--utm-danger-bg);
}

.utm-help {
	display: block;
	margin-top: 4px;
	font-size: 0.875em;
	color: var(--utm-muted);
}

.utm-help--error {
	color: var(--utm-danger-ink);
}

.utm-required::after {
	content: " *";
	color: var(--utm-danger-ink);
}

/* Checkbox rows (the utmNoShow roster). The ngGrid transform below is the
   Chrome/Firefox checkbox-sizing fix documented in pagebuilder.md. */
.utm-check-row {
	display: flex;
	align-items: center;
	gap: var(--utm-gap-sm);
	padding: 6px 8px;
	border-bottom: var(--utm-rule);
}

.utm-check-row:hover {
	background: var(--utm-navy-050);
}

.ngGrid input[type="checkbox"] {
	-webkit-transform: scale(1, 0.6);
	-moz-transform: scale(1.4);
	transform: scale(1, 0.6);
}

/* --------------------------------------------------------------------------
   9. Accent chips — the UT system secondary palette as usable classes.
   Every one puts navy or white text on the fill, chosen for contrast; none
   of these colors is safe as text on white.
   -------------------------------------------------------------------------- */

.utm-chip {
	display: inline-block;
	padding: 3px 10px;
	border-radius: var(--utm-radius-pill);
	font-size: 0.85em;
	font-weight: 600;
	letter-spacing: var(--utm-letter-spacing);
	background: var(--utm-limestone);
	color: var(--utm-navy);
}

.utm-chip--limestone {
	background: var(--utm-limestone);
	color: var(--utm-navy);
}
.utm-chip--summitt {
	background: var(--utm-summitt);
	color: var(--utm-navy);
}
.utm-chip--sunsphere {
	background: var(--utm-sunsphere);
	color: var(--utm-navy);
}
.utm-chip--eureka {
	background: var(--utm-eureka);
	color: var(--utm-navy);
}
.utm-chip--switchgrass {
	background: var(--utm-switchgrass);
	color: var(--utm-navy);
}
.utm-chip--rock {
	background: var(--utm-rock);
	color: var(--utm-navy);
}
.utm-chip--torch {
	background: var(--utm-torch);
	color: var(--utm-navy);
}
.utm-chip--legacy {
	background: var(--utm-legacy);
	color: var(--utm-navy);
}
.utm-chip--valley {
	background: var(--utm-valley);
	color: var(--utm-text-on-dark);
}
.utm-chip--globe {
	background: var(--utm-globe);
	color: var(--utm-text-on-dark);
}
.utm-chip--river {
	background: var(--utm-river);
	color: var(--utm-text-on-dark);
}
.utm-chip--fountain {
	background: var(--utm-fountain);
	color: var(--utm-navy);
}
.utm-chip--regalia {
	background: var(--utm-regalia);
	color: var(--utm-text-on-dark);
}
.utm-chip--leconte {
	background: var(--utm-leconte);
	color: var(--utm-text-on-dark);
}
.utm-chip--energy {
	background: var(--utm-energy);
	color: var(--utm-navy);
}
.utm-chip--buckskin {
	background: var(--utm-buckskin);
	color: var(--utm-text-on-dark);
}
.utm-chip--smokey {
	background: var(--utm-smokey);
	color: var(--utm-text-on-dark);
}

/* --------------------------------------------------------------------------
   10. Layout utilities — deliberately few. Prefer a named component class.
   -------------------------------------------------------------------------- */

.utm-grid-2 {
	display: flex;
	flex-wrap: wrap;
	gap: var(--utm-gap);
}

.utm-grid-2 > * {
	flex: 1 1 280px;
	min-width: 0;
}

/* .utm-muted is the class; --utm-muted is the token. CSS keeps classes and
   custom properties in separate namespaces, so both names can coexist. */
.utm-muted,
.utm-muted-text {
	color: var(--utm-muted);
}
/* The only safe way to set orange-toned TEXT on a light background. Do not
   substitute --utm-orange here; it is 2.5:1 on white and fails WCAG AA. */
.utm-accent-text {
	color: var(--utm-orange-ink);
}
.utm-strong {
	font-weight: 600;
}
.utm-nowrap {
	white-space: nowrap;
}
.utm-mt-0 {
	margin-top: 0;
}
.utm-mb-0 {
	margin-bottom: 0;
}
.utm-hidden {
	display: none;
}

/* Visible to screen readers only. Byte-for-byte the site's own .sr-only,
   renamed to stay out of Banner's namespace. */
.utm-sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* --------------------------------------------------------------------------
   11. Print — these pages get printed (rosters, confirmations, hold letters).
   -------------------------------------------------------------------------- */

@media print {
	.utm-btn,
	.utm-actions,
	.utm-no-print,
	.utm-page-header .utm-page-subtitle {
		display: none !important;
	}

	.utm-page-header {
		background: none;
		color: #000000;
		border-bottom: 2px solid #000000;
		padding: 0 0 8px;
	}

	.utm-page .utm-page-header h1,
	.utm-page .utm-page-header h2,
	.utm-page-header .utm-page-title {
		color: #000000;
	}

	.utm-table th {
		background: none;
		color: #000000;
		border-bottom: 2px solid #000000;
	}

	.utm-table td,
	.utm-table tbody tr:nth-child(even) td {
		background: none;
	}

	.utm-callout,
	.utm-card,
	.utm-error-block,
	.utm-status,
	.utm-chip {
		border: 1px solid #000000;
		background: none;
		color: #000000;
	}

	.utm-table {
		page-break-inside: auto;
	}

	.utm-table tr {
		page-break-inside: avoid;
	}
}

/* --------------------------------------------------------------------------
   12. Motion — utm.edu carries the same reduced-motion guard.

   DEVIATION: no dark-mode block. utm.edu defines one (its dark tokens include
   --utm-accent-text #ffbd75 and --utm-focus-ring #8ac8ff), but Banner
   Self-Service has no dark theme, so a dark Page Builder page would be an
   island of dark inside light Banner chrome. The site's dark values are
   recorded here in case that ever changes.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	.utm-page *,
	.utm-btn {
		transition: none !important;
		animation: none !important;
	}
}

/* --------------------------------------------------------------------------
   13. Reports — filter bars, tabs, stat tiles, bars and distributions.

   The markup comes from the reports module (JSUTILS_REPORTS): stat, statGrid,
   bar, distribution, legend, table, loading. Tabs are Page Builder BUTTON
   components with style "utm-tab" ("utm-tab utm-tab--active" for the open one),
   inside a block with style "utm-tabbar"; like every button class, the rules
   target the <button> inside the #pbid-<name>-container wrapper.
   -------------------------------------------------------------------------- */

.utm-toolbar {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: var(--utm-gap-sm) var(--utm-gap);
	padding: 14px 18px;
	margin-bottom: var(--utm-gap);
	background: var(--utm-surface-soft);
	border: var(--utm-rule);
	border-radius: var(--utm-radius);
}

.utm-toolbar .utm-field {
	margin: 0;
	min-width: 180px;
}

.utm-toolbar .utm-select,
.utm-toolbar .utm-input {
	width: 100%;
}

.utm-toolbar__end {
	margin-left: auto;
}

.utm-toolbar__group {
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	gap: var(--utm-gap-sm) var(--utm-gap);
}

/* PBUI.columns: side-by-side panels */
.utm-columns {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
	gap: var(--utm-gap);
	margin-bottom: var(--utm-gap);
}

/* Tabs */
.utm-tabbar {
	display: flex;
	flex-wrap: wrap;
	gap: 2px;
	margin-bottom: var(--utm-gap);
	border-bottom: var(--utm-rule);
}

.utm-tab:not(#\#) {
	display: inline-block;
	margin: 0;
}

button.utm-tab,
.utm-tab:not(#\#) > button {
	padding: 10px 18px;
	margin: 0 0 -1px;
	border: 0;
	border-bottom: 3px solid transparent;
	border-radius: 0;
	background: transparent;
	box-shadow: none;
	color: var(--utm-muted);
	font-family: var(--utm-body-font);
	font-size: 0.95em;
	font-weight: 600;
	letter-spacing: 0;
	text-transform: none;
	cursor: pointer;
}

button.utm-tab:hover,
.utm-tab:not(#\#) > button:hover {
	background: var(--utm-surface-soft);
	color: var(--utm-navy);
}

button.utm-tab--active,
.utm-tab--active:not(#\#) > button {
	border-bottom-color: var(--utm-orange);
	color: var(--utm-navy);
}

.utm-tab:not(#\#) > button[disabled] {
	opacity: 0.6;
	cursor: default;
}

/* Stat tiles: PBUI.stat / statGrid */
.utm-stat-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
	gap: 14px;
	margin-bottom: var(--utm-gap);
}

.utm-stat {
	--utm-stat-accent: var(--utm-navy);
	--utm-stat-ink: var(--utm-navy);
	padding: 14px 16px;
	background: var(--utm-surface);
	border: var(--utm-rule);
	border-top: 4px solid var(--utm-stat-accent);
	border-radius: var(--utm-radius);
}

.utm-stat__head {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-bottom: 6px;
}

.utm-stat__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	border-radius: var(--utm-radius);
	background: var(--utm-surface-soft);
	color: var(--utm-stat-ink);
}

.utm-stat__label {
	font-size: 0.78em;
	font-weight: 600;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	color: var(--utm-muted);
}

.utm-stat__value {
	font-size: 1.9em;
	font-weight: 700;
	line-height: 1.15;
	color: var(--utm-navy);
	font-variant-numeric: tabular-nums;
}

.utm-stat__note {
	margin-top: 4px;
	font-size: 0.85em;
	color: var(--utm-muted);
}

/* Orange is 2.5:1 on white: fine for the rule, too light for the icon. */
.utm-stat--orange {
	--utm-stat-accent: var(--utm-orange);
	--utm-stat-ink: var(--utm-orange-ink);
}
.utm-stat--globe {
	--utm-stat-accent: var(--utm-globe);
	--utm-stat-ink: var(--utm-globe);
}
.utm-stat--valley {
	--utm-stat-accent: var(--utm-valley);
	--utm-stat-ink: var(--utm-valley);
}
.utm-stat--regalia {
	--utm-stat-accent: var(--utm-regalia);
	--utm-stat-ink: var(--utm-regalia);
}
.utm-stat--leconte {
	--utm-stat-accent: var(--utm-leconte);
	--utm-stat-ink: var(--utm-leconte);
}
.utm-stat--river {
	--utm-stat-accent: var(--utm-river);
	--utm-stat-ink: var(--utm-river);
}
.utm-stat--legacy {
	--utm-stat-accent: var(--utm-legacy);
	--utm-stat-ink: var(--utm-valley);
}

/* PBUI.delta: green is better, red is worse (the caller decides which way is better). */
.utm-delta {
	font-weight: 600;
	white-space: nowrap;
}
.utm-delta--good {
	color: var(--utm-success-ink);
}
.utm-delta--bad {
	color: var(--utm-danger-ink);
}
.utm-delta--flat {
	color: var(--utm-muted);
}

/* Fills for bars, distribution segments and legend swatches: utm-fill--<palette name> */
.utm-fill--navy { background: var(--utm-navy); }
.utm-fill--orange { background: var(--utm-orange); }
.utm-fill--globe { background: var(--utm-globe); }
.utm-fill--valley { background: var(--utm-valley); }
.utm-fill--legacy { background: var(--utm-legacy); }
.utm-fill--switchgrass { background: var(--utm-switchgrass); }
.utm-fill--sunsphere { background: var(--utm-sunsphere); }
.utm-fill--torch { background: var(--utm-torch); }
.utm-fill--leconte { background: var(--utm-leconte); }
.utm-fill--regalia { background: var(--utm-regalia); }
.utm-fill--river { background: var(--utm-river); }
.utm-fill--fountain { background: var(--utm-fountain); }
.utm-fill--rock { background: var(--utm-rock); }

/* PBUI.bar */
.utm-bar {
	position: relative;
	display: block;
	height: 10px;
	min-width: 60px;
	overflow: hidden;
	background: var(--utm-surface-soft);
	border-radius: 5px;
}

.utm-bar__fill {
	position: absolute;
	top: 0;
	bottom: 0;
	left: 0;
	border-radius: 5px;
}

.utm-bar-cell {
	display: flex;
	align-items: center;
	gap: 8px;
}

.utm-bar-cell .utm-bar {
	flex: 1 1 auto;
}

.utm-bar-cell__value {
	min-width: 4em;
	text-align: right;
	font-variant-numeric: tabular-nums;
}

/* PBUI.distribution and PBUI.legend */
.utm-dist {
	display: flex;
	height: 14px;
	min-width: 140px;
	overflow: hidden;
	background: var(--utm-surface-soft);
	border-radius: 3px;
}

.utm-dist__seg {
	display: block;
	height: 100%;
}

.utm-dist__seg + .utm-dist__seg {
	border-left: 1px solid var(--utm-surface);
}

.utm-legend {
	display: flex;
	flex-wrap: wrap;
	gap: 4px 14px;
	margin-top: 6px;
	font-size: 0.85em;
	color: var(--utm-muted);
}

.utm-legend__item {
	display: inline-flex;
	align-items: center;
	gap: 6px;
}

.utm-legend__swatch {
	display: inline-block;
	width: 10px;
	height: 10px;
	border-radius: 2px;
}

/* PBUI.table / renderTable */
.utm-table-wrap {
	overflow-x: auto;
	margin-bottom: var(--utm-gap);
}

.utm-table-wrap .utm-table {
	margin-bottom: 0;
}

.utm-table--compact th,
.utm-table--compact td {
	padding: 5px 8px;
}

.utm-table tfoot td {
	font-weight: 700;
	border-top: 2px solid var(--utm-navy);
}

.utm-table__sort {
	padding: 0;
	border: 0;
	background: none;
	color: inherit;
	font: inherit;
	letter-spacing: inherit;
	text-align: inherit;
	cursor: pointer;
}

.utm-table__sort::after {
	content: " \2195";
	opacity: 0.5;
}

th[aria-sort="ascending"] .utm-table__sort::after {
	content: " \25B2";
	opacity: 1;
}

th[aria-sort="descending"] .utm-table__sort::after {
	content: " \25BC";
	opacity: 1;
}

/* PBUI.loading and a table's empty state */
.utm-empty {
	padding: 18px;
	margin-bottom: var(--utm-gap);
	text-align: center;
	color: var(--utm-muted);
	border: 1px dashed var(--utm-navy-100);
	border-radius: var(--utm-radius);
}

@media print {
	.utm-toolbar,
	.utm-tabbar,
	.utm-table__sort::after {
		display: none !important;
	}

	.utm-bar,
	.utm-dist,
	.utm-legend__swatch,
	.utm-stat {
		-webkit-print-color-adjust: exact;
		print-color-adjust: exact;
	}
}