/*
 * Tindahang Tapat OnPrem — "tt" design language
 *
 * Flat surfaces + frosted overlays, patterned on the SIMS design principles but in this app's own colours
 * (brand green, the logo's lime and yellow). Loaded last in the layout — after Bootstrap, the Neptune
 * template (plugins/main.min.css) and custom.css — so equal-specificity rules here win.
 *
 * Principles
 * - Flat, no gradients. Every surface, tint and fill is one solid colour: white cards with a hairline border,
 *   an inset top highlight and a soft shadow offset downward; accents as flat rgba tints over the surface;
 *   hover and press take a fill a shade deeper (color-mix() with black).
 * - Colour to a whisper. Neutrals dominate; the accent shows up only in eyebrows, icon tiles, key dots, active
 *   states and primary actions. Cards stay white, never tinted. Status uses semantic colours.
 * - One accent variable. Components read --tt-accent / --tt-accent-rgb / --tt-accent-ink (always with a
 *   fallback — never declared as a default inside the primitive, or it would out-order an equal-specificity
 *   .tt-accent-* modifier on the same element). The .tt-accent-* modifiers set them.
 * - Tokens, not hexes. Components use var(--tt-*) for colour and rgba(var(--tt-*-rgb), α) for tints.
 * - Glass is painted once. backdrop-filter only goes on overlays that nothing scrolls under (menus, the modal
 *   backdrop). The fixed top bar and floating buttons use a solid frost; the canvas is a flat body colour.
 * - Motion is optional. Every animation and hover lift lives inside prefers-reduced-motion: no-preference.
 *
 * Two ways the language is applied
 * 1. Global chrome — Bootstrap/Neptune classes re-skinned in place. Cards, tables, menus and list groups are
 *    scoped to .app-content (page content only, so the sidebar and top bar keep their own look); modals are
 *    scoped as .modal .x so they're caught wherever they mount; buttons anchor on `body .btn` so they apply
 *    everywhere, including sign-in.
 * 2. Shared tt-* primitives — one implementation each: .tt-eyebrow, .tt-tile, .tt-pill, .tt-kpi, .tt-stat,
 *    .tt-state, .tt-surface, .tt-person, .tt-metric, .tt-heading, .tt-dot, .tt-switch, .tt-setting,
 *    .tt-page-header, .tt-card-head, .tt-card-actions, .tt-subnav, .tt-code, .tt-screen, plus the .tt-accent-*
 *    modifiers. The existing page components (dash-*, picklist-queue-*) are wired onto these primitives below
 *    instead of carrying their own copies — extend the primitive rather than adding another per-feature variant.
 *    The signed-out screens (sign-in, setup) are built from .tt-auth, which uses the same primitives on the
 *    sidebar's dark surface + a white card.
 *
 * Type comes from one ramp (--tt-fs-*): pick the role, not a size.
 *
 * Note: this app's root font size is 14px (template), so rem values are 14px-based.
 */

/* ==========================================================================
   Foundation tokens
   ========================================================================== */

:root {
  /* Brand — the app's green plus the two logo colours.
     Every accent sits at the brand green's perceived lightness (OKLCH L ≈ 0.60, #349832) so the palette reads
     as one family: the base colour is also the fill behind white text, and each -ink is the same hue taken
     down only as far as it needs to stay readable as text (≥ 4.5:1 on its own 14% tint). */
  --tt-primary: #349832;
  --tt-primary-rgb: 52, 152, 50;
  --tt-primary-ink: #0c7d11;             /* text on white / on primary tints */
  --tt-primary-ink-rgb: 12, 125, 17;
  --tt-primary-deep: #006d06;            /* hover text, text on the heavier 18% tints */
  --tt-primary-strong-rgb: var(--tt-primary-rgb);  /* fills that carry white text */
  --tt-lime: #76bc37;                    /* logo green — the secondary accent */
  --tt-lime-rgb: 118, 188, 55;
  --tt-lime-ink: #447a00;
  --tt-sun-rgb: 255, 205, 63;            /* logo yellow — illustration warmth only */

  /* Semantic */
  --tt-danger: #e4312e;
  --tt-danger-rgb: 228, 49, 46;
  --tt-danger-ink: #d0121a;
  --tt-danger-strong-rgb: var(--tt-danger-rgb);
  --tt-warning: #f59e0b;                 /* already brighter than the brand green — kept, fills carry dark text */
  --tt-warning-rgb: 245, 158, 11;
  --tt-warning-ink: #9c6200;
  --tt-on-warning: #1f1300;
  --tt-info: #338ca9;
  --tt-info-rgb: 51, 140, 169;
  --tt-info-ink: #0f7490;
  --tt-info-strong-rgb: var(--tt-info-rgb);
  --tt-blue: #3575fe;
  --tt-blue-rgb: 53, 117, 254;
  --tt-blue-ink: #2360e8;
  --tt-blue-strong-rgb: var(--tt-blue-rgb);
  --tt-violet: #8c52ff;
  --tt-violet-rgb: 140, 82, 255;
  --tt-violet-ink: #7f3ff1;
  --tt-dark: #1e293b;
  --tt-dark-rgb: 30, 41, 59;
  --tt-secondary: #5b6b80;
  --tt-secondary-rgb: 91, 107, 128;
  --tt-secondary-ink: #475569;

  /* Text */
  --tt-ink: #0f172a;
  --tt-text: #1e293b;
  --tt-text-2: #334155;
  --tt-muted: #5b6b80;
  --tt-placeholder: #7b8698;
  --tt-subtle: #94a3b8;

  /* Type — Poppins is self-hosted up to 700, so 700 stands in for the SIMS 800 */
  --tt-font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  --tt-font-display: "Poppins", var(--tt-font-sans);
  --tt-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  --tt-heading-weight: 700;

  /* Type ramp — px because the root is 14px. Each role has one size:
     overline 11 · caption 12.5 · label 13 · body 14 · lede 15 · heading 16 · title 22 · display 30 */
  --tt-fs-overline: 11px;                /* eyebrow chips, uppercase */
  --tt-fs-caption: 12.5px;               /* helper text, step details, meta */
  --tt-fs-label: 13px;                   /* form labels, alerts */
  --tt-fs-body: 14px;                    /* body copy, subtitles */
  --tt-fs-lede: 15px;                    /* intro paragraphs, inputs, large buttons */
  --tt-fs-heading: 16px;                 /* panel and card headings */
  --tt-fs-title: 22px;                   /* page titles */
  --tt-fs-display: 30px;                 /* brand statements */

  /* Radii */
  --tt-radius-card: 1.25rem;
  --tt-radius-modal: 1.35rem;
  --tt-radius-tile: 1.1rem;
  --tt-radius-btn: 0.8rem;
  --tt-radius-nav: 0.7rem;
  --tt-radius-pill: 999px;

  /* Surfaces */
  --tt-hairline: rgba(var(--tt-dark-rgb), 0.07);
  --tt-surface-border: rgba(255, 255, 255, 0.65);                /* overlays: menus, modals, toasts */
  --tt-card-border: rgba(var(--tt-dark-rgb), 0.09);              /* cards need a visible edge on the light canvas */
  --tt-surface-shadow: 0 1px 2px rgba(var(--tt-dark-rgb), 0.06), 0 1.5rem 3rem -1.5rem rgba(var(--tt-dark-rgb), 0.32),
    inset 0 1px 0 rgba(255, 255, 255, 0.7);
  --tt-surface-shadow-sm: 0 0.75rem 1.75rem -1.25rem rgba(var(--tt-dark-rgb), 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.7);
  /* every surface is a single solid colour — they stay separate tokens so each role can be retuned alone */
  --tt-surface-hero: #fff;                                      /* heroes, page headers, sign-in card */
  --tt-surface-card: #fff;                                       /* cards and tiles */
  --tt-surface-plain: #fff;                                      /* modals */
  --tt-surface-frost-solid: #fff;                                /* fixed bars and floating controls */
  --tt-surface-frost: rgba(255, 255, 255, 0.88);                 /* blurred overlays: menus, toasts */
  --tt-frost-filter: blur(16px) saturate(170%);

  /* Dark surface (sidebar) */
  --tt-dark-surface: #0f2417;
  --tt-on-dark: #b0bdb5;
  --tt-on-dark-strong: #f1f5f2;
  --tt-on-dark-muted: #a1b2a8;
  --tt-on-dark-accent: #a3d98a;
  --tt-on-dark-warning: #f6c453;         /* logo-yellow warmth for "needs attention" on the dark surface */
  --tt-dark-raised: #16311f;             /* tooltips and flyouts that pop off the dark surface */

  /* Interaction */
  --tt-ring: 0 0 0 3px rgba(var(--tt-primary-rgb), 0.25);
  --tt-ring-danger: 0 0 0 3px rgba(var(--tt-danger-rgb), 0.22);
  --tt-row-hover: rgba(var(--tt-primary-rgb), 0.05);

  /* Layout & motion */
  --tt-header-h: 64px;
  --tt-gutter: 28px;
  --tt-dur: 180ms;
  --tt-ease: cubic-bezier(0.2, 0.7, 0.2, 1);

  /* Bootstrap hooks (body bg stays white on purpose: tables, inputs and cards read --bs-body-bg) */
  --bs-body-font-family: var(--tt-font-sans);
  --bs-body-color: var(--tt-text);
  --bs-emphasis-color: var(--tt-ink);
  --bs-secondary-color: var(--tt-muted);
  --bs-border-color: var(--tt-hairline);
  --bs-border-radius: var(--tt-radius-nav);
  --bs-link-color: var(--tt-primary-ink);
  --bs-link-color-rgb: var(--tt-primary-ink-rgb);
  --bs-link-hover-color: var(--tt-primary-deep);
  --bs-link-hover-color-rgb: 0, 109, 6;
  --bs-focus-ring-color: rgba(var(--tt-primary-rgb), 0.25);
}

/* ==========================================================================
   Canvas — one flat near-neutral grey behind the white cards
   ========================================================================== */

body {
  background-color: #edf0ee;
}

/* The template makes html and body height: 100% and puts overflow-x: hidden on html. Together they broke
   dialog scroll locking: Bootstrap's body { overflow: hidden } clipped the page to one screen and threw the
   reader back to the top, and SweetAlert2 (which works around that) left the scrollbar in place while padding
   for it, so the page slid 17px on Windows. Standard root styles fix both; the sideways clip moves onto the
   app wrappers, where clip (unlike hidden) doesn't make them scroll containers. */
html,
body {
  height: auto;
}

html {
  overflow-x: visible;
}

.app,
.tt-external {
  overflow-x: clip;
}

/* ==========================================================================
   Base & type
   ========================================================================== */

body {
  font-family: var(--tt-font-sans);
  color: var(--tt-text);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* the template forces Poppins onto every a/span; let them inherit instead */
a,
span,
text {
  font-family: inherit;
}

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
  font-family: var(--tt-font-display);
  font-weight: var(--tt-heading-weight);
  letter-spacing: -0.01em;
  color: var(--tt-ink);
}

p {
  line-height: 1.6;
}

a {
  color: var(--tt-primary-ink);
  text-decoration: none;
  transition: color var(--tt-dur) var(--tt-ease);
}

a:hover {
  color: var(--tt-primary-deep);
}

small,
.small {
  font-size: 0.8125rem;
}

strong,
b {
  font-weight: 600;
}

code {
  padding: 0.15em 0.5em;
  border-radius: 0.45rem;
  background: rgba(var(--tt-dark-rgb), 0.06);
  color: var(--tt-text-2);
  font-family: var(--tt-font-mono);
  font-size: 0.8125rem;
}

hr {
  border-color: var(--tt-hairline);
  opacity: 1;
}

::selection {
  background: rgba(var(--tt-primary-rgb), 0.22);
}

/* native checkboxes, radios and ranges take the brand colour too */
:root {
  accent-color: rgb(var(--tt-primary-strong-rgb));
}

/* keyboard focus — the template strips outlines with !important, so restore them for keyboard users only */
a:focus-visible,
button:focus-visible,
.btn:focus-visible,
summary:focus-visible,
[role="button"]:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible {
  outline: 2px solid var(--tt-primary) !important;
  outline-offset: 2px;
}

/* figures line up in columns */
td,
th,
.badge,
.dt-info {
  font-variant-numeric: tabular-nums;
}

/* colour utilities — the template's values fail contrast on white */
.text-muted { color: var(--tt-muted) !important; }
.text-success { color: var(--tt-primary-ink) !important; }
.text-danger { color: var(--tt-danger-ink) !important; }
.text-warning { color: var(--tt-warning-ink) !important; }
.text-info { color: var(--tt-info-ink) !important; }
.text-primary { color: var(--tt-blue-ink) !important; }
.text-secondary { color: var(--tt-muted) !important; }
.text-dark { color: var(--tt-ink) !important; }
.text-gray { color: var(--tt-text-2) !important; }

.bg-success { background-color: rgb(var(--tt-primary-strong-rgb)) !important; }
.bg-danger { background-color: var(--tt-danger) !important; }
.bg-warning { background-color: var(--tt-warning) !important; }
.bg-info { background-color: var(--tt-info) !important; }
.bg-primary { background-color: var(--tt-blue) !important; }
.bg-dark { background-color: var(--tt-dark) !important; }
.bg-light { background-color: rgba(var(--tt-dark-rgb), 0.035) !important; }
.bg-secondary { background-color: rgba(var(--tt-dark-rgb), 0.06) !important; }

/* ==========================================================================
   Accent modifiers — set the accent for an element and its children
   (the page components' existing modifier classes are mapped onto the same values)
   ========================================================================== */

.tt-accent-primary,
.dash-kpi-card--green,
.dash-leaderboard-card__header-icon--green,
.picklist-queue-summary-item--picked,
.picklist-queue-lane--picked {
  --tt-accent: var(--tt-primary);
  --tt-accent-rgb: var(--tt-primary-rgb);
  --tt-accent-ink: var(--tt-primary-ink);
}

.tt-accent-lime {
  --tt-accent: var(--tt-lime);
  --tt-accent-rgb: var(--tt-lime-rgb);
  --tt-accent-ink: var(--tt-lime-ink);
}

.tt-accent-danger,
.picklist-queue-summary-item--waiting,
.picklist-queue-lane--waiting {
  --tt-accent: var(--tt-danger);
  --tt-accent-rgb: var(--tt-danger-rgb);
  --tt-accent-ink: var(--tt-danger-ink);
}

.tt-accent-warning,
.dash-kpi-card--orange,
.dash-mini-card__icon--yellow,
.picklist-queue-summary-item--assigned,
.picklist-queue-lane--assigned {
  --tt-accent: var(--tt-warning);
  --tt-accent-rgb: var(--tt-warning-rgb);
  --tt-accent-ink: var(--tt-warning-ink);
}

.tt-accent-info,
.dash-mini-card__icon--teal {
  --tt-accent: var(--tt-info);
  --tt-accent-rgb: var(--tt-info-rgb);
  --tt-accent-ink: var(--tt-info-ink);
}

.tt-accent-blue,
.dash-kpi-card--blue,
.dash-mini-card__icon--blue {
  --tt-accent: var(--tt-blue);
  --tt-accent-rgb: var(--tt-blue-rgb);
  --tt-accent-ink: var(--tt-blue-ink);
}

.tt-accent-violet,
.dash-leaderboard-card__header-icon--purple {
  --tt-accent: var(--tt-violet);
  --tt-accent-rgb: var(--tt-violet-rgb);
  --tt-accent-ink: var(--tt-violet-ink);
}

.tt-accent-secondary,
.picklist-queue-empty {
  --tt-accent: var(--tt-secondary);
  --tt-accent-rgb: var(--tt-secondary-rgb);
  --tt-accent-ink: var(--tt-secondary-ink);
}

/* ==========================================================================
   Primitive: surface — the light card recipe (heroes, modals, sign-in panels)
   ========================================================================== */

.tt-surface,
.dash-header,
.picklist-queue-header,
.tt-auth__card {
  border: 1px solid var(--tt-card-border);
  border-radius: var(--tt-radius-card);
  background: var(--tt-surface-hero);
  box-shadow: var(--tt-surface-shadow);
}

/* ==========================================================================
   Primitive: eyebrow chip
   ========================================================================== */

.tt-eyebrow,
.dash-status,
.picklist-queue-status {
  width: fit-content;
  padding: 0.3rem 0.7rem;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  border: 0;
  border-radius: var(--tt-radius-pill);
  background: rgba(var(--tt-accent-rgb, var(--tt-primary-rgb)), 0.12);
  color: var(--tt-accent-ink, var(--tt-primary-ink));
  font-size: var(--tt-fs-overline);
  font-weight: 700;
  letter-spacing: 0.08em;
  line-height: 1.25;
  text-transform: uppercase;
}

