/* ==========================================================================
   Enterprise Design System — global override layer.
   Loaded last (see index.html) so it wins the cascade over carbon-components,
   carbon-overrides, app.css and base.css without needing !important except
   where legacy rules already use !important themselves.

   Token source: "minimal CRM / sales workspace" spec (v2). Where a token
   below has both a spec name (--bg-app) and an --xpa-* alias, the --xpa-*
   name is what the component rules in this file consume — aliasing keeps
   the spec's literal variable names available for future reference/copy-paste
   without having to rewrite every rule below when tokens are refined again.
   ========================================================================== */

:root {
  /* ---- v2 spec token NAMES, kept because ~25 rules below still reference
     them directly — their VALUES now equal the v5 equivalents below, so
     every reference (aliased or direct) resolves to the same palette
     instead of colors coexisting across iterations. ---- */
  --bg-app: #f8f7f5;
  --bg-sidebar: #f6f4f1;
  --bg-surface: #ffffff;
  --bg-subtle: #faf9f7;
  --bg-hover: #f4f2ee;
  --bg-selected: #ffffff;

  --border-subtle: #f0ece8;
  --border-default: #e7e2dc;
  --border-strong: #d8d2cb;

  --text-primary: #23201c;
  --text-secondary: #5f5a54;
  --text-tertiary: #8a847c;
  --text-disabled: #bdb6ae;
  --text-link: var(--link);

  --brand-yellow: #c78318;
  --brand-yellow-soft: #fcf6e8;
  --brand-yellow-border: #eecf98;

  --blue: #111111;
  --blue-soft: #f0f0f0;
  --blue-border: #d9d9d9;

  --pink: #c94a4a;
  --pink-soft: #fbecec;
  --pink-border: #e9c2c2;

  --charcoal: #111111;

  --shadow-shell: 0 1px 3px rgba(35, 32, 28, 0.08), 0 8px 24px rgba(35, 32, 28, 0.06);
  --shadow-menu: 0 4px 12px rgba(35, 32, 28, 0.06);

  /* ---- v5 spec tokens (verbatim names) — refines v4's earthy direction
     with exact values, and reverses one structural call: the sidebar is
     now LIGHT (near-invisible against the app background) rather than a
     dark espresso surface, and links are decoupled from the terracotta
     accent entirely — orange is reserved for buttons, active nav, and
     badges only. ---- */
  --canvas: #f8f7f5;
  --surface: #ffffff;
  --surface-subtle: #faf9f7;
  --surface-muted: #f5f3f0;
  --surface-hover: #f4f2ee;

  --nav-bg: #f6f4f1;
  --nav-hover: #f2eee9;
  --nav-active: #efe9e2;
  --nav-text: #49443d;
  --nav-text-active: #23201c;
  --nav-icon: #7a736b;

  --ink: #23201c;
  --ink-secondary: #5f5a54;
  --ink-tertiary: #8a847c;
  --ink-disabled: #bdb6ae;

  --border: #e7e2dc;
  --border-strong-v3: #d8d2cb;

  --primary: #111111;
  --primary-hover: #2b2b2b;
  --primary-soft: #f0f0f0;
  --primary-border: #d9d9d9;

  --link: #3d4d68;
  --link-hover: #2f425f;
  --link-visited: #5a6577;

  --success: #2f8f57;
  --success-soft: #edf8f0;
  --warning: #c78318;
  --warning-soft: #fcf6e8;
  --danger: #c94a4a;
  --danger-soft: #fbecec;
  --info: #4f6d95;
  --info-soft: #eef3f9;

  --shadow-sm: 0 1px 2px rgba(35, 32, 28, 0.05);
  --shadow-md: 0 4px 12px rgba(35, 32, 28, 0.07);
  --shadow-lg: 0 16px 36px rgba(35, 32, 28, 0.10);
  --shadow-focus: 0 0 0 3px rgba(17, 17, 17, 0.16);

  --radius-xs: 4px;
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --radius-xl: 18px;
  --radius-pill: 999px;

  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;

  --font-sans: 'Sora', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  /* Was a distinct 'Blinker' — retired in favor of one font for both
     headings and body text. Aliased to --font-sans (not a duplicate literal
     stack) so the two can never drift apart again. */
  --font-heading: var(--font-sans);

  --font-size-xs: 11px;
  --font-size-sm: 12px;
  --font-size-md: 13px;
  --font-size-base: 14px;
  --font-size-lg: 16px;
  --font-size-xl: 20px;

  --line-xs: 16px;
  --line-sm: 18px;
  --line-md: 20px;
  --line-base: 22px;
  --line-lg: 24px;
  --line-xl: 28px;

  /* ---- Aliases consumed by the component rules below (now pointed at the
     v3 tokens — warm neutral canvas, graphite nav, indigo accent) ---- */
  --xpa-bg-page: var(--canvas);
  --xpa-bg-surface: var(--surface);
  --xpa-bg-nav: var(--nav-bg);
  --xpa-bg-header: var(--surface);
  --xpa-bg-hover: var(--surface-hover);
  --xpa-bg-selected: var(--surface);

  --xpa-border-default: var(--border);
  --xpa-border-light: var(--border);
  --xpa-border-focus: var(--border-strong-v3);

  --xpa-text-primary: var(--ink);
  --xpa-text-secondary: var(--ink-secondary);
  --xpa-text-muted: var(--ink-tertiary);
  --xpa-text-disabled: var(--ink-disabled);

  /* Primary CTA fill is a warm dark GREY, not the near-black --primary —
     matches swacch_tron, whose primary buttons take --primary-strong off a
     mid dark-grey tenant primary. (--primary #111 stays as the accent below
     and elsewhere.) */
  --xpa-btn-primary-bg: #4c4842;
  --xpa-btn-primary-bg-hover: #3b3833;
  --xpa-accent-blue: var(--primary);
  --xpa-accent-blue-hover: var(--primary-hover);
  --xpa-accent-blue-tint: var(--primary-soft);
  --xpa-accent-purple: #8B6EF5;
  --xpa-accent-green: var(--success);
  --xpa-accent-yellow: var(--warning);
  --xpa-accent-red: var(--danger);
  --xpa-accent-pink: var(--pink);

  --xpa-font-sans: var(--font-sans);
  --xpa-font-heading: var(--font-heading);

  --xpa-radius-sm: var(--radius-md);
  --xpa-radius-md: var(--radius-lg);
  --xpa-radius-lg: var(--radius-xl);

  --xpa-shadow-sm: var(--shadow-sm);
  --xpa-shadow-md: var(--shadow-md);

  --xpa-space-1: var(--space-1);
  --xpa-space-2: var(--space-2);
  --xpa-space-3: var(--space-3);
  --xpa-space-4: var(--space-4);
  --xpa-space-6: var(--space-6);
  --xpa-space-8: var(--space-8);
  --xpa-space-10: var(--space-10);
  --xpa-space-12: 48px;
  --xpa-space-16: 64px;

  --xpa-motion-duration: 150ms;
  --xpa-motion-ease: cubic-bezier(0, 0, 0.38, 0.9);

  /* Height the old fixed top header used to reserve. 0 at >=1024px, where
     the persistent sidebar shell replaces it entirely (see App shell
     section below) — components with layout math built around the old
     header height read this var instead of a hardcoded 48px. */
  --xpa-legacy-header-offset: 48px;
}
@media (min-width: 1024px) {
  :root { --xpa-legacy-header-offset: 0px; }
}

/* ==== Base / typography =================================================== */

html,
body {
  background-color: var(--xpa-bg-page) !important;
  color: var(--xpa-text-primary);
  font-family: var(--xpa-font-sans) !important;
  font-size: var(--font-size-base);
  line-height: var(--line-base);
  -webkit-font-smoothing: antialiased;
}

/* Global slim scrollbar — previously only the sidebar had a custom
   scrollbar; everywhere else (page content, modals, dropdowns) still
   showed the browser's default chunky one. */
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
  background: transparent;
}
::-webkit-scrollbar-track {
  background-color: transparent;
}
::-webkit-scrollbar-thumb {
  background-color: rgba(35, 32, 28, 0.2);
  border-radius: 6px;
}
::-webkit-scrollbar-thumb:hover {
  background-color: rgba(35, 32, 28, 0.35);
}

input,
select,
textarea,
button,
.bx--btn,
.bx--text-input,
.bx--select-input,
.bx--dropdown,
.form-control {
  font-family: var(--xpa-font-sans) !important;
}

/* app.css has `body *{font-family:'Heebo', sans-serif!important}` — a
   universal descendant selector with the same (0,0,1) specificity as any
   single-tag rule, so a plain `body{font-family:...!important}` above only
   wins for the body element itself; every OTHER element inherits nothing
   because this legacy rule gives it an explicit value of its own that
   inheritance can't override. Mirroring the same selector shape here,
   loaded later, is the only way to actually win the tie everywhere.
   (.fa/.fas icon-font classes are unaffected — class selectors outrank
   this by specificity regardless of load order.) */
body * {
  font-family: var(--xpa-font-sans) !important;
}

/* base.css's heading-font rule matches via `.h1`-`.h6` Bootstrap utility
   classes (commonly applied to non-heading tags throughout this app) at
   (0,1,0) specificity, which otherwise beats a plain `h1`-`h6` tag
   selector at (0,0,1) regardless of load order. Matching the exact same
   selector shape (tags + .h1-.h6 classes + .bx--modal-header__heading)
   guarantees this rule is never less specific than the one it needs to
   beat, so later source order can actually decide the tie. */
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6,
.bx--modal-header__heading,
.xpa-page-title, .xpa-section-title, .xpa-card-title {
  font-family: var(--xpa-font-heading) !important;
  font-weight: 600;
  letter-spacing: -0.01em;
  /* base.css's competing rule sets color:black!important — needs !important
     here too, since equal specificity + important-vs-not always loses to
     the important side regardless of source order. */
  color: var(--xpa-text-primary) !important;
}

/* Page title 24/30 600, section/item title 12-13/18 600 (spec section 4) */
h1 { font-size: var(--font-size-xl); line-height: var(--line-xl); }
/* Applied on .xpa-page-title itself (not a page-specific override) so it
   takes effect everywhere the shared PageTitle component renders. */
.xpa-page-title { font-size: 20px; line-height: 30px; font-weight: 600; letter-spacing: -0.02em; text-transform: capitalize; }
h2, .xpa-section-title { font-size: var(--font-size-lg); line-height: var(--line-lg); }
h3, .xpa-card-title { font-size: var(--font-size-md); line-height: var(--line-md); font-weight: 600; }

small, .xpa-text-small { font-size: var(--font-size-xs); font-weight: 500; color: var(--xpa-text-muted); }
.xpa-text-secondary { color: var(--xpa-text-secondary) !important; }
.xpa-text-muted { color: var(--xpa-text-muted) !important; }

/* `--blue` (#111111) was long ago repurposed for button theming, not an
   actual blue — its own `#2878e6` fallback here never applied, since a
   CSS var() fallback only kicks in when the variable is undefined, not
   just "not blue". --link/--link-hover/--link-visited (a deliberately
   muted slate-blue family, consistent with this app's restrained earthy
   palette rather than a saturated web-standard blue) already exist for
   exactly this and were sitting unused — using them here instead. */
/* Scope the blanket link colour so it never repaints a link that is styled as
   a button (<Link className="bx--btn ...">, Bootstrap .btn, or the app's
   .xpa-auth__sso-btn). Without the :not() guards the `!important` here beat
   `.bx--btn--primary { color:#fff }`, leaving slate-blue text on a near-black
   fill — e.g. the "Go to dashboard" button on the NotFound page. */
a:not(.bx--btn):not(.btn):not(.xpa-btn-reset),
.xpa-link {
  color: var(--link, #3d4d68) !important;
  cursor: pointer !important;
  text-decoration: none !important;
}
a:not(.bx--btn):not(.btn):not(.xpa-btn-reset):hover,
.xpa-link:hover {
  color: var(--link-hover, #2f425f) !important;
}
/* Links-as-buttons: keep the variant's own label colour and Carbon's own
   cursor/decoration. */
a.bx--btn,
a.btn {
  text-decoration: none !important;
  cursor: pointer !important;
}
a.bx--btn--primary,
a.bx--btn--primary:hover,
a.bx--btn--primary:focus,
a.bx--btn--danger,
a.bx--btn--danger:hover {
  color: #fff !important;
}
a.bx--btn--secondary,
a.bx--btn--tertiary,
a.bx--btn--ghost,
a.bx--btn--secondary:hover,
a.bx--btn--tertiary:hover,
a.bx--btn--ghost:hover {
  color: var(--xpa-text-primary) !important;
}

/* ==== Focus ================================================================= */

:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}

/* ==== Buttons ============================================================== */
/* Primary = dark charcoal fill (spec section 13). Gold is reserved for
   creation/onboarding moments only, applied per-component, not globally. */

/* min-height (not height) so content/icons can't force the row taller than
   the box — 40px default, 32px for --sm, noticeably more substantial than
   the 32px this used to be everywhere. */
.bx--btn {
  min-height: 40px;
  padding: 6px 14px;
  border-radius: var(--radius-md);
  font-weight: 600;
  font-size: var(--font-size-base);
  box-shadow: none;
  transition: background-color var(--xpa-motion-duration) var(--xpa-motion-ease),
              border-color var(--xpa-motion-duration) var(--xpa-motion-ease),
              box-shadow var(--xpa-motion-duration) var(--xpa-motion-ease);
}
.bx--btn--sm {
  min-height: 32px;
  padding: 4px 12px;
  font-size: var(--font-size-md);
}
/* Carbon absolutely-positions a button's icon and reserves 36-60px of
   padding on that side to make room for it — flowing the icon inline
   instead (matching how every non-icon-only button here actually renders
   its icon) removes that reserved gap and lets padding stay symmetric. */
.bx--btn:not(.bx--btn--icon-only) .bx--btn__icon {
  position: static;
  margin-inline-start: 8px;
  flex-shrink: 0;
}
.bx--btn--primary {
  background-color: var(--xpa-btn-primary-bg);
  border-color: var(--xpa-btn-primary-bg);
  color: #fff;
  /* Subtle depth instead of a flat fill — the primary action should read
     as slightly raised, not pasted onto the page. */
  box-shadow: 0 1px 2px rgba(17, 17, 17, 0.18);
}
.bx--btn--primary:hover { background-color: var(--xpa-btn-primary-bg-hover); }
.bx--btn--secondary,
.bx--btn--tertiary,
.bx--btn--ghost {
  background-color: #fff;
  border: 1px solid var(--xpa-border-default);
  color: var(--xpa-text-primary);
}
/* Carbon ships its own :hover/:focus/:active rules for these variants that
   force white (or IBM-blue) text and, on :focus, an IBM-blue fill — none of
   which our light override touches, so a hovered/focused secondary/tertiary/
   ghost button ends up white-on-near-white (invisible label) or bright blue.
   Pin the text colour, fill and border for every interactive state, and drop
   Carbon's inset white focus box-shadow (the real focus ring is restored for
   keyboard users just below). */
.bx--btn--secondary:hover,
.bx--btn--secondary:focus,
.bx--btn--secondary:active,
.bx--btn--tertiary:hover,
.bx--btn--tertiary:focus,
.bx--btn--tertiary:active,
.bx--btn--ghost:hover,
.bx--btn--ghost:focus,
.bx--btn--ghost:active {
  background-color: var(--xpa-bg-hover);
  border-color: var(--border-strong);
  color: var(--xpa-text-primary);
  box-shadow: none;
  outline: none;
}
.bx--btn--primary:focus-visible,
.bx--btn--secondary:focus-visible,
.bx--btn--tertiary:focus-visible,
.bx--btn--ghost:focus-visible,
.bx--btn--danger:focus-visible {
  box-shadow: var(--shadow-focus);
  outline: none;
}
.bx--btn--secondary .bx--btn__icon,
.bx--btn--secondary .bx--btn__icon path,
.bx--btn--tertiary .bx--btn__icon,
.bx--btn--tertiary .bx--btn__icon path,
.bx--btn--ghost .bx--btn__icon,
.bx--btn--ghost .bx--btn__icon path {
  fill: currentColor;
}
.bx--btn--danger,
.bx--btn--danger--primary {
  background-color: var(--xpa-accent-red);
  border-color: var(--xpa-accent-red);
  color: #fff;
}
.bx--btn--danger:hover,
.bx--btn--danger:focus,
.bx--btn--danger:active,
.bx--btn--danger--primary:hover,
.bx--btn--danger--primary:focus,
.bx--btn--danger--primary:active {
  background-color: #b23b3b;
  border-color: #b23b3b;
  color: #fff;
}
/* Primary keeps its white label in every state (Carbon's hover only swaps the
   fill, but be explicit so nothing downstream can wash it out). */
.bx--btn--primary:hover,
.bx--btn--primary:focus,
.bx--btn--primary:active {
  color: #fff;
}

.btn {
  border-radius: var(--radius-md) !important;
  min-height: 40px;
  padding: 6px 14px !important;
  font-weight: 600;
  font-size: var(--font-size-sm);
  box-shadow: none !important;
  transition: background-color var(--xpa-motion-duration) var(--xpa-motion-ease),
              border-color var(--xpa-motion-duration) var(--xpa-motion-ease);
}
.btn-primary {
  background-color: var(--xpa-btn-primary-bg) !important;
  border-color: var(--xpa-btn-primary-bg) !important;
}
.btn-primary:hover { background-color: var(--xpa-btn-primary-bg-hover) !important; }
.btn-default,
.btn-secondary,
.btn-light {
  background-color: #fff !important;
  border: 1px solid var(--xpa-border-default) !important;
  color: var(--xpa-text-primary) !important;
}
.btn-default:hover,
.btn-secondary:hover,
.btn-light:hover {
  background-color: var(--xpa-bg-hover) !important;
  border-color: var(--border-strong) !important;
}
.btn-danger {
  background-color: var(--xpa-accent-red) !important;
  border-color: var(--xpa-accent-red) !important;
}
.btn-success {
  background-color: var(--xpa-accent-green) !important;
  border-color: var(--xpa-accent-green) !important;
}

/* Compact outline button (spec section 8) — opt-in via .button-compact */
.button-compact {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 28px;
  padding: 0 10px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  background: #fff;
  color: #40403d;
  font-size: var(--font-size-sm);
  font-weight: 500;
}
.button-compact:hover {
  background: var(--bg-hover);
  border-color: var(--border-strong);
}

/* ==== Inputs ================================================================ */

.bx--text-input,
.bx--text-area,
.bx--select-input,
.bx--dropdown,
.bx--number input[type='number'],
.bx--search-input,
.bx--date-picker__input {
  min-height: 36px;
  border-radius: var(--radius-md);
  border: 1px solid var(--xpa-border-default);
  background-color: #fff;
  font-size: var(--font-size-base);
  color: var(--xpa-text-primary);
}
.bx--text-area { height: auto; }
.bx--text-input::placeholder,
.bx--text-area::placeholder,
.bx--date-picker__input::placeholder { color: var(--xpa-text-muted); }
/* carbon-components-react 7.60.5 renders `.bx--text-input__field-outer-wrapper`
   around every <TextInput>, but the vendored (older) carbon-components.min.css
   has no rule for it — so under `.bx--form-item { align-items: flex-start }`
   it shrink-wraps and the input collapses to its intrinsic ~20rem width and
   clips its value (seen in every form modal). Give it, and the inner wrapper,
   a real width. The `--inline` TextInput variant opts out on purpose. */
.bx--text-input__field-outer-wrapper:not(.bx--text-input__field-outer-wrapper--inline),
.bx--text-input__field-outer-wrapper:not(.bx--text-input__field-outer-wrapper--inline) .bx--text-input__field-wrapper {
  width: 100%;
}
.bx--text-input:focus,
.bx--text-area:focus,
.bx--select-input:focus,
.bx--dropdown:focus-within,
.bx--search-input:focus,
.bx--date-picker__input:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: var(--shadow-focus);
}
/* Search — a hover state distinct from focus, plus the magnifier/clear
   icons, which had no
   styling anywhere in this file before (Carbon's own defaults render
   them in raw black). */
