From 38a88d223bc7b298f60b15bd6b587efde5be69f5 Mon Sep 17 00:00:00 2001 From: Diego Dereck Sosa-Escamilla Date: Tue, 8 Sep 2026 13:15:16 -0400 Subject: [PATCH 1/3] TDX-Enhanced, fully documented --- tdx-enhanced.documented.js | 4434 ++++++++++++++++++++++++++++++++++++ 1 file changed, 4434 insertions(+) create mode 100644 tdx-enhanced.documented.js diff --git a/tdx-enhanced.documented.js b/tdx-enhanced.documented.js new file mode 100644 index 0000000..f5b83a7 --- /dev/null +++ b/tdx-enhanced.documented.js @@ -0,0 +1,4434 @@ +// ==UserScript== +// @name tdx-enhanced +// @namespace purdue-it +// @version 2026-05-08-01 +// @description enhanced tdx coloring & formatting. follows system color scheme. +// @author Purdue STEM IT - it@purdue.edu +// @match https://service.purdue.edu/TDWorkManagement* +// @match https://service.purdue.edu/tdworkmanagement* +// @match https://service.purdue.edu/TDNext* +// @match https://service.purdue.edu/TDWebApi* +// @match https://purdue.teamdynamixpreview.com/TDWorkManagement* +// @match https://purdue.teamdynamixpreview.com/TDNext* +// @require https://momentjs.com/downloads/moment.min.js +// @require https://cdnjs.cloudflare.com/ajax/libs/tinycolor/1.6.0/tinycolor.min.js +// @downloadURL https://raw.github.itap.purdue.edu/ECN/tdx-userscript/refs/heads/main/tdx-enhanced.js +// @updateURL https://raw.github.itap.purdue.edu/ECN/tdx-userscript/refs/heads/main/tdx-enhanced.js +// @grant GM_getResourceText +// @grant GM_addStyle +// @run-at document-end +// ==/UserScript== + +/** + * TDX Userscript — maintainer overview + * + * Purpose: turns the standard TeamDynamix/TDNext interface into a more legible, + * configurable Purdue IT workspace. It supplies light/dark presentation, + * themes, contextual queue/status/date highlights, browser-native date inputs, + * TDX Tools and IT Status header shortcuts, tab-oriented navigation, dashboard + * layouts, sticky columns, and optional embedded dashboard websites. + * + * Runtime dependencies: Tampermonkey executes this file and exposes GM_addStyle; + * Moment.js parses/formats TDX dates; tinycolor improves dark-mode contrast. + * TeamDynamix IDs and CSS classes are implementation dependencies—verify the + * selectors when TDX changes its UI. + * + * Preferences: localStorage.userSettings holds settings per browser. The wrench + * menu is added beside #globalSearchBar. Most settings take effect immediately, + * but independently rendered TDX components may need a page refresh. + * + * Dashboard embeds: create a dummy Desktop report named, for example, + * `{"name":"Clock","url":"https://example.edu/clock"}`. It needs an Age + * column plus an `Age equals -1` filter; updateHeading replaces its widget with + * an iframe. The linked site must allow iframe embedding. + */ + + +(function() { + 'use strict'; + + /** + * TeamDynamix enhancement entry point. The script relies on Moment.js for + * date handling, tinycolor for feed contrast, Tampermonkey's GM_addStyle + * for page CSS, and TDX's current DOM/class names. User preferences live + * in localStorage under `userSettings`. + */ + + // Product name displayed in the TeamDynamix header after the page loads. + const primaryTitle = "Purdue University IT" + + /* QUEUE COLORS */ + + /** + * Visual identity for known queues. Keys must be lowercase because callers + * normalize queue labels before using this lookup. + */ + var colorsByQueue = { + 'aae': {'bg' : '#7030A0', 'txt' : 'white' }, + 'abe' : {'bg' : '#256f78', 'txt' : 'white'}, + 'ag' : {'bg' : '#99CC00', 'txt' : 'white'}, + 'bidc' : {'bg' : '#C5FFC5', 'txt' : 'black'}, + 'biology' : {'bg' : '#67c1ee', 'txt' : 'black'}, + 'bme' : {'bg' : '#0D69FF', 'txt' : 'white'}, + 'ce' : {'bg' : '#008000', 'txt' : 'white' }, + 'che' : {'bg' : '#00FF00', 'txt' : 'black'}, + 'chem' : {'bg' : '#ffb1b7', 'txt' : 'black'}, + 'coea' : {'bg' : '#00D6BD', 'txt' : 'black'}, + 'coep' : {'bg' : '#FFDDB7', 'txt' : 'black'}, + 'comp.sci.' : {'bg' : '#772212', 'txt' : 'white'}, + 'cos admin' : {'bg' : '#ddaa33', 'txt' : 'black'}, + 'dp' : {'bg' : '#0070A8', 'txt' : 'white'}, + 'doe': {'bg' : 'red', 'txt' : 'white'}, + 'ece' : {'bg' : '#FF6600', 'txt' : 'white'}, + 'ecnaccts' : {'bg' : '#98A4AE', 'txt' : 'white'}, + 'eaps' : {'bg' : '#629454', 'txt': 'white'}, + 'eee' : {'bg' : '#F66A6A', 'txt' : 'white'}, + 'ene': {'bg' : '#A45CD0', 'txt': 'white' }, + 'engineering' : {'bg' : '#FFD900', 'txt' : 'black'}, + 'engr - south' : {'bg' : '#663300', 'txt' : 'white'}, + 'engr - north' : {'bg' : '#663300', 'txt' : 'white'}, + 'epics': {'bg' : '#E399E3', 'txt' : 'black'}, + 'flex' : {'bg' : '#A7ECFF', 'txt' : 'black'}, + 'helpdesk' : {'bg' : '#98A4AE', 'txt' : 'white'}, + 'hhs' : {'bg' : '#CFB991', 'txt' : 'black'}, + 'ie' : {'bg' : '#FFB7B7', 'txt' : 'black'}, + 'imi' : {'bg' : '#FFB96D', 'txt' : 'black'}, + 'apple' : {'bg' : '#666666', 'txt' : 'white'}, + 'mailman' : {'bg' : 'white', 'txt' : 'black'}, + 'math' : {'bg' : '#f7977a', 'txt' : 'black'}, + 'me' : {'bg' : '#b30000', 'txt' : 'white'}, + 'mse': {'bg' : '#EFD3F5', 'txt' : 'black'}, + 'ne': {'bg' : '#af6377', 'txt' : 'white'}, + 'pari' : {'bg' : '#3f5c8a', 'txt': 'white'}, + 'pharmacy' : {'bg' : '#FF33FF', 'txt' : 'white'}, + 'physics' : {'bg' : '#07622f', 'txt': 'white'}, + //'potr' : {'bg' : '#663300', 'txt' : 'white'}, + 'president' : {'bg' : '#cfb991', 'txt' : 'black'}, + 'sacc' : {'bg' : '#434343', 'txt' : 'white'}, + 'science' : {'bg' : '#22dd94', 'txt' : 'black'}, + 'sitemgrs' : {'bg' : '#98A4AE', 'txt' : 'white'}, + 'stat' : {'bg' : '#ff6f44', 'txt' : 'white'}, + 'students' : {'bg' : '#98A4AE', 'txt' : 'white'}, + 'swt' : {'bg' : '#000ED6', 'txt' : '#FFEE00'}, + 'polytechnic' : {'bg' : 'black', 'txt' : 'white'}, + 'cnit' : {'bg' : '#434343', 'txt' : 'white'}, + 'uds' : {'bg' : '#98A4AE', 'txt' : 'white'}, + 'udsprojects': {'bg' : '#98A4AE', 'txt' : 'white'}, + 'vet' : {'bg' : '#CCFFFF', 'txt' : 'black'}, + //'wang' : {'bg' : '#000099', 'txt' : 'white'}, + 'web' : {'bg' : '#B46086', 'txt' : 'white'}, + 'windows' : {'bg' : '#b77729', 'txt' : 'white'}, + 'zsite' : {'bg' : '#98A4AE', 'txt' : 'white'}, + }; + + /** + * Status pill colors for the standard TeamDynamix report-table statuses. + * Alpha-channel backgrounds stay readable against either theme. + */ + var colorsByTdxStatus = { + 'In Process': {'bg' : '#FF3C3C20', 'txt' : 'var(--txt-1)', 'border' : '#FF3C3C50'}, + 'New': {'bg' : '#FF3C3C20', 'txt' : 'var(--txt-1)', 'border' : '#FF3C3C50'}, + 'Assigned': {'bg' : '#FF3C3C20', 'txt' : 'var(--txt-1)', 'border' : '#FF3C3C50'}, + 'Awaiting Customer Response': {'bg' : '#33CC3320', 'txt' : 'var(--txt-1)', 'border' : '#33CC3350'}, + 'Pending External': {'bg' : '#FF990020', 'txt' : 'var(--txt-1)', 'border' : '#FF990050'}, + 'Pending Internal': {'bg' : '#FF990020', 'txt' : 'var(--txt-1)', 'border' : '#FF990050'}, + }; + + // Trusted origin for the companion TDX Tools and highlight-editor pages. + var tdxtoolsUrl = "https://engineering.purdue.edu" + + /** + * Built-in inline markers. For example, `!! urgent !!` is rendered using + * highlight 1. The regular expressions are global, so their lastIndex is + * reset after a successful use below. + */ + var colorsByStatus = { + '!!': {style: {background: 'var(--col-highlight-1)'}, type: 'highlight', re: new RegExp("\!! (.*) \!!","g")}, + '~~': {style: {background: 'var(--col-highlight-2)'}, type: 'highlight', re: new RegExp("\~~ (.*) \~~","g")}, + } + + // The active page color mode, set by setColorMode and read while styling feeds. + var colorScheme + + /* BEGIN FUNCTIONS */ + + //color manipulation via css filters: https://github.com/angel-rs/css-color-filter-generator + //modified to return an object instead of filter string + + /** + * Mutable RGB color used to simulate the CSS filter pipeline. Values are + * clamped to 0-255 after every transformation. + */ + class Color { + constructor(r, g, b) { + this.set(r, g, b); + } + + toString() { + return `rgb(${Math.round( + this.r + )}, ${Math.round(this.g)}, ${Math.round(this.b)})`; + } + + set(r, g, b) { + this.r = this.clamp(r); + this.g = this.clamp(g); + this.b = this.clamp(b); + } + + hueRotate(angle = 0) { + // Applies the same 3×3 RGB matrix used by CSS hue-rotate(). + angle = (angle / 180) * Math.PI; + const sin = Math.sin(angle); + const cos = Math.cos(angle); + + this.multiply([ + 0.213 + cos * 0.787 - sin * 0.213, + 0.715 - cos * 0.715 - sin * 0.715, + 0.072 - cos * 0.072 + sin * 0.928, + 0.213 - cos * 0.213 + sin * 0.143, + 0.715 + cos * 0.285 + sin * 0.14, + 0.072 - cos * 0.072 - sin * 0.283, + 0.213 - cos * 0.213 - sin * 0.787, + 0.715 - cos * 0.715 + sin * 0.715, + 0.072 + cos * 0.928 + sin * 0.072 + ]); + } + + grayscale(value = 1) { + // Interpolates between the original color and grayscale. + this.multiply([ + 0.2126 + 0.7874 * (1 - value), + 0.7152 - 0.7152 * (1 - value), + 0.0722 - 0.0722 * (1 - value), + 0.2126 - 0.2126 * (1 - value), + 0.7152 + 0.2848 * (1 - value), + 0.0722 - 0.0722 * (1 - value), + 0.2126 - 0.2126 * (1 - value), + 0.7152 - 0.7152 * (1 - value), + 0.0722 + 0.9278 * (1 - value) + ]); + } + + sepia(value = 1) { + // Interpolates between the original color and a sepia transform. + this.multiply([ + 0.393 + 0.607 * (1 - value), + 0.769 - 0.769 * (1 - value), + 0.189 - 0.189 * (1 - value), + 0.349 - 0.349 * (1 - value), + 0.686 + 0.314 * (1 - value), + 0.168 - 0.168 * (1 - value), + 0.272 - 0.272 * (1 - value), + 0.534 - 0.534 * (1 - value), + 0.131 + 0.869 * (1 - value) + ]); + } + + saturate(value = 1) { + // Multiplies saturation using CSS-compatible coefficients. + this.multiply([ + 0.213 + 0.787 * value, + 0.715 - 0.715 * value, + 0.072 - 0.072 * value, + 0.213 - 0.213 * value, + 0.715 + 0.285 * value, + 0.072 - 0.072 * value, + 0.213 - 0.213 * value, + 0.715 - 0.715 * value, + 0.072 + 0.928 * value + ]); + } + + multiply(matrix) { + // Applies a row-major 3×3 transformation matrix in place. + const newR = this.clamp( + this.r * matrix[0] + this.g * matrix[1] + this.b * matrix[2] + ); + const newG = this.clamp( + this.r * matrix[3] + this.g * matrix[4] + this.b * matrix[5] + ); + const newB = this.clamp( + this.r * matrix[6] + this.g * matrix[7] + this.b * matrix[8] + ); + this.r = newR; + this.g = newG; + this.b = newB; + } + + brightness(value = 1) { + // CSS brightness is a linear multiplication with no offset. + this.linear(value); + } + contrast(value = 1) { + // CSS contrast expands values around the midpoint (128). + this.linear(value, -(0.5 * value) + 0.5); + } + + linear(slope = 1, intercept = 0) { + this.r = this.clamp(this.r * slope + intercept * 255); + this.g = this.clamp(this.g * slope + intercept * 255); + this.b = this.clamp(this.b * slope + intercept * 255); + } + + invert(value = 1) { + // `value` is normalized (0-1), matching the CSS invert() function. + this.r = this.clamp((value + (this.r / 255) * (1 - 2 * value)) * 255); + this.g = this.clamp((value + (this.g / 255) * (1 - 2 * value)) * 255); + this.b = this.clamp((value + (this.b / 255) * (1 - 2 * value)) * 255); + } + + hsl() { + // Produces HSL for the solver's color-distance calculation. + // Code taken from https://stackoverflow.com/a/9493060/2688027, licensed under CC BY-SA. + const r = this.r / 255; + const g = this.g / 255; + const b = this.b / 255; + const max = Math.max(r, g, b); + const min = Math.min(r, g, b); + let h, + s, + l = (max + min) / 2; + + if (max === min) { + h = s = 0; + } else { + const d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + + case g: + h = (b - r) / d + 2; + break; + + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; + } + + return { + h: h * 100, + s: s * 100, + l: l * 100 + }; + } + + clamp(value) { + if (value > 255) { + value = 255; + } else if (value < 0) { + value = 0; + } + return value; + } + } + + /** + * Searches for CSS filter values that transform black icons to `target`. + * This is adapted from css-color-filter-generator and returns structured + * values rather than a ready-to-inject `filter:` declaration. + */ + class Solver { + constructor(target, baseColor) { + this.target = target; + // Compare RGB and HSL so hue/saturation mismatches cannot look "good". + this.targetHSL = target.hsl(); + // Reuse one object for optimizer iterations to avoid allocation churn. + this.reusedColor = new Color(0, 0, 0); + } + + solve() { + // First find a broad approximation, then refine it locally. + const result = this.solveNarrow(this.solveWide()); + return { + values: result.values, + loss: result.loss, + filter: this.css(result.values) + }; + } + + solveWide() { + // Repeated broad SPSA passes avoid depending on one random start. + const A = 5; + const c = 15; + const a = [60, 180, 18000, 600, 1.2, 1.2]; + + let best = { loss: Infinity }; + for (let i = 0; best.loss > 25 && i < 3; i++) { + const initial = [50, 20, 3750, 50, 100, 100]; + const result = this.spsa(A, a, c, initial, 1000); + if (result.loss < best.loss) { + best = result; + } + } + return best; + } + + solveNarrow(wide) { + // Narrow search starts from the best broad-search filter values. + const A = wide.loss; + const c = 2; + const A1 = A + 1; + const a = [0.25 * A1, 0.25 * A1, A1, 0.25 * A1, 0.2 * A1, 0.2 * A1]; + return this.spsa(A, a, c, wide.values, 500); + } + + spsa(A, a, c, values, iters) { + // Simultaneous Perturbation Stochastic Approximation optimizer. + const alpha = 1; + const gamma = 0.16666666666666666; + + let best = null; + let bestLoss = Infinity; + const deltas = new Array(6); + const highArgs = new Array(6); + const lowArgs = new Array(6); + + for (let k = 0; k < iters; k++) { + const ck = c / Math.pow(k + 1, gamma); + for (let i = 0; i < 6; i++) { + deltas[i] = Math.random() > 0.5 ? 1 : -1; + highArgs[i] = values[i] + ck * deltas[i]; + lowArgs[i] = values[i] - ck * deltas[i]; + } + + const lossDiff = this.loss(highArgs) - this.loss(lowArgs); + + // Estimate the gradient from two simultaneous perturbations. + for (let i = 0; i < 6; i++) { + const g = (lossDiff / (2 * ck)) * deltas[i]; + const ak = a[i] / Math.pow(A + k + 1, alpha); + values[i] = fix(values[i] - ak * g, i); + } + + const loss = this.loss(values); + if (loss < bestLoss) { + best = values.slice(0); + bestLoss = loss; + } + } + return { values: best, loss: bestLoss }; + + function fix(value, idx) { + let max = 100; + if (idx === 2 /* saturate */) { + max = 7500; + } else if (idx === 4 /* brightness */ || idx === 5 /* contrast */) { + max = 200; + } + + if (idx === 3 /* hue-rotate */) { + // Hue is circular: 101% and 1% represent the same rotation. + if (value > max) { + value %= max; + } else if (value < 0) { + value = max + (value % max); + } + } else if (value < 0) { + value = 0; + } else if (value > max) { + value = max; + } + return value; + } + } + + loss(filters) { + // Lower loss means both RGB and HSL values more closely match target. + // Argument is array of percentages. + const color = this.reusedColor; + color.set(0, 0, 0); + + // CSS filters below run in the same order as the generated CSS rule. + color.invert(filters[0] / 100); + color.sepia(filters[1] / 100); + color.saturate(filters[2] / 100); + color.hueRotate(filters[3] * 3.6); + color.brightness(filters[4] / 100); + color.contrast(filters[5] / 100); + + const colorHSL = color.hsl(); + return ( + Math.abs(color.r - this.target.r) + + Math.abs(color.g - this.target.g) + + Math.abs(color.b - this.target.b) + + Math.abs(colorHSL.h - this.targetHSL.h) + + Math.abs(colorHSL.s - this.targetHSL.s) + + Math.abs(colorHSL.l - this.targetHSL.l) + ); + } + + css(filters) { + // Converts optimizer percentages to CSS custom-property values. + function fmt(idx, multiplier = 1) { + return Math.round(filters[idx] * multiplier); + } + + //modified here + return { + invert: `${fmt(0)}%`, + sepia: `${fmt(1)}%`, + saturate: `${fmt(2)}%`, + hue_rotate: `${fmt(3, 3.6)}deg`, + brightness: `${fmt(4)}%`, + contrast: `${fmt(5)}%` + } + + //return `filter: invert(${fmt( + // 0 + //)}%) sepia(${fmt(1)}%) saturate(${fmt(2)}%) hue-rotate(${fmt(3, 3.6)}deg) brightness(${fmt(4)}%) contrast(${fmt(5)}%);`; + } + } + + /** Converts three- or six-digit hexadecimal notation to an [r, g, b] array. */ + function hexToRgb(hex) { + // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") + const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; + hex = hex.replace(shorthandRegex, (m, r, g, b) => { + return r + r + g + g + b + b; + }); + + const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); + // null signals an invalid CSS color to callers. + return result + ? [ + parseInt(result[1], 16), + parseInt(result[2], 16), + parseInt(result[3], 16) + ] + : null; + } + + /** + * Runs several independent solver attempts and retains the closest result. + * Kept for callers that need a higher-quality (but more expensive) search. + */ + function getFilterForColor(rgbColor) { + let bestResult = null; + let iterationCount = 0; // Initialize a counter for iterations + + for (let i = 0; i < 200; i++) { + iterationCount++; // Increment the counter for each iteration + const color = new Color(rgbColor[0], rgbColor[1], rgbColor[2]); + const solver = new Solver(color); + const result = solver.solve(); + + if (!bestResult || result.loss < bestResult.loss) { + bestResult = result; + if (bestResult.loss <= 0.01) { + // exit early if good result is found + break; + } + } + } + + console.log("Total iterations: ", iterationCount); // Log the total iterations + return bestResult; + } + + //end color manipulation + + /** + * Processes dashboard-widget titles. A JSON report title such as + * `{ "name": "Clock", "url": "https://…" }` is an embed instruction: + * the title becomes a readable heading and its `.tdx-widget` is replaced by + * an iframe. Invalid JSON falls through without breaking the dashboard. + * Non-embed titles remain eligible for custom report highlights. + */ + function updateHeading(mutation) { + let headings = mutation.querySelectorAll(".tdx-control-bar__title") + + for (const heading of headings) { + //color the header if queue name is found + let headingTxt = heading.innerText + let headingFirst = headingTxt.split(" ")[0] + headingFirst = headingFirst.toLowerCase() + + let parent = heading.parentElement + + handleHighlight("report",headingTxt,heading) + + //try embedding + if (headingTxt.startsWith("{")) { + try { + let embedData = JSON.parse(headingTxt) + + let title = document.createElement("h4") + title.classList = heading.classList + title.innerText = embedData.name + // TDX nests the title three levels beneath the widget body. + let moduleBody = heading.parentNode.parentNode.parentNode.querySelector(".tdx-widget") + let embed = document.createElement("iframe") + embed.classList = "customEmbed" + embed.src = embedData.url + heading.replaceWith(title) + moduleBody.replaceWith(embed) + } catch { + } + } + } + } + + /** + * Enhances a ticket/task page and, when `mutation` is supplied, newly + * inserted feed nodes. It replaces legacy date inputs, labels the queue, + * changes the browser title, normalizes action links, and improves dark-mode + * contrast for inline feed colors. Legacy `#txtStartDate` / `#txtEndDate` + * inputs are retained but hidden because TDX still needs their original + * `M/D/YYYY h:mm A` values when the form is submitted. The displayed + * datetime-local input mirrors changes back to that legacy field. + */ + function parseTicket(mutation=null) { + + let qBlock = document.querySelector("#ctlAttribute2285") + //ticket or task + let header = document.getElementById("thTicket_spnTitle") || document.querySelector("#upTaskHeader>div>h1") + + //find calendar inputs when editing tickets/tasks + //let calendars = document.querySelectorAll("input.hasDatepicker") + let calendars = document.querySelectorAll("#txtStartDate, #txtEndDate") //tasks for now, will add more as found + if (calendars) { + let originalFormat = "M/D/YYYY h:mm A"; + let newFormat = "YYYY-MM-DDTHH:mm"; + [...calendars].forEach(calendar=>{ + // Parse the value exactly as the legacy TDX control serializes it. + let date = moment(calendar.value,originalFormat) + + let newCal = document.createElement("input") + newCal.id = `${calendar.id}-new` + newCal.classList = calendar.classList + newCal.type = "datetime-local" + + function updateDate() { + // Keep the hidden TDX field submit-ready in its expected format. + let parsedFormat = date.format(originalFormat) + calendar.value = parsedFormat + + // Keep the browser-native control and its friendly weekday label in sync. + let iso = date.format(newFormat) + newCal.value = iso + calTxt.innerText = date.calendar() + + console.log("Cal update!",date) + } + + //convert to original format + newCal.addEventListener("input",event=>{ + let parsedValue = moment(event.target.value,newFormat) + date = parsedValue + updateDate() + }) + + //date modifier shortcuts + let calBox = document.createElement("div") + calBox.classList = ["calBox"] + let calTxt = document.createElement("span") + calTxt.innerText = date.format('dddd') + + //modify date + function btnModify(btn) { + console.log("Modify date:",btn) + if ('add' in btn) { + date.add(btn.add) + } else if ('set' in btn) { + date.set(btn.set) + } + + // Avoid scheduling the shortcut result outside the support workweek. + let day = date.isoWeekday() + let hour = date.hour() + let min = date.minute() + let wkday = date.weekday() + + console.log("WkDay:",wkday,"Day:",day,"hour:",hour,"min:",min) + + //if Friday after 5pm + if (day>=5 && (hour>17 || (hour==17 && min>0))) { + // Friday evening (or later) moves to Monday at 8:00 AM. + date.set({ + h: 8, + d: 1+7, + m: 0 + }) + } else if (day>5) { + // Saturday/Sunday selections also move to the following Monday. + date.set({ + d: 1+7 + }) + } + + + updateDate() + } + + let buttons = [ + {name:"+1 day",add: {days:1}}, + {name:"+1 week",add: {weeks:1}}, + {name:"+1 month",add: {months:1}}, + {name:"12PM",set: {h:12,m:0}}, + {name:"5PM",set: {h:17,m:0}} + ] + + for (const btn of buttons) { + let button = document.createElement("button") + button.classList = "btn btn-calendar" + button.innerText = btn.name + button.addEventListener("click",(event)=>{ + event.preventDefault() + btnModify(btn) + }) + calBox.appendChild(button) + } + + updateDate() + + //old input still needs to exist for proper format conversion + calendar.style.display = "none" + calendar.parentElement.append(newCal) + calendar.parentElement.append(calTxt) + calendar.parentElement.append(calBox) + }); + } + + //change tab title + if (header) { + // Use the ticket subject for easier identification among browser tabs. + let ticketTitle = header.childNodes[0].textContent + document.title = ticketTitle + } else { + return + } + + //add queue tag to ticket title + if (qBlock && !document.querySelector(".qBox")) { + let qElement = qBlock.querySelector("span.wrap-text") + let qTxt = qElement.innerText + + //console.log("GOT QUEUE:",qTxt) + + let newBox = document.createElement("span") + newBox.innerText = qTxt + newBox.classList.add("qBox") + + // Only known queues receive a color; unknown names retain default styling. + for (const qK of Object.keys(colorsByQueue)) { + let q = colorsByQueue[qK] + if (qTxt.toLowerCase() == qK) { + newBox.style.color = q.txt + newBox.style.backgroundColor = q.bg + } + + } + + header.appendChild(newBox) + } + + //handle button links - updates/tasks for now + //update buttons + [...document.querySelectorAll("#btnUpdateTicket, #divUpdateFromActions")].forEach(button=>{ + handleLink("Update",button) + }); + + //task button + [...document.querySelectorAll("#liAddTicketTask>a")].forEach(button=>{ + handleLink("TicketTaskNew",button) + }); + + //task template button + [...document.querySelectorAll("#divAddTaskTemplate>a")].forEach(button=>{ + handleLink("TicketAddTaskTemplate",button) + }); + + //color the feed if darkmode + var feedItems + + if (mutation) { + feedItems = mutation + } else { + feedItems = document.querySelectorAll("#ttDescription") + } + + //console.log("Feed items:",feedItems) + + if (feedItems) { + for (const feedItem of feedItems) { + [...feedItem.querySelectorAll("*[style*='color']")].forEach(feedElement=>{ + let color = tinycolor(feedElement.style.color) + let brightness = color.getBrightness() + //console.warn("ELEMENT:",feedElement) + //console.log("Brightness:",brightness) + + //if color is too dark + if (brightness < 100 && colorScheme == "darkMode") { + // TDX may supply dark inline text that disappears on dark surfaces. + + var newColor + var isGrey = true + let rgb = color.toRgb() + + if (rgb.r == rgb.b && rgb.r == rgb.g) { + isGrey = true + } else { + isGrey = false + } + + //if color is shade of grey + if (isGrey) { + // Rotate then invert neutral tones to create a readable contrast. + let flippedColor = tinycolor(invertHex(color.spin(180).toHex())) + newColor = flippedColor + //console.log(feedElement.innerText,"is grey") + } else { + // Preserve a colored label's hue while increasing its brightness. + let threshold = 50 + let diff = (threshold - brightness) + brightness + newColor = color.brighten(diff) + //console.log(feedElement.innerText,"is a color") + } + //console.log("oldColor:",color.toHex(),"newColor:",newColor.toHex()) + + feedElement.style.color = newColor.toHexString() + } + }); + } + } + } + + /** + * Applies enhancements outside ticket content: styles accessible shadow DOM, + * enforces readable inline text, optionally hides AI Assist, changes the + * dashboard layout, and makes requested dashboard columns sticky. + */ + function parseOtherElements() { + let path = document.location.pathname; + + //inject styles into search bar + [...document.querySelectorAll("tdx-search-bar, .js_sidePanelX")].forEach(searchBar=>{ + //console.log("SEARCH BAR:",searchBar) + let shadow = searchBar.shadowRoot + if (shadow) { + + injectOtherStyles(shadow); + + //check nested shadows + [...shadow.querySelectorAll("tdx-close-x")].forEach(nested=>{ + let nestedShadow = nested.shadowRoot + //console.log("NESTED:",nestedShadow) + if (nestedShadow) { + injectOtherStyles(nestedShadow) + } + }) + } + }) + + //force contrastive colors in descriptions with inline styles + // Do not alter anchors: their color conveys normal link affordance. + document.querySelectorAll("div.moreToggle *:not(a), div.lessToggle *:not(a), div.wrap-text *:not(a)").forEach(textBlock=>{ + textBlock.style.color = "var(--txt-1)" + }) + document.querySelectorAll("#ToggleAIAgentAssist").forEach(AIAgentButton=>{ + let selected = settings('get','aiBehavior'); + console.log("AI Behavior selected:",selected.value) + if (selected == "aiDisable") { + AIAgentButton.style.display = "none" + } + }) + + let desktopLayout = settings('get','layout') + let desktop = document.querySelector("#divContent") + if (desktop && desktopLayout) { + let col1 = desktop.querySelector("#Column1") + let col2 = desktop.querySelector("#Column2") + let col3 = desktop.querySelector("#Column3") + + //100% / 33-66% + if (desktopLayout=="1_100-66-33" && col2 && col3) { + console.log("Applying layout:",desktopLayout) + + //define width classes + let col2WidthClass = "col-md-8" + let col3WidthClass = "col-md-4" + + //resize column 2 + for (const cls of col2.classList) { + if (cls.startsWith("col-md")) { + console.log("Found col2 width class:",cls) + col2.classList.remove(cls) + col2.classList.add(col2WidthClass) + break + } + } + + //resize column 3 + for (const cls of col3.classList) { + if (cls.startsWith("col-md")) { + col3.classList.remove(cls) + col3.classList.add(col3WidthClass) + break + } + } + } + } + + //apply sticky columns + let stickyColumns = settings('get','stickyColumns') + if (stickyColumns) { + // Sticky positioning is useful only when columns differ in height. + [...document.querySelectorAll(".tdx-dashboard__column")].forEach(column=>{ + column.style.position = "sticky" + column.style.alignSelf = "flex-start" + column.style.top = "4px" + }); + } + } + + /** Returns the RGB inverse of a six-character hexadecimal color (without #). */ + function invertHex(hex) { + return (Number(`0x1${hex}`) ^ 0xFFFFFF).toString(16).substr(1).toUpperCase() + } + + /** + * Converts a TDX table into row objects keyed by visible column headings, + * then delegates each row to parseItem. Checkbox cells are intentionally + * skipped so their position does not affect the heading-to-cell mapping. + */ + function parseTable(element) { + //let t = mutation.target; + //console.error("BEGIN MUTATION",t) + let table = element.querySelector("table") + let items = []; + + if (table) { + let headers = []; + //console.log("Table",table); + + //get headers of the tables + [...table.querySelectorAll("th")].forEach((header)=>{ + var txt = header.querySelector("span") + //txt = txt.dataset.sort + //txt = txt.split(" ")[0] + if (txt) { + headers.push(txt.textContent) + } + //console.log("i:",header.cellIndex,txt) + }); + + //console.log("Headers:",headers); + + //parse rows + [...table.querySelectorAll("tr:has(td)")].forEach((row)=>{ + //console.log("row:",row); + let item = {}; + //parse each cell + let i = 0; + [...row.querySelectorAll("td:not(:has(input))")].forEach((cell)=>{ + //let i = cell.cellIndex; //can't use cellindex if there's a checkbox in the table + let txt = cell.textContent; + txt = txt.trim() + + //console.log("Cell:",i,cell); + + // Retain text and its source cell so formatting can mutate the DOM. + item[headers[i]] = {txt:txt,cell:cell} + i++ + }) + + item.row = row + items.push(item) + //console.log("ITEM:",item) + + //being coloring + parseItem(item) + }) + } + + //updateHeading(element) + } + + /** + * Replaces an element's content with a styled, text-only highlight badge. + * Use this only where discarding nested markup/links is acceptable. + */ + function createHighlightBubble(element,bgColor,txtColor,borderColor = "#00000000") { + + //should the bubble carry links over? + //let copy = element.cloneNode(true) + + //create new element to highlight + let newSpan = document.createElement("span") + newSpan.innerText = element.innerText //item["2285"].txt + newSpan.style.backgroundColor = bgColor + newSpan.style.color = txtColor + newSpan.style.borderColor = borderColor + newSpan.classList.add("qHighlight") + + //if we use the copy method + //newSpan.appendChild(copy) + + //replace cell with new span + element.replaceChildren(newSpan) + return newSpan + } + + /** + * Applies all row-level rules: queue/status badges, human-readable dates, + * age and due-date urgency, reply/internal-update cues, person/title + * highlights, and report link behavior. + */ + function parseItem(item) { + + //console.log("Parse item:",item) + + //color queue names + if ('CSS Support' in item) { + let qCell = item["CSS Support"].cell + let qTxt = item["CSS Support"].txt.toLowerCase() + if (qTxt in colorsByQueue) { + let q = colorsByQueue[qTxt] + + createHighlightBubble(qCell,q.bg,q.txt) + } + } + + if ('Status' in item) { + let statusCell = item["Status"].cell + let statusText = item["Status"].txt + if (colorsByTdxStatus.hasOwnProperty(statusText)) { + let statusStyle = colorsByTdxStatus[statusText] + createHighlightBubble(statusCell, statusStyle.bg, statusStyle.txt, statusStyle.border) + } + } + + //change date modified + let relativeDates = ['Modified','Created'] + for (const dType of relativeDates) { + if (dType in item) { + let dTxt = item[dType].txt + let dCell = item[dType].cell + + // `fromNow` turns server timestamps into compact list-view age text. + let date = moment(dTxt) + let dTxtNew = date.fromNow() + + if (dTxtNew == "Invalid date") { + //console.warn("Failed date:",dTxt,item) + } else { + dCell.innerText = dTxtNew + } + } + } + + let detailedDates = ['Date Due','Due','Created','Start','SLA Resolve By','SLA Respond By'] + for (const dType of detailedDates) { + if (dType in item) { + let dTxt = item[dType].txt + let dCell = item[dType].cell + + // `calendar` gives a more actionable label such as "Tomorrow at 5:00 PM". + let date = moment(dTxt) + let dTxtNew = date.calendar() + + if (dTxtNew == "Invalid date") { + //console.warn("Failed date:",dTxt,item) + } else { + dCell.innerText = dTxtNew + } + } + } + + //highlight modified/age red + let modifiedDates = ['Modified'] + for (const dType of modifiedDates) { + if (dType in item) { + let modDate = item[dType] + // Fade from clear to full warning red over 14 days (336 hours). + const ageThreshold = 336 + + let date = moment(modDate.txt) + let duration = moment.duration(moment().diff(date)) + let hours = duration.asHours() + + let alpha = hours / ageThreshold + alpha = alpha > 1 ? 1 : alpha + + let cell = modDate.cell + handleHighlight("dateModified",alpha,cell) + cell.classList.add(alpha > 0.5 ? "light" : "dark") + } + } + + //highlight modified/age red + let dueDates = ['Due','Date Due','SLA Resolve By','SLA Respond By'] + for (const dType of dueDates) { + if (dType in item) { + let dueDate = item[dType] + // Due dates fade in across the five days preceding their deadline. + const ageThreshold = -5*24 + + let date = moment(dueDate.txt) + let duration = moment.duration(moment().diff(date)) + let hours = duration.asHours() + let alpha + if (hours < 0) { + alpha = 1 - ((hours / ageThreshold)) + alpha = alpha < 0? 0: alpha + } else { + alpha = 1 + } + + if (!Number.isNaN(hours)) { + let cell = dueDate.cell + handleHighlight("dateModified",alpha,cell) + cell.classList.add(alpha > 0.5 ? "light" : "dark") + } + } + } + + let age = ['Age'] + for (const dType of age) { + if (dType in item) { + let Age = item[dType] + const ageThreshold = 30 + + let days = Age.txt.slice(0,-1) + + if (days > 30){ + days = days - 30 + let alpha = days / ageThreshold + alpha = alpha > 1 ? 1 : alpha + let cell = Age.cell + handleHighlight("age",alpha,cell) + cell.classList.add(alpha > 0.5 ? "light" : "dark") + } + } + } + + // let Status = ['Status'] + // for (const dType of Status) { + // if (dType in item) { + // let CurrentStatus = item[dType] + // let cell = CurrentStatus.cell + // handleHighlight("status",CurrentStatus.txt,cell) + // } + // } + + //find user replies & last modified by internal + if ('Requestor' in item && 'Modified By' in item && 'Prim Resp' in item) { + let fromUser = item["Requestor"] + let lastModified = item["Modified By"] + let assignedTo = item["Prim Resp"] + + //reply from user + if (fromUser.txt == lastModified.txt && fromUser.txt != assignedTo.txt && assignedTo.txt != "Unassigned") { + // The requester, rather than an assignee, supplied the latest update. + //item.row.style.backgroundColor = "var(--col-reply)"; + handleHighlight("reply",null,item.row) + } + + //modified by internal + if (lastModified.txt != fromUser.txt && lastModified.txt != assignedTo.txt) { + let cell = lastModified.cell + //cell.style.backgroundColor = "var(--col-modified)" + handleHighlight("userModified",null,cell) + } + } + + //find internal users and highlight them + if ('Prim Resp' in item) { + handleHighlight("person",item['Prim Resp'].txt,item['Prim Resp'].cell) + } else if ('Responsibility' in item) { + handleHighlight("person",item.Responsibility.txt,item.Responsibility.cell) + } + + //find inline highlights for tasks + if ('Title' in item) { + let title = item.Title + handleHighlight("title",title.txt,title.cell) + } + + //find links & open in new tab, if configured + //let linkTypes = ['Title','TicketID','CustomerName','ResponsibleFullName','LastModifiedByFullName'] //open people in new tabs + let linkTypes = ['Title','TicketID','TicketTitle'] + for (const linkType of linkTypes) { + if (linkType in item) { + let link = item[linkType].cell.querySelector("a") + if (link) { + //override function that opens in windows + handleLink("report",link) + } + } + } + } + + /** + * Applies the user's preferred navigation behavior to a report or ticket + * action. In tab mode, TDX's default pop-up handlers are replaced with a + * centered new-tab/window call; the dormant alternate branch preserves the + * original pop-up implementation for future use. + */ + function handleLink(source,link) { + // `tabs` is the documented preferred behavior; other values preserve TDX defaults. + let behavior = settings('get','linkBehavior') + + let relL = window.screenLeft != undefined ? window.screenLeft : screen.left + let relT = window.screenTop != undefined ? window.screenTop : screen.top + + if (behavior=="tabs") { + + switch(source) { + case 'report': { + // Remove TDX's popup handler before making the anchor a normal new tab. + link.onclick = null + link.target = "_blank" + break + } + + case 'Update': + case 'TicketTaskNew': + case 'TicketAddTaskTemplate': { + link.onclick = (event)=>{ + event.preventDefault() + let w = (window.screen.width / 1.75) + let h = (window.screen.height / 1.25) + let l = ((window.screen.width / 2) - (w/2)) + relL + let t = ((window.screen.height / 2) - (h/2)) + relT + + //restructure url for updating + let location = window.location.pathname + let baseHref = location.substr(0, location.lastIndexOf('/')) + let href = `${baseHref}/${source}${window.location.search}` + + // Window geometry is retained for browsers that honor popup features. + let params = `width=${w}px,height=${h}px,left=${l}px,top=${t}px` + return window.open(href,'_blank',params) + } + break + } + } + + } else { + return + //leave default + link.onclick = (event)=>{ + event.preventDefault() + var params + var href + let w = (window.screen.width / 2.1) + let h = (window.screen.height / 1.25) + let l = 20 + relL + let t = 50 + relT + + switch(source) { + case 'report': { + href = link.href + break + } + + case 'Update': + case 'TicketTaskNew': + case 'TicketAddTaskTemplate': { + l = (window.screen.width / 2) + l + + //restructure url for updating + let location = window.location.pathname + let baseHref = location.substr(0, location.lastIndexOf('/')) + href = `${baseHref}/${source}${window.location.search}` + break + } + } + + params = `width=${w}px,height=${h}px,left=${l}px,top=${t}px` + return window.open(href,'_blank',params) + } + } + + } + + /** + * Resolves built-in and user-defined highlight rules and applies their CSS. + * `type` identifies semantic context; `txt` is either cell text or a + * 0-1 opacity value for age/date rules. Custom-highlight entries supplied by + * the editor use `{type, value, style}`: type can be `highlight`, `reply`, + * `dateModified`, `userModified`, `report`, `report-regex`, or `person`; + * `style` is assigned directly to element.style. Highlight behavior controls whether + * matching marker text is removed from the whole cell or only its link text. + */ + function handleHighlight(type, txt, element) { + let behavior = settings('get','highlightBehavior') + + var re + var style = null + + // Built-in `!! … !!`/`~~ … ~~` markers establish the initial style. + for (const [key,color] of Object.entries(colorsByStatus)) { + re = color.re.exec(txt) + if (re) { + style = color.style + break + } + } + + // User-defined rules run after built-ins and can therefore override them. + const customHighlights = settings('get','customHighlights') || [] + for (const customHighlight of customHighlights) { + let customType = customHighlight.type + if (customType=="highlight") { + let char = customHighlight.value + let reg = new RegExp(`\\${char} (.*) \\${char}`,"g") + re = reg.exec(txt) + if (re) { + style = customHighlight.style + break + } + } + + if (type=="reply" && customType=="reply") { + style = customHighlight.style + } + + if (type=="dateModified" && customType=="dateModified") { + style = customHighlight.style + if (style.background) { + // Append an alpha byte to a hex background based on urgency. + let a = Math.floor(txt * 255).toString(16); + style.background = style.background + a + } + } + + if (type=="userModified" && customType=="userModified") { + style = customHighlight.style + } + + if (type=="report" && customType=="report") { + if (customHighlight.value==txt) { + element.classList.add("reportTitle") + style = customHighlight.style + } + } + + if (type=="report" && customType=="report-regex") { + if ((new RegExp(customHighlight.value).exec(txt))) { + element.classList.add("reportTitle") + style = customHighlight.style + } + } + + if (type=="person" && customType=="person") { + if (customHighlight.value==txt) { + element = createHighlightBubble(element) + style = customHighlight.style + } + } + } + + if (style) { + //console.log("Apply custom highlight:",txt) + + let link = element.querySelector("a") + if (behavior==="block") { + // Block mode removes marker characters from the link label. + if (re && link) { + let newTitle = re[1] + link.innerText = newTitle + //reset regex + re.lastIndex = 0 + } + } else { + if (re && link) { + let text = link.innerText + link.innerText = "" + element = link.appendChild(document.createElement("span")) + element.innerText = text + element.style.lineHeight = "1.4" + //reset regex + re.lastIndex = 0 + } + } + + for (const [attr,val] of Object.entries(style)) { + element.style[attr] = val + } + //element.style.backgroundColor = style.background + + } else { + //apply defaults + if (type=="reply") { + element.style.backgroundColor = "var(--col-reply)"; + + } + if (type=="userModified") { + element.style.backgroundColor = "var(--col-modified)"; + } + if (type=="dateModified") { + element.style.backgroundColor = `rgba(255,0,0,${txt}`; + } + // if (type=="status"){ + // if (txt=="In Process") { + // element.style.backgroundColor = "red" + // } + // } + if (type=="age") { + element.style.backgroundColor = `rgba(255,0,0,${txt}`; + } + } + } + + /** Reserved extension point for a shared pop-up creator; currently unused. */ + function generatePopup(href,w,h,l,t,source) { + + } + + /** + * Adds the generated CSS to a shadow root or iframe document once. For + * iframe editors it also applies the current color-mode class to the frame. + */ + function injectOtherStyles(element) { + + let s = document.createElement("style") + s.id = "customStyles" + s.innerText = customStyles + + //find iframes - likely text editors + if (element.tagName == "IFRAME") { + // Iframes have a separate document; page styles do not cross this boundary. + let frame = element.contentWindow.document; + + //attempt color coded tables on non-desktop pages + /*let tables = frame.querySelectorAll("table"); + [...tables].forEach(table=>{ + parseTable(table.parentElement) + })*/ + + //console.log("Found iFrame:",frame) + + //check for existing style block + if (!frame.querySelector("#customStyles")) { + let head = frame.querySelector("head") + let html = frame.querySelector("html") + html.classList.add(settings("get","colorMode")) + head.appendChild(s) + } + } else { + // Shadow roots accept a style element directly but cannot see page CSS. + if (!element.querySelector("#customStyles")) { + setCssFilters(s) + element.appendChild(s) + } + } + } + + /** Injects this userscript's styles and readable text color into CKEditor. */ + function ckeinjectCustomCss(event) { + // var editor = event.editor + try { + if (!(event.document.$.getElementById("tdxuserscript-style"))) { + var style = event.document.$.createElement('style'); + style.id = "tdxuserscript-style" + style.innerHTML = customStyles + event.document.$.getElementsByTagName('head')[0].appendChild(style); + event.document.$.querySelectorAll("div, span").forEach((element) => { + element.style.color = "var(--txt-1)" + }) + } + } catch(error) {} + } + + /** + * Keeps enhancements active in TDX's single-page UI as it replaces feed, + * dashboard, side-panel, and rich-text-editor content. + */ + let observer = new MutationObserver((mutations) => { + mutations.forEach((mutation) => { + let t = mutation.target + if (t.querySelector("div > table")) { + //let table = t.firstElementChild.querySelector("table") + //console.log("Matched table",t) + + //potential cause of freezing issue + //parseTable(t) + } + + //parse the feed if it updates + if (t.classList.contains("feed")) { + // Only process added feed content rather than reparsing the whole ticket. + parseTicket(mutation.addedNodes) + } else if (t.classList.contains("feed-body")) { + parseTicket(t.querySelectorAll(".feed-reply")) + } + + //force contrastive colors in comments/replies with inline styles + document.querySelectorAll("div.feed-item-text *:not(a)").forEach(textBlock=>{ + textBlock.style.color = "var(--txt-1)" + }) + + //parse dashboard widgets + if (t.id=="tdx-workmgmt-container-collection") { + parseOtherElements() + } + + //parse side panels + if (t.classList.contains("tdx-right-side-panel")) { + parseOtherElements() + } + + // A new widget container may contain an embed-style report title. + let module = t.querySelector("div > .tdx-dashboard__widget-container") + if (module) { + updateHeading(t) + } + + try { + for (const instance in CKEDITOR.instances) { + ckeinjectCustomCss(CKEDITOR.instances[instance]); + } + } catch (error) {} + + //search whole document, frames may reset when reopened + // let frames = document.querySelectorAll("iframe:not(.customEmbed)") + // if (frames) { + // [...frames].forEach(frame=>{ + // injectOtherStyles(frame) + // }); + // } + }); + }); + + if (true) { + console.log("Observing...") + observer.observe(document.body, { + characterDataOldValue: false, + subtree: true, + // Child-list changes cover TDX's dynamically rendered view updates. + childList: true, + characterData: false + }); + } + + /** Sets the product header text, then inserts the toolbar controls. */ + async function changeTitle() { + let title = document.querySelector(".tdx-headerbar-headline a") + if (title) { + title.innerText = primaryTitle + } + + await injectToolbar() + } + + /** Stores a color choice and immediately applies the corresponding CSS value. */ + function colorChange(color) { + localStorage.setItem("colors",color) + setColors(color) + } + + /** + * Updates CSS custom properties for a custom accent/background or a named + * theme. `value` is either a CSS color or a theme suffix such as `gold`. + */ + function setColors(color,value) { + console.log("Setting",color,"to",value) + //let col = tinycolor(value).toRgbString() + let col = value + let style = document.documentElement.style + + switch(color) { + case 'primaryColor': + style.setProperty('--dark-col-primary', col); + style.setProperty('--light-col-primary', col); + break + + case 'backgroundColor': + style.setProperty('--dark-bg-primary', col); + style.setProperty('--light-bg-primary', col); + break + + case 'theme': { + + for (const col of ["dark","light"]) { + let accent = `var(--${col}-${value}-accent)` + let bg = `var(--${col}-${value}-bg)` + style.setProperty(`--${col}-col-primary`, accent) + style.setProperty(`--${col}-bg-primary`, `var(--${col}-bg-default)`) + + } + + break + } + } + } + + /** + * Calculates filters that recolor monochrome icons to the current accent. + * When an element is supplied, its inline style receives the filter vars; + * otherwise they are stored on the document root. + */ + function setCssFilters(element=null) { + let style = element ? element.style : document.documentElement.style + //quick test for filter generation + let mode = getColorMode().split("Mode")[0] + // Filters start from black; derive target RGB from the active primary color. + let priCol = window.getComputedStyle(document.body).getPropertyValue("--dark-col-primary") + let rgb = hexToRgb(priCol) + //let filters = getFilterForColor(rgb) + + const color = new Color(rgb[0], rgb[1], rgb[2]); + const solver = new Solver(color); + const result = solver.solve(); + let filters = result.filter + + //console.log("STYLES:",priCol) + //console.log("FILTERS:",priCol,rgb,filters) + + style.setProperty("--filter-brightness",filters.brightness) + style.setProperty("--filter-contrast",filters.contrast) + style.setProperty("--filter-hue-rotate",filters.hue_rotate) + style.setProperty("--filter-invert",filters.invert) + style.setProperty("--filter-saturate",filters.saturate) + style.setProperty("--filter-sepia",filters.sepia) + } + + /* + function toggleColorMode() { + let mode = getColorMode() == "darkMode" ? "lightMode" : "darkMode" + setColorMode(mode) + } + + */ + + /** Returns the operating system's current light/dark preference. */ + function getColorMode() { + let mode = window.matchMedia('(prefers-color-scheme: dark)').matches ? "darkMode" : "lightMode" + return mode + } + + /** + * Activates an explicit or automatic color mode. Automatic mode follows the + * OS and is persisted as `auto` when it matches the current preference. + */ + function setColorMode(mode,store=true) { + if (!mode) { + mode = "auto" + } + console.log("Set color mode to",mode) + colorScheme = mode + var storageMode = mode + + let autoScheme = getColorMode() + if (autoScheme == mode) { + storageMode = "auto" + } + + if (mode == "auto" || storageMode == "auto") { + // No explicit class lets the CSS media queries follow the OS preference. + mode = autoScheme + document.documentElement.classList.remove("lightMode") + document.documentElement.classList.remove("darkMode") + } else { + document.documentElement.classList.add(mode) + } + + if (store) { + localStorage.setItem("styles",storageMode) + } + + } + + try { + CKEDITOR.on('instanceReady', function(event) { + ckeinjectCustomCss(event) + }) + } catch (error) {} + + /** + * Builds the TDX Tools link, service-status control, and settings menu, + * attaches their listeners, then populates the current IT status. + */ + async function injectToolbar() { + let iconBar = document.querySelector("#globalSearchBar") + + // Kept as strings so a single insertion creates the complete status control. + let statusHTML = ` +
+ + +
+ ` + + let toolsHTML = ` +
+ +
+ ` + + let buttonHTML = ` +
+ +
+ ` + + // Form names intentionally match localStorage setting keys used by settings(). + let settingsHTML = ` + + + ` + + let settingsButton = document.createElement("span") + settingsButton.innerHTML = buttonHTML + + let settingsPage = document.createElement("div") + settingsPage.innerHTML = settingsHTML + + let statusLink = document.createElement("span") + statusLink.innerHTML = statusHTML + + let toolsLink = document.createElement("span") + toolsLink.innerHTML = toolsHTML + + if (iconBar) { + // The wrench follows TDX's global search bar to match header icon placement. + iconBar.after(settingsButton) + + //settings + //settingsPage.querySelector("#colorMode").onclick = toggleColorMode + settingsButton.querySelector("#settingsButton").addEventListener("click",()=>{ + settings("toggle",settingsPage) + }) + settingsButton.appendChild(settingsPage) + + //form changes + let form = settingsPage.querySelector("form") + form.addEventListener("change", (event)=>{ + // Persist all controls together, including the hidden JSON text input. + settings("update",form) + }); + form.addEventListener("submit", (event)=>{ + event.preventDefault() + }); + + //send/recieve data from popup + // The editor runs on the TDX Tools origin and communicates via postMessage. + let customColorButton = settingsPage.querySelector("#colorPopup") + customColorButton.addEventListener("click", (event)=>{ + let url = `${tdxtoolsUrl}/ecnuds/tdx/userscript/coloreditor` + let colorWindow = window.open(url,"TDX Color Editor","popup=true") + colorWindow.onload = function() { + colorWindow.postMessage({msg:"here's the data"},"*") + } + }); + + //links + let parent = iconBar.parentElement + + //tools + parent.prepend(toolsLink) + + //status + parent.prepend(statusLink) + let statusData = await getITStatus() + let statusIcon = statusLink.querySelector("#statusIcon") + let statusTime = statusLink.querySelector("#statusTime") + let statusText = statusLink.querySelector("#statusText") + + let operationalText = "All systems operational." + //check the first 5 words. do they contain operational or green? + //since the default message can vary sometimes + // Treat variants beginning with "operational" or "green" as healthy. + let operationalRegex = /^(?=(?:\w+\s){0,5}?(?:operational|green)\b(?!-))(\w+(?:\s\w+){0,5})/gm + + if (statusData) { + if (statusData.msg.length==0) { + statusData.msg = operationalText + } + } else { + statusData = { + msg: operationalText + } + } + + if (!operationalRegex.test(statusData.msg)) { + statusIcon.classList = ("fa-solid fa-triangle-exclamation") + } else { + statusIcon.classList = ("fa-solid fa-check") + } + + // A missing timestamp displays Moment's invalid-date text; message still works. + let statusTimeParsed = moment(statusData.time) + statusTime.innerText = statusTimeParsed.fromNow() + statusText.innerText = statusData.msg + } + } + + /** + * Fetches the latest public Purdue IT status message, or null when none + * exists. The endpoint currently returns `Results`; this code interprets + * Results[0] as a timestamp and Results[1] as the display message. + */ + async function getITStatus() { + let url = "https://it.purdue.edu/api-status/messages.php" + let res = await fetch(url) + let data = await res.json() + + let msg = {} + + let msgs = data.Results + if (msgs.length>0) { + msg = { + time: msgs[0], + msg: msgs[1] + } + console.warn("IT Message:",msg) + } else { + msg = null + } + + return msg + } + + /* SETTINGS */ + + /** + * Single access point for `userSettings` in localStorage. + * - apply: synchronize controls and runtime CSS/classes + * - get: return one setting (or all settings) + * - toggle: show/hide the settings menu + * - update: serialize the form and reapply settings + * + * Default keys are colorMode, linkBehavior, highlightBehavior, and + * customHighlights. Optional form keys include theme, primaryColor, + * backgroundColor, stickyColumns, and aiBehavior. customHighlights is saved + * as JSON because form data contains only strings, then decoded on read. + */ + function settings(action,value=null) { + var data + var menu + try { + // Read once per operation so callers always receive the latest saved preferences. + data = JSON.parse(localStorage.getItem("userSettings")) + + if (!data) { + throw "Data is null" + } else { + //resolve stringified objects + if ('customHighlights' in data) { + // The form stores this array as a JSON string, unlike simple controls. + data.customHighlights = JSON.parse(data.customHighlights) + } + } + } catch(e) { + //console.error("Couldn't grab settings!",e) + //set defaults + data = { + colorMode: getColorMode(), + linkBehavior: "tabs", + highlightBehavior: "block", + customHighlights: [], + } + } + + switch(action) { + case 'apply': { + for (const setting in data) { + // Mirror storage into the menu if it has already been injected. + let form = document.forms.settingsForm + let value = data[setting] + + if (typeof value == "object") { + value = JSON.stringify(value) + } + + console.log("Apply setting:",setting,value) + try { + if (form) { + let elements = form.elements + form[setting].value = value + if (form[setting].type=="checkbox") { + form[setting].checked = value=="enabled" ? true : false + } + } + } catch {} + } + + if ('colorMode' in data) { + setColorMode(data.colorMode) + } + + if ('theme' in data) { + if (data.theme=="custom") { + setColors('primaryColor',data.primaryColor) + setColors('backgroundColor',data.backgroundColor) + } else { + setColors('theme',data.theme) + } + } + break + } + + case 'get': { + if (value) { + return value in data ? data[value] : null + } else { + // Text mode preserves surrounding cell content and styles only the link. + return data + } + break + } + + case 'toggle': { + let menu = document.querySelector("#settingsMenu") + // Toggle mutually exclusive state classes expected by the injected CSS. + let newState = menu.classList.contains("show") ? "hide" : "show" + let oldState = newState=="show" ? "hide" : "show" + menu.classList.add(newState) + menu.classList.remove(oldState) + break + } + + case 'update': { + let form = document.querySelector("#settingsForm") + // FormData omits unchecked checkboxes, which leaves stickyColumns absent. + let formData = new FormData(form) + data = Object.fromEntries([...formData]) + console.log("Settings update!",data) + localStorage.setItem("userSettings",JSON.stringify(data)) + settings("apply") + setCssFilters() + } + } + } + + /** Placeholder for validation/migration of custom highlight definitions. */ + function parseCustomHighlights(data) { + console.log("Custom highlights:",data) + } + + /* TDX TOOLS */ + /** + * Handles the SSO API callback opened by TDX Tools: forwards the displayed + * key to the opener, then closes the temporary browser window. + */ + function checkPath() { + let path = document.location.pathname + if (path=="/TDWebApi/api/auth/loginsso") { + // This route renders the SSO token as plain text in a
 element.
+            let pre = document.querySelector("pre")
+            if (pre) {
+                console.log("Got key!",pre.innerText)
+                let key = pre.innerText
+                window.opener.postMessage({tdxkey:key},tdxtoolsUrl)
+                window.close()
+            }
+        }
+    }
+
+    /** Exchanges custom-highlight data with the companion color-editor window. */
+    window.addEventListener("message",(event) => {
+        let data = event.data
+        let origin = event.origin
+        let trgt = event.currentTarget
+        console.log("Message from:",origin,data,event)
+
+        if (data.colorsReady) {
+            // Send the editor the current array so it can initialize its controls.
+            let colors = settings('get','customHighlights')
+            event.source.postMessage({ customColors: colors }, "*")
+        }
+        if (data.colorData) {
+            // Write edited data to the hidden form field, then use normal persistence.
+            let element = document.getElementById("customHighlights")
+            let strData = JSON.stringify(data.colorData)
+            element.value = strData
+            settings('update')
+        }
+    },false);
+
+    // Bootstrap existing TDX content immediately; asynchronous UI changes use observer.
+    changeTitle()
+    //checkColorMode()
+    settings("apply")
+    parseTicket()
+    checkPath()
+
+    addEventListener("storage", (event) => {
+        //console.log("Storage event:",event)
+        if (event.key == "userSettings") {
+            // Keep another open TDX tab synchronized after a settings change.
+            settings("apply")
+        }
+    });
+
+    /**
+     * TDX visual override sheet. Sections are ordered by UI area so selectors
+     * can be maintained alongside the corresponding TeamDynamix component.
+     */
+    var customStyles = `
+
+/* Root Styles: theme variables, computed colors, and reusable semantic tokens. */
+
+:root {
+
+    --dark-bg-default: #000;
+    --light-bg-default: #fff;
+
+    --dark-col-default: #ab9266;
+    --light-col-default: #cbb080;
+
+    --dark-col-primary: var(--dark-col-default);
+    --light-col-primary: var(--light-col-default);
+
+    --dark-bg-primary: var(--dark-bg-default);
+    --light-bg-primary: var(--light-bg-default);
+
+    --dark-gold-accent: #ab9266;
+    --light-gold-accent: #c3aa7f;
+
+    --dark-col-green: #295f29;
+    --dark-col-red: #912c2c;
+    --dark-col-blue: #32577a;
+    --dark-col-yellow: #654a24;
+
+    --light-col-green: #e3fcea;
+    --light-col-red: #ff6190;
+    --light-col-blue: #e1f5fc;
+    --light-col-yellow: #ffefd8;
+
+    /* Original TDX blue */
+    --dark-blue-accent: #4c778d;
+    --light-blue-accent: #4b3bb9;
+
+    --dark-green-accent: #559170;
+    --light-green-accent: var(--dark-green-accent);
+
+    --filter-invert: 0;
+    --filter-sepia: 0;
+    --filter-saturate: 0;
+    --filter-hue-rotate: 0;
+    --filter-brightness: 0;
+    --filter-contrast: 0;
+
+    --dark-bg-0: color-mix(in srgb,var(--dark-bg-primary),#fff 5%);
+    --dark-bg-1: color-mix(in srgb,var(--dark-bg-primary),#fff 12%);
+    --dark-bg-2: color-mix(in srgb,var(--dark-bg-primary),#fff 20%);
+    --dark-bg-3: color-mix(in srgb,var(--dark-bg-primary),#fff 25%);
+    --dark-bg-4: color-mix(in srgb,var(--dark-bg-primary),#fff 30%);
+    --dark-col-100: color-mix(in srgb,var(--dark-col-primary),#000 70%);
+    --dark-col-200: color-mix(in srgb,var(--dark-col-primary),#000 60%);
+    --dark-col-300: color-mix(in srgb,var(--dark-col-primary),#000 50%);
+    --dark-col-400: var(--dark-col-primary);
+    --dark-col-500: color-mix(in srgb, var(--dark-col-primary), #aaa 50%);
+    --dark-col-600: color-mix(in srgb,var(--dark-col-primary),#fff 35%);
+    --dark-col-700: color-mix(in srgb,var(--dark-col-primary),#fff 25%);
+    --dark-col-link: #d1dbff;
+    --dark-txt-0: #bbb;
+    --dark-txt-1: #fff;
+    --dark-txt-2: #ececec;
+    --dark-txt-3: #929292;
+    --dark-txt-4: #ffffff8c;
+    --dark-txt-5: var(--light-txt-1);
+    --dark-border-0: color-mix(in srgb,var(--dark-bg-primary),#fff 18%);
+    --dark-border-1: color-mix(in srgb,var(--dark-bg-primary),#fff 30%);
+    --dark-col-reply: #1e3438;
+    --dark-col-highlight-1: #ffdb0059;
+    --dark-col-highlight-2: #5f00ff5e;
+    --dark-col-currentuser: #09482f;
+    --dark-col-modified: #ff660012;
+    --dark-txt-invert: 1;
+    --dark-txt-hue: 180deg;
+    --dark-shadow-1: rgba(200, 200, 200, 0.1);
+    --dark-shadow-2: rgba(200, 200, 200, 0.06);
+
+    --light-txt-1: #000;
+    --light-txt-2: #222;
+    --light-txt-3: #333;
+    --light-txt-4: #0000008c;
+    --light-txt-5: var(--dark-txt-1);
+    --light-col-100: color-mix(in srgb,var(--light-col-primary),#fff 85%);
+    --light-col-200: color-mix(in srgb,var(--light-col-primary),#fff 75%);
+    --light-col-300: color-mix(in srgb,var(--light-col-primary),#fff 65%);
+    --light-col-400: var(--light-col-primary);
+    --light-col-500: color-mix(in srgb, var(--light-col-primary), #aaa 50%);
+    --light-col-600: color-mix(in srgb,var(--light-col-primary),#111 70%);
+    --light-col-700: color-mix(in srgb,var(--light-col-primary),#000 75%);
+    --light-bg-0: color-mix(in srgb,var(--light-bg-primary),#000 0%);
+    --light-bg-1: color-mix(in srgb,var(--light-bg-primary),#000 7%);
+    --light-bg-2: color-mix(in srgb,var(--light-bg-primary),#000 13%);
+    --light-bg-3: color-mix(in srgb,var(--light-bg-primary),#000 20%);
+    --light-bg-4: color-mix(in srgb,var(--light-bg-primary),#000 25%);
+    --light-bg-5: color-mix(in srgb,var(--light-col-primary),#ffffffd7 75%);
+    --light-border-0: color-mix(in srgb,var(--light-bg-primary),#000 18%);
+    --light-border-1: color-mix(in srgb,var(--light-bg-primary),#000 30%);
+    --light-col-reply: #d3f2ff;
+    --light-col-highlight-1: #fff3c4;
+    --light-col-highlight-2: #e3c4ff;
+    --light-col-currentuser: #5de2ad;
+    --light-col-modified: #ffe8d1;
+    --light-txt-invert: 0;
+    --light-txt-hue: 0deg;
+    --light-shadow-1: rgba(50, 50, 50, 0.1);
+    --light-shadow-2: rgba(50, 50, 50, 0.06);
+
+    --body-text-color: var(--txt-0);
+}
+
+@media (prefers-color-scheme: light) {
+:root {
+color-scheme: light;
+--bg-0: var(--light-bg-0);
+--bg-1: var(--light-bg-1);
+--bg-2: var(--light-bg-2);
+--bg-3: var(--light-bg-3);
+--bg-4: var(--light-bg-4);
+        --bg-5: var(--light-bg-5);
+        --col-100: var(--light-col-100);
+--col-200: var(--light-col-200);
+        --col-300: var(--light-col-300);
+--col-400: var(--light-col-400);
+        --col-500: var(--light-col-500);
+--col-600: var(--light-col-600);
+        --col-700: var(--light-col-700);
+--col-link: var(--light-col-link);
+--txt-0: var(--light-txt-0);
+--txt-1: var(--light-txt-1);
+--txt-2: var(--light-txt-2);
+--txt-3: var(--light-txt-3);
+--txt-4: var(--light-txt-4);
+        --txt-5: var(--light-txt-5);
+        --txt-invert: var(--light-txt-invert);
+        --txt-hue: var(--light-txt-hue);
+--border-0: var(--light-border-0);
+        --border-1: var(--light-border-1);
+--col-reply: var(--light-col-reply);
+--col-highlight-1: var(--dark-col-highlight-1);
+--col-highlight-2: var(--dark-col-highlight-2);
+--col-currentuser: var(--light-col-currentuser);
+--col-modified: var(--dark-col-modified);
+        --shadow-1: var(--light-shadow-1);
+        --shadow-2: var(--light-shadow-2);
+        --filter-brightness: var(--light-filter-brightness);
+        --filter-invert: var(--light-filter-invert);
+}
+}
+
+@media (prefers-color-scheme: dark) {
+:root {
+color-scheme: dark;
+--bg-0: var(--dark-bg-0);
+--bg-1: var(--dark-bg-1);
+--bg-2: var(--dark-bg-2);
+--bg-3: var(--dark-bg-3);
+--bg-4: var(--dark-bg-4);
+        --bg-5: var(--dark-bg-5);
+        --col-100: var(--dark-col-100);
+--col-200: var(--dark-col-200);
+        --col-300: var(--dark-col-300);
+--col-400: var(--dark-col-400);
+        --col-500: var(--dark-col-500);
+--col-600: var(--dark-col-600);
+        --col-700: var(--dark-col-700);
+        --col-red: var(--dark-col-red);
+        --col-green: var(--dark-col-green);
+        --col-blue: var(--dark-col-blue);
+        --col-yellow: var(--dark-col-yellow);
+--col-link: var(--dark-col-link);
+--txt-0: var(--dark-txt-0);
+--txt-1: var(--dark-txt-1);
+--txt-2: var(--dark-txt-2);
+--txt-3: var(--dark-txt-3);
+--txt-4: var(--dark-txt-4);
+        --txt-5: var(--dark-txt-5);
+        --txt-invert: var(--dark-txt-invert);
+        --txt-hue: var(--dark-txt-hue);
+--border-0: var(--dark-border-0);
+        --border-1: var(--dark-border-1);
+--col-reply: var(--dark-col-reply);
+--col-highlight-1: var(--dark-col-highlight-1);
+--col-highlight-2: var(--dark-col-highlight-2);
+--col-currentuser: var(--dark-col-currentuser);
+--col-modified: var(--dark-col-modified);
+        --shadow-1: var(--dark-shadow-1);
+        --shadow-2: var(--dark-shadow-2);
+        --filter-brightness: var(--dark-filter-brightness);
+        --filter-invert: var(--dark-filter-invert);
+}
+}
+
+:root.darkMode {
+    color-scheme: dark;
+    --bg-0: var(--dark-bg-0);
+    --bg-1: var(--dark-bg-1);
+    --bg-2: var(--dark-bg-2);
+    --bg-3: var(--dark-bg-3);
+    --bg-4: var(--dark-bg-4);
+    --bg-5: var(--dark-bg-5);
+    --col-100: var(--dark-col-100);
+    --col-200: var(--dark-col-200);
+    --col-300: var(--dark-col-300);
+    --col-400: var(--dark-col-400);
+    --col-500: var(--dark-col-500);
+    --col-600: var(--dark-col-600);
+    --col-700: var(--dark-col-700);
+    --col-red: var(--dark-col-red);
+    --col-green: var(--dark-col-green);
+    --col-blue: var(--dark-col-blue);
+    --col-yellow: var(--dark-col-yellow);
+    --col-link: var(--dark-col-link);
+    --txt-0: var(--dark-txt-0);
+    --txt-1: var(--dark-txt-1);
+    --txt-2: var(--dark-txt-2);
+    --txt-3: var(--dark-txt-3);
+    --txt-4: var(--dark-txt-4);
+    --txt-5: var(--dark-txt-5);
+    --txt-invert: var(--dark-txt-invert);
+    --txt-hue: var(--dark-txt-hue);
+    --border-0: var(--dark-border-0);
+    --border-1: var(--dark-border-1);
+    --col-reply: var(--dark-col-reply);
+    --col-highlight-1: var(--dark-col-highlight-1);
+    --col-highlight-2: var(--dark-col-highlight-2);
+    --col-currentuser: var(--dark-col-currentuser);
+    --col-modified: var(--dark-col-modified);
+    --shadow-1: var(--dark-shadow-1);
+    --shadow-2: var(--dark-shadow-2);
+    --filter-brightness: var(--dark-filter-brightness);
+    --filter-invert: var(--dark-filter-invert);
+}
+
+:root.lightMode {
+    color-scheme: light;
+    --bg-0: var(--light-bg-0);
+    --bg-1: var(--light-bg-1);
+    --bg-2: var(--light-bg-2);
+    --bg-3: var(--light-bg-3);
+    --bg-4: var(--light-bg-4);
+    --bg-5: var(--light-bg-5);
+    --col-100: var(--light-col-100);
+    --col-200: var(--light-col-200);
+    --col-300: var(--light-col-300);
+    --col-400: var(--light-col-400);
+    --col-500: var(--light-col-500);
+    --col-600: var(--light-col-600);
+    --col-700: var(--light-col-700);
+    --col-red: var(--light-col-red);
+    --col-green: var(--light-col-green);
+    --col-blue: var(--light-col-blue);
+    --col-yellow: var(--light-col-yellow);
+    --col-link: var(--light-col-link);
+    --txt-0: var(--light-txt-0);
+    --txt-1: var(--light-txt-1);
+    --txt-2: var(--light-txt-2);
+    --txt-3: var(--light-txt-3);
+    --txt-4: var(--light-txt-4);
+    --txt-5: var(--light-txt-5);
+    --txt-invert: var(--light-txt-invert);
+    --txt-hue: var(--light-txt-hue);
+    --border-0: var(--light-border-0);
+    --border-1: var(--light-border-1);
+    --col-reply: var(--light-col-reply);
+    --col-highlight-1: var(--dark-col-highlight-1);
+    --col-highlight-2: var(--dark-col-highlight-2);
+    --col-currentuser: var(--light-col-currentuser);
+    --col-modified: var(--dark-col-modified);
+    --shadow-1: var(--light-shadow-1);
+    --shadow-2: var(--light-shadow-2);
+    --filter-brightness: var(--light-filter-brightness);
+    --filter-invert: var(--light-filter-invert);
+}
+
+/* Body: global page background, foreground, and base-surface overrides. */
+
+body {
+    background-color: var(--bg-0) !important;
+    color: var(--txt-1) !important;
+}
+
+::-webkit-scrollbar-track {
+    background: var(--bg-0) !important;
+}
+
+::-webkit-scrollbar-thumb {
+    background: var(--col-400) !important;
+    border: 5px solid var(--bg-0) !important;
+}
+
+::-webkit-scrollbar-thumb:hover {
+    border: 3px solid var(--bg-0) !important;
+    background: var(--col-400) !important;
+}
+
+::-webkit-scrollbar-corner {
+    background-color: var(--bg-0) !important;
+  }
+
+.tdx-overlay {
+    background-color: color-mix(in srgb,var(--col-400),#00000000 25%) !important;
+}
+
+.tdx-overlay__item {
+    background-color: var(--bg-0) !important;
+    color: var(--col-400) !important;
+}
+
+.tdx-overlay__item:hover, .tdx-overlay__item:focus-visible {
+    background-color: var(--col-400) !important;
+    color: var(--col-100) !important;
+}
+
+.tdx-navigation-tab-bar {
+    background-color: initial !important;
+}
+
+.tdx-leftnav__container {
+    background-color: var(--bg-0) !important;
+    border-color: var(--border-0) !important;
+    box-shadow: 0 1px 3px var(--shadow-1),0 2px 10px var(--shadow-2) !important;
+}
+
+.tdx-leftnav__item {
+    color: var(--txt-1) !important;
+}
+
+.tdx-leftnav__item--active .tdx-leftnav__link {
+    background-color: var(--col-100) !important;
+    color: var(--col-400) !important;
+}
+
+.tdx-leftnav__link:hover, .tdx-leftnav__link:focus-visible {
+    background-color: var(--col-100) !important;
+}
+
+.tdx-main-container {
+    background-color: var(--bg-0) !important;
+}
+
+.tdx-layout-option__layout-preview {
+    background-color: var(--col-100) !important;
+}
+
+.tdx-layout-option__column {
+    background-color: var(--bg-0) !important;
+}
+
+.tdx-layout-selector__layout-option:hover, .tdx-layout-selector__layout-option:focus, .tdx-layout-selector__layout-option--selected {
+    background-color: var(--col-400) !important;
+}
+
+.tdx-list__section {
+    color: var(--txt-2);
+}
+
+/* Script-Specific Additions: settings menu, toolbar widgets, badges, and calendars. */
+#settingsMenu {
+    right: 50px;
+    padding: 10px;
+    width: 250px;
+    background: var(--bg-1);
+}
+
+#settingsMenu.hide {
+    visibility: hidden;
+}
+
+#settingsMenu h5 {
+    margin-bottom: 2px;
+}
+
+#settingsMenu h3 {
+    padding-top: 10px;
+    font-weight: 500;
+    font-size: 18px;
+}
+
+#settingsForm .flex {
+    display: flex;
+    gap: 24px;
+    align-items: baseline;
+}
+
+#settingsForm .textBox {
+    display: flex;
+    flex-direction: column;
+    gap: 8px;
+}
+
+.customEmbed {
+    border: 0;
+    width: 100%;
+    height: 400px;
+}
+
+.calBox {
+    display: flex;
+    justify-content: space-around;
+    flex-wrap: wrap;
+    padding-top: 4px;
+    gap: 4px;
+    max-width: 220px;
+}
+
+#statusBox:hover #statusMsg {
+    display: block;
+    width: 400px;
+    line-height: 22px;
+    padding: 8px;
+    right: 390px;
+}
+
+#statusTime, #statusText {
+    margin: 6px;
+}
+
+#statusTime {
+    font-size: 12px;
+}
+
+#statusBox .fa-triangle-exclamation {
+    color: #ff8c4c;
+}
+
+#statusBox .fa-check {
+    color: #0dbb28;
+}
+
+.qBox {
+margin-left: 10px;
+padding: 5px;
+font-size: 20px;
+border-radius: 7px;
+}
+
+.qHighlight {
+padding: 4px;
+border-radius: 8px;
+    border-width: 2px;
+    border-style: solid;
+    white-space: nowrap;
+}
+
+.btn-calendar {
+    flex-grow: 1;
+    padding: 2px;
+    background-color: var(--col-500);
+    color: var(--txt-5);
+}
+
+.btn-calendar:hover {
+    background-color: var(--col-400);
+    color: var(--txt-5)
+}
+
+.reportTitle {
+    border-radius: 12px;
+    padding-left: 10px !important;
+    padding-right: 10px !important;
+}
+
+/* Others: miscellaneous TDX components not covered by a more specific section. */
+.tdx-loading-animation {
+    color: var(--col-400) !important;
+}
+
+.refresh-indicator {
+    background: linear-gradient(180deg,var(--bg-0),hsla(0,0%,100%,0)) !important;
+}
+
+.breadcrumb {
+    background-color: var(--bg-0);
+}
+
+.breadcrumb>.active {
+    color: var(--txt-3);
+}
+
+p.row {
+    gap: 8px;
+}
+
+/* Headers: global navigation, page headings, and drop-down menus. */
+
+h1, h2, h3, h4, h5 {
+    color: var(--txt-1) !important;
+}
+
+.tdx-header-container {
+    background-color: var(--col-100) !important;
+}
+
+.tdx-headerbar-headline, .tdx-headerbar-headline a {
+    color: var(--col-1) !important;
+}
+
+.tdx-headline {
+    color: var(--txt-1) !important;
+}
+
+.tdx-headline--underline {
+    border-color: var(--border-0);
+}
+
+.tdx-navigation-tabs__tab {
+    color: var(--col-600) !important;
+}
+
+.tdx-navigation-tabs__home-tab--active, .tdx-navigation-tabs__tab--active {
+    background-color: var(--bg-0) !important;
+    color: var(--col-400) !important;
+}
+
+.tdx-navigation-tabs__tab:hover:not(.tdx-navigation-tabs__tab--active) {
+    background-color: var(--col-200) !important;
+}
+
+.tdx-navigation-tabs__home-tab:hover {
+    background-color: var(--col-200) !important;
+}
+
+.tdx-navigation-tabs__home-tab--active:hover {
+    background-color: var(--bg-0) !important;
+}
+
+.tdx-dropdown--headline {
+    color: var(--txt-1) !important;
+}
+
+.tdx-dropdown:hover {
+    background-color: var(--col-200) !important;
+}
+
+.tdx-dropdown.active {
+    background-color: var(--col-300) !important;
+}
+
+.tdx-dropdown-popout,
+.tdx-dropdown-popout__menu {
+    background-color: var(--bg-0) !important;
+}
+
+.tdx-dropdown-popout__menu-item {
+    background-color: var(--bg-0) !important;
+    color: var(--txt-1) !important;
+}
+
+.tdx-dropdown-popout__menu-item:hover, .tdx-dropdown-popout__menu-item:focus {
+    color: var(--txt-1) !important;
+    background-color: var(--col-300) !important;
+}
+
+.tdx-dropdown-popout__menu-item--selected {
+    color: var(--col-400) !important;
+}
+
+.tdx-dropdown-popout__header {
+    background-color: var(--bg-0) !important;
+    color: var(--col-600) !important;
+}
+
+.tdx-dropdown-popout__break {
+    border-color: var(--border-0) !important;
+}
+
+.tdx-dropdown__divider {
+    background-color: var(--bg-0) !important;
+}
+
+.tdx-dropdown__divider::before {
+    background: linear-gradient(90deg,var(--bg-0),var(--border-0),var(--border-0),var(--border-0),var(--bg-0)) !important;
+}
+
+.tdx-label {
+    color: var(--txt-1) !important;
+}
+
+/* Inputs: search, lookup, select, text-entry, and tooltip styling. */
+
+.tdx-dropdown--dark,
+.tdx-searchbar__textbox--dark {
+    background-color: var(--col-200) !important;
+    color: var(--txt-1) !important;
+}
+
+.tdx-dropdown--dark:hover, .tdx-dropdown--dark:focus-visible {
+    background-color: var(--col-300) !important;
+}
+
+.tdx-searchbar__textbox:not(.tdx-searchbar__textbox--dark) {
+    background-color: var(--bg-0) !important;
+    color: var(--txt-1) !important;
+}
+
+.tdx-searchbar__textbox:hover:not(:focus), .tdx-searchbar:hover .tdx-searchbar__textbox:not(:focus) {
+    background-color: var(--col-200) !important;
+}
+
+.tdx-searchbar__textbox:focus, .tdx-searchbar__textbox:active, .tdx-searchbar__textbox:focus-within {
+    border-color: var(--col-400) !important;
+}
+
+.tdx-searchbar__textbox::placeholder {
+    color: var(--col-400) !important;
+}
+
+.tdx-searchbar__textbox--dark:hover:not(:focus)::placeholder, .tdx-searchbar:hover .tdx-searchbar__textbox--dark:not(:focus)::placeholder,
+.tdx-searchbar__textbox:hover:not(:focus)::placeholder, .tdx-searchbar:hover .tdx-searchbar__textbox:not(:focus)::placeholder {
+    color: var(--col-400) !important;
+}
+
+input[type=checkbox], input[type=radio] {
+    accent-color: var(--col-400) !important;
+}
+
+.tdx-checkbox {
+    background-color: var(--bg-0) !important;
+    border-color: var(--border-0) !important;
+}
+
+.tdx-checkbox:checked {
+    background-color: var(--col-400) !important;
+}
+
+.tdx-checkbox:checked:disabled {
+    background-color: var(--col-200) !important;
+}
+
+.control-label, label {
+    color: var(--txt-2) !important;
+}
+
+.form-control {
+background-color: var(--bg-0);
+color: var(--txt-2);
+    border-color: var(--border-0);
+}
+
+.form-control:hover {
+    border-color: var(--border-0);
+}
+
+.form-control:focus {
+    border-color: var(--col-400);
+}
+
+.talu_holder .luac_default {
+    color: var(--col-500);
+}
+
+.talu_holder .bit-input input {
+    background-color: var(--bg-0);
+}
+
+.talu_holder .bit-box {
+    background-color: var(--col-100);
+    color: var(--col-600);
+}
+
+.talu_holder .bit-box:hover, .talu_holder .bit-box:active {
+    background-color: var(--col-300);
+    color: var(--col-500);
+}
+
+.talu_holder .bit-box a.closebutton {
+    color: var(--col-600);
+}
+
+.lu_tdac-auto ul {
+    background: var(--bg-0) !important;
+    box-shadow: 0 1px 3px var(--shadow-1),0 2px 10px var(--shadow-2) !important;
+}
+
+.lu_tdac-auto ul li {
+    color: var(--txt-1) !important;
+}
+
+.lu_tdac-auto ul .auto-focus {
+    background-color: var(--col-300);
+    color: var(--col-500);
+}
+
+.lu_tdac-auto ul .auto-focus div.talu_subcaption {
+    color: var(--col-400);
+}
+
+div.WhiteOut {
+    background-color: var(--bg-0) !important;
+}
+
+[role=status]:has(div>div>.tdx-loading-animation) {
+    background-color: var(--bg-0) !important;
+}
+
+.ms-drop .ms-search input::placeholder {
+    color: var(--txt-3);
+}
+
+.ms-choice {
+    background-color: var(--bg-0);
+    color: var(--txt-3);
+}
+
+.ms-drop {
+    background-color: var(--bg-0) !important;
+    border-color: var(--border-0);
+}
+
+button.ms-choice {
+    background-color: var(--bg-0) !important;
+    border-color: var(--border-0) !important;
+}
+
+button.ms-choice:hover {
+    border-color: var(--border-0) !important;
+}
+
+button.ms-choice:focus {
+    border-color: var(--col-400) !important;
+}
+
+.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control {
+background-color: var(--bg-1);
+}
+
+.tdx-lookup-group div.select2-container.form-control a.select2-choices, .input-group div.select2-container.form-control a.select2-choice {
+    border-color: var(--border-0) !important;
+}
+
+.tdx-lookup-group.input-group {
+    background-color: var(--bg-0) !important;
+}
+
+.input-group:not(:has(.input-group-section)):not(.input-group--no-border) {
+    border-color: var(--border-0);
+}
+
+.input-group:focus, .input-group:active, .input-group:focus-within {
+    border-color: var(--col-400) !important;
+}
+
+div.input-group .input-group-btn .btn-file:last-child {
+    color: var(--txt-3);
+}
+
+.tdx-lookup-group {
+    background-color: var(--bg-0);
+    border-color: var(--border-0);
+}
+
+.tdx-lookup-group:hover {
+    border-color: var(--border-0);
+}
+
+.tdx-lookup-group .k-input:hover, .tdx-lookup-group .k-input:focus, .tdx-lookup-group .k-input:focus-within, .tdx-lookup-group.input-group:hover, .tdx-lookup-group.input-group:focus, .tdx-lookup-group.input-group:focus-within, .tdx-lookup-group select:hover, .tdx-lookup-group select:focus, .tdx-lookup-group select:focus-within, .tdx-lookup-group input:hover, .tdx-lookup-group input:focus, .tdx-lookup-group input:focus-within, .tdx-lookup-group input.form-control:hover, .tdx-lookup-group input.form-control:focus, .tdx-lookup-group input.form-control:focus-within {
+    border-color: var(--border-0);
+}
+
+.tdx-lookup-group .k-input, .tdx-lookup-group.input-group, .tdx-lookup-group select, .tdx-lookup-group input, .tdx-lookup-group input.form-control {
+    border-color: var(--border-0);
+}
+
+.tdx-lookup-group .k-svg-icon.k-svg-i-caret-alt-down::after {
+    color: var(--txt-1);
+}
+
+.tdx-lookup-group:focus, .tdx-lookup-group:active, .tdx-lookup-group:focus-within {
+    border-color: var(--col-400);
+}
+
+.tdx-lookup-group .k-input .k-input-inner::selection, .tdx-lookup-group.input-group .k-input-inner::selection, .tdx-lookup-group select .k-input-inner::selection, .tdx-lookup-group input .k-input-inner::selection, .tdx-lookup-group input.form-control .k-input-inner::selection {
+    background-color: var(--bg-2);
+}
+
+.tdx-lookup-group>.select2-container-multi .select2-choices:not(div.attributeValue .select2-container-multi .select2-choices) {
+    border-color: var(--border-0) !important;
+}
+
+.tdx-searchbar__textbox--border {
+    border-color: var(--border-0) !important;
+}
+
+.tdx-lookup-group__input {
+    border-color: var(--border-0) !important;
+}
+
+.tdx-input-group__textbox,
+.tdx-input-group__textarea {
+    color: var(--txt-1) !important;
+    background-color: var(--bg-0) !important;
+    border-color: var(--border-0) !important;
+}
+
+.k-input {
+    background-color: var(--bg-0) !important;
+}
+
+.k-input-solid {
+    background-color: var(--bg-0);
+}
+
+.k-list {
+    background-color: var(--bg-0);
+    color: var(--txt-1);
+}
+
+.k-list-container.k-popup {
+    background-color: var(--bg-0);
+}
+
+.k-list-content .k-list-item:hover, .k-list-content .k-list-item:focus, .k-list-content .k-list-item.k-focus {
+    background-color: var(--col-300);
+    color: var(--txt-1);
+}
+
+.k-list-content .k-list-item {
+    color: var(--txt-1);
+    background-color: var(--bg-0);
+}
+
+.k-popup {
+    color: var(--txt-1);
+}
+
+.k-popup:has(.k-list) {
+    box-shadow: 0 1px 3px var(--shadow-1),0 2px 10px var(--shadow-2);
+}
+
+.tdx-lookup-group .k-input, .tdx-lookup-group.input-group, .tdx-lookup-group select, .tdx-lookup-group input, .tdx-lookup-group input.form-control {
+    color: var(--txt-1);
+}
+
+.tdx-lookup-group .k-input .k-button-solid-base, .tdx-lookup-group.input-group .k-button-solid-base, .tdx-lookup-group select .k-button-solid-base, .tdx-lookup-group input .k-button-solid-base, .tdx-lookup-group input.form-control .k-button-solid-base {
+    background-color: var(--bg-0);
+}
+
+.k-input-md .k-input-inner::placeholder,
+.form-control::placeholder {
+    color: var(--txt-3) !important;
+}
+
+.select2-container .select2-choice, .select2-container .select2-choices, .select2-container .select2-choices .select2-search-field input {
+    background: var(--bg-0) !important;
+}
+
+div.select2-container.form-control .select2-choice.select2-default {
+    border-color: var(--border-0);
+}
+
+.select2-container .select2-choice>.select2-chosen {
+    color: var(--txt-1) !important;
+}
+
+.select2-container .select2-choice.select2-default>.select2-chosen {
+    color: var(--txt-3) !important;
+}
+
+.tdx-lookup-group>.select2-container-multi .select2-choices:not(div.attributeValue .select2-container-multi .select2-choices) .select2-search-field input.select2-default {
+    color: var(--txt-3) !important;
+}
+
+.select2-results .select2-no-results, .select2-results .select2-selection-limit {
+    background: var(--bg-1) !important;
+}
+
+.select2-results .select2-no-results, .select2-results .select2-searching, .select2-results .select2-selection-limit {
+    color: var(--txt-1) !important;
+}
+
+.select2-drop {
+    background: var(--bg-0);
+    color: var(--txt-1);
+}
+
+.select2-drop {
+    color: var(--txt-1) !important;
+    background-color: var(--bg-0);
+}
+
+.select2-drop .select2-search input {
+    background-color: var(--bg-0);
+    border-color: var(--border-0);
+}
+
+.select2-search input {
+    color: var(--txt-1);
+}
+
+div.select2-drop.select2-drop-active, div.select2-drop.select2-drop-above.select2-drop-active {
+    box-shadow: 0 1px 3px var(--shadow-1),0 2px 10px var(--shadow-2);
+    background-color: var(--bg-0);
+}
+
+.select2-drop .select2-results .select2-highlighted {
+    color: var(--txt-1) !important;
+    background-color: var(--col-300);
+}
+
+.select2-results div.select2-result-label {
+    color: var(--txt-1);
+}
+
+.select2-container:focus-within, .select2-container:focus-within a {
+    border-color: var(--col-400) !important;
+}
+
+.form-group:has(select:not([multiple]):not([size])):hover::after {
+    color: var(--col-400) !important;
+}
+
+div.select2-container.form-control .select2-choice, div.js-tagformfield .select2-container-multi .select2-choices, div.js-tags-inlineedit .select2-container-multi .select2-choices, div.attributeValue .select2-container-multi .select2-choices, div.select2-listbox .select2-container-multi .select2-choices, div.select2-container.form-control.select2-container-multi .select2-choices {
+    border-color: var(--border-0);
+}
+
+div.select2-container.form-control .select2-choice:hover, div.js-tagformfield .select2-container-multi .select2-choices:hover, div.js-tags-inlineedit .select2-container-multi .select2-choices:hover, div.attributeValue .select2-container-multi .select2-choices:hover, div.select2-listbox .select2-container-multi .select2-choices:hover, div.select2-container.form-control.select2-container-multi .select2-choices:hover {
+    border-color: var(--border-0);
+}
+
+div.select2-container-multi .select2-choices .select2-search-choice {
+    background-color: var(--col-100);
+    color: var(--col-600);
+}
+
+div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close {
+    color: var(--col-600) !important;
+}
+
+div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:hover, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:focus-visible, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:active, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:active:hover, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:focus:active, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:focus:hover {
+    color: var(--col-400) !important;
+}
+
+div.select2-container-multi .select2-choices .select2-search-choice:hover, div.select2-container-multi .select2-choices .select2-search-choice:active {
+    background-color: var(--col-300);
+    color: var(--col-500);
+}
+
+select.form-control:hover:not(:focus),
+select.form-control {
+    border-color: var(--border-0);
+}
+
+.k-chip-solid-base {
+    background-color: var(--col-100) !important;
+    color: var(--col-600) !important;
+}
+
+.k-chip-action {
+    color: var(--col-600) !important;
+}
+
+.k-chip-action:hover, .k-chip-action:focus-visible, .k-chip-action:active, .k-chip-action:active:hover, .k-chip-action:focus:active, .k-chip-action:focus:hover {
+    color: var(--col-400) !important;
+}
+
+.tooltip-inner {
+    background-color: var(--bg-0);
+    color: var(--txt-1);
+    box-shadow: 0 .5px 1px 1px var(--shadow-1),0 2px 4px var(--shadow-2),0 4px 6px var(--shadow-2);
+}
+
+div#ui-datepicker-div .ui-datepicker-title select, div#ui-datepicker-div .ui-timepicker-div.ui-timepicker-oneLine select, div.ui-datepicker .ui-datepicker-title select, div.ui-datepicker .ui-timepicker-div.ui-timepicker-oneLine select {
+    color: var(--txt-1);
+    border-color: var(--bg-0);
+    background-color: var(--bg-0);
+}
+
+div#ui-datepicker-div .ui-datepicker-title select:hover, div#ui-datepicker-div .ui-timepicker-div.ui-timepicker-oneLine select:hover, div.ui-datepicker .ui-datepicker-title select:hover, div.ui-datepicker .ui-timepicker-div.ui-timepicker-oneLine select:hover {
+    border-color: var(--border-0);
+}
+
+div#ui-datepicker-div .ui-state-default, div#ui-datepicker-div .ui-state-default:hover, div.ui-datepicker .ui-state-default, div.ui-datepicker .ui-state-default:hover {
+    border-color: var(--bg-0) !important;
+}
+
+div#ui-datepicker-div .ui-datepicker-header, div.ui-datepicker .ui-datepicker-header {
+    background: var(--col-100) !important;
+}
+
+div#ui-datepicker-div th, div#ui-datepicker-div td, div.ui-datepicker th, div.ui-datepicker td {
+    color: var(--txt-1);
+}
+
+div#ui-datepicker-div .ui-state-highlight, div#ui-datepicker-div .ui-widget-content .ui-state-highlight, div#ui-datepicker-div .ui-widget-header .ui-state-highlight, div.ui-datepicker .ui-state-highlight, div.ui-datepicker .ui-widget-content .ui-state-highlight, div.ui-datepicker .ui-widget-header .ui-state-highlight {
+    background: var(--col-100) !important;
+    color: var(--col-400) !important;
+}
+
+button:has(>.ui-icon-circle-triangle-e), span:has(>.ui-icon-circle-triangle-e), a:has(>.ui-icon-circle-triangle-e), button:has(>.fa-chevron-circle-right), span:has(>.fa-chevron-circle-right), a:has(>.fa-chevron-circle-right),
+button:has(>.ui-icon-circle-triangle-w), span:has(>.ui-icon-circle-triangle-w), a:has(>.ui-icon-circle-triangle-w), button:has(>.fa-chevron-circle-left), span:has(>.fa-chevron-circle-left), a:has(>.fa-chevron-circle-left) {
+    color: var(--col-400);
+}
+
+/* Links: standard anchors, navigation badges, grouping rows, and link buttons. */
+
+.tdx-dashboard__widget-container a:not(.btn):not(.k-icon) {
+    color: var(--col-400) !important;
+}
+
+.tdx-dashboard__widget-container a:not(.btn):not(.k-icon):hover, .tdx-dashboard__widget-container a:not(.btn):not(.k-icon):focus-visible {
+    color: var(--col-500) !important;
+}
+
+a {
+    color: var(--col-400);
+    background-color: initial !important;
+}
+
+a:hover, a:focus-visible,
+.tdworkmgmt td a.visited-link:hover, .tdworkmgmt td a.visited-link:focus-visible {
+    color: var(--col-500) !important;
+}
+
+a:visited,
+.tdworkmgmt td a.visited-link,
+.tdworkmgmt td a:visited, .tdworkmgmt.table .hilite a:visited {
+    color: var(--col-400);
+}
+
+.tdworkmgmt.table-contents div.row > div > a {
+    color: var(--col-400);
+}
+
+.tdworkmgmt.table-striped > tbody > tr.tdx-grid__group-header > td, .tdworkmgmt.table-bordered > tbody > tr.tdx-grid__group-header > td {
+    background-color: var(--col-100);
+}
+
+.tdx-time-panel, .tdx-time-panel__heading {
+  color: var(--txt-1) !important;
+  background-color: var(--bg-1) !important;
+  border: 1px solid var(--border-0) !important;
+}
+
+.tdx-leftnav__badge {
+  color: var(--txt-1) !important;
+  background-color: var(--col-300) !important;
+}
+
+body .tdworkmgmt.table.table--vertical-lines > tbody > tr > td:not(:last-of-type) {
+  border-right: 1px solid var(--border-0);
+}
+
+.TDGroupingRow {
+  color: var(--txt-1);
+}
+
+a.disabledLink {
+    color: var(--txt-1) !important;
+}
+
+.k-grid a.tdx-link {
+    color: var(--col-400) !important;
+}
+
+.tdx-link:visited {
+    color: var(--col-400) !important;
+}
+
+.tdx-btn--link {
+    color: var(--col-400) !important;
+}
+
+/* Buttons: primary/secondary/tertiary actions plus calendar and feed controls. */
+.tdx-btn--secondary {
+    background-color: var(--col-200) !important;
+    color: var(--col-400) !important;
+    border: none !important;
+}
+
+.tdx-btn--secondary > a {
+    color: var(--col-400) !important;
+}
+
+.tdx-btn--secondary:hover, .tdx-btn--secondary:hover:focus, .tdx-btn--secondary:focus-visible {
+    background-color: var(--col-300) !important;
+    color: var(--col-600) !important;
+}
+
+.tdx-action-menu-dropdown__popout {
+    background-color: var(--bg-0) !important;
+    box-shadow: 0 1px 3px var(--shadow-1),0 2px 10px var(--shadow-2) !important;
+}
+
+.tdx-action-menu-dropdown-popout__menu-item:not(.tdx-dropdown-popout__header) {
+    background-color: var(--bg-0) !important;
+    color: var(--txt-1) !important;
+}
+
+.tdx-action-menu-dropdown-popout__menu-item:hover, .tdx-action-menu-dropdown-popout__menu-item:focus {
+    background-color: var(--col-300) !important;
+}
+
+.tdx-action-menu__item--primary {
+    color: var(--txt-5) !important;
+    background: var(--col-600) !important;
+    border-color: var(--col-600) !important;
+}
+
+.tdx-action-menu__item--primary:hover, .tdx-action-menu__item--primary:hover:focus, .tdx-action-menu__item--primary:focus-visible {
+    color: var(--txt-5) !important;
+    background: var(--col-400) !important;
+    border-color: var(--col-400) !important;
+}
+
+.tdx-action-menu__item:not(.tdx-action-menu__item--primary) {
+    color: var(--txt-1) !important;
+    background: var(--bg-0) !important;
+}
+
+.tdx-action-menu__item:not(.tdx-action-menu__item--primary):hover, .tdx-action-menu__item.tdx-action-menu__item:not(.tdx-action-menu__item--primary):hover:focus, .tdx-action-menu__item.tdx-action-menu__item:not(.tdx-action-menu__item--primary):focus-visible {
+    background: var(--col-200) !important;
+    color: var(--txt-2) !important;
+}
+
+.tdx-primary-button-override {
+    background-color: var(--col-600) !important;
+    color: var(--txt-5) !important;
+    border-color: var(--col-600) !important;
+}
+
+.tdx-primary-button-override:hover, .tdx-primary-button-override:hover:focus, .tdx-primary-button-override:focus-visible {
+    background: var(--col-400) !important;
+    border-color: var(--col-400) !important;
+    color: var(--txt-5) !important;
+}
+
+.tdx-primary-button-override.active, .tdx-primary-button-override.active:hover, .tdx-primary-button-override.active:focus, .tdx-primary-button-override:active, .tdx-primary-button-override:active:hover, .tdx-primary-button-override:active:focus,
+.tdx-primary-button-override:focus:not(:focus-visible,.active,:active,:hover) {
+    background-color: var(--col-600) !important;
+    color: var(--txt-5) !important;
+    border-color: var(--col-600) !important;
+}
+
+span.input-group-btn .btn-default {
+    color: var(--txt-3);
+}
+
+span.input-group-btn .btn-default:hover, span.input-group-btn .btn-default:focus-visible, span.input-group-btn .btn-default:active, span.input-group-btn .btn-default:active:hover, span.input-group-btn .btn-default:focus:active, span.input-group-btn .btn-default:focus:hover {
+    color: var(--txt-2);
+}
+
+div.input-group .input-group-btn .btn-file:last-child:hover, div.input-group .input-group-btn .btn-file:last-child:hover:focus, div.input-group .input-group-btn .btn-file:last-child:focus-visible {
+    background-color: var(--col-100);
+    color: var(--txt-2);
+}
+
+.btn.active, .btn.active:hover, .btn.active:focus, .btn:active, .btn:active:hover, .btn:active:focus {
+    background: var(--col-300);
+    color: var(--txt-5);
+}
+
+.btn-default {
+    color: var(--txt-1);
+}
+
+.btn-default:hover, .btn-default:hover:focus, .btn-default:focus-visible {
+    background: var(--col-200);
+    color: var(--txt-1);
+}
+
+.tdx-btn--tertiary {
+    color: var(--txt-1);
+}
+
+.tdx-btn--tertiary:hover {
+    background: var(--col-200);
+    color: var(--txt-2);
+}
+
+.tdx-btn--primary {
+    background-color: var(--col-600) !important;
+    color: var(--txt-5) !important;
+    border-color: var(--col-600) !important;
+}
+
+.tdx-btn--primary:hover, .tdx-btn--primary:hover:focus, .tdx-btn--primary:focus-visible {
+    background: var(--col-400) !important;
+    border-color: var(--col-400) !important;
+    color: var(--txt-5) !important;
+}
+
+.feed-button-group .btn-primary:hover, .feed-button-group .btn-primary:hover:focus, .feed-button-group .btn-primary:focus-visible {
+    background: var(--col-200);
+}
+
+.feed-button-group .btn-primary.active, .feed-button-group .btn-primary.active:hover, .feed-button-group .btn-primary.active:focus, .feed-button-group .btn-primary:active, .feed-button-group .btn-primary:active:hover, .feed-button-group .btn-primary:active:focus {
+    background: var(--col-300);
+}
+
+#btnSave.btn-primary, #btnClientSave.btn-primary, #btnRunReport.btn-primary, #btnApply.btn-primary, #btnAddSelected.btn-primary, #btnSubmit.btn-primary {
+    color: var(--txt-5) !important;
+    background-color: var(--col-500) !important;
+    border-color: var(--col-500) !important;
+}
+
+#btnSave.btn-primary:hover, #btnSave.btn-primary:hover:focus, #btnSave.btn-primary:focus-visible, #btnClientSave.btn-primary:hover, #btnClientSave.btn-primary:hover:focus, #btnClientSave.btn-primary:focus-visible, #btnRunReport.btn-primary:hover, #btnRunReport.btn-primary:hover:focus, #btnRunReport.btn-primary:focus-visible, #btnApply.btn-primary:hover, #btnApply.btn-primary:hover:focus, #btnApply.btn-primary:focus-visible, #btnAddSelected.btn-primary:hover, #btnAddSelected.btn-primary:hover:focus, #btnAddSelected.btn-primary:focus-visible, #btnSubmit.btn-primary:hover, #btnSubmit.btn-primary:hover:focus, #btnSubmit.btn-primary:focus-visible {
+    background: var(--col-400) !important;
+    border-color: var(--col-400) !important;
+    color: var(--txt-5) !important;
+}
+
+#btnSave.btn-primary.active, #btnSave.btn-primary.active:hover, #btnSave.btn-primary.active:focus, #btnSave.btn-primary:active, #btnSave.btn-primary:active:hover, #btnSave.btn-primary:active:focus, #btnClientSave.btn-primary.active, #btnClientSave.btn-primary.active:hover, #btnClientSave.btn-primary.active:focus, #btnClientSave.btn-primary:active, #btnClientSave.btn-primary:active:hover, #btnClientSave.btn-primary:active:focus, #btnRunReport.btn-primary.active, #btnRunReport.btn-primary.active:hover, #btnRunReport.btn-primary.active:focus, #btnRunReport.btn-primary:active, #btnRunReport.btn-primary:active:hover, #btnRunReport.btn-primary:active:focus, #btnApply.btn-primary.active, #btnApply.btn-primary.active:hover, #btnApply.btn-primary.active:focus, #btnApply.btn-primary:active, #btnApply.btn-primary:active:hover, #btnApply.btn-primary:active:focus, #btnAddSelected.btn-primary.active, #btnAddSelected.btn-primary.active:hover, #btnAddSelected.btn-primary.active:focus, #btnAddSelected.btn-primary:active, #btnAddSelected.btn-primary:active:hover, #btnAddSelected.btn-primary:active:focus, #btnSubmit.btn-primary.active, #btnSubmit.btn-primary.active:hover, #btnSubmit.btn-primary.active:focus, #btnSubmit.btn-primary:active, #btnSubmit.btn-primary:active:hover, #btnSubmit.btn-primary:active:focus {
+    background: var(--col-600) !important;
+    border-color: var(--col-600) !important;
+    color: var(--txt-5) !important;
+}
+
+#btnSave.btn-primary:focus:not(:focus-visible,.active,:active,:hover), #btnClientSave.btn-primary:focus:not(:focus-visible,.active,:active,:hover), #btnRunReport.btn-primary:focus:not(:focus-visible,.active,:active,:hover), #btnApply.btn-primary:focus:not(:focus-visible,.active,:active,:hover), #btnAddSelected.btn-primary:focus:not(:focus-visible,.active,:active,:hover), #btnSubmit.btn-primary:focus:not(:focus-visible,.active,:active,:hover) {
+    background: var(--col-400) !important;
+    border-color: var(--col-400) !important;
+    color: var(--txt-5) !important;
+}
+
+.btn-tertiary, .btn-info, .ButtonCellTopPadding .ButtonCellTop .btn-primary {
+    color: var(--txt-1);
+    background-color: var(--col-100);
+}
+
+.btn-tertiary:hover, .btn-tertiary:hover:focus, .btn-tertiary:focus-visible, .btn-info:hover, .btn-info:hover:focus, .btn-info:focus-visible, .ButtonCellTopPadding .ButtonCellTop .btn-primary:hover, .ButtonCellTopPadding .ButtonCellTop .btn-primary:hover:focus, .ButtonCellTopPadding .ButtonCellTop .btn-primary:focus-visible {
+    background-color: var(--col-200);
+    color: var(--txt-1);
+}
+
+.modal-footer .btn-default {
+    background-color: var(--col-200) !important;
+    color: var(--col-400) !important;
+    border: none !important;
+}
+
+.modal-footer .btn-default:hover, .modal-footer .btn-default:hover:focus, .modal-footer .btn-default:focus-visible {
+    background-color: var(--col-300) !important;
+    color: var(--col-600) !important;
+}
+
+/* .btn.btn-primary:not(.btn-sm) {
+    color: var(--txt-1);
+    background-color: var(--bg-5);
+    border-color: var(--bg-5);
+} */
+
+.TabButtonCell .btn-primary, .TabButtonCell .btn-info, .tab-row .btn-primary, #divViewButtons, .TabButtonCell .btn-primary:active, .tab-row .btn-primary:active {
+    color: var(--txt-2);
+}
+
+.TabButtonCell .btn-primary:hover, .TabButtonCell .btn-primary:hover:focus, .TabButtonCell .btn-primary:focus-visible, .TabButtonCell .btn-info:hover, .TabButtonCell .btn-info:hover:focus, .TabButtonCell .btn-info:focus-visible, .tab-row .btn-primary:hover, .tab-row .btn-primary:hover:focus, .tab-row .btn-primary:focus-visible, #divViewButtons:hover, #divViewButtons:hover:focus, #divViewButtons:focus-visible, .TabButtonCell .btn-primary:active:hover, .TabButtonCell .btn-primary:active:hover:focus, .TabButtonCell .btn-primary:active:focus-visible, .tab-row .btn-primary:active:hover, .tab-row .btn-primary:active:hover:focus, .tab-row .btn-primary:active:focus-visible {
+    background: var(--col-200);
+    color: var(--txt-2);
+}
+
+.TabButtonCell .btn-danger, .tab-row .btn-danger {
+    background: var(--bg-5);
+    color: var(--txt-2);
+}
+
+.TabButtonCell .btn-danger:hover, .TabButtonCell .btn-danger:hover:focus, .TabButtonCell .btn-danger:focus-visible, .tab-row .btn-danger:hover, .tab-row .btn-danger:hover:focus, .tab-row .btn-danger:focus-visible {
+    background: var(--col-0);
+    color: var(--txt-2);
+}
+
+.ButtonCellTop {
+    background: var(--bg-0);
+}
+
+.feed-button-group .btn-primary {
+    color: var(--txt-2) !important;
+}
+
+.btn-secondary {
+    background-color: var(--col-200);
+    color: var(--col-400);
+    border-color: var(--col-200);
+}
+
+.btn-secondary:hover, .btn-secondary:hover:focus, .btn-secondary:focus-visible {
+    background-color: var(--col-300) !important;
+    color: var(--col-500) !important;
+    border-color: var(--col-300) !important;
+}
+
+.btn-danger {
+    background-color: var(--col-200);
+    color: var(--col-400);
+    border-color: var(--col-200);
+}
+
+.btn-danger:hover, .btn-danger:hover:focus, .btn-danger:focus-visible {
+    background-color: var(--col-300);
+    color: var(--col-500);
+    border-color: var(--col-300);
+}
+
+.tdx-button-bar .btn-primary {
+    color: var(--txt-1);
+    background-color: var(--col-100);
+    border-color: var(--col-100);
+}
+
+.tdx-button-bar .btn-primary:hover, .tdx-button-bar .btn-primary:hover:focus, .tdx-button-bar .btn-primary:focus-visible {
+    background-color: var(--col-300);
+    background: var(--col-300);
+    color: var(--txt-2);
+    border-color: var(--col-300);
+}
+
+.tdx-button-bar .btn-primary:visited {
+    color: var(--txt-1);
+}
+
+.tdx-button-bar .btn-danger {
+    color: var(--col-400);
+}
+
+.tdx-button-bar .btn-danger:hover, .tdx-button-bar .btn-danger:hover:focus, .tdx-button-bar .btn-danger:focus-visible {
+    background-color: var(--col-300);
+    color: var(--col-500);
+    border-color: var(--col-300);
+}
+
+.tdx-tile-list__item-container,
+.tdx-tile-list__item-container:visited {
+    background-color: var(--col-100) !important;
+    color: var(--col-400) !important;
+}
+
+.tdx-tile-list__item-container:hover, .tdx-tile-list__item-container:focus {
+    background-color: var(--col-400) !important;
+    color: var(--col-100) !important;
+}
+
+a.btn.btn-primary {
+    background-color: var(--col-600) !important;
+    color: var(--txt-5) !important;
+    border-color: var(--col-600) !important;
+}
+
+a.btn.btn-primary:hover {
+    background-color: var(--col-400) !important;
+    color: var(--txt-5) !important;
+    border-color: var(--col-400) !important;
+}
+
+.btn-primary {
+    background-color: var(--col-600);
+    color: var(--txt-5);
+    border-color: var(--col-600);
+}
+
+.btn-primary:hover, .btn-primary:hover:focus, .btn-primary:focus-visible {
+    background: var(--col-400);
+    color: var(--txt-5);
+    border-color: var(--col-400);
+}
+
+td > a.btn.btn-primary {
+    background-color: var(--col-400) !important;
+    color: var(--txt-5) !important;
+    border-color: var(--col-400);
+}
+
+td > a.btn.btn-primary:hover {
+    background-color: var(--col-500) !important;
+    color: var(--txt-5) !important;
+    border-color: var(--col-500);
+}
+
+.btn-default.active, .btn-default.active:hover, .btn-default.active:focus, .btn-default:active, .btn-default:active:hover, .btn-default:active:focus {
+    background: var(--col-100) !important;
+    color: var(--txt-1) !important;
+    border-color: var(--col-100) !important;
+}
+
+a.btn.btn-link.tdx-primary-button-override {
+    color: var(--txt-5) !important;
+}
+
+.btn-link, .btn.btn-link, .sidebar-btn.btn-link {
+    color: var(--col-400) !important;
+}
+
+.btn-link:hover, .btn.btn-link:hover, .sidebar-btn.btn-link:hover {
+    color: var(--col-400) !important;
+}
+
+.btn-link[role=button]:hover, .btn.btn-link[role=button]:hover, .sidebar-btn.btn-link[role=button]:hover,
+a.btn.btn-link.tdx-tertiary-button-override:hover {
+    background-color: var(--col-200) !important;
+}
+
+.tdx-calendar .cal-views {
+    border-color: var(--col-400) !important;
+}
+
+.tdx-calendar .cal-view {
+    color: var(--txt-2) !important;
+}
+
+.tdx-calendar .cal-view.light-blue-bg {
+    background-color: var(--col-400) !important;
+    color: var(--txt-2) !important;
+}
+
+.tdx-calendar .cal-view:not(.cal-view.light-blue-bg):hover, .tdx-calendar .cal-view:hover:focus, .tdx-calendar .cal-view:focus-visible {
+    background-color: var(--col-200) !important;
+}
+
+.tdx-calendar #btnDatePicker {
+    background-color: var(--bg-0) !important;
+    color: var(--col-400) !important;
+}
+
+.tdx-calendar #btnDatePicker:hover, .tdx-calendar #btnDatePicker:focus-visible, .tdx-calendar #btnDatePicker:active, .tdx-calendar #btnDatePicker:active:hover, .tdx-calendar #btnDatePicker:focus:active, .tdx-calendar #btnDatePicker:focus:hover {
+    color: var(--col-600) !important;
+}
+
+button:has(.ui-icon-circle-triangle-w), span:has(.ui-icon-circle-triangle-w),
+button:has(.ui-icon-circle-triangle-e), span:has(.ui-icon-circle-triangle-e) {
+    color: var(--col-400) !important;
+}
+
+button:has(.ui-icon-circle-triangle-e):hover, button:has(.ui-icon-circle-triangle-e):focus-visible, button:has(.ui-icon-circle-triangle-e):active, button:has(.ui-icon-circle-triangle-e):active:hover, button:has(.ui-icon-circle-triangle-e):focus:active, button:has(.ui-icon-circle-triangle-e):focus:hover, span:has(.ui-icon-circle-triangle-e):hover, span:has(.ui-icon-circle-triangle-e):focus-visible, span:has(.ui-icon-circle-triangle-e):active, span:has(.ui-icon-circle-triangle-e):active:hover, span:has(.ui-icon-circle-triangle-e):focus:active, span:has(.ui-icon-circle-triangle-e):focus:hover,
+button:has(.ui-icon-circle-triangle-w):hover, button:has(.ui-icon-circle-triangle-w):focus-visible, button:has(.ui-icon-circle-triangle-w):active, button:has(.ui-icon-circle-triangle-w):active:hover, button:has(.ui-icon-circle-triangle-w):focus:active, button:has(.ui-icon-circle-triangle-w):focus:hover, span:has(.ui-icon-circle-triangle-w):hover, span:has(.ui-icon-circle-triangle-w):focus-visible, span:has(.ui-icon-circle-triangle-w):active, span:has(.ui-icon-circle-triangle-w):active:hover, span:has(.ui-icon-circle-triangle-w):focus:active, span:has(.ui-icon-circle-triangle-w):focus:hover {
+    color: var(--col-600) !important;
+}
+
+.ui-widget-header {
+    background: var(--bg-0) !important;
+}
+
+.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default,
+.ui-widget-content, .ui-widget.ui-widget-content {
+    background: var(--bg-0) !important;
+    border-color: var(--border-0) !important;
+}
+
+.tdx-calendar .fc-day-header {
+    color: var(--col-400) !important;
+}
+
+.tdx-calendar .fc-day-number.fc-other-month a:first-child {
+    color: var(--col-200) !important;
+}
+
+.tdx-calendar .fc-day-number a {
+    color: var(--col-600) !important;
+}
+
+.tdx-calendar .ui-state-highlight a, .tdx-calendar .ui-widget-content .ui-state-highlight a, .tdx-calendar .ui-widget-header .ui-state-highlight a {
+    color: var(--col-400) !important;
+}
+
+.tdx-calendar .ui-state-highlight {
+    background: var(--col-100) !important;
+}
+
+.td-day-off {
+    background: var(--bg-2) !important;
+}
+
+.label-primary, .tdworkmgmt.table .hilite .label.label-primary {
+    background-color: var(--col-300);
+}
+
+.label-info, .label-success, .label-default {
+    color: var(--col-200);
+    background-color: var(--col-500);
+}
+
+.tdTilemd,
+.tdTilesm {
+    background-color: var(--col-300);
+    border-color: var(--col-300);
+}
+
+.tdTilemd.secondary,
+.tdTilesm.secondary {
+    background-color: var(--col-300);
+    border-color: var(--col-300);
+}
+
+.tdTilesm.tertiary {
+    background-color: var(--col-300);
+    border-color: var(--col-300);
+}
+
+.block-actions .btn.btn-link {
+    color: var(--txt-1);
+}
+
+.block-actions .btn.btn-link:hover, .block-actions .btn.btn-link:hover:focus, .block-actions .btn.btn-link:focus-visible {
+    background: var(--bg-5);
+    color: var(--txt-1);
+}
+
+.btn-link:hover, .btn-link:focus-visible, .btn.btn-link:hover, .btn.btn-link:focus-visible, .sidebar-btn.btn-link:hover, .sidebar-btn.btn-link:focus-visible {
+    color: var(--col-500);
+}
+
+ul.dropdown-menu .btn.btn-link[data-v-775a00fa] {
+    color: var(--txt-1) !important;
+}
+
+ul.dropdown-menu .btn.btn.btn-link[data-v-775a00fa]:hover {
+    background-color: var(--col-300) !important;
+    color: var(--txt-1) !important;
+}
+
+.copyButton {
+    color: var(--txt-2) !important;
+    background-color: var(--bg-0) !important;
+    border-color: var(--border-0) !important;
+}
+
+.copyButton:hover {
+    background-color: var(--bg-2) !important;
+}
+
+.js-open-monitor .btn {
+    color: var(--col-1);
+}
+
+.js-open-monitor .btn:hover {
+    color: var(--col-2);
+}
+
+/* .btn:hover, .btn:hover:focus, .btn:focus-visible {
+    background: var(--bg-1);
+} */
+
+.btn:focus:not(:focus-visible,.active,:active,:hover) {
+    color: var(--txt-5);
+    background-color: var(--col-400);
+}
+
+.btn:hover, .btn:hover:focus, .btn:focus-visible {
+    color: var(--txt-5);
+    background-color: var(--col-600);
+}
+
+.popover {
+background-color: var(--bg-0);
+    box-shadow: 0 5px 10px var(--shadow-1);
+    border-color: var(--border-0);
+}
+
+.popover.right > .arrow {
+border-right-color: var(--border-0);
+}
+
+.popover.right > .arrow::after {
+    border-right-color: var(--bg-0);
+}
+
+/* Tables: report grids, row/cell states, sorting, paging, and dashboard tables. */
+
+table.table {
+    color: var(--txt-1) !important;
+    border-color: var(--border-0);
+}
+
+.tdx-table__th {
+    background-color: var(--bg-0) !important;
+    color: var(--col-600) !important;
+}
+
+.tdx-table__td {
+    color: var(--txt-2) !important;
+}
+
+.tdx-table-fade-right {
+    background: linear-gradient(to right,transparent,var(--bg-0)) !important;
+}
+
+thead, tbody, tfoot, tr, td, th {
+    border-color: var(--border-0);
+}
+
+.tdx-pagination-bar {
+    background-color: var(--bg-0) !important;
+}
+
+.tdx-pagination-bar__item-count {
+    color: var(--txt-2) !important;
+}
+
+.tdx-dashboard__widget-container {
+    box-shadow: 0 .5px 1px 1px var(--shadow-1),0 2px 4px var(--shadow-2),0 4px 6px var(--shadow-1) !important;
+}
+
+.tdx-widget-selector__widget-option {
+    box-shadow: 0 .5px 1px 1px var(--shadow-1),0 2px 4px var(--shadow-2),0 4px 6px var(--shadow-2) !important;
+}
+
+.tdx-widget-selector__widget-name {
+    color: var(--txt-1) !important;
+}
+
+.tdx-widget-selector__category {
+    color: var(--col-600) !important;
+}
+
+.tdx-widget-selector__widget-option:hover, .tdx-widget-selector__widget-option:focus {
+    outline-color: var(--col-400) !important;
+}
+
+.tdx-dashboard-row-editor {
+    background-color: var(--col-100) !important;
+    box-shadow: 0 .5px 1px 1px var(--shadow-1),0 2px 4px var(--shadow-2),0 4px 6px var(--shadow-2) !important;
+}
+
+.tdx-dashboard-row-editor__column {
+    background-color: var(--bg-0) !important;
+}
+
+.tdx-dashboard-row-editor__selected-widget {
+    background-color: var(--bg-0) !important;
+    outline-color: var(--border-0) !important;
+}
+
+.tdx-dashboard-row-editor__selected-widget-category-text {
+    color: var(--col-600) !important;
+}
+
+.tdx-dashboard-editor__add-widget {
+    color: var(--txt-3) !important;
+}
+
+.tdx-dashboard-editor__add-widget:hover, .tdx-dashboard-editor__add-widget:focus-visible {
+    box-shadow: 0 .5px 1px 1px var(--shadow-1),0 2px 4px var(--shadow-2),0 4px 6px var(--shadow-2) !important;
+}
+
+.tdx-control-bar {
+    background-color: var(--bg-0) !important;
+}
+
+.tdx-control-bar__title {
+    color: var(--txt-1) !important;
+}
+
+.tdx-confirmation-dialog {
+    background-color: var(--bg-0);
+    color: var(--col-600);
+}
+
+.tdx-confirmation-dialog__text-area {
+    color: var(--col-600);
+}
+
+.k-grid, .k-pager, .k-table {
+    background-color: var(--bg-0) !important;
+    color: var(--txt-1) !important;
+}
+
+.k-table-tbody>.k-table-row:not(.k-table-group-row):first-child>.k-table-td,
+.k-table-tbody>.k-table-row:not(.k-table-group-row)>.k-table-td {
+    border-color: var(--border-0) !important;
+}
+
+.k-grid-header, .k-grid-pager {
+    background-color: var(--bg-0) !important;
+    color: var(--txt-0) !important;
+}
+
+.k-grid .k-table-row.k-table-alt-row {
+    background-color: var(--bg-0);
+}
+
+.k-grid .k-table-row {
+    background-color: var(--bg-1); /* can change to 0 for non-striped rows */
+}
+
+td.k-table-td {
+    /* background-color: var(--bg-1); */
+}
+
+.k-grid .k-table-tbody > .k-alt.k-table-row:not(.k-detail-row) {
+    background-color: var(--bg-0);
+}
+
+.k-table-th {
+    background-color: var(--bg-0) !important;
+}
+
+.k-grid .k-grid-header .k-table-th {
+    color: var(--txt-4) !important;
+}
+
+.k-grid .k-grid-header .k-table-th, .k-table-tbody .k-group-cell {
+    background-color: unset;
+}
+
+.k-table-th, .k-table-td,
+td.k-table-td {
+    background-color: unset;
+}
+
+.k-grid .k-table-tbody>.k-table-row:not(.k-detail-row):not([style]):hover, .k-grid .k-table-tbody>.k-table-row:not(.k-detail-row).k-hover {
+    background-color: var(--bg-1) !important;
+}
+
+.k-grid .k-table-tbody>.k-table-alt-row:not(.k-detail-row):not([style]):hover, .k-grid .k-table-tbody>.k-table-alt-row:not(.k-detail-row).k-hover:not([style]) {
+    background-color: var(--bg-0) !important;
+}
+
+button.k-pager-nav.k-button.k-button-flat.k-button-flat-base.k-icon-button.k-button-md {
+    background-color: var(--bg-0) !important;
+    color: var(--col-400) !important;
+}
+
+.k-pager-md .k-pager-numbers-wrap .k-button.k-pager-nav.k-disabled,
+button.k-pager-nav.k-button.k-button-flat.k-button-flat-base.k-icon-button.k-pager-last.k-button-md {
+    background-color: var(--bg-0) !important;
+    color: var(--col-400) !important;
+}
+
+button.k-pager-nav.k-button.k-button-flat.k-button-flat-base.k-icon-button.k-pager-last.k-button-md.k-disabled,
+button.k-pager-nav.k-button.k-button-flat.k-button-flat-base.k-icon-button.k-button-md.k-disabled {
+    color: var(--bg-2) !important;
+}
+
+.k-pager-md .k-pager-numbers-wrap .k-button.k-pager-nav:hover {
+    color: var(--col-600) !important;
+}
+
+#lookupIframeWrapper {
+    background-color: var(--bg-0);
+}
+
+.k-window, .k-window:focus {
+    background: var(--bg-0);
+    box-shadow: 0 8px 16px var(--shadow-1),0 24px 38px var(--shadow-2);
+}
+
+.k-window-titlebar {
+    background-color: var(--bg-0) !important;
+}
+
+.k-window-content {
+    background-color: var(--bg-0) !important;
+}
+
+.k-window-title {
+    color: var(--col-500) !important;
+}
+
+.k-button .k-svg-i-window {
+    color: var(--col-500);
+}
+
+.k-button .k-svg-i-x {
+    color: var(--col-500);
+}
+
+button.k-button.k-button-md.k-button-flat.k-button-flat-primary.k-selected {
+    background-color: var(--col-100) !important;
+}
+
+button.k-selected {
+    background-color: var(--col-1) !important;
+    color: var(--col-400) !important;
+}
+
+.k-pager-md .k-pager-numbers-wrap .k-button {
+    color: var(--col-400) !important;
+}
+
+button.k-button.k-button-md.k-button-flat.k-button-flat-primary:hover {
+    color: var(--col-500);
+    background-color: var(--col-100)!important;
+}
+
+.k-pager-md .k-pager-numbers-wrap .k-button.k-pager-nav {
+    background-color: var(--bg-0) !important;
+}
+
+.tdx-pagination-bar {
+    background-color: var(--bg-0);
+}
+
+.tdx-pagination-bar__active-page-item {
+    color: var(--col-400);
+    background-color: var(--col-200);
+}
+
+.tdx-pagination-bar__page-item:hover:not(.tdx-pagination-bar__active-page-item,.tdx-pagination-bar__separator) {
+    color: var(--col-500);
+    background-color: var(--col-100);
+}
+
+.tdx-pagination-bar .fa, .tdx-pagination-bar a {
+    color: var(--col-400);
+}
+
+.tdx-pager-button .fa-chevron-right, .tdx-pager-button .fa-chevron-left {
+    -webkit-text-stroke-color: var(--bg-0);
+}
+
+.hilite, .hilite .btn-link, .hilite a, .hilite td, .table>tbody>tr.hilite label, .table>tbody>tr.hilite.active, .table>tbody>tr.hilite.danger, .table>tbody>tr.hilite.info, .table>tbody>tr.hilite.success, .table>tbody>tr.hilite.warning, .table>tbody>tr.hilite>td.active, .table>tbody>tr.hilite>td.danger, .table>tbody>tr.hilite>td.info, .table>tbody>tr.hilite>td.success, .table>tbody>tr.hilite>td.warning {
+    color: var(--txt-5);
+    background-color: var(--bg-5) !important;
+}
+
+.tdworkmgmt.table-header > div {
+    background-color: var(--bg-1);
+    color: var(--col-400);
+}
+
+/* Side Panels: off-canvas panels and their headers, controls, and body content. */
+
+.tdx-right-side-panel {
+    background-color: var(--bg-0) !important;
+    box-shadow: 0 8px 16px var(--shadow-1),0 24px 38px var(--shadow-2) !important;
+}
+
+.white-bg, .white-hover-bg:hover {
+    background-color: var(--bg-0) !important;
+}
+
+.tdx-right-side-panel__drag-border {
+    background: linear-gradient(var(--col-400),var(--col-400)) no-repeat left/1px 10% !important;
+}
+
+.tdx-right-side-panel__drag-border:hover {
+    border-color: var(--col-400) !important;
+}
+
+.tdx-right-side-panel__header-title {
+    color: var(--txt-2) !important;
+}
+
+.tdx-right-side-panel__drag-border:focus-visible, .tdx-right-side-panel__drag-border.active {
+    border-color: var(--col-500) !important;
+}
+
+
+.tdx-right-side-panel__home-button {
+    color: var(--col-400) !important;
+    border-color: var(--col-500) !important;
+}
+
+.tdx-right-side-panel__home-button:hover {
+    color: var(--col-200) !important;
+    border-color: var(--col-300) !important;
+}
+
+.tdx-leftnav-drag-handle {
+    background: linear-gradient(var(--col-400),var(--col-400)) no-repeat right/1px 10% !important;
+}
+
+.tdx-leftnav-drag-handle:hover {
+    background-color: var(--col-400) !important;
+}
+
+.tdx-leftnav-drag-handle:focus-visible, .tdx-leftnav-drag-handle.active {
+    background-color: var(--col-500) !important;;
+}
+
+/* Tickets: ticket/task forms, attributes, feed entries, and work-management views. */
+
+.control-label, label.control-label, span.control-label {
+    color: var(--txt-3) !important;
+}
+
+.control-label~* {
+    color: var(--txt-1) !important;
+}
+
+.black {
+    color: var(--txt-1) !important;
+}
+
+nav#divTabHeader,
+.TabButtonCell, .tab-row,
+.tdx-button-bar {
+    background-color: var(--col-100) !important;
+}
+
+.panel-default>.panel-heading {
+    background-color: var(--bg-0) !important;
+    border-color: var(--border-0) !important;
+}
+
+.panel-body, .panel-footer {
+    background-color: var(--bg-0) !important;
+    border-color: var(--border-0) !important;
+}
+
+.panel {
+    background-color: var(--bg-0) !important;
+}
+
+.panel-body, .panel-footer {
+    color: var(--txt-3) !important;
+}
+
+.h2, h2, h2.h3, .panel-title {
+    color: var(--txt-1) !important;
+    border-color: var(--border-0) !important;
+}
+
+.alert-info, div.alert-info {
+    color: var(--txt-1) !important;
+    background-color: var(--col-blue) !important;
+}
+
+.alert-warning, div.alert-warning {
+    color: var(--txt-1) !important;
+    background-color: var(--col-yellow) !important;
+}
+
+.nav-tabs>li.active>a, .nav-tabs>li.active>button, .nav-pills>li.active>a, .nav-pills>li.active>button {
+    color: var(--col-600) !important;
+    background-color: var(--bg-0) !important;
+    border-color: var(--border-0);
+    box-shadow: 0 .5px 1px 1px var(--shadow-1),0 2px 4px var(--shadow-2),0 4px 6px var(--shadow-2) !important;
+}
+
+.nav-tabs>li>a, .nav-tabs>li>a:hover, .nav-tabs>li>button, .nav-tabs>li>button:hover, .nav-pills>li>a, .nav-pills>li>a:hover {
+    color: var(--txt-3);
+}
+
+.nav-tabs>li>a:hover, .nav-tabs>li>a:hover:hover {
+    color: var(--txt-2);
+    border-color: var(--border-0);
+}
+
+.nav-tabs>li>a:hover {
+    color: var(--col-600);
+}
+
+a.btn.btn-link.tdx-tertiary-button-override {
+    background-color: var(--col-100) !important;
+    color: var(--txt-1) !important;
+}
+
+.gray, .gray-hover:hover {
+    color: var(--txt-3) !important;
+}
+
+.dropdown-menu {
+    background-color: var(--bg-0) !important;
+    color: var(--txt-1) !important;
+    box-shadow: 0 1px 3px var(--shadow-1),0 2px 10px var(--shadow-2);
+}
+
+.dropdown-menu li {
+    color: var(--txt-1);
+    background-color: var(--bg-0);
+}
+
+.dropdown-menu>span>li>a:hover, .dropdown-menu>span>li>a:focus, .dropdown-menu>span>li:hover, .dropdown-menu>span>li:focus, .dropdown-menu>li>a:hover, .dropdown-menu>li>span>a:hover, .dropdown-menu>li>a:focus, .dropdown-menu>li>span>a:focus,
+.dropdown-menu li:hover {
+    color: var(--txt-1);
+    background-color: var(--col-300);
+}
+
+.TabButtonCell .btn-primary.active, .TabButtonCell .btn-primary.active:hover, .TabButtonCell .btn-primary.active:focus, .TabButtonCell .btn-primary:active, .TabButtonCell .btn-primary:active:hover, .TabButtonCell .btn-primary:active:focus, .TabButtonCell .btn-info.active, .TabButtonCell .btn-info.active:hover, .TabButtonCell .btn-info.active:focus, .TabButtonCell .btn-info:active, .TabButtonCell .btn-info:active:hover, .TabButtonCell .btn-info:active:focus, .tab-row .btn-primary.active, .tab-row .btn-primary.active:hover, .tab-row .btn-primary.active:focus, .tab-row .btn-primary:active, .tab-row .btn-primary:active:hover, .tab-row .btn-primary:active:focus, #divViewButtons.active, #divViewButtons.active:hover, #divViewButtons.active:focus, #divViewButtons:active, #divViewButtons:active:hover, #divViewButtons:active:focus, .TabButtonCell .btn-primary:active.active, .TabButtonCell .btn-primary:active.active:hover, .TabButtonCell .btn-primary:active.active:focus, .TabButtonCell .btn-primary:active:active, .TabButtonCell .btn-primary:active:active:hover, .TabButtonCell .btn-primary:active:active:focus, .tab-row .btn-primary:active.active, .tab-row .btn-primary:active.active:hover, .tab-row .btn-primary:active.active:focus, .tab-row .btn-primary:active:active, .tab-row .btn-primary:active:active:hover, .tab-row .btn-primary:active:active:focus {
+    background: var(--col-600);
+    color: var(--txt-1);
+}
+
+div.btn-group.open>.dropdown-toggle.btn-primary, .open>.dropdown-toggle.btn-primary, .open>.dropdown-toggle.btn-primary:hover, .open>.dropdown-toggle.btn-primary:focus {
+    background: var(--col-100);
+    color: var(--txt-1);
+}
+
+.TabButtonCell .btn-primary:focus:not(:focus-visible,.active,:active,:hover), .TabButtonCell .btn-info:focus:not(:focus-visible,.active,:active,:hover), .tab-row .btn-primary:focus:not(:focus-visible,.active,:active,:hover), #divViewButtons:focus:not(:focus-visible,.active,:active,:hover), .TabButtonCell .btn-primary:active:focus:not(:focus-visible,.active,:active,:hover), .tab-row .btn-primary:active:focus:not(:focus-visible,.active,:active,:hover) {
+    background: var(--col-100);
+    color: var(--txt-1);
+}
+
+.btn-primary--tertiary {
+    background-color: var(--bg-0) !important;
+    color: var(--txt-1) !important;
+    border-color: var(--bg-0) !important;
+}
+
+.btn-primary--tertiary:hover, .btn-primary--tertiary:hover:focus, .btn-primary--tertiary:focus-visible {
+    background-color: var(--col-200) !important;
+    color: var(--col-400) !important;
+}
+
+.time-cell-approved {
+    background-color: var(--col-green);
+}
+
+.time-cell-rejected {
+    background-color: var(--col-red);
+}
+
+[class^=fa-].red, [class^=fa-].red:hover {
+    color: var(--col-red) !important;
+}
+
+[class^=fa-].green, [class^=fa-].green:hover {
+    color: var(--col-green) !important;
+}
+
+.tdx-error-text, span.tdx-error-text,
+.tdx-error-text:hover, span.tdx-error-text:hover {
+    /* color: var(--col-red) !important; */
+    color: var(--col-600) !important;
+}
+
+.red-bg,
+.status.red, .status-danger, .pri-hi {
+    background-color: var(--col-red) !important;
+    color: var(--txt-1) !important;
+}
+
+.status.blue, .status.gray, .status-primary, .status-default {
+    background-color: var(--col-blue);
+    color: var(--txt-1) !important;
+}
+
+.status-warning {
+    background-color: var(--col-yellow);
+    color: var(--txt-1) !important;
+}
+
+.status.green, .status-success,
+.js-open-monitor .btn .label-success {
+    background-color: var(--col-green);
+    color: var(--txt-1) !important;
+}
+
+div.feed-body>div.feed-child-box {
+    background-color: var(--col-100);
+    color: var(--txt-1);
+}
+
+.modal-content {
+    background-color: var(--bg-0);
+}
+
+.modal-dialog {
+    box-shadow: 0 8px 16px var(--shadow-1),0 24px 38px var(--shadow-2);
+}
+
+.modal-title {
+    color: var(--txt-1);
+}
+
+.tdx-modal {
+    background-color: var(--bg-0) !important;
+    box-shadow: 0 0 8px var(--shadow-1),0 5px 12px var(--shadow-1),0 15px 35px var(--shadow-2);
+}
+
+.tdx-modal .modal-content {
+    color: var(--txt-1) !important;
+}
+
+.tdx-modal__iframe-header,
+.tdx-modal__iframe-footer {
+    background-color: var(--bg-0) !important;
+}
+
+.modal-content {
+    background-color: var(--bg-0) !important;
+}
+
+hr {
+    background-color: var(--col-300);
+}
+
+blockquote {
+    border-color: var(--border-0);
+}
+
+.code, code, pre {
+    background-color: var(--bg-1);
+    color: var(--txt-1);
+    border-color: var(--border-0);
+}
+
+div.comment {
+    background-color: var(--col-100);
+}
+
+.block-actions {
+    background-color: var(--bg-0);
+}
+
+body .tdworkmgmt.table>thead>tr>th, body .tdworkmgmt.table>tbody>tr>th, body .tdworkmgmt.table>tfoot>tr>th, body .tdworkmgmt.table>tbody>tr.TDGridHeader>td, body .tdworkmgmt.table>thead>tr.TDGridHeader>td {
+    background-color: var(--bg-0);
+    color: var(--txt-1);
+}
+
+body .tdworkmgmt.table>tbody>tr:not(.tdx-grid__group-header):not(.TDGridHeader)>td {
+    color: var(--txt-1);
+    border-color: var(--border-0);
+}
+
+body .tdworkmgmt.table>tbody>tr:not(.tdx-grid__group-header):not(.TDGridHeader):last-child:not(.TDPagerRow) th, body .tdworkmgmt.table>tbody>tr:not(.tdx-grid__group-header):not(.TDGridHeader):last-child:not(.TDPagerRow) td {
+    border-color: var(--border-0);
+}
+
+.tdworkmgmt td a, .tdworkmgmt.table .hilite a {
+    color: var(--col-400);
+}
+
+.tdworkmgmt td a:hover, .tdworkmgmt td a:focus-visible, .tdworkmgmt.table .hilite a:hover, .tdworkmgmt.table .hilite a:focus-visible {
+    color: var(--col-0);
+}
+
+.input-group-addon {
+    background-color: var(--bg-5);
+    color: var(--txt-1);
+}
+
+.list-group-item {
+    background-color: var(--bg-0) !important;
+    border-color: var(--border-0);
+}
+
+/* Text Editor: CKEditor and rich-text content styles, including embedded frames. */
+.cke_editable {
+color: var(--txt-1);
+background-color: var(--bg-4);
+}
+
+html .cke_editable {
+  background-color: var(--bg-0) !important;
+  color: var(--txt-1) !important;
+}
+
+.cke_wysiwyg_div, .cke_wysiwyg_frame {
+    background: var(--bg-0) !important;
+}
+
+.cke_combo_button, .cke_toolgroup {
+background: var(--bg-0) !important;
+}
+
+.cke_button_icon {
+opacity: 1 !important;
+    filter: invert(var(--txt-invert)) !important;
+}
+
+.cke_combo_text {
+color: var(--txt-2) !important;
+    background-color: var(--bg-0) !important;
+}
+
+.cke_panel_grouptitle {
+background: var(--bg-2) !important;
+color: var(--txt-1);
+}
+
+.cke_panel_listItem a:active, .cke_panel_listItem a:focus, .cke_panel_listItem a:hover {
+background: var(--bg-3) !important;
+}
+
+a.cke_button_disabled:active, a.cke_button_disabled:focus, a.cke_button_disabled:hover, a.cke_button_off:active, a.cke_button_off:focus, a.cke_button_off:hover {
+background: var(--bg-3) !important;
+}
+
+.cke_bottom, .cke_top, .cke_chrome {
+background-color: var(--bg-1) !important;
+color: var(--txt-2) !important;
+}
+
+.cke_combo_button,
+.cke_toolgroup,
+.cke_contents {
+    border-color: var(--border-0) !important;
+}
+
+div .cke_top, div .cke_bottom, div .comment-options, div .cke_chrome {
+    background-color: var(--col-100) !important;
+}
+
+.cke_panel_listItem a {
+    border: none;
+}
+
+.cke_panel,
+.cke_panel_grouptitle {
+    border-color: var(--border-0) !important;
+}
+
+a.cke_colorbox,
+a.cke_colorauto, a.cke_colormore {
+    border-color: var(--border-0) !important;
+}
+
+.cke_colorblock, .cke_colorblock a {
+color: var(--txt-1);
+}
+
+a:active.cke_colorauto, a:active.cke_colormore, a:focus.cke_colorauto, a:focus.cke_colormore, a:hover.cke_colorauto, a:hover.cke_colormore {
+background: var(--bg-3) !important;
+}
+
+a:active.cke_colorbox, a:focus.cke_colorbox, a:hover.cke_colorbox {
+background: var(--bg-3) !important;
+}
+
+.cke_dialog_contents, .cke_dialog_body {
+color: var(--txt-1) !important;
+background: var(--bg-2) !important;
+}
+
+.cke_dialog_footer, .cke_dialog_title {
+background: var(--bg-1) !important;
+}
+
+.cke_reset_all, .cke_reset_all * {
+color: var(--txt-2) !important;
+}
+
+.cke_dialog_page_contents a.cke_dialog_ui_button, a.cke_dialog_ui_button_cancel {
+background: var(--bg-3) !important;
+}
+
+input.cke_dialog_ui_input_password, input.cke_dialog_ui_input_text, textarea.cke_dialog_ui_input_textarea {
+background: var(--bg-3) !important;
+}
+
+a.cke_dialog_tab_selected {
+background: var(--bg-2) !important;
+}
+
+a.cke_dialog_tab {
+background: var(--bg-3) !important;
+}
+
+select.cke_dialog_ui_input_select {
+background-color: var(--bg-4) !important;
+}
+
+.cke_button_on {
+background: var(--bg-2) !important;
+}
+
+.dropdown-menu>li>a, .dropdown-menu>span>li>a, .dropdown-menu>li>span>a {
+    color: var(--txt-1) !important;
+}
+
+/* Icons: icon colors, hover states, and component-specific glyph overrides. */
+.js-help a, .js-help .fa-solid, .js-default-help a, .js-default-help .fa-solid,
+.disp-group .control-label>a>span {
+    color: var(--col-400);
+}
+
+.js-help a:hover, .js-help a:focus-visible, .js-help a:active, .js-help a:active:hover, .js-help a:focus:active, .js-help a:focus:hover, .js-help .fa-solid:hover, .js-help .fa-solid:focus-visible, .js-help .fa-solid:active, .js-help .fa-solid:active:hover, .js-help .fa-solid:focus:active, .js-help .fa-solid:focus:hover, .js-default-help a:hover, .js-default-help a:focus-visible, .js-default-help a:active, .js-default-help a:active:hover, .js-default-help a:focus:active, .js-default-help a:focus:hover, .js-default-help .fa-solid:hover, .js-default-help .fa-solid:focus-visible, .js-default-help .fa-solid:active, .js-default-help .fa-solid:active:hover, .js-default-help .fa-solid:focus:active, .js-default-help .fa-solid:focus:hover,
+.disp-group .control-label>a>span:hover, .disp-group .control-label>a>span:focus-visible, .disp-group .control-label>a>span:active, .disp-group .control-label>a>span:active:hover, .disp-group .control-label>a>span:focus:active, .disp-group .control-label>a>span:focus:hover {
+    color: var(--col-500);
+}
+
+.tdx-lookup-button-group a, .tdx-lookup-button-group button, .input-btn-group a, .input-btn-group button,
+div.select2-container.select2-allowclear .select2-choice abbr {
+    color: var(--col-400);
+}
+
+.tdx-lookup-button-group a:hover, .tdx-lookup-button-group a:focus-visible, .tdx-lookup-button-group a:active, .tdx-lookup-button-group a:active:hover, .tdx-lookup-button-group a:focus:active, .tdx-lookup-button-group a:focus:hover, .tdx-lookup-button-group button:hover, .tdx-lookup-button-group button:focus-visible, .tdx-lookup-button-group button:active, .tdx-lookup-button-group button:active:hover, .tdx-lookup-button-group button:focus:active, .tdx-lookup-button-group button:focus:hover, .input-btn-group a:hover, .input-btn-group a:focus-visible, .input-btn-group a:active, .input-btn-group a:active:hover, .input-btn-group a:focus:active, .input-btn-group a:focus:hover, .input-btn-group button:hover, .input-btn-group button:focus-visible, .input-btn-group button:active, .input-btn-group button:active:hover, .input-btn-group button:focus:active, .input-btn-group button:focus:hover {
+    color: var(--col-500);
+}
+
+.tdx-icon__encircled--active {
+    background-color: var(--col-200) !important;
+}
+
+.tdx-icon__encircled--active:hover {
+    background-color: var(--col-300) !important;
+}
+
+.tdx-icon__encircled:not(.tdx-icon__encircled--active) {
+    background-color: var(--bg-0) !important;
+}
+
+.tdx-icon__encircled:not(.tdx-icon__encircled--active):hover {
+    background-color: var(--col-200) !important;
+}
+
+.tdx-user-icon, .tdx-multiuser-icon,
+div.profile-image.red-bg, div.profile-image.green-bg, div.profile-image.red-bg, div.profile-image.blue-bg, div.profile-image.yellow-bg, div.profile-image.gray-bg, div.profile-image.initials.red-bg, div.profile-image.initials.green-bg, div.profile-image.initials.red-bg, div.profile-image.initials.blue-bg, div.profile-image.initials.yellow-bg, div.profile-image.initials.gray-bg {
+    background-color: var(--col-400) !important;
+    color: var(--col-100) !important;
+}
+
+.tdx-widget-indicator-icon {
+    color: var(--col-600) !important;
+}
+
+.tdx-dirty-indicator {
+    color: var(--col-400) !important;
+}
+
+.tdx-hover-darken {
+    color: var(--col-400);
+}
+
+.tdx-hover-darken:hover {
+    color: var(--col-300);
+}
+
+.form-group>a, .form-group>.checkbox>a, .disp-group>a, .form-group>.control-label>a, .checkbox>label>a {
+    color: var(--col-400) !important;
+}
+
+.form-group>a:hover, .form-group>.checkbox>a:hover, .disp-group>a:hover, .form-group>.control-label>a:hover, .checkbox>label>a:hover {
+    color: var(--col-500) !important;
+}
+
+.k-table-th[data-role=columnsorter] .k-link:not(:has(>.k-sort-icon)):after {
+    color: var(--col-400) !important;
+}
+
+.k-table-th[data-role=columnsorter] .k-link:not(:has(>.k-sort-icon)):hover:after {
+    color: var(--col-500) !important;
+}
+
+.tdx-calendar .fa-plus {
+    color: var(--col-300) !important;
+}
+
+.icon-button {
+    color: var(--col-400) !important;
+}
+
+.tdx-view-ticket-summary #divSummaryHeading a {
+  color: var(--col-400);
+}
+
+.tdx-view-ticket-summary #divSummaryHeading a #spnCopySummaryIcon {
+  color: var(--col-400);
+}
+
+/* Icons + Filters: calculated filter variables recolor monochrome TDX assets. */
+.tdx-dropdown__menu-icon,
+.tdx-dropdown--headline:after,
+.tdx-dropdown:after,
+.tdx-icon--search,
+.k-icon
+{
+    filter: brightness(0) invert(var(--filter-invert)) sepia(var(--filter-sepia)) saturate(var(--filter-saturate)) hue-rotate(var(--filter-hue-rotate)) brightness(var(--filter-brightness)) contrast(var(--filter-contrast));
+}
+
+#divDescription .wrap-text [style*="color"]:not([style*="color"] [style*="color"]), .feed-item-text [style*="color"]:not([style*="color"] [style*="color"]), #divCustomLoginPrompt [style*="color"]:not([style*="color"] [style*="color"]) {
+  filter: none !important;
+}
+
+/* Same but with !important */
+.tdx-icon__encircled--active .tdx-icon,
+.tdx-icon--filter-purple,
+.tdx-navigation-tabs__tab--active .tdx-close-x,
+.tdx-icon--new-browser,
+.tdx-close-x, button.tdx-close-x,
+.tdx-action-menu__item--primary:after,
+.tdx-action-menu-dropdown:after,
+.tdx-icon.tdx-icon--hover-darken, .tdx-icon--hover-darken>.tdx-icon,
+.tdx-dropdown__menu-icon, .tdx-dropdown--headline:after, .tdx-dropdown:after, .tdx-icon--search, .tdx-icon:not(.label),
+div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:hover, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:focus-visible, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:active, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:active:hover, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:focus:active, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:focus:hover
+{
+    filter: brightness(0) invert(var(--filter-invert)) sepia(var(--filter-sepia)) saturate(var(--filter-saturate)) hue-rotate(var(--filter-hue-rotate)) brightness(var(--filter-brightness)) contrast(var(--filter-contrast)) !important;
+}
+
+/* Hover + !important */
+.tdx-icon__encircled:hover .tdx-icon,
+.tdx-close-x:hover, button.tdx-close-x:hover,
+.tdx-icon.tdx-icon--hover-darken:hover, .tdx-icon.tdx-icon--hover-darken:focus, .tdx-icon--hover-darken>.tdx-icon:hover, .tdx-icon--hover-darken>.tdx-icon:focus,
+.tdx-leftnav__item-expander:hover .tdx-icon, .tdx-leftnav__item-expander:focus .tdx-icon,
+.tdx-action-menu-dropdown--no-arrow:hover .tdx-icon, .tdx-action-menu-dropdown--no-arrow.active .tdx-icon,
+div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close
+{
+    filter: brightness(0) invert(var(--filter-invert)) sepia(var(--filter-sepia)) saturate(var(--filter-saturate)) hue-rotate(var(--filter-hue-rotate)) brightness(var(--filter-brightness)) contrast(var(--filter-contrast)) brightness(125%) !important;
+}
+
+    `
+    // Backstop for tables added without a useful mutation target. Marking a
+    // table prevents repeat processing during the five-second polling cycle.
+    setInterval(() => {
+    document.querySelectorAll("table:not([data-parsed])").forEach(table => {
+        table.dataset.parsed = "true";
+        parseTable(table.parentElement);
+    });
+    }, 5000);
+    //const customStyles = GM_getResourceText("IMPORTED_CSS");
+    // Final startup order: add styles, calculate icon filters, then enhance
+    // already-rendered page controls. The observer handles later updates.
+    GM_addStyle(customStyles);
+    setCssFilters()
+    parseOtherElements()
+
+})();

From 4d79b91425dc0c6433e29c7785000dfbfca70d03 Mon Sep 17 00:00:00 2001
From: Diego Dereck Sosa-Escamilla 
Date: Wed, 9 Sep 2026 07:46:58 -0400
Subject: [PATCH 2/3] Delete tdx-enhanced.js

---
 tdx-enhanced.js | 4197 -----------------------------------------------
 1 file changed, 4197 deletions(-)
 delete mode 100644 tdx-enhanced.js

diff --git a/tdx-enhanced.js b/tdx-enhanced.js
deleted file mode 100644
index 61d65f5..0000000
--- a/tdx-enhanced.js
+++ /dev/null
@@ -1,4197 +0,0 @@
-// ==UserScript==
-// @name         tdx-enhanced
-// @namespace    purdue-it
-// @version      2026-05-08-01
-// @description  enhanced tdx coloring & formatting. follows system color scheme.
-// @author       Purdue STEM IT - it@purdue.edu
-// @match        https://service.purdue.edu/TDWorkManagement*
-// @match        https://service.purdue.edu/tdworkmanagement*
-// @match        https://service.purdue.edu/TDNext*
-// @match        https://service.purdue.edu/TDWebApi*
-// @match        https://purdue.teamdynamixpreview.com/TDWorkManagement*
-// @match        https://purdue.teamdynamixpreview.com/TDNext*
-// @require      https://momentjs.com/downloads/moment.min.js
-// @require      https://cdnjs.cloudflare.com/ajax/libs/tinycolor/1.6.0/tinycolor.min.js
-// @downloadURL  https://raw.github.itap.purdue.edu/ECN/tdx-userscript/refs/heads/main/tdx-enhanced.js
-// @updateURL    https://raw.github.itap.purdue.edu/ECN/tdx-userscript/refs/heads/main/tdx-enhanced.js
-// @grant        GM_getResourceText
-// @grant        GM_addStyle
-// @run-at       document-end
-// ==/UserScript==
-
-
-
-(function() {
-    'use strict';
-
-    const primaryTitle = "Purdue University IT"
-
-    /* QUEUE COLORS */
-
-    //from main webqueue script
-    var colorsByQueue = {
-        'aae': {'bg' : '#7030A0', 'txt' : 'white' },
-        'abe' : {'bg' : '#256f78', 'txt' : 'white'},
-        'ag' : {'bg' : '#99CC00', 'txt' : 'white'},
-        'bidc' : {'bg' : '#C5FFC5', 'txt' : 'black'},
-        'biology' : {'bg' : '#67c1ee', 'txt' : 'black'},
-        'bme' : {'bg' : '#0D69FF', 'txt' : 'white'},
-        'ce' : {'bg' : '#008000', 'txt' : 'white' },
-        'che' : {'bg' : '#00FF00', 'txt' : 'black'},
-        'chem' : {'bg' : '#ffb1b7', 'txt' : 'black'},
-        'coea' : {'bg' : '#00D6BD', 'txt' : 'black'},
-        'coep' : {'bg' : '#FFDDB7', 'txt' : 'black'},
-        'comp.sci.' : {'bg' : '#772212', 'txt' : 'white'},
-        'cos admin' : {'bg' : '#ddaa33', 'txt' : 'black'},
-        'dp' : {'bg' : '#0070A8', 'txt' : 'white'},
-        'doe': {'bg' : 'red', 'txt' : 'white'},
-        'ece' : {'bg' : '#FF6600', 'txt' : 'white'},
-        'ecnaccts' : {'bg' : '#98A4AE', 'txt' : 'white'},
-        'eaps' : {'bg' : '#629454', 'txt': 'white'},
-        'eee' : {'bg' : '#F66A6A', 'txt' : 'white'},
-        'ene': {'bg' : '#A45CD0', 'txt': 'white' },
-        'engineering' : {'bg' : '#FFD900', 'txt' : 'black'},
-        'engr - south' : {'bg' : '#663300', 'txt' : 'white'},
-        'engr - north' : {'bg' : '#663300', 'txt' : 'white'},
-        'epics': {'bg' : '#E399E3', 'txt' : 'black'},
-        'flex' : {'bg' : '#A7ECFF', 'txt' : 'black'},
-        'helpdesk' : {'bg' : '#98A4AE', 'txt' : 'white'},
-        'hhs' : {'bg' : '#CFB991', 'txt' : 'black'},
-        'ie' : {'bg' : '#FFB7B7', 'txt' : 'black'},
-        'imi' : {'bg' : '#FFB96D', 'txt' : 'black'},
-        'apple' : {'bg' : '#666666', 'txt' : 'white'},
-        'mailman' : {'bg' : 'white', 'txt' : 'black'},
-        'math' : {'bg' : '#f7977a', 'txt' : 'black'},
-        'me' : {'bg' : '#b30000', 'txt' : 'white'},
-        'mse': {'bg' : '#EFD3F5', 'txt' : 'black'},
-        'ne': {'bg' : '#af6377', 'txt' : 'white'},
-        'pari' : {'bg' : '#3f5c8a', 'txt': 'white'},
-        'pharmacy' : {'bg' : '#FF33FF', 'txt' : 'white'},
-        'physics' : {'bg' : '#07622f', 'txt': 'white'},
-        //'potr' : {'bg' : '#663300', 'txt' : 'white'},
-        'president' : {'bg' : '#cfb991', 'txt' : 'black'},
-        'sacc' : {'bg' : '#434343', 'txt' : 'white'},
-        'science' : {'bg' : '#22dd94', 'txt' : 'black'},
-        'sitemgrs' : {'bg' : '#98A4AE', 'txt' : 'white'},
-        'stat' : {'bg' : '#ff6f44', 'txt' : 'white'},
-        'students' : {'bg' : '#98A4AE', 'txt' : 'white'},
-        'swt' : {'bg' : '#000ED6', 'txt' : '#FFEE00'},
-        'polytechnic' : {'bg' : 'black', 'txt' : 'white'},
-        'cnit' : {'bg' : '#434343', 'txt' : 'white'},
-        'uds' : {'bg' : '#98A4AE', 'txt' : 'white'},
-        'udsprojects': {'bg' : '#98A4AE', 'txt' : 'white'},
-        'vet' : {'bg' : '#CCFFFF', 'txt' : 'black'},
-        //'wang' : {'bg' : '#000099', 'txt' : 'white'},
-        'web' : {'bg' : '#B46086', 'txt' : 'white'},
-        'windows' : {'bg' : '#b77729', 'txt' : 'white'},
-        'zsite' : {'bg' : '#98A4AE', 'txt' : 'white'},
-    };
-
-    var colorsByTdxStatus = {
-        'In Process': {'bg' : '#FF3C3C20', 'txt' : 'var(--txt-1)', 'border' : '#FF3C3C50'},
-        'New': {'bg' : '#FF3C3C20', 'txt' : 'var(--txt-1)', 'border' : '#FF3C3C50'},
-        'Assigned': {'bg' : '#FF3C3C20', 'txt' : 'var(--txt-1)', 'border' : '#FF3C3C50'},
-        'Awaiting Customer Response': {'bg' : '#33CC3320', 'txt' : 'var(--txt-1)', 'border' : '#33CC3350'},
-        'Pending External': {'bg' : '#FF990020', 'txt' : 'var(--txt-1)', 'border' : '#FF990050'},
-        'Pending Internal': {'bg' : '#FF990020', 'txt' : 'var(--txt-1)', 'border' : '#FF990050'},
-    };
-
-    var tdxtoolsUrl = "https://engineering.purdue.edu"
-
-    //regex for matching inline highlights
-    var colorsByStatus = {
-        '!!': {style: {background: 'var(--col-highlight-1)'}, type: 'highlight', re: new RegExp("\!! (.*) \!!","g")},
-        '~~': {style: {background: 'var(--col-highlight-2)'}, type: 'highlight', re: new RegExp("\~~ (.*) \~~","g")},
-    }
-
-    var colorScheme
-
-    /* BEGIN FUNCTIONS */
-
-    //color manipulation via css filters: https://github.com/angel-rs/css-color-filter-generator
-    //modified to return an object instead of filter string
-
-    class Color {
-          constructor(r, g, b) {
-              this.set(r, g, b);
-          }
-
-          toString() {
-              return `rgb(${Math.round(
-                  this.r
-              )}, ${Math.round(this.g)}, ${Math.round(this.b)})`;
-          }
-
-          set(r, g, b) {
-              this.r = this.clamp(r);
-              this.g = this.clamp(g);
-              this.b = this.clamp(b);
-          }
-
-          hueRotate(angle = 0) {
-              angle = (angle / 180) * Math.PI;
-              const sin = Math.sin(angle);
-              const cos = Math.cos(angle);
-
-              this.multiply([
-                  0.213 + cos * 0.787 - sin * 0.213,
-                  0.715 - cos * 0.715 - sin * 0.715,
-                  0.072 - cos * 0.072 + sin * 0.928,
-                  0.213 - cos * 0.213 + sin * 0.143,
-                  0.715 + cos * 0.285 + sin * 0.14,
-                  0.072 - cos * 0.072 - sin * 0.283,
-                  0.213 - cos * 0.213 - sin * 0.787,
-                  0.715 - cos * 0.715 + sin * 0.715,
-                  0.072 + cos * 0.928 + sin * 0.072
-              ]);
-          }
-
-          grayscale(value = 1) {
-              this.multiply([
-                  0.2126 + 0.7874 * (1 - value),
-                  0.7152 - 0.7152 * (1 - value),
-                  0.0722 - 0.0722 * (1 - value),
-                  0.2126 - 0.2126 * (1 - value),
-                  0.7152 + 0.2848 * (1 - value),
-                  0.0722 - 0.0722 * (1 - value),
-                  0.2126 - 0.2126 * (1 - value),
-                  0.7152 - 0.7152 * (1 - value),
-                  0.0722 + 0.9278 * (1 - value)
-              ]);
-          }
-
-          sepia(value = 1) {
-              this.multiply([
-                  0.393 + 0.607 * (1 - value),
-                  0.769 - 0.769 * (1 - value),
-                  0.189 - 0.189 * (1 - value),
-                  0.349 - 0.349 * (1 - value),
-                  0.686 + 0.314 * (1 - value),
-                  0.168 - 0.168 * (1 - value),
-                  0.272 - 0.272 * (1 - value),
-                  0.534 - 0.534 * (1 - value),
-                  0.131 + 0.869 * (1 - value)
-              ]);
-          }
-
-          saturate(value = 1) {
-              this.multiply([
-                  0.213 + 0.787 * value,
-                  0.715 - 0.715 * value,
-                  0.072 - 0.072 * value,
-                  0.213 - 0.213 * value,
-                  0.715 + 0.285 * value,
-                  0.072 - 0.072 * value,
-                  0.213 - 0.213 * value,
-                  0.715 - 0.715 * value,
-                  0.072 + 0.928 * value
-              ]);
-          }
-
-          multiply(matrix) {
-              const newR = this.clamp(
-                  this.r * matrix[0] + this.g * matrix[1] + this.b * matrix[2]
-              );
-              const newG = this.clamp(
-                  this.r * matrix[3] + this.g * matrix[4] + this.b * matrix[5]
-              );
-              const newB = this.clamp(
-                  this.r * matrix[6] + this.g * matrix[7] + this.b * matrix[8]
-              );
-              this.r = newR;
-              this.g = newG;
-              this.b = newB;
-          }
-
-          brightness(value = 1) {
-              this.linear(value);
-          }
-          contrast(value = 1) {
-              this.linear(value, -(0.5 * value) + 0.5);
-          }
-
-          linear(slope = 1, intercept = 0) {
-              this.r = this.clamp(this.r * slope + intercept * 255);
-              this.g = this.clamp(this.g * slope + intercept * 255);
-              this.b = this.clamp(this.b * slope + intercept * 255);
-          }
-
-          invert(value = 1) {
-              this.r = this.clamp((value + (this.r / 255) * (1 - 2 * value)) * 255);
-              this.g = this.clamp((value + (this.g / 255) * (1 - 2 * value)) * 255);
-              this.b = this.clamp((value + (this.b / 255) * (1 - 2 * value)) * 255);
-          }
-
-          hsl() {
-              // Code taken from https://stackoverflow.com/a/9493060/2688027, licensed under CC BY-SA.
-              const r = this.r / 255;
-              const g = this.g / 255;
-              const b = this.b / 255;
-              const max = Math.max(r, g, b);
-              const min = Math.min(r, g, b);
-              let h,
-                  s,
-                  l = (max + min) / 2;
-
-              if (max === min) {
-                  h = s = 0;
-              } else {
-                  const d = max - min;
-                  s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
-                  switch (max) {
-                      case r:
-                          h = (g - b) / d + (g < b ? 6 : 0);
-                          break;
-
-                      case g:
-                          h = (b - r) / d + 2;
-                          break;
-
-                      case b:
-                          h = (r - g) / d + 4;
-                          break;
-                  }
-                  h /= 6;
-              }
-
-              return {
-                  h: h * 100,
-                  s: s * 100,
-                  l: l * 100
-              };
-          }
-
-          clamp(value) {
-              if (value > 255) {
-                  value = 255;
-              } else if (value < 0) {
-                  value = 0;
-              }
-              return value;
-          }
-      }
-
-    class Solver {
-        constructor(target, baseColor) {
-            this.target = target;
-            this.targetHSL = target.hsl();
-            this.reusedColor = new Color(0, 0, 0);
-        }
-
-        solve() {
-            const result = this.solveNarrow(this.solveWide());
-            return {
-                values: result.values,
-                loss: result.loss,
-                filter: this.css(result.values)
-            };
-        }
-
-        solveWide() {
-            const A = 5;
-            const c = 15;
-            const a = [60, 180, 18000, 600, 1.2, 1.2];
-
-            let best = { loss: Infinity };
-            for (let i = 0; best.loss > 25 && i < 3; i++) {
-                const initial = [50, 20, 3750, 50, 100, 100];
-                const result = this.spsa(A, a, c, initial, 1000);
-                if (result.loss < best.loss) {
-                    best = result;
-                }
-            }
-            return best;
-        }
-
-        solveNarrow(wide) {
-            const A = wide.loss;
-            const c = 2;
-            const A1 = A + 1;
-            const a = [0.25 * A1, 0.25 * A1, A1, 0.25 * A1, 0.2 * A1, 0.2 * A1];
-            return this.spsa(A, a, c, wide.values, 500);
-        }
-
-        spsa(A, a, c, values, iters) {
-            const alpha = 1;
-            const gamma = 0.16666666666666666;
-
-            let best = null;
-            let bestLoss = Infinity;
-            const deltas = new Array(6);
-            const highArgs = new Array(6);
-            const lowArgs = new Array(6);
-
-            for (let k = 0; k < iters; k++) {
-                const ck = c / Math.pow(k + 1, gamma);
-                for (let i = 0; i < 6; i++) {
-                    deltas[i] = Math.random() > 0.5 ? 1 : -1;
-                    highArgs[i] = values[i] + ck * deltas[i];
-                    lowArgs[i] = values[i] - ck * deltas[i];
-                }
-
-                const lossDiff = this.loss(highArgs) - this.loss(lowArgs);
-
-                for (let i = 0; i < 6; i++) {
-                    const g = (lossDiff / (2 * ck)) * deltas[i];
-                    const ak = a[i] / Math.pow(A + k + 1, alpha);
-                    values[i] = fix(values[i] - ak * g, i);
-                }
-
-                const loss = this.loss(values);
-                if (loss < bestLoss) {
-                    best = values.slice(0);
-                    bestLoss = loss;
-                }
-            }
-            return { values: best, loss: bestLoss };
-
-            function fix(value, idx) {
-                let max = 100;
-                if (idx === 2 /* saturate */) {
-                    max = 7500;
-                } else if (idx === 4 /* brightness */ || idx === 5 /* contrast */) {
-                    max = 200;
-                }
-
-                if (idx === 3 /* hue-rotate */) {
-                    if (value > max) {
-                        value %= max;
-                    } else if (value < 0) {
-                        value = max + (value % max);
-                    }
-                } else if (value < 0) {
-                    value = 0;
-                } else if (value > max) {
-                    value = max;
-                }
-                return value;
-            }
-        }
-
-        loss(filters) {
-            // Argument is array of percentages.
-            const color = this.reusedColor;
-            color.set(0, 0, 0);
-
-            color.invert(filters[0] / 100);
-            color.sepia(filters[1] / 100);
-            color.saturate(filters[2] / 100);
-            color.hueRotate(filters[3] * 3.6);
-            color.brightness(filters[4] / 100);
-            color.contrast(filters[5] / 100);
-
-            const colorHSL = color.hsl();
-            return (
-                Math.abs(color.r - this.target.r) +
-                Math.abs(color.g - this.target.g) +
-                Math.abs(color.b - this.target.b) +
-                Math.abs(colorHSL.h - this.targetHSL.h) +
-                Math.abs(colorHSL.s - this.targetHSL.s) +
-                Math.abs(colorHSL.l - this.targetHSL.l)
-            );
-        }
-
-        css(filters) {
-            function fmt(idx, multiplier = 1) {
-                return Math.round(filters[idx] * multiplier);
-            }
-
-            //modified here
-            return {
-                invert: `${fmt(0)}%`,
-                sepia: `${fmt(1)}%`,
-                saturate: `${fmt(2)}%`,
-                hue_rotate: `${fmt(3, 3.6)}deg`,
-                brightness: `${fmt(4)}%`,
-                contrast: `${fmt(5)}%`
-            }
-
-            //return `filter: invert(${fmt(
-            //    0
-            //)}%) sepia(${fmt(1)}%) saturate(${fmt(2)}%) hue-rotate(${fmt(3, 3.6)}deg) brightness(${fmt(4)}%) contrast(${fmt(5)}%);`;
-        }
-    }
-
-    function hexToRgb(hex) {
-        // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
-        const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
-        hex = hex.replace(shorthandRegex, (m, r, g, b) => {
-            return r + r + g + g + b + b;
-        });
-
-        const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
-        return result
-            ? [
-            parseInt(result[1], 16),
-            parseInt(result[2], 16),
-            parseInt(result[3], 16)
-        ]
-        : null;
-    }
-
-    function getFilterForColor(rgbColor) {
-        let bestResult = null;
-        let iterationCount = 0; // Initialize a counter for iterations
-
-        for (let i = 0; i < 200; i++) {
-            iterationCount++; // Increment the counter for each iteration
-            const color = new Color(rgbColor[0], rgbColor[1], rgbColor[2]);
-            const solver = new Solver(color);
-            const result = solver.solve();
-
-            if (!bestResult || result.loss < bestResult.loss) {
-                bestResult = result;
-                if (bestResult.loss <= 0.01) {
-                    // exit early if good result is found
-                    break;
-                }
-            }
-        }
-
-        console.log("Total iterations: ", iterationCount); // Log the total iterations
-        return bestResult;
-    }
-
-    //end color manipulation
-
-    function updateHeading(mutation) {
-        let headings = mutation.querySelectorAll(".tdx-control-bar__title")
-
-        for (const heading of headings) {
-            //color the header if queue name is found
-            let headingTxt = heading.innerText
-            let headingFirst = headingTxt.split(" ")[0]
-            headingFirst = headingFirst.toLowerCase()
-
-            let parent = heading.parentElement
-
-            handleHighlight("report",headingTxt,heading)
-
-            //try embedding
-            if (headingTxt.startsWith("{")) {
-                try {
-                    let embedData = JSON.parse(headingTxt)
-
-                    let title = document.createElement("h4")
-                    title.classList = heading.classList
-                    title.innerText = embedData.name
-                    let moduleBody = heading.parentNode.parentNode.parentNode.querySelector(".tdx-widget")
-                    let embed = document.createElement("iframe")
-                    embed.classList = "customEmbed"
-                    embed.src = embedData.url
-                    heading.replaceWith(title)
-                    moduleBody.replaceWith(embed)
-                } catch {
-                }
-            }
-        }
-    }
-
-    function parseTicket(mutation=null) {
-
-        let qBlock = document.querySelector("#ctlAttribute2285")
-        //ticket or task
-        let header = document.getElementById("thTicket_spnTitle") || document.querySelector("#upTaskHeader>div>h1")
-
-        //find calendar inputs when editing tickets/tasks
-        //let calendars = document.querySelectorAll("input.hasDatepicker")
-        let calendars = document.querySelectorAll("#txtStartDate, #txtEndDate") //tasks for now, will add more as found
-        if (calendars) {
-            let originalFormat = "M/D/YYYY h:mm A";
-            let newFormat = "YYYY-MM-DDTHH:mm";
-            [...calendars].forEach(calendar=>{
-                let date = moment(calendar.value,originalFormat)
-
-                let newCal = document.createElement("input")
-                newCal.id = `${calendar.id}-new`
-                newCal.classList = calendar.classList
-                newCal.type = "datetime-local"
-
-                function updateDate() {
-                    //update old tdx calendar
-                    let parsedFormat = date.format(originalFormat)
-                    calendar.value = parsedFormat
-
-                    //update new calendar
-                    let iso = date.format(newFormat)
-                    newCal.value = iso
-                    calTxt.innerText = date.calendar()
-
-                    console.log("Cal update!",date)
-                }
-
-                //convert to original format
-                newCal.addEventListener("input",event=>{
-                    let parsedValue = moment(event.target.value,newFormat)
-                    date = parsedValue
-                    updateDate()
-                })
-
-                //date modifier shortcuts
-                let calBox = document.createElement("div")
-                calBox.classList = ["calBox"]
-                let calTxt = document.createElement("span")
-                calTxt.innerText = date.format('dddd')
-
-                //modify date
-                function btnModify(btn) {
-                    console.log("Modify date:",btn)
-                    if ('add' in btn) {
-                        date.add(btn.add)
-                    } else if ('set' in btn) {
-                        date.set(btn.set)
-                    }
-
-                    //check business days
-                    let day = date.isoWeekday()
-                    let hour = date.hour()
-                    let min = date.minute()
-                    let wkday = date.weekday()
-
-                    console.log("WkDay:",wkday,"Day:",day,"hour:",hour,"min:",min)
-
-                    //if Friday after 5pm
-                    if (day>=5 && (hour>17 || (hour==17 && min>0))) {
-                        date.set({
-                            h: 8,
-                            d: 1+7,
-                            m: 0
-                        })
-                    } else if (day>5) {
-                        //if sat/sun
-                        date.set({
-                            d: 1+7
-                        })
-                    }
-
-
-                    updateDate()
-                }
-
-                let buttons = [
-                    {name:"+1 day",add: {days:1}},
-                    {name:"+1 week",add: {weeks:1}},
-                    {name:"+1 month",add: {months:1}},
-                    {name:"12PM",set: {h:12,m:0}},
-                    {name:"5PM",set: {h:17,m:0}}
-                ]
-
-                for (const btn of buttons) {
-                    let button = document.createElement("button")
-                    button.classList = "btn btn-calendar"
-                    button.innerText = btn.name
-                    button.addEventListener("click",(event)=>{
-                        event.preventDefault()
-                        btnModify(btn)
-                    })
-                    calBox.appendChild(button)
-                }
-
-                updateDate()
-
-                //old input still needs to exist for proper format conversion
-                calendar.style.display = "none"
-                calendar.parentElement.append(newCal)
-                calendar.parentElement.append(calTxt)
-                calendar.parentElement.append(calBox)
-            });
-        }
-
-        //change tab title
-        if (header) {
-            let ticketTitle = header.childNodes[0].textContent
-            document.title = ticketTitle
-        } else {
-            return
-        }
-
-        //add queue tag to ticket title
-        if (qBlock && !document.querySelector(".qBox")) {
-            let qElement = qBlock.querySelector("span.wrap-text")
-            let qTxt = qElement.innerText
-
-            //console.log("GOT QUEUE:",qTxt)
-
-            let newBox = document.createElement("span")
-            newBox.innerText = qTxt
-            newBox.classList.add("qBox")
-
-            for (const qK of Object.keys(colorsByQueue)) {
-                let q = colorsByQueue[qK]
-                if (qTxt.toLowerCase() == qK) {
-                    newBox.style.color = q.txt
-                    newBox.style.backgroundColor = q.bg
-                }
-
-            }
-
-            header.appendChild(newBox)
-        }
-
-        //handle button links - updates/tasks for now
-        //update buttons
-        [...document.querySelectorAll("#btnUpdateTicket, #divUpdateFromActions")].forEach(button=>{
-            handleLink("Update",button)
-        });
-
-        //task button
-        [...document.querySelectorAll("#liAddTicketTask>a")].forEach(button=>{
-            handleLink("TicketTaskNew",button)
-        });
-
-        //task template button
-        [...document.querySelectorAll("#divAddTaskTemplate>a")].forEach(button=>{
-            handleLink("TicketAddTaskTemplate",button)
-        });
-
-        //color the feed if darkmode
-        var feedItems
-
-        if (mutation) {
-            feedItems = mutation
-        } else {
-            feedItems = document.querySelectorAll("#ttDescription")
-        }
-
-        //console.log("Feed items:",feedItems)
-
-        if (feedItems) {
-            for (const feedItem of feedItems) {
-                [...feedItem.querySelectorAll("*[style*='color']")].forEach(feedElement=>{
-                    let color = tinycolor(feedElement.style.color)
-                    let brightness = color.getBrightness()
-                    //console.warn("ELEMENT:",feedElement)
-                    //console.log("Brightness:",brightness)
-
-                    //if color is too dark
-                    if (brightness < 100 && colorScheme == "darkMode") {
-
-                        var newColor
-                        var isGrey = true
-                        let rgb = color.toRgb()
-
-                        if (rgb.r == rgb.b && rgb.r == rgb.g) {
-                            isGrey = true
-                        } else {
-                            isGrey = false
-                        }
-
-                        //if color is shade of grey
-                        if (isGrey) {
-                            let flippedColor = tinycolor(invertHex(color.spin(180).toHex()))
-                            newColor = flippedColor
-                            //console.log(feedElement.innerText,"is grey")
-                        } else {
-                            let threshold = 50
-                            let diff = (threshold - brightness) + brightness
-                            newColor = color.brighten(diff)
-                            //console.log(feedElement.innerText,"is a color")
-                        }
-                        //console.log("oldColor:",color.toHex(),"newColor:",newColor.toHex())
-
-                        feedElement.style.color = newColor.toHexString()
-                    }
-                });
-            }
-        }
-    }
-
-    function parseOtherElements() {
-        let path = document.location.pathname;
-
-        //inject styles into search bar
-        [...document.querySelectorAll("tdx-search-bar, .js_sidePanelX")].forEach(searchBar=>{
-            //console.log("SEARCH BAR:",searchBar)
-            let shadow = searchBar.shadowRoot
-            if (shadow) {
-
-                injectOtherStyles(shadow);
-
-                //check nested shadows
-                [...shadow.querySelectorAll("tdx-close-x")].forEach(nested=>{
-                    let nestedShadow = nested.shadowRoot
-                    //console.log("NESTED:",nestedShadow)
-                    if (nestedShadow) {
-                        injectOtherStyles(nestedShadow)
-                    }
-                })
-            }
-        })
-
-        //force contrastive colors in descriptions with inline styles
-        document.querySelectorAll("div.moreToggle *:not(a), div.lessToggle *:not(a), div.wrap-text *:not(a)").forEach(textBlock=>{
-            textBlock.style.color = "var(--txt-1)"
-        })
-        document.querySelectorAll("#ToggleAIAgentAssist").forEach(AIAgentButton=>{     
-        let selected = settings('get','aiBehavior');
-            console.log("AI Behavior selected:",selected.value)
-            if (selected == "aiDisable") {
-                AIAgentButton.style.display = "none"
-            }  
-        })
-
-        let desktopLayout = settings('get','layout')
-        let desktop = document.querySelector("#divContent")
-        if (desktop && desktopLayout) {
-            let col1 = desktop.querySelector("#Column1")
-            let col2 = desktop.querySelector("#Column2")
-            let col3 = desktop.querySelector("#Column3")
-
-            //100% / 33-66%
-            if (desktopLayout=="1_100-66-33" && col2 && col3) {
-                console.log("Applying layout:",desktopLayout)
-
-                //define width classes
-                let col2WidthClass = "col-md-8"
-                let col3WidthClass = "col-md-4"
-
-                //resize column 2
-                for (const cls of col2.classList) {
-                    if (cls.startsWith("col-md")) {
-                        console.log("Found col2 width class:",cls)
-                        col2.classList.remove(cls)
-                        col2.classList.add(col2WidthClass)
-                        break
-                    }
-                }
-
-                //resize column 3
-                for (const cls of col3.classList) {
-                    if (cls.startsWith("col-md")) {
-                        col3.classList.remove(cls)
-                        col3.classList.add(col3WidthClass)
-                        break
-                    }
-                }
-            }
-        }
-
-        //apply sticky columns
-        let stickyColumns = settings('get','stickyColumns')
-        if (stickyColumns) {
-            [...document.querySelectorAll(".tdx-dashboard__column")].forEach(column=>{
-                column.style.position = "sticky"
-                column.style.alignSelf = "flex-start"
-                column.style.top = "4px"
-            });
-        }
-    }
-
-    function invertHex(hex) {
-      return (Number(`0x1${hex}`) ^ 0xFFFFFF).toString(16).substr(1).toUpperCase()
-    }
-
-    function parseTable(element) {
-        //let t = mutation.target;
-        //console.error("BEGIN MUTATION",t)
-        let table = element.querySelector("table")
-        let items = [];
-
-        if (table) {
-            let headers = [];
-            //console.log("Table",table);
-
-            //get headers of the tables
-            [...table.querySelectorAll("th")].forEach((header)=>{
-                var txt = header.querySelector("span")
-                //txt = txt.dataset.sort
-                //txt = txt.split(" ")[0]
-                if (txt) {
-                    headers.push(txt.textContent)
-                }
-                //console.log("i:",header.cellIndex,txt)
-            });
-
-            //console.log("Headers:",headers);
-
-            //parse rows
-            [...table.querySelectorAll("tr:has(td)")].forEach((row)=>{
-                //console.log("row:",row);
-                let item = {};
-                //parse each cell
-                let i = 0;
-                [...row.querySelectorAll("td:not(:has(input))")].forEach((cell)=>{
-                    //let i = cell.cellIndex; //can't use cellindex if there's a checkbox in the table
-                    let txt = cell.textContent;
-                    txt = txt.trim()
-
-                    //console.log("Cell:",i,cell);
-
-                    item[headers[i]] = {txt:txt,cell:cell}
-                    i++
-                })
-
-                item.row = row
-                items.push(item)
-                //console.log("ITEM:",item)
-
-                //being coloring
-                parseItem(item)
-            })
-        }
-
-        //updateHeading(element)
-    }
-
-    function createHighlightBubble(element,bgColor,txtColor,borderColor = "#00000000") {
-
-        //should the bubble carry links over?
-        //let copy = element.cloneNode(true)
-
-        //create new element to highlight
-        let newSpan = document.createElement("span")
-        newSpan.innerText = element.innerText //item["2285"].txt
-        newSpan.style.backgroundColor = bgColor
-        newSpan.style.color = txtColor
-        newSpan.style.borderColor = borderColor
-        newSpan.classList.add("qHighlight")
-
-        //if we use the copy method
-        //newSpan.appendChild(copy)
-
-        //replace cell with new span
-        element.replaceChildren(newSpan)
-        return newSpan
-    }
-
-    //modify/color the cells
-    function parseItem(item) {
-
-        //console.log("Parse item:",item)
-
-        //color queue names
-        if ('CSS Support' in item) {
-            let qCell = item["CSS Support"].cell
-            let qTxt = item["CSS Support"].txt.toLowerCase()
-            if (qTxt in colorsByQueue) {
-                let q = colorsByQueue[qTxt]
-
-                createHighlightBubble(qCell,q.bg,q.txt)
-            }
-        }
-
-        if ('Status' in item) {
-            let statusCell = item["Status"].cell
-            let statusText = item["Status"].txt
-            if (colorsByTdxStatus.hasOwnProperty(statusText)) {
-                let statusStyle = colorsByTdxStatus[statusText]
-                createHighlightBubble(statusCell, statusStyle.bg, statusStyle.txt, statusStyle.border)
-            }
-        }
-
-        //change date modified
-        let relativeDates = ['Modified','Created']
-        for (const dType of relativeDates) {
-            if (dType in item) {
-                let dTxt = item[dType].txt
-                let dCell = item[dType].cell
-
-                let date = moment(dTxt)
-                let dTxtNew = date.fromNow()
-
-                if (dTxtNew == "Invalid date") {
-                    //console.warn("Failed date:",dTxt,item)
-                } else {
-                    dCell.innerText = dTxtNew
-                }
-            }
-        }
-
-        let detailedDates = ['Date Due','Due','Created','Start','SLA Resolve By','SLA Respond By']
-        for (const dType of detailedDates) {
-            if (dType in item) {
-                let dTxt = item[dType].txt
-                let dCell = item[dType].cell
-
-                let date = moment(dTxt)
-                let dTxtNew = date.calendar()
-
-                if (dTxtNew == "Invalid date") {
-                    //console.warn("Failed date:",dTxt,item)
-                } else {
-                    dCell.innerText = dTxtNew
-                }
-            }
-        }
-
-        //highlight modified/age red
-        let modifiedDates = ['Modified']
-        for (const dType of modifiedDates) {
-            if (dType in item) {
-                let modDate = item[dType]
-                const ageThreshold = 336
-
-                let date = moment(modDate.txt)
-                let duration = moment.duration(moment().diff(date))
-                let hours = duration.asHours()
-
-                let alpha = hours / ageThreshold
-                alpha = alpha > 1 ? 1 : alpha
-
-                let cell = modDate.cell
-                handleHighlight("dateModified",alpha,cell)
-                cell.classList.add(alpha > 0.5 ? "light" : "dark")
-            }
-        }
-
-        //highlight modified/age red
-        let dueDates = ['Due','Date Due','SLA Resolve By','SLA Respond By']
-        for (const dType of dueDates) {
-            if (dType in item) {
-                let dueDate = item[dType]
-                const ageThreshold = -5*24
-
-                let date = moment(dueDate.txt)
-                let duration = moment.duration(moment().diff(date))
-                let hours = duration.asHours()
-                let alpha
-                if (hours < 0) {
-                    alpha = 1 - ((hours / ageThreshold))
-                    alpha = alpha < 0? 0: alpha
-                } else {
-                    alpha = 1
-                }
-                
-                if (!Number.isNaN(hours)) {
-                    let cell = dueDate.cell
-                    handleHighlight("dateModified",alpha,cell)
-                    cell.classList.add(alpha > 0.5 ? "light" : "dark")
-                }
-            }
-        }
-
-        let age = ['Age']
-        for (const dType of age) {
-            if (dType in item) {
-                let Age = item[dType]
-                const ageThreshold = 30
-
-                let days = Age.txt.slice(0,-1)
-
-                if (days > 30){
-                    days = days - 30
-                    let alpha = days / ageThreshold
-                    alpha = alpha > 1 ? 1 : alpha
-                    let cell = Age.cell
-                    handleHighlight("age",alpha,cell)
-                    cell.classList.add(alpha > 0.5 ? "light" : "dark")
-                }
-            }
-        }
-        
-        // let Status = ['Status']
-        // for (const dType of Status) {
-        //     if (dType in item) {
-        //         let CurrentStatus = item[dType]
-        //         let cell = CurrentStatus.cell
-        //         handleHighlight("status",CurrentStatus.txt,cell)
-        //     }
-        // }
-
-        //find user replies & last modified by internal
-        if ('Requestor' in item && 'Modified By' in item && 'Prim Resp' in item) {
-            let fromUser = item["Requestor"]
-            let lastModified = item["Modified By"]
-            let assignedTo = item["Prim Resp"]
-
-            //reply from user
-            if (fromUser.txt == lastModified.txt && fromUser.txt != assignedTo.txt && assignedTo.txt != "Unassigned") {
-                //item.row.style.backgroundColor = "var(--col-reply)";
-                handleHighlight("reply",null,item.row)
-            }
-
-            //modified by internal
-            if (lastModified.txt != fromUser.txt && lastModified.txt != assignedTo.txt) {
-                let cell = lastModified.cell
-                //cell.style.backgroundColor = "var(--col-modified)"
-                handleHighlight("userModified",null,cell)
-            }
-        }
-
-        //find internal users and highlight them
-        if ('Prim Resp' in item) {
-            handleHighlight("person",item['Prim Resp'].txt,item['Prim Resp'].cell)
-        } else if ('Responsibility' in item) {
-            handleHighlight("person",item.Responsibility.txt,item.Responsibility.cell)
-        }
-
-        //find inline highlights for tasks
-        if ('Title' in item) {
-            let title = item.Title
-            handleHighlight("title",title.txt,title.cell)
-        }
-
-        //find links & open in new tab, if configured
-        //let linkTypes = ['Title','TicketID','CustomerName','ResponsibleFullName','LastModifiedByFullName'] //open people in new tabs
-        let linkTypes = ['Title','TicketID','TicketTitle']
-        for (const linkType of linkTypes) {
-            if (linkType in item) {
-                let link = item[linkType].cell.querySelector("a")
-                if (link) {
-                    //override function that opens in windows
-                    handleLink("report",link)
-                }
-            }
-        }
-    }
-
-    function handleLink(source,link) {
-        let behavior = settings('get','linkBehavior')
-
-        let relL = window.screenLeft != undefined ? window.screenLeft : screen.left
-        let relT = window.screenTop != undefined ? window.screenTop : screen.top
-
-        if (behavior=="tabs") {
-
-            switch(source) {
-                case 'report': {
-                    link.onclick = null
-                    link.target = "_blank"
-                    break
-                }
-
-                case 'Update':
-                    case 'TicketTaskNew':
-                    case 'TicketAddTaskTemplate': {
-                    link.onclick = (event)=>{
-                        event.preventDefault()
-                        let w = (window.screen.width / 1.75)
-                        let h = (window.screen.height / 1.25)
-                        let l = ((window.screen.width / 2) - (w/2)) + relL
-                        let t = ((window.screen.height / 2) - (h/2)) + relT
-
-                        //restructure url for updating
-                        let location = window.location.pathname
-                        let baseHref = location.substr(0, location.lastIndexOf('/'))
-                        let href = `${baseHref}/${source}${window.location.search}`
-
-                        let params = `width=${w}px,height=${h}px,left=${l}px,top=${t}px`
-                        return window.open(href,'_blank',params)
-                    }
-                    break
-                }
-            }
-
-        } else {
-            return
-            //leave default
-            link.onclick = (event)=>{
-                event.preventDefault()
-                var params
-                var href
-                let w = (window.screen.width / 2.1)
-                let h = (window.screen.height / 1.25)
-                let l = 20 + relL
-                let t = 50 + relT
-
-                switch(source) {
-                    case 'report': {
-                        href = link.href
-                        break
-                    }
-
-                    case 'Update':
-                    case 'TicketTaskNew':
-                    case 'TicketAddTaskTemplate': {
-                        l = (window.screen.width / 2) + l
-
-                        //restructure url for updating
-                        let location = window.location.pathname
-                        let baseHref = location.substr(0, location.lastIndexOf('/'))
-                        href = `${baseHref}/${source}${window.location.search}`
-                        break
-                    }
-                }
-
-                params = `width=${w}px,height=${h}px,left=${l}px,top=${t}px`
-                return window.open(href,'_blank',params)
-            }
-        }
-
-    }
-
-    function handleHighlight(type, txt, element) {
-        let behavior = settings('get','highlightBehavior')
-
-        var re
-        var style = null
-
-        for (const [key,color] of Object.entries(colorsByStatus)) {
-            re = color.re.exec(txt)
-            if (re) {
-                style = color.style
-                break
-            }
-        }
-
-        const customHighlights = settings('get','customHighlights') || []
-        for (const customHighlight of customHighlights) {
-            let customType = customHighlight.type
-            if (customType=="highlight") {
-                let char = customHighlight.value
-                let reg = new RegExp(`\\${char} (.*) \\${char}`,"g")
-                re = reg.exec(txt)
-                if (re) {
-                    style = customHighlight.style
-                    break
-                }
-            }
-
-            if (type=="reply" && customType=="reply") {
-                style = customHighlight.style
-            }
-
-            if (type=="dateModified" && customType=="dateModified") {
-                style = customHighlight.style
-                if (style.background) {
-                    let a = Math.floor(txt * 255).toString(16);
-                    style.background = style.background + a
-                }
-            }
-
-            if (type=="userModified" && customType=="userModified") {
-                style = customHighlight.style
-            }
-
-            if (type=="report" && customType=="report") {
-                if (customHighlight.value==txt) {
-                    element.classList.add("reportTitle")
-                    style = customHighlight.style
-                }
-            }
-
-            if (type=="report" && customType=="report-regex") {
-                if ((new RegExp(customHighlight.value).exec(txt))) {
-                    element.classList.add("reportTitle")
-                    style = customHighlight.style
-                }
-            }
-
-            if (type=="person" && customType=="person") {
-                if (customHighlight.value==txt) {
-                    element = createHighlightBubble(element)
-                    style = customHighlight.style
-                }
-            }
-        }
-
-        if (style) {
-            //console.log("Apply custom highlight:",txt)
-
-            let link = element.querySelector("a")
-            if (behavior==="block") {
-                if (re && link) {
-                    let newTitle = re[1]
-                    link.innerText = newTitle
-                    //reset regex
-                    re.lastIndex = 0
-                }
-            } else {
-                if (re && link) {
-                    let text = link.innerText
-                    link.innerText = ""
-                    element = link.appendChild(document.createElement("span"))
-                    element.innerText = text
-                    element.style.lineHeight = "1.4"
-                    //reset regex
-                    re.lastIndex = 0
-                }
-            }
-
-            for (const [attr,val] of Object.entries(style)) {
-                element.style[attr] = val
-            }
-            //element.style.backgroundColor = style.background
-
-        } else {
-            //apply defaults
-            if (type=="reply") {
-                element.style.backgroundColor = "var(--col-reply)";
-
-            }
-            if (type=="userModified") {
-                element.style.backgroundColor = "var(--col-modified)";
-            }
-            if (type=="dateModified") {
-                element.style.backgroundColor = `rgba(255,0,0,${txt}`;
-            }
-            // if (type=="status"){
-            //     if (txt=="In Process") {
-            //         element.style.backgroundColor = "red"
-            //     }
-            // }
-            if (type=="age") {
-                element.style.backgroundColor = `rgba(255,0,0,${txt}`;
-            }
-        }
-    }
-
-    function generatePopup(href,w,h,l,t,source) {
-
-    }
-
-    function injectOtherStyles(element) {
-
-        let s = document.createElement("style")
-        s.id = "customStyles"
-        s.innerText = customStyles
-
-        //find iframes - likely text editors
-        if (element.tagName == "IFRAME") {
-            let frame = element.contentWindow.document;
-
-            //attempt color coded tables on non-desktop pages
-            /*let tables = frame.querySelectorAll("table");
-            [...tables].forEach(table=>{
-                parseTable(table.parentElement)
-            })*/
-
-            //console.log("Found iFrame:",frame)
-
-            //check for existing style block
-            if (!frame.querySelector("#customStyles")) {
-                let head = frame.querySelector("head")
-                let html = frame.querySelector("html")
-                html.classList.add(settings("get","colorMode"))
-                head.appendChild(s)
-            }
-        } else {
-            if (!element.querySelector("#customStyles")) {
-                setCssFilters(s)
-                element.appendChild(s)
-            }
-        }
-    }
-
-    function ckeinjectCustomCss(event) {
-        // var editor = event.editor
-        try {
-            if (!(event.document.$.getElementById("tdxuserscript-style"))) {
-                var style = event.document.$.createElement('style');
-                style.id = "tdxuserscript-style"
-                style.innerHTML = customStyles
-                event.document.$.getElementsByTagName('head')[0].appendChild(style);
-                event.document.$.querySelectorAll("div, span").forEach((element) => {
-                    element.style.color = "var(--txt-1)"
-                })
-            }
-        } catch(error) {}
-    }
-
-    //setup observer to watch report/table changes/refreshes
-    let observer = new MutationObserver((mutations) => {
-        mutations.forEach((mutation) => {
-            let t = mutation.target
-            if (t.querySelector("div > table")) {
-                //let table = t.firstElementChild.querySelector("table")
-                //console.log("Matched table",t)
-                
-                //potential cause of freezing issue 
-                //parseTable(t)
-            }
-
-            //parse the feed if it updates
-            if (t.classList.contains("feed")) {
-                parseTicket(mutation.addedNodes)
-            } else if (t.classList.contains("feed-body")) {
-                parseTicket(t.querySelectorAll(".feed-reply"))
-            }
-
-            //force contrastive colors in comments/replies with inline styles
-            document.querySelectorAll("div.feed-item-text *:not(a)").forEach(textBlock=>{
-                textBlock.style.color = "var(--txt-1)"
-            })
-
-            //parse dashboard widgets
-            if (t.id=="tdx-workmgmt-container-collection") {
-                parseOtherElements()
-            }
-
-            //parse side panels
-            if (t.classList.contains("tdx-right-side-panel")) {
-                parseOtherElements()
-            }
-            
-            let module = t.querySelector("div > .tdx-dashboard__widget-container")
-            if (module) {
-                updateHeading(t)
-            }
-
-            try { 
-                for (const instance in CKEDITOR.instances) {
-                    ckeinjectCustomCss(CKEDITOR.instances[instance]);
-                }
-            } catch (error) {}
-
-            //search whole document, frames may reset when reopened
-            // let frames = document.querySelectorAll("iframe:not(.customEmbed)")
-            // if (frames) {
-            //     [...frames].forEach(frame=>{
-            //         injectOtherStyles(frame)
-            //     });
-            // }
-        });
-    });
-
-    if (true) {
-        console.log("Observing...")
-        observer.observe(document.body, {
-            characterDataOldValue: false,
-            subtree: true,
-            childList: true,
-            characterData: false
-        });
-    }
-
-    async function changeTitle() {
-        let title = document.querySelector(".tdx-headerbar-headline a")
-        if (title) {
-            title.innerText = primaryTitle
-        }
-
-        await injectToolbar()
-    }
-
-    function colorChange(color) {
-        localStorage.setItem("colors",color)
-        setColors(color)
-    }
-
-    function setColors(color,value) {
-        console.log("Setting",color,"to",value)
-        //let col = tinycolor(value).toRgbString()
-        let col = value
-        let style = document.documentElement.style
-
-        switch(color) {
-            case 'primaryColor':
-                style.setProperty('--dark-col-primary', col);
-                style.setProperty('--light-col-primary', col);
-                break
-
-            case 'backgroundColor':
-                style.setProperty('--dark-bg-primary', col);
-                style.setProperty('--light-bg-primary', col);
-                break
-
-            case 'theme': {
-
-                for (const col of ["dark","light"]) {
-                    let accent = `var(--${col}-${value}-accent)`
-                    let bg = `var(--${col}-${value}-bg)`
-                    style.setProperty(`--${col}-col-primary`, accent)
-                    style.setProperty(`--${col}-bg-primary`, `var(--${col}-bg-default)`)
-
-                }
-
-                break
-            }
-        }
-    }
-
-    function setCssFilters(element=null) {
-        let style = element ? element.style : document.documentElement.style
-        //quick test for filter generation
-        let mode = getColorMode().split("Mode")[0]
-        let priCol = window.getComputedStyle(document.body).getPropertyValue("--dark-col-primary")
-        let rgb = hexToRgb(priCol)
-        //let filters = getFilterForColor(rgb)
-
-        const color = new Color(rgb[0], rgb[1], rgb[2]);
-        const solver = new Solver(color);
-        const result = solver.solve();
-        let filters = result.filter
-
-        //console.log("STYLES:",priCol)
-        //console.log("FILTERS:",priCol,rgb,filters)
-
-        style.setProperty("--filter-brightness",filters.brightness)
-        style.setProperty("--filter-contrast",filters.contrast)
-        style.setProperty("--filter-hue-rotate",filters.hue_rotate)
-        style.setProperty("--filter-invert",filters.invert)
-        style.setProperty("--filter-saturate",filters.saturate)
-        style.setProperty("--filter-sepia",filters.sepia)
-    }
-
-    /*
-    function toggleColorMode() {
-        let mode = getColorMode() == "darkMode" ? "lightMode" : "darkMode"
-        setColorMode(mode)
-    }
-
-    */
-
-    function getColorMode() {
-        let mode = window.matchMedia('(prefers-color-scheme: dark)').matches ? "darkMode" : "lightMode"
-        return mode
-    }
-
-    function setColorMode(mode,store=true) {
-        if (!mode) {
-            mode = "auto"
-        }
-        console.log("Set color mode to",mode)
-        colorScheme = mode
-        var storageMode = mode
-
-        let autoScheme = getColorMode()
-        if (autoScheme == mode) {
-            storageMode = "auto"
-        }
-
-        if (mode == "auto" || storageMode == "auto") {
-            mode = autoScheme
-            document.documentElement.classList.remove("lightMode")
-            document.documentElement.classList.remove("darkMode")
-        } else {
-            document.documentElement.classList.add(mode)
-        }
-
-        if (store) {
-            localStorage.setItem("styles",storageMode)
-        }
-
-    }
-
-    try {
-        CKEDITOR.on('instanceReady', function(event) {
-            ckeinjectCustomCss(event)
-        })
-    } catch (error) {}
-
-    async function injectToolbar() {
-        let iconBar = document.querySelector("#globalSearchBar")
-
-        let statusHTML = `
-            
- - -
- ` - - let toolsHTML = ` - - ` - - let buttonHTML = ` -
- -
- ` - - let settingsHTML = ` - - - ` - - let settingsButton = document.createElement("span") - settingsButton.innerHTML = buttonHTML - - let settingsPage = document.createElement("div") - settingsPage.innerHTML = settingsHTML - - let statusLink = document.createElement("span") - statusLink.innerHTML = statusHTML - - let toolsLink = document.createElement("span") - toolsLink.innerHTML = toolsHTML - - if (iconBar) { - iconBar.after(settingsButton) - - //settings - //settingsPage.querySelector("#colorMode").onclick = toggleColorMode - settingsButton.querySelector("#settingsButton").addEventListener("click",()=>{ - settings("toggle",settingsPage) - }) - settingsButton.appendChild(settingsPage) - - //form changes - let form = settingsPage.querySelector("form") - form.addEventListener("change", (event)=>{ - settings("update",form) - }); - form.addEventListener("submit", (event)=>{ - event.preventDefault() - }); - - //send/recieve data from popup - let customColorButton = settingsPage.querySelector("#colorPopup") - customColorButton.addEventListener("click", (event)=>{ - let url = `${tdxtoolsUrl}/ecnuds/tdx/userscript/coloreditor` - let colorWindow = window.open(url,"TDX Color Editor","popup=true") - colorWindow.onload = function() { - colorWindow.postMessage({msg:"here's the data"},"*") - } - }); - - //links - let parent = iconBar.parentElement - - //tools - parent.prepend(toolsLink) - - //status - parent.prepend(statusLink) - let statusData = await getITStatus() - let statusIcon = statusLink.querySelector("#statusIcon") - let statusTime = statusLink.querySelector("#statusTime") - let statusText = statusLink.querySelector("#statusText") - - let operationalText = "All systems operational." - //check the first 5 words. do they contain operational or green? - //since the default message can vary sometimes - let operationalRegex = /^(?=(?:\w+\s){0,5}?(?:operational|green)\b(?!-))(\w+(?:\s\w+){0,5})/gm - - if (statusData) { - if (statusData.msg.length==0) { - statusData.msg = operationalText - } - } else { - statusData = { - msg: operationalText - } - } - - if (!operationalRegex.test(statusData.msg)) { - statusIcon.classList = ("fa-solid fa-triangle-exclamation") - } else { - statusIcon.classList = ("fa-solid fa-check") - } - - let statusTimeParsed = moment(statusData.time) - statusTime.innerText = statusTimeParsed.fromNow() - statusText.innerText = statusData.msg - } - } - - async function getITStatus() { - let url = "https://it.purdue.edu/api-status/messages.php" - let res = await fetch(url) - let data = await res.json() - - let msg = {} - - let msgs = data.Results - if (msgs.length>0) { - msg = { - time: msgs[0], - msg: msgs[1] - } - console.warn("IT Message:",msg) - } else { - msg = null - } - - return msg - } - - /* SETTINGS */ - - function settings(action,value=null) { - var data - var menu - try { - data = JSON.parse(localStorage.getItem("userSettings")) - - if (!data) { - throw "Data is null" - } else { - //resolve stringified objects - if ('customHighlights' in data) { - data.customHighlights = JSON.parse(data.customHighlights) - } - } - } catch(e) { - //console.error("Couldn't grab settings!",e) - //set defaults - data = { - colorMode: getColorMode(), - linkBehavior: "tabs", - highlightBehavior: "block", - customHighlights: [], - } - } - - switch(action) { - case 'apply': { - for (const setting in data) { - let form = document.forms.settingsForm - let value = data[setting] - - if (typeof value == "object") { - value = JSON.stringify(value) - } - - console.log("Apply setting:",setting,value) - try { - if (form) { - let elements = form.elements - form[setting].value = value - if (form[setting].type=="checkbox") { - form[setting].checked = value=="enabled" ? true : false - } - } - } catch {} - } - - if ('colorMode' in data) { - setColorMode(data.colorMode) - } - - if ('theme' in data) { - if (data.theme=="custom") { - setColors('primaryColor',data.primaryColor) - setColors('backgroundColor',data.backgroundColor) - } else { - setColors('theme',data.theme) - } - } - break - } - - case 'get': { - if (value) { - return value in data ? data[value] : null - } else { - return data - } - break - } - - case 'toggle': { - let menu = document.querySelector("#settingsMenu") - let newState = menu.classList.contains("show") ? "hide" : "show" - let oldState = newState=="show" ? "hide" : "show" - menu.classList.add(newState) - menu.classList.remove(oldState) - break - } - - case 'update': { - let form = document.querySelector("#settingsForm") - let formData = new FormData(form) - data = Object.fromEntries([...formData]) - console.log("Settings update!",data) - localStorage.setItem("userSettings",JSON.stringify(data)) - settings("apply") - setCssFilters() - } - } - } - - function parseCustomHighlights(data) { - console.log("Custom highlights:",data) - } - - /* TDX TOOLS */ - function checkPath() { - let path = document.location.pathname - if (path=="/TDWebApi/api/auth/loginsso") { - let pre = document.querySelector("pre") - if (pre) { - console.log("Got key!",pre.innerText) - let key = pre.innerText - window.opener.postMessage({tdxkey:key},tdxtoolsUrl) - window.close() - } - } - } - - window.addEventListener("message",(event) => { - let data = event.data - let origin = event.origin - let trgt = event.currentTarget - console.log("Message from:",origin,data,event) - - if (data.colorsReady) { - let colors = settings('get','customHighlights') - event.source.postMessage({ customColors: colors }, "*") - } - if (data.colorData) { - let element = document.getElementById("customHighlights") - let strData = JSON.stringify(data.colorData) - element.value = strData - settings('update') - } - },false); - - changeTitle() - //checkColorMode() - settings("apply") - parseTicket() - checkPath() - - addEventListener("storage", (event) => { - //console.log("Storage event:",event) - if (event.key == "userSettings") { - settings("apply") - } - }); - - var customStyles = ` - -/* Root Styles */ - -:root { - - --dark-bg-default: #000; - --light-bg-default: #fff; - - --dark-col-default: #ab9266; - --light-col-default: #cbb080; - - --dark-col-primary: var(--dark-col-default); - --light-col-primary: var(--light-col-default); - - --dark-bg-primary: var(--dark-bg-default); - --light-bg-primary: var(--light-bg-default); - - --dark-gold-accent: #ab9266; - --light-gold-accent: #c3aa7f; - - --dark-col-green: #295f29; - --dark-col-red: #912c2c; - --dark-col-blue: #32577a; - --dark-col-yellow: #654a24; - - --light-col-green: #e3fcea; - --light-col-red: #ff6190; - --light-col-blue: #e1f5fc; - --light-col-yellow: #ffefd8; - - /* Original TDX blue */ - --dark-blue-accent: #4c778d; - --light-blue-accent: #4b3bb9; - - --dark-green-accent: #559170; - --light-green-accent: var(--dark-green-accent); - - --filter-invert: 0; - --filter-sepia: 0; - --filter-saturate: 0; - --filter-hue-rotate: 0; - --filter-brightness: 0; - --filter-contrast: 0; - - --dark-bg-0: color-mix(in srgb,var(--dark-bg-primary),#fff 5%); - --dark-bg-1: color-mix(in srgb,var(--dark-bg-primary),#fff 12%); - --dark-bg-2: color-mix(in srgb,var(--dark-bg-primary),#fff 20%); - --dark-bg-3: color-mix(in srgb,var(--dark-bg-primary),#fff 25%); - --dark-bg-4: color-mix(in srgb,var(--dark-bg-primary),#fff 30%); - --dark-col-100: color-mix(in srgb,var(--dark-col-primary),#000 70%); - --dark-col-200: color-mix(in srgb,var(--dark-col-primary),#000 60%); - --dark-col-300: color-mix(in srgb,var(--dark-col-primary),#000 50%); - --dark-col-400: var(--dark-col-primary); - --dark-col-500: color-mix(in srgb, var(--dark-col-primary), #aaa 50%); - --dark-col-600: color-mix(in srgb,var(--dark-col-primary),#fff 35%); - --dark-col-700: color-mix(in srgb,var(--dark-col-primary),#fff 25%); - --dark-col-link: #d1dbff; - --dark-txt-0: #bbb; - --dark-txt-1: #fff; - --dark-txt-2: #ececec; - --dark-txt-3: #929292; - --dark-txt-4: #ffffff8c; - --dark-txt-5: var(--light-txt-1); - --dark-border-0: color-mix(in srgb,var(--dark-bg-primary),#fff 18%); - --dark-border-1: color-mix(in srgb,var(--dark-bg-primary),#fff 30%); - --dark-col-reply: #1e3438; - --dark-col-highlight-1: #ffdb0059; - --dark-col-highlight-2: #5f00ff5e; - --dark-col-currentuser: #09482f; - --dark-col-modified: #ff660012; - --dark-txt-invert: 1; - --dark-txt-hue: 180deg; - --dark-shadow-1: rgba(200, 200, 200, 0.1); - --dark-shadow-2: rgba(200, 200, 200, 0.06); - - --light-txt-1: #000; - --light-txt-2: #222; - --light-txt-3: #333; - --light-txt-4: #0000008c; - --light-txt-5: var(--dark-txt-1); - --light-col-100: color-mix(in srgb,var(--light-col-primary),#fff 85%); - --light-col-200: color-mix(in srgb,var(--light-col-primary),#fff 75%); - --light-col-300: color-mix(in srgb,var(--light-col-primary),#fff 65%); - --light-col-400: var(--light-col-primary); - --light-col-500: color-mix(in srgb, var(--light-col-primary), #aaa 50%); - --light-col-600: color-mix(in srgb,var(--light-col-primary),#111 70%); - --light-col-700: color-mix(in srgb,var(--light-col-primary),#000 75%); - --light-bg-0: color-mix(in srgb,var(--light-bg-primary),#000 0%); - --light-bg-1: color-mix(in srgb,var(--light-bg-primary),#000 7%); - --light-bg-2: color-mix(in srgb,var(--light-bg-primary),#000 13%); - --light-bg-3: color-mix(in srgb,var(--light-bg-primary),#000 20%); - --light-bg-4: color-mix(in srgb,var(--light-bg-primary),#000 25%); - --light-bg-5: color-mix(in srgb,var(--light-col-primary),#ffffffd7 75%); - --light-border-0: color-mix(in srgb,var(--light-bg-primary),#000 18%); - --light-border-1: color-mix(in srgb,var(--light-bg-primary),#000 30%); - --light-col-reply: #d3f2ff; - --light-col-highlight-1: #fff3c4; - --light-col-highlight-2: #e3c4ff; - --light-col-currentuser: #5de2ad; - --light-col-modified: #ffe8d1; - --light-txt-invert: 0; - --light-txt-hue: 0deg; - --light-shadow-1: rgba(50, 50, 50, 0.1); - --light-shadow-2: rgba(50, 50, 50, 0.06); - - --body-text-color: var(--txt-0); -} - -@media (prefers-color-scheme: light) { - :root { - color-scheme: light; - --bg-0: var(--light-bg-0); - --bg-1: var(--light-bg-1); - --bg-2: var(--light-bg-2); - --bg-3: var(--light-bg-3); - --bg-4: var(--light-bg-4); - --bg-5: var(--light-bg-5); - --col-100: var(--light-col-100); - --col-200: var(--light-col-200); - --col-300: var(--light-col-300); - --col-400: var(--light-col-400); - --col-500: var(--light-col-500); - --col-600: var(--light-col-600); - --col-700: var(--light-col-700); - --col-link: var(--light-col-link); - --txt-0: var(--light-txt-0); - --txt-1: var(--light-txt-1); - --txt-2: var(--light-txt-2); - --txt-3: var(--light-txt-3); - --txt-4: var(--light-txt-4); - --txt-5: var(--light-txt-5); - --txt-invert: var(--light-txt-invert); - --txt-hue: var(--light-txt-hue); - --border-0: var(--light-border-0); - --border-1: var(--light-border-1); - --col-reply: var(--light-col-reply); - --col-highlight-1: var(--dark-col-highlight-1); - --col-highlight-2: var(--dark-col-highlight-2); - --col-currentuser: var(--light-col-currentuser); - --col-modified: var(--dark-col-modified); - --shadow-1: var(--light-shadow-1); - --shadow-2: var(--light-shadow-2); - --filter-brightness: var(--light-filter-brightness); - --filter-invert: var(--light-filter-invert); - } -} - -@media (prefers-color-scheme: dark) { - :root { - color-scheme: dark; - --bg-0: var(--dark-bg-0); - --bg-1: var(--dark-bg-1); - --bg-2: var(--dark-bg-2); - --bg-3: var(--dark-bg-3); - --bg-4: var(--dark-bg-4); - --bg-5: var(--dark-bg-5); - --col-100: var(--dark-col-100); - --col-200: var(--dark-col-200); - --col-300: var(--dark-col-300); - --col-400: var(--dark-col-400); - --col-500: var(--dark-col-500); - --col-600: var(--dark-col-600); - --col-700: var(--dark-col-700); - --col-red: var(--dark-col-red); - --col-green: var(--dark-col-green); - --col-blue: var(--dark-col-blue); - --col-yellow: var(--dark-col-yellow); - --col-link: var(--dark-col-link); - --txt-0: var(--dark-txt-0); - --txt-1: var(--dark-txt-1); - --txt-2: var(--dark-txt-2); - --txt-3: var(--dark-txt-3); - --txt-4: var(--dark-txt-4); - --txt-5: var(--dark-txt-5); - --txt-invert: var(--dark-txt-invert); - --txt-hue: var(--dark-txt-hue); - --border-0: var(--dark-border-0); - --border-1: var(--dark-border-1); - --col-reply: var(--dark-col-reply); - --col-highlight-1: var(--dark-col-highlight-1); - --col-highlight-2: var(--dark-col-highlight-2); - --col-currentuser: var(--dark-col-currentuser); - --col-modified: var(--dark-col-modified); - --shadow-1: var(--dark-shadow-1); - --shadow-2: var(--dark-shadow-2); - --filter-brightness: var(--dark-filter-brightness); - --filter-invert: var(--dark-filter-invert); - } -} - -:root.darkMode { - color-scheme: dark; - --bg-0: var(--dark-bg-0); - --bg-1: var(--dark-bg-1); - --bg-2: var(--dark-bg-2); - --bg-3: var(--dark-bg-3); - --bg-4: var(--dark-bg-4); - --bg-5: var(--dark-bg-5); - --col-100: var(--dark-col-100); - --col-200: var(--dark-col-200); - --col-300: var(--dark-col-300); - --col-400: var(--dark-col-400); - --col-500: var(--dark-col-500); - --col-600: var(--dark-col-600); - --col-700: var(--dark-col-700); - --col-red: var(--dark-col-red); - --col-green: var(--dark-col-green); - --col-blue: var(--dark-col-blue); - --col-yellow: var(--dark-col-yellow); - --col-link: var(--dark-col-link); - --txt-0: var(--dark-txt-0); - --txt-1: var(--dark-txt-1); - --txt-2: var(--dark-txt-2); - --txt-3: var(--dark-txt-3); - --txt-4: var(--dark-txt-4); - --txt-5: var(--dark-txt-5); - --txt-invert: var(--dark-txt-invert); - --txt-hue: var(--dark-txt-hue); - --border-0: var(--dark-border-0); - --border-1: var(--dark-border-1); - --col-reply: var(--dark-col-reply); - --col-highlight-1: var(--dark-col-highlight-1); - --col-highlight-2: var(--dark-col-highlight-2); - --col-currentuser: var(--dark-col-currentuser); - --col-modified: var(--dark-col-modified); - --shadow-1: var(--dark-shadow-1); - --shadow-2: var(--dark-shadow-2); - --filter-brightness: var(--dark-filter-brightness); - --filter-invert: var(--dark-filter-invert); -} - -:root.lightMode { - color-scheme: light; - --bg-0: var(--light-bg-0); - --bg-1: var(--light-bg-1); - --bg-2: var(--light-bg-2); - --bg-3: var(--light-bg-3); - --bg-4: var(--light-bg-4); - --bg-5: var(--light-bg-5); - --col-100: var(--light-col-100); - --col-200: var(--light-col-200); - --col-300: var(--light-col-300); - --col-400: var(--light-col-400); - --col-500: var(--light-col-500); - --col-600: var(--light-col-600); - --col-700: var(--light-col-700); - --col-red: var(--light-col-red); - --col-green: var(--light-col-green); - --col-blue: var(--light-col-blue); - --col-yellow: var(--light-col-yellow); - --col-link: var(--light-col-link); - --txt-0: var(--light-txt-0); - --txt-1: var(--light-txt-1); - --txt-2: var(--light-txt-2); - --txt-3: var(--light-txt-3); - --txt-4: var(--light-txt-4); - --txt-5: var(--light-txt-5); - --txt-invert: var(--light-txt-invert); - --txt-hue: var(--light-txt-hue); - --border-0: var(--light-border-0); - --border-1: var(--light-border-1); - --col-reply: var(--light-col-reply); - --col-highlight-1: var(--dark-col-highlight-1); - --col-highlight-2: var(--dark-col-highlight-2); - --col-currentuser: var(--light-col-currentuser); - --col-modified: var(--dark-col-modified); - --shadow-1: var(--light-shadow-1); - --shadow-2: var(--light-shadow-2); - --filter-brightness: var(--light-filter-brightness); - --filter-invert: var(--light-filter-invert); -} - -/* Body */ - -body { - background-color: var(--bg-0) !important; - color: var(--txt-1) !important; -} - -::-webkit-scrollbar-track { - background: var(--bg-0) !important; -} - -::-webkit-scrollbar-thumb { - background: var(--col-400) !important; - border: 5px solid var(--bg-0) !important; -} - -::-webkit-scrollbar-thumb:hover { - border: 3px solid var(--bg-0) !important; - background: var(--col-400) !important; -} - -::-webkit-scrollbar-corner { - background-color: var(--bg-0) !important; - } - -.tdx-overlay { - background-color: color-mix(in srgb,var(--col-400),#00000000 25%) !important; -} - -.tdx-overlay__item { - background-color: var(--bg-0) !important; - color: var(--col-400) !important; -} - -.tdx-overlay__item:hover, .tdx-overlay__item:focus-visible { - background-color: var(--col-400) !important; - color: var(--col-100) !important; -} - -.tdx-navigation-tab-bar { - background-color: initial !important; -} - -.tdx-leftnav__container { - background-color: var(--bg-0) !important; - border-color: var(--border-0) !important; - box-shadow: 0 1px 3px var(--shadow-1),0 2px 10px var(--shadow-2) !important; -} - -.tdx-leftnav__item { - color: var(--txt-1) !important; -} - -.tdx-leftnav__item--active .tdx-leftnav__link { - background-color: var(--col-100) !important; - color: var(--col-400) !important; -} - -.tdx-leftnav__link:hover, .tdx-leftnav__link:focus-visible { - background-color: var(--col-100) !important; -} - -.tdx-main-container { - background-color: var(--bg-0) !important; -} - -.tdx-layout-option__layout-preview { - background-color: var(--col-100) !important; -} - -.tdx-layout-option__column { - background-color: var(--bg-0) !important; -} - -.tdx-layout-selector__layout-option:hover, .tdx-layout-selector__layout-option:focus, .tdx-layout-selector__layout-option--selected { - background-color: var(--col-400) !important; -} - -.tdx-list__section { - color: var(--txt-2); -} - -/* Script-Specific Additions */ -#settingsMenu { - right: 50px; - padding: 10px; - width: 250px; - background: var(--bg-1); -} - -#settingsMenu.hide { - visibility: hidden; -} - -#settingsMenu h5 { - margin-bottom: 2px; -} - -#settingsMenu h3 { - padding-top: 10px; - font-weight: 500; - font-size: 18px; -} - -#settingsForm .flex { - display: flex; - gap: 24px; - align-items: baseline; -} - -#settingsForm .textBox { - display: flex; - flex-direction: column; - gap: 8px; -} - -.customEmbed { - border: 0; - width: 100%; - height: 400px; -} - -.calBox { - display: flex; - justify-content: space-around; - flex-wrap: wrap; - padding-top: 4px; - gap: 4px; - max-width: 220px; -} - -#statusBox:hover #statusMsg { - display: block; - width: 400px; - line-height: 22px; - padding: 8px; - right: 390px; -} - -#statusTime, #statusText { - margin: 6px; -} - -#statusTime { - font-size: 12px; -} - -#statusBox .fa-triangle-exclamation { - color: #ff8c4c; -} - -#statusBox .fa-check { - color: #0dbb28; -} - -.qBox { - margin-left: 10px; - padding: 5px; - font-size: 20px; - border-radius: 7px; -} - -.qHighlight { - padding: 4px; - border-radius: 8px; - border-width: 2px; - border-style: solid; - white-space: nowrap; -} - -.btn-calendar { - flex-grow: 1; - padding: 2px; - background-color: var(--col-500); - color: var(--txt-5); -} - -.btn-calendar:hover { - background-color: var(--col-400); - color: var(--txt-5) -} - -.reportTitle { - border-radius: 12px; - padding-left: 10px !important; - padding-right: 10px !important; -} - -/* Others */ -.tdx-loading-animation { - color: var(--col-400) !important; -} - -.refresh-indicator { - background: linear-gradient(180deg,var(--bg-0),hsla(0,0%,100%,0)) !important; -} - -.breadcrumb { - background-color: var(--bg-0); -} - -.breadcrumb>.active { - color: var(--txt-3); -} - -p.row { - gap: 8px; -} - -/* Headers */ - -h1, h2, h3, h4, h5 { - color: var(--txt-1) !important; -} - -.tdx-header-container { - background-color: var(--col-100) !important; -} - -.tdx-headerbar-headline, .tdx-headerbar-headline a { - color: var(--col-1) !important; -} - -.tdx-headline { - color: var(--txt-1) !important; -} - -.tdx-headline--underline { - border-color: var(--border-0); -} - -.tdx-navigation-tabs__tab { - color: var(--col-600) !important; -} - -.tdx-navigation-tabs__home-tab--active, .tdx-navigation-tabs__tab--active { - background-color: var(--bg-0) !important; - color: var(--col-400) !important; -} - -.tdx-navigation-tabs__tab:hover:not(.tdx-navigation-tabs__tab--active) { - background-color: var(--col-200) !important; -} - -.tdx-navigation-tabs__home-tab:hover { - background-color: var(--col-200) !important; -} - -.tdx-navigation-tabs__home-tab--active:hover { - background-color: var(--bg-0) !important; -} - -.tdx-dropdown--headline { - color: var(--txt-1) !important; -} - -.tdx-dropdown:hover { - background-color: var(--col-200) !important; -} - -.tdx-dropdown.active { - background-color: var(--col-300) !important; -} - -.tdx-dropdown-popout, -.tdx-dropdown-popout__menu { - background-color: var(--bg-0) !important; -} - -.tdx-dropdown-popout__menu-item { - background-color: var(--bg-0) !important; - color: var(--txt-1) !important; -} - -.tdx-dropdown-popout__menu-item:hover, .tdx-dropdown-popout__menu-item:focus { - color: var(--txt-1) !important; - background-color: var(--col-300) !important; -} - -.tdx-dropdown-popout__menu-item--selected { - color: var(--col-400) !important; -} - -.tdx-dropdown-popout__header { - background-color: var(--bg-0) !important; - color: var(--col-600) !important; -} - -.tdx-dropdown-popout__break { - border-color: var(--border-0) !important; -} - -.tdx-dropdown__divider { - background-color: var(--bg-0) !important; -} - -.tdx-dropdown__divider::before { - background: linear-gradient(90deg,var(--bg-0),var(--border-0),var(--border-0),var(--border-0),var(--bg-0)) !important; -} - -.tdx-label { - color: var(--txt-1) !important; -} - -/* Inputs */ - -.tdx-dropdown--dark, -.tdx-searchbar__textbox--dark { - background-color: var(--col-200) !important; - color: var(--txt-1) !important; -} - -.tdx-dropdown--dark:hover, .tdx-dropdown--dark:focus-visible { - background-color: var(--col-300) !important; -} - -.tdx-searchbar__textbox:not(.tdx-searchbar__textbox--dark) { - background-color: var(--bg-0) !important; - color: var(--txt-1) !important; -} - -.tdx-searchbar__textbox:hover:not(:focus), .tdx-searchbar:hover .tdx-searchbar__textbox:not(:focus) { - background-color: var(--col-200) !important; -} - -.tdx-searchbar__textbox:focus, .tdx-searchbar__textbox:active, .tdx-searchbar__textbox:focus-within { - border-color: var(--col-400) !important; -} - -.tdx-searchbar__textbox::placeholder { - color: var(--col-400) !important; -} - -.tdx-searchbar__textbox--dark:hover:not(:focus)::placeholder, .tdx-searchbar:hover .tdx-searchbar__textbox--dark:not(:focus)::placeholder, -.tdx-searchbar__textbox:hover:not(:focus)::placeholder, .tdx-searchbar:hover .tdx-searchbar__textbox:not(:focus)::placeholder { - color: var(--col-400) !important; -} - -input[type=checkbox], input[type=radio] { - accent-color: var(--col-400) !important; -} - -.tdx-checkbox { - background-color: var(--bg-0) !important; - border-color: var(--border-0) !important; -} - -.tdx-checkbox:checked { - background-color: var(--col-400) !important; -} - -.tdx-checkbox:checked:disabled { - background-color: var(--col-200) !important; -} - -.control-label, label { - color: var(--txt-2) !important; -} - -.form-control { - background-color: var(--bg-0); - color: var(--txt-2); - border-color: var(--border-0); -} - -.form-control:hover { - border-color: var(--border-0); -} - -.form-control:focus { - border-color: var(--col-400); -} - -.talu_holder .luac_default { - color: var(--col-500); -} - -.talu_holder .bit-input input { - background-color: var(--bg-0); -} - -.talu_holder .bit-box { - background-color: var(--col-100); - color: var(--col-600); -} - -.talu_holder .bit-box:hover, .talu_holder .bit-box:active { - background-color: var(--col-300); - color: var(--col-500); -} - -.talu_holder .bit-box a.closebutton { - color: var(--col-600); -} - -.lu_tdac-auto ul { - background: var(--bg-0) !important; - box-shadow: 0 1px 3px var(--shadow-1),0 2px 10px var(--shadow-2) !important; -} - -.lu_tdac-auto ul li { - color: var(--txt-1) !important; -} - -.lu_tdac-auto ul .auto-focus { - background-color: var(--col-300); - color: var(--col-500); -} - -.lu_tdac-auto ul .auto-focus div.talu_subcaption { - color: var(--col-400); -} - -div.WhiteOut { - background-color: var(--bg-0) !important; -} - -[role=status]:has(div>div>.tdx-loading-animation) { - background-color: var(--bg-0) !important; -} - -.ms-drop .ms-search input::placeholder { - color: var(--txt-3); -} - -.ms-choice { - background-color: var(--bg-0); - color: var(--txt-3); -} - -.ms-drop { - background-color: var(--bg-0) !important; - border-color: var(--border-0); -} - -button.ms-choice { - background-color: var(--bg-0) !important; - border-color: var(--border-0) !important; -} - -button.ms-choice:hover { - border-color: var(--border-0) !important; -} - -button.ms-choice:focus { - border-color: var(--col-400) !important; -} - -.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control { - background-color: var(--bg-1); -} - -.tdx-lookup-group div.select2-container.form-control a.select2-choices, .input-group div.select2-container.form-control a.select2-choice { - border-color: var(--border-0) !important; -} - -.tdx-lookup-group.input-group { - background-color: var(--bg-0) !important; -} - -.input-group:not(:has(.input-group-section)):not(.input-group--no-border) { - border-color: var(--border-0); -} - -.input-group:focus, .input-group:active, .input-group:focus-within { - border-color: var(--col-400) !important; -} - -div.input-group .input-group-btn .btn-file:last-child { - color: var(--txt-3); -} - -.tdx-lookup-group { - background-color: var(--bg-0); - border-color: var(--border-0); -} - -.tdx-lookup-group:hover { - border-color: var(--border-0); -} - -.tdx-lookup-group .k-input:hover, .tdx-lookup-group .k-input:focus, .tdx-lookup-group .k-input:focus-within, .tdx-lookup-group.input-group:hover, .tdx-lookup-group.input-group:focus, .tdx-lookup-group.input-group:focus-within, .tdx-lookup-group select:hover, .tdx-lookup-group select:focus, .tdx-lookup-group select:focus-within, .tdx-lookup-group input:hover, .tdx-lookup-group input:focus, .tdx-lookup-group input:focus-within, .tdx-lookup-group input.form-control:hover, .tdx-lookup-group input.form-control:focus, .tdx-lookup-group input.form-control:focus-within { - border-color: var(--border-0); -} - -.tdx-lookup-group .k-input, .tdx-lookup-group.input-group, .tdx-lookup-group select, .tdx-lookup-group input, .tdx-lookup-group input.form-control { - border-color: var(--border-0); -} - -.tdx-lookup-group .k-svg-icon.k-svg-i-caret-alt-down::after { - color: var(--txt-1); -} - -.tdx-lookup-group:focus, .tdx-lookup-group:active, .tdx-lookup-group:focus-within { - border-color: var(--col-400); -} - -.tdx-lookup-group .k-input .k-input-inner::selection, .tdx-lookup-group.input-group .k-input-inner::selection, .tdx-lookup-group select .k-input-inner::selection, .tdx-lookup-group input .k-input-inner::selection, .tdx-lookup-group input.form-control .k-input-inner::selection { - background-color: var(--bg-2); -} - -.tdx-lookup-group>.select2-container-multi .select2-choices:not(div.attributeValue .select2-container-multi .select2-choices) { - border-color: var(--border-0) !important; -} - -.tdx-searchbar__textbox--border { - border-color: var(--border-0) !important; -} - -.tdx-lookup-group__input { - border-color: var(--border-0) !important; -} - -.tdx-input-group__textbox, -.tdx-input-group__textarea { - color: var(--txt-1) !important; - background-color: var(--bg-0) !important; - border-color: var(--border-0) !important; -} - -.k-input { - background-color: var(--bg-0) !important; -} - -.k-input-solid { - background-color: var(--bg-0); -} - -.k-list { - background-color: var(--bg-0); - color: var(--txt-1); -} - -.k-list-container.k-popup { - background-color: var(--bg-0); -} - -.k-list-content .k-list-item:hover, .k-list-content .k-list-item:focus, .k-list-content .k-list-item.k-focus { - background-color: var(--col-300); - color: var(--txt-1); -} - -.k-list-content .k-list-item { - color: var(--txt-1); - background-color: var(--bg-0); -} - -.k-popup { - color: var(--txt-1); -} - -.k-popup:has(.k-list) { - box-shadow: 0 1px 3px var(--shadow-1),0 2px 10px var(--shadow-2); -} - -.tdx-lookup-group .k-input, .tdx-lookup-group.input-group, .tdx-lookup-group select, .tdx-lookup-group input, .tdx-lookup-group input.form-control { - color: var(--txt-1); -} - -.tdx-lookup-group .k-input .k-button-solid-base, .tdx-lookup-group.input-group .k-button-solid-base, .tdx-lookup-group select .k-button-solid-base, .tdx-lookup-group input .k-button-solid-base, .tdx-lookup-group input.form-control .k-button-solid-base { - background-color: var(--bg-0); -} - -.k-input-md .k-input-inner::placeholder, -.form-control::placeholder { - color: var(--txt-3) !important; -} - -.select2-container .select2-choice, .select2-container .select2-choices, .select2-container .select2-choices .select2-search-field input { - background: var(--bg-0) !important; -} - -div.select2-container.form-control .select2-choice.select2-default { - border-color: var(--border-0); -} - -.select2-container .select2-choice>.select2-chosen { - color: var(--txt-1) !important; -} - -.select2-container .select2-choice.select2-default>.select2-chosen { - color: var(--txt-3) !important; -} - -.tdx-lookup-group>.select2-container-multi .select2-choices:not(div.attributeValue .select2-container-multi .select2-choices) .select2-search-field input.select2-default { - color: var(--txt-3) !important; -} - -.select2-results .select2-no-results, .select2-results .select2-selection-limit { - background: var(--bg-1) !important; -} - -.select2-results .select2-no-results, .select2-results .select2-searching, .select2-results .select2-selection-limit { - color: var(--txt-1) !important; -} - -.select2-drop { - background: var(--bg-0); - color: var(--txt-1); -} - -.select2-drop { - color: var(--txt-1) !important; - background-color: var(--bg-0); -} - -.select2-drop .select2-search input { - background-color: var(--bg-0); - border-color: var(--border-0); -} - -.select2-search input { - color: var(--txt-1); -} - -div.select2-drop.select2-drop-active, div.select2-drop.select2-drop-above.select2-drop-active { - box-shadow: 0 1px 3px var(--shadow-1),0 2px 10px var(--shadow-2); - background-color: var(--bg-0); -} - -.select2-drop .select2-results .select2-highlighted { - color: var(--txt-1) !important; - background-color: var(--col-300); -} - -.select2-results div.select2-result-label { - color: var(--txt-1); -} - -.select2-container:focus-within, .select2-container:focus-within a { - border-color: var(--col-400) !important; -} - -.form-group:has(select:not([multiple]):not([size])):hover::after { - color: var(--col-400) !important; -} - -div.select2-container.form-control .select2-choice, div.js-tagformfield .select2-container-multi .select2-choices, div.js-tags-inlineedit .select2-container-multi .select2-choices, div.attributeValue .select2-container-multi .select2-choices, div.select2-listbox .select2-container-multi .select2-choices, div.select2-container.form-control.select2-container-multi .select2-choices { - border-color: var(--border-0); -} - -div.select2-container.form-control .select2-choice:hover, div.js-tagformfield .select2-container-multi .select2-choices:hover, div.js-tags-inlineedit .select2-container-multi .select2-choices:hover, div.attributeValue .select2-container-multi .select2-choices:hover, div.select2-listbox .select2-container-multi .select2-choices:hover, div.select2-container.form-control.select2-container-multi .select2-choices:hover { - border-color: var(--border-0); -} - -div.select2-container-multi .select2-choices .select2-search-choice { - background-color: var(--col-100); - color: var(--col-600); -} - -div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close { - color: var(--col-600) !important; -} - -div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:hover, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:focus-visible, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:active, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:active:hover, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:focus:active, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:focus:hover { - color: var(--col-400) !important; -} - -div.select2-container-multi .select2-choices .select2-search-choice:hover, div.select2-container-multi .select2-choices .select2-search-choice:active { - background-color: var(--col-300); - color: var(--col-500); -} - -select.form-control:hover:not(:focus), -select.form-control { - border-color: var(--border-0); -} - -.k-chip-solid-base { - background-color: var(--col-100) !important; - color: var(--col-600) !important; -} - -.k-chip-action { - color: var(--col-600) !important; -} - -.k-chip-action:hover, .k-chip-action:focus-visible, .k-chip-action:active, .k-chip-action:active:hover, .k-chip-action:focus:active, .k-chip-action:focus:hover { - color: var(--col-400) !important; -} - -.tooltip-inner { - background-color: var(--bg-0); - color: var(--txt-1); - box-shadow: 0 .5px 1px 1px var(--shadow-1),0 2px 4px var(--shadow-2),0 4px 6px var(--shadow-2); -} - -div#ui-datepicker-div .ui-datepicker-title select, div#ui-datepicker-div .ui-timepicker-div.ui-timepicker-oneLine select, div.ui-datepicker .ui-datepicker-title select, div.ui-datepicker .ui-timepicker-div.ui-timepicker-oneLine select { - color: var(--txt-1); - border-color: var(--bg-0); - background-color: var(--bg-0); -} - -div#ui-datepicker-div .ui-datepicker-title select:hover, div#ui-datepicker-div .ui-timepicker-div.ui-timepicker-oneLine select:hover, div.ui-datepicker .ui-datepicker-title select:hover, div.ui-datepicker .ui-timepicker-div.ui-timepicker-oneLine select:hover { - border-color: var(--border-0); -} - -div#ui-datepicker-div .ui-state-default, div#ui-datepicker-div .ui-state-default:hover, div.ui-datepicker .ui-state-default, div.ui-datepicker .ui-state-default:hover { - border-color: var(--bg-0) !important; -} - -div#ui-datepicker-div .ui-datepicker-header, div.ui-datepicker .ui-datepicker-header { - background: var(--col-100) !important; -} - -div#ui-datepicker-div th, div#ui-datepicker-div td, div.ui-datepicker th, div.ui-datepicker td { - color: var(--txt-1); -} - -div#ui-datepicker-div .ui-state-highlight, div#ui-datepicker-div .ui-widget-content .ui-state-highlight, div#ui-datepicker-div .ui-widget-header .ui-state-highlight, div.ui-datepicker .ui-state-highlight, div.ui-datepicker .ui-widget-content .ui-state-highlight, div.ui-datepicker .ui-widget-header .ui-state-highlight { - background: var(--col-100) !important; - color: var(--col-400) !important; -} - -button:has(>.ui-icon-circle-triangle-e), span:has(>.ui-icon-circle-triangle-e), a:has(>.ui-icon-circle-triangle-e), button:has(>.fa-chevron-circle-right), span:has(>.fa-chevron-circle-right), a:has(>.fa-chevron-circle-right), -button:has(>.ui-icon-circle-triangle-w), span:has(>.ui-icon-circle-triangle-w), a:has(>.ui-icon-circle-triangle-w), button:has(>.fa-chevron-circle-left), span:has(>.fa-chevron-circle-left), a:has(>.fa-chevron-circle-left) { - color: var(--col-400); -} - -/* Links */ - -.tdx-dashboard__widget-container a:not(.btn):not(.k-icon) { - color: var(--col-400) !important; -} - -.tdx-dashboard__widget-container a:not(.btn):not(.k-icon):hover, .tdx-dashboard__widget-container a:not(.btn):not(.k-icon):focus-visible { - color: var(--col-500) !important; -} - -a { - color: var(--col-400); - background-color: initial !important; -} - -a:hover, a:focus-visible, -.tdworkmgmt td a.visited-link:hover, .tdworkmgmt td a.visited-link:focus-visible { - color: var(--col-500) !important; -} - -a:visited, -.tdworkmgmt td a.visited-link, -.tdworkmgmt td a:visited, .tdworkmgmt.table .hilite a:visited { - color: var(--col-400); -} - -.tdworkmgmt.table-contents div.row > div > a { - color: var(--col-400); -} - -.tdworkmgmt.table-striped > tbody > tr.tdx-grid__group-header > td, .tdworkmgmt.table-bordered > tbody > tr.tdx-grid__group-header > td { - background-color: var(--col-100); -} - -.tdx-time-panel, .tdx-time-panel__heading { - color: var(--txt-1) !important; - background-color: var(--bg-1) !important; - border: 1px solid var(--border-0) !important; -} - -.tdx-leftnav__badge { - color: var(--txt-1) !important; - background-color: var(--col-300) !important; -} - -body .tdworkmgmt.table.table--vertical-lines > tbody > tr > td:not(:last-of-type) { - border-right: 1px solid var(--border-0); -} - -.TDGroupingRow { - color: var(--txt-1); -} - -a.disabledLink { - color: var(--txt-1) !important; -} - -.k-grid a.tdx-link { - color: var(--col-400) !important; -} - -.tdx-link:visited { - color: var(--col-400) !important; -} - -.tdx-btn--link { - color: var(--col-400) !important; -} - -/* Buttons */ -.tdx-btn--secondary { - background-color: var(--col-200) !important; - color: var(--col-400) !important; - border: none !important; -} - -.tdx-btn--secondary > a { - color: var(--col-400) !important; -} - -.tdx-btn--secondary:hover, .tdx-btn--secondary:hover:focus, .tdx-btn--secondary:focus-visible { - background-color: var(--col-300) !important; - color: var(--col-600) !important; -} - -.tdx-action-menu-dropdown__popout { - background-color: var(--bg-0) !important; - box-shadow: 0 1px 3px var(--shadow-1),0 2px 10px var(--shadow-2) !important; -} - -.tdx-action-menu-dropdown-popout__menu-item:not(.tdx-dropdown-popout__header) { - background-color: var(--bg-0) !important; - color: var(--txt-1) !important; -} - -.tdx-action-menu-dropdown-popout__menu-item:hover, .tdx-action-menu-dropdown-popout__menu-item:focus { - background-color: var(--col-300) !important; -} - -.tdx-action-menu__item--primary { - color: var(--txt-5) !important; - background: var(--col-600) !important; - border-color: var(--col-600) !important; -} - -.tdx-action-menu__item--primary:hover, .tdx-action-menu__item--primary:hover:focus, .tdx-action-menu__item--primary:focus-visible { - color: var(--txt-5) !important; - background: var(--col-400) !important; - border-color: var(--col-400) !important; -} - -.tdx-action-menu__item:not(.tdx-action-menu__item--primary) { - color: var(--txt-1) !important; - background: var(--bg-0) !important; -} - -.tdx-action-menu__item:not(.tdx-action-menu__item--primary):hover, .tdx-action-menu__item.tdx-action-menu__item:not(.tdx-action-menu__item--primary):hover:focus, .tdx-action-menu__item.tdx-action-menu__item:not(.tdx-action-menu__item--primary):focus-visible { - background: var(--col-200) !important; - color: var(--txt-2) !important; -} - -.tdx-primary-button-override { - background-color: var(--col-600) !important; - color: var(--txt-5) !important; - border-color: var(--col-600) !important; -} - -.tdx-primary-button-override:hover, .tdx-primary-button-override:hover:focus, .tdx-primary-button-override:focus-visible { - background: var(--col-400) !important; - border-color: var(--col-400) !important; - color: var(--txt-5) !important; -} - -.tdx-primary-button-override.active, .tdx-primary-button-override.active:hover, .tdx-primary-button-override.active:focus, .tdx-primary-button-override:active, .tdx-primary-button-override:active:hover, .tdx-primary-button-override:active:focus, -.tdx-primary-button-override:focus:not(:focus-visible,.active,:active,:hover) { - background-color: var(--col-600) !important; - color: var(--txt-5) !important; - border-color: var(--col-600) !important; -} - -span.input-group-btn .btn-default { - color: var(--txt-3); -} - -span.input-group-btn .btn-default:hover, span.input-group-btn .btn-default:focus-visible, span.input-group-btn .btn-default:active, span.input-group-btn .btn-default:active:hover, span.input-group-btn .btn-default:focus:active, span.input-group-btn .btn-default:focus:hover { - color: var(--txt-2); -} - -div.input-group .input-group-btn .btn-file:last-child:hover, div.input-group .input-group-btn .btn-file:last-child:hover:focus, div.input-group .input-group-btn .btn-file:last-child:focus-visible { - background-color: var(--col-100); - color: var(--txt-2); -} - -.btn.active, .btn.active:hover, .btn.active:focus, .btn:active, .btn:active:hover, .btn:active:focus { - background: var(--col-300); - color: var(--txt-5); -} - -.btn-default { - color: var(--txt-1); -} - -.btn-default:hover, .btn-default:hover:focus, .btn-default:focus-visible { - background: var(--col-200); - color: var(--txt-1); -} - -.tdx-btn--tertiary { - color: var(--txt-1); -} - -.tdx-btn--tertiary:hover { - background: var(--col-200); - color: var(--txt-2); -} - -.tdx-btn--primary { - background-color: var(--col-600) !important; - color: var(--txt-5) !important; - border-color: var(--col-600) !important; -} - -.tdx-btn--primary:hover, .tdx-btn--primary:hover:focus, .tdx-btn--primary:focus-visible { - background: var(--col-400) !important; - border-color: var(--col-400) !important; - color: var(--txt-5) !important; -} - -.feed-button-group .btn-primary:hover, .feed-button-group .btn-primary:hover:focus, .feed-button-group .btn-primary:focus-visible { - background: var(--col-200); -} - -.feed-button-group .btn-primary.active, .feed-button-group .btn-primary.active:hover, .feed-button-group .btn-primary.active:focus, .feed-button-group .btn-primary:active, .feed-button-group .btn-primary:active:hover, .feed-button-group .btn-primary:active:focus { - background: var(--col-300); -} - -#btnSave.btn-primary, #btnClientSave.btn-primary, #btnRunReport.btn-primary, #btnApply.btn-primary, #btnAddSelected.btn-primary, #btnSubmit.btn-primary { - color: var(--txt-5) !important; - background-color: var(--col-500) !important; - border-color: var(--col-500) !important; -} - -#btnSave.btn-primary:hover, #btnSave.btn-primary:hover:focus, #btnSave.btn-primary:focus-visible, #btnClientSave.btn-primary:hover, #btnClientSave.btn-primary:hover:focus, #btnClientSave.btn-primary:focus-visible, #btnRunReport.btn-primary:hover, #btnRunReport.btn-primary:hover:focus, #btnRunReport.btn-primary:focus-visible, #btnApply.btn-primary:hover, #btnApply.btn-primary:hover:focus, #btnApply.btn-primary:focus-visible, #btnAddSelected.btn-primary:hover, #btnAddSelected.btn-primary:hover:focus, #btnAddSelected.btn-primary:focus-visible, #btnSubmit.btn-primary:hover, #btnSubmit.btn-primary:hover:focus, #btnSubmit.btn-primary:focus-visible { - background: var(--col-400) !important; - border-color: var(--col-400) !important; - color: var(--txt-5) !important; -} - -#btnSave.btn-primary.active, #btnSave.btn-primary.active:hover, #btnSave.btn-primary.active:focus, #btnSave.btn-primary:active, #btnSave.btn-primary:active:hover, #btnSave.btn-primary:active:focus, #btnClientSave.btn-primary.active, #btnClientSave.btn-primary.active:hover, #btnClientSave.btn-primary.active:focus, #btnClientSave.btn-primary:active, #btnClientSave.btn-primary:active:hover, #btnClientSave.btn-primary:active:focus, #btnRunReport.btn-primary.active, #btnRunReport.btn-primary.active:hover, #btnRunReport.btn-primary.active:focus, #btnRunReport.btn-primary:active, #btnRunReport.btn-primary:active:hover, #btnRunReport.btn-primary:active:focus, #btnApply.btn-primary.active, #btnApply.btn-primary.active:hover, #btnApply.btn-primary.active:focus, #btnApply.btn-primary:active, #btnApply.btn-primary:active:hover, #btnApply.btn-primary:active:focus, #btnAddSelected.btn-primary.active, #btnAddSelected.btn-primary.active:hover, #btnAddSelected.btn-primary.active:focus, #btnAddSelected.btn-primary:active, #btnAddSelected.btn-primary:active:hover, #btnAddSelected.btn-primary:active:focus, #btnSubmit.btn-primary.active, #btnSubmit.btn-primary.active:hover, #btnSubmit.btn-primary.active:focus, #btnSubmit.btn-primary:active, #btnSubmit.btn-primary:active:hover, #btnSubmit.btn-primary:active:focus { - background: var(--col-600) !important; - border-color: var(--col-600) !important; - color: var(--txt-5) !important; -} - -#btnSave.btn-primary:focus:not(:focus-visible,.active,:active,:hover), #btnClientSave.btn-primary:focus:not(:focus-visible,.active,:active,:hover), #btnRunReport.btn-primary:focus:not(:focus-visible,.active,:active,:hover), #btnApply.btn-primary:focus:not(:focus-visible,.active,:active,:hover), #btnAddSelected.btn-primary:focus:not(:focus-visible,.active,:active,:hover), #btnSubmit.btn-primary:focus:not(:focus-visible,.active,:active,:hover) { - background: var(--col-400) !important; - border-color: var(--col-400) !important; - color: var(--txt-5) !important; -} - -.btn-tertiary, .btn-info, .ButtonCellTopPadding .ButtonCellTop .btn-primary { - color: var(--txt-1); - background-color: var(--col-100); -} - -.btn-tertiary:hover, .btn-tertiary:hover:focus, .btn-tertiary:focus-visible, .btn-info:hover, .btn-info:hover:focus, .btn-info:focus-visible, .ButtonCellTopPadding .ButtonCellTop .btn-primary:hover, .ButtonCellTopPadding .ButtonCellTop .btn-primary:hover:focus, .ButtonCellTopPadding .ButtonCellTop .btn-primary:focus-visible { - background-color: var(--col-200); - color: var(--txt-1); -} - -.modal-footer .btn-default { - background-color: var(--col-200) !important; - color: var(--col-400) !important; - border: none !important; -} - -.modal-footer .btn-default:hover, .modal-footer .btn-default:hover:focus, .modal-footer .btn-default:focus-visible { - background-color: var(--col-300) !important; - color: var(--col-600) !important; -} - -/* .btn.btn-primary:not(.btn-sm) { - color: var(--txt-1); - background-color: var(--bg-5); - border-color: var(--bg-5); -} */ - -.TabButtonCell .btn-primary, .TabButtonCell .btn-info, .tab-row .btn-primary, #divViewButtons, .TabButtonCell .btn-primary:active, .tab-row .btn-primary:active { - color: var(--txt-2); -} - -.TabButtonCell .btn-primary:hover, .TabButtonCell .btn-primary:hover:focus, .TabButtonCell .btn-primary:focus-visible, .TabButtonCell .btn-info:hover, .TabButtonCell .btn-info:hover:focus, .TabButtonCell .btn-info:focus-visible, .tab-row .btn-primary:hover, .tab-row .btn-primary:hover:focus, .tab-row .btn-primary:focus-visible, #divViewButtons:hover, #divViewButtons:hover:focus, #divViewButtons:focus-visible, .TabButtonCell .btn-primary:active:hover, .TabButtonCell .btn-primary:active:hover:focus, .TabButtonCell .btn-primary:active:focus-visible, .tab-row .btn-primary:active:hover, .tab-row .btn-primary:active:hover:focus, .tab-row .btn-primary:active:focus-visible { - background: var(--col-200); - color: var(--txt-2); -} - -.TabButtonCell .btn-danger, .tab-row .btn-danger { - background: var(--bg-5); - color: var(--txt-2); -} - -.TabButtonCell .btn-danger:hover, .TabButtonCell .btn-danger:hover:focus, .TabButtonCell .btn-danger:focus-visible, .tab-row .btn-danger:hover, .tab-row .btn-danger:hover:focus, .tab-row .btn-danger:focus-visible { - background: var(--col-0); - color: var(--txt-2); -} - -.ButtonCellTop { - background: var(--bg-0); -} - -.feed-button-group .btn-primary { - color: var(--txt-2) !important; -} - -.btn-secondary { - background-color: var(--col-200); - color: var(--col-400); - border-color: var(--col-200); -} - -.btn-secondary:hover, .btn-secondary:hover:focus, .btn-secondary:focus-visible { - background-color: var(--col-300) !important; - color: var(--col-500) !important; - border-color: var(--col-300) !important; -} - -.btn-danger { - background-color: var(--col-200); - color: var(--col-400); - border-color: var(--col-200); -} - -.btn-danger:hover, .btn-danger:hover:focus, .btn-danger:focus-visible { - background-color: var(--col-300); - color: var(--col-500); - border-color: var(--col-300); -} - -.tdx-button-bar .btn-primary { - color: var(--txt-1); - background-color: var(--col-100); - border-color: var(--col-100); -} - -.tdx-button-bar .btn-primary:hover, .tdx-button-bar .btn-primary:hover:focus, .tdx-button-bar .btn-primary:focus-visible { - background-color: var(--col-300); - background: var(--col-300); - color: var(--txt-2); - border-color: var(--col-300); -} - -.tdx-button-bar .btn-primary:visited { - color: var(--txt-1); -} - -.tdx-button-bar .btn-danger { - color: var(--col-400); -} - -.tdx-button-bar .btn-danger:hover, .tdx-button-bar .btn-danger:hover:focus, .tdx-button-bar .btn-danger:focus-visible { - background-color: var(--col-300); - color: var(--col-500); - border-color: var(--col-300); -} - -.tdx-tile-list__item-container, -.tdx-tile-list__item-container:visited { - background-color: var(--col-100) !important; - color: var(--col-400) !important; -} - -.tdx-tile-list__item-container:hover, .tdx-tile-list__item-container:focus { - background-color: var(--col-400) !important; - color: var(--col-100) !important; -} - -a.btn.btn-primary { - background-color: var(--col-600) !important; - color: var(--txt-5) !important; - border-color: var(--col-600) !important; -} - -a.btn.btn-primary:hover { - background-color: var(--col-400) !important; - color: var(--txt-5) !important; - border-color: var(--col-400) !important; -} - -.btn-primary { - background-color: var(--col-600); - color: var(--txt-5); - border-color: var(--col-600); -} - -.btn-primary:hover, .btn-primary:hover:focus, .btn-primary:focus-visible { - background: var(--col-400); - color: var(--txt-5); - border-color: var(--col-400); -} - -td > a.btn.btn-primary { - background-color: var(--col-400) !important; - color: var(--txt-5) !important; - border-color: var(--col-400); -} - -td > a.btn.btn-primary:hover { - background-color: var(--col-500) !important; - color: var(--txt-5) !important; - border-color: var(--col-500); -} - -.btn-default.active, .btn-default.active:hover, .btn-default.active:focus, .btn-default:active, .btn-default:active:hover, .btn-default:active:focus { - background: var(--col-100) !important; - color: var(--txt-1) !important; - border-color: var(--col-100) !important; -} - -a.btn.btn-link.tdx-primary-button-override { - color: var(--txt-5) !important; -} - -.btn-link, .btn.btn-link, .sidebar-btn.btn-link { - color: var(--col-400) !important; -} - -.btn-link:hover, .btn.btn-link:hover, .sidebar-btn.btn-link:hover { - color: var(--col-400) !important; -} - -.btn-link[role=button]:hover, .btn.btn-link[role=button]:hover, .sidebar-btn.btn-link[role=button]:hover, -a.btn.btn-link.tdx-tertiary-button-override:hover { - background-color: var(--col-200) !important; -} - -.tdx-calendar .cal-views { - border-color: var(--col-400) !important; -} - -.tdx-calendar .cal-view { - color: var(--txt-2) !important; -} - -.tdx-calendar .cal-view.light-blue-bg { - background-color: var(--col-400) !important; - color: var(--txt-2) !important; -} - -.tdx-calendar .cal-view:not(.cal-view.light-blue-bg):hover, .tdx-calendar .cal-view:hover:focus, .tdx-calendar .cal-view:focus-visible { - background-color: var(--col-200) !important; -} - -.tdx-calendar #btnDatePicker { - background-color: var(--bg-0) !important; - color: var(--col-400) !important; -} - -.tdx-calendar #btnDatePicker:hover, .tdx-calendar #btnDatePicker:focus-visible, .tdx-calendar #btnDatePicker:active, .tdx-calendar #btnDatePicker:active:hover, .tdx-calendar #btnDatePicker:focus:active, .tdx-calendar #btnDatePicker:focus:hover { - color: var(--col-600) !important; -} - -button:has(.ui-icon-circle-triangle-w), span:has(.ui-icon-circle-triangle-w), -button:has(.ui-icon-circle-triangle-e), span:has(.ui-icon-circle-triangle-e) { - color: var(--col-400) !important; -} - -button:has(.ui-icon-circle-triangle-e):hover, button:has(.ui-icon-circle-triangle-e):focus-visible, button:has(.ui-icon-circle-triangle-e):active, button:has(.ui-icon-circle-triangle-e):active:hover, button:has(.ui-icon-circle-triangle-e):focus:active, button:has(.ui-icon-circle-triangle-e):focus:hover, span:has(.ui-icon-circle-triangle-e):hover, span:has(.ui-icon-circle-triangle-e):focus-visible, span:has(.ui-icon-circle-triangle-e):active, span:has(.ui-icon-circle-triangle-e):active:hover, span:has(.ui-icon-circle-triangle-e):focus:active, span:has(.ui-icon-circle-triangle-e):focus:hover, -button:has(.ui-icon-circle-triangle-w):hover, button:has(.ui-icon-circle-triangle-w):focus-visible, button:has(.ui-icon-circle-triangle-w):active, button:has(.ui-icon-circle-triangle-w):active:hover, button:has(.ui-icon-circle-triangle-w):focus:active, button:has(.ui-icon-circle-triangle-w):focus:hover, span:has(.ui-icon-circle-triangle-w):hover, span:has(.ui-icon-circle-triangle-w):focus-visible, span:has(.ui-icon-circle-triangle-w):active, span:has(.ui-icon-circle-triangle-w):active:hover, span:has(.ui-icon-circle-triangle-w):focus:active, span:has(.ui-icon-circle-triangle-w):focus:hover { - color: var(--col-600) !important; -} - -.ui-widget-header { - background: var(--bg-0) !important; -} - -.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default, -.ui-widget-content, .ui-widget.ui-widget-content { - background: var(--bg-0) !important; - border-color: var(--border-0) !important; -} - -.tdx-calendar .fc-day-header { - color: var(--col-400) !important; -} - -.tdx-calendar .fc-day-number.fc-other-month a:first-child { - color: var(--col-200) !important; -} - -.tdx-calendar .fc-day-number a { - color: var(--col-600) !important; -} - -.tdx-calendar .ui-state-highlight a, .tdx-calendar .ui-widget-content .ui-state-highlight a, .tdx-calendar .ui-widget-header .ui-state-highlight a { - color: var(--col-400) !important; -} - -.tdx-calendar .ui-state-highlight { - background: var(--col-100) !important; -} - -.td-day-off { - background: var(--bg-2) !important; -} - -.label-primary, .tdworkmgmt.table .hilite .label.label-primary { - background-color: var(--col-300); -} - -.label-info, .label-success, .label-default { - color: var(--col-200); - background-color: var(--col-500); -} - -.tdTilemd, -.tdTilesm { - background-color: var(--col-300); - border-color: var(--col-300); -} - -.tdTilemd.secondary, -.tdTilesm.secondary { - background-color: var(--col-300); - border-color: var(--col-300); -} - -.tdTilesm.tertiary { - background-color: var(--col-300); - border-color: var(--col-300); -} - -.block-actions .btn.btn-link { - color: var(--txt-1); -} - -.block-actions .btn.btn-link:hover, .block-actions .btn.btn-link:hover:focus, .block-actions .btn.btn-link:focus-visible { - background: var(--bg-5); - color: var(--txt-1); -} - -.btn-link:hover, .btn-link:focus-visible, .btn.btn-link:hover, .btn.btn-link:focus-visible, .sidebar-btn.btn-link:hover, .sidebar-btn.btn-link:focus-visible { - color: var(--col-500); -} - -ul.dropdown-menu .btn.btn-link[data-v-775a00fa] { - color: var(--txt-1) !important; -} - -ul.dropdown-menu .btn.btn.btn-link[data-v-775a00fa]:hover { - background-color: var(--col-300) !important; - color: var(--txt-1) !important; -} - -.copyButton { - color: var(--txt-2) !important; - background-color: var(--bg-0) !important; - border-color: var(--border-0) !important; -} - -.copyButton:hover { - background-color: var(--bg-2) !important; -} - -.js-open-monitor .btn { - color: var(--col-1); -} - -.js-open-monitor .btn:hover { - color: var(--col-2); -} - -/* .btn:hover, .btn:hover:focus, .btn:focus-visible { - background: var(--bg-1); -} */ - -.btn:focus:not(:focus-visible,.active,:active,:hover) { - color: var(--txt-5); - background-color: var(--col-400); -} - -.btn:hover, .btn:hover:focus, .btn:focus-visible { - color: var(--txt-5); - background-color: var(--col-600); -} - -.popover { - background-color: var(--bg-0); - box-shadow: 0 5px 10px var(--shadow-1); - border-color: var(--border-0); -} - -.popover.right > .arrow { - border-right-color: var(--border-0); -} - -.popover.right > .arrow::after { - border-right-color: var(--bg-0); -} - -/* Tables */ - -table.table { - color: var(--txt-1) !important; - border-color: var(--border-0); -} - -.tdx-table__th { - background-color: var(--bg-0) !important; - color: var(--col-600) !important; -} - -.tdx-table__td { - color: var(--txt-2) !important; -} - -.tdx-table-fade-right { - background: linear-gradient(to right,transparent,var(--bg-0)) !important; -} - -thead, tbody, tfoot, tr, td, th { - border-color: var(--border-0); -} - -.tdx-pagination-bar { - background-color: var(--bg-0) !important; -} - -.tdx-pagination-bar__item-count { - color: var(--txt-2) !important; -} - -.tdx-dashboard__widget-container { - box-shadow: 0 .5px 1px 1px var(--shadow-1),0 2px 4px var(--shadow-2),0 4px 6px var(--shadow-1) !important; -} - -.tdx-widget-selector__widget-option { - box-shadow: 0 .5px 1px 1px var(--shadow-1),0 2px 4px var(--shadow-2),0 4px 6px var(--shadow-2) !important; -} - -.tdx-widget-selector__widget-name { - color: var(--txt-1) !important; -} - -.tdx-widget-selector__category { - color: var(--col-600) !important; -} - -.tdx-widget-selector__widget-option:hover, .tdx-widget-selector__widget-option:focus { - outline-color: var(--col-400) !important; -} - -.tdx-dashboard-row-editor { - background-color: var(--col-100) !important; - box-shadow: 0 .5px 1px 1px var(--shadow-1),0 2px 4px var(--shadow-2),0 4px 6px var(--shadow-2) !important; -} - -.tdx-dashboard-row-editor__column { - background-color: var(--bg-0) !important; -} - -.tdx-dashboard-row-editor__selected-widget { - background-color: var(--bg-0) !important; - outline-color: var(--border-0) !important; -} - -.tdx-dashboard-row-editor__selected-widget-category-text { - color: var(--col-600) !important; -} - -.tdx-dashboard-editor__add-widget { - color: var(--txt-3) !important; -} - -.tdx-dashboard-editor__add-widget:hover, .tdx-dashboard-editor__add-widget:focus-visible { - box-shadow: 0 .5px 1px 1px var(--shadow-1),0 2px 4px var(--shadow-2),0 4px 6px var(--shadow-2) !important; -} - -.tdx-control-bar { - background-color: var(--bg-0) !important; -} - -.tdx-control-bar__title { - color: var(--txt-1) !important; -} - -.tdx-confirmation-dialog { - background-color: var(--bg-0); - color: var(--col-600); -} - -.tdx-confirmation-dialog__text-area { - color: var(--col-600); -} - -.k-grid, .k-pager, .k-table { - background-color: var(--bg-0) !important; - color: var(--txt-1) !important; -} - -.k-table-tbody>.k-table-row:not(.k-table-group-row):first-child>.k-table-td, -.k-table-tbody>.k-table-row:not(.k-table-group-row)>.k-table-td { - border-color: var(--border-0) !important; -} - -.k-grid-header, .k-grid-pager { - background-color: var(--bg-0) !important; - color: var(--txt-0) !important; -} - -.k-grid .k-table-row.k-table-alt-row { - background-color: var(--bg-0); -} - -.k-grid .k-table-row { - background-color: var(--bg-1); /* can change to 0 for non-striped rows */ -} - -td.k-table-td { - /* background-color: var(--bg-1); */ -} - -.k-grid .k-table-tbody > .k-alt.k-table-row:not(.k-detail-row) { - background-color: var(--bg-0); -} - -.k-table-th { - background-color: var(--bg-0) !important; -} - -.k-grid .k-grid-header .k-table-th { - color: var(--txt-4) !important; -} - -.k-grid .k-grid-header .k-table-th, .k-table-tbody .k-group-cell { - background-color: unset; -} - -.k-table-th, .k-table-td, -td.k-table-td { - background-color: unset; -} - -.k-grid .k-table-tbody>.k-table-row:not(.k-detail-row):not([style]):hover, .k-grid .k-table-tbody>.k-table-row:not(.k-detail-row).k-hover { - background-color: var(--bg-1) !important; -} - -.k-grid .k-table-tbody>.k-table-alt-row:not(.k-detail-row):not([style]):hover, .k-grid .k-table-tbody>.k-table-alt-row:not(.k-detail-row).k-hover:not([style]) { - background-color: var(--bg-0) !important; -} - -button.k-pager-nav.k-button.k-button-flat.k-button-flat-base.k-icon-button.k-button-md { - background-color: var(--bg-0) !important; - color: var(--col-400) !important; -} - -.k-pager-md .k-pager-numbers-wrap .k-button.k-pager-nav.k-disabled, -button.k-pager-nav.k-button.k-button-flat.k-button-flat-base.k-icon-button.k-pager-last.k-button-md { - background-color: var(--bg-0) !important; - color: var(--col-400) !important; -} - -button.k-pager-nav.k-button.k-button-flat.k-button-flat-base.k-icon-button.k-pager-last.k-button-md.k-disabled, -button.k-pager-nav.k-button.k-button-flat.k-button-flat-base.k-icon-button.k-button-md.k-disabled { - color: var(--bg-2) !important; -} - -.k-pager-md .k-pager-numbers-wrap .k-button.k-pager-nav:hover { - color: var(--col-600) !important; -} - -#lookupIframeWrapper { - background-color: var(--bg-0); -} - -.k-window, .k-window:focus { - background: var(--bg-0); - box-shadow: 0 8px 16px var(--shadow-1),0 24px 38px var(--shadow-2); -} - -.k-window-titlebar { - background-color: var(--bg-0) !important; -} - -.k-window-content { - background-color: var(--bg-0) !important; -} - -.k-window-title { - color: var(--col-500) !important; -} - -.k-button .k-svg-i-window { - color: var(--col-500); -} - -.k-button .k-svg-i-x { - color: var(--col-500); -} - -button.k-button.k-button-md.k-button-flat.k-button-flat-primary.k-selected { - background-color: var(--col-100) !important; -} - -button.k-selected { - background-color: var(--col-1) !important; - color: var(--col-400) !important; -} - -.k-pager-md .k-pager-numbers-wrap .k-button { - color: var(--col-400) !important; -} - -button.k-button.k-button-md.k-button-flat.k-button-flat-primary:hover { - color: var(--col-500); - background-color: var(--col-100)!important; -} - -.k-pager-md .k-pager-numbers-wrap .k-button.k-pager-nav { - background-color: var(--bg-0) !important; -} - -.tdx-pagination-bar { - background-color: var(--bg-0); -} - -.tdx-pagination-bar__active-page-item { - color: var(--col-400); - background-color: var(--col-200); -} - -.tdx-pagination-bar__page-item:hover:not(.tdx-pagination-bar__active-page-item,.tdx-pagination-bar__separator) { - color: var(--col-500); - background-color: var(--col-100); -} - -.tdx-pagination-bar .fa, .tdx-pagination-bar a { - color: var(--col-400); -} - -.tdx-pager-button .fa-chevron-right, .tdx-pager-button .fa-chevron-left { - -webkit-text-stroke-color: var(--bg-0); -} - -.hilite, .hilite .btn-link, .hilite a, .hilite td, .table>tbody>tr.hilite label, .table>tbody>tr.hilite.active, .table>tbody>tr.hilite.danger, .table>tbody>tr.hilite.info, .table>tbody>tr.hilite.success, .table>tbody>tr.hilite.warning, .table>tbody>tr.hilite>td.active, .table>tbody>tr.hilite>td.danger, .table>tbody>tr.hilite>td.info, .table>tbody>tr.hilite>td.success, .table>tbody>tr.hilite>td.warning { - color: var(--txt-5); - background-color: var(--bg-5) !important; -} - -.tdworkmgmt.table-header > div { - background-color: var(--bg-1); - color: var(--col-400); -} - -/* Side Panels */ - -.tdx-right-side-panel { - background-color: var(--bg-0) !important; - box-shadow: 0 8px 16px var(--shadow-1),0 24px 38px var(--shadow-2) !important; -} - -.white-bg, .white-hover-bg:hover { - background-color: var(--bg-0) !important; -} - -.tdx-right-side-panel__drag-border { - background: linear-gradient(var(--col-400),var(--col-400)) no-repeat left/1px 10% !important; -} - -.tdx-right-side-panel__drag-border:hover { - border-color: var(--col-400) !important; -} - -.tdx-right-side-panel__header-title { - color: var(--txt-2) !important; -} - -.tdx-right-side-panel__drag-border:focus-visible, .tdx-right-side-panel__drag-border.active { - border-color: var(--col-500) !important; -} - - -.tdx-right-side-panel__home-button { - color: var(--col-400) !important; - border-color: var(--col-500) !important; -} - -.tdx-right-side-panel__home-button:hover { - color: var(--col-200) !important; - border-color: var(--col-300) !important; -} - -.tdx-leftnav-drag-handle { - background: linear-gradient(var(--col-400),var(--col-400)) no-repeat right/1px 10% !important; -} - -.tdx-leftnav-drag-handle:hover { - background-color: var(--col-400) !important; -} - -.tdx-leftnav-drag-handle:focus-visible, .tdx-leftnav-drag-handle.active { - background-color: var(--col-500) !important;; -} - -/* Tickets */ - -.control-label, label.control-label, span.control-label { - color: var(--txt-3) !important; -} - -.control-label~* { - color: var(--txt-1) !important; -} - -.black { - color: var(--txt-1) !important; -} - -nav#divTabHeader, -.TabButtonCell, .tab-row, -.tdx-button-bar { - background-color: var(--col-100) !important; -} - -.panel-default>.panel-heading { - background-color: var(--bg-0) !important; - border-color: var(--border-0) !important; -} - -.panel-body, .panel-footer { - background-color: var(--bg-0) !important; - border-color: var(--border-0) !important; -} - -.panel { - background-color: var(--bg-0) !important; -} - -.panel-body, .panel-footer { - color: var(--txt-3) !important; -} - -.h2, h2, h2.h3, .panel-title { - color: var(--txt-1) !important; - border-color: var(--border-0) !important; -} - -.alert-info, div.alert-info { - color: var(--txt-1) !important; - background-color: var(--col-blue) !important; -} - -.alert-warning, div.alert-warning { - color: var(--txt-1) !important; - background-color: var(--col-yellow) !important; -} - -.nav-tabs>li.active>a, .nav-tabs>li.active>button, .nav-pills>li.active>a, .nav-pills>li.active>button { - color: var(--col-600) !important; - background-color: var(--bg-0) !important; - border-color: var(--border-0); - box-shadow: 0 .5px 1px 1px var(--shadow-1),0 2px 4px var(--shadow-2),0 4px 6px var(--shadow-2) !important; -} - -.nav-tabs>li>a, .nav-tabs>li>a:hover, .nav-tabs>li>button, .nav-tabs>li>button:hover, .nav-pills>li>a, .nav-pills>li>a:hover { - color: var(--txt-3); -} - -.nav-tabs>li>a:hover, .nav-tabs>li>a:hover:hover { - color: var(--txt-2); - border-color: var(--border-0); -} - -.nav-tabs>li>a:hover { - color: var(--col-600); -} - -a.btn.btn-link.tdx-tertiary-button-override { - background-color: var(--col-100) !important; - color: var(--txt-1) !important; -} - -.gray, .gray-hover:hover { - color: var(--txt-3) !important; -} - -.dropdown-menu { - background-color: var(--bg-0) !important; - color: var(--txt-1) !important; - box-shadow: 0 1px 3px var(--shadow-1),0 2px 10px var(--shadow-2); -} - -.dropdown-menu li { - color: var(--txt-1); - background-color: var(--bg-0); -} - -.dropdown-menu>span>li>a:hover, .dropdown-menu>span>li>a:focus, .dropdown-menu>span>li:hover, .dropdown-menu>span>li:focus, .dropdown-menu>li>a:hover, .dropdown-menu>li>span>a:hover, .dropdown-menu>li>a:focus, .dropdown-menu>li>span>a:focus, -.dropdown-menu li:hover { - color: var(--txt-1); - background-color: var(--col-300); -} - -.TabButtonCell .btn-primary.active, .TabButtonCell .btn-primary.active:hover, .TabButtonCell .btn-primary.active:focus, .TabButtonCell .btn-primary:active, .TabButtonCell .btn-primary:active:hover, .TabButtonCell .btn-primary:active:focus, .TabButtonCell .btn-info.active, .TabButtonCell .btn-info.active:hover, .TabButtonCell .btn-info.active:focus, .TabButtonCell .btn-info:active, .TabButtonCell .btn-info:active:hover, .TabButtonCell .btn-info:active:focus, .tab-row .btn-primary.active, .tab-row .btn-primary.active:hover, .tab-row .btn-primary.active:focus, .tab-row .btn-primary:active, .tab-row .btn-primary:active:hover, .tab-row .btn-primary:active:focus, #divViewButtons.active, #divViewButtons.active:hover, #divViewButtons.active:focus, #divViewButtons:active, #divViewButtons:active:hover, #divViewButtons:active:focus, .TabButtonCell .btn-primary:active.active, .TabButtonCell .btn-primary:active.active:hover, .TabButtonCell .btn-primary:active.active:focus, .TabButtonCell .btn-primary:active:active, .TabButtonCell .btn-primary:active:active:hover, .TabButtonCell .btn-primary:active:active:focus, .tab-row .btn-primary:active.active, .tab-row .btn-primary:active.active:hover, .tab-row .btn-primary:active.active:focus, .tab-row .btn-primary:active:active, .tab-row .btn-primary:active:active:hover, .tab-row .btn-primary:active:active:focus { - background: var(--col-600); - color: var(--txt-1); -} - -div.btn-group.open>.dropdown-toggle.btn-primary, .open>.dropdown-toggle.btn-primary, .open>.dropdown-toggle.btn-primary:hover, .open>.dropdown-toggle.btn-primary:focus { - background: var(--col-100); - color: var(--txt-1); -} - -.TabButtonCell .btn-primary:focus:not(:focus-visible,.active,:active,:hover), .TabButtonCell .btn-info:focus:not(:focus-visible,.active,:active,:hover), .tab-row .btn-primary:focus:not(:focus-visible,.active,:active,:hover), #divViewButtons:focus:not(:focus-visible,.active,:active,:hover), .TabButtonCell .btn-primary:active:focus:not(:focus-visible,.active,:active,:hover), .tab-row .btn-primary:active:focus:not(:focus-visible,.active,:active,:hover) { - background: var(--col-100); - color: var(--txt-1); -} - -.btn-primary--tertiary { - background-color: var(--bg-0) !important; - color: var(--txt-1) !important; - border-color: var(--bg-0) !important; -} - -.btn-primary--tertiary:hover, .btn-primary--tertiary:hover:focus, .btn-primary--tertiary:focus-visible { - background-color: var(--col-200) !important; - color: var(--col-400) !important; -} - -.time-cell-approved { - background-color: var(--col-green); -} - -.time-cell-rejected { - background-color: var(--col-red); -} - -[class^=fa-].red, [class^=fa-].red:hover { - color: var(--col-red) !important; -} - -[class^=fa-].green, [class^=fa-].green:hover { - color: var(--col-green) !important; -} - -.tdx-error-text, span.tdx-error-text, -.tdx-error-text:hover, span.tdx-error-text:hover { - /* color: var(--col-red) !important; */ - color: var(--col-600) !important; -} - -.red-bg, -.status.red, .status-danger, .pri-hi { - background-color: var(--col-red) !important; - color: var(--txt-1) !important; -} - -.status.blue, .status.gray, .status-primary, .status-default { - background-color: var(--col-blue); - color: var(--txt-1) !important; -} - -.status-warning { - background-color: var(--col-yellow); - color: var(--txt-1) !important; -} - -.status.green, .status-success, -.js-open-monitor .btn .label-success { - background-color: var(--col-green); - color: var(--txt-1) !important; -} - -div.feed-body>div.feed-child-box { - background-color: var(--col-100); - color: var(--txt-1); -} - -.modal-content { - background-color: var(--bg-0); -} - -.modal-dialog { - box-shadow: 0 8px 16px var(--shadow-1),0 24px 38px var(--shadow-2); -} - -.modal-title { - color: var(--txt-1); -} - -.tdx-modal { - background-color: var(--bg-0) !important; - box-shadow: 0 0 8px var(--shadow-1),0 5px 12px var(--shadow-1),0 15px 35px var(--shadow-2); -} - -.tdx-modal .modal-content { - color: var(--txt-1) !important; -} - -.tdx-modal__iframe-header, -.tdx-modal__iframe-footer { - background-color: var(--bg-0) !important; -} - -.modal-content { - background-color: var(--bg-0) !important; -} - -hr { - background-color: var(--col-300); -} - -blockquote { - border-color: var(--border-0); -} - -.code, code, pre { - background-color: var(--bg-1); - color: var(--txt-1); - border-color: var(--border-0); -} - -div.comment { - background-color: var(--col-100); -} - -.block-actions { - background-color: var(--bg-0); -} - -body .tdworkmgmt.table>thead>tr>th, body .tdworkmgmt.table>tbody>tr>th, body .tdworkmgmt.table>tfoot>tr>th, body .tdworkmgmt.table>tbody>tr.TDGridHeader>td, body .tdworkmgmt.table>thead>tr.TDGridHeader>td { - background-color: var(--bg-0); - color: var(--txt-1); -} - -body .tdworkmgmt.table>tbody>tr:not(.tdx-grid__group-header):not(.TDGridHeader)>td { - color: var(--txt-1); - border-color: var(--border-0); -} - -body .tdworkmgmt.table>tbody>tr:not(.tdx-grid__group-header):not(.TDGridHeader):last-child:not(.TDPagerRow) th, body .tdworkmgmt.table>tbody>tr:not(.tdx-grid__group-header):not(.TDGridHeader):last-child:not(.TDPagerRow) td { - border-color: var(--border-0); -} - -.tdworkmgmt td a, .tdworkmgmt.table .hilite a { - color: var(--col-400); -} - -.tdworkmgmt td a:hover, .tdworkmgmt td a:focus-visible, .tdworkmgmt.table .hilite a:hover, .tdworkmgmt.table .hilite a:focus-visible { - color: var(--col-0); -} - -.input-group-addon { - background-color: var(--bg-5); - color: var(--txt-1); -} - -.list-group-item { - background-color: var(--bg-0) !important; - border-color: var(--border-0); -} - -/* Text Editor */ -.cke_editable { - color: var(--txt-1); - background-color: var(--bg-4); -} - -html .cke_editable { - background-color: var(--bg-0) !important; - color: var(--txt-1) !important; -} - -.cke_wysiwyg_div, .cke_wysiwyg_frame { - background: var(--bg-0) !important; -} - -.cke_combo_button, .cke_toolgroup { - background: var(--bg-0) !important; -} - -.cke_button_icon { - opacity: 1 !important; - filter: invert(var(--txt-invert)) !important; -} - -.cke_combo_text { - color: var(--txt-2) !important; - background-color: var(--bg-0) !important; -} - -.cke_panel_grouptitle { - background: var(--bg-2) !important; - color: var(--txt-1); -} - -.cke_panel_listItem a:active, .cke_panel_listItem a:focus, .cke_panel_listItem a:hover { - background: var(--bg-3) !important; -} - -a.cke_button_disabled:active, a.cke_button_disabled:focus, a.cke_button_disabled:hover, a.cke_button_off:active, a.cke_button_off:focus, a.cke_button_off:hover { - background: var(--bg-3) !important; -} - -.cke_bottom, .cke_top, .cke_chrome { - background-color: var(--bg-1) !important; - color: var(--txt-2) !important; -} - -.cke_combo_button, -.cke_toolgroup, -.cke_contents { - border-color: var(--border-0) !important; -} - -div .cke_top, div .cke_bottom, div .comment-options, div .cke_chrome { - background-color: var(--col-100) !important; -} - -.cke_panel_listItem a { - border: none; -} - -.cke_panel, -.cke_panel_grouptitle { - border-color: var(--border-0) !important; -} - -a.cke_colorbox, -a.cke_colorauto, a.cke_colormore { - border-color: var(--border-0) !important; -} - -.cke_colorblock, .cke_colorblock a { - color: var(--txt-1); -} - -a:active.cke_colorauto, a:active.cke_colormore, a:focus.cke_colorauto, a:focus.cke_colormore, a:hover.cke_colorauto, a:hover.cke_colormore { - background: var(--bg-3) !important; -} - -a:active.cke_colorbox, a:focus.cke_colorbox, a:hover.cke_colorbox { - background: var(--bg-3) !important; -} - -.cke_dialog_contents, .cke_dialog_body { - color: var(--txt-1) !important; - background: var(--bg-2) !important; -} - -.cke_dialog_footer, .cke_dialog_title { - background: var(--bg-1) !important; -} - -.cke_reset_all, .cke_reset_all * { - color: var(--txt-2) !important; -} - -.cke_dialog_page_contents a.cke_dialog_ui_button, a.cke_dialog_ui_button_cancel { - background: var(--bg-3) !important; -} - -input.cke_dialog_ui_input_password, input.cke_dialog_ui_input_text, textarea.cke_dialog_ui_input_textarea { - background: var(--bg-3) !important; -} - -a.cke_dialog_tab_selected { - background: var(--bg-2) !important; -} - -a.cke_dialog_tab { - background: var(--bg-3) !important; -} - -select.cke_dialog_ui_input_select { - background-color: var(--bg-4) !important; -} - -.cke_button_on { - background: var(--bg-2) !important; -} - -.dropdown-menu>li>a, .dropdown-menu>span>li>a, .dropdown-menu>li>span>a { - color: var(--txt-1) !important; -} - -/* Icons */ -.js-help a, .js-help .fa-solid, .js-default-help a, .js-default-help .fa-solid, -.disp-group .control-label>a>span { - color: var(--col-400); -} - -.js-help a:hover, .js-help a:focus-visible, .js-help a:active, .js-help a:active:hover, .js-help a:focus:active, .js-help a:focus:hover, .js-help .fa-solid:hover, .js-help .fa-solid:focus-visible, .js-help .fa-solid:active, .js-help .fa-solid:active:hover, .js-help .fa-solid:focus:active, .js-help .fa-solid:focus:hover, .js-default-help a:hover, .js-default-help a:focus-visible, .js-default-help a:active, .js-default-help a:active:hover, .js-default-help a:focus:active, .js-default-help a:focus:hover, .js-default-help .fa-solid:hover, .js-default-help .fa-solid:focus-visible, .js-default-help .fa-solid:active, .js-default-help .fa-solid:active:hover, .js-default-help .fa-solid:focus:active, .js-default-help .fa-solid:focus:hover, -.disp-group .control-label>a>span:hover, .disp-group .control-label>a>span:focus-visible, .disp-group .control-label>a>span:active, .disp-group .control-label>a>span:active:hover, .disp-group .control-label>a>span:focus:active, .disp-group .control-label>a>span:focus:hover { - color: var(--col-500); -} - -.tdx-lookup-button-group a, .tdx-lookup-button-group button, .input-btn-group a, .input-btn-group button, -div.select2-container.select2-allowclear .select2-choice abbr { - color: var(--col-400); -} - -.tdx-lookup-button-group a:hover, .tdx-lookup-button-group a:focus-visible, .tdx-lookup-button-group a:active, .tdx-lookup-button-group a:active:hover, .tdx-lookup-button-group a:focus:active, .tdx-lookup-button-group a:focus:hover, .tdx-lookup-button-group button:hover, .tdx-lookup-button-group button:focus-visible, .tdx-lookup-button-group button:active, .tdx-lookup-button-group button:active:hover, .tdx-lookup-button-group button:focus:active, .tdx-lookup-button-group button:focus:hover, .input-btn-group a:hover, .input-btn-group a:focus-visible, .input-btn-group a:active, .input-btn-group a:active:hover, .input-btn-group a:focus:active, .input-btn-group a:focus:hover, .input-btn-group button:hover, .input-btn-group button:focus-visible, .input-btn-group button:active, .input-btn-group button:active:hover, .input-btn-group button:focus:active, .input-btn-group button:focus:hover { - color: var(--col-500); -} - -.tdx-icon__encircled--active { - background-color: var(--col-200) !important; -} - -.tdx-icon__encircled--active:hover { - background-color: var(--col-300) !important; -} - -.tdx-icon__encircled:not(.tdx-icon__encircled--active) { - background-color: var(--bg-0) !important; -} - -.tdx-icon__encircled:not(.tdx-icon__encircled--active):hover { - background-color: var(--col-200) !important; -} - -.tdx-user-icon, .tdx-multiuser-icon, -div.profile-image.red-bg, div.profile-image.green-bg, div.profile-image.red-bg, div.profile-image.blue-bg, div.profile-image.yellow-bg, div.profile-image.gray-bg, div.profile-image.initials.red-bg, div.profile-image.initials.green-bg, div.profile-image.initials.red-bg, div.profile-image.initials.blue-bg, div.profile-image.initials.yellow-bg, div.profile-image.initials.gray-bg { - background-color: var(--col-400) !important; - color: var(--col-100) !important; -} - -.tdx-widget-indicator-icon { - color: var(--col-600) !important; -} - -.tdx-dirty-indicator { - color: var(--col-400) !important; -} - -.tdx-hover-darken { - color: var(--col-400); -} - -.tdx-hover-darken:hover { - color: var(--col-300); -} - -.form-group>a, .form-group>.checkbox>a, .disp-group>a, .form-group>.control-label>a, .checkbox>label>a { - color: var(--col-400) !important; -} - -.form-group>a:hover, .form-group>.checkbox>a:hover, .disp-group>a:hover, .form-group>.control-label>a:hover, .checkbox>label>a:hover { - color: var(--col-500) !important; -} - -.k-table-th[data-role=columnsorter] .k-link:not(:has(>.k-sort-icon)):after { - color: var(--col-400) !important; -} - -.k-table-th[data-role=columnsorter] .k-link:not(:has(>.k-sort-icon)):hover:after { - color: var(--col-500) !important; -} - -.tdx-calendar .fa-plus { - color: var(--col-300) !important; -} - -.icon-button { - color: var(--col-400) !important; -} - -.tdx-view-ticket-summary #divSummaryHeading a { - color: var(--col-400); -} - -.tdx-view-ticket-summary #divSummaryHeading a #spnCopySummaryIcon { - color: var(--col-400); -} - -/* Icons + Filters */ -.tdx-dropdown__menu-icon, -.tdx-dropdown--headline:after, -.tdx-dropdown:after, -.tdx-icon--search, -.k-icon -{ - filter: brightness(0) invert(var(--filter-invert)) sepia(var(--filter-sepia)) saturate(var(--filter-saturate)) hue-rotate(var(--filter-hue-rotate)) brightness(var(--filter-brightness)) contrast(var(--filter-contrast)); -} - -#divDescription .wrap-text [style*="color"]:not([style*="color"] [style*="color"]), .feed-item-text [style*="color"]:not([style*="color"] [style*="color"]), #divCustomLoginPrompt [style*="color"]:not([style*="color"] [style*="color"]) { - filter: none !important; -} - -/* Same but with !important */ -.tdx-icon__encircled--active .tdx-icon, -.tdx-icon--filter-purple, -.tdx-navigation-tabs__tab--active .tdx-close-x, -.tdx-icon--new-browser, -.tdx-close-x, button.tdx-close-x, -.tdx-action-menu__item--primary:after, -.tdx-action-menu-dropdown:after, -.tdx-icon.tdx-icon--hover-darken, .tdx-icon--hover-darken>.tdx-icon, -.tdx-dropdown__menu-icon, .tdx-dropdown--headline:after, .tdx-dropdown:after, .tdx-icon--search, .tdx-icon:not(.label), -div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:hover, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:focus-visible, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:active, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:active:hover, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:focus:active, div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close:focus:hover -{ - filter: brightness(0) invert(var(--filter-invert)) sepia(var(--filter-sepia)) saturate(var(--filter-saturate)) hue-rotate(var(--filter-hue-rotate)) brightness(var(--filter-brightness)) contrast(var(--filter-contrast)) !important; -} - -/* Hover + !important */ -.tdx-icon__encircled:hover .tdx-icon, -.tdx-close-x:hover, button.tdx-close-x:hover, -.tdx-icon.tdx-icon--hover-darken:hover, .tdx-icon.tdx-icon--hover-darken:focus, .tdx-icon--hover-darken>.tdx-icon:hover, .tdx-icon--hover-darken>.tdx-icon:focus, -.tdx-leftnav__item-expander:hover .tdx-icon, .tdx-leftnav__item-expander:focus .tdx-icon, -.tdx-action-menu-dropdown--no-arrow:hover .tdx-icon, .tdx-action-menu-dropdown--no-arrow.active .tdx-icon, -div.select2-container-multi .select2-choices .select2-search-choice>.select2-search-choice-close -{ - filter: brightness(0) invert(var(--filter-invert)) sepia(var(--filter-sepia)) saturate(var(--filter-saturate)) hue-rotate(var(--filter-hue-rotate)) brightness(var(--filter-brightness)) contrast(var(--filter-contrast)) brightness(125%) !important; -} - - ` - setInterval(() => { - document.querySelectorAll("table:not([data-parsed])").forEach(table => { - table.dataset.parsed = "true"; - parseTable(table.parentElement); - }); - }, 5000); - //const customStyles = GM_getResourceText("IMPORTED_CSS"); - GM_addStyle(customStyles); - setCssFilters() - parseOtherElements() - -})(); From e5b5dd3bb7bebb376192ff85bb385cf206264418 Mon Sep 17 00:00:00 2001 From: Diego Dereck Sosa-Escamilla Date: Wed, 9 Sep 2026 07:47:12 -0400 Subject: [PATCH 3/3] Rename tdx-enhanced.documented.js to tdx-enhanced.js --- tdx-enhanced.documented.js => tdx-enhanced.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tdx-enhanced.documented.js => tdx-enhanced.js (100%) diff --git a/tdx-enhanced.documented.js b/tdx-enhanced.js similarity index 100% rename from tdx-enhanced.documented.js rename to tdx-enhanced.js