/* on the dark brand surface the chip takes the sidebar's lime accent */
.tt-eyebrow--on-dark {
  background: rgba(var(--tt-lime-rgb), 0.16);
  color: var(--tt-on-dark-accent);
}

.tt-eyebrow .material-icons-outlined,
.dash-status .material-icons-outlined,
.picklist-queue-status .material-icons-outlined {
  font-size: 1rem;
}

/* ==========================================================================
   Primitive: icon tile
   (legacy selectors carry an extra class where custom.css set tile colours at higher specificity)
   ========================================================================== */

.tt-tile,
.dash-kpi-card .dash-kpi-card__icon,
.dash-mini-card .dash-mini-card__icon,
.dash-header-card > .material-icons-outlined,
.dash-panel-title > .material-icons-outlined,
.dash-leaderboard-card .dash-leaderboard-card__header-icon,
.picklist-queue-summary-item > .material-icons-outlined,
.picklist-queue-lane .picklist-queue-lane-title > .material-icons-outlined,
.picklist-queue-empty .material-icons-outlined {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  border-radius: var(--tt-radius-tile);
  background: rgba(var(--tt-accent-rgb, var(--tt-primary-rgb)), 0.12);
  box-shadow: inset 0 0 0 1px rgba(var(--tt-accent-rgb, var(--tt-primary-rgb)), 0.15);
  color: var(--tt-accent-ink, var(--tt-primary-ink));
}

/* small tiles read better with a tighter corner */
.picklist-queue-summary-item > .material-icons-outlined {
  border-radius: 0.8rem;
}

/* ==========================================================================
   Primitive: pill — neutral by default; --accent tints it with the inherited accent
   ========================================================================== */

.tt-pill,
.dash-badge-neutral,
.dash-leaderboard-item__rank-pill {
  width: fit-content;
  padding: 0.25rem 0.7rem;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  border: 0;
  border-radius: var(--tt-radius-pill);
  background: rgba(var(--tt-secondary-rgb), 0.14);
  color: var(--tt-secondary-ink);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.3;
}

.tt-pill--accent,
.app-header .nav-link > .fw-semibold.text-success {
  padding: 0.25rem 0.75rem;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  border: 0;
  border-radius: var(--tt-radius-pill);
  background: rgba(var(--tt-accent-rgb, var(--tt-primary-rgb)), 0.14);
  color: var(--tt-accent-ink, var(--tt-primary-ink)) !important;
  font-weight: 600;
}

.dash-badge-neutral {
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* ==========================================================================
   Primitive: KPI — stat card
   ========================================================================== */

/* A white card read top to bottom: the label with a small icon tile beside it, the figure as the hero, then one
   line of context keyed by a dot in the card's accent. The accent never fills the card itself. */
.tt-kpi,
.dash-kpi-card,
.dash-mini-card {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--tt-card-border);
  border-radius: var(--tt-radius-card);
  background: var(--tt-surface-card);
  box-shadow: var(--tt-surface-shadow);
}

/* the template hover lifts these unconditionally — lifts live in the motion section instead */
.dash-kpi-card:hover,
.dash-mini-card:hover {
  transform: none;
  box-shadow: var(--tt-surface-shadow);
}

/* custom.css draws a coloured strip across the top of each KPI card — not part of the tt language */
.dash-kpi-card::before {
  display: none;
}

.tt-kpi,
.dash-kpi-card {
  min-height: 148px;
  padding: 1.35rem 1.45rem 1.25rem;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: 0;
}

.dash-kpi-card__top {
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.dash-kpi-card .dash-kpi-card__icon {
  width: 36px;
  height: 36px;
  border-radius: 10px;
}

.dash-kpi-card .dash-kpi-card__icon .material-icons-outlined {
  font-size: 1.15rem;
}

.tt-kpi-label,
.dash-kpi-card__label {
  min-width: 0;
  color: var(--tt-text-2);
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: 0;
  line-height: 1.35;
  text-transform: none;              /* custom.css sets these labels in caps */
}

/* the context line, keyed by a dot in the card's accent */
.dash-kpi-card__sub {
  margin-top: 0.6rem;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--tt-muted);
  font-size: var(--tt-fs-caption);
  font-weight: 500;
  line-height: 1.4;
}

.dash-kpi-card__sub::before {
  content: "";
  width: 7px;
  height: 7px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--tt-accent, var(--tt-primary));
}

.tt-kpi-value,
.dash-kpi-card__value,
.dash-mini-card__value {
  font-family: var(--tt-font-display);
  font-weight: var(--tt-heading-weight);
  letter-spacing: -0.02em;
  color: var(--tt-ink);
}

.dash-kpi-card__value {
  margin-top: 0.85rem;
  font-size: 2.6rem;
  line-height: 1;
}

.dash-mini-card__label {
  color: var(--tt-muted);
}

/* ==========================================================================
   Primitive: state — empty / error placeholder
   ========================================================================== */

.tt-state,
.picklist-queue-empty {
  border: 1px dashed rgba(var(--tt-dark-rgb), 0.16);
  border-radius: var(--tt-radius-card);
  background: rgba(255, 255, 255, 0.6);
  color: var(--tt-muted);
}

.picklist-queue-empty strong {
  font-family: var(--tt-font-display);
  font-weight: 600;
  color: var(--tt-text);
}

/* illustrated: an SVG scene on a flat brand disc, then a title and a hint (scenes: libs/datatable_empty_state.js) */
.tt-state--illustrated {
  padding: 1.75rem 1.5rem 2rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  white-space: normal;
}

.tt-state__art {
  width: min(100%, 220px);
  height: auto;
  margin-bottom: 0.85rem;
  overflow: visible;
}

.tt-state__title {
  color: var(--tt-ink);
  font-family: var(--tt-font-display);
  font-size: var(--tt-fs-heading);
  font-weight: 600;
}

.tt-state__text {
  max-width: 36ch;
  margin: 0.3rem 0 0;
  color: var(--tt-muted);
  font-size: var(--tt-fs-label);
  font-weight: 400;
  line-height: 1.5;
}

/* scene shapes — translucent fills tint whatever they overlap; anything that must hide what's behind it
   sits on a .tt-art-solid copy of itself */