.bx--search-input:hover:not(:focus):not(:disabled) {
  border-color: var(--xpa-border-hover, #d8d2ca);
}
.bx--search .bx--search-magnifier {
  fill: var(--xpa-text-muted);
}
.bx--search .bx--search-close {
  border-radius: var(--radius-sm);
}
.bx--search .bx--search-close:hover {
  background-color: var(--xpa-bg-hover);
}
.bx--search .bx--search-close svg {
  fill: var(--xpa-text-secondary);
}
/* Disabled — Carbon's own greys the field but doesn't match our palette.
   Non-native disabled patterns (Carbon Dropdown/ComboBox, react-select)
   can't use :disabled at all — see the dedicated "Disabled" section
   further down for those. */
.bx--text-input:disabled,
.bx--text-area:disabled,
.bx--select-input:disabled,
.bx--search-input:disabled,
.bx--date-picker__input:disabled,
.form-control:disabled,
.form-input:disabled {
  background-color: var(--bg-subtle) !important;
  color: var(--xpa-text-disabled) !important;
  border-color: var(--border-subtle) !important;
  cursor: not-allowed;
}
/* Invalid/error state — this app uses two different hooks for it: Carbon's
   own `invalid` prop (renders .bx--text-input--invalid, which by default
   is IBM red #da1e28, not our --danger token) and a plain `.invalid`
   class applied ad hoc to inputs/wrappers throughout the codebase
   (confirmed via grep — .invalid-msg/.xpa-error-message render the actual
   error text below the field). Neither had any custom styling before. */
.bx--text-input--invalid,
.bx--text-input.invalid,
.bx--text-area.invalid,
.bx--select-input.invalid,
.bx--date-picker__input.invalid {
  outline: none !important;
  border: 2px solid var(--danger) !important;
  box-shadow: none !important;
}
.invalid-msg,
.xpa-error-message {
  margin-top: 4px;
  color: var(--danger);
  font-size: var(--font-size-xs);
  font-weight: 500;
}

/* react-datepicker (the standalone library, separate from Carbon's own
   DatePicker — both are used in this app) */
.react-datepicker-wrapper .react-datepicker__input-container input {
  min-height: 36px;
  border-radius: var(--radius-md);
  border: 1px solid var(--xpa-border-default);
  background-color: #fff;
  font-size: var(--font-size-base);
  color: var(--xpa-text-primary);
  padding: 0 12px;
}
.react-datepicker-wrapper .react-datepicker__input-container input:focus,
.react-datepicker-wrapper .react-datepicker__input-container input:active {
  outline: none;
  border-color: var(--blue);
  box-shadow: var(--shadow-focus);
}

/* Carbon's ComboBox (a text-input-with-dropdown, distinct from plain
   Dropdown/Select) nests three layers — .bx--list-box wraps
   .bx--list-box__field wraps an actual .bx--text-input used for the
   typed search text. Verified by rendering ComboBox directly: that inner
   element really is .bx--text-input, so the generic input rule above
   was styling it too — a second background/border/radius independently
   of the outer wrapper produced a visible "box inside a box", and on
   focus BOTH layers added their own indicator (this rule's border-color
   + box-shadow on the inner input, plus Carbon's own separate 2px blue
   outline on .bx--list-box__field), stacking into one thick dark ring
   instead of the single soft one every other input gets. */
.bx--list-box {
  min-height: 36px;
  height: auto;
  max-height: none;
  border-radius: var(--radius-md);
  border: 1px solid var(--xpa-border-default);
  background-color: #fff;
}
.bx--list-box__field {
  height: auto;
  min-height: 36px;
}
.bx--list-box__field:focus {
  outline: none !important;
}
.bx--list-box .bx--text-input {
  min-height: auto;
  border: none !important;
  border-radius: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
}
.bx--list-box:focus-within {
  border-color: var(--blue);
  box-shadow: var(--shadow-focus);
}

.form-control {
  min-height: 36px !important;
  border-radius: var(--radius-md) !important;
  border: 1px solid var(--xpa-border-default) !important;
  box-shadow: none !important;
  font-size: var(--font-size-base);
  color: var(--xpa-text-primary) !important;
}
.form-control::placeholder { color: var(--xpa-text-muted) !important; }
.form-control:focus {
  border-color: var(--blue) !important;
  box-shadow: var(--shadow-focus) !important;
}

/* Legacy TextBox/.form-input pattern (components/common/common.js's
   TextBox/SelectDropdown helpers, used by SignUp, Admin Office/Company
   forms) — `.form-input` (src/styles/layout/_custom-b.scss) only sets
   font-family/color/margin, no box styling at all, so these inputs and
   the two raw <textarea className="form-input"> fields in
   Admin/Office.js + Admin/Company.js were still rendering as bare
   browser-default fields after every other input pattern got restyled. */
.form-input {
  display: block;
  width: 100%;
  min-height: 36px;
  padding: 6px 12px;
  border-radius: var(--radius-md);
  border: 1px solid var(--xpa-border-default);
  background-color: #fff;
  font-size: var(--font-size-base);
  color: var(--xpa-text-primary);
}
textarea.form-input { height: auto; }
.form-input::placeholder { color: var(--xpa-text-muted); }
.form-input:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: var(--shadow-focus);
}
.has-error .form-input {
  border: 2px solid var(--danger) !important;
  box-shadow: none !important;
}
.form-input-hint {
  margin-top: 4px;
  color: var(--danger);
  font-size: var(--font-size-xs);
  font-weight: 500;
}

label { color: var(--xpa-text-secondary); font-size: var(--font-size-sm); font-weight: 500; }

/* react-virtualized-select (v1-style API, separate from react-select
   below — both libraries are used in this app) */
.Select-control {
  border-radius: var(--radius-md) !important;
  border-color: var(--xpa-border-default) !important;
  min-height: 32px !important;
  box-shadow: none !important;
}
.Select.is-focused > .Select-control {
  border-color: var(--blue) !important;
  box-shadow: var(--shadow-focus) !important;
}

/* react-select v2 — 9 files use this library and are inconsistent about
   setting classNamePrefix (none, "", or "xrs" depending on the file), so
   targeting an exact classname would miss most of them. Verified instead
   (by actually rendering the installed version) that react-select always
   emits its emotion-generated class — e.g. "css-bg1rzq-control" — even
   when a classNamePrefix is also set (it just adds BEM classes alongside,
   never replacing the hash one). Substring-matching that stable
   "-control"/"-menu"/etc. suffix therefore works identically across every
   usage in the app with zero JSX changes. !important throughout because
   react-select computes a lot of this via emotion's own injected
   stylesheet, which our plain load-order otherwise can't reliably beat. */
[class*="-container"] [class*="-control"] {
  min-height: 36px !important;
  border-radius: var(--radius-md) !important;
  border: 1px solid var(--xpa-border-default) !important;
  background-color: #fff !important;
  box-shadow: none !important;
}
[class*="-container"] [class*="-control"]:hover {
  border-color: var(--border-strong) !important;
}
/* :focus-within fires whenever the control's own internal <input> has focus
   — native, so it works regardless of how react-select tracks focus state.
   Keyed on the control (`-container > -control`), NOT on the container:
   `[class*="-container"]` also substring-matches `.bx--modal-container`,
   `.bx--data-table-container`, `.sui-facet-container` etc., so
   `[class*="-container"]:focus-within` would light up EVERY react-select in
   any such wrapper the moment any unrelated field inside it took focus. */
[class*="-container"] > [class*="-control"]:focus-within {
  border-color: var(--blue) !important;
  box-shadow: var(--shadow-focus) !important;
}
[class*="-placeholder"],
[class*="-singleValue"],
[class*="-single-value"] {
  color: var(--xpa-text-muted) !important;
}
[class*="-menu"] {
  border-radius: var(--radius-md) !important;
  border: 1px solid var(--xpa-border-default) !important;
  box-shadow: var(--shadow-md) !important;
  overflow: hidden;
}
[class*="-option"] {
  font-size: var(--font-size-base) !important;
}
[class*="-option"]:hover,
[class*="-option"][class*="isFocused"],
[class*="-option"][class*="is-focused"] {
  background-color: var(--xpa-bg-hover) !important;
  color: var(--xpa-text-primary) !important;
}
[class*="-option"][class*="isSelected"],
[class*="-option"][class*="is-selected"] {
  background-color: var(--xpa-btn-primary-bg) !important;
  color: #ffffff !important;
}
[class*="-multiValue"],
[class*="-multi-value"] {
  border-radius: var(--radius-sm) !important;
  background-color: var(--bg-subtle) !important;
}
[class*="-indicatorSeparator"],
[class*="-indicator-separator"] {
  background-color: var(--xpa-border-default) !important;
}
/* react-select's internal typing input (used for search/filter/create-
   option text) is a plain, mostly class-less <input> nested inside the
   control — normally invisible (react-select inlines width:1px;border:0
   on it directly). Reported as a visible "gray box inside the field" in
   one usage of this app; couldn't pin down the exact conflicting rule
   across the ~9 files/3 different classNamePrefix configurations that
   render this component, so neutralizing it directly and robustly here
   instead, wherever it ends up nested. */
[class*="-container"] input,
[class*="-control"] input {
  border: none !important;
  background: transparent !important;
  box-shadow: none !important;
  outline: none !important;
}

/* ==== Checkboxes / radios / toggles =========================================
   This app's own extension of the same token system used elsewhere in this
   file, applied to Carbon's stock checkbox/radio/toggle styling. */
.bx--checkbox-label::before {
  border-color: var(--xpa-border-default);
  border-radius: 4px;
}
/* :not(:disabled) matters here because these rules are !important — without
   it they'd beat Carbon's own (non-!important, but MORE specific thanks to
   its extra :disabled) checked+disabled rule anyway on specificity, but
   !important ignores specificity entirely and would win regardless, making
   a disabled+checked checkbox render in full primary color instead of
   Carbon's intended grey. Verified against carbon-components.css directly. */
.bx--checkbox:checked:not(:disabled) + .bx--checkbox-label::before,
.bx--checkbox:indeterminate:not(:disabled) + .bx--checkbox-label::before {
  background-color: var(--xpa-btn-primary-bg) !important;
  border-color: var(--xpa-btn-primary-bg) !important;
}
.bx--radio-button__appearance {
  border-color: var(--xpa-border-default);
}
.bx--radio-button:checked:not(:disabled) + .bx--radio-button__label .bx--radio-button__appearance {
  border-color: var(--xpa-btn-primary-bg);
}
.bx--radio-button:checked:not(:disabled) + .bx--radio-button__label .bx--radio-button__appearance::before {
  background-color: var(--xpa-btn-primary-bg);
}
/* Toggle switch color rules live in the dedicated "Toggle switches"
   section further down — Carbon paints them via a ::before pseudo-element
   chained through a specific label class, consolidated in one place
   rather than split (a duplicate, incorrectly-structured rule used to
   live here too). */

/* ==== Cards / tiles / metric cards ========================================= */

/* Border + shadow treatment: a near-invisible
   hairline border rendered via a ::before pseudo-element (rather than a
   real `border`) paired with a subtle box-shadow, instead of the flatter
   solid-border/no-shadow look this used to have. Carbon's own .bx--tile
   already sets position:relative, so the ::before anchors correctly. */
.bx--tile {
  position: relative;
  background-color: var(--xpa-bg-surface);
  border: none;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--space-5) var(--space-6);
}
.bx--tile::before {
  content: '';
  position: absolute;
  inset: 0;
  border: 0.92px solid rgba(239, 240, 246, 1);
  border-radius: inherit;
  pointer-events: none;
}

.card,
.xpa-card {
  background-color: var(--xpa-bg-surface) !important;
  border: 1px solid var(--xpa-border-default) !important;
  border-radius: var(--radius-lg) !important;
  box-shadow: var(--shadow-menu) !important;
}
.card-header { background-color: transparent !important; border-bottom: 1px solid var(--xpa-border-light) !important; }

/* ==== Dashboard section cards =============================================
   Each logical dashboard section (welcome, filters, companies, students,
   job postings, candidates, etc.) gets isolated in its own white card
   instead of being separated from its neighbors by a bare <hr/> floating
   on the page background — matches the "main content isolated in a white
   card" layout used across the rest of the app. */