.tt-art-halo { fill: rgba(var(--tt-primary-rgb), 0.08); }
.tt-art-solid { fill: #fff; }
.tt-art-shadow { fill: rgba(var(--tt-dark-rgb), 0.07); }
.tt-art-paper { fill: #fff; stroke: rgba(var(--tt-dark-rgb), 0.1); stroke-width: 1.5; }
.tt-art-paper--back { fill: rgba(var(--tt-primary-rgb), 0.07); }
.tt-art-bar { fill: rgba(var(--tt-dark-rgb), 0.09); }
.tt-art-bar--accent { fill: rgba(var(--tt-primary-rgb), 0.4); }
.tt-art-dot { fill: rgba(var(--tt-lime-rgb), 0.45); }
.tt-art-box { fill: rgba(var(--tt-primary-rgb), 0.16); stroke: rgba(var(--tt-primary-rgb), 0.38); stroke-width: 1.5; stroke-linejoin: round; }
.tt-art-box-inside { fill: rgba(var(--tt-primary-ink-rgb), 0.3); }
.tt-art-flap { fill: #fff; stroke: rgba(var(--tt-primary-rgb), 0.38); stroke-width: 1.5; stroke-linejoin: round; }
.tt-art-lens { fill: rgba(var(--tt-lime-rgb), 0.14); stroke: var(--tt-primary); stroke-width: 6; }
.tt-art-handle { fill: none; stroke: var(--tt-primary-deep); stroke-width: 11; stroke-linecap: round; }
.tt-art-glare { fill: none; stroke: #fff; stroke-width: 3.5; stroke-linecap: round; }
.tt-art-mark { fill: none; stroke: var(--tt-primary-ink); stroke-width: 3.5; stroke-linecap: round; stroke-linejoin: round; }
.tt-art-mark-dot { fill: var(--tt-primary-ink); }
.tt-art-spark { fill: var(--tt-lime); }
.tt-art-spark--primary { fill: var(--tt-primary); }

/* plain (no scene): an icon tile stands in for the art */
.tt-state > .tt-tile {
  width: 52px;
  height: 52px;
  margin-bottom: 0.8rem;
  font-size: 1.5rem;
}

/* ==========================================================================
   Primitive: stat — compact summary tile for list pages (the KPI card, scaled down to sit above a table)
   ========================================================================== */

.tt-stats {
  margin-bottom: 1.25rem;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 0.85rem;
}

.tt-stat {
  min-width: 0;
  container: tt-stat / inline-size;
  padding: 0.95rem 1.1rem;
  display: flex;
  align-items: center;
  gap: 0.9rem;
  border: 1px solid var(--tt-card-border);
  border-radius: var(--tt-radius-tile);
  background: var(--tt-surface-card);
  box-shadow: var(--tt-surface-shadow-sm);
}

.tt-stat > .tt-tile {
  width: 44px;
  height: 44px;
  border-radius: 0.85rem;
  font-size: 1.35rem;
}

.tt-stat__body {
  min-width: 0;
  display: grid;
  gap: 0.2rem;
}

.tt-stat__label {
  color: var(--tt-text-2);
  font-size: var(--tt-fs-overline);
  font-weight: 700;
  letter-spacing: 0.06em;
  line-height: 1.3;
  text-transform: uppercase;
}

.tt-stat__value {
  color: var(--tt-ink);
  font-family: var(--tt-font-display);
  font-size: var(--tt-fs-title);
  font-weight: var(--tt-heading-weight);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.tt-stat__value small {
  margin-left: 0.3rem;
  color: var(--tt-muted);
  font-family: var(--tt-font-sans);
  font-size: var(--tt-fs-label);
  font-weight: 600;
  letter-spacing: 0;
}

.tt-stat__meta {
  overflow: hidden;
  color: var(--tt-muted);
  font-size: var(--tt-fs-caption);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* a narrow tile (four across on a laptop, two across on a phone) gives the icon's room to the figures, and a dot
   in the accent keys the label instead */
@container tt-stat (max-width: 250px) {
  .tt-stat > .tt-tile {
    display: none;
  }

  .tt-stat__label {
    display: flex;
    align-items: center;
    gap: 0.45rem;
  }

  .tt-stat__label::before {
    content: "";
    width: 8px;
    height: 8px;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--tt-accent, var(--tt-primary));
  }
}

/* ==========================================================================
   Primitive: person — initials avatar with a presence dot, beside a name and a status line.
   The accent (tt-accent-primary for online, tt-accent-secondary for offline) colours the avatar, dot and status.
   ========================================================================== */

.tt-person {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.tt-avatar {
  position: relative;
  width: 36px;
  height: 36px;
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(var(--tt-accent-rgb, var(--tt-secondary-rgb)), 0.14);
  box-shadow: inset 0 0 0 1px rgba(var(--tt-accent-rgb, var(--tt-secondary-rgb)), 0.18);
  color: var(--tt-accent-ink, var(--tt-secondary-ink));
  font-family: var(--tt-font-display);
  font-size: var(--tt-fs-caption);
  font-weight: 600;
  letter-spacing: 0.02em;
}

.tt-avatar__dot {
  position: absolute;
  right: -1px;
  bottom: -1px;
  width: 11px;
  height: 11px;
  border: 2px solid #fff;
  border-radius: 50%;
  background: var(--tt-accent, var(--tt-secondary));
}

.tt-person__body {
  min-width: 0;
  display: grid;
  gap: 0.1rem;
}

/* break-word (not anywhere) keeps whole words as the column's minimum width, so a narrow table hands columns to
   DataTables' responsive child row instead of breaking names mid-word */
.tt-person__name {
  color: var(--tt-ink);
  font-weight: 600;
  overflow-wrap: break-word;
}

.tt-person__status {
  color: var(--tt-accent-ink, var(--tt-muted));
  font-size: var(--tt-fs-caption);
  font-weight: 500;
}

/* ==========================================================================
   Primitive: metric — a figure in a table cell: a state icon tile beside a headline figure (a drill-down link)
   over a muted note, the same rhythm as .tt-person. The accent tints the tile and the link, so each state reads
   by colour and icon as well as by its column header.
   ========================================================================== */

.tt-metric {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 0.7rem;
}

.tt-metric > .tt-tile {
  width: 34px;
  height: 34px;
  border-radius: 0.7rem;
  font-size: 1.1rem;
}

.tt-metric__body {
  min-width: 0;
  display: grid;
  justify-items: start;
  gap: 0.25rem;
}

/* column header marker in the column's state colour (a dot, so the header's text stays the plain label that
   DataTables reuses for responsive child rows) */
.tt-legend {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
}

.tt-legend::before {
  content: "";
  width: 8px;
  height: 8px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--tt-accent, var(--tt-primary));
}

/* the secondary line, and the whole cell when there's nothing to show (muted, still AA) */
.tt-metric__note {
  color: var(--tt-muted);
  font-size: var(--tt-fs-caption);
}

/* the headline figure is the link: plain text in the accent ink (AA on white and on the row hover tint).
   inline-block, not flex, so the space between the count and its unit renders (and is read out). */
.tt-metric__link {
  display: inline-block;
  color: var(--tt-accent-ink, var(--tt-primary-ink));
  font-family: var(--tt-font-display);
  font-size: var(--tt-fs-lede);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1.3;
  text-decoration: none;
  white-space: nowrap;
}

.tt-metric__link small {
  font-family: var(--tt-font-sans);
  font-size: var(--tt-fs-label);
  font-weight: 600;
}

.tt-metric__link:hover {
  color: var(--tt-accent-ink, var(--tt-primary-ink));
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.tt-metric__link:focus-visible {
  border-radius: 0.35rem;
  outline: 0;
  box-shadow: var(--tt-ring);
}

.tt-metric__link .material-icons-outlined {
  font-size: 1.15rem;
  vertical-align: -0.22em;
}

/* ==========================================================================
   Primitive: heading — icon tile beside an eyebrow, a title and a meta line (modal and panel headers)
   ========================================================================== */

.tt-heading {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 0.9rem;
}

.tt-heading > .tt-tile {
  width: 46px;
  height: 46px;
  font-size: 1.4rem;
}

.tt-heading__text {
  min-width: 0;
  display: grid;
  justify-items: start;
  gap: 0.3rem;
}

.tt-heading__meta {
  color: var(--tt-muted);
  font-size: var(--tt-fs-caption);
  font-weight: 400;                      /* the template sets card headers to 600 */
}

/* ==========================================================================
   Primitive: dot — a status light in the inherited accent; --live pulses it (see Motion)
   ========================================================================== */

.tt-dot {
  width: 8px;
  height: 8px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--tt-accent, var(--tt-primary));
  box-shadow: 0 0 0 3px rgba(var(--tt-accent-rgb, var(--tt-primary-rgb)), 0.2);
}

/* ==========================================================================
   Primitive: switch — an on/off checkbox (role="switch"). Off is an outlined track with a grey knob, on fills
   with the brand and turns the knob white; both the outline and the fill hold 3:1 against a white card.
   The knob is a hard-stop radial-gradient — a flat dot with no fade — so its colour and size can come from tokens.
   ========================================================================== */

.tt-switch {
  --tt-switch-knob: var(--tt-placeholder);
  --tt-switch-knob-size: 54%;
  width: 42px;
  height: 24px;
  margin: 0;
  flex-shrink: 0;
  -webkit-appearance: none;
  appearance: none;
  border: 1px solid var(--tt-placeholder);
  border-radius: var(--tt-radius-pill);
  background: radial-gradient(circle closest-side, var(--tt-switch-knob) var(--tt-switch-knob-size), transparent calc(var(--tt-switch-knob-size) + 1px))
    left center / 22px 22px no-repeat #fff;
  cursor: pointer;
  vertical-align: middle;
}

.tt-switch:hover:not(:disabled):not(:checked) {
  border-color: var(--tt-muted);
  background-color: rgba(var(--tt-dark-rgb), 0.04);
}

.tt-switch:checked {
  --tt-switch-knob: #fff;
  --tt-switch-knob-size: 72%;
  border-color: rgb(var(--tt-primary-strong-rgb));
  background-color: rgb(var(--tt-primary-strong-rgb));
  background-position: right center;
}

/* the keyboard outline every control uses (a box-shadow ring would vanish in Windows contrast themes) */
.tt-switch:focus-visible {
  outline: 2px solid var(--tt-primary) !important;
  outline-offset: 2px;
}

.tt-switch:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

/* ==========================================================================
   Primitive: setting — one row of a settings list: a label and a help line on the left, the control or the
   current value on the right. A --toggle row is one big hit area: its label stretches over the row, so a
   click anywhere flips the switch while the accessible name stays the short label.
   ========================================================================== */

.tt-setting-list {
  --tt-setting-pad-x: 1.7rem;            /* matches the card body, so rows line up with the card header */
  margin: 0;
  padding: 0;
  list-style: none;
}

.tt-setting {
  position: relative;
  padding: 1rem var(--tt-setting-pad-x);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  border-top: 1px solid var(--tt-hairline);
}

.tt-setting__text {
  min-width: 0;
  display: grid;
  flex: 1 1 18rem;
  gap: 0.2rem;
}

.tt-setting__label {
  margin: 0;
  color: var(--tt-ink);
  font-size: var(--tt-fs-body);
  font-weight: 600;
  line-height: 1.4;
}

.tt-setting__help {
  max-width: 62ch;
  margin: 0;
  color: var(--tt-muted);
  font-size: var(--tt-fs-caption);
  line-height: 1.5;
}

.tt-setting__value {
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.tt-setting__code {
  padding: 0.3rem 0.6rem;
  border-radius: 0.55rem;
  background: rgba(var(--tt-dark-rgb), 0.05);
  box-shadow: inset 0 0 0 1px var(--tt-hairline);
  color: var(--tt-ink);
  font-family: var(--tt-font-mono);
  font-size: var(--tt-fs-label);
  font-weight: 600;
  word-break: break-all;
}

/* a code under the label and help (an identifier, secondary to them): sized to its text */
.tt-setting__text > .tt-setting__code {
  margin-top: 0.15rem;
  justify-self: start;
  font-size: var(--tt-fs-caption);
  font-weight: 500;
}

.tt-setting--toggle {
  cursor: pointer;
  transition: background-color var(--tt-dur) var(--tt-ease);
}

.tt-setting--toggle:hover {
  background: var(--tt-row-hover);
}

.tt-setting--toggle .tt-setting__label {
  cursor: pointer;
}

.tt-setting--toggle .tt-setting__label::after {
  content: "";
  position: absolute;
  inset: 0;
}

.tt-setting--toggle .tt-switch {
  position: relative;
  z-index: 1;
}

/* key/value chips beside a row (an account's invoice numbering) */
.tt-setting__facts {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.tt-setting__fact {
  min-width: 6.5rem;
  padding: 0.45rem 0.75rem;
  display: grid;
  gap: 0.1rem;
  border-radius: 0.75rem;
  background: rgba(var(--tt-dark-rgb), 0.035);
  box-shadow: inset 0 0 0 1px var(--tt-hairline);
}

.tt-setting__fact dt {
  color: var(--tt-muted);
  font-size: var(--tt-fs-overline);
  font-weight: 700;
  letter-spacing: 0.06em;
  line-height: 1.3;
  text-transform: uppercase;
}

.tt-setting__fact dd {
  margin: 0;
  color: var(--tt-ink);
  font-size: var(--tt-fs-label);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   Primitive: page header — the white band that opens a cardless page: an icon tile beside an eyebrow, the page
   title and a meta line, with a status pill or an action on the right. Pair with .tt-surface.
   ========================================================================== */

.tt-page-header {
  padding: 1.5rem 1.7rem;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 1.5rem;
}

.tt-page-header .tt-heading > .tt-tile {
  width: 56px;
  height: 56px;
  font-size: 1.75rem;
}

.tt-page-header__title {
  margin: 0;
  font-size: var(--tt-fs-title);
}

/* ==========================================================================
   Primitive: card actions — a card footer with a note on the left and the card's action on the right
   ========================================================================== */

.tt-card-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1rem;
  color: var(--tt-muted);
  font-size: var(--tt-fs-caption);
}

/* the save button stays on the right when a narrow footer wraps it under the note */
.tt-card-actions .btn {
  margin-left: auto;
}

/* compact input in a .tt-setting row (a number with its unit) */
.tt-setting__field {
  width: 12rem;
  flex-wrap: nowrap;
}

/* ==========================================================================
   Primitive: card head — a card header row: a .tt-heading on the left, a status pill or the card's action on
   the right. The pill or button keeps to one line; the title beside it wraps instead.
   ========================================================================== */

.tt-card-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem 1rem;
}

.tt-card-head > .tt-heading {
  flex: 1 1 16rem;
}

.tt-card-head > :is(.tt-pill, .btn) {
  margin-left: auto;                     /* stays on the right when a narrow card wraps it under the heading */
  flex-shrink: 0;
  white-space: nowrap;
}

/* ==========================================================================
   Primitive: subnav — a page's own mini sidebar: a sticky card of links beside the content, marked with
   aria-current ("true" for in-page sections, "page" for sibling pages), each with an optional count. Lay it out
   with .tt-subnav-layout > .tt-subnav + .tt-subnav-layout__main. Below 992px it becomes wrapping chips above the
   content (see Responsive).
   ========================================================================== */

.tt-subnav-layout {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  align-items: start;
  gap: 1.25rem;
}

.tt-subnav {
  position: sticky;
  top: calc(var(--tt-header-h) + 1.25rem);
  padding: 0.5rem;
  display: grid;
  gap: 2px;
  border: 1px solid var(--tt-card-border);
  border-radius: var(--tt-radius-tile);
  background: var(--tt-surface-card);
  box-shadow: var(--tt-surface-shadow-sm);
}

.tt-subnav__link {
  padding: 0.55rem 0.75rem;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  border-radius: var(--tt-radius-nav);
  color: var(--tt-text-2);
  font-size: var(--tt-fs-label);
  font-weight: 600;
  white-space: nowrap;
  transition: background-color var(--tt-dur) var(--tt-ease), color var(--tt-dur) var(--tt-ease);
}

.tt-subnav__link .material-icons-outlined {
  color: var(--tt-muted);
  font-size: 1.2rem;
  transition: color var(--tt-dur) var(--tt-ease);
}

.tt-subnav__link:hover {
  background: rgba(var(--tt-dark-rgb), 0.05);
  color: var(--tt-ink);
}

.tt-subnav__link:is([aria-current="true"], [aria-current="page"]) {
  background: rgba(var(--tt-primary-rgb), 0.12);
  color: var(--tt-primary-ink);
}

.tt-subnav__link:is([aria-current="true"], [aria-current="page"]) .material-icons-outlined {
  color: var(--tt-primary-ink);
}

.tt-subnav__count {
  min-width: 1.6rem;
  margin-left: auto;
  padding: 0.05rem 0.45rem;
  border-radius: var(--tt-radius-pill);
  background: rgba(var(--tt-secondary-rgb), 0.12);
  color: var(--tt-secondary-ink);
  font-size: var(--tt-fs-caption);
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.tt-subnav__link:is([aria-current="true"], [aria-current="page"]) .tt-subnav__count {
  background: rgba(var(--tt-primary-rgb), 0.16);
  color: var(--tt-primary-ink);
}

.tt-subnav-layout__main {
  min-width: 0;
  display: grid;
  gap: 1.25rem;
}

/* the grid gap spaces the cards (the template gives content cards a bottom margin); scroll-margin clears the
   fixed top bar when a nav link, or a #hash after saving, scrolls a card into view */
.tt-subnav-layout__main > .card {
  margin-bottom: 0;
  scroll-margin-top: calc(var(--tt-header-h) + 1.25rem);
}

/* ==========================================================================
   Primitive: code — a short sign-in code as letter tiles, easy to read off one screen and type on another.
   Mark it up as <data value="abcd"> so copying takes the value rather than the tiles; --empty draws blank
   slots. Real borders, not inset shadows, so the tiles survive Windows contrast themes.
   ========================================================================== */

.tt-code {
  display: inline-flex;
  gap: 0.4rem;
}

.tt-code__char {
  width: 2.75rem;
  height: 3.25rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--tt-card-border);
  border-radius: 0.75rem;
  background: #fff;
  box-shadow: 0 1px 2px rgba(var(--tt-dark-rgb), 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.8);
  color: var(--tt-ink);
  font-family: var(--tt-font-mono);
  font-size: 1.6rem;
  font-weight: 700;
  line-height: 1;
}

.tt-code--empty .tt-code__char {
  border: 1.5px dashed rgba(var(--tt-dark-rgb), 0.2);
  background: transparent;
  box-shadow: none;
}

/* ==========================================================================
   Primitive: screen — a 16:9 preview in a light bezel: the card's own hairline on a flat grey, with the picture inset
   on corners that run parallel to the frame's (outer radius − bezel − border). Markup: .tt-screen >
   .tt-screen__view > img. As a <button> it opens the full-size preview and shows its label on hover or focus
   (always, on touch screens). --empty puts an icon and a note in a dashed view instead of a picture.
   ========================================================================== */

.tt-screen {
  --tt-screen-bezel: 5px;
  --tt-screen-radius: 14px;
  position: relative;
  width: 100%;
  padding: var(--tt-screen-bezel);
  display: block;
  border: 1px solid var(--tt-card-border);
  border-radius: var(--tt-screen-radius);
  background: #f5f7f6;
  box-shadow: 0 1px 2px rgba(var(--tt-dark-rgb), 0.05), 0 0.75rem 1.5rem -1.1rem rgba(var(--tt-dark-rgb), 0.35),
    inset 0 1px 0 rgba(255, 255, 255, 0.9);
  text-align: inherit;
}

button.tt-screen {
  cursor: zoom-in;
  transition: border-color var(--tt-dur) var(--tt-ease), box-shadow var(--tt-dur) var(--tt-ease);
}

button.tt-screen:hover {
  border-color: rgba(var(--tt-primary-rgb), 0.35);
}

.tt-screen__view {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: 16 / 9;
  border-radius: calc(var(--tt-screen-radius) - var(--tt-screen-bezel) - 1px);
  background: #fff;
}

/* the picture's edge, drawn over it so a white board still separates from the bezel */
.tt-screen__view::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(var(--tt-dark-rgb), 0.08);
  pointer-events: none;
}

.tt-screen__view > img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
}

.tt-screen__label {
  position: absolute;
  right: calc(var(--tt-screen-bezel) + 0.4rem);
  bottom: calc(var(--tt-screen-bezel) + 0.4rem);
  padding: 0.3rem 0.65rem;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  border-radius: var(--tt-radius-pill);
  background: rgba(var(--tt-dark-rgb), 0.85);
  color: #fff;
  font-size: var(--tt-fs-caption);
  font-weight: 600;
  opacity: 0;
}

.tt-screen__label .material-icons-outlined {
  font-size: 1rem;
}

.tt-screen:is(:hover, :focus-visible) .tt-screen__label {
  opacity: 1;
}

@media (hover: none) {
  .tt-screen__label {
    opacity: 1;
  }
}

.tt-screen--empty .tt-screen__view {
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 0.35rem;
  border: 1.5px dashed rgba(var(--tt-dark-rgb), 0.16);
  background: rgba(var(--tt-dark-rgb), 0.025);
  color: var(--tt-muted);
  font-size: var(--tt-fs-caption);
  text-align: center;
}

.tt-screen--empty .tt-screen__view::after {
  display: none;
}

.tt-screen--empty .material-icons-outlined {
  color: var(--tt-subtle);
  font-size: 1.9rem;
}

/* ==========================================================================
   Sidebar — dark surface
   ========================================================================== */

.app.menu-dark .app-sidebar {
  border-right: 1px solid rgba(255, 255, 255, 0.06);
  background: var(--tt-dark-surface);
  box-shadow: 1rem 0 2.5rem -2rem rgba(11, 26, 17, 0.7);
}

.app .app-sidebar .logo {
  height: var(--tt-header-h) !important;
  display: flex;
  align-items: center;
}

.app .app-sidebar .logo.text-center {
  justify-content: center;
}

.app.menu-dark .app-sidebar .logo.logo-sm {
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  background: transparent;
}

.app-sidebar .logo.logo-sm a {
  width: 200px;
  max-width: 100%;
  display: block;
  flex: 0 0 auto;
  line-height: 1;
}

.app-sidebar-logo {
  display: block;
  width: 100%;
  height: auto;
}

/* labels stay on one line while the sidebar animates between widths */
.app-menu .menu-label {
  white-space: nowrap;
}

@media (min-width: 1200px) {
  .full-width-header .app-menu {
    height: calc(100% - var(--tt-header-h)) !important;
  }
}

.app-menu {
  padding-top: 8px;
  padding-bottom: 24px;
}

.app.menu-dark .accordion-menu li.sidebar-title {
  padding: 16px 28px 8px;
  color: var(--tt-on-dark-muted);
  font-family: var(--tt-font-sans);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  opacity: 1;
}

.app.menu-dark .app-menu > ul > li > a {
  position: relative;
  margin: 2px 12px;
  padding: 9px 12px;
  display: flex;
  align-items: center;
  gap: 12px;
  border-radius: var(--tt-radius-nav);
  color: var(--tt-on-dark);
  font-size: 14px;
  font-weight: 500;
  line-height: 20px;
  transition: background-color var(--tt-dur) var(--tt-ease), color var(--tt-dur) var(--tt-ease);
}

.app.menu-dark .app-menu > ul > li > a:hover {
  padding-left: 12px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--tt-on-dark-strong);
}

.app.menu-dark .app-menu > ul > li > a > i,
.app.menu-dark .app-menu > ul > li > a > i:not(.has-sub-menu) {
  margin: 0;
  color: inherit !important;
  font-size: 20px;
  line-height: 20px;
  filter: none !important;
}

.app.menu-dark .app-menu > ul > li > a > i.has-sub-menu {
  float: none;
  margin: 0 0 0 auto;
  color: var(--tt-on-dark-muted) !important;
  font-size: 18px;
}

/* expanded or current parent */
.app.menu-dark .app-menu > ul > li.open > a {
  color: var(--tt-on-dark-strong);
}

/* current page: a flat brand fill + inset ring (sidebars_controller marks the leaf .active and its li .open) */
.app.menu-dark .app-menu > ul > li.open > a.active,
.app.menu-dark .app-menu > ul > li ul li a.active {
  background: rgba(var(--tt-primary-rgb), 0.3);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
  color: #fff;
}

.app.menu-dark .app-menu > ul > li.open > a.active > i:not(.has-sub-menu) {
  color: var(--tt-on-dark-accent) !important;
}

/* sub-menus hang off a guide line under the parent icon */
.app.menu-dark .app-menu > ul > li ul {
  margin: 2px 12px 8px 33px;
  padding: 2px 0;
  border-left: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 0;
  background: transparent;
}

.app.menu-dark .app-menu > ul > li ul li a {
  margin: 2px 0 2px 8px;
  padding: 7px 12px;
  border-radius: var(--tt-radius-nav);
  color: var(--tt-on-dark);
  font-size: 13.5px;
  font-weight: 400;
  transition: color var(--tt-dur) var(--tt-ease), background-color var(--tt-dur) var(--tt-ease);
}

.app.menu-dark .app-menu > ul > li ul li a:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--tt-on-dark-strong);
}

.app.menu-dark .app-menu > ul > li ul li a.active {
  font-weight: 500;
}

.app-sidebar .ps__rail-y:hover > .ps__thumb-y,
.app-sidebar .ps__thumb-y {
  background-color: rgba(255, 255, 255, 0.22);
}

.app-sidebar .ps__rail-y:hover,
.app-sidebar .ps--clicking {
  background-color: transparent !important;
}

/* the logo box that moves into the top bar while the sidebar is hidden (and below 1200px) */
.app.menu-dark.sidebar-hidden.full-width-header .app-sidebar .logo.hidden-sidebar-logo {
  border-bottom: 1px solid var(--tt-hairline);
  background: #fff;
  background: var(--tt-surface-frost-solid);
}

/* ==========================================================================
   Sidebar — icon rail (1200px and up; .sidebar-rail is set by libs/sidebar_toggle.js and remembered in a cookie)
   Icons only. A link's .menu-label becomes its tooltip; a parent's sub-menu becomes a flyout titled by its
   data-label. Both hide with opacity, not display, so every link keeps its accessible name.
   ========================================================================== */

@media (min-width: 1200px) {
  .app.sidebar-rail {
    --tt-rail-w: 76px;
  }

  .app.sidebar-rail .app-sidebar {
    width: var(--tt-rail-w);
  }

  .app.sidebar-rail .app-container {
    width: calc(100vw - var(--tt-rail-w));
    margin-left: var(--tt-rail-w);
  }

  .app.sidebar-rail.full-width-header .app-header {
    width: calc(100% - var(--tt-rail-w));
  }

  /* the same logo, cropped to "Tindahang Tapat": its first 66.5 of 168 units, just before ONPREM */
  .app.sidebar-rail .app-sidebar .logo.logo-sm {
    padding-right: 0;
    padding-left: 0;
  }

  .app.sidebar-rail .app-sidebar .logo.logo-sm a {
    width: 48px;
    aspect-ratio: 66.5 / 40;
    overflow: hidden;
  }

  .app.sidebar-rail .app-sidebar-logo {
    width: auto;
    max-width: none;
    height: 100%;
  }

  /* flyouts overhang the rail, so the menu can't clip them (the rail is short enough not to scroll) */
  .app.sidebar-rail .app-menu,
  .app.sidebar-rail .app-menu.ps {
    overflow: visible !important;
  }

  .app.sidebar-rail .app-menu > :is(.ps__rail-x, .ps__rail-y) {
    display: none;
  }

  .app.sidebar-rail .app-menu > ul > li {
    position: relative;
  }

  .app.menu-dark.sidebar-rail .app-menu > ul > li > a,
  .app.menu-dark.sidebar-rail .app-menu > ul > li > a:hover {
    width: 48px;
    height: 44px;
    margin: 2px auto;
    padding: 0;
    justify-content: center;
  }

  .app.menu-dark.sidebar-rail .app-menu > ul > li > a > i:not(.has-sub-menu) {
    font-size: 22px;
  }

  .app.menu-dark.sidebar-rail .app-menu > ul > li > a > i.has-sub-menu {
    display: none;
  }

  /* a parent with an open flyout reads as hovered */
  .app.menu-dark.sidebar-rail .app-menu > ul > li:has(> ul.sub-menu):is(:hover, :focus-within) > a {
    background: rgba(255, 255, 255, 0.06);
    color: var(--tt-on-dark-strong);
  }

  /* its sub-menu is tucked away, so a parent holding the current page carries the current-page fill */
  .app.menu-dark.sidebar-rail .app-menu > ul > li:has(> ul a.active) > a {
    background: rgba(var(--tt-primary-rgb), 0.3);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
    color: #fff;
  }

  .app.menu-dark.sidebar-rail .app-menu > ul > li:has(> ul a.active) > a > i:not(.has-sub-menu) {
    color: var(--tt-on-dark-accent) !important;
  }

  /* tooltip: the link's own label, parked 8px past the rail edge */
  .app.sidebar-rail .app-menu > ul > li > a > .menu-label {
    position: absolute;
    top: 50%;
    left: calc(100% + 22px);
    z-index: 2;
    padding: 6px 10px;
    border-radius: 0.55rem;
    background: var(--tt-dark-raised);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08), 0 0.75rem 1.5rem -0.75rem rgba(11, 26, 17, 0.75);
    color: var(--tt-on-dark-strong);
    font-size: var(--tt-fs-label);
    font-weight: 500;
    line-height: 18px;
    opacity: 0;
    pointer-events: none;
    transform: translate(-4px, -50%);
  }

  .app.sidebar-rail .app-menu > ul > li > a > .menu-label::before {
    content: "";
    position: absolute;
    top: 50%;
    left: -4px;
    width: 8px;
    height: 8px;
    border-radius: 1px;
    background: inherit;
    transform: translateY(-50%) rotate(45deg);
  }

  .app.sidebar-rail .app-menu > ul > li:not(:has(> ul.sub-menu)) > a:is(:hover, :focus-visible) > .menu-label {
    opacity: 1;
    transform: translate(0, -50%);
  }

  /* flyout: the accordion leaves inline display / height on sub-menus, hence the !important */
  .app.menu-dark.sidebar-rail .app-menu > ul > li > ul.sub-menu {
    position: absolute;
    top: -4px;
    left: calc(100% + 8px);
    z-index: 3;
    display: block !important;
    height: auto !important;
    min-width: 212px;
    margin: 0;
    padding: 4px 6px 6px;
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 0.9rem;
    background: var(--tt-dark-raised);
    box-shadow: 0 1.25rem 2.25rem -1rem rgba(11, 26, 17, 0.8);
    opacity: 0;
    visibility: hidden;
    transform: translateX(-4px);
  }

  .app.menu-dark.sidebar-rail .app-menu > ul > li > ul.sub-menu::before {
    content: attr(data-label);
    display: block;
    padding: 8px 10px 6px;
    color: var(--tt-on-dark-muted);
    font-size: var(--tt-fs-overline);
    font-weight: 700;
    letter-spacing: 0.08em;
    line-height: 1.4;
    text-transform: uppercase;
  }

  /* bridges the gap to the rail, so the pointer can travel into the flyout without closing it */
  .app.sidebar-rail .app-menu > ul > li > ul.sub-menu::after {
    content: "";
    position: absolute;
    top: 0;
    right: 100%;
    bottom: 0;
    width: 12px;
  }

  .app.menu-dark.sidebar-rail .app-menu > ul > li > ul.sub-menu li a {
    margin: 1px 0;
    padding: 8px 10px;
    white-space: nowrap;
  }

  .app.sidebar-rail .app-menu > ul > li:is(:hover, :focus-within) > ul.sub-menu {
    opacity: 1;
    visibility: visible;
    transform: none;
  }
}

/* ==========================================================================
   Top bar — solid frost (fixed, content scrolls under it, so no backdrop-filter)
   ========================================================================== */

.app-header::before {
  display: none;
}

.app.full-width-header .app-header .navbar {
  height: var(--tt-header-h);
  padding: 0 calc(var(--tt-gutter) - 12px);
  border-bottom: 1px solid var(--tt-hairline);
  background: var(--tt-surface-frost-solid);
  box-shadow: 0 0.75rem 1.5rem -1.25rem rgba(var(--tt-dark-rgb), 0.22);
}

.app-header .navbar > .container-fluid {
  flex-wrap: nowrap;
  gap: 16px;
}

.app-header .navbar > .container-fluid > .d-flex {
  flex-shrink: 0;
}

.app-header-start {
  min-width: 0;
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  gap: 10px;
}

.app-header .navbar .navbar-nav > li > a.tt-sidebar-toggle,
.app-header .nav-link > a.btn {
  width: 36px;
  height: 36px;
  margin: 0;
  padding: 0 !important;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--tt-radius-nav);
  box-shadow: none !important;
  color: var(--tt-text-2) !important;
  line-height: 1;
  transition: background-color var(--tt-dur) var(--tt-ease), color var(--tt-dur) var(--tt-ease);
}

.app-header .navbar .navbar-nav > li > a.tt-sidebar-toggle:hover,
.app-header .nav-link > a.btn:hover {
  background: rgba(var(--tt-dark-rgb), 0.06);
  color: var(--tt-ink) !important;
}

.app-header .nav-link > a.btn .material-symbols-outlined {
  font-size: 22px;
}

.app-header .navbar .nav-link.text-muted {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--tt-muted) !important;
  font-size: 13px;
}

.app-header .nav-link > .fw-semibold.text-success {
  font-size: 12.5px;
}

.app-header .nav-link > .text-muted.ms-1 {
  display: none;
}

/* breadcrumb, inside the top bar */
.app-header-breadcrumb {
  min-width: 0;
  padding-left: 12px;
  border-left: 1px solid var(--tt-hairline);
}

.app-header-breadcrumb .breadcrumb {
  margin: 0;
  padding: 0;
  flex-wrap: nowrap;
  align-items: center;
  border-radius: 0;
  background: transparent;
  font-size: 13.5px;
  line-height: 20px;
}

.app-header-breadcrumb .breadcrumb-item {
  flex-shrink: 0;
  white-space: nowrap;
}

.app-header-breadcrumb .breadcrumb-item a {
  margin: 0 -4px;
  padding: 4px;
  border-radius: 0.45rem;
  color: var(--tt-muted);
  font-weight: 500;
  transition: background-color var(--tt-dur) var(--tt-ease), color var(--tt-dur) var(--tt-ease);
}

.app-header-breadcrumb .breadcrumb-item a:hover {
  background: rgba(var(--tt-dark-rgb), 0.05);
  color: var(--tt-primary-ink);
}

/* non-link crumbs (section names) stay muted; only the last one is the current page */
.app-header-breadcrumb .breadcrumb-item.active {
  color: var(--tt-muted);
  font-weight: 500;
}

.app-header-breadcrumb .breadcrumb-item.active:last-child {
  min-width: 0;
  flex-shrink: 1;
  overflow: hidden;
  color: var(--tt-ink);
  font-weight: 600;
  text-overflow: ellipsis;
}

.app-header-breadcrumb .breadcrumb-item + .breadcrumb-item {
  padding-left: 4px;
}

.app-header-breadcrumb .breadcrumb-item + .breadcrumb-item::before {
  padding-right: 4px;
  color: var(--tt-subtle);
  font-size: 16px;
  line-height: 20px;
}

/* page content: one header-height below the container padding, with or without crumbs */
.app-container {
  padding: 24px var(--tt-gutter) 56px;
}

.app-container > .app-content.mt-4 {
  margin-top: var(--tt-header-h) !important;
}

/* ==========================================================================
   Global chrome: cards (content only)
   ========================================================================== */

.app-content .card,
.dash-panel,
.dash-leaderboard-card,
.picklist-queue-toolbar,
.picklist-queue-lane {
  --bs-card-bg: #fff;
  --bs-card-border-color: var(--tt-card-border);
  --bs-card-border-radius: var(--tt-radius-card);
  --bs-card-inner-border-radius: calc(var(--tt-radius-card) - 1px);
  --bs-card-cap-bg: transparent;
  --bs-card-title-color: var(--tt-ink);
  border: 1px solid var(--tt-card-border);
  border-radius: var(--tt-radius-card);
  background: var(--tt-surface-card);
  box-shadow: var(--tt-surface-shadow);
}

/* lift a card above its later siblings while a menu or select inside it is open */
.app-content .card:focus-within,
.picklist-queue-toolbar:focus-within {
  z-index: 20;
}

.picklist-queue-toolbar {
  position: relative;
}

.app-content .card .card-header {
  padding: 1.5rem 1.7rem 0.85rem;
  border-bottom: 0;
  background: transparent;
  color: var(--tt-ink);
}

.app-content .card .card-title {
  font-family: var(--tt-font-display);
  font-size: 1.15rem;
  font-weight: var(--tt-heading-weight);
  letter-spacing: -0.01em;
  color: var(--tt-ink);
}

.app-content .card .card-header p {
  margin-bottom: 0;
  color: var(--tt-muted);
  font-size: 13px;
}

.app-content .card .card-body {
  padding: 1.4rem 1.7rem;
}

.app-content .card .card-header + .card-body {
  padding-top: 0.85rem;
}

.app-content .card .card-footer {
  padding: 1rem 1.7rem;
  border-top: 1px solid var(--tt-hairline);
  background: rgba(var(--tt-dark-rgb), 0.02);
}

.app-content .card .card-footer:last-child {
  border-radius: 0 0 var(--tt-radius-card) var(--tt-radius-card);
}

.app-content .card-subtitle,
.app-content .card-text {
  color: var(--tt-muted);
}

/* count badge next to a card title (custom.css positions it with a fixed 100px offset) */
.card-title:has(+ .title-badge) {
  display: inline-block;
  vertical-align: middle;
}

.title-badge {
  float: none;
  margin: 0 0 0 8px;
  vertical-align: middle;
}

:has(> .title-badge) {
  white-space: nowrap;
}

/* ==========================================================================
   Global chrome: tables & DataTables (content, and modals wherever they mount)
   ========================================================================== */

.app-content .table,
.modal .table {
  --bs-table-color: var(--tt-text);
  --bs-table-bg: transparent;
  --bs-table-hover-bg: var(--tt-row-hover);
  --bs-table-striped-bg: rgba(var(--tt-dark-rgb), 0.025);
  color: var(--tt-text);
  font-size: 13.5px;
}

.app-content .table *,
.modal .table * {
  border-color: var(--tt-hairline) !important;
}

.app-content .table td,
.app-content .table th,
.app-content table.dataTable td,
.app-content table.dataTable th,
.modal .table td,
.modal .table th {
  padding: 11px 14px !important;
  vertical-align: middle;
}

.app-content table.dataTable td,
.app-content table.dataTable th {
  border-bottom: 1px solid var(--tt-hairline) !important;
}

.app-content .table > thead > tr > th,
.app-content .table thead th,
.app-content table.dataTable thead th,
.app-content .table-light th,
.modal .table > thead > tr > th {
  border-bottom: 1px solid var(--tt-hairline) !important;
  background-color: rgba(var(--tt-dark-rgb), 0.035);
  color: var(--tt-muted);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  line-height: 1.35;
  text-transform: uppercase;
}

.app-content .table > thead > tr > th:first-child,
.app-content table.dataTable thead th:first-child,
.modal .table > thead > tr > th:first-child {
  border-radius: var(--tt-radius-nav) 0 0 var(--tt-radius-nav);
}

.app-content .table > thead > tr > th:last-child,
.app-content table.dataTable thead th:last-child,
.modal .table > thead > tr > th:last-child {
  border-radius: 0 var(--tt-radius-nav) var(--tt-radius-nav) 0;
}

/* a modal table ends at the modal body's padding, not on a rule */
.modal .table {
  margin-bottom: 0;
}

.modal .table > tbody > tr:last-child > * {
  border-bottom-width: 0;
}

.app-content .table tfoot th,
.app-content table.dataTable tfoot th {
  color: var(--tt-text-2);
  font-weight: 600;
}

.app-content .table td:first-child,
.app-content .table.dataTable td.text-muted,
.app-content .table.dataTable td:first-child,
.modal .table td:first-child {
  color: var(--tt-muted);
  font-weight: 500;
}

.app-content .table-hover > tbody > tr:hover {
  background: var(--tt-row-hover);
}

.app-content table.dataTable.table > tbody > tr:hover > * {
  --bs-table-bg-state: var(--tt-row-hover);
}

.app-content tr.unopened-order td {
  font-weight: 600;
}

.app-content .dataTables_scroll,
.app-content table.dataTable {
  margin-top: 12px !important;
  margin-bottom: 12px !important;
}

/* sort indicators */
table.dataTable thead th.dt-orderable-asc::after,
table.dataTable thead th.dt-orderable-desc::after {
  color: var(--tt-subtle);
  font-size: 18px;
}

table.dataTable thead th.dt-ordering-asc,
table.dataTable thead th.dt-ordering-desc {
  color: var(--tt-text-2);
}

table.dataTable thead th.dt-ordering-asc::after,
table.dataTable thead th.dt-ordering-desc::after {
  color: var(--tt-primary-ink);
}

table.dataTable thead th.dt-orderable-asc,
table.dataTable thead th.dt-orderable-desc {
  cursor: pointer;
}

/* length + search controls match the 36px filter bar */
.dt-length select,
.dt-search input[type="search"] {
  height: 36px;
  min-height: 36px;
  padding-top: 0;
  padding-bottom: 0;
  border: 1px solid rgba(var(--tt-dark-rgb), 0.14);
  border-radius: var(--tt-radius-nav);
  font-size: 13px;
}

.dt-length select {
  width: auto;
  min-width: 76px;
}

.dt-search input[type="search"] {
  width: 240px;
  padding-left: 12px;
}

.dt-length label,
.dt-search label {
  color: var(--tt-muted);
  font-size: 13px;
  font-weight: 500;
}

.dt-info {
  color: var(--tt-muted);
  font-size: 13px;
}

/* sits over a scrolling table, so solid frost rather than blur */
.dt-processing {
  top: 72px;
  left: 50%;
  padding: 0.8rem 1.2rem;
  border: 1px solid var(--tt-surface-border);
  border-radius: var(--tt-radius-btn);
  background: var(--tt-surface-frost-solid);
  box-shadow: var(--tt-surface-shadow-sm);
  color: var(--tt-text);
  font-size: 13px;
  transform: translateX(-50%);
}

.dt-processing > div > div {
  background: var(--tt-primary) !important;
}

/* the empty / no-match row holds an illustrated .tt-state (datatables_config.js) — it isn't a data row, so no
   row padding, rule or hover tint */
.app-content table.dataTable td.dt-empty {
  padding: 14px 0 2px !important;
  border-bottom: 0 !important;
  white-space: normal;
}

.app-content table.dataTable.table > tbody > tr:hover > td.dt-empty {
  --bs-table-bg-state: transparent;
}

/* `.app-content .table *` flattens every border to the hairline — give the state its dashed edge back */
.app-content table.dataTable td.dt-empty .tt-state {
  border-color: rgba(var(--tt-dark-rgb), 0.16) !important;
}