.xpa-dashboard-section {
  position: relative;
  background: var(--surface, #fff);
  border: none;
  border-radius: var(--radius-lg, 14px);
  box-shadow: var(--shadow-sm, 0 1px 2px rgba(35, 32, 28, 0.05));
  padding: 20px 24px;
  margin-bottom: 20px;
}
.xpa-dashboard-section::before {
  content: '';
  position: absolute;
  inset: 0;
  border: 0.92px solid rgba(239, 240, 246, 1);
  border-radius: inherit;
  pointer-events: none;
}
.xpa-dashboard-section:last-child {
  margin-bottom: 0;
}
.xpa-dashboard-section h6 {
  font-size: 12px;
  /* 600, per this file's own "section/item title 12-13/18 600" spec note
     above (~line 279) — 650 isn't a real weight in the loaded Blinker/Sora
     font files (only 400/600/700 exist), so it was silently rendering as
     the much heavier 700 for what's meant to be a quiet small label. */
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink-secondary, #5f5a54);
  margin-bottom: 16px;
}
/* Welcome greeting (candidate dashboard) — two-tier hierarchy: a quiet
   "Welcome!" line followed by a noticeably bigger, bolder name. Kept in
   rpfe's own typeface/token colors. */
.xpa-welcome-label {
  font-size: 14px;
  font-weight: 400;
  color: var(--ink-secondary, #5f5a54);
}
.xpa-welcome-name {
  margin: 2px 0 0;
  font-size: 20px;
  line-height: 1.3;
  font-weight: 600;
  color: var(--ink, #23201c);
  text-transform: capitalize;
}

.numiconcard__container {
  background: var(--xpa-bg-surface) !important;
  border: 1px solid var(--xpa-border-default) !important;
  border-radius: var(--radius-lg) !important;
  box-shadow: none !important;
}
.numiconcard__number--number {
  color: var(--xpa-text-primary) !important;
  font-weight: 300 !important;
  font-size: 44px !important;
}
.numiconcard__number--title {
  color: var(--xpa-text-muted) !important;
  font-weight: 500 !important;
}
.numiconcard__icon {
  background-color: var(--xpa-bg-page) !important;
}

/* ==== Tables ================================================================
   Superseded by the Universal Data Table Design System block near the end
   of this file (kept here only as a marker so a future search for
   "Tables" still finds the right place) — that block supersedes the
   smaller table ruleset that used to live here; merging two overlapping
   definitions of the same selectors in one file was already getting
   confusing, so it's consolidated into one place instead. */

body .table-striped tbody tr:nth-of-type(odd) {
  background-color: transparent !important;
}
.table thead th {
  color: var(--xpa-text-muted) !important;
  font-weight: 600 !important;
  font-size: var(--font-size-sm) !important;
  text-transform: none !important;
  border-bottom: 1px solid var(--xpa-border-default) !important;
  border-top: none !important;
}
.table td,
.table th {
  border-color: var(--xpa-border-light) !important;
  vertical-align: middle !important;
  font-size: var(--font-size-base);
}

/* ==== Header / navigation ================================================== */

.bx--header {
  background-color: var(--xpa-bg-header);
  border-bottom: 1px solid var(--xpa-border-default);
  box-shadow: none;
}
.bx--header__name,
.bx--header__menu-item,
.bx--header__menu-title {
  color: var(--xpa-text-primary);
}
.bx--header__menu-item:hover,
.bx--header__submenu:hover {
  background-color: var(--xpa-bg-hover);
}
.bx--header__menu-item[aria-expanded='true'] {
  color: var(--blue);
}

.sidebar,
.sidebar-sticky,
.xpa-off-canvas .off-canvas-sidebar.xpa-sidebar__normal,
.xpa-off-canvas .off-canvas-sidebar.xpa-sidebar__tiny {
  background: var(--xpa-bg-nav) !important;
  border-right: none;
  box-shadow: none !important;
}

/* Nav item: 35px row, 8px radius, 12px icon/label gap (spec section 6).
   Active state is a white "selection card" with a hairline shadow — NOT a
   tinted/colored background — per "Active item should not use a full
   yellow background; retain a white selection card." */
/* Selectors include the .nav-item ancestor (not just .sidebar .nav-link) to
   match-or-exceed the specificity of a bundled legacy Bootstrap admin
   template's `.sidebar .nav-item .nav-link { width: 6.5rem; text-align:
   center }` rule in app.css, which otherwise wins on specificity alone
   regardless of load order and clips every nav label to ~104px. Key
   layout properties are !important as a second, independent guarantee. */
.sidebar .nav-item .nav-link,
.sidebar .nav-link,
.xpa-off-canvas .off-canvas-sidebar .nav-item a {
  display: flex !important;
  align-items: center;
  gap: 12px;
  height: 35px;
  width: auto !important;
  max-width: none !important;
  text-align: left !important;
  white-space: normal;
  color: var(--xpa-text-primary) !important;
  font-weight: 500;
  font-size: var(--font-size-md);
  text-transform: none !important;
  letter-spacing: normal !important;
  margin: 1px 8px;
  padding: 0 10px !important;
  border-radius: var(--radius-md);
}
.sidebar .nav-item .nav-link:hover,
.sidebar .nav-link:hover,
.xpa-off-canvas .off-canvas-sidebar .nav-item a:hover {
  background-color: var(--bg-hover) !important;
}
.sidebar .nav-item .nav-link.active,
.sidebar .nav-link.active,
.xpa-off-canvas .off-canvas-sidebar .nav-item.active a {
  background-color: var(--xpa-bg-selected) !important;
  color: var(--xpa-text-primary) !important;
  border-radius: var(--radius-md);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
}
.sidebar .nav-item,
.xpa-off-canvas .off-canvas-sidebar .nav-item {
  color: var(--xpa-text-secondary) !important;
}

/* ==== Elastic Search UI Layout chrome ======================================
   @elastic/react-search-ui-views' <Layout> (sideContent/bodyContent split)
   is used across ~10 list pages (JobList, BrowseCompanies, BrowseStudents,
   BrowseEmployees, XopaTable, InstitutionView, StudentsView, UsersView,
   EmployeesView, FacetsBrowse) — its own styles.css (imported per-page,
   e.g. JobList.js) ships defaults built for a taller, differently-themed
   page than this app's card-based layout:
   - .sui-layout-body::after is an 80px gradient "fade" decoration bar
     that renders as pure dead space below the results on every one of
     these pages (confirmed via computed-style inspection: body's own
     height is exactly inner's height + 80px) — this app's content ends
     in a bordered card, not a fading page edge, so it's just cut.
   - .sui-layout-body__inner is `display:flex` with no align-items
     override, so flexbox's default `stretch` forces the (usually much
     shorter) sidebar filter list to match the results column's height —
     a large empty block under a 2-3-item filter list. flex-start lets
     each column keep its own natural height.
   - .sui-layout-header's border and .sui-layout-body's background are
     Elastic's own raw grays (#eeeeee / #fcfcfc), uncoordinated with this
     app's --border/--bg-app tokens.
   - .sui-layout-body__inner's own max-width:1300px + auto side-margins +
     24px padding double up with this app's own page-level content
     padding (every page already sits inside a padded workspace panel),
     producing an extra, redundant inset — removed so the Layout fills
     whatever width its actual page container already provides.

   !important throughout except align-items: Elastic's styles.css is
   bundled via a direct JS import in each page (e.g. JobList.js), which
   in this build ends up loaded AFTER this file's own <link> tag — for
   every property below Elastic also sets on the same selector, that's
   an exact (0,1,0)-vs-(0,1,0) specificity tie, and the later-loaded
   sheet wins ties. Confirmed empirically (computed-style inspection)
   that a non-!important version of this block was silently overridden
   on background/border/max-width/margin/padding/::after — only
   align-items took effect on its own, because Elastic never sets that
   property at all, so there was no tie to lose. */
.sui-layout {
  background: transparent !important;
}
.sui-layout-header {
  border-bottom-color: var(--border, #e7e2dc) !important;
}
.sui-layout-body {
  background: transparent !important;
}
.sui-layout-body::after {
  content: none !important;
  display: none !important;
  height: 0 !important;
}
.sui-layout-body__inner {
  align-items: flex-start;
  max-width: none !important;
  margin: 0 !important;
  padding: 0 !important;
}

/* ==== App shell (persistent sidebar + workspace panel, >=1024px) ========== */
/* Below 1024px these rules do nothing (.xpa-legacy-chrome stays visible,
   .xpa-sidebar stays display:none) — today's Header/hamburger/mega-menu/
   drawer experience is byte-identical to before this section existed. */

/* Dedicated, collision-proof classes for the new sidebar's own markup —
   deliberately NOT reusing the generic .sidebar/.nav/.nav-item/.nav-link/
   .sidebar-sticky names, which this codebase's app.css already defines
   twice over for two different bundled legacy Bootstrap admin-dashboard
   templates (Bootstrap's own "Dashboard" example and a third-party "SB
   Admin 2" template), including a `.sidebar .nav-item .nav-link{width:
   6.5rem}` rule whose specificity silently wins over generic 2-class
   selectors regardless of load order. Using our own namespaced classes
   sidesteps that whole class of bugs instead of chasing it rule-by-rule. */

.xpa-sidebar {
  display: none;
  background: var(--nav-bg);
  /* The hairline that separates the rail from the workspace panel — ours
     never had it, so the two surfaces ran together with no dividing edge. */
  border-inline-end: 1px solid var(--border);
}

.xpa-sidebar-sticky {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
}

.xpa-sidebar-brand {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 56px;
  padding: 0 10px;
  margin-bottom: var(--space-2);
  flex: 0 0 auto;
}
.xpa-sidebar-brand-logo-btn {
  display: flex;
  align-items: center;
  cursor: pointer;
}
.xpa-sidebar-brand-logo {
  height: 26px;
  width: auto;
}

.xpa-sidebar-nav {
  display: flex;
  flex-direction: column;
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 0 0 auto;
}

.xpa-sidebar-nav-item {
  list-style: none;
}

/* Row spacing is margin on the link itself (2px top+bottom, not a
   list-level gap), padding 12px, radius 8px, 14px type. */
.xpa-sidebar-nav-link {
  display: flex;
  align-items: center;
  gap: 12px;
  height: 40px;
  width: 100%;
  box-sizing: border-box;
  margin: 2px 0;
  padding: 0 12px;
  border-radius: 8px;
  color: var(--nav-text);
  font-weight: 500;
  font-size: 14px;
  line-height: 20px;
  text-decoration: none;
  white-space: normal;
  transition: background-color var(--xpa-motion-duration) var(--xpa-motion-ease),
              color var(--xpa-motion-duration) var(--xpa-motion-ease);
}
/* Browser/Carbon default focus rings (blue outline) show on plain :focus
   for mouse clicks too, not just keyboard nav — suppress them for every
   interactive sidebar element. The existing hover/focus background-color
   change already gives a clear, visible focus indicator, so nothing is
   lost for accessibility. */
.xpa-sidebar button:focus,
.xpa-sidebar a:focus,
.xpa-sidebar [tabindex]:focus {
  outline: none;
}
.xpa-sidebar-nav-link:hover,
.xpa-sidebar-nav-link:focus {
  background-color: var(--nav-hover);
  color: var(--nav-text-active);
  text-decoration: none;
}
/* Parent items with sub-items render as a <button> disclosure toggle
   rather than an <a> — reset the button-specific UA defaults that would
   otherwise stop it filling the row like its <a> sibling does. Width
   itself is inherited from the base .xpa-sidebar-nav-link rule (100%,
   border-box) so both variants always match. */
.xpa-sidebar-nav-link--toggle {
  border: 0;
  background: transparent;
  text-align: left;
  cursor: pointer;
}
.xpa-sidebar-nav-link__chevron {
  flex: 0 0 auto;
  margin-left: auto;
  color: var(--nav-icon);
  transform: rotate(-90deg);
  transition: transform var(--xpa-motion-duration) var(--xpa-motion-ease);
}
.xpa-sidebar-nav-link__chevron--expanded {
  transform: rotate(0deg);
}
.xpa-sidebar-nav-link--active-parent .xpa-sidebar-nav-link__chevron,
.xpa-sidebar-nav-link--toggle:hover .xpa-sidebar-nav-link__chevron {
  color: currentColor;
}
/* Active top-level item (or a standalone item with no children): a dark
   raised surface, not an accent color — the parent "container" for
   whichever child is actually selected. */
.xpa-sidebar-nav-link--active-parent {
  background-color: var(--nav-active);
  color: var(--nav-text-active);
}
/* Active sub-item: same warm raised-surface treatment as an active parent
   (--nav-active), so it reads as "selected" against this earthy palette —
   var(--primary-soft) (#f0f0f0, a leftover flat gray from an earlier
   palette version) was nearly indistinguishable from the plain hover
   state, which is why the highlight looked wrong/washed out. */
.xpa-sidebar-nav-link--active-child {
  background-color: var(--nav-active);
  color: var(--nav-text-active);
}
/* :hover/:focus (a class + pseudo-class) outrank a single active-state
   class on specificity alone, so without this the active row would flash
   back to the plain hover gray the instant the cursor sat over it. */
.xpa-sidebar-nav-link--active-parent:hover,
.xpa-sidebar-nav-link--active-parent:focus,
.xpa-sidebar-nav-link--active-child:hover,
.xpa-sidebar-nav-link--active-child:focus {
  background-color: var(--nav-active);
  color: var(--nav-text-active);
}
/* Nav icons are react-icons' lucide set — stroke-based SVGs
   (stroke="currentColor"), so colour them via `color`, not `fill` (same as
   the submenu chevron's own rules above). */
.xpa-sidebar-nav-icon {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  color: var(--nav-icon);
}
.xpa-sidebar-nav-link--active-parent .xpa-sidebar-nav-icon,
.xpa-sidebar-nav-link--active-child .xpa-sidebar-nav-icon,
.xpa-sidebar-nav-link:hover .xpa-sidebar-nav-icon {
  color: currentColor;
}

/* Vertical guide line connecting a section's sub-items, with a short
   accent "tick" marking whichever one is active — the enterprise-nav
   convention (rail + tick) rather than a bare indented list. */
/* Geometry below (30px indent, line at 20px, notch at -10px/16px-tall),
   replacing the border-left rail this used before. This ul sits inside
   the parent <li>, as a sibling of the toggle
   button — not as a sibling <li> of the parent within the outer <ul> — so
   the outer list's row margin never applied to this boundary; the bottom
   margin below is what puts space before the *next* top-level item. */
.xpa-sidebar-subnav {
  position: relative;
  margin: 0 0 6px;
  padding-inline-start: 30px;
}
.xpa-sidebar-subnav::before {
  content: '';
  position: absolute;
  inset-inline-start: 20px;
  top: 2px;
  bottom: 2px;
  width: 1px;
  background: var(--border);
  /* Without this, the active row's opaque pill background (painted later
     in tree order, at the same implicit stacking level) covers this line
     for that row's whole height — leaving only the notch visible and a
     gap above/below it instead of one continuous line. z-index:1 lifts
     the line above ordinary row backgrounds; the notch below is lifted
     again, to z-index:2, so it still shows on top of the line itself. */
  z-index: 1;
}
.xpa-sidebar-subnav .xpa-sidebar-nav-link {
  position: relative;
  min-height: 32px;
  height: auto;
  margin: 0;
  padding: 5px 10px;
  border-radius: var(--radius-sm);
  font-size: var(--font-size-md);
  font-weight: 400;
  line-height: 18px;
}
/* Notch on the guide line: transparent at rest, a faint hint on hover, and
   the full accent color when this sub-item is the active one. */
.xpa-sidebar-subnav .xpa-sidebar-nav-link::before {
  content: '';
  position: absolute;
  inset-inline-start: -13.5px;
  top: 50%;
  transform: translateY(-50%);
  width: 2px;
  height: 16px;
  border-radius: 2px;
  background: transparent;
  transition: background-color var(--xpa-motion-duration) var(--xpa-motion-ease);
  z-index: 2;
}
.xpa-sidebar-subnav .xpa-sidebar-nav-link:hover::before,
.xpa-sidebar-subnav .xpa-sidebar-nav-link:focus::before {
  background: var(--border-strong-v3);
}
.xpa-sidebar-subnav .xpa-sidebar-nav-link--active-child::before {
  background: var(--primary);
}

/* White bordered card — a deliberate contrast against the dark graphite
   sidebar, per spec: "should feel like a quiet utility area rather than
   part of the primary product navigation." */
.xpa-sidebar-utility-card {
  margin-top: auto;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}

.xpa-utility-nav-item {
  display: flex;
  align-items: center;
  width: 100%;
  gap: 8px;
  /* 30px here, 36px on .xpa-session-action below — deliberately two
     different row heights, not a shared one. */
  min-height: 30px;
  padding: 0 10px;
  border: 0;
  border-bottom: 1px solid var(--border);
  background: transparent;
  color: var(--ink);
  font-size: 12px;
  font-weight: 500;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.xpa-utility-nav-item:hover {
  background: var(--surface-hover);
  color: var(--ink);
  text-decoration: none;
}
.xpa-utility-nav-item__trailing {
  margin-left: auto;
  color: var(--ink-tertiary);
  flex: 0 0 auto;
}

.xpa-session-action {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  height: 36px;
  padding: 0 10px;
  border: 0;
  background: transparent;
  color: var(--ink);
  font-size: 12px;
  font-weight: 500;
  text-align: left;
  text-decoration: none;
}
.xpa-session-action:hover {
  background: var(--danger-soft);
  color: var(--danger);
  text-decoration: none;
}

/* ==== User identity row + account popup ==================================== */

.xpa-sidebar-user-identity-wrap {
  position: relative;
  flex: 0 0 auto;
  margin-top: 10px;
  padding: 0 4px;
}
/* Contained account card: a raised hairline surface so the "you" block reads
   as a control, not floating text — warm tan border, avatar ringed in gold,
   a sort chevron trailing. */
.xpa-sidebar-user-identity {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-width: 0;
  padding: 7px 10px;
  border: 1px solid #d9c7ab;
  border-radius: 10px;
  background: #ffffff;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: background-color 120ms ease-out, border-color 120ms ease-out;
}
.xpa-sidebar-user-identity:hover,
.xpa-sidebar-user-identity:focus {
  background: #faf9f7;
  border-color: #c9b190;
  outline: none;
}
.xpa-sidebar-user-identity:focus-visible {
  box-shadow: var(--shadow-focus);
}
/* Opens upward from the bottom-anchored identity row. SidebarUserIdentity.js
   portals this into <body> and sets position:fixed + left/bottom/width inline
   off the trigger's rect — so it is never clipped by the sidebar's
   overflow:auto nor trapped beneath the workspace panel by the sidebar's
   sticky stacking context (both of which broke it while it lived in-tree). */
.xpa-sidebar-user-popup {
  width: 240px;
  max-width: calc(100vw - 24px);
  max-height: calc(100vh - 24px);
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: 10px;
  /* explicit opaque fill + forced opacity so nothing upstream in the cascade
     can leave this translucent. */
  background: #ffffff !important;
  opacity: 1 !important;
  box-shadow: var(--shadow-lg);
  z-index: 9000;
}
/* keep the inner rows flush with the rounded corners now that the wrapper
   scrolls instead of clipping */
.xpa-sidebar-user-popup__header:first-child { border-radius: 10px 10px 0 0; }
.xpa-sidebar-user-popup__header {
  padding: 12px 10px;
  border-bottom: 1px solid var(--border);
}
.xpa-sidebar-user-popup__name {
  overflow: hidden;
  color: var(--ink);
  font-size: 12px;
  font-weight: 600;
  line-height: 16px;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.xpa-sidebar-user-popup__email {
  overflow: hidden;
  margin-top: 1px;
  color: var(--ink-tertiary);
  font-size: 11px;
  line-height: 14px;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.xpa-sidebar-user-identity__avatar {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  overflow: hidden;
  font-size: 12px;
  font-weight: 600;
  /* gold double-ring — white gap then a warm halo */
  box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #e8dcc4;
}
.xpa-sidebar-user-identity__text {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
}
.xpa-sidebar-user-identity__name {
  overflow: hidden;
  color: var(--nav-text-active);
  font-size: 13px;
  font-weight: 600;
  line-height: 17px;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.xpa-sidebar-user-identity__meta {
  overflow: hidden;
  margin-top: 1px;
  color: var(--nav-icon);
  font-size: 11px;
  line-height: 14px;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.xpa-sidebar-user-identity__chevron {
  flex: 0 0 auto;
  margin-left: auto;
  fill: var(--nav-icon);
  transition: fill 120ms ease-out;
}
.xpa-sidebar-user-identity:hover .xpa-sidebar-user-identity__chevron {
  fill: var(--nav-text-active);
}

/* ==== Collapsed "More" button + popover ===================================== */

.xpa-sidebar-more-wrap {
  position: relative;
  margin-top: auto;
  display: flex;
  justify-content: center;
}
.xpa-sidebar-more-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--nav-icon);
}
.xpa-sidebar-more-btn:hover {
  background: var(--nav-hover);
  color: var(--nav-text-active);
}
.xpa-sidebar-more-popover {
  position: fixed;
  left: 80px;
  bottom: 16px;
  width: 220px;
  z-index: 2000;
}
.xpa-sidebar-more-popover .xpa-sidebar-utility-card {
  margin-top: 0;
  background: #ffffff !important;
  opacity: 1 !important;
  box-shadow: var(--shadow-md);
}

.xpa-sidebar-collapse-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  margin: 0;
  padding: 0;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: var(--nav-icon);
}
.xpa-sidebar-collapse-btn:hover {
  background: var(--nav-hover);
  color: var(--nav-text-active);
}

/* Collapsed state: 72px icon-only rail. Labels/subnav/utility card hide;
   icons center within the row. */
.xpa-sidebar--collapsed .xpa-sidebar-nav-link span {
  display: none;
}
/* The full wordmark logo doesn't fit a 72px rail, so it used to just be
   hidden outright (display:none) — leaving no brand mark at all while
   collapsed. AppSidebar.js swaps the <img> src to a square-cropped shield
   mark in this state instead, so stack it above the collapse toggle
   rather than trying to fit both side by side in ~52px of usable width. */
/* Values below: 6px/14px 8px 8px, 8px gap, 4px identity padding. */
.xpa-sidebar--collapsed .xpa-sidebar-brand {
  flex-direction: column;
  justify-content: center;
  height: auto;
  padding: 14px 8px 8px;
  gap: 6px;
}
.xpa-sidebar--collapsed .xpa-sidebar-nav-link {
  justify-content: center;
  padding: 0;
}
.xpa-sidebar--collapsed .xpa-sidebar-user-identity-wrap {
  margin-top: 8px;
  padding: 0;
}
.xpa-sidebar--collapsed .xpa-sidebar-user-identity {
  justify-content: center;
  padding: 4px;
  border-color: transparent;
  background: transparent;
}
.xpa-sidebar--collapsed .xpa-sidebar-user-identity:hover,
.xpa-sidebar--collapsed .xpa-sidebar-user-identity:focus {
  background: var(--nav-hover);
  border-color: transparent;
}

@media (min-width: 1024px) {
  .xpa-legacy-chrome {
    display: none !important;
  }
  .xpa-app-shell {
    display: flex;
    align-items: stretch;
    min-height: 100vh;
    background: var(--bg-app);
    box-sizing: border-box;
  }
  .xpa-sidebar {
    display: flex;
    flex-direction: column;
    flex: 0 0 240px;
    /* !important beats a bundled legacy template's .sidebar{width:14rem!important} */
    width: 240px !important;
    min-height: auto !important;
    /* Flush against the viewport edge now (no outer inset gap), so the
       outer corners stay square — rounding only made sense with the
       padding that used to surround the shell. */
    border-radius: 0;
    padding: var(--space-4) var(--space-2);
    box-sizing: border-box;
    transition: width var(--xpa-motion-duration) var(--xpa-motion-ease),
                flex-basis var(--xpa-motion-duration) var(--xpa-motion-ease);
    /* Pin to the viewport instead of stretching (and scrolling away) with
       tall page content — .xpa-app-shell's align-items:stretch would
       otherwise grow the sidebar to match the workspace panel's full
       content height. align-self overrides that; a fixed, viewport-
       relative height + its own scroll keeps it independent. */
    position: -webkit-sticky;
    position: sticky;
    top: 0;
    align-self: flex-start;
    height: 100vh;
    overflow-y: auto;
    /* position:sticky makes .xpa-sidebar its own stacking context at
       z-index:auto — which paints BEFORE .xpa-workspace-panel's
       relatively-positioned cards (.xpa-dashboard-section / .bx--tile),
       so the account / "More" popovers (z-index:2000 *within* this
       context) still landed behind the dashboard cards. Lifting the whole
       rail to a low positive z-index puts its stacking context above the
       page cards while staying far below Carbon overlays (modals/menus
       sit at 6000+). This is the fix for the long-standing
       "sidebar popup hidden behind main content" issue. */
    z-index: 10;
    /* Keep the scroll capability (as a safety net for short viewports /
       many expanded sub-items) without showing scrollbar chrome when it
       isn't actually needed. */
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .xpa-sidebar::-webkit-scrollbar {
    display: none;
    width: 0;
    height: 0;
  }
  .xpa-sidebar--collapsed {
    flex: 0 0 72px !important;
    width: 72px !important;
  }
  /* Was `background: var(--bg-surface)` (#ffffff) — the exact same white
     as every card floating inside it (the table, the pill-tabs bar, the
     sort-by row), so those cards' own borders/shadows were the ONLY thing
     distinguishing them from the page, with zero background contrast to
     reinforce it. Switched to a light warm-gray page background with white
     cards floating distinctly within it — --bg-app, not --bg-surface.
     This one token swap is what
     makes the "isolated card" look actually read as isolated, across
     every page using this shell, not just the ones with the most
     deliberately-styled tables.
     overflow was `hidden` — presumably left over from when this panel
     was itself a clipped rounded card; now that it's just the page
     backdrop (not a card with corners to protect), hidden would clip
     anything that needs to render outside its bounds — dropdown menus,
     tooltips, date pickers — a real bug or an easy repeat of the earlier
     ComboBox/dropdown clipping-and-invisible-content bugs on legitimate
     content. */
  .xpa-workspace-panel {
    flex: 1 1 auto;
    min-width: 0;
    background: var(--bg-app);
    border-radius: 0;
    box-shadow: none;
    overflow: visible;
  }
  .xpa-workspace-panel .section-align-center {
    min-height: auto;
  }
  /* MainApp.js's main content <section> no longer carries the bx--tile
     class (removed — it was giving every page's content a redundant
     nested card border/shadow/background now that .xpa-workspace-panel
     is itself the card, and was also the subject of an unresolved
     investigation into unrelated sidebar-popup rendering issues). This
     is a defensive baseline in case anything else ever re-introduces
     tile-like chrome onto this element. */
  .xpa-workspace-panel .main-application-view {
    border: 0 !important;
    box-shadow: none !important;
    background: transparent !important;
    /* This section's pt-5/mt-3/pl-4+pl-lg-5/pr-4+pr-lg-5 Bootstrap utility
       classes (48px+16px top, 48px sides at this width) were sized to
       clear the old fixed top header — that header no longer exists at
       this breakpoint (the sidebar replaced it), so on top of the outer
       wrapper's own pt-3 below, content was starting 80px down with no
       header there to justify it. One consistent 24px gutter instead. */
    padding: 24px !important;
    margin-top: 0 !important;
  }
  /* The pt-3 wrapper div between .xpa-workspace-panel and the section
     above — no class of its own to hook, targeted structurally. */
  .xpa-workspace-panel > .w-100.pt-3 {
    padding-top: 0 !important;
  }
  /* MapView.js's 48px term is already var()-driven (resolves to 0 here);
     these two are literal calc() strings in other stylesheets that load
     before this one, so a scoped override wins by cascade order alone. */
  .BubbleChart {
    height: calc(100vh - 147.26px - 27.27px - 100px);
  }
  .leftcards-container {
    height: calc(100vh - 16px); /* best-guess placeholder — flag for QA */
  }
}
.xpa-top-nav {
  background: var(--xpa-bg-header) !important;
  box-shadow: none !important;
  border-bottom: 1px solid var(--xpa-border-default);
}

/* Full-width page frame for list pages whose filters have moved into the
   right-side FilterDrawer — replaces the old `.<page>-layout` + Elastic
   `<Layout>` (or `bx--row` grid) two-column split, so the table now fills
   the content column instead of a centred band with a facet rail beside it. */
.xpa-browse-list {
  width: 100%;
  min-width: 0;
}

/* ==== Tabs / filter pills =================================================== */
/* Filter tab: quiet blue outlined pill when active, no underline (spec
   section 8). Applied to Carbon tabs and the app's own .xpa-tab pattern. */

.bx--tabs__nav-item {
  font-weight: 500;
  color: var(--xpa-text-secondary);
  font-size: var(--font-size-sm);
}
.bx--tabs__nav-item--selected,
.bx--tabs-trigger-text,
.bx--tabs__nav-link[aria-selected='true'] {
  color: var(--blue);
}
.bx--tabs__nav-item--selected {
  border-color: var(--blue);
}

.xpa-tab {
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 10px;
  border: 1px solid var(--border-subtle) !important;
  border-radius: var(--radius-pill) !important;
  background: var(--bg-subtle) !important;
  color: var(--xpa-text-secondary) !important;
  font-weight: 500 !important;
  font-size: var(--font-size-sm) !important;
}
.xpa-tab.xpa-selected-tab {
  color: var(--blue) !important;
  background: var(--blue-soft) !important;
  border-color: var(--blue-border) !important;
}

/* ==== Modals ================================================================
   Mapped to this app's tokens (--default-border-radius 14px -> --radius-lg,
   --btn-border-radius 10px -> --radius-md, --divider-color -> --border-subtle).
   The important change over stock Carbon is the footer: Carbon ships a
   full-width, split 4rem-tall two-button slab; this makes it a compact,
   right-aligned 36px button row. */

.bx--modal {
  background-color: rgba(35, 32, 28, 0.4);
  z-index: 9000 !important;
}

.bx--modal-container {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  background-color: var(--surface);
}

.bx--modal-header {
  border-bottom: 1px solid var(--border-subtle);
}

.bx--modal-header__heading {
  font-size: 20px;
  font-weight: 600;
  color: var(--ink);
}

.bx--modal-content:focus {
  outline: 0 solid transparent;
  outline-offset: -2px;
}

.bx--modal-close {
  /* Carbon's close button isn't a flex container, so the SVG icon inside lays
     out inline and keeps a couple px of baseline/descender space below it —
     it looks visibly off-center in the square button. Centering it with flex
     is exact regardless of the icon's own metrics. Unscoped: every Carbon
     Modal's close button gets this, not just the XPAPortal drawer. */
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
  margin: 0.1rem;
}

/* Compact, right-aligned footer — replaces Carbon's full-width 4rem button slabs. */
.bx--modal-footer {
  height: auto !important;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 8px;
  padding: 12px 16px;
  background-color: var(--surface) !important;
  border-top: 1px solid var(--border-subtle);
  border-radius: 0 0 calc(var(--radius-lg) - 1px) calc(var(--radius-lg) - 1px);
}

.bx--modal-footer .bx--btn {
  flex: 0 0 auto !important;
  width: auto !important;
  max-width: none !important;
  height: 36px !important;
  min-height: 36px !important;
  margin: 0 !important;
  padding: 0 16px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  border-radius: var(--radius-md) !important;
}

.bx--modal-footer .bx--btn--secondary {
  background-color: var(--surface) !important;
}

.modal-content {
  border-radius: var(--radius-lg) !important;
  border: 1px solid var(--xpa-border-default) !important;
  box-shadow: var(--shadow-lg) !important;
}

/* ---- Batch Actions modal body (JobList `showBatchActionModal`) ----
   Carbon's stock modal body left `.bx--modal-content` with asymmetric
   padding (1rem left / 20% right), cool #161616 text + letter-spacing and a
   2.5rem gap before the footer; the Yes/No choice was two bare radios inside
   Bootstrap `.col-md-3` columns. This resets the body to the enterprise type
   scale and turns each radio into a selectable option pill. */
.xpa-batch-modal .bx--modal-content {
  padding: 4px 24px;
  margin-bottom: 1.25rem;
  color: var(--ink, #23201c);
  letter-spacing: normal;
}
.xpa-batch-modal .bx--modal-header__label {
  color: var(--ink-tertiary, #8a847c);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.xpa-batch-modal__intro {
  max-width: 60ch;
  margin: 0 0 20px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-secondary, #5f5a54);
}
.xpa-batch-modal .bx--form-item {
  margin: 0;
}
/* Legend sits on its own line; the options flow as a row beneath it. */
.xpa-batch-modal .bx--radio-button-group {
  flex-wrap: wrap;
  align-items: stretch;
  gap: 10px;
}
.xpa-batch-modal .bx--radio-button-group > .bx--label {
  flex-basis: 100%;
  /* sits on top of the flex container's own 10px row-gap → ~24px clear
     of the option pills below */
  margin: 0 0 14px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink, #23201c);
}
.xpa-batch-modal .bx--radio-button-wrapper {
  margin: 0 !important;
}
/* The whole pill is the hit area — Carbon's real <input> is visually hidden,
   the <label> is what receives the click. Scoped through
   `.bx--radio-button-wrapper` so it outranks Carbon's own
   `.bx--radio-button-wrapper .bx--radio-button__label` (which loads after
   this file). */
.xpa-batch-modal .bx--radio-button-wrapper .bx--radio-button__label {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 104px;
  margin: 0;
  padding: 9px 16px;
  border: 1px solid var(--border, #e7e2dc);
  border-radius: var(--radius-md, 10px);
  background: var(--surface, #ffffff);
  font-size: 14px;
  letter-spacing: 0;
  color: var(--ink, #23201c);
  cursor: pointer;
  transition: border-color 150ms ease, background-color 150ms ease,
              box-shadow 150ms ease;
}
.xpa-batch-modal .bx--radio-button:not(:checked):not(:disabled)
  + .bx--radio-button__label:hover {
  border-color: var(--border-strong-v3, #d8d2cb);
  background: var(--surface-hover, #f4f2ee);
}
.xpa-batch-modal .bx--radio-button:checked + .bx--radio-button__label {
  border-color: var(--xpa-btn-primary-bg, #4c4842);
  background: var(--surface-hover, #f4f2ee);
  font-weight: 500;
}
.xpa-batch-modal .bx--radio-button:focus-visible + .bx--radio-button__label {
  box-shadow: var(--shadow-focus, 0 0 0 3px rgba(17, 17, 17, 0.16));
  border-color: var(--xpa-btn-primary-bg, #4c4842);
}
/* The dot */
.xpa-batch-modal .bx--radio-button-wrapper .bx--radio-button__appearance {
  width: 16px;
  height: 16px;
  margin: 0;
  border-width: 1.5px;
  border-color: var(--border-strong-v3, #d8d2cb);
}
.xpa-batch-modal .bx--radio-button:checked
  + .bx--radio-button__label .bx--radio-button__appearance {
  border-color: var(--xpa-btn-primary-bg, #4c4842);
}
.xpa-batch-modal .bx--radio-button:checked
  + .bx--radio-button__label .bx--radio-button__appearance::before {
  background-color: var(--xpa-btn-primary-bg, #4c4842);
}
/* Carbon's own blue focus ring sits on the inner dot — drop it, the pill
   carries focus now. */
.xpa-batch-modal .bx--radio-button:focus
  + .bx--radio-button__label .bx--radio-button__appearance {
  box-shadow: none;
  outline: none;
}

/* ==== Slide-in portal / drawer =============================================
   A Carbon <Modal> whose container is CSS-pinned to the right edge as a
   full-height drawer. Used via
   `components/common/XPAPortal.js` for filter panels and other contextual side
   content. The scrim, close button, focus trap and open/close transition come
   from Carbon's own `.bx--modal` rules; this only re-places and re-shapes the
   container. ============================================================== */

.xpa-portal .bx--modal-container {
  position: fixed;
  top: 0;
  right: -460px;              /* parked off-screen right when hidden */
  bottom: 0;
  left: auto;
  width: 460px;
  max-width: 92vw;
  height: 100%;
  min-height: 100%;
  max-height: 100%;
  border-radius: 0;
  border-width: 0 0 0 1px;    /* only the left hairline */
  /* Slide via `right`, not `transform`. A non-`none` transform on this element
     — even a resting translate3d(0,0,0) once "open" — makes it the containing
     block for any `position: fixed` descendant (per spec: transform/filter/
     perspective on an ancestor overrides fixed positioning to be relative to
     that ancestor instead of the viewport, regardless of the ancestor's own
     `position`). react-beautiful-dnd lifts a dragged row with exactly
     `position: fixed`, computed relative to the viewport — left under a
     transformed ancestor, the browser resolved that "fixed" position against
     this drawer panel instead, rendering the dragged column row off-canvas
     for the whole drag. `right` gives the identical slide-in with no such
     side effect. */
  transition: right 260ms cubic-bezier(0.4, 0.14, 1, 1);
}

.xpa-portal.bx--modal.is-visible .bx--modal-container {
  right: 0;                   /* slides in from the edge */
  transition: right 300ms cubic-bezier(0, 0, 0.3, 1);
}

.xpa-portal .bx--modal-content {
  padding-right: 1rem;         /* drop Carbon's 20% right padding in a narrow panel */
  overflow-y: auto;
}

/* passiveModal already omits the footer; this covers any non-passive use. */
.xpa-portal .bx--modal-footer {
  display: none;
}

@media (max-width: 640px) {
  .xpa-portal .bx--modal-container {
    width: 100%;
    max-width: 100%;
    right: -100%;              /* full-width panel needs a full-width offset to park off-screen */
  }
}

/* ==== Badges / tags ========================================================= */

.bx--tag {
  border-radius: var(--radius-pill);
  font-weight: 500;
  font-size: var(--font-size-sm);
  padding: 2px 10px;
  background-color: var(--bg-subtle);
  color: var(--xpa-text-secondary);
}
.bx--tag--blue { background-color: var(--blue-soft); color: #1c53b3; }
.bx--tag--green { background-color: #e8f6ef; color: #1f7a51; }
.bx--tag--red { background-color: #fbe9e9; color: #b83c3c; }
.bx--tag--magenta,
.bx--tag--purple { background-color: var(--pink-soft); color: #c24884; }

.badge {
  border-radius: var(--radius-sm) !important;
  font-weight: 500 !important;
  font-size: var(--font-size-sm) !important;
  padding: 3px 8px !important;
}

/* ==== Pagination ============================================================
   Full ruleset (including the button/select fixes below) lives in the
   Universal Data Table Design System block near the end of this file —
   consolidated there instead of split across two places. */
.bx--select__item-count .bx--select-input {
  color: var(--xpa-text-secondary);
}

/* ==== Multi-select tags / chips (Personas-style pill tags) ================= */

.Select-value {
  background-color: var(--bg-subtle) !important;
  border: 1px solid var(--border-default) !important;
  border-radius: var(--radius-pill) !important;
  color: var(--xpa-text-primary) !important;
  padding: 1px 6px 1px 10px !important;
  font-size: var(--font-size-sm) !important;
}
.Select-value-icon {
  border-right: 1px solid var(--border-default) !important;
  color: var(--xpa-text-muted) !important;
}
.Select-value-icon:hover {
  background-color: var(--border-subtle) !important;
  color: var(--xpa-text-primary) !important;
}

/* ==== Toggle switches =======================================================
   Carbon paints the switch's actual color on the ::before pseudo-element,
   not .bx--toggle__switch itself, and the checked-state selector chains
   through .bx--toggle-input__label (not .bx--toggle__label, a different,
   unrelated class) via a direct-child combinator — verified against
   carbon-components.min.css directly since guessing this structure from
   naming convention alone is exactly how the previous version of this
   rule ended up targeting nothing. */
.bx--toggle__switch::before {
  background-color: var(--text-disabled) !important;
}
/* :not(:disabled) so a disabled+checked toggle keeps Carbon's own grey
   (#f4f4f4, set via .bx--toggle-input:disabled+...::before with no
   !important) instead of this !important rule forcing full primary
   color regardless of disabled state. */
.bx--toggle-input:checked:not(:disabled) + .bx--toggle-input__label > .bx--toggle__switch::before {
  background-color: var(--xpa-btn-primary-bg) !important;
}

/* ==== Disabled ===============================================================
   Text/textarea/select/.form-control/.form-input are already handled at
   the point each is defined (Inputs section, [disabled] real form
   controls, so :disabled just works there). What's collected here is
   everything that ISN'T a real form control and so can't use :disabled at
   all: Carbon's Dropdown/ComboBox/MultiSelect render their disabled state
   as a `--disabled` modifier class on a <div>, and react-select does the
   same via emotion-computed inline styles with no reliable class (its BEM
   `--is-disabled` class only appears when classNamePrefix is a non-empty
   string, which most of the ~9 usages in this app don't set — verified in
   react-select's own utils.js). The one thing react-select always renders
   regardless of prefix is a real `disabled` attribute on its nested
   <input> (confirmed in Input.js), so :has() against that is the only
   selector that works identically across every usage. */

[disabled],
.disabled {
  color: var(--text-disabled) !important;
  cursor: not-allowed;
}
.bx--btn:disabled,
.bx--btn.bx--btn--disabled,
.bx--btn:disabled:hover,
.bx--btn:disabled:focus,
.btn:disabled {
  background-color: var(--surface-muted) !important;
  border-color: var(--border-default) !important;
  /* --text-disabled (#bdb6ae) on the old near-white fill was ~1.9:1 — a
     disabled label should still be legible. --ink-tertiary on --surface-muted
     is ~3:1: clearly muted, but readable. */
  color: var(--ink-tertiary) !important;
  box-shadow: none !important;
}
.bx--btn:disabled .bx--btn__icon path,
.bx--btn.bx--btn--disabled .bx--btn__icon path,
.btn:disabled .bx--btn__icon path {
  fill: var(--ink-tertiary) !important;
}

/* Carbon Dropdown / ComboBox / MultiSelect */
.bx--dropdown--disabled,
.bx--list-box--disabled {
  background-color: var(--bg-subtle) !important;
  border-color: var(--border-subtle) !important;
  cursor: not-allowed;
}
.bx--dropdown--disabled .bx--dropdown-text,
.bx--dropdown--disabled .bx--list-box__label,
.bx--list-box--disabled .bx--list-box__field,
.bx--list-box--disabled .bx--list-box__label,
.bx--list-box--disabled input {
  color: var(--xpa-text-disabled) !important;
  cursor: not-allowed;
}
.bx--dropdown--disabled svg,
.bx--list-box--disabled svg {
  fill: var(--xpa-text-disabled) !important;
}

/* react-select — the disabled look is keyed on the CONTROL owning a disabled
   <input> (`-container > -control:has(input:disabled)`), never on the
   container. `[class*="-container"]` also substring-matches wrappers like
   `.bx--modal-container` / `.bx--data-table-container` / `.sui-facet-container`,
   so `[class*="-container"]:has(input:disabled) [class*="-control"]` was
   greying EVERY react-select that merely shared such a wrapper with one
   unrelated disabled field (e.g. a read-only email in the same modal),
   making enabled dropdowns look disabled. react-select nests its own
   <input> inside its control, so this stays accurate. */
[class*="-container"] > [class*="-control"]:has(input:disabled) {
  background-color: var(--bg-subtle) !important;
  border-color: var(--border-subtle) !important;
  cursor: not-allowed;
}
[class*="-container"] > [class*="-control"]:has(input:disabled) [class*="-placeholder"],
[class*="-container"] > [class*="-control"]:has(input:disabled) [class*="-singleValue"],
[class*="-container"] > [class*="-control"]:has(input:disabled) [class*="-single-value"] {
  color: var(--xpa-text-disabled) !important;
}
[class*="-control"] input:disabled {
  cursor: not-allowed;
}

/* ==== Motion ================================================================ */

.bx--btn,
.bx--tile,
.bx--tabs__nav-item,
.btn,
.card,
a,
.nav-link,
.xpa-tab {
  transition-duration: var(--xpa-motion-duration);
  transition-timing-function: var(--xpa-motion-ease);
}

/* ==== Universal Data Table Design System ===================================
   Meant to become the single table treatment across Jobs/Candidates/
   Assessments/Interviews/CRM/Outreach — targets Carbon's actual DataTable/
   Pagination/OverflowMenu classes directly (GenericDataTable.js renders
   these as-is, so the chrome below needs no JS changes to take effect).
   The cell-pattern classes (.xpa-td-*, .xpa-table-avatar, .xpa-status-badge,
   .xpa-number-pill) are new utility classes — callers construct cell
   content themselves (GenericDataTable takes pre-built cell.value JSX), so
   adopting these per-page is a separate, later migration, not something
   this stylesheet alone can complete.

   Token note: most of this spec's palette is this app's EXISTING earthy
   tokens verified as exact hex matches (App Background=--canvas,
   Surface=--surface, Header=--surface-subtle, Text Primary=--ink, Text
   Secondary=--ink-secondary, Text Muted=--ink-tertiary, Link=--link,
   Link Hover=--link-hover, and the success/warning/error badge colors are
   exactly --success/--warning/--danger) — reused directly rather than
   redefined. Only the terracotta accent and a couple of table-specific
   surface/border shades are genuinely new, so they're scoped under
   --table-* rather than touching the app-wide --primary (near-black,
   used for buttons/sidebar) — this is a table-local accent, not a
   global palette change. ============================================= */

:root {
  --table-surface-hover: #fcfbf9;
  --table-header-bg: var(--surface-subtle, #faf9f7);
  --table-border: #ece7e1;
  --table-divider: #f3f0ec;
  --table-accent: #c46a3a;
  --table-accent-hover: #ae5b30;
  --table-accent-light: #f6ece6;
}

/* ---- Container ----
   GenericDataTable.js wraps the <Table> in its own `.xpa-table-scroll` div —
   TableToolbar is a sibling outside that wrapper, not sharing it with
   <Table> — so a wide
   table scrolls independently of the toolbar above it, which never moves.
   The container itself no longer needs to scroll at all: hidden on both axes
   just keeps corners rounded (a nested bottom element can't poke square
   corners past the radius; the table's own overflow is fully reachable via
   .xpa-table-scroll's independent scrollbar, so nothing is amputated). */
.bx--data-table-container {
  background: var(--surface);
  border-radius: 20px;
  border: 1px solid var(--table-border);
  /* was a heavy 30px-blur drop shadow — it bled visibly below the card and
     under the pagination bar. A tight shadow, matching the rest of the app's
     cards (--shadow-sm). */
  box-shadow: var(--shadow-sm, 0 1px 2px rgba(35, 32, 28, 0.05));
  overflow: hidden;
  padding: 0 !important;
}
.xpa-table-scroll {
  overflow-x: auto;
}
/* Escape hatch — strips all card chrome back off a child that
   deliberately opts out of the container's own card treatment (e.g. a
   nested table-like element that shouldn't read as its own card). */
.bx--data-table-container .bx--no-context {
  margin: 0 !important;
  border: none !important;
  border-radius: 0 !important;
  box-shadow: none !important;
}

/* ---- Toolbar ----
   Fixes the actual mess: Carbon's own `.bx--toolbar-content` (the wrapper
   around otherActions buttons)
   ships `width: 100%` — a flex CHILD claiming 100% of its container's
   width while sharing that row with the search field as a sibling. That's
   what produced the huge dead gap between the search icon and the action
   buttons: not a spacing/padding gap, but the search field and the
   button-wrapper each fighting for the same row instead of sharing it
   properly. Fixed by giving .bx--toolbar-content its own real flex
   sizing (flex:1 1 auto, width:auto) instead of leaving Carbon's
   default uncontested — the missing piece the previous pass here
   never added (it only styled .bx--search, never .bx--toolbar-content
   at all). Height is content-driven (auto, not a forced min-height) so
   toolbars without a search field compact instead of showing an empty
   band. */
.bx--table-toolbar {
  display: flex;
  align-items: center;
  height: auto !important;
  padding: 14px 24px;
  background: var(--surface);
  border-bottom: 1px solid var(--table-divider);
  /* With overflow:visible (needed so focus rings/dropdowns aren't
     clipped), a tight toolbar must wrap instead of the search field
     painting over the action buttons on narrow widths or with several
     actions present. */
  overflow: visible;
  flex-wrap: wrap;
  /* column gap = breathing room between the search field and the right-side
     action group (sort / filter / export); row gap keeps wrapped rows apart. */
  gap: 8px 16px;
}
/* GenericDataTable always renders a <TableToolbar>; collapse it only when
   it's genuinely empty — no search, no batch actions, and nothing in the
   otherActions slot — so an empty padded bar + divider doesn't sit above the
   column headers. (:has() unsupported → rule dropped → toolbar shows as
   before.) */
.bx--table-toolbar:not(:has(.bx--search)):not(:has(.bx--batch-actions)):not(:has(.bx--toolbar-content > *)) {
  display: none;
}

/* ---- Table toolbar search ----
   GenericDataTable renders a plain Carbon <Search> here, not
   <TableToolbarSearch> — so there's no expand/collapse wrapper to
   fight: a single always-visible 44px pill. Warm fill, hairline border,
   terracotta focus ring, per the universal table spec. The
   `.bx--toolbar-search-container-*` selectors below only matter for the
   couple of screens that still use <TableToolbarSearch> directly
   (e.g. AdminDashboard) — they neutralise its width:100%/height:3rem/
   borderless vendor rules so it lands on the same look. */
.bx--table-toolbar .bx--search {
  flex: 0 1 360px;
  min-width: 180px;
  width: 360px;
  max-width: 100%;
}
.bx--table-toolbar .bx--search-input {
  height: 44px !important;
  min-height: 44px;
  border: 1px solid #e8e3dd !important;
  border-radius: 14px !important;
  background-color: #fcfbf9 !important;
  color: var(--ink, #23201c);
  font-size: 14px;
}
.bx--table-toolbar .bx--search-input:hover:not(:focus):not(:disabled) {
  border-color: var(--xpa-border-hover, #d8d2ca) !important;
}
.bx--table-toolbar .bx--search-input:focus {
  outline: none !important;
  border-color: var(--table-accent, #c46a3a) !important;
  box-shadow: 0 0 0 4px rgba(196, 106, 58, 0.08) !important;
}
.bx--table-toolbar .bx--search .bx--search-close {
  height: 44px;
  width: 44px;
  border-radius: 14px;
}
.bx--table-toolbar .bx--search .bx--search-close::before {
  display: none;
}
/* Only hit when <TableToolbarSearch> is still used directly: undo the
   expandable/persistent wrapper geometry so the field above shows in full. */
.bx--table-toolbar .bx--toolbar-search-container-expandable,
.bx--table-toolbar .bx--toolbar-search-container-persistent,
.bx--table-toolbar .bx--toolbar-search-container-active {
  width: 360px !important;
  max-width: 100%;
  height: 44px !important;
}
.bx--table-toolbar .bx--toolbar-search-container-persistent .bx--search .bx--search-input {
  border: 1px solid #e8e3dd !important;
  padding: 0 2.5rem !important;
}
.bx--table-toolbar .bx--toolbar-search-container-persistent + .bx--toolbar-content {
  width: auto;
}

/* ---- Toolbar action buttons (otherActions) — the actual fix for the
   "fighting for the row" bug, plus a toolbar-scoped button treatment
   (compact 36px, quieter secondary/tertiary/ghost) distinct from this
   app's full 40px standalone buttons elsewhere, matching how the batch-
   actions toolbar also gets its own scoped button treatment rather than
   inheriting the global one verbatim. ---- */
.bx--table-toolbar .bx--toolbar-content {
  display: flex;
  align-items: center;
  gap: 8px;
  height: auto;
  width: auto;
  flex: 1 1 auto;
  /* hug the right edge even if flex-grow is lost to a vendor rule, so the
     action group never crowds the search field on its left */
  margin-left: auto;
  min-width: 0;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.bx--table-toolbar .bx--toolbar-content .bx--btn {
  min-height: 36px !important;
  max-height: 36px;
  align-items: center;
  border-radius: 10px !important;
  padding: 6px 14px !important;
  font-size: 13px;
  font-weight: 500;
  column-gap: 6px;
}
.bx--table-toolbar .bx--toolbar-content .bx--btn--secondary,
.bx--table-toolbar .bx--toolbar-content .bx--btn--tertiary,
.bx--table-toolbar .bx--toolbar-content .bx--btn--ghost {
  background: var(--surface, #ffffff) !important;
  border: 1px solid #e8e3dd !important;
  color: var(--xpa-text-secondary, #5f5a54) !important;
  box-shadow: none !important;
}
.bx--table-toolbar .bx--toolbar-content .bx--btn--secondary:hover,
.bx--table-toolbar .bx--toolbar-content .bx--btn--secondary:focus,
.bx--table-toolbar .bx--toolbar-content .bx--btn--tertiary:hover,
.bx--table-toolbar .bx--toolbar-content .bx--btn--tertiary:focus,
.bx--table-toolbar .bx--toolbar-content .bx--btn--ghost:hover,
.bx--table-toolbar .bx--toolbar-content .bx--btn--ghost:focus {
  background: #f5f2ee !important;
  border-color: #ddd6cf !important;
  color: var(--xpa-text-primary, #23201c) !important;
}
.bx--table-toolbar .bx--toolbar-content .bx--btn svg {
  flex: 0 0 auto;
  fill: currentColor;
}

/* ---- Header ---- */
/* Same color as each th below, painted on the row/group behind them —
   adjacent <th> cells can leave a sub-pixel rendering gap between them
   (a well-known Chrome table-layout quirk at non-integer column widths),
   which without this shows the card's white background bleeding through
   as a thin seam between header columns. Matching the color underneath
   makes any such gap invisible instead of chasing the exact pixel math. */
.bx--data-table thead,
.bx--data-table thead tr {
  background: var(--table-header-bg);
}
.bx--data-table thead th {
  height: 56px;
  background: var(--table-header-bg);
  border-bottom: 1px solid var(--table-border);
  padding: 0 24px;
}
/* Carbon's TableHeader always renders as a <button class="bx--table-sort">
   filling the th (GenericDataTable attaches onClick to every header
   regardless of isSortable) — that button carries its own solid gray fill
   (#e0e0e0, #cacaca on hover) which reads as a mismatched box sitting
   inside the th's cream background, showing up as thin lines framing
   every column header. Neutralize it so the th's own background shows
   through uniformly. */
.bx--data-table thead .bx--table-sort {
  background: transparent;
}
.bx--data-table thead .bx--table-sort:hover {
  background: var(--bg-hover, #f4f2ee);
}
.bx--data-table thead .bx--table-sort:focus {
  outline: 2px solid var(--info, #4f6d95);
  outline-offset: -2px;
}
.bx--data-table thead .bx--table-header-label {
  display: block;
  min-width: 0;
  max-width: 100%;
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #7a746d;
  /* Generic, table-level fix (not a per-page width hack): table-layout is
     auto everywhere (confirmed nowhere in this codebase forces `fixed`), so a
     nowrap header simply makes auto-layout size that column to fit it — every
     GenericDataTable column header, on every page, renders on one line with
     no wrapping and no bleeding into its neighbor, without any column needing
     an explicit width. Ellipsis is only a backstop for a page that *does*
     force a narrow fixed-width column elsewhere — it shouldn't normally
     trigger, since nothing here caps the column below its label's width. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bx--table-sort__icon,
.bx--table-sort__icon-unsorted {
  fill: var(--xpa-text-muted);
}

/* ---- Rows ----
   Carbon paints row backgrounds on the <td>/<th> elements themselves
   (.bx--data-table td{background:#f4f4f4}, tr:hover td{background:#e5e5e5},
   tr.bx--data-table--selected td{background:#e0e0e0}), not on <tr> — a
   child's own background always covers its parent's, so setting these
   colors only on <tr> (as a first pass here did) silently loses to
   Carbon's td-level defaults. Every state below is therefore set on the
   actual td/th, matched to Carbon's own selector shape so specificity
   ties break in our favor by source order alone. */
.bx--data-table tbody tr {
  height: 76px;
  border-bottom: 1px solid var(--table-divider);
}
.bx--data-table td,
.bx--data-table tbody th {
  background: var(--surface, #ffffff);
  transition: background-color 180ms ease;
}
.bx--data-table tbody tr:hover td,
.bx--data-table tbody tr:hover th {
  background: var(--table-surface-hover);
}
/* inset box-shadow, not border-left — a real border would shift cell
   content by its own width; the shadow draws the accent stripe without
   affecting layout. */
.bx--data-table tbody tr.bx--data-table--selected {
  box-shadow: inset 3px 0 0 var(--table-accent);
}
.bx--data-table tbody tr.bx--data-table--selected td,
.bx--data-table tbody tr.bx--data-table--selected th {
  background: #fdf8f5;
}

/* ---- Cell padding + text hierarchy ---- */
.bx--data-table tbody td,
.bx--data-table tbody th {
  padding: 16px 20px;
  /* Carbon ships `vertical-align: top`, which strands single-line text at the
     top of the 76px row with dead space beneath it. Middle is the
     conventional data-table default and what every simple table here wants.
     Tables that need top-alignment (the Job Recommendations panel, whose
     cells are stacked mini-cards of very different heights) opt back in via
     `.xpa-jobrec-table` below. */
  vertical-align: middle;
}
/* The card's own border already closes the surface at the bottom edge —
   the last row doesn't need its own divider floating just above it. */
.bx--data-table tbody tr:last-child td,
.bx--data-table tbody tr:last-child th {
  border-bottom: none !important;
}
.xpa-td-primary {
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
}
.xpa-td-secondary {
  font-size: 14px;
  font-weight: 400;
  color: var(--ink-secondary);
}
.xpa-td-meta {
  font-size: 13px;
  font-weight: 400;
  color: var(--ink-tertiary);
}

/* ---- Avatar cell ---- */
.xpa-table-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 999px;
  background: var(--table-accent-light);
  color: #ae5b30;
  font-size: 15px;
  font-weight: 600;
  flex: 0 0 auto;
}

/* ---- Status badges — reuses the app's existing semantic tokens exactly,
   not new colors. ---- */
.xpa-status-badge {
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 12px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
}
.xpa-status-badge--success { background: var(--success-soft); color: var(--success); }
.xpa-status-badge--warning { background: var(--warning-soft); color: var(--warning); }
.xpa-status-badge--error { background: var(--danger-soft); color: var(--danger); }
.xpa-status-badge--neutral { background: #f6f2ed; color: var(--ink-secondary); }

/* ---- Number pills — e.g. "16 Years" instead of plain text ----
   Blue-tinted (--info-soft/--info, the same real-blue accent used for the
   active pill-tab) rather than a neutral warm fill, so it
   reads more like a distinct, glanceable metric against the row's plain
   text columns than a neutral tag would. */
.xpa-number-pill {
  display: inline-flex;
  align-items: center;
  height: 30px;
  padding: 0 12px;
  border-radius: 999px;
  background: var(--info-soft, #eef3f9);
  font-size: 14px;
  font-weight: 600;
  color: var(--info, #4f6d95);
}

/* ---- Row actions menu — re-skins Carbon's OverflowMenu (the "•••"
   trigger), already the standard row-actions pattern in this app. ---- */
.bx--data-table .bx--overflow-menu {
  width: 36px;
  height: 36px;
  border-radius: 10px;
}
.bx--data-table .bx--overflow-menu:hover,
.bx--data-table .bx--overflow-menu--open {
  background: #f5f2ee;
}

/* ---- Row-selection checkbox ----
   The box keeps Carbon's native 1rem size on purpose: Carbon draws the tick
   as a CSS-border `::after` whose position, size and `transform-origin`
   (bottom right) are pixel-tuned to a 1rem box. Resizing `::before` without
   redoing that whole `::after` geometry left the tick sitting low and left
   of centre — so only the fill colour is themed here. */
.bx--data-table .bx--checkbox:checked + .bx--checkbox-label::before,
.bx--data-table .bx--checkbox:indeterminate + .bx--checkbox-label::before {
  background-color: var(--table-accent) !important;
  border-color: var(--table-accent) !important;
}
/* Carbon hardcodes the select-all checkbox's OWN header cell to a raw grey
   (#e0e0e0, #cacaca on hover) via `.bx--data-table th.bx--table-column-
   checkbox` — 2 classes + 1 type = higher specificity than the plain
   `.bx--data-table thead th` header-background rule above, so it silently
   wins and leaves a mismatched grey patch at the start of every header
   row regardless of load order. Matching its exact selector shape here
   (rather than adding !important, which would also have to fight the
   :hover variant's own specificity) is what actually beats it. */
.bx--data-table th.bx--table-column-checkbox {
  background: var(--table-header-bg);
}
.bx--data-table th.bx--table-column-checkbox:hover {
  background: var(--table-header-bg);
}

/* ---- Misc table refinements — remaining pieces not covered above ---- */

/* Column alignment utility — apply to a header's className (headers[].className) */
.bx--data-table-v2 thead th .text-center {
  display: block;
}
.text-center .bx--table-header-label {
  text-align: center !important;
}

/* Carbon <Tag> used inside a cell — pill shape instead of Carbon's
   default rounded-rect. */
.bx--data-table .bx--tag {
  border-radius: 999px;
  font-weight: 500;
}

/* Avatar + name pair layout — distinct from .xpa-table-avatar (the
   avatar chip itself); this is the gap between the chip and the name
   text next to it. */
.xpa-avatar-name-row {
  column-gap: 0.5rem;
}

/* Lightweight row-action icon button — plain icon, no button chrome at
   rest, for tables that want a quieter action column than a full Carbon
   <Button> or the OverflowMenu treatment above. Also the only
   :focus-visible rule in this whole table system — worth keeping since
   nothing else here (headers, rows, checkboxes) has an explicit
   keyboard-focus style otherwise. */
.xpa-icon-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--xpa-text-secondary);
  cursor: pointer;
  transition: background-color 150ms ease-out;
}
.xpa-icon-action:hover:not(:disabled) {
  background-color: var(--xpa-bg-hover);
}
.xpa-icon-action:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.xpa-icon-action:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

/* Sticky action column — a narrow (35px) leading column (checkbox/icon)
   that stays pinned to the left edge while the table body scrolls
   horizontally. Apply .actionable to the header/cell, add .sticky to
   pin it. */
.bx--data-table th.actionable,
.bx--data-table td.actionable {
  width: 35px;
  z-index: 30;
  padding: 0.6rem 0.6rem 0 0.6rem !important;
}
.actionable.sticky {
  position: sticky !important;
  inset-inline-start: 0;
}

/* Horizontal-scroll wrapper for tables that don't use the full
   .bx--data-table-container card treatment — a thin but always-VISIBLE
   scrollbar. A hidden scrollbar here previously left wide tables'
   rightmost columns unreachable. */
.x-table-scroll,
.x-table-scroll-nt {
  overflow-x: auto;
  scrollbar-width: thin;
  scrollbar-color: #d8d2ca transparent;
}
.x-table-scroll::-webkit-scrollbar,
.x-table-scroll-nt::-webkit-scrollbar {
  height: 10px;
  background-color: transparent;
}
.x-table-scroll::-webkit-scrollbar-track,
.x-table-scroll-nt::-webkit-scrollbar-track {
  background-color: transparent;
}
.x-table-scroll::-webkit-scrollbar-thumb,
.x-table-scroll-nt::-webkit-scrollbar-thumb {
  background-color: #d8d2ca;
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: content-box;
}

/* "Undecorated" table mode — flat black-on-white, no hover tint anywhere
   (header, pagination, or body). Apply to the same wrapper as
   .bx--data-table-container for tables that shouldn't read as a
   colorful card. */
.simple-table .bx--data-table th,
.simple-table .bx--data-table thead,
.simple-table .bx--pagination,
.simple-table .bx--pagination .bx--pagination__text {
  color: #000 !important;
  background-color: #fff !important;
}
.simple-table .bx--data-table th {
  text-transform: uppercase !important;
  font-size: 13px;
}
.simple-table .bx--data-table tr:hover,
.simple-table .bx--data-table tbody th:hover,
.simple-table .bx--data-table tbody td,
.simple-table .bx--data-table tbody td:hover {
  background-color: #fff !important;
}

/* Hides the "items per page" selector — for contexts where page size
   shouldn't be configurable. */
.hide-page-size .bx--pagination__left {
  display: none !important;
}

/* ---- Pagination ----
   The `<Pagination>` bar is ALWAYS a table's footer, but every page wraps
   `GenericDataTable` + `<Pagination>` in different (or no) markup, so past
   `:has(+ sibling)` welds only fired on some pages — elsewhere the bar was
   left as an unstyled white strip detached from the table, with a gap
   (the table's heavy 30px drop-shadow bleeding through).
   Now the bar carries the footer look on ITSELF, no relational check
   needed: side + bottom border matching the table card, bottom corners
   rounded, no top border, `margin-top: 0`. The table shadow is dropped to
   `--shadow-sm` so nothing bleeds under it. A best-effort `:has()` weld
   below additionally flattens the table's own bottom where it can reach.
   Prev/next arrows: Carbon renders them as `<Button kind="ghost"
   hasIconOnly>` — full `.bx--btn` chrome + a 13rem `::after` / assistive
   tooltip. Stripped to a plain 36px icon target; tooltip removed (keeps
   `aria-label`, span left sr-only). */
.bx--pagination {
  min-height: 56px;
  align-items: center;
  font-size: 14px;
  background: var(--surface);
  /* A pagination bar is always a table's footer. Rather than fight every
     page's different wrapper markup with a `:has()` weld (the prior two
     passes here), the bar just assumes it: side + bottom border matching
     the table card, bottom corners rounded, no top border, flush (no gap).
     The `:has()` weld below additionally flattens the table's own bottom
     where it can reach, for a perfectly seamless join. */
  border: 1px solid var(--table-border);
  border-top: none;
  border-radius: 0 0 20px 20px;
  margin-top: 0;
}
.bx--pagination__left,
.bx--pagination__right {
  align-items: center;
}
.bx--pagination__text {
  color: var(--xpa-text-secondary) !important;
  font-size: 13px;
}
.bx--pagination .bx--select-input {
  min-width: auto;
  height: auto;
  border: none !important;
  background-color: transparent !important;
  color: var(--xpa-text-primary);
  font-size: 13px;
  font-weight: 500;
  /* Carbon reserves 2.25rem for the chevron — tighten so the number and
     its dropdown arrow sit together instead of drifting apart. */
  padding: 0 26px 0 12px !important;
}
.bx--pagination .bx--select__arrow {
  inset-inline-end: 8px;
}
/* Carbon builds these as <Button kind="ghost" hasIconOnly> — they arrive
   carrying the full `.bx--btn` / `.bx--btn--ghost` chrome (40px min-height,
   border, hover border, an oversized `::after` "Previous page" tooltip that
   renders as a 13rem dark box). Strip all of it back to a plain 36px
   icon hit-target. */
.bx--pagination__button.bx--btn,
.bx--pagination__button {
  width: 36px !important;
  min-width: 36px !important;
  height: 36px !important;
  min-height: 36px !important;
  max-height: 36px !important;
  padding: 0 !important;
  border: none !important;
  border-radius: var(--radius-sm, 6px) !important;
  margin-inline: 2px !important;
  box-shadow: none !important;
  transform: none !important;
  background: transparent !important;
  transition: background-color 150ms ease;
}
/* the caret glyph is 16px inside a bigger box — nudge it up a touch */
.bx--pagination__button svg,
.bx--pagination__button .bx--btn__icon {
  width: 18px;
  height: 18px;
  fill: var(--ink-secondary, #5f5a54);
}
/* Kill Carbon's icon-only hover/focus tooltip: the `::before` caret + the
   `.bx--assistive-text` span that renders as a 13rem dark "Previous page"
   box on hover (it was overlapping the table). The button keeps its
   `aria-label`, and the span is left in the DOM as sr-only so nothing is
   lost for screen readers — just no visible bubble on a plain ◂ / ▸. */
.bx--pagination__button::before,
.bx--pagination__button::after {
  display: none !important;
  content: none !important;
}
.bx--pagination__button .bx--assistive-text {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  border: 0 !important;
  overflow: hidden !important;
  clip: rect(0 0 0 0) !important;
  white-space: nowrap !important;
  background: transparent !important;
  box-shadow: none !important;
  opacity: 0 !important;
  pointer-events: none !important;
}
.bx--pagination__right {
  padding-inline-end: 10px;
}
.bx--pagination__button:hover:not(:disabled):not(.bx--pagination__button--no-index),
.bx--pagination__button.bx--btn:hover:not(:disabled):not(.bx--pagination__button--no-index) {
  background: var(--surface-hover, #f4f2ee) !important;
  border: none !important;
}
.bx--pagination__button:focus,
.bx--pagination__button.bx--btn:focus {
  outline: none !important;
  box-shadow: none !important;
}
.bx--pagination__button:focus-visible {
  outline: 2px solid var(--info, #4f6d95) !important;
  outline-offset: -2px;
}
/* disabled prev/next (on the first / last page) — muted, no hover fill */
.bx--pagination__button:disabled,
.bx--pagination__button:disabled:hover,
.bx--pagination__button--no-index,
.bx--pagination__button--no-index:hover,
.bx--pagination__button.bx--btn:disabled {
  background: transparent !important;
  cursor: not-allowed;
  opacity: 0.3;
}

.bx--data-table tbody tr:last-child td {
  border-bottom: none !important;
}
/* The pagination footer look is on `.bx--pagination` itself (above). This
   just flattens the TABLE's own bottom edge where a pagination follows its
   wrapper, so the two join with no seam. The wrapper varies per page, so it
   checks "an element that contains a table container AND is immediately
   followed by a pagination". Skipped inside `.xpa-record-panel`. */
*:has(.bx--data-table-container):has(+ .bx--pagination):not(.xpa-record-panel *) .bx--data-table-container {
  border-bottom: none !important;
  border-bottom-left-radius: 0 !important;
  border-bottom-right-radius: 0 !important;
  box-shadow: none !important;
}
/* Inside a SectionTabsLayout card the table already has its chrome stripped —
   the pagination is just a flat strip with a top divider, not its own card. */
.sections-top-view .bx--pagination {
  border: none;
  border-top: 1px solid var(--table-divider, #f3f0ec);
  border-radius: 0;
}

/* ---- Batch actions (GenericDataTable's `batchActions` prop) ----
   swacch_tron's treatment: Carbon's raw blue (#0f62fe) bar becomes a PALE
   tint of its primary (`color-mix(--primary-color 15%, #fff)`), "N selected"
   takes the primary colour, and the buttons are a solid, square, full-height
   fill of the darker primary shade — one continuous two-tone bar. That
   tenant's `--primary-color` is a dark neutral, so it renders as light-grey
   bar + dark-grey buttons; rpfe's dark neutral is `--ink`, used the same way
   through the same formulas. rpfe's global .bx--btn--primary also adds a
   near-black border + shadow that reads as chunky separated blocks on this
   bar, so that chrome is stripped back off below. */
.bx--batch-actions {
  padding-inline-end: 1rem !important;
  background-color: var(--surface-muted, #f5f3f0) !important;
  background-color: color-mix(in srgb, var(--ink, #23201c) 15%, #ffffff) !important;
}
.bx--batch-actions .bx--batch-summary {
  color: var(--ink, #23201c) !important;
}
.bx--batch-actions .bx--action-list {
  top: 0;
  height: 100%;
  align-items: stretch;
}
.bx--batch-actions .bx--action-list .bx--btn,
.bx--table-toolbar .bx--batch-actions .bx--action-list .bx--btn {
  height: 100%;
  max-height: none;
  margin: 0 !important;
  border: none !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  /* Same warm dark grey as every other primary button — these ARE
     .bx--btn--primary, same as in swacch_tron. */
  background-color: var(--xpa-btn-primary-bg, #4c4842) !important;
  color: #fff !important;
  padding: calc(0.875rem - 3px) 15px calc(0.875rem - 3px) 15px !important;
}
.bx--batch-actions .bx--action-list .bx--btn:hover {
  background-color: var(--xpa-btn-primary-bg-hover, #3b3833) !important;
}
.bx--batch-actions .bx--action-list .bx--btn .bx--btn__icon {
  fill: #fff !important;
}
/* Carbon's filled "+" icons carry a two-tone inner path in a darker shade
   meant for light backgrounds — reset it so it inherits white here too. */
.bx--batch-actions .bx--action-list .bx--btn .bx--btn__icon path[data-icon-path='inner-path'] {
  fill: initial !important;
}
.bx--btn--primary.bx--batch-summary__cancel::before {
  content: none !important;
}
/* Stacking fix — without this the active batch bar can render behind
   other toolbar/page content instead of floating above it. */
.bx--batch-actions--active {
  z-index: 1111;
}

/* Batch summary as its own banner row, only once there are enough batch
   actions (>4) that Carbon's own absolutely-positioned "N selected" text
   (which sits at the bar's left edge, .bx--action-list at its right edge,
   both position:absolute within the same row) risks landing on top of
   the first action button instead of beside it. GenericDataTable.js adds
   the "xpa-actionlist-position" class + renders .xpa-batch-summary-banner
   only in that case — below 4 actions there's always room, so Carbon's
   default positioning is left alone. */
.xpa-actionlist-position .bx--batch-summary {
  display: none;
}
.xpa-actionlist-position .bx--action-list {
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(35, 32, 28, 0.3) transparent;
}
.xpa-actionlist-position .bx--action-list::-webkit-scrollbar {
  height: 6px;
  background-color: transparent;
}
.xpa-actionlist-position .bx--action-list::-webkit-scrollbar-thumb {
  background-color: rgba(35, 32, 28, 0.3);
  border-radius: 999px;
}
.xpa-batch-summary-banner {
  display: flex;
  align-items: center;
  padding: 10px 20px;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink, #23201c);
  background: var(--primary-soft, #f0f0f0);
  border-bottom: 1px solid var(--table-border);
  border-radius: 20px 20px 0 0;
}

/* ---- Empty state — utility class for callers to wrap their "no results"
   message in. ---- */
.xpa-table-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 20px;
  padding: 64px 24px;
  text-align: center;
}
.xpa-table-empty-state__icon {
  font-size: 56px;
  color: var(--ink-tertiary);
}
.xpa-table-empty-state__title {
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
}
.xpa-table-empty-state__subtitle {
  font-size: 14px;
  color: var(--ink-secondary);
}

/* ---- Loading skeleton (GenericDataTable's `loading` prop) ----
   Carbon's <SkeletonText> ships with square corners: its ::before shimmer
   is a full-size absolutely-positioned overlay with no radius of its own,
   so rounding the <p> alone does nothing — `overflow: hidden` clips that
   overlay to the rounded box. Colours (the #e5e5e5 rest / #c6c6c6 sweep)
   are Carbon's own, left as-is. */
.xpa-table-skeleton .bx--skeleton__text {
  border-radius: var(--radius-sm, 6px);
  overflow: hidden;
}

/* ==== AppTooltip ============================================================
   See src/components/common/AppTooltip.js. The reference this was based on
   styled this pill with Tailwind utility classes (tw-rounded-lg, tw-px-2.5,
   tw-shadow-lg, etc.) —
   this app has no Tailwind, so it's translated 1:1 into plain CSS here
   using this file's own token scale instead of Tailwind's. */
.xpa-tooltip {
  position: fixed;
  z-index: 9999;
  pointer-events: none;
  width: max-content;
  max-width: 260px;
  border-radius: var(--radius-md);
  padding: 6px 10px;
  font-size: var(--font-size-xs);
  font-weight: 500;
  line-height: 16px;
  /* Deliberately not nowrap — width:max-content already keeps a short
     tooltip snug to its content; longer text needs to wrap instead of
     overflowing max-width unclipped (nowrap forced this to render past
     the pill's own background, "ghost" text bleeding out to the right). */
  white-space: normal;
  box-shadow: var(--shadow-lg);
  background-color: var(--ink);
  color: #fff;
  transition: opacity 100ms;
  opacity: 0;
}
.xpa-tooltip--shown {
  opacity: 1;
}

/* ==== Facet / section nav list (SingleLinkFacetCustom) =====================
   Unscoped/global here — rpfe doesn't yet
   have an equivalent page to scope it to, and nothing else in the app uses
   these Elastic Search UI class names today, so styling them globally is
   safe and makes the component work out of the box wherever it's dropped
   in (a real <Facets><SingleLinkFacetCustom/></Facets> or standalone). */
.sui-facet__title {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-tertiary);
  margin: 0 0 8px;
}
.sui-single-option-facet {
  list-style: none;
  padding: 0;
  margin: 0;
}
.sui-single-option-facet__item {
  display: block;
  margin: 2px 0;
  border-radius: var(--radius-sm);
}
.sui-single-option-facet__link {
  display: flex;
  align-items: center;
  min-height: 36px;
  padding: 6px 12px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  font-weight: 400;
  color: var(--ink-secondary);
  text-decoration: none;
  transition: background-color 150ms ease, color 150ms ease;
}
.sui-single-option-facet__link:hover {
  background-color: var(--xpa-bg-hover);
  color: var(--ink);
  text-decoration: none;
}
.sui-single-option-facet__link.active {
  background-color: var(--xpa-bg-hover);
  color: var(--ink);
  font-weight: 600;
}

/* Standalone "section label" utility — the same small uppercase muted
   heading treatment as .sui-facet__title above, but not tied to the
   Elastic-specific markup, so it can label any cluster of controls
   (tabs, filters, a nav list) with a consistent heading style. */
.xpa-section-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-tertiary);
  margin: 0 0 8px;
}

/* ---- Pill-tab variant of SingleLinkFacetCustom ----
   A horizontal row of fully-rounded pills instead of the vertical list
   above — inactive = quiet bordered-gray pill, active = a soft blue
   fill/border/text, not a solid block. This app's own `--blue`/`--blue-soft`/
   `--blue-border` tokens were repurposed elsewhere for near-black button
   theming (`--blue: #111111`), so genuinely-blue `--info`/`--info-soft` are
   used instead for the active state — same "quiet informational accent"
   intent, correct color.
   Scoped under .xpa-section-pills (applied via SingleLinkFacetCustom's
   `className` prop) so it doesn't affect the vertical-list default above.
   !important throughout: @elastic/react-search-ui-views ships its own
   styles.css (imported directly in JobList.js) with an unconditional
   `.sui-single-option-facet__link { font-weight: bold }` — same (0,2,0)
   specificity as this rule's own :hover state, so a specificity tie is
   possible depending on exact bundle order; !important removes the
   ambiguity rather than relying on load-order to keep winning it.

   The strip is also a card HEADER: on a list page it renders as a
   full-width white bar (hairline, top-rounded, divider under the pills)
   that sits flush on top of the table card below it, so pills + toolbar +
   table read as one card. Inside a
   dashboard widget it stays a lightweight inline label row — the widget's
   own .xpa-dashboard-section is already the card. */
.xpa-section-pills {
  display: block;
  width: 100%;
  margin: 0 0 16px;
  padding: 12px 16px;
  background: var(--surface);
  border: 1px solid var(--table-border, #ece7e1);
  border-radius: 20px;
}
/* When a table card follows the strip (directly, or nested in the next
   sibling), the strip becomes the card's top: square its bottom corners,
   add the divider, drop the gap, and flatten the table card's top so the
   two fuse into one card. */
.xpa-section-pills:has(+ .bx--data-table-container),
.xpa-section-pills:has(+ .table-responsive .bx--data-table-container),
.xpa-section-pills:has(+ div .bx--data-table-container),
.xpa-section-pills:has(+ .bx--row .bx--data-table-container) {
  margin-bottom: 0;
  border-bottom: 1px solid var(--table-divider, #f3f0ec);
  border-radius: 20px 20px 0 0;
}
.xpa-section-pills + .bx--data-table-container,
.xpa-section-pills + .table-responsive .bx--data-table-container,
.xpa-section-pills + div .bx--data-table-container,
.xpa-section-pills + .bx--row .bx--data-table-container {
  border-top: none;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}
/* Dashboard widgets (and any other in-card use): keep it inline, no bar. */
.xpa-dashboard-section .xpa-section-pills,
.xpa-tabs-wrapper .xpa-section-pills,
.bx--tile .xpa-section-pills {
  display: inline-flex;
  width: auto;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
}

.xpa-section-pills .sui-single-option-facet {
  display: flex !important;
  flex-wrap: wrap !important;
  align-items: center !important;
  gap: 10px !important;
  background: transparent !important;
}
.xpa-section-pills .sui-facet,
.xpa-section-pills .sui-facet > div {
  background: transparent !important;
}
.xpa-section-pills .sui-single-option-facet__item {
  margin: 0 !important;
  padding: 0 !important;
  border-radius: 999px !important;
  background: transparent !important;
  display: inline-flex !important;
}
.xpa-section-pills .sui-single-option-facet__link {
  height: 36px !important;
  min-height: 0 !important;
  padding: 0 16px !important;
  border-radius: 999px !important;
  background: var(--bg-subtle) !important;
  border: 1px solid var(--border) !important;
  color: var(--ink-secondary) !important;
  font-size: 13px !important;
  font-weight: 500 !important;
  white-space: nowrap !important;
}
.xpa-section-pills .sui-single-option-facet__link:hover {
  background: var(--xpa-bg-hover) !important;
  border-color: var(--border) !important;
  color: var(--ink) !important;
  font-weight: 500 !important;
}
.xpa-section-pills .sui-single-option-facet__link.active {
  background: var(--info-soft) !important;
  border-color: var(--info) !important;
  color: var(--info) !important;
  font-weight: 500 !important;
}
.xpa-section-pills .sui-single-option-facet__link:after {
  display: none !important;
}

/* ---- Record-page tab bar: SingleLinkFacetCustom
   className="xpa-section-pills xpa-record-tab-bar" — the page-level tab
   strip. Used on the campus Student Profile page (StudentProfileView top
   nav). Standalone bordered bar with breathing room by default; when a
   SectionTabsLayout card follows it (Profile Views tab) the two fuse into
   one card — the page pills become its top strip, above the section
   pills. */
.xpa-record-tab-bar {
  margin-top: 24px !important;
  margin-bottom: 24px !important;
  border-color: var(--table-border, #ece7e1) !important;
}
.xpa-record-tab-bar:has(+ .sections-top-view) {
  margin-bottom: 0 !important;
  border-bottom-color: var(--table-divider, #f3f0ec) !important;
  border-radius: 20px 20px 0 0 !important;
}
.xpa-record-tab-bar + .sections-top-view {
  margin-top: 0 !important;
}
.xpa-record-tab-bar + .sections-top-view > .sui-layout > .sui-layout-body > .sui-layout-body__inner {
  border-top: 0 !important;
  border-top-left-radius: 0 !important;
  border-top-right-radius: 0 !important;
}

/* ---- Record-page content panel: `.xpa-record-panel` wraps a whole tab's
   render (StudentProfileView Job Recommendations / Settings) so the table,
   its pagination and any footnote read as one card instead of loose
   elements + a nested Carbon table-card on the page background. */
.xpa-record-panel {
  position: relative;
  background: var(--surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 20px 24px;
  margin-bottom: 20px;
}
.xpa-record-panel::before {
  content: '';
  position: absolute;
  inset: 0;
  border: 0.92px solid rgba(239, 240, 246, 1);
  border-radius: inherit;
  pointer-events: none;
}
.xpa-record-panel__title {
  margin: 0 !important;
  font-family: var(--font-heading);
  font-size: 15px !important;
  font-weight: 600 !important;
  line-height: 1.3 !important;
  color: var(--ink);
}
.xpa-record-panel > hr {
  margin: 12px 0 16px;
  border: 0;
  border-top: 1px solid var(--border-subtle);
}
.xpa-record-panel > .d-flex.justify-content-end {
  margin-bottom: 12px;
}
/* the data table + its toolbar sit inside this panel — drop their own
   card chrome so it doesn't read as a card within a card. */
.xpa-record-panel .bx--data-table-container,
.xpa-record-panel .bx--table-toolbar {
  border: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  background: transparent !important;
}
/* pagination — a flat row with just a hairline above it. */
.xpa-record-panel .bx--pagination {
  margin: 0 !important;
  border: 0 !important;
  border-top: 1px solid var(--border-subtle) !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  background: transparent !important;
}
/* footnote / explainer beneath the table (e.g. the "Recommended Badge"
   text on Job Recommendations) — a quiet note, not body copy. */
.xpa-record-panel__note {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--border-subtle);
  font-size: 12px;
  line-height: 1.6;
  color: var(--ink-secondary);
}
.xpa-record-panel__note p {
  margin: 0 0 8px;
}
.xpa-record-panel__note .ml-3 {
  margin-left: 16px !important;
}
.xpa-record-panel__note .xpa-link {
  color: var(--link);
}

/* ---- Top-aligned tables — opt-in via `className="xpa-table-top"` on the
   GenericDataTable. For tables whose rows are stacked "card" cells of very
   different heights per column (Job Recommendations; the Companies /
   Institutions / Students / Employees browse lists — avatar block beside a
   status-tag stack), where the standard middle alignment would float the
   shorter column against the middle of the taller one. Every plain data
   table keeps `vertical-align: middle` from the base rule above. */
.xpa-table-top .bx--data-table tbody td,
.xpa-table-top .bx--data-table tbody th {
  vertical-align: top;
}
.xpa-jobrec-job {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  padding: 2px 0;
}
.xpa-jobrec-job__name {
  font-size: 14px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--link);
  text-transform: capitalize;
}
.xpa-jobrec-job__name:hover {
  color: var(--link-hover);
  text-decoration: underline;
}
.xpa-jobrec-job__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 10px;
  font-size: 12px;
  color: var(--ink-tertiary);
}
.xpa-jobrec-job__id {
  font-variant-numeric: tabular-nums;
}
.xpa-jobrec-job__tag {
  display: inline-flex;
  align-items: center;
  height: 18px;
  padding: 0 8px;
  border-radius: var(--radius-pill);
  background: var(--info-soft);
  color: var(--info);
  font-size: 11px;
  font-weight: 600;
}
.xpa-jobrec-job__sen--danger { color: var(--danger); }
.xpa-jobrec-job__sen--success { color: var(--success); }
.xpa-jobrec-job__sen--muted { color: var(--ink-tertiary); }
.xpa-jobrec-job__skills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.xpa-jobrec-job__skill {
  display: inline-flex;
  align-items: center;
  max-width: 160px;
  height: 20px;
  padding: 0 8px;
  border-radius: var(--radius-sm);
  background: var(--surface-muted);
  border: 1px solid var(--border-subtle);
  color: var(--ink-secondary);
  font-size: 11px;
  text-transform: capitalize;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.xpa-jobrec-company {
  text-transform: capitalize;
  color: var(--ink);
}
.xpa-jobrec-rank {
  font-weight: 600;
  color: var(--ink);
}
.xpa-jobrec-scores {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.xpa-jobrec-scores__row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--ink-secondary);
}
.xpa-jobrec-scores__row > div,
.xpa-jobrec-scores__row > div > div {
  margin: 0 !important;
}
.xpa-jobrec-action {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.xpa-jobrec-action__error {
  max-width: 220px;
  font-size: 11px;
  line-height: 1.4;
  text-align: left;
  color: var(--danger);
}

/* ==== "sections-top-view" — Elastic <Layout> with the section facet as the
   card's top strip ========================================================
   Wrap a
   <Layout> in <div className="sections-top-view"> and pass the section nav
   as sideContent (<Facets><SingleLinkFacetCustom/></Facets>). The sidebar
   column is flipped to a full-width horizontal pill strip at the top, and
   the whole Layout body renders as ONE bordered card — pill strip, the
   bodyHeader toolbar, and the table all inside a single surface, no seams.
   !important throughout: fights react-search-ui-views' own styles.css and
   JobList.css's global `.sui-layout-sidebar { width:20% !important }`.
   Rendered via the <SectionTabsLayout> component (or inline). */
.sections-top-view {
  margin-bottom: 20px;
}
.sections-top-view > .sui-layout {
  background: transparent !important;
  min-height: 0 !important;
}
.sections-top-view > .sui-layout > .sui-layout-header {
  display: none !important;
}
.sections-top-view > .sui-layout > .sui-layout-body {
  background: transparent !important;
  padding: 0 !important;
}
/* styles.css appends an 80px `linear-gradient(#fcfcfc, #fff)` pseudo-element
   after the body — a stray light slab inside our card. Kill it. */
.sections-top-view > .sui-layout > .sui-layout-body::after,
.sections-top-view > .sui-layout > .sui-layout-body:after {
  display: none !important;
  content: none !important;
}
.sections-top-view > .sui-layout > .sui-layout-body > .sui-layout-body__inner {
  display: flex !important;
  flex-direction: column !important;
  max-width: none !important;
  margin: 0 !important;
  padding: 0 !important;
  background: var(--surface) !important;
  border: 1px solid var(--table-border, #ece7e1) !important;
  border-radius: 20px !important;
  overflow: hidden !important;
}
.sections-top-view > .sui-layout > .sui-layout-body > .sui-layout-body__inner > .sui-layout-sidebar {
  width: 100% !important;
  order: 0 !important;
  flex: 0 0 auto !important;
  padding: 14px 16px !important;
  margin: 0 !important;
  background: var(--surface) !important;
  border: none !important;
  border-bottom: 1px solid var(--table-divider, #f3f0ec) !important;
  /* Soft downward elevation so the pill strip reads as the card's raised
     header. position/z-index keep it above the sticky toolbar (z-index 4)
     so the shadow falls onto the toolbar rather than being painted over. */
  position: relative !important;
  z-index: 5 !important;
  box-shadow: 0 3px 8px rgba(35, 32, 28, 0.05) !important;
  filter: none !important;
}
.sections-top-view > .sui-layout > .sui-layout-body > .sui-layout-body__inner > .sui-layout-sidebar:empty {
  display: none !important;
}
.sections-top-view > .sui-layout > .sui-layout-body > .sui-layout-body__inner > .sui-layout-main {
  width: 100% !important;
  order: 1 !important;
  padding: 0 !important;
  min-width: 0 !important;
  max-width: 100% !important;
  overflow: hidden !important;
}
/* Superseded by GenericDataTable.js's own `.xpa-table-scroll` wrapper (see the
   Container section above) — the toolbar is now structurally outside the
   table's scroll region everywhere, not just here, so it never needs sticky
   positioning to "stay put": it was never part of the scrolled content. Kept:
   layout-constraint-only rules, and a plain (non-sticky) position + z-index
   on the toolbar so it still stacks correctly under the pill strip's shadow
   (z-index 5, above). */
.sections-top-view .sui-layout-main-body {
  min-width: 0 !important;
  max-width: 100% !important;
}
.sections-top-view .sui-layout-main .bx--table-toolbar {
  position: relative !important;
  z-index: 4 !important;
  background: var(--surface, #fff) !important;
}
/* Section strip contents: hide the facet heading, lay the links out as a
   horizontal pill row (reuses the .xpa-section-pills look). */
.sections-top-view .sui-layout-sidebar .sui-facet__title {
  display: none !important;
}
/* Every wrapper between the sidebar strip and the pill <ul> — the
   <Facets> container, SingleLinkFacetCustom's own (class-less) root div,
   .sui-facet and its inner div — must be fully see-through so nothing
   paints a band behind the pills. Only the active pill itself has a fill. */
.sections-top-view .sui-layout-sidebar > div,
.sections-top-view .sui-layout-sidebar .sui-facet-container,
.sections-top-view .sui-layout-sidebar .sui-facet-container > div,
.sections-top-view .sui-layout-sidebar .sui-facets,
.sections-top-view .sui-layout-sidebar .sui-facet,
.sections-top-view .sui-layout-sidebar .sui-facet > div {
  background: transparent !important;
  background-color: transparent !important;
  border: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  margin: 0 !important;
  padding: 0 !important;
}
.sections-top-view .sui-layout-sidebar .sui-single-option-facet {
  list-style: none !important;
  margin: 0 !important;
  padding: 0 !important;
  background: transparent !important;
  border: 0 !important;
  display: flex !important;
  flex-wrap: wrap !important;
  align-items: center !important;
  gap: 10px !important;
}
.sections-top-view .sui-layout-sidebar .sui-single-option-facet__item {
  margin: 0 !important;
  padding: 0 !important;
  background: transparent !important;
  border-radius: 999px !important;
  display: inline-flex !important;
}
.sections-top-view .sui-layout-sidebar .sui-single-option-facet__item:hover {
  background: transparent !important;
}
.sections-top-view .sui-layout-sidebar .sui-single-option-facet__link {
  display: inline-flex !important;
  align-items: center !important;
  height: 36px !important;
  min-height: 0 !important;
  padding: 0 16px !important;
  border-radius: 999px !important;
  background: var(--bg-subtle) !important;
  border: 1px solid var(--border) !important;
  color: var(--ink-secondary) !important;
  font-size: 13px !important;
  font-weight: 500 !important;
  line-height: 1 !important;
  white-space: nowrap !important;
  text-decoration: none !important;
}
.sections-top-view .sui-layout-sidebar .sui-single-option-facet__link:hover {
  background: var(--xpa-bg-hover) !important;
  color: var(--ink) !important;
}
.sections-top-view .sui-layout-sidebar .sui-single-option-facet__item.active,
.sections-top-view .sui-layout-sidebar .sui-single-option-facet__link.active {
  background: var(--info-soft) !important;
}
.sections-top-view .sui-layout-sidebar .sui-single-option-facet__link.active {
  border-color: var(--info) !important;
  color: var(--info) !important;
  font-weight: 500 !important;
}
.sections-top-view .sui-layout-sidebar .sui-single-option-facet__link:after {
  display: none !important;
}
/* bodyHeader toolbar — a padded row under the strip, inside the same card */
.sections-top-view .sui-layout-main-header {
  padding: 10px 16px !important;
  border-bottom: 1px solid var(--table-divider, #f3f0ec) !important;
}
.sections-top-view .sui-layout-main-header__inner {
  max-width: none !important;
  margin: 0 !important;
  padding: 0 !important;
}
.sections-top-view .sui-layout-main-header .sui-paging-info {
  margin: 0 !important;
  font-size: 12px !important;
  color: var(--ink-secondary) !important;
}
.sections-top-view .sui-layout-main-header .sui-paging-info em {
  font-style: normal;
  font-weight: 600;
  color: var(--ink);
}
.sections-top-view .sui-layout-main-header:empty,
.sections-top-view .sui-layout-main-header__inner:empty {
  display: none !important;
  padding: 0 !important;
  border: none !important;
}
/* No bodyHeader → collapse the row entirely. Elastic's <Layout> always
   renders `.sui-layout-main-header > .sui-layout-main-header__inner`, so the
   outer is never itself `:empty` even with no toolbar — it just wraps an
   empty inner, and would otherwise keep its 10px padding + 1px border and
   show as a stray divider under the pills. Kept in its own rule so a browser
   without :has() support just drops this one (the :empty rule above still
   stands) rather than the whole group. */
.sections-top-view .sui-layout-main-header:has(> .sui-layout-main-header__inner:empty) {
  display: none !important;
  padding: 0 !important;
  border: none !important;
}
.sections-top-view .sui-layout-main-body {
  padding: 0 !important;
}
.sections-top-view .sui-layout-main-footer {
  display: none !important;
}
/* The data table is already inside the card — strip its own card chrome. */
.sections-top-view .sui-layout-main .bx--data-table-container,
.sections-top-view .xpa-jobs-data-card .bx--data-table-container {
  border: none !important;
  border-radius: 0 !important;
  box-shadow: none !important;
}

/* Opt-in (`padded` prop on <SectionTabsLayout>): a data table brings its own
   cell padding so the body defaults to none — a non-table body (forms, detail
   panels, accordions) needs real padding. Later source order + !important
   beats the `.sui-layout-main-body { padding: 0 !important }` rule above. */
.sections-top-view--padded .sui-layout-main-body {
  padding: 24px !important;
}
/* Opt-in (`bodyTitle` prop): the swacch_tron-style section header — a short
   uppercase label + hairline rule at the top of the body. */
.sections-top-view__body-title {
  margin: 0 0 16px;
  padding-bottom: 12px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink, #23201c);
  border-bottom: 1px solid var(--border-subtle, #f0ece8);
}

/* ==== "Recommended" endorsement badge ====================================
   The AI shortlist signal on an applicant. Replaces the washed-out default
   Carbon yellow tag with a real gold badge + star, everywhere it renders
   (applicants list row, candidate search result, Applicant Info hero).
   `.xpa-recommended-badge--lg` bumps the scale for the hero heading. */
.xpa-recommended-badge.bx--tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: auto;
  min-height: 0;
  margin: 0 0 0 8px;
  padding: 3px 9px;
  background: var(--warning-soft, #fcf6e8);
  color: var(--warning, #c78318);
  border: 1px solid var(--warning, #c78318);
  border-radius: var(--radius-pill, 999px);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1;
  white-space: nowrap;
  vertical-align: middle;
}
.xpa-recommended-badge.xpa-recommended-badge--lg.bx--tag {
  gap: 5px;
  margin-left: 10px;
  padding: 4px 10px;
  font-size: 11px;
}
.xpa-recommended-badge__icon {
  flex: 0 0 auto;
}

/* ==== Applicant card =======================================================
   The list-row / search-result representation of one job application:
   components/roboroy/common/ApplicantCard.js in its compact (non-
   isApplicantInfo) mode. Renders inside a .bx--data-table cell on the
   applicants list (.xpa-xopa-table) and in global search results. The old
   markup was a half-width bootstrap column of raw utility-class text + a pile
   of conditional status tags; this restyles it into a readable card. The only
   markup change is the .xpa-appcard__* class hooks + swapping the status-tag
   soup for <ApplicantStageSummary> (the compact pipeline). ================= */
.xpa-appcard {
  width: 100%;
  min-width: 0;
  color: var(--ink, #23201c);
}
/* the inner Carbon grid row + its negative margins collapse to a plain block */
.xpa-appcard > .bx--row {
  margin: 0;
  display: block;
}
/* the bootstrap .row wrapping the location line — kill its ±15px gutter */
.xpa-appcard .row {
  margin: 0;
}
.xpa-appcard__main {
  width: 100%;
  min-width: 0;
  max-width: none;
  padding: 0;
  flex: 1 1 auto;
}
.xpa-appcard .xpa-left--1 {
  margin: 0;
  padding: 0;
  border: 0;
}

/* eyebrow — "APPLICATION ID: 1544508" */
.xpa-appcard__eyebrow {
  display: block;
  margin: 0 0 4px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-tertiary, #8a847c) !important;
}

/* name row — avatar + name + Recommended badge + LinkedIn */
.xpa-appcard .xpa-appcard__name {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 !important;
}
.xpa-appcard__name > span:first-child,
.xpa-appcard__name > img:first-child {
  flex: 0 0 auto;
  margin: 0 !important;
}
.xpa-appcard__name .card-title {
  margin: 0 !important;
  padding: 0;
  font-family: var(--font-heading, 'Sora', sans-serif);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink, #23201c);
  cursor: pointer;
  transition: color 150ms ease;
}
.xpa-appcard__name .card-title:hover {
  color: var(--link, #3d4d68);
}
.xpa-appcard__name a img {
  display: block;
  width: 16px;
  height: 16px;
}

/* meta lines — "Applied for X with Y", school, course */
.xpa-appcard .bx--type-caption {
  margin: 6px 0 0;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--ink-tertiary, #8a847c);
}
.xpa-appcard .bx--type-caption + .bx--type-caption {
  margin-top: 2px;
}
.xpa-appcard .bx--type-caption > .bx--row {
  margin: 0 !important;
  display: inline;
}
.xpa-appcard .bx--type-caption > .bx--row > div {
  display: inline;
}
.xpa-appcard .bx--type-caption > .bx--row > div.ml-1 {
  margin-left: 4px !important;
}
.xpa-appcard .bx--type-caption a {
  color: var(--ink-secondary, #5f5a54);
  font-weight: 500;
}
.xpa-appcard .bx--type-caption a:hover {
  color: var(--link, #3d4d68);
  text-decoration: underline;
}

/* location line */
.xpa-appcard .row .text-black-50 {
  padding: 0 !important;
}
.xpa-appcard .text-black-50 small {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  width: auto;
  max-width: none;
  margin: 4px 0 0;
  padding: 0;
  font-size: 12.5px;
  color: var(--ink-tertiary, #8a847c);
}
.xpa-appcard .text-black-50 small svg {
  flex: 0 0 auto;
  width: 12px !important;
  height: 12px !important;
}

/* favourite-candidate tag */
.xpa-appcard .bx--tag--blue {
  height: auto;
  margin: 8px 0 0 !important;
  padding: 3px 9px !important;
  border-radius: 999px;
  background: var(--info-soft, #eef3f9);
  color: var(--info, #4f6d95);
  font-size: 11px;
  font-weight: 500;
}

.xpa-appcard-cell {
  width: 100%;
}

/* status region — the shared .xpa-applicantinfo__status wrapper holds the
   compact <ApplicantProgress> meter + an optional missing-email warning below
   it. Scoped to .xpa-appcard so the Applicant Info hero's own wrapper (which
   holds the full stepper) is untouched. */
.xpa-appcard .xpa-applicantinfo__status {
  display: block;
  margin: 12px 0 0;
}
.xpa-appcard .xpa-applicantinfo__status .bx--inline-notification {
  margin: 10px 0 0;
  max-width: none;
}

/* ---- Compact progress meter (ApplicantProgress in ApplicantPipeline.js) ----
   The applicants-LIST form of the pipeline: a thin connector line + six small
   stage dots + one caption naming the current stage / outcome. Same green
   success / red reject language as the full stepper (same tokens), a fraction
   of the height, so it supports the applicant's details instead of dominating
   the row. Not the Applicant Info hero — that keeps the full stepper. */
.xpa-appcard-progress {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
  max-width: 340px;
}
.xpa-appcard-progress__track {
  display: flex;
  align-items: center;
  width: 100%;
}
.xpa-appcard-progress__dot {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 1.5px solid var(--border, #e7e2dc);
  background: var(--surface, #fff);
  box-sizing: border-box;
  cursor: pointer;
  transition: transform 120ms ease;
}
/* pop on hover — transform only, so the track's dot spacing never shifts */
.xpa-appcard-progress__dot:hover {
  transform: scale(1.4);
}
.xpa-appcard-progress__seg {
  flex: 1 1 auto;
  min-width: 10px;
  height: 2px;
  background: var(--border, #e7e2dc);
}
/* completed */
.xpa-appcard-progress__dot--done,
.xpa-appcard-progress__seg--done {
  background: var(--success, #2f8f57);
  border-color: var(--success, #2f8f57);
}
/* current — the emphasis point */
.xpa-appcard-progress__dot--current {
  width: 11px;
  height: 11px;
  background: var(--success, #2f8f57);
  border-color: var(--success, #2f8f57);
  box-shadow: 0 0 0 3px var(--success-soft, #edf8f0);
}
/* rejected — sits at the step the applicant dropped out; later dots stay hollow
   so "Hired" is never implied */
.xpa-appcard-progress__dot--rejected {
  width: 11px;
  height: 11px;
  background: var(--danger, #c94a4a);
  border-color: var(--danger, #c94a4a);
  box-shadow: 0 0 0 3px var(--danger-soft, #fbecec);
}
.xpa-appcard-progress--complete .xpa-appcard-progress__dot:last-child {
  width: 11px;
  height: 11px;
  box-shadow: 0 0 0 3px var(--success-soft, #edf8f0);
}
.xpa-appcard-progress__caption {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: 500;
  line-height: 1.3;
  text-transform: capitalize;
  color: var(--ink-secondary, #5f5a54);
}
.xpa-appcard-progress__caption::before {
  content: '';
  flex: 0 0 auto;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--success, #2f8f57);
}
.xpa-appcard-progress--complete .xpa-appcard-progress__caption {
  color: var(--success, #2f8f57);
}
.xpa-appcard-progress--rejected .xpa-appcard-progress__caption {
  color: var(--danger, #c94a4a);
}
.xpa-appcard-progress--rejected .xpa-appcard-progress__caption::before {
  background: var(--danger, #c94a4a);
}
@media (prefers-reduced-motion: reduce) {
  .xpa-appcard-progress__dot {
    transition: none;
  }
  .xpa-appcard-progress__dot:hover {
    transform: none;
  }
}
@media (max-width: 640px) {
  .xpa-appcard-progress {
    max-width: none;
  }
  .xpa-appcard-progress__seg {
    min-width: 6px;
  }
}

/* ---- Applicants list rows (XopaTable.js → .xpa-xopa-table) ----
   The one column is a whole ApplicantCard; give the cell room and top-align
   the checkbox with the card's identity line. Everything else about this
   table comes from the Universal Data Table system earlier in this file. */
.xpa-xopa-table .bx--data-table tbody td {
  padding: 20px;
  vertical-align: top;
}
.xpa-xopa-table .bx--data-table td.bx--table-column-checkbox {
  padding-top: 22px;
}

/* ApplicantSort (<Select>) now lives in the toolbar's otherActions, beside
   the Filter button — size + skin it to match the toolbar buttons. It ships
   className="bx--col-xs-12 p-0" (a full-width grid col), overridden here so it
   sits inline instead of stretching the whole toolbar row. */
.xpa-xopa-table .bx--table-toolbar .bx--toolbar-content .bx--select {
  flex: 0 0 auto;
  max-width: none;
  margin: 0;
}
.xpa-xopa-table .bx--table-toolbar .bx--select-input {
  height: 36px;
  min-height: 36px;
  min-width: 176px;
  padding: 0 34px 0 12px;
  background: var(--surface, #fff);
  border: 1px solid #e8e3dd;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-secondary, #5f5a54);
  box-shadow: none;
}
.xpa-xopa-table .bx--table-toolbar .bx--select-input:hover {
  background: #f5f2ee;
  border-color: #ddd6cf;
}
.xpa-xopa-table .bx--table-toolbar .bx--select-input:focus {
  outline: none;
  border-color: var(--link, #3d4d68);
  box-shadow: 0 0 0 3px var(--info-soft, #eef3f9);
}
.xpa-xopa-table .bx--table-toolbar .bx--select__arrow {
  top: 50%;
  transform: translateY(-50%);
  fill: var(--ink-tertiary, #8a847c);
}

/* ==== View toggle — quiet grouped table/list switcher ======================
   NOTE: intentionally NOT named *-control / *-container / *-option — the
   react-select override block above uses `[class*="-container"] [class*="-control"]`
   etc. with !important, which would otherwise paint a border + `--shadow-focus`
   ring on these buttons whenever anything on the page has focus. */
.xpa-view-toggle {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--border, #e7e2dc);
  border-radius: 10px;
  background: var(--surface-muted, #f5f3f0);
}
.xpa-view-toggle__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 30px;
  min-width: 36px;
  padding: 0 8px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--ink-tertiary, #8a847c);
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  transition: background-color 120ms ease-out, color 120ms ease-out;
}
.xpa-view-toggle__btn svg {
  width: 18px;
  height: 18px;
}
.xpa-view-toggle__btn:hover,
.xpa-view-toggle__btn:focus {
  color: var(--ink, #23201c);
  outline: none;
}
.xpa-view-toggle__btn:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--info, #4f6d95);
}
.xpa-view-toggle__btn--active {
  background: var(--surface, #fff);
  color: var(--ink, #23201c);
  box-shadow: var(--shadow-sm, 0 1px 2px rgba(35, 32, 28, 0.05));
}

/* ==== Profile page (containers/common/profile) =============================
   Enterprise card treatment for the "My Profile" view — replaces the old
   Bootstrap <table class="pro-label/pro-details"> layout with a header row
   (avatar + identity + edit action) and a responsive label/value grid,
   reusing .xpa-dashboard-section for the outer card. */
.xpa-dashboard-section.xpa-profile-card {
  position: relative;
}
.xpa-profile-edit-btn {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
  color: var(--text-secondary);
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
}
.xpa-profile-edit-btn:hover {
  background: var(--bg-hover);
  color: var(--text-primary);
  border-color: var(--border-strong);
}
.xpa-profile-edit-btn:focus-visible {
  outline: 2px solid var(--info);
  outline-offset: 2px;
}
.xpa-profile-edit-btn svg {
  fill: currentColor;
}
.xpa-profile-header {
  display: flex;
  align-items: center;
  gap: 20px;
  padding-right: 44px;
  padding-bottom: 36px;
  margin-bottom: 20px;
  border-bottom: 1px solid var(--border-subtle);
}
/* Fixed to exactly the avatar's own size (not avatar + caption) so
   align-items: center on the header centers the name/subtitle against
   the avatar image itself — the caption is pulled out of flow below via
   absolute positioning instead of stacking under it, which would have
   pushed the perceived avatar height taller than 100px and thrown off
   the centering against the identity block. */
.xpa-profile-avatar-wrap {
  position: relative;
  flex: 0 0 auto;
  width: 100px;
  height: 100px;
  cursor: pointer;
}
.xpa-profile-avatar {
  display: block;
  border: 3px solid var(--bg-surface);
  box-shadow: 0 0 0 1px var(--border-default);
}
.xpa-profile-avatar-upload {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  margin-top: 8px;
  font-size: 11px;
  line-height: 1.3;
  color: var(--text-tertiary);
  text-align: center;
  white-space: nowrap;
}
.xpa-profile-identity {
  flex: 1 1 auto;
  min-width: 0;
}
.xpa-profile-name {
  font-family: var(--xpa-font-heading);
  font-size: 20px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--text-primary);
  text-transform: capitalize;
}
.xpa-profile-role-line {
  margin-top: 4px;
  font-size: 13px;
  color: var(--text-secondary);
}
.xpa-profile-details-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 20px 32px;
}
.xpa-profile-field-label {
  font-size: 12px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-tertiary);
  margin-bottom: 4px;
}
.xpa-profile-field-value {
  font-size: 14px;
  font-weight: 500;
  color: var(--text-primary);
}
.xpa-profile-field-value .xpa-bx--tag--s {
  margin-right: 6px;
  margin-bottom: 4px;
}
@media (max-width: 576px) {
  .xpa-profile-header {
    padding-right: 0;
  }
  .xpa-profile-edit-btn {
    top: 20px;
    right: 20px;
  }
}

/* ==== Student profile / registration — personal info + settings ===========
   containers/roboroy/StudentProfileRegister.js, the step-0 / detailsTab===null
   block (campus Student Profile view + registration wizard step 1) plus the
   containers/roboroy/StudentApplicationsStatus.js filter row nested in it.
   Was bare .bx--row label/value pairs on misaligned Carbon grid columns with
   <hr> dividers, an unstyled scholar/ring-fenced toggle stack and a
   full-width Save button — now cards with an aligned definition grid and a
   right-aligned settings-row pattern. */
.xpa-stu-reg {
  margin-left: 0;
}
.xpa-stu-reg__section {
  position: relative;
  background: var(--surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: 22px 24px;
  margin-bottom: 16px;
}
.xpa-stu-reg__section::before {
  content: '';
  position: absolute;
  inset: 0;
  border: 0.92px solid rgba(239, 240, 246, 1);
  border-radius: inherit;
  pointer-events: none;
}
.xpa-stu-reg__section:last-child {
  margin-bottom: 0;
}
.xpa-stu-reg__section-title {
  margin: 0 0 18px;
  font-family: var(--font-heading);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--ink);
}

/* ---- read-only definition grid ---- */
.xpa-stu-reg__grid {
  display: grid;
  /* min(240px, 100%) — the track never grows wider than its container, so
     a very narrow card can't get a horizontal scrollbar. */
  grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 1fr));
  gap: 18px 32px;
  margin: 0;
}
.xpa-stu-reg__field {
  min-width: 0;
}
.xpa-stu-reg__field-label {
  margin-bottom: 4px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-tertiary);
}
.xpa-stu-reg__field-value {
  font-size: 14px;
  font-weight: 500;
  line-height: 1.45;
  color: var(--ink);
  word-break: break-word;
}
.xpa-stu-reg__field-value.is-capitalize {
  text-transform: capitalize;
}
.xpa-stu-reg__field-link {
  color: var(--link);
  font-weight: 500;
}
.xpa-stu-reg__field-link:hover {
  color: var(--link-hover);
  text-decoration: underline;
}

/* ---- editable settings rows ---- */
.xpa-stu-reg__control-notif {
  margin-bottom: 8px;
}
.xpa-stu-reg__control-notif .bx--inline-notification {
  margin-top: 0;
  margin-bottom: 8px;
  max-width: none;
}
.xpa-stu-reg__controls {
  display: flex;
  flex-direction: column;
}
/* Each row: label + description together in a bounded left block, the
   control immediately to its right. The description stays inside the
   left block (never runs under / past the control), and the controls
   line up in a predictable column near the left — not flung to the far
   card edge. */
.xpa-stu-reg__control {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 12px 28px;
  padding: 16px 0;
  border-top: 1px solid var(--border-subtle);
}
.xpa-stu-reg__control:first-child {
  padding-top: 0;
  border-top: none;
}
.xpa-stu-reg__control:last-child {
  padding-bottom: 0;
}
.xpa-stu-reg__control-main {
  flex: 0 1 360px;
  min-width: 0;
}
.xpa-stu-reg__control-label {
  font-size: 13px;
  font-weight: 600;
  line-height: 20px;
  color: var(--ink);
}
.xpa-stu-reg__control-hint {
  margin-top: 4px;
  font-size: 12px;
  line-height: 1.4;
  color: var(--ink-tertiary);
}
.xpa-stu-reg__control-field {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
}
.xpa-stu-reg__control-field .form-group {
  margin-bottom: 0;
}
.xpa-stu-reg__batch-select {
  width: 220px;
  max-width: 100%;
}
.xpa-stu-reg__batch-save {
  flex: 0 0 auto;
  white-space: nowrap;
}

/* Carbon's stock <Toggle> hangs its redundant on/off state word (labelA /
   labelB) off the RIGHT of the 48px switch with position:absolute, so in a
   right-aligned settings row it spills past the card padding and clips
   ("No" cut off at the card edge). Drop the word — the switch's colour and
   knob position already convey the state — and strip the switch's block
   margins so it sits centred in the row. */
.xpa-stu-reg__control-field .bx--form-item {
  flex: 0 0 auto;
  margin: 0;
}
.xpa-stu-reg__control-field .bx--toggle__switch {
  margin: 0;
}
.xpa-stu-reg__control-field .bx--toggle__text--off,
.xpa-stu-reg__control-field .bx--toggle__text--on {
  display: none;
}

/* ---- Application Status filter row (StudentApplicationsStatus) ---- */
.xpa-stu-appstatus__filters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
  gap: 12px 16px;
  margin-bottom: 16px;
}
.xpa-stu-appstatus__filters .form-group {
  min-width: 0;
  margin-bottom: 0;
}
.xpa-stu-appstatus__filter-labelwrap {
  margin-bottom: 4px;
}
.xpa-stu-appstatus__filter-label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-tertiary);
}
.xpa-stu-appstatus__filter-select {
  width: 100%;
}
.xpa-stu-appstatus__empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 48px 24px;
  text-align: center;
}
.xpa-stu-appstatus__empty-icon {
  font-size: 32px;
  color: var(--ink-tertiary);
}
.xpa-stu-appstatus__empty-text {
  margin: 0;
  max-width: 42ch;
  font-size: 14px;
  font-weight: 500;
  color: var(--ink-secondary);
}

/* ---- Long-text safety ----
   Every text element on this page wraps inside its box rather than
   widening the layout — covers future fields, long i18n strings, and
   unbroken tokens (emails, IDs, batch names). Flex/grid children are
   allowed to shrink below their content width. */
.xpa-stu-reg__section-title,
.xpa-stu-reg__field-label,
.xpa-stu-reg__field-value,
.xpa-stu-reg__field-link,
.xpa-stu-reg__control-label,
.xpa-stu-reg__control-hint,
.xpa-stu-appstatus__filter-label,
.xpa-stu-appstatus__empty-text {
  min-width: 0;
  overflow-wrap: anywhere;
  word-break: break-word;
}
.xpa-stu-reg__field-link {
  display: inline-block;
  max-width: 100%;
}
.xpa-stu-reg__control-field {
  min-width: 0;
}
/* Batch react-select: ellipsis a long option label instead of pushing
   the control wider than its 220px box. */
.xpa-stu-reg__batch-select [class*="-singleValue"],
.xpa-stu-reg__batch-select [class*="-single-value"] {
  max-width: calc(100% - 8px);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 640px) {
  .xpa-stu-reg__section {
    padding: 18px 16px;
  }
  .xpa-stu-reg__grid {
    grid-template-columns: 1fr;
  }
  .xpa-stu-reg__control-main {
    flex-basis: 100%;
  }
  .xpa-stu-reg__control-field {
    width: 100%;
  }
  .xpa-stu-reg__batch-select {
    width: auto;
    flex: 1 1 auto;
  }
  .xpa-stu-appstatus__filters {
    grid-template-columns: 1fr;
  }
}

/* ==== Student Profile — detail sections (SectionTabsLayout) ================
   containers/roboroy/StudentProfileView.js `selectedTab === 0` — the
   Bio/Academia / Preferences / Documents / Contract pills + their form
   panels, now wrapped in <SectionTabsLayout className="xpa-stu-profile__sections">
   (the welded pills+body card, styled by the .sections-top-view block
   above). This block only tidies what renders INSIDE the body: the
   read-only registration form (StudentProfileRegister with showSteps=false)
   was bare `.bx--row` label/field pairs with `<hr>` dividers and faint
   disabled Carbon inputs. Scoped so the live registration wizard (same
   component, no this class) is untouched. */

/* The active pill already names the section — drop the branch's own
   duplicate `<div class="h6">` title + rule. */
.xpa-stu-profile__sections .sui-layout-main-body > div > .h6:first-child,
.xpa-stu-profile__sections .sui-layout-main-body > div > .h6:first-child + hr {
  display: none;
}

/* Sub-section headers ("ADDRESS", "Upload Additional Documents", "Offer
   Documents"). CandidateDetails' own section titles (`.xpa-cand-section__title`)
   are excluded — they're styled by the dedicated `.xpa-cand-profile` /
   `.xpa-cand-profile--embedded` block in CandidateDetails.css. */
.xpa-stu-profile__sections .sui-layout-main-body h6:not(.xpa-cand-section__title),
.xpa-stu-profile__sections .sui-layout-main-body .bx--type-epsilon,
.xpa-stu-profile__sections .sui-layout-main-body .text-uppercase.text-dark:not(.xpa-cand-section__title) {
  margin: 24px 0 12px;
  font-family: var(--font-heading);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-tertiary);
}
.xpa-stu-profile__sections .sui-layout-main-body > div > h6:first-child,
.xpa-stu-profile__sections .sui-layout-main-body > div > .bx--type-epsilon:first-child {
  margin-top: 0;
}
.xpa-stu-profile__sections .sui-layout-main-body hr {
  margin: 14px 0 20px;
  border: 0;
  border-top: 1px solid var(--border-subtle);
}

/* Read-only detail form → horizontal "label | value" rows, one shared
   label-column width, matching the Personal Information card at the top of
   the page. --xpa-stu-label-col is the left column for every row type. */
.xpa-stu-profile__sections .sui-layout-main-body {
  --xpa-stu-label-col: 190px;
}

/* Rows that already come as a Carbon grid .bx--row (Gender, Portfolio,
   Citizenship, GPA, Course, Phone) — Carbon's grid gave the label 25% and
   the field 41%, a third of the row empty between them. */
.xpa-stu-profile__sections .sui-layout-main-body > div > .bx--row {
  align-items: center !important;
  margin: 0 0 14px !important;
}
.xpa-stu-profile__sections .sui-layout-main-body > div > .bx--row > [class*="bx--col-lg-3"],
.xpa-stu-profile__sections .sui-layout-main-body > div > .bx--row > .bx--type-zeta {
  flex: 0 0 var(--xpa-stu-label-col) !important;
  max-width: var(--xpa-stu-label-col) !important;
  padding-top: 0;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ink-secondary);
  overflow-wrap: anywhere;
}
.xpa-stu-profile__sections .sui-layout-main-body > div > .bx--row > [class*="bx--col-lg-5"] {
  flex: 1 1 auto !important;
  max-width: 440px !important;
}
.xpa-stu-profile__sections .sui-layout-main-body .req-feild {
  color: var(--danger);
}

/* Address block (OfficeDetails, isStudentProfile) — renders its fields
   STACKED (label above input) via Carbon `.bx--form-item` (flex column),
   `.bx--select`, and a DropDownBox `.form-group.row`. Flip each container
   to the same horizontal label | value row. */
.xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 {
  width: 100% !important;
  max-width: 660px;
}
.xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 > div {
  margin-bottom: 14px !important;
}
.xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 > div:last-child {
  margin-bottom: 0 !important;
}
.xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 .bx--form-item,
.xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 .bx--select,
.xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 .form-group.row {
  display: flex !important;
  flex-direction: row !important;
  flex-wrap: nowrap;
  align-items: center;
  gap: 16px;
  margin: 0 !important;
}
/* label cell — `color !important` beats dropdown.css's
   `.disabled-label { color: #c6c6c6 !important }`. */
.xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 .bx--form-item > .bx--label,
.xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 .bx--select > .bx--label,
.xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 .form-group.row > div:first-child,
.xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 label {
  flex: 0 0 var(--xpa-stu-label-col);
  width: var(--xpa-stu-label-col);
  max-width: var(--xpa-stu-label-col);
  margin: 0 !important;
  padding: 0 !important;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1.3;
  color: var(--ink-secondary) !important;
}
/* value cell */
.xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 .bx--form-item > .bx--text-input,
.xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 .bx--select > .bx--select-input__wrapper,
.xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 .form-group.row > div:last-child,
.xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 [class*="-container"] {
  flex: 1 1 auto !important;
  width: auto !important;
  min-width: 0;
  max-width: 440px !important;
  margin: 0 !important;
  padding: 0 !important;
}
/* Carbon <select> and the react-select control keep their own default
   widths (14rem / content) — make them fill the value cell. */
.xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 .bx--select-input,
.xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 .bx--select-input__wrapper {
  width: 100% !important;
  min-width: 0 !important;
  max-width: 100% !important;
}
.xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 [class*="-container"] [class*="-control"] {
  width: 100% !important;
}
/* Disabled react-select (city) value — match the Carbon input/select
   legibility bump below. */
.xpa-stu-profile__sections .sui-layout-main-body [class*="-container"] [class*="-singleValue"],
.xpa-stu-profile__sections .sui-layout-main-body [class*="-container"] [class*="-single-value"] {
  color: var(--ink-secondary) !important;
}

/* Read-only view: the whole form renders `disabled` (edit happens on the
   /update/profile route). Carbon's disabled text is #c6c6c6-faint — bump it
   so the values stay legible; keep the muted fill/border as the "not
   editable here" cue. */
.xpa-stu-profile__sections .sui-layout-main-body .bx--text-input:disabled,
.xpa-stu-profile__sections .sui-layout-main-body .bx--select-input:disabled,
.xpa-stu-profile__sections .sui-layout-main-body .bx--text-input[disabled],
.xpa-stu-profile__sections .sui-layout-main-body .bx--select-input[disabled] {
  color: var(--ink-secondary) !important;
  -webkit-text-fill-color: var(--ink-secondary) !important;
}
.xpa-stu-profile__sections .sui-layout-main-body .bx--radio-button:disabled + .bx--radio-button__label,
.xpa-stu-profile__sections .sui-layout-main-body .bx--radio-button__label {
  color: var(--ink-secondary);
}

/* Long-text safety for anything that lands in the body. */
.xpa-stu-profile__sections .sui-layout-main-body,
.xpa-stu-profile__sections .sui-layout-main-body .bx--col,
.xpa-stu-profile__sections .sui-layout-main-body [class*="bx--col-"] {
  min-width: 0;
}
.xpa-stu-profile__offer-docs {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* ---- Preferences tab (StudentProfileRegister detailsTab 2 / wizard step 5)
   `studentLearnMsg` / `sliderTitle` were full instructional SENTENCES set as
   <h6> — the generic sub-header rule turned them into shouty uppercase
   eyebrows; the slider end-labels were `.bx--type-zeta` (bold 16px) and
   wrapped; the legend was a wall of loose `.bx--type-zeta` / `.text-secondary`
   divs. Scoped to `.xpa-stu-pref` so it also applies in the wizard. */
.xpa-stu-pref__hint {
  margin: 22px 0 14px;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.5;
  color: var(--ink-secondary);
}
.xpa-stu-pref__hint:first-of-type {
  margin-top: 0;
}
.xpa-stu-pref > .bx--row {
  align-items: center;
  margin-bottom: 14px;
}
.xpa-stu-pref > .bx--row > [class*="bx--col-lg-3"],
.xpa-stu-pref > .bx--row > .bx--type-zeta {
  flex: 0 0 190px;
  max-width: 190px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--ink-secondary);
}
.xpa-stu-pref > .bx--row > [class*="bx--col-lg-5"] {
  flex: 1 1 auto;
  max-width: 440px;
}
.xpa-stu-pref > .bx--row > [class*="bx--col-lg-8"] {
  flex: 1 1 auto;
  max-width: 620px;
  margin-left: 0 !important;
}
/* Slider row — the two long end-labels + slider on one flex row wrapped
   into a mess. Stack them: label, slider full-width, label right-aligned. */
.xpa-stu-pref .Slider {
  display: block !important;
  margin: 6px 0 4px !important;
}
.xpa-stu-pref .Slider > div {
  width: 100% !important;
  max-width: 100% !important;
  flex: none !important;
  padding: 0 !important;
}
.xpa-stu-pref .Slider .bx--type-zeta {
  margin: 0 0 4px !important;
  font-size: 12px !important;
  font-weight: 500 !important;
  line-height: 1.35;
  color: var(--ink-secondary);
}
.xpa-stu-pref .Slider .bx--type-zeta:last-child {
  margin: 6px 0 0 !important;
  text-align: right;
}
.xpa-stu-pref .Slider .bx--slider-container,
.xpa-stu-pref .Slider .bx--slider {
  width: 100%;
  max-width: 100%;
}
/* legend — label / description pairs */
.xpa-stu-pref__legend {
  margin-top: 22px;
  padding-top: 16px;
  border-top: 1px solid var(--border-subtle);
}
.xpa-stu-pref__legend-title {
  margin-bottom: 12px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-tertiary);
}
.xpa-stu-pref__legend-item {
  margin-bottom: 14px;
}
.xpa-stu-pref__legend-item:last-child {
  margin-bottom: 0;
}
.xpa-stu-pref__legend-term {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
}
.xpa-stu-pref__legend-def {
  margin-top: 2px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink-secondary);
}

@media (max-width: 640px) {
  .xpa-stu-pref > .bx--row {
    align-items: flex-start;
  }
  .xpa-stu-pref > .bx--row > [class*="bx--col-lg-3"],
  .xpa-stu-pref > .bx--row > .bx--type-zeta {
    flex-basis: 100%;
    max-width: 100%;
    margin-bottom: 4px;
  }
  /* stack label above value on narrow screens */
  .xpa-stu-profile__sections .sui-layout-main-body > div > .bx--row {
    align-items: flex-start !important;
  }
  .xpa-stu-profile__sections .sui-layout-main-body > div > .bx--row > [class*="bx--col-lg-3"],
  .xpa-stu-profile__sections .sui-layout-main-body > div > .bx--row > .bx--type-zeta {
    flex-basis: 100% !important;
    max-width: 100% !important;
    margin-bottom: 4px;
  }
  .xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 .bx--form-item,
  .xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 .bx--select,
  .xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 .form-group.row {
    flex-direction: column !important;
    align-items: stretch;
    gap: 4px;
  }
  .xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 .bx--form-item > .bx--label,
  .xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 .bx--select > .bx--label,
  .xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 .form-group.row > div:first-child,
  .xpa-stu-profile__sections .sui-layout-main-body > div > .w-50 label {
    flex-basis: auto;
    width: auto;
    max-width: none;
  }
}

/* ==== PageTitle (components/common/PageTitle) ===============================
   Heading + optional info-tooltip. */
.xpa-page-title-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}
.xpa-page-title-info {
  display: inline-flex;
  align-items: center;
  color: var(--text-tertiary);
  cursor: help;
  transition: color 150ms ease;
}
.xpa-page-title-info:hover,
.xpa-page-title-info:focus-visible {
  color: var(--text-primary);
}
.xpa-page-title-info svg {
  fill: currentColor;
}

/* ==== Applicants list — page header + job-details card ====================
   containers/roboroy/CandidatesListXopa: BackRow (breadcrumb) → PageTitle
   ("Applicants") → the job-details card (<DetailsHeader>). Same card + type
   language as the Job Info hero (.xpa-jobinfo__hero) so the applicants page
   and the job page read as one system. The old markup was raw utility-class
   text (bx--type-gamma / bx--type-delta, ml-1/ml-3) + a bare <hr>. */
.xpa-appl-header .xpa-page-title-row {
  margin-bottom: 14px;
}

.xpa-appl-header__job {
  margin-bottom: 16px;
  padding: 18px 20px;
  background: var(--surface, #fff);
  border: 1px solid var(--border, #e7e2dc);
  border-radius: var(--radius-lg, 14px);
  box-shadow: var(--shadow-sm, 0 1px 2px rgba(35, 32, 28, 0.05));
}
.xpa-appl-header__job-body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  min-width: 0;
}

/* eyebrow — "REQUISITION ID: 2766" */
.xpa-appl-header__job-req {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-tertiary, #8a847c);
}

/* job name — a heading that links through to the job detail page */
.xpa-appl-header__job-name {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  font-family: var(--font-heading, 'Sora', sans-serif);
  font-size: 19px;
  line-height: 1.25;
  font-weight: 600;
  color: var(--ink, #23201c);
  text-transform: capitalize;
  transition: color 150ms ease;
}
.xpa-appl-header__job-name:hover,
.xpa-appl-header__job-name:focus {
  color: var(--link, #3d4d68);
  text-decoration: none;
  outline: none;
}
.xpa-appl-header__job-name > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.xpa-appl-header__job-arrow {
  flex: 0 0 auto;
  color: var(--ink-tertiary, #8a847c);
  transition: transform 150ms ease, color 150ms ease;
}
.xpa-appl-header__job-name:hover .xpa-appl-header__job-arrow,
.xpa-appl-header__job-name:focus .xpa-appl-header__job-arrow {
  color: var(--link, #3d4d68);
  transform: translate(2px, -2px);
}

/* skill pills — matches .xpa-jobinfo__skills on the job page */
.xpa-appl-header__job-skills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 2px;
}
.xpa-appl-header__skill {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  background: var(--surface-muted, #f5f3f0);
  color: var(--ink-secondary, #5f5a54);
  border: 1px solid var(--border, #e7e2dc);
  border-radius: var(--radius-sm, 6px);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

@media (prefers-reduced-motion: reduce) {
  .xpa-appl-header__job-arrow {
    transition: none;
  }
  .xpa-appl-header__job-name:hover .xpa-appl-header__job-arrow {
    transform: none;
  }
}
@media (max-width: 640px) {
  .xpa-appl-header__job {
    padding: 16px;
  }
  .xpa-appl-header__job-name {
    font-size: 17px;
  }
}

/* ==== Notifications page (containers/roboroy/Notifications) ================
   Replaces the old Accordion-as-fake-table hack (a non-interactive
   AccordionItem whose only job was to fake a column-header row, plus one
   real AccordionItem per notification) with the real GenericDataTable in
   expandable-row mode — a proper header row and native expand/collapse
   instead of an accordion pretending to be a table. */
.xpa-notif-context {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 24px;
  margin-bottom: 20px;
}
.xpa-notif-context-label {
  font-size: 13px;
  color: var(--text-tertiary);
}
.xpa-notif-context-value {
  margin-left: 4px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary);
}
.xpa-notif-subject {
  font-weight: 500;
  color: var(--text-primary);
}
.xpa-notif-body {
  max-width: 100%;
  margin: 4px 0;
  padding: 20px;
  overflow-x: auto;
  background: var(--bg-subtle);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}
.xpa-notif-body img {
  max-width: 100%;
  height: auto;
}

/* ==== Auth / login (containers/common/campusLogin) ========================
   Split-screen enterprise sign-in — action column (left) + branded panel
   (right). Replaces the old purple .login-page / .left-side (photo + dark
   scrim) / .right-side (.form-signin card) pattern from Login.css. The new
   markup deliberately uses none of those class names, so the bundled
   Login.css purple rules can't match; background/color are still set
   explicitly on every region below so nothing inherits a stale
   `color:white` if Login.css happens to load after this file.
   Consumed by AuthShell / AuthBrandPanel / OtpForm and the four
   campusLogin containers. Mobile-first; two columns at >=1024px. */
.xpa-auth {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--surface);
  color: var(--ink);
  font-family: var(--xpa-font-sans);
}
.xpa-auth__action {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  overflow-y: auto;
  padding: var(--space-8) var(--space-6);
  background: var(--surface);
  color: var(--ink);
}
.xpa-auth__action-inner {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  width: 100%;
  max-width: 380px;
  padding: var(--space-8) 0;
}
.xpa-auth__brand-side { display: none; }

.xpa-auth__logo {
  display: inline-flex;
  height: 30px;
  margin-bottom: var(--space-8);
  background: transparent;
  border: 0;
  padding: 0;
}
button.xpa-auth__logo { cursor: pointer; }
.xpa-auth__logo img { height: 100%; width: auto; display: block; }

.xpa-auth__eyebrow {
  font-size: var(--font-size-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-tertiary);
  margin: 0 0 var(--space-2);
}
.xpa-auth__title {
  font-family: var(--xpa-font-heading);
  font-size: 24px;
  line-height: 32px;
  /* 700, not 650 — Sora only loads at 300/400/500/600/700 (index.html), so
     650 always silently rendered as 700 anyway. */
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 0 0 var(--space-2);
}
.xpa-auth__subtitle {
  font-size: var(--font-size-md);
  line-height: var(--line-md);
  color: var(--ink-secondary);
  margin: 0 0 var(--space-6);
}

.xpa-auth__notifications { margin-bottom: var(--space-4); }
.xpa-auth__notifications:empty { display: none; }
/* Errors are already retinted by carbon-overrides.css; just tighten spacing. */
.xpa-auth__notifications .bx--inline-notification {
  margin-top: var(--space-2);
  margin-bottom: var(--space-2);
  max-width: 100%;
}

.xpa-auth__sso-btn.bx--btn {
  width: 100%;
  min-height: 44px;
  justify-content: center;
}
.xpa-auth__helper {
  margin-top: var(--space-4);
  font-size: var(--font-size-md);
  line-height: var(--line-md);
  color: var(--ink-secondary);
}
.xpa-auth__helper-btn {
  appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--link);
  cursor: pointer;
}
.xpa-auth__helper-btn:hover { color: var(--link-hover); }

.xpa-auth__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
/* Carbon's <TextInput> nests several wrappers (.bx--form-item →
   .bx--text-input__field-outer-wrapper → .bx--text-input__field-wrapper →
   <input>), and .bx--form-item is display:flex; align-items:flex-start, so
   nothing in that chain stretches on its own — each layer collapses to the
   input's intrinsic width. Pin every layer to full width so the field
   matches the full-width primary button exactly. (The __field-outer-wrapper
   layer is newer than the vendored public/css/carbon-components.min.css, so
   that file has no width rule of its own for it — this override is what
   covers it.) */
.xpa-auth__form .bx--form-item,
.xpa-auth__form .bx--text-input-wrapper,
.xpa-auth__form .bx--text-input__label-helper-wrapper,
.xpa-auth__form .bx--text-input__field-outer-wrapper,
.xpa-auth__form .bx--text-input__field-wrapper,
.xpa-auth__form .bx--text-input,
.xpa-auth__form .bx--text-area {
  width: 100%;
}
/* ...and neutralise the label wrapper's own 8rem cap from newer Carbon. */
.xpa-auth__form .bx--text-input__label-helper-wrapper {
  max-width: none;
}
.xpa-auth__form .bx--form-item { margin-bottom: 0; }
.xpa-auth__form .bx--text-input { min-height: 44px; }
/* The email field is locked (disabled) on the code step so it can't drift out
   of sync with the sent code — but the user still needs to *read* it to check
   the address. Keep the text at a readable secondary ink (the muted fill +
   removed focus already signal "locked"). -webkit-text-fill-color is required
   or WebKit forces its own washed-out disabled colour. */
.xpa-auth__form .bx--text-input:disabled {
  color: var(--ink-secondary);
  -webkit-text-fill-color: var(--ink-secondary);
  opacity: 1;
}
/* Email field. On the code step it is locked and carries a trailing edit
   icon (aligned to the input row, not the label) that hands back to the
   email step; the input gets right padding so a long address can't run
   under the icon. */
.xpa-auth__field {
  position: relative;
  display: flex;
  flex-direction: column;
}
.xpa-auth__field--locked .bx--text-input { padding-right: 42px; }
.xpa-auth__field-edit {
  position: absolute;
  right: 6px;
  bottom: 0;
  height: 44px;
  width: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  appearance: none;
  background: transparent;
  border: 0;
  padding: 0;
  border-radius: var(--radius-sm);
  color: var(--ink-tertiary);
  cursor: pointer;
  transition: color var(--xpa-motion-duration) var(--xpa-motion-ease),
              background-color var(--xpa-motion-duration) var(--xpa-motion-ease);
}
.xpa-auth__field-edit:hover {
  color: var(--ink);
  background-color: var(--surface-hover);
}
.xpa-auth__field-edit:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
.xpa-auth__field-edit:disabled {
  color: var(--ink-disabled);
  cursor: not-allowed;
  background-color: transparent;
}
.xpa-auth__field-edit svg { fill: currentColor; }
.xpa-auth__field-hint {
  margin-top: var(--space-1);
  font-size: var(--font-size-xs);
  color: var(--ink-tertiary);
}
.xpa-auth__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-1);
}
/* Carbon caps .bx--btn at max-width:20rem — release it so the auth CTAs can
   fill the form column and line up with the input above. */
.xpa-auth__actions .bx--btn,
.xpa-auth__sso-btn.bx--btn { min-height: 44px; max-width: none; }
.xpa-auth__actions .xpa-auth__primary { flex: 1 1 auto; justify-content: center; }

.xpa-auth__divider {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin: var(--space-5) 0;
  font-size: var(--font-size-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-tertiary);
}
.xpa-auth__divider::before,
.xpa-auth__divider::after {
  content: '';
  flex: 1 1 auto;
  height: 1px;
  background: var(--border);
}

/* Role chooser (campusLogin/login.js) */
.xpa-auth__role-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.xpa-auth__role-card {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--ink);
  text-align: left;
  text-decoration: none;
  transition: background-color var(--xpa-motion-duration) var(--xpa-motion-ease),
              border-color var(--xpa-motion-duration) var(--xpa-motion-ease);
}
.xpa-auth__role-card:hover {
  background: var(--surface-hover);
  border-color: var(--border-strong);
  color: var(--ink);
  text-decoration: none;
}
.xpa-auth__role-card-icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-sm);
  background: var(--surface-muted);
  color: var(--ink-secondary);
}
.xpa-auth__role-card-icon svg { fill: currentColor; }
.xpa-auth__role-card-body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.xpa-auth__role-card-title {
  display: block;
  font-size: var(--font-size-base);
  font-weight: 600;
  color: var(--ink);
}
.xpa-auth__role-card-desc {
  display: block;
  margin-top: 2px;
  font-size: var(--font-size-md);
  color: var(--ink-secondary);
}
.xpa-auth__role-card-chevron {
  flex: 0 0 auto;
  color: var(--ink-tertiary);
}
.xpa-auth__role-card-chevron svg { fill: currentColor; }

.xpa-auth__staff-link {
  display: inline-block;
  margin-top: var(--space-5);
  font-size: var(--font-size-md);
  color: var(--link);
}
.xpa-auth__staff-link:hover { color: var(--link-hover); }

.xpa-auth__aside {
  margin-top: var(--space-5);
  font-size: var(--font-size-md);
  color: var(--ink-secondary);
}
.xpa-auth__aside a { color: var(--link); }
.xpa-auth__aside a:hover { color: var(--link-hover); }

.xpa-auth__staging {
  margin-bottom: var(--space-5);
  padding: var(--space-4);
  border: 1px solid var(--danger);
  border-radius: var(--radius-md);
  background: var(--danger-soft);
  color: var(--ink);
  font-size: var(--font-size-md);
  line-height: var(--line-md);
}
.xpa-auth__staging a { color: var(--link); }

.xpa-auth__footer {
  flex: 0 0 auto;
  width: 100%;
  max-width: 380px;
  padding-top: var(--space-6);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  font-size: var(--font-size-xs);
  color: var(--ink-tertiary);
}
.xpa-auth__footer a {
  color: var(--ink-tertiary);
  padding: var(--space-1) 0;
}
.xpa-auth__footer a:hover { color: var(--ink-secondary); }

/* Branded panel */
.xpa-auth__brand-inner { max-width: 34rem; position: relative; z-index: 1; }
.xpa-auth__brand-eyebrow {
  font-size: var(--font-size-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-secondary);
}
.xpa-auth__brand-accent {
  width: 32px;
  height: 2px;
  background: var(--table-accent, #c46a3a);
  margin: var(--space-3) 0 var(--space-5);
}
.xpa-auth__brand-headline {
  font-family: var(--xpa-font-heading);
  font-size: 28px;
  line-height: 34px;
  /* 700, not 650 — Sora only loads at 300/400/500/600/700 (index.html), so
     650 always silently rendered as 700 anyway. */
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  max-width: 22ch;
  margin: 0;
}
.xpa-auth__brand-supporting {
  margin-top: var(--space-3);
  font-size: var(--font-size-base);
  line-height: var(--line-base);
  color: var(--ink-secondary);
  max-width: 42ch;
}
.xpa-auth__brand-points {
  margin: var(--space-6) 0 0;
  padding: 0;
  list-style: none;
}
.xpa-auth__brand-point {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  margin-top: var(--space-3);
  font-size: var(--font-size-md);
  line-height: var(--line-md);
  color: var(--ink-secondary);
}
.xpa-auth__brand-point::before {
  content: '';
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  margin-top: 7px;
  border-radius: 50%;
  background: var(--table-accent, #c46a3a);
}
.xpa-auth__brand-watermark {
  position: absolute;
  right: var(--space-6);
  bottom: var(--space-6);
  width: clamp(190px, 32%, 380px);
  height: auto;
  opacity: 0.07;
  -webkit-filter: grayscale(0.35);
  filter: grayscale(0.35);
  pointer-events: none;
  -webkit-user-select: none;
  user-select: none;
}

@media (min-width: 1024px) {
  .xpa-auth { flex-direction: row; }
  .xpa-auth__action {
    flex: 0 0 clamp(440px, 42vw, 560px);
    padding: var(--space-10) var(--space-10);
  }
  .xpa-auth__action-inner,
  .xpa-auth__footer { max-width: 360px; }
  .xpa-auth__brand-side {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    justify-content: center;
    position: relative;
    overflow: hidden;
    padding: var(--space-10) clamp(var(--space-10), 6vw, 72px);
    background: linear-gradient(160deg, var(--nav-bg) 0%, var(--nav-active) 100%);
    color: var(--ink);
    border-inline-start: 1px solid var(--border);
  }
}

@media (prefers-reduced-motion: no-preference) {
  .xpa-auth__brand-inner > * {
    animation: xpaAuthRise 480ms var(--xpa-motion-ease) both;
  }
  .xpa-auth__brand-accent { animation-delay: 40ms; }
  .xpa-auth__brand-headline { animation-delay: 80ms; }
  .xpa-auth__brand-supporting { animation-delay: 120ms; }
  .xpa-auth__brand-points { animation-delay: 160ms; }
}
@keyframes xpaAuthRise {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .xpa-auth__brand-inner > * { animation: none; }
}

/* ==== App loading surface ==================================================
   The full-screen loader background — the pre-React boot loader
   (public/index.html carries a copy of this rule inline for first paint), the
   auth-check screen in routes/index.js, and route-chunk <Suspense> fallbacks
   (common.js FlaskLoader). Only on `.xpa-app-loader`, not the shared
   `.xpa-loader-wrap` — JDProcessOverlay reuses that class inside its own
   scrim and neutralises it in NewJob.css. */
.xpa-app-loader {
  background-color: var(--bg-app, #f8f7f5);
}