/* pagination */
.app-content .pagination {
  flex-wrap: wrap;
  gap: 4px;
}

.app-content .page-link,
.app-content .page-item.disabled .page-link,
.app-content .dt-paging .pagination .page-item .page-link {
  min-width: 34px;
  height: 34px;
  padding: 0 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--tt-radius-nav) !important;
  background: rgba(var(--tt-dark-rgb), 0.05);
  color: var(--tt-text-2);
  font-size: 13px;
  font-weight: 600;
}

.app-content .page-item:not(:first-child) .page-link {
  margin-left: 0;
}

.app-content .page-link:hover,
.app-content .dt-paging .pagination .page-item .page-link:hover {
  background: rgba(var(--tt-primary-rgb), 0.12);
  color: var(--tt-primary-ink);
}

.app-content .page-link:focus,
.app-content .dt-paging .pagination .page-item .page-link:focus-visible {
  box-shadow: var(--tt-ring);
}

.app-content .page-item.active .page-link,
.app-content .dt-paging .pagination .page-item.active .page-link,
.app-content .dt-paging .pagination .page-item.active .page-link:hover {
  background: rgb(var(--tt-primary-strong-rgb));
  box-shadow: 0 0.6rem 1.2rem -0.6rem rgba(var(--tt-primary-strong-rgb), 0.85);
  color: #fff;
}

.app-content .page-item.disabled .page-link,
.app-content .dt-paging .pagination .page-item.disabled .page-link {
  background: rgba(var(--tt-dark-rgb), 0.03);
  color: #b3bdc9;
  opacity: 1;
}

/* prev/next render a chevron via ::before (custom.css); keep the text glyph hidden */
.app-content .dt-paging .pagination .page-item .page-link.previous,
.app-content .dt-paging .pagination .page-item .page-link.next {
  padding: 0;
  font-size: 0;
}

.app-content .dt-paging .pagination .page-item .page-link.ellipsis {
  background: none;
  color: var(--tt-subtle);
}

/* DatatableFilterHelper controls */
.dt-filter .form-select,
.dt-filter .form-control {
  border-color: rgba(var(--tt-dark-rgb), 0.14);
  border-radius: var(--tt-radius-nav);
  background-color: #fff;
  color: var(--tt-text);
}

.dt-filter .dt-filter-icon {
  color: var(--tt-subtle);
}

.dt-filter .form-select:focus,
.dt-filter .form-control:focus,
.dt-filter .ts-wrapper.form-select.focus {
  border-color: var(--tt-primary);
  box-shadow: var(--tt-ring);
}

.dt-filter .form-select:disabled,
.dt-filter .ts-wrapper.form-select.disabled {
  border-color: var(--tt-hairline);
  background-color: rgba(var(--tt-dark-rgb), 0.04);
  color: var(--tt-subtle);
}

.dt-filter.is-active .form-select,
.dt-filter.is-active .form-control {
  border-color: rgba(var(--tt-primary-rgb), 0.5);
  background-color: #f1f8f0;
  color: var(--tt-primary-ink);
}

.dt-filter.is-active .dt-filter-icon {
  color: var(--tt-primary-ink);
}

/* Custom duration dates (input[type=date], added by the gem's filter controller). Browsers draw these
   themselves: Safari top-aligned the date in the 36px field, shrank it to 87px and showed no calendar icon,
   while Chrome and Edge centre it beside their own black icon. Give both the same width, centring and icon.
   WebKit and Blink both support ::-webkit-datetime-edit; Firefox doesn't and keeps its native icon. */
@supports selector(::-webkit-datetime-edit) {
  .dt-filter .customDurationField {
    position: relative;
    width: 140px;
    padding: 0 34px 0 10px;
    background-image: var(--tt-date-icon);
    background-repeat: no-repeat;
    background-position: right 10px center;
    background-size: 16px;
    line-height: 34px;
    /* calendar_today, in --tt-subtle / --tt-primary-ink (data URIs can't read tokens) */
    --tt-date-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2394a3b8'%3E%3Cpath d='M20 3h-1V1h-2v2H7V1H5v2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 18H4V10h16v11zm0-13H4V5h16v3z'/%3E%3C/svg%3E");
  }

  .dt-filter.is-active .customDurationField {
    --tt-date-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%230c7d11'%3E%3Cpath d='M20 3h-1V1h-2v2H7V1H5v2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 18H4V10h16v11zm0-13H4V5h16v3z'/%3E%3C/svg%3E");
  }

  /* Safari lays this out as a block at the top of the field; a full-height line centres it */
  .dt-filter .customDurationField::-webkit-datetime-edit {
    padding: 0;
    line-height: 34px;
  }

  /* iOS Safari shows the value here instead; Bootstrap caps it at 1.5em and centres it */
  .dt-filter .customDurationField::-webkit-date-and-time-value {
    height: auto;
    line-height: 34px;
    text-align: left;
  }

  /* Chrome and Edge only: keep their picker button as an invisible hit area over the drawn icon */
  .dt-filter .customDurationField::-webkit-calendar-picker-indicator {
    position: absolute;
    top: 50%;
    right: 8px;
    width: 20px;
    height: 20px;
    margin: 0;
    padding: 0;
    opacity: 0;
    cursor: pointer;
    transform: translateY(-50%);
  }

  /* an empty date reads as a placeholder in both: Chrome shows mm/dd/yyyy, Safari today's date (which it
     tints from the field's own colour, so this goes on the input, not ::-webkit-datetime-edit) */
  .dt-filter .customDurationField.is-empty {
    color: var(--tt-placeholder);
  }
}

.dt-filter-dropdown {
  border-radius: var(--tt-radius-btn);
}

/* page action buttons in the card header (custom.css squares them at 8px) */
.dt-header-actions > .btn {
  border-radius: var(--tt-radius-btn);
}

.dt-filter-reset,
.dt-filter-reset:focus {
  border-color: transparent;
  border-radius: var(--tt-radius-btn);
  background-color: rgba(var(--tt-dark-rgb), 0.06);
  color: var(--tt-muted);
}

.dt-filter-reset:hover {
  border-color: transparent;
  background-color: rgba(var(--tt-danger-rgb), 0.12);
  color: var(--tt-danger-ink);
}

.dt-filter-reset:disabled {
  background-color: rgba(var(--tt-dark-rgb), 0.04);
  color: var(--tt-subtle);
}

/* ==========================================================================
   Global chrome: menus & list groups (content menus are painted once, so they may blur)
   ========================================================================== */

.app-content .dropdown-menu,
.ts-dropdown,
.popover {
  border: 1px solid var(--tt-surface-border);
  border-radius: 0.9rem;
  background: var(--tt-surface-frost);
  box-shadow: 0 0 0 1px var(--tt-hairline), 0 1.25rem 2.5rem -1rem rgba(var(--tt-dark-rgb), 0.3);
  -webkit-backdrop-filter: var(--tt-frost-filter);
  backdrop-filter: var(--tt-frost-filter);
}

.app-content .dropdown-menu {
  min-width: 180px;
  padding: 6px;
  font-size: 13.5px;
}

.dropdown-menu::after,
.dropdown-menu:after {
  display: none !important;
}

.app-content .dropdown-item,
.app-content .dropdown-menu li a {
  margin: 0;
  padding: 7px 10px;
  border-radius: 0.55rem;
  color: var(--tt-text);
  font-size: 13.5px;
  font-weight: 500;
}

.app-content .dropdown-item:hover,
.app-content .dropdown-item:focus,
.app-content .dropdown-menu li a:hover {
  background: rgba(var(--tt-dark-rgb), 0.05);
  color: var(--tt-ink);
  font-weight: 500;
}

.app-content .dropdown-item.active,
.app-content .dropdown-item:active {
  background: rgba(var(--tt-primary-rgb), 0.12);
  color: var(--tt-primary-ink);
}

.app-content .dropdown-divider {
  margin: 6px 0;
  border-color: var(--tt-hairline);
}

.app-content .dropdown-menu .dropdown-header {
  padding: 6px 10px;
  color: var(--tt-muted);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.08em;
}

/* the row "…" trigger */
.btn-group.dropdown > .dropdown-toggle.text-gray {
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--tt-radius-nav);
  color: var(--tt-muted) !important;
  transition: background-color var(--tt-dur) var(--tt-ease), color var(--tt-dur) var(--tt-ease);
}

.btn-group.dropdown > .dropdown-toggle.text-gray:hover,
.btn-group.dropdown > .dropdown-toggle.text-gray.show {
  background: rgba(var(--tt-dark-rgb), 0.07);
  color: var(--tt-ink) !important;
}

.btn-group.dropdown > .dropdown-toggle .animate-scale:hover {
  transform: none;
}

.ts-dropdown {
  font-size: 13.5px;
  overflow: hidden;
}

.ts-dropdown .active {
  background-color: rgba(var(--tt-primary-rgb), 0.12);
  color: var(--tt-primary-ink);
}

.popover-header {
  border-color: var(--tt-hairline);
  background: transparent;
  color: var(--tt-ink);
  font-weight: 600;
}

.popover-body {
  color: var(--tt-text-2);
  font-size: 13px;
}

.app-content .list-group-item {
  border-color: var(--tt-hairline);
  background-color: rgba(255, 255, 255, 0.7);
  color: var(--tt-text);
}

.app-content .list-group-item.active {
  border-color: var(--tt-hairline);
  background: rgba(var(--tt-primary-rgb), 0.12);
  color: var(--tt-primary-ink);
}

/* ==========================================================================
   Modals — flat white, caught wherever they mount
   ========================================================================== */

/* backdrop is painted once (body scroll is locked), so it may blur; opacity stays 1 so the blur isn't washed out */
.modal-backdrop {
  --bs-backdrop-bg: rgba(var(--tt-dark-rgb), 0.38);
  --bs-backdrop-opacity: 1;
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}

/* forms live in modals, so no tint — plain white */
.modal .modal-content {
  border: 1px solid var(--tt-surface-border);
  border-radius: var(--tt-radius-modal);
  background: var(--tt-surface-plain);
  box-shadow: 0 2rem 4rem -1.5rem rgba(var(--tt-dark-rgb), 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.7);
}

.modal .modal-header {
  padding: 1.35rem 1.7rem 1rem;
  border-bottom: 1px solid var(--tt-hairline);
}

.modal .modal-title {
  font-family: var(--tt-font-display);
  font-size: 1.15rem;
  font-weight: var(--tt-heading-weight);
  letter-spacing: -0.01em;
  color: var(--tt-ink);
}

.modal .modal-body {
  padding: 1.4rem 1.7rem;
}

.modal .modal-footer {
  padding: 1rem 1.7rem 1.35rem;
  border-top: 1px solid var(--tt-hairline);
  background: transparent;
}

.btn-close:focus {
  box-shadow: var(--tt-ring);
}

/* a header carrying an accent takes a flat tint of it, so a modal reads as its state before its title */
.modal .modal-header:is([class*="tt-accent-"]) {
  border-radius: calc(var(--tt-radius-modal) - 1px) calc(var(--tt-radius-modal) - 1px) 0 0;
  background: rgba(var(--tt-accent-rgb, var(--tt-primary-rgb)), 0.07);
}

/* ==========================================================================
   Buttons — everywhere (body .btn), incl. sign-in and modals
   ========================================================================== */

body .btn {
  padding: 0.5rem 1rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  border-radius: var(--tt-radius-btn);
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 20px;
  transition: background-color var(--tt-dur) var(--tt-ease), border-color var(--tt-dur) var(--tt-ease),
    color var(--tt-dur) var(--tt-ease), box-shadow var(--tt-dur) var(--tt-ease),
    transform var(--tt-dur) var(--tt-ease) !important;
}

body .btn-sm {
  padding: 0.35rem 0.75rem;
  border-radius: var(--tt-radius-nav);
  font-size: 12.5px;
  line-height: 18px;
}

body .btn-lg {
  padding: 0.7rem 1.4rem;
  border-radius: 0.9rem;
  font-size: 15px;
  line-height: 22px;
}

body .btn i,
body .btn .material-icons-outlined,
body .btn .material-symbols-outlined {
  margin: 0;
  font-size: 18px;
  line-height: 1;
  vertical-align: 0;
}

body .btn-sm i,
body .btn-sm .material-icons-outlined,
body .btn-sm .material-symbols-outlined {
  font-size: 16px;
}

/* views nudge button icons down with .pt-1 (a fix for the old inline-block buttons);
   buttons centre their content now, so that padding only pushes the icon off-centre */
body .btn > :is(i, .material-icons-outlined, .material-symbols-outlined) {
  padding-top: 0 !important;
  padding-bottom: 0 !important;
  line-height: inherit; /* icon-only buttons match the height of text buttons */
}

/* filled variants: a solid fill of the variant colour + a glow in the same colour; hover and press take the fill
   a shade deeper. The fills are the brand-lightness base colours, a step deeper than the template's #4bad48. */
body .btn-success { --tt-btn-rgb: var(--tt-primary-strong-rgb); }
body .btn-primary { --tt-btn-rgb: var(--tt-blue-strong-rgb); }
body .btn-danger { --tt-btn-rgb: var(--tt-danger-strong-rgb); }
body .btn-info { --tt-btn-rgb: var(--tt-info-strong-rgb); }
body .btn-dark { --tt-btn-rgb: var(--tt-dark-rgb); }
body .btn-warning { --tt-btn-rgb: var(--tt-warning-rgb); --tt-btn-color: var(--tt-on-warning); }
body .btn-violet { --tt-btn-rgb: var(--tt-violet-rgb); }

/* the template drops every button shadow on focus/active with !important, hence the !important glow */
body .btn:is(.btn-success, .btn-primary, .btn-danger, .btn-info, .btn-dark, .btn-warning, .btn-violet) {
  border-color: transparent;
  background-color: rgb(var(--tt-btn-rgb));
  background-image: none;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.16), 0 0.7rem 1.5rem -0.6rem rgba(var(--tt-btn-rgb), 0.85) !important;
  color: var(--tt-btn-color, #fff);
}

body .btn-sm:is(.btn-success, .btn-primary, .btn-danger, .btn-info, .btn-dark, .btn-warning, .btn-violet) {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.16), 0 0.5rem 1rem -0.55rem rgba(var(--tt-btn-rgb), 0.85) !important;
}

/* full-width buttons: a wide glow reads as a smear, and these often sit in .overflow-hidden rows that crop it,
   so keep the shadow tight enough to stay inside the row padding */
body .btn:is(.w-100, .d-block, .btn-block):is(.btn-success, .btn-primary, .btn-danger, .btn-info, .btn-dark, .btn-warning, .btn-violet) {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.16), 0 1px 2px rgba(var(--tt-btn-rgb), 0.3),
    0 0.3rem 0.7rem -0.45rem rgba(var(--tt-btn-rgb), 0.6) !important;
}

body .btn:is(.btn-success, .btn-primary, .btn-danger, .btn-info, .btn-dark, .btn-warning, .btn-violet):hover {
  border-color: transparent;
  background-color: color-mix(in srgb, rgb(var(--tt-btn-rgb)) 90%, #000);
  background-image: none;
  color: var(--tt-btn-color, #fff);
}

body .btn:is(.btn-success, .btn-primary, .btn-danger, .btn-info, .btn-dark, .btn-warning, .btn-violet):not(:disabled):not(.disabled):active,
body .btn:is(.btn-success, .btn-primary, .btn-danger, .btn-info, .btn-dark, .btn-warning, .btn-violet):not(:disabled):not(.disabled).active,
body .show > .btn:is(.btn-success, .btn-primary, .btn-danger, .btn-info, .btn-dark, .btn-warning, .btn-violet).dropdown-toggle {
  border-color: transparent;
  background-color: color-mix(in srgb, rgb(var(--tt-btn-rgb)) 82%, #000);
  background-image: none;
  color: var(--tt-btn-color, #fff);
}

/* neutral: a soft tint, no border, no glow */
body .btn:is(.btn-light, .btn-secondary, .btn-outline-secondary),
body .btn:is(.btn-light, .btn-secondary, .btn-outline-secondary):focus {
  border-color: transparent;
  background-color: rgba(var(--tt-dark-rgb), 0.06);
  background-image: none;
  box-shadow: none !important;
  color: var(--tt-secondary-ink);
}

body .btn:is(.btn-light, .btn-secondary, .btn-outline-secondary):hover,
body .btn:is(.btn-light, .btn-secondary, .btn-outline-secondary):not(:disabled):not(.disabled):active,
body .btn:is(.btn-light, .btn-secondary, .btn-outline-secondary).active,
body .show > .btn:is(.btn-light, .btn-outline-secondary).dropdown-toggle {
  border-color: transparent;
  background-color: rgba(var(--tt-dark-rgb), 0.1);
  color: var(--tt-ink);
}

/* outline variants keep a border in the variant colour and fill with its tint on hover */
body .btn-outline-success { --tt-btn-rgb: var(--tt-primary-rgb); --tt-btn-ink: var(--tt-primary-ink); }
body .btn-outline-danger { --tt-btn-rgb: var(--tt-danger-rgb); --tt-btn-ink: var(--tt-danger-ink); }
body .btn-outline-primary { --tt-btn-rgb: var(--tt-blue-rgb); --tt-btn-ink: var(--tt-blue-ink); }
body .btn-outline-dark { --tt-btn-rgb: var(--tt-dark-rgb); --tt-btn-ink: var(--tt-text); }

body .btn:is(.btn-outline-success, .btn-outline-danger, .btn-outline-primary, .btn-outline-dark),
body .btn:is(.btn-outline-success, .btn-outline-danger, .btn-outline-primary, .btn-outline-dark):focus {
  border-color: rgba(var(--tt-btn-rgb), 0.55);
  background-color: transparent;
  box-shadow: none !important;
  color: var(--tt-btn-ink);
}

body .btn:is(.btn-outline-success, .btn-outline-danger, .btn-outline-primary, .btn-outline-dark):hover,
body .btn:is(.btn-outline-success, .btn-outline-danger, .btn-outline-primary, .btn-outline-dark):not(:disabled):not(.disabled):active,
body .btn:is(.btn-outline-success, .btn-outline-danger, .btn-outline-primary, .btn-outline-dark).active {
  border-color: rgba(var(--tt-btn-rgb), 0.55);
  background-color: rgba(var(--tt-btn-rgb), 0.12);
  color: var(--tt-btn-ink);
}

body .btn-link,
body .btn-link:focus {
  border-color: transparent;
  background-color: transparent;
  box-shadow: none !important;
  color: var(--tt-primary-ink);
}

body .btn-link:hover,
body .btn-link:not(:disabled):not(.disabled):active {
  border-color: transparent;
  background-color: rgba(var(--tt-primary-rgb), 0.1);
  color: var(--tt-primary-deep);
}

/* template "style-light" tinted buttons = a filled tint of the variant */
body .btn-style-light:is(.btn-success, .btn-danger, .btn-primary, .btn-warning, .btn-dark),
body .btn-style-light:is(.btn-success, .btn-danger, .btn-primary, .btn-warning, .btn-dark):hover {
  background-color: rgba(var(--tt-btn-rgb), 0.12);
  background-image: none;
  box-shadow: none !important;
  color: rgb(var(--tt-btn-rgb));
}

body .btn-style-light.btn-warning,
body .btn-style-light.btn-warning:hover {
  color: var(--tt-warning-ink);
}

body .btn:disabled,
body .btn.disabled {
  box-shadow: none !important;
  opacity: 0.5;
}

/* ==========================================================================
   Forms
   ========================================================================== */

.form-label,
.col-form-label {
  margin-bottom: 6px;
  color: var(--tt-text-2);
  font-size: 13px;
  font-weight: 600;
}

.form-control,
.form-select {
  padding: 8px 12px;
  border-color: rgba(var(--tt-dark-rgb), 0.14);
  border-radius: var(--tt-radius-nav);
  background-color: #fff;
  color: var(--tt-text);
  font-size: 14px;
  line-height: 20px;
  transition: border-color var(--tt-dur) var(--tt-ease), box-shadow var(--tt-dur) var(--tt-ease),
    background-color var(--tt-dur) var(--tt-ease);
}

.form-select {
  padding-right: 36px;
}

.form-control-sm,
.form-select-sm {
  padding-top: 5px;
  padding-bottom: 5px;
  border-radius: 0.6rem;
  font-size: 13px;
}

.form-control-sm {
  padding-right: 10px;
  padding-left: 10px;
}

.form-select-sm {
  padding-left: 10px;
}

.form-control-lg {
  padding: 11px 14px;
  font-size: 15px;
}

.form-control::placeholder {
  color: var(--tt-placeholder);
  opacity: 1;
}

.form-control::-webkit-input-placeholder {
  color: var(--tt-placeholder);
}

.form-control:hover:not(:disabled):not([readonly]):not(:focus),
.form-select:hover:not(:disabled):not(:focus) {
  border-color: rgba(var(--tt-dark-rgb), 0.26);
}

.form-control:focus,
.form-select:focus {
  border-color: var(--tt-primary);
  background-color: #fff;
  box-shadow: var(--tt-ring);
  outline: 0;
}

.form-control:disabled,
.form-select:disabled,
input.form-control:disabled {
  border-color: var(--tt-hairline);
  background-color: rgba(var(--tt-dark-rgb), 0.04);
  color: var(--tt-muted);
}

/* custom.css dims read-only inputs to 50% opacity, which makes the value hard to read */
input.form-control[readonly] {
  border-color: var(--tt-hairline);
  background-color: rgba(var(--tt-dark-rgb), 0.04) !important;
  color: var(--tt-text-2);
  opacity: 1;
}

.form-text {
  color: var(--tt-muted);
  font-size: 12.5px;
}

.form-control.is-invalid,
.was-validated .form-control:invalid,
.form-select.is-invalid {
  border-color: var(--tt-danger);
}

.form-control.is-invalid:focus,
.form-select.is-invalid:focus {
  border-color: var(--tt-danger);
  box-shadow: var(--tt-ring-danger);
}

.invalid-feedback {
  color: var(--tt-danger-ink);
  font-size: 12.5px;
}

.form-check-input {
  border-color: rgba(var(--tt-dark-rgb), 0.26);
}

.form-check-input:focus {
  border-color: var(--tt-primary);
  box-shadow: var(--tt-ring);
}

.form-check-input:checked,
input.form-check-input:checked,
.custom-checkbox .form-check-input:checked,
.form-check-input[type="checkbox"]:indeterminate {
  border-color: rgb(var(--tt-primary-strong-rgb));
  background-color: rgb(var(--tt-primary-strong-rgb));
}

.form-check-label {
  color: var(--tt-text);
}

.input-group-text {
  padding: 8px 12px;
  border-color: rgba(var(--tt-dark-rgb), 0.14);
  border-radius: var(--tt-radius-nav);
  background-color: rgba(var(--tt-dark-rgb), 0.035);
  color: var(--tt-muted);
}

.ts-wrapper.form-select,
.ts-wrapper.form-control {
  padding: 0;
}

.ts-control {
  border-color: rgba(var(--tt-dark-rgb), 0.14);
  border-radius: var(--tt-radius-nav);
  color: var(--tt-text);
  font-size: 14px;
}

.ts-wrapper.focus .ts-control,
.ts-wrapper.form-select.focus,
.ts-wrapper.form-control.focus {
  border-color: var(--tt-primary);
  box-shadow: var(--tt-ring);
}

.ts-wrapper.multi .ts-control > div {
  border-radius: var(--tt-radius-pill);
  background: rgba(var(--tt-primary-rgb), 0.14);
  color: var(--tt-primary-ink);
}

/* ==========================================================================
   Badges — pills; soft badges tint with their semantic colour
   ========================================================================== */

.badge {
  padding: 0.4em 0.7em;
  border-radius: var(--tt-radius-pill);
  font-weight: 600;
  letter-spacing: 0.01em;
}

.badge.badge-success { background: rgb(var(--tt-primary-strong-rgb)); color: #fff; }
.badge.badge-danger { background: var(--tt-danger); color: #fff; }
.badge.badge-warning { background: var(--tt-warning); color: #fff; }
.badge.badge-info { background: var(--tt-info); color: #fff; }
.badge.badge-primary { background: var(--tt-blue); color: #fff; }
.badge.badge-dark { background: var(--tt-secondary-ink); color: #fff; }
.badge.badge-secondary,
.badge.badge-light { background: rgba(var(--tt-secondary-rgb), 0.14); color: var(--tt-secondary-ink); }

/* status pills: semantic colour on a 14% tint of itself */
.badge.badge-style-light {
  background: rgba(var(--tt-accent-rgb, var(--tt-secondary-rgb)), 0.14);
  color: var(--tt-accent-ink, var(--tt-secondary-ink));
}

.badge.badge-style-light.badge-success { --tt-accent-rgb: var(--tt-primary-rgb); --tt-accent-ink: var(--tt-primary-ink); }
.badge.badge-style-light.badge-danger { --tt-accent-rgb: var(--tt-danger-rgb); --tt-accent-ink: var(--tt-danger-ink); }
.badge.badge-style-light.badge-warning { --tt-accent-rgb: var(--tt-warning-rgb); --tt-accent-ink: var(--tt-warning-ink); }
.badge.badge-style-light.badge-info { --tt-accent-rgb: var(--tt-info-rgb); --tt-accent-ink: var(--tt-info-ink); }
.badge.badge-style-light.badge-primary { --tt-accent-rgb: var(--tt-blue-rgb); --tt-accent-ink: var(--tt-blue-ink); }

.badge-dark-green {
  background: rgba(var(--tt-primary-rgb), 0.18);
  color: var(--tt-primary-deep);
}

/* order statuses keep their light/solid pairs (in progress vs done); only the text is adjusted for contrast */
.badge-order-status-voided { background-color: var(--tt-danger); color: #fff; }
.badge-order-status-invoiced { background-color: #f78600; color: #fff; }
.badge-order-status-picking { background-color: #fdf0cc; color: #92400e; }
.badge-order-status-picked { background-color: #f5b300; color: #3b2a00; }
.badge-order-status-invoicing { background-color: #fde7cc; color: #9a3412; }
.badge-order-status-pending { background-color: var(--tt-secondary-ink); color: #fff; }
.badge-order-status-acknowledged,
.badge-order-status-assigning { background-color: #dbeafe; color: var(--tt-blue-ink); }
.badge-order-status-queued { background-color: #1f7fe7; color: #fff; }

.status {
  border-radius: var(--tt-radius-pill);
  background-color: rgba(var(--tt-secondary-rgb), 0.14);
  color: var(--tt-secondary-ink);
  font-weight: 600;
}

.status-green {
  background-color: rgba(var(--tt-primary-rgb), 0.14);
  color: var(--tt-primary-ink);
}

/* ==========================================================================
   Alerts, navs, tooltips, toasts
   ========================================================================== */

.alert {
  padding: 0.85rem 1.15rem;
  border: 1px solid rgba(var(--tt-accent-rgb, var(--tt-secondary-rgb)), 0.25);
  border-radius: 0.9rem;
  background: rgba(var(--tt-accent-rgb, var(--tt-secondary-rgb)), 0.1);
  color: var(--tt-accent-ink, var(--tt-secondary-ink));
  font-size: 13.5px;
}

.alert.alert-danger { --tt-accent-rgb: var(--tt-danger-rgb); --tt-accent-ink: var(--tt-danger-ink); }
.alert.alert-success { --tt-accent-rgb: var(--tt-primary-rgb); --tt-accent-ink: var(--tt-primary-ink); }
.alert.alert-warning { --tt-accent-rgb: var(--tt-warning-rgb); --tt-accent-ink: var(--tt-warning-ink); }
.alert.alert-info { --tt-accent-rgb: var(--tt-info-rgb); --tt-accent-ink: var(--tt-info-ink); }
.alert.alert-primary { --tt-accent-rgb: var(--tt-blue-rgb); --tt-accent-ink: var(--tt-blue-ink); }
.alert.alert-dark { border-color: var(--tt-dark); background: var(--tt-dark); color: #fff; }

.alert-dismissible .btn-close {
  padding: 15px 16px;
}

.nav-tabs {
  border-bottom: 1px solid var(--tt-hairline);
}

.nav-tabs .nav-link {
  padding: 10px 14px;
  color: var(--tt-muted);
  font-weight: 600;
  opacity: 1;
}

.nav-tabs .nav-link:hover {
  color: var(--tt-text);
}

.nav-tabs .nav-item.show .nav-link,
.nav-tabs .nav-link.active {
  border-bottom-color: var(--tt-primary);
  color: var(--tt-ink);
}

.nav-pills .nav-link {
  border-radius: var(--tt-radius-nav);
  color: var(--tt-muted);
  font-weight: 600;
  opacity: 1;
}

.nav-pills .nav-link.active,
.nav-pills .show > .nav-link {
  background: rgba(var(--tt-primary-rgb), 0.12);
  color: var(--tt-primary-ink);
}

.accordion-item,
.accordion-item .accordion-button {
  border-color: var(--tt-hairline);
}

.accordion-item .accordion-button:not(.collapsed) {
  border-bottom-color: var(--tt-hairline);
  background-color: rgba(var(--tt-primary-rgb), 0.1);
  color: var(--tt-primary-ink);
}

.accordion-item .accordion-button.collapsed {
  background-color: transparent;
}

.accordion-item .accordion-button.collapsed:hover {
  background: rgba(var(--tt-dark-rgb), 0.04);
}

.tooltip {
  --bs-tooltip-bg: rgba(var(--tt-dark-rgb), 0.94);
  --bs-tooltip-font-size: 12px;
  --bs-tooltip-border-radius: 0.5rem;
  --bs-tooltip-padding-x: 8px;
  --bs-tooltip-padding-y: 5px;
}

.progress {
  border-radius: var(--tt-radius-pill);
  background-color: rgba(var(--tt-dark-rgb), 0.07);
}

/* SweetAlert2 injects its CSS after ours, hence the body prefix; toasts are fixed, so solid frost */
body .swal2-popup {
  border-radius: var(--tt-radius-modal);
  font-family: var(--tt-font-sans);
}

body .swal2-popup.swal2-toast {
  padding: 10px 14px;
  border: 1px solid var(--tt-surface-border);
  border-radius: var(--tt-radius-btn);
  background: var(--tt-surface-frost-solid);
  box-shadow: 0 0 0 1px var(--tt-hairline), 0 1.25rem 2.5rem -1rem rgba(var(--tt-dark-rgb), 0.3);
}

body .swal2-popup.swal2-toast .swal2-title {
  color: var(--tt-ink);
  font-size: 13.5px;
}

/* Typed toasts (libs/toasts.js) carry a solid semantic fill so the outcome reads at a glance. The fills are the
   -ink tones, which keep white text above 4.5:1; warning keeps its bright fill with dark text. The fill goes on
   background-color alone: SweetAlert2 copies it onto the success icon's masks, so a gradient would show seams. */
.tt-toast-success { --tt-toast-fill: var(--tt-primary-ink); --tt-toast-rgb: var(--tt-primary-rgb); }
.tt-toast-error { --tt-toast-fill: var(--tt-danger-ink); --tt-toast-rgb: var(--tt-danger-rgb); }
.tt-toast-info { --tt-toast-fill: var(--tt-info-ink); --tt-toast-rgb: var(--tt-info-rgb); }
.tt-toast-warning {
  --tt-toast-fill: var(--tt-warning);
  --tt-toast-rgb: var(--tt-warning-rgb);
  --tt-toast-on: var(--tt-on-warning);
  --tt-toast-edge: rgba(var(--tt-dark-rgb), 0.12);
}

body .swal2-popup.swal2-toast.tt-toast {
  padding: 12px 14px;
  border: 1px solid var(--tt-toast-edge, rgba(255, 255, 255, 0.2));
  background: var(--tt-toast-fill, var(--tt-dark));
  color: var(--tt-toast-on, #fff);
  box-shadow: 0 0 0 1px rgba(var(--tt-toast-rgb, var(--tt-dark-rgb)), 0.3),
    0 1.25rem 2.5rem -1rem rgba(var(--tt-toast-rgb, var(--tt-dark-rgb)), 0.65),
    inset 0 1px 0 rgba(255, 255, 255, 0.22);
}

body .swal2-popup.swal2-toast.tt-toast .swal2-title {
  color: inherit;
  font-size: var(--tt-fs-body);
  font-weight: 600;
}

body .swal2-popup.tt-toast .swal2-icon,
body .swal2-popup.tt-toast .swal2-icon .swal2-success-ring {
  border-color: currentColor;
  color: inherit;
}

body .swal2-popup.tt-toast .swal2-icon [class^="swal2-success-line"],
body .swal2-popup.tt-toast .swal2-icon [class^="swal2-x-mark-line"] {
  background-color: currentColor;
}

body .swal2-popup.tt-toast .swal2-close {
  color: inherit;
  opacity: 0.75;
}

body .swal2-popup.tt-toast .swal2-close:hover,
body .swal2-popup.tt-toast .swal2-close:focus-visible {
  color: inherit;
  opacity: 1;
}

/* the bar is a light stripe on the fill now, so its container follows the toast's corners instead of 5px */
body .swal2-popup.tt-toast .swal2-timer-progress-bar-container {
  border-radius: 0 0 var(--tt-radius-btn) var(--tt-radius-btn);
}

body .swal2-popup.tt-toast .swal2-timer-progress-bar {
  background: currentColor;
  opacity: 0.45;
}

body .swal2-popup .swal2-title {
  font-family: var(--tt-font-display);
  color: var(--tt-ink);
}

body .swal2-timer-progress-bar {
  background: rgba(var(--tt-primary-rgb), 0.55);
}

.pace .pace-progress {
  height: 3px;
  background: var(--tt-primary);
}

/* ==========================================================================
   Floating controls — fixed over scrolling content, so solid (no blur)
   ========================================================================== */

/* Bootstrap modals and SweetAlert2 dialogs lock scrolling and pad the body by the scrollbar's width, but skip
   fixed elements narrower than the window, so these slid sideways under the backdrop (17px with Windows' classic
   scrollbars, 0 with overlay ones). libs/scroll_lock.js hands them the same gap. */
.app.full-width-header .app-header {
  padding-right: var(--tt-scroll-lock-gap, 0px);
  /* the template transitions everything here; the gap has to land in the same frame as the body padding */
  transition-property: left, right, width, transform;
}

.fixed-hover-bottom {
  right: calc(16px + var(--tt-scroll-lock-gap, 0px));
  bottom: 16px;
  z-index: 1030;
}

.fixed-hover-bottom > .btn {
  width: 38px;
  height: 38px;
  padding: 0 !important;
  border: 1px solid var(--tt-surface-border);
  border-radius: var(--tt-radius-pill);
  background: var(--tt-surface-frost-solid);
  box-shadow: 0 0 0 1px var(--tt-hairline), var(--tt-surface-shadow-sm) !important;
  cursor: pointer;
}

.fixed-hover-bottom > .btn > .material-symbols-outlined {
  color: var(--tt-muted) !important;
  font-size: 20px !important;
}

/* .btn is inline-flex now; keep this hidden until scroll_to_top_controller shows it */
body .scroll-to-top-btn {
  right: calc(66px + var(--tt-scroll-lock-gap, 0px));
  bottom: 16px;
  padding: 8px 14px 8px 10px;
  display: none;
  border-radius: var(--tt-radius-pill);
  font-size: 11.5px;
  letter-spacing: 0.06em;
  opacity: 1;
}

.scroll-to-top-btn i {
  margin-right: 4px;
  font-size: 18px;
  vertical-align: -4px;
}

/* ==========================================================================
   Dashboard
   ========================================================================== */

.dash-header h1,
.picklist-queue-header h1 {
  font-family: var(--tt-font-display);
  font-size: var(--tt-fs-title);
  font-weight: var(--tt-heading-weight);
  letter-spacing: -0.01em;
  color: var(--tt-ink);
}

.dash-header p,
.picklist-queue-header p {
  color: var(--tt-muted);
  font-size: var(--tt-fs-body);
}

/* inset tiles inside a white surface */
.dash-header-card,
.picklist-queue-summary-item,
.tt-auth-record {
  border: 1px solid rgba(255, 255, 255, 0.8);
  border-radius: 1rem;
  background: rgba(255, 255, 255, 0.62);
  box-shadow: 0 0 0 1px var(--tt-hairline), inset 0 1px 0 rgba(255, 255, 255, 0.8);
}

.dash-header-card {
  border: 0;
  background: none;
  box-shadow: none;
}

.dash-panel-title h2,
.picklist-queue-lane-title h2 {
  font-family: var(--tt-font-display);
  font-size: var(--tt-fs-heading);
  font-weight: var(--tt-heading-weight);
  letter-spacing: -0.01em;
  color: var(--tt-ink);
}

.dash-panel-title small,
.picklist-queue-lane-title small,
.picklist-queue-summary-item small {
  color: var(--tt-muted);
}

.dash-leaderboard-card__header {
  border-color: var(--tt-hairline);
  background: transparent;
}

.dash-leaderboard-item {
  border-color: var(--tt-hairline);
}

.dash-leaderboard-item__name {
  font-weight: 600;
}

.dash-leaderboard-item__score,
.picklist-queue-summary-item strong,
.picklist-queue-lane-header > strong {
  font-family: var(--tt-font-display);
  font-weight: var(--tt-heading-weight);
  color: var(--tt-ink);
}

/* ==========================================================================
   Picklist queue
   ========================================================================== */

.picklist-queue-control {
  border-color: rgba(var(--tt-dark-rgb), 0.14);
  border-radius: var(--tt-radius-nav);
  background-color: #fff;
}

.picklist-queue-control:focus {
  border-color: var(--tt-primary);
  box-shadow: var(--tt-ring);
}

.picklist-queue-lane-header > strong {
  border: 1px solid rgba(255, 255, 255, 0.85);
  border-radius: 0.9rem;
  background: rgba(255, 255, 255, 0.85);
  box-shadow: 0 0 0 1px var(--tt-hairline);
}

.picklist-queue-item {
  border: 1px solid rgba(255, 255, 255, 0.9);
  border-radius: 1rem;
  background: #fff;
  box-shadow: 0 0 0 1px var(--tt-hairline), 0 0.75rem 1.5rem -1.25rem rgba(var(--tt-dark-rgb), 0.35);
}

.picklist-queue-item:hover {
  transform: none;
  box-shadow: 0 0 0 1px var(--tt-hairline), 0 0.75rem 1.5rem -1.25rem rgba(var(--tt-dark-rgb), 0.35);
}

.picklist-queue-item-index {
  border-radius: 0.6rem;
  background: rgba(var(--tt-dark-rgb), 0.06);
  color: var(--tt-text-2);
  font-weight: 700;
}

.picklist-queue-store strong,
.picklist-queue-store span {
  font-weight: 600;
}

.picklist-queue-meta {
  border-top-color: var(--tt-hairline);
  color: var(--tt-muted);
}

.picklist-queue-meta time {
  color: var(--tt-muted);
}

/* ==========================================================================
   Warehouse displays — a .tt-page-header, a 2×2 grid of board cards (a .tt-screen preview beside the board's
   .tt-code), then the rotation card. A narrow card stacks the preview over the code.
   ========================================================================== */

.tt-displays {
  display: grid;
  gap: 1.25rem;
}

/* the grid gaps space the cards (the template gives content cards a bottom margin) */
.tt-displays .card {
  margin-bottom: 0;
  scroll-margin-top: calc(var(--tt-header-h) + 1.25rem);
}

.tt-displays__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.25rem;
}

.tt-display {
  container: tt-display / inline-size;
}

/* line the footers up across a row of cards */
.tt-display > .card-footer {
  margin-top: auto;
}

.tt-display__body {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  align-items: center;
  gap: 1.25rem 1.5rem;
}

.tt-display__code {
  min-width: 0;
  display: grid;
  justify-items: start;
  gap: 0.55rem;
}

.tt-display__label {
  color: var(--tt-text-2);
  font-size: var(--tt-fs-overline);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.tt-display__code-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
}

.tt-display__meta {
  margin: 0;
  color: var(--tt-muted);
  font-size: var(--tt-fs-caption);
}

.tt-tv-search {
  min-height: 148px;
  padding: 1.1rem;
  display: flex;
  align-items: center;
  gap: 1rem;
  border: 1px dashed rgba(var(--tt-primary-rgb), 0.3);
  border-radius: var(--tt-radius-nav);
  background:
    linear-gradient(135deg, rgba(var(--tt-primary-rgb), 0.1), rgba(var(--tt-lime-rgb), 0.08)),
    rgba(255, 255, 255, 0.76);
}

.tt-tv-search__radar {
  position: relative;
  width: 70px;
  height: 70px;
  display: inline-grid;
  flex: 0 0 auto;
  place-items: center;
  border-radius: 50%;
  background: rgba(var(--tt-primary-rgb), 0.12);
  color: var(--tt-primary-ink);
  overflow: hidden;
}

.tt-tv-search__radar .material-icons-outlined {
  position: relative;
  z-index: 2;
  font-size: 1.8rem;
}

.tt-tv-search__rings,
.tt-tv-search__rings::before,
.tt-tv-search__rings::after {
  position: absolute;
  inset: 50%;
  width: 16px;
  height: 16px;
  border: 2px solid rgba(var(--tt-primary-rgb), 0.32);
  border-radius: 50%;
  transform: translate(-50%, -50%);
}

.tt-tv-search__rings::before,
.tt-tv-search__rings::after {
  content: "";
}

.tt-tv-search__rings::before {
  animation-delay: 450ms;
}

.tt-tv-search__rings::after {
  animation-delay: 900ms;
}

.tt-tv-search__copy {
  min-width: 0;
  display: grid;
  gap: 0.25rem;
}

.tt-tv-search__copy strong {
  color: var(--tt-ink);
  font-family: var(--tt-font-display);
  font-size: var(--tt-fs-heading);
  font-weight: 600;
}

.tt-tv-search__copy span {
  color: var(--tt-muted);
  font-size: var(--tt-fs-label);
  line-height: 1.45;
}

@container tt-display (max-width: 440px) {
  .tt-display__body {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ==========================================================================
   Detail pages & settings
   ========================================================================== */

.widget-list .widget-list-content .widget-list-item .widget-list-item-description-date {
  color: var(--tt-muted);
}

.widget-list .widget-list-content .widget-list-item .widget-list-item-description .widget-list-item-description-title {
  color: var(--tt-ink);
}

.widget-list .widget-list-content .widget-list-item .widget-list-item-description .widget-list-item-description-title:hover {
  color: var(--tt-primary-ink);
}

.datagrid-title {
  color: var(--tt-muted);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
}

.datagrid-content {
  color: var(--tt-text);
}

/* Settings page: a .tt-page-header, then a .tt-subnav of in-page links beside the groups (each group a card of
   .tt-setting rows) */
.tt-settings {
  display: grid;
  gap: 1.25rem;
}

/* OnPrem users area: the same shell, its .tt-subnav linking Users, Roles and Abilities as pages */
.tt-access {
  display: grid;
  gap: 1.25rem;
}

/* ability rows list the roles that grant them */
.tt-access__roles {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 0.4rem;
}

/* ==========================================================================
   Sign-in & setup — split screen: the sidebar's dark surface as the brand panel, one white card for the task.
   Every size comes from the type ramp: display (brand) · title (card) · lede / body · label · caption · overline.
   ========================================================================== */

.tt-external {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
}

.tt-auth {
  flex: 1;
  min-width: 0;
  display: grid;
  grid-template-columns: clamp(380px, 40vw, 600px) minmax(0, 1fr);
}

/* brand panel — pinned while a long form scrolls beside it */
.tt-auth__brand {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  padding: 44px clamp(32px, 4vw, 64px) 36px;
  display: flex;
  flex-direction: column;
  gap: 40px;
  overflow: hidden auto;
  isolation: isolate;
  background: var(--tt-dark-surface);
  color: var(--tt-on-dark);
  scrollbar-color: rgba(255, 255, 255, 0.22) transparent;   /* if it ever scrolls, not a light Windows bar */
  scrollbar-width: thin;
}

.tt-auth__logo {
  width: 208px;
  height: auto;
}

/* the intro and the panel extras sit together in the middle; the footnote drops to the bottom */
.tt-auth__intro {
  margin-top: auto;
  display: grid;
  justify-items: start;
  gap: 16px;
}

.tt-auth__headline {
  max-width: 20ch;
  margin: 0;
  color: var(--tt-on-dark-strong);
  font-family: var(--tt-font-display);
  font-size: var(--tt-fs-display);
  font-weight: var(--tt-heading-weight);
  letter-spacing: -0.02em;
  line-height: 1.15;
  text-wrap: balance;
}

.tt-auth__lede {
  max-width: 42ch;
  margin: 0;
  color: var(--tt-on-dark);
  font-size: var(--tt-fs-lede);
  line-height: 1.65;
}

.tt-auth__footnote {
  margin: auto 0 0;
  color: var(--tt-on-dark-muted);
  font-size: var(--tt-fs-caption);
}

.tt-auth__brand code {
  background: rgba(255, 255, 255, 0.08);
  color: var(--tt-on-dark-strong);
  font-size: 0.92em;
}

/* sign-in highlights */
.tt-auth-features {
  margin: 0;
  padding: 0;
  display: grid;
  gap: 18px;
  list-style: none;
}

.tt-auth-features li {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}

.tt-auth-features .tt-auth-features__icon {
  width: 40px;
  height: 40px;
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  border-radius: 0.8rem;
  background: rgba(var(--tt-lime-rgb), 0.14);
  box-shadow: inset 0 0 0 1px rgba(var(--tt-lime-rgb), 0.22);
  color: var(--tt-on-dark-accent);
  font-size: 20px;
}

.tt-auth-features strong,
.tt-auth-step__body strong {
  display: block;
  color: var(--tt-on-dark-strong);
  font-size: var(--tt-fs-body);
  font-weight: 600;
  line-height: 1.4;
}

.tt-auth-features small,
.tt-auth-step__body small {
  display: block;
  margin-top: 2px;
  color: var(--tt-on-dark-muted);
  font-size: var(--tt-fs-caption);
  line-height: 1.5;
}

/* setup stepper — numbered markers on a rail; the rail turns lime behind finished steps */
.tt-auth-steps {
  margin: 0;
  padding: 0;
  list-style: none;
}

.tt-auth-step {
  position: relative;
  padding-bottom: 20px;
  display: flex;
  align-items: flex-start;
  gap: 14px;
}

.tt-auth-step:last-child {
  padding-bottom: 0;
}

.tt-auth-step:not(:last-child)::before {
  content: "";
  position: absolute;
  top: 34px;
  bottom: 6px;
  left: 13px;
  width: 2px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.12);
}

.tt-auth-step--done:not(:last-child)::before {
  background: rgba(var(--tt-lime-rgb), 0.5);
}

.tt-auth-step__marker {
  width: 28px;
  height: 28px;
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  border-radius: var(--tt-radius-pill);
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, 0.22);
  color: var(--tt-on-dark-muted);
  font-family: var(--tt-font-display);
  font-size: var(--tt-fs-caption);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.tt-auth-step__marker .material-icons-outlined {
  font-size: 17px;
}

.tt-auth-step--done .tt-auth-step__marker {
  background: var(--tt-lime);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 0.4rem 1rem -0.5rem rgba(var(--tt-lime-rgb), 0.8);
  color: #0b1a11;
}

.tt-auth-step--current .tt-auth-step__marker {
  background: rgba(var(--tt-lime-rgb), 0.14);
  box-shadow: inset 0 0 0 2px var(--tt-on-dark-accent), 0 0 0 4px rgba(var(--tt-lime-rgb), 0.12);
  color: var(--tt-on-dark-accent);
}

.tt-auth-step--blocked .tt-auth-step__marker {
  background: rgba(var(--tt-warning-rgb), 0.16);
  box-shadow: inset 0 0 0 2px rgba(var(--tt-warning-rgb), 0.85);
  color: var(--tt-on-dark-warning);
}

.tt-auth-step__body {
  min-width: 0;
  padding-top: 3px;
}

.tt-auth-step--blocked .tt-auth-step__body small {
  color: var(--tt-on-dark-warning);
}

.tt-auth-step--pending .tt-auth-step__body strong {
  color: var(--tt-on-dark);
}

/* task side: the light canvas, with the card centred */
.tt-auth__main {
  min-width: 0;
  padding: 48px clamp(20px, 4vw, 56px);
  display: flex;
  align-items: center;
  justify-content: center;
}

.tt-auth__card {
  width: 100%;
  max-width: 452px;
  padding: 36px;
}

.tt-auth__header {
  margin-bottom: 28px;
  display: grid;
  justify-items: start;
  gap: 10px;
}

.tt-auth__title {
  margin: 4px 0 0;
  font-size: var(--tt-fs-title);
  letter-spacing: -0.015em;
  line-height: 1.25;
  text-wrap: balance;
}

.tt-auth__subtitle {
  margin: 0;
  color: var(--tt-muted);
  font-size: var(--tt-fs-body);
  line-height: 1.6;
}

.tt-auth__subtitle code {
  font-size: 0.9em;
}

/* the card body — a form or a plain stack, same rhythm either way */
.tt-auth__body {
  display: grid;
  gap: 18px;
}

.tt-auth-field {
  display: grid;
  gap: 8px;
}

.tt-auth-field .form-label {
  margin: 0;
  font-size: var(--tt-fs-label);
}

.tt-auth .form-control {
  min-height: 46px;
  padding: 11px 14px;
  border-radius: var(--tt-radius-btn);
  font-size: var(--tt-fs-lede);
  line-height: 22px;
}

.tt-auth-password {
  position: relative;
}

.tt-auth-password .form-control {
  padding-right: 50px;
}

.tt-auth-password .password-icon {
  right: 5px;
  width: 36px;
  height: 36px;
  margin: 0;
  border-radius: var(--tt-radius-nav);
  transition: background-color var(--tt-dur) var(--tt-ease);
}

.tt-auth-password .password-icon:hover {
  background: rgba(var(--tt-dark-rgb), 0.06);
}

.tt-auth-password .password-icon .material-icons-outlined {
  color: var(--tt-muted);
  font-size: 20px;
}

/* password rules — password_checker.js marks each .valid / .unmet. Unmet stays neutral: nothing turns red
   while the user is still typing; the disabled submit already says the password isn't there yet. */
.tt-auth-rules {
  margin: 2px 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px 16px;
  list-style: none;
}

.tt-auth-rule,
.tt-auth-rule.unmet {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--tt-muted);
  font-size: var(--tt-fs-caption);
  line-height: 1.4;
  transition: color var(--tt-dur) var(--tt-ease);
}

.tt-auth-rule .material-icons-outlined {
  font-size: 16px;
}

.tt-auth-rule .tt-auth-rule__idle {
  color: var(--tt-placeholder);
}

.tt-auth-rule .tt-auth-rule__met {
  display: none;
}

.tt-auth-rule.valid {
  color: var(--tt-primary-ink);
}

.tt-auth-rule.valid .tt-auth-rule__idle {
  display: none;
}

.tt-auth-rule.valid .tt-auth-rule__met {
  display: inline-block;
}

/* the submit matches the fields above it (height and corners), so the form reads as one even column */
body .tt-auth__submit {
  min-height: 46px;
  margin-top: 6px;
  border-radius: var(--tt-radius-btn);
  font-size: var(--tt-fs-body);
}

.tt-auth__alert {
  margin-bottom: 20px;
  padding: 12px 14px;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  border-radius: var(--tt-radius-btn);
  background: rgba(var(--tt-danger-rgb), 0.07);
  box-shadow: inset 0 0 0 1px rgba(var(--tt-danger-rgb), 0.2);
  color: var(--tt-danger-ink);
  font-size: var(--tt-fs-label);
  font-weight: 500;
  line-height: 1.5;
}

.tt-auth__alert > .material-icons-outlined {
  flex-shrink: 0;
  font-size: 20px;
}

.tt-auth__alert strong {
  display: block;
  font-weight: 600;
}

.tt-auth__alert :is(p, ul) {
  margin: 0;
}

.tt-auth__alert ul {
  padding-left: 1.1em;
}

.tt-auth__alert strong + :is(p, ul) {
  margin-top: 2px;
}

.tt-auth__note {
  margin: 20px 0 0;
  color: var(--tt-muted);
  font-size: var(--tt-fs-caption);
  text-align: center;
}

/* address record counts on the paused-setup card */
.tt-auth-records {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.tt-auth-record {
  padding: 12px 14px;
}

.tt-auth-record dt {
  color: var(--tt-muted);
  font-size: var(--tt-fs-caption);
  font-weight: 500;
}

.tt-auth-record dd {
  margin: 2px 0 0;
  color: var(--tt-ink);
  font-family: var(--tt-font-display);
  font-size: var(--tt-fs-heading);
  font-weight: var(--tt-heading-weight);
  font-variant-numeric: tabular-nums;
}

.tt-auth-record--missing dd {
  color: var(--tt-danger-ink);
}

/* App ID with its copy button, on the setup-complete card */
.tt-auth-copy {
  min-height: 46px;
  padding: 5px 5px 5px 14px;
  display: flex;
  align-items: center;
  gap: 10px;
  border: 1px solid rgba(var(--tt-dark-rgb), 0.14);
  border-radius: var(--tt-radius-btn);
  background: rgba(var(--tt-dark-rgb), 0.035);
}

.tt-auth-copy code {
  flex: 1;
  min-width: 0;
  padding: 0;
  background: none;
  color: var(--tt-ink);
  font-size: var(--tt-fs-body);
  overflow-wrap: anywhere;
}

body .tt-auth-copy .btn {
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  padding: 0;
}

/* short desktop windows: tighten the brand panel before it has to scroll */
@media (min-width: 992px) and (max-height: 760px) {
  .tt-auth__brand {
    padding-top: 32px;
    padding-bottom: 28px;
    gap: 28px;
  }

  .tt-auth-step {
    padding-bottom: 14px;
  }
}

/* 150% Windows display scaling on a 1080p laptop leaves ~600px under the browser bars: drop the lede so the
   steps still fit without the panel scrolling */
@media (min-width: 992px) and (max-height: 640px) {
  .tt-auth__lede {
    display: none;
  }

  .tt-auth-step {
    padding-bottom: 10px;
  }
}

/* tablet and down: the brand panel becomes a compact band above the card, so the task comes first */
@media (max-width: 991.98px) {
  .tt-auth {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto 1fr;
  }

  .tt-auth__brand {
    position: relative;
    height: auto;
    padding: 18px 20px 22px;
    flex-flow: row wrap;
    align-content: flex-start;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    overflow: hidden;
  }

  .tt-auth__logo {
    width: 148px;
  }

  .tt-auth__intro {
    margin-top: 0;
  }

  .tt-auth__headline,
  .tt-auth__lede,
  .tt-auth-features,
  .tt-auth__footnote {
    display: none;
  }

  .tt-auth-steps {
    flex-basis: 100%;
  }

  .tt-auth-step {
    padding-bottom: 12px;
  }

  /* only the steps that need attention keep their detail */
  .tt-auth-step:not(.tt-auth-step--blocked) .tt-auth-step__body small {
    display: none;
  }

  .tt-auth__main {
    padding: 24px 16px 72px;
    align-items: flex-start;
  }
}

@media (max-width: 575.98px) {
  .tt-auth__card {
    padding: 26px 20px 24px;
  }

  /* 16px keeps iOS from zooming into the field */
  .tt-auth .form-control {
    font-size: 16px;
  }

  .tt-auth-rules {
    grid-template-columns: minmax(0, 1fr);
  }

  .tt-auth-record {
    padding: 10px;
  }
}

/* ==========================================================================
   Motion — every animation and hover lift is opt-in via no-preference
   ========================================================================== */

/* custom.css animates these unconditionally; neutralise here and re-enable below */
.dash-animate-in {
  opacity: 1;
  animation: none;
}

.animate-scale:hover {
  transform: none;
}

@media (prefers-reduced-motion: no-preference) {
  @keyframes ttIntroUp {
    from {
      opacity: 0;
      transform: translateY(10px);
    }

    to {
      opacity: 1;
      transform: none;
    }
  }

  @keyframes ttPulse {
    0%,
    100% {
      transform: scale(0.72);
    }

    50% {
      transform: scale(1);
    }
  }

  /* buttons lift on hover */
  body .btn:not(:disabled):not(.disabled):hover {
    transform: translateY(-1px);
  }

  body .btn:not(:disabled):not(.disabled):active {
    transform: none;
  }

  /* stat tiles and queue cards lift, with a deeper accent shadow */
  .tt-kpi,
  .dash-kpi-card,
  .dash-mini-card,
  .picklist-queue-item {
    transition: transform var(--tt-dur) var(--tt-ease), box-shadow var(--tt-dur) var(--tt-ease);
  }

  .tt-kpi:hover,
  .dash-kpi-card:hover,
  .dash-mini-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 1.75rem 3rem -1.5rem rgba(var(--tt-accent-rgb, var(--tt-primary-rgb)), 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.7);
  }

  .picklist-queue-item:hover {
    transform: translateY(-3px);
    box-shadow: 0 0 0 1px var(--tt-hairline), 0 1.25rem 2rem -1.25rem rgba(var(--tt-accent-rgb, var(--tt-primary-rgb)), 0.5);
  }

  /* drill-down links nudge their chevron toward what they open */
  .tt-metric__link .material-icons-outlined {
    transition: transform var(--tt-dur) var(--tt-ease);
  }

  .tt-metric__link:hover .material-icons-outlined {
    transform: translateX(2px);
  }

  /* entrances */
  .dash-animate-in {
    animation: ttIntroUp 0.45s var(--tt-ease) both;
    animation-delay: var(--dash-delay, 0ms);
  }

  .tt-auth__card,
  .tt-auth__intro {
    animation: ttIntroUp 0.5s var(--tt-ease) both;
  }

  .tt-auth-features,
  .tt-auth-steps {
    animation: ttIntroUp 0.5s var(--tt-ease) 90ms both;
  }

  .tt-dot--live {
    animation: ttPulse 2s ease-in-out infinite;
  }

  /* a board preview leans in under the pointer (clipped by its view); its label fades in */
  .tt-screen__view > img,
  .tt-screen__label {
    transition: transform var(--tt-dur) var(--tt-ease), opacity var(--tt-dur) var(--tt-ease);
  }

  button.tt-screen:hover .tt-screen__view > img {
    transform: scale(1.03);
  }

  /* the switch knob slides across its track */
  .tt-switch {
    transition: background-position var(--tt-dur) var(--tt-ease), background-color var(--tt-dur) var(--tt-ease),
      border-color var(--tt-dur) var(--tt-ease);
  }

  /* illustrated empty states: the scene settles in, then idles — the sheet bobs, the magnifier hunts,
     sparkles twinkle out of step */
  @keyframes ttFloat {
    from {
      transform: translateY(0);
    }

    to {
      transform: translateY(-5px);
    }
  }

  @keyframes ttSearch {
    0%,
    100% {
      transform: translate(0, 0);
    }

    25% {
      transform: translate(-8px, -6px);
    }

    50% {
      transform: translate(-14px, 1px);
    }

    75% {
      transform: translate(-6px, 6px);
    }
  }

  @keyframes ttTwinkle {
    0%,
    100% {
      opacity: 1;
      transform: scale(1);
    }

    50% {
      opacity: 0.35;
      transform: scale(0.6);
    }
  }

  @keyframes ttTvSearchRing {
    from {
      opacity: 0.75;
      transform: translate(-50%, -50%) scale(0.6);
    }

    to {
      opacity: 0;
      transform: translate(-50%, -50%) scale(4.2);
    }
  }

  @keyframes ttTvSearchFloat {
    0%,
    100% {
      transform: translateY(0);
    }

    50% {
      transform: translateY(-3px);
    }
  }

  .tt-tv-search__radar .material-icons-outlined {
    animation: ttTvSearchFloat 1.4s ease-in-out infinite;
  }

  .tt-tv-search__rings,
  .tt-tv-search__rings::before,
  .tt-tv-search__rings::after {
    animation: ttTvSearchRing 1.8s ease-out infinite;
  }

  .tt-state--illustrated {
    animation: ttIntroUp 0.45s var(--tt-ease) both;
  }

  .tt-art-float {
    animation: ttFloat 2.6s ease-in-out infinite alternate;
  }

  .tt-art-search {
    animation: ttSearch 5s ease-in-out infinite;
  }

  .tt-art-spark {
    transform-box: fill-box;
    transform-origin: center;
    animation: ttTwinkle 2.4s ease-in-out infinite;
  }

  .tt-art-spark--late {
    animation-delay: 1.2s;
  }

  /* rail tooltips and flyouts fade in place; visibility waits for the fade-out before hiding */
  .app.sidebar-rail .app-menu > ul > li > a > .menu-label,
  .app.sidebar-rail .app-menu > ul > li > ul.sub-menu {
    transition: opacity 140ms var(--tt-ease), transform 140ms var(--tt-ease), visibility 0s linear 140ms;
  }

  .app.sidebar-rail .app-menu > ul > li:is(:hover, :focus-within) > ul.sub-menu {
    transition-delay: 0s;
  }
}

/* ==========================================================================
   Responsive
   ========================================================================== */

@media (max-width: 1199px) {
  .app.menu-dark.full-width-header .app-sidebar .logo {
    border-bottom-color: #14301f;
    background: var(--tt-dark-surface);
  }

  /* here the sidebar is off-screen by default and .sidebar-hidden slides it in */
  .app.menu-dark.full-width-header:not(.sidebar-hidden) .app-sidebar .logo {
    border-bottom-color: var(--tt-hairline);
    background: #fff;
  }
}

/* a page's subnav becomes chips above the content. They wrap rather than scroll sideways, which a mouse on
   Windows can only do with shift + wheel. */
@media (max-width: 991.98px) {
  .tt-subnav-layout {
    grid-template-columns: minmax(0, 1fr);
  }

  .tt-subnav {
    position: static;
    padding: 0.4rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
  }
}

@media (max-width: 767.98px) {
  :root {
    --tt-gutter: 16px;
  }

  .tt-displays__grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .dt-search input[type="search"] {
    width: 100%;
  }

  /* narrow screens: the breadcrumb shows just the current page */
  .app-header-breadcrumb .breadcrumb-item:not(:last-child) {
    display: none;
  }

  .app-header-breadcrumb .breadcrumb-item + .breadcrumb-item {
    padding-left: 0;
  }

  .app-header-breadcrumb .breadcrumb-item:last-child::before {
    display: none;
  }
}

@media (max-width: 576px) {
  :root {
    --tt-gutter: 12px;
    --tt-radius-card: 1rem;
  }

  .app-container {
    padding: 16px var(--tt-gutter) 48px;
  }

  .app-content .card .card-header {
    padding: 1.1rem 1.15rem 0.7rem;
  }

  .app-content .card .card-body {
    padding: 1.15rem;
  }

  /* summary tiles pair up instead of stacking four deep */
  .tt-stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.6rem;
  }

  .tt-stat {
    padding: 0.8rem 0.85rem;
  }

  /* settings rows keep in line with the tighter card padding above */
  .tt-setting-list {
    --tt-setting-pad-x: 1.15rem;
  }

  .tt-page-header {
    padding: 1.15rem;
  }

  .tt-page-header .tt-heading > .tt-tile {
    width: 46px;
    height: 46px;
    font-size: 1.4rem;
  }
}

/* ==========================================================================
   Windows contrast themes (forced colors) — fills and shadows are stripped, so anything that showed state
   with a tinted fill or an inset ring gets a real outline or border in a system colour instead
   ========================================================================== */

@media (forced-colors: active) {
  /* the current page, in the sidebar, the icon rail and its flyouts */
  .app.menu-dark .app-menu > ul > li.open > a.active,
  .app.menu-dark .app-menu > ul > li ul li a.active,
  .app.menu-dark.sidebar-rail .app-menu > ul > li:has(> ul a.active) > a {
    outline: 2px solid Highlight;
    outline-offset: -2px;
  }

  .app.sidebar-rail .app-menu > ul > li > a > .menu-label,
  .tt-auth__alert {
    border: 1px solid CanvasText;
  }

  /* setup stepper: ring every marker, the current one in the highlight colour, and keep the rail between them */
  .tt-auth-step__marker {
    border: 2px solid CanvasText;
  }

  .tt-auth-step--current .tt-auth-step__marker {
    border-color: Highlight;
  }

  .tt-auth-step:not(:last-child)::before {
    background: GrayText;
    forced-color-adjust: none;
  }

  .tt-auth-step--done:not(:last-child)::before {
    background: CanvasText;
  }

  /* empty-state scenes are drawn in tints a contrast theme strips; the title and hint carry the message */
  .tt-state__art {
    display: none;
  }

  /* the switch's knob is a background image the theme strips, so hand it back to the native checkbox */
  .tt-switch {
    width: 18px;
    height: 18px;
    -webkit-appearance: auto;
    appearance: auto;
  }

  .tt-subnav__link:is([aria-current="true"], [aria-current="page"]) {
    outline: 2px solid Highlight;
    outline-offset: -2px;
  }
}

/* ==========================================================================
   Solid fallbacks — no backdrop-filter, or the user asked for less transparency / more contrast
   ========================================================================== */

@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  :root {
    --tt-surface-frost: #fff;
  }
}

@media (prefers-reduced-transparency: reduce), (prefers-contrast: more) {
  :root {
    --tt-surface-frost: #fff;
    --tt-frost-filter: none;
    --tt-hairline: rgba(var(--tt-dark-rgb), 0.16);
    --tt-surface-border: rgba(var(--tt-dark-rgb), 0.12);
    --tt-card-border: rgba(var(--tt-dark-rgb), 0.16);
  }

  .modal-backdrop {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}
