/* ── Reset & Base ─────────────────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{--sidebar-w:265px;
  --brand:#102542;--brand-light:#1a3a6b;--accent:#0057b8;--accent-hover:#0046a0;
  --bg:#f0f2f7;--surface:white;--border:#e2e8f0;--text:#1f2937;--muted:#64748b;
  --sb-bg:#f7f8fc;--sb-border:#e8eaf0;--sb-text:#374151;--sb-muted:#9ca3af;
  --sb-active-bg:#e8f0fe;--sb-active-text:#1d4ed8;--sb-section:#9ca3af;
  --sb-hover-bg:#eef0f6;--sb-accent-orange:#e8610a;
  --danger:#dc2626;--warn:#f59e0b;--success:#10b981;--purple:#7c3aed;
  /* BUG-64: EBOS Technologies brand orange (ebos.com.cy / WiseBOS Suite).
     Secondary shade #f7991d. Defined once here so brand-orange accents cannot
     drift into ad-hoc oranges again — the Internal Notes accent was a generic
     burnt orange (#c2410c) that belongs to no palette. */
  /* --ebos-orange is a FILL, never a text colour: as text on white it measures
     2.32:1, well under WCAG AA. --ebos-orange-text is the darkened companion
     (5.13:1 on white) for anything that has to be read. Using the brand orange
     for label text is exactly the mistake BUG-80 is about. */
  --ebos-orange:#f3941f;--ebos-orange-text:#a35c08;--ebos-orange-on:#1f2937;
  font-family:'Segoe UI',Arial,Helvetica,sans-serif;color:var(--text);background:var(--bg);
  font-size:15px;
}

/* ── App Shell ────────────────────────────────────────────────────────────── */
.app-shell{display:flex;min-height:100vh}

/* ── Sidebar — Light / Off-white with orange brand ──────────────────────── */
.sidebar{
  width:var(--sidebar-w,265px);min-width:var(--sidebar-w,265px);
  background:var(--sb-bg);border-right:1px solid var(--sb-border);
  display:flex;flex-direction:column;position:fixed;top:0;left:0;
  height:100vh;z-index:100;overflow:visible;
}
.sidebar-brand{
  display:flex;align-items:center;gap:9px;padding:16px 18px 12px;
  border-bottom:1px solid var(--sb-border);text-decoration:none;
  background:#fff;
}
.sidebar-brand-text{color:#0f172a;font-weight:800;font-size:17px;line-height:1.15;letter-spacing:-.3px}
.sidebar-brand-text small{display:block;font-size:10px;color:var(--sb-muted);font-weight:400;letter-spacing:0;margin-top:2px}

.sidebar-user{
  padding:6px 18px 8px;border-bottom:1px solid var(--sb-border);
}
.sidebar-user-name{color:#374151;font-size:12px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sidebar-user-role{color:var(--sb-muted);font-size:10.5px;margin-top:0;font-weight:400}

.sidebar-nav{flex:1;padding:8px 0;overflow-y:auto;max-height:calc(100vh - 120px)}

/* ── Collapsible section headings ── */
/* BUG-80 — the section headers were the ones failing contrast, not the links.
   .sidebar-link uses var(--sb-text) and measures 8.87–13.75:1 across all themes.
   These headers hard-coded #374151, which is the LIGHT-theme default: on a dark
   accent sidebar that is 1.40:1 on teal, 1.43 on sapphire, 1.52 on rose, 1.55 on
   indigo, 1.73 on navy, 1.81 on aurora, 1.82 on copper — the exact figures in the
   report, which is what identified the element.
   Using the token means every theme already has a correct value; the chevron
   follows via currentColor so it can never drift from its label again. */
.sidebar-section{
  padding:16px 16px 5px 16px;color:var(--sb-text);font-size:11px;font-weight:800;
  letter-spacing:.06em;text-transform:uppercase;
  display:flex;align-items:center;justify-content:space-between;
  cursor:pointer;user-select:none;transition:color .15s;
  border-top:1px solid var(--sb-border);margin-top:4px;
}
.sidebar-section:first-child{border-top:none;margin-top:0}
.sidebar-section:hover{color:var(--sb-hover-text,var(--sb-text))}
.sidebar-section .chevron{
  width:10px;height:10px;opacity:.75;flex-shrink:0;
  transition:transform .2s ease;stroke:currentColor;
}
.sidebar-section.collapsed .chevron{transform:rotate(-90deg)}

.sidebar-group{overflow:hidden;transition:max-height .22s ease}
.sidebar-group.collapsed{max-height:0 !important}

.sidebar-link{
  display:flex;align-items:center;gap:8px;padding:6px 10px;
  color:var(--sb-text);text-decoration:none;font-size:12px;
  transition:background .12s,color .12s;border-radius:7px;margin:1px 7px;
}
/* BUG-80: hover used a hardcoded near-black (#111827). That works on the light
   sidebars it was written for (default/corporate/arctic), but every accent theme
   has a DARK sidebar — teal --sb-hover-bg is #063a36 — so hovering turned the
   label near-black on near-black, ~1.4:1. The measured "sidebar link text
   1.40–1.82:1" across Teal/Sapphire/Rose/Indigo/Navy/Aurora/Copper is this rule,
   not the resting colour: resting uses --sb-text, which is already a light tint
   on those themes and passes comfortably.
   --sb-hover-text lets each theme state its own readable hover colour; it falls
   back to --sb-text, so a theme that never sets it simply keeps its resting
   colour on hover and can no longer go unreadable. */
.sidebar-link:hover{background:var(--sb-hover-bg);color:var(--sb-hover-text,var(--sb-text))}
.sidebar-link.active{background:var(--sb-active-bg);color:var(--sb-active-text);font-weight:600}
.sidebar-link svg{width:15px;height:15px;opacity:.6;flex-shrink:0;color:var(--sb-text)}
.sidebar-link:hover svg{opacity:.85}
.sidebar-link.active svg{opacity:1;color:var(--sb-active-text)}

/* ── Resize handle ── */
.sidebar-resizer{
  position:absolute;top:0;right:0;width:4px;height:100%;
  cursor:col-resize;z-index:200;background:transparent;transition:background .15s;
}
.sidebar-resizer:hover,.sidebar-resizer.dragging{background:var(--sb-border)}

.sidebar-footer{padding:10px 14px;border-top:1px solid var(--sb-border);background:#fff}
.sidebar-logout{
  display:flex;align-items:center;gap:7px;color:var(--sb-muted);
  font-size:12.5px;cursor:pointer;background:none;border:none;
  padding:4px 0;transition:color .15s;border-radius:6px;
}
.sidebar-logout:hover{color:#dc2626}

/* ── Main Content ─────────────────────────────────────────────────────────── */
/* BUG-57 / BUG-101: min-width:0 is load-bearing, not tidying.
   .main-content is a FLEX ITEM of .app-shell, and a flex item defaults to
   min-width:auto — meaning it refuses to shrink below its content. A ticket grid
   2534px wide therefore stretched .main-content to 2636px and the whole page
   scrolled sideways, taking the sticky .topbar with it: the bell, theme and
   language controls ended up at x≈2500, off the right edge of a 1664px viewport,
   which is why they looked "gone" on All Tickets (BUG-101).
   min-width:0 lets it shrink to the viewport again, so the overflow lands on
   .wb-grid-scroll — the element that is supposed to scroll — instead of the page.
   The earlier fix put overflow-x:auto on the wrapper but never capped its
   ancestors, so the wrapper simply grew to the table and never scrolled. */
.main-content{margin-left:var(--sidebar-w,265px);flex:1;display:flex;flex-direction:column;min-height:100vh;min-width:0;max-width:100%}
.topbar{
  background:var(--surface);border-bottom:1px solid var(--border);
  padding:14px 28px;display:flex;justify-content:space-between;align-items:center;
  position:sticky;top:0;z-index:50;
  /* BUG-101: never let page content widen the sticky bar. */
  min-width:0;max-width:100%;
}
.topbar-title{font-weight:700;font-size:18px;color:var(--brand)}
.topbar-actions{display:flex;align-items:center;gap:10px}
/* Same reasoning one level down: .page-body is a flex item of .main-content and
   must also be allowed to shrink, or it re-introduces the overflow itself. */
.page-body{padding:24px 28px;flex:1;min-width:0;max-width:100%;overflow-x:clip}

/* ── Cards ────────────────────────────────────────────────────────────────── */
.card{background:var(--surface);border-radius:12px;padding:22px;min-width:0;max-width:100%;box-shadow:0 1px 4px rgba(0,0,0,.07);margin-bottom:20px;border:1px solid var(--border)}
.card-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:18px}
.card-title{font-size:16px;font-weight:700;color:var(--brand)}

/* BUG-134 — the page heading, in ONE place instead of nineteen inline copies.
   It was 22px sitting above 16px card titles, which is what made it read as
   oversized once BUG-134's dedup left it as the only title on the page. 18px
   keeps it clearly the top of the hierarchy without shouting over the cards
   beneath it. The orange rule and colour are the previous treatment, kept. */
.page-title{
  font-size:18px;font-weight:700;color:#0f172a;
  padding-left:10px;border-left:3px solid #FF8A1F;
  margin:0 0 6px;
}
.page-title.tight  { margin:0; }
.page-title.roomy  { margin:0 0 18px; }

/* ── Grid ─────────────────────────────────────────────────────────────────── */
.grid{display:grid;gap:16px}
.grid-4{grid-template-columns:repeat(4,1fr)}
.grid-3{grid-template-columns:repeat(3,1fr)}
.grid-2{grid-template-columns:repeat(2,1fr)}

/* ── Stat Tiles ───────────────────────────────────────────────────────────── */
.stat-tile{background:var(--surface);border-radius:12px;padding:20px 22px;box-shadow:0 1px 4px rgba(0,0,0,.07);border:1px solid var(--border);border-top:4px solid var(--accent);text-align:center}
.stat-num{font-size:2.2rem;font-weight:800;color:var(--brand);line-height:1}
.stat-label{font-size:.8rem;color:var(--muted);margin-top:6px;font-weight:500}
.stat-alert{border-top-color:var(--danger)!important;background:#fff5f5}
.stat-alert .stat-num{color:var(--danger)}
.stat-warn{border-top-color:var(--warn)!important;background:#fffbeb}
.stat-warn .stat-num{color:#b45309}
.stat-success{border-top-color:var(--success)!important}
.stat-purple{border-top-color:var(--purple)!important}

/* ── Buttons ──────────────────────────────────────────────────────────────── */
.btn{display:inline-flex;align-items:center;gap:6px;background:var(--accent);color:white;border:none;padding:9px 16px;border-radius:8px;font-size:13.5px;font-weight:600;cursor:pointer;text-decoration:none;transition:background .15s}
.btn:hover{background:var(--accent-hover)}
.btn-sm{padding:6px 12px;font-size:12.5px}
.btn-secondary{background:#334155}.btn-secondary:hover{background:#1e293b}
.btn-danger{background:var(--danger)}.btn-danger:hover{background:#b91c1c}
.btn-success{background:var(--success)}.btn-success:hover{background:#059669}
.btn-purple{background:var(--purple)}.btn-purple:hover{background:#6d28d9}
.btn-ghost{background:transparent;color:var(--accent);border:1.5px solid var(--accent)}.btn-ghost:hover{background:#eff6ff}

/* ── Tables ───────────────────────────────────────────────────────────────── */
.table{width:100%;border-collapse:collapse}
.table th{background:#f8fafc;color:var(--muted);font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;padding:10px 14px;text-align:left;border-bottom:2px solid var(--border)}
.table td{padding:11px 14px;border-bottom:1px solid var(--border);font-size:13.5px;vertical-align:middle}
.table tbody tr:hover{background:#f8fafc}
.table tbody tr:last-child td{border-bottom:none}

/* ── Forms ────────────────────────────────────────────────────────────────── */
.field{display:flex;flex-direction:column;gap:5px;margin-bottom:16px}
.field label{font-size:13px;font-weight:600;color:#374151}
.field input,.field textarea,.field select{
  padding:9px 12px;border:1.5px solid var(--border);border-radius:8px;
  font-size:14px;color:var(--text);background:white;transition:border-color .15s;
  font-family:inherit;
}
.field input:focus,.field textarea:focus,.field select:focus{outline:none;border-color:var(--accent)}
textarea{min-height:120px;resize:vertical}
.form-row{display:grid;grid-template-columns:1fr 1fr;gap:16px}
/* BUG-22: the Linked-Tickets "Add Link" row lays its controls out in a grid, not
   .field wrappers, so the Relation/Direction selects and the Ticket/Remarks inputs
   missed the shared input styling and rendered as bare native controls. Give them
   the same border/radius/padding as every other form control so the row matches the
   rest of the app. */
.wb-linkform select,.wb-linkform input:not([type=hidden]){
  padding:9px 12px;border:1.5px solid var(--border);border-radius:8px;
  font-size:14px;color:var(--text);background:white;font-family:inherit;width:100%;
}
.wb-linkform select:focus,.wb-linkform input:not([type=hidden]):focus{outline:none;border-color:var(--accent)}

/* ── Badges ───────────────────────────────────────────────────────────────── */
.badge{display:inline-block;padding:3px 10px;border-radius:999px;font-size:12px;font-weight:600}
.badge-open{background:#dbeafe;color:#1d4ed8}
.badge-inprogress{background:#fef3c7;color:#92400e}
.badge-forwarded{background:#ede9fe;color:#5b21b6}
.badge-resolved{background:#d1fae5;color:#065f46}
.badge-closed{background:#f1f5f9;color:#475569}
.badge-critical{background:#fee2e2;color:#991b1b}
.badge-high{background:#ffedd5;color:#9a3412}
.badge-medium{background:#fef9c3;color:#854d0e}
.badge-low{background:#f0fdf4;color:#166534}
/* BUG-69 severity scale: System Unavailable=Red (badge-critical),
   Business Impact=Orange (badge-high), Functional=Blue (new), Cosmetic=Grey.
   badge-low is reused for Cosmetic; its green tint reads as "nothing to worry
   about", which is what Cosmetic means. Tints match the existing badges rather
   than using the raw spec hexes as backgrounds — solid #2563EB behind dark text
   would fail the same contrast bar BUG-80 is about. */
.badge-functional{background:#dbeafe;color:#1e40af}
.badge-cosmetic{background:#f1f5f9;color:#334155}
.badge-admin{background:#ede9fe;color:#5b21b6}
.badge-agent{background:#dbeafe;color:#1d4ed8}
.badge-partner{background:#fef3c7;color:#92400e}
.badge-customer{background:#f0fdf4;color:#166534}

/* ── Alerts ───────────────────────────────────────────────────────────────── */
.alert{padding:12px 16px;border-radius:8px;margin-bottom:16px;font-size:13.5px;display:flex;align-items:flex-start;gap:8px}
.alert-danger{background:#fef2f2;border:1px solid #fecaca;color:#991b1b}
.alert-success{background:#f0fdf4;border:1px solid #bbf7d0;color:#166534}
.alert-warn{background:#fffbeb;border:1px solid #fde68a;color:#92400e}
.alert-info{background:#eff6ff;border:1px solid #bfdbfe;color:#1d4ed8}
.alert-tamper{background:#fef2f2;border-left:4px solid var(--danger)}

/* ── Misc ─────────────────────────────────────────────────────────────────── */
.danger{color:var(--danger)}
.muted{color:var(--muted)}
.html-content{background:#fafafa;border:1px solid var(--border);padding:16px 18px;border-radius:8px;line-height:1.65;color:#0f172a;font-size:14px;max-width:88ch;white-space:pre-wrap}
.html-content p{margin:0 0 12px;white-space:normal}
.html-content p:last-child{margin-bottom:0}
.html-content ul,.html-content ol{margin:0 0 12px;padding-left:22px;white-space:normal}
.html-content li{margin:2px 0}
.html-content h1,.html-content h2,.html-content h3{margin:14px 0 8px;font-weight:700;color:#0f172a;white-space:normal}
.html-content code{background:#eef2ff;border:1px solid #e0e7ff;padding:1px 6px;border-radius:4px;font-size:.92em}
.html-content pre{background:#0f172a;color:#e2e8f0;padding:12px 14px;border-radius:8px;overflow-x:auto;font-size:.92em;line-height:1.5;margin:0 0 12px;white-space:pre}
.html-content blockquote{border-left:3px solid var(--accent,#0ea5e9);background:#f1f5f9;padding:6px 12px;margin:0 0 12px;color:#334155;border-radius:0 6px 6px 0;white-space:normal}
.html-content a{color:#0369a1;text-decoration:underline}
.html-content img{max-width:100%;height:auto;border-radius:6px}
/* ENH-09: comment/notes list — capped height, internal scrollbar only on overflow */
.wb-comment-scroll{max-height:min(60vh,560px);overflow-y:auto}
.wb-comment-scroll>div{margin-right:2px}
/* ENH-29: comment / internal-note bodies use the FULL width of their card. The 88ch cap
   above is a readable-measure for standalone prose (the ticket description opts out the
   same way, inline — ENH-06), but inside a comment bubble it left roughly the right half
   of the card empty and wrapped replies into more lines than necessary. */
/* BUG-24: the plain override above still measured ~78% — the global 88ch readable
   measure was winning (88ch happens to land near 78% of the card at this font size).
   Force it, and cover nested wrappers, so a comment genuinely fills its card. The
   bubble itself has no width cap, so this is the only thing holding the text in. */
.wb-comment-scroll .html-content,
.wb-comment-scroll .html-content > *{max-width:100% !important}
.section-title{font-size:15px;font-weight:700;color:var(--brand);margin-bottom:16px;padding-bottom:10px;border-bottom:1px solid var(--border)}
.empty-state{text-align:center;padding:40px 20px;color:var(--muted)}
.empty-state p{margin-top:8px;font-size:13.5px}

/* ── Login Page ───────────────────────────────────────────────────────────── */
.login-wrap{min-height:100vh;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,var(--brand) 0%,var(--brand-light) 100%)}
.login-card{background:white;border-radius:16px;padding:40px;width:100%;max-width:420px;box-shadow:0 20px 60px rgba(0,0,0,.2)}
.login-logo{text-align:center;margin-bottom:28px}
.login-logo h1{color:var(--brand);font-size:22px;font-weight:800;margin-top:8px}
.login-logo p{color:var(--muted);font-size:13px;margin-top:4px}

/* ── Responsive ───────────────────────────────────────────────────────────── */
@media(max-width:768px){
  /* Sidebar + main-content on phones are owned by mobile.css (the off-canvas
     hamburger drawer). The old icon-rail rules that used to live here
     (.sidebar width:60px and display:none on .sidebar-section / .sidebar-link
     span / brand / user-info) conflicted with that drawer: mobile.css won on
     width/position, but these display:none rules leaked through, so opening
     the drawer showed icons with no labels or headers — an unreadable,
     "missing" menu. Removed; mobile.css is the single source for mobile nav. */
  .grid-4{grid-template-columns:repeat(2,1fr)}
  .grid-3{grid-template-columns:repeat(2,1fr)}
  .form-row{grid-template-columns:1fr}
}

/* ── Sidebar favourites ───────────────────────────────────────────────────── */
.sidebar-link .fav-star{
  margin-left:auto;width:14px;height:14px;opacity:0;flex-shrink:0;
  color:#d1d5db;transition:opacity .15s,color .15s;cursor:pointer;
}
.sidebar-link:hover .fav-star{opacity:1}
.sidebar-link.is-fav .fav-star{opacity:1;color:#f59e0b}
.fav-group-heading{
  padding:6px 16px 2px;font-size:9.5px;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:#9ca3af;
  display:flex;align-items:center;gap:6px;
}
.fav-group-heading svg{width:11px;height:11px;fill:#f59e0b;stroke:none}

/* ── Grid Toolbar (shared pattern) ─────────────────────────────────────────── */
.grid-toolbar{
  display:flex;align-items:center;gap:8px;padding:10px 14px;
  background:#fafbfc;border-bottom:1px solid var(--border);
  flex-wrap:wrap;min-height:48px;
}
.grid-toolbar .grid-actions{display:flex;gap:6px;align-items:center;flex-wrap:wrap}
.grid-toolbar .grid-spacer{flex:1}
.grid-toolbar .grid-search{
  padding:6px 11px;border:1.5px solid var(--border);border-radius:8px;
  font-size:13px;width:200px;
}
.grid-sel-badge{
  display:none;align-items:center;gap:5px;padding:3px 10px;
  background:#dbeafe;color:#1d4ed8;border-radius:10px;font-size:12px;font-weight:600;
}
.grid-sel-badge.visible{display:inline-flex}

/* Toolbar action buttons — disabled state */
.grid-action-btn{cursor:pointer}
.grid-action-btn:disabled,.grid-action-btn[disabled]{
  opacity:.4;cursor:not-allowed;pointer-events:none;
}

/* Table checkbox column */
.table th.cb-col,.table td.cb-col{width:36px;padding:10px 4px 10px 12px}
.table tbody tr.selected{background:#eff6ff !important}
.table tbody tr:hover{background:var(--hover,#f8fafc);cursor:pointer}

/* Grid Framework (Phase 3) */
.col-hidden{display:none !important}
th[data-sort]{cursor:pointer;user-select:none}
th[data-sort]:hover{background:#eef2f7}
.grid-sort-ind{margin-left:4px;font-size:11px;opacity:.8}/* BUG-80: was .45 (~2.0-2.4:1 in every theme) */
th.sort-asc .grid-sort-ind,th.sort-desc .grid-sort-ind{opacity:1;color:var(--accent)}
.grid-filter-row input.js-grid-filter{width:100%;padding:3px 6px;font-size:11.5px;border:1px solid var(--border);border-radius:5px;font-weight:400}
.grid-filter-row th{background:#fafbfc;padding-top:4px;padding-bottom:4px}
.muted{color:var(--muted)}
.js-grid-gear{background:none;border:1px solid var(--border);border-radius:6px;padding:4px 9px;cursor:pointer;font-size:13px}
.js-grid-gear:hover{background:#eef2f7}

/* Column chooser modal: drag-to-reorder rows */
.grid-col-list{position:relative}
.grid-col-item{display:flex;align-items:center;gap:8px;font-size:13px;padding:6px 8px;border:1px solid transparent;border-radius:6px;background:#fff;user-select:none}
.grid-col-item:hover{background:#f5f8fc;cursor:grab}
.grid-col-item.dragging{opacity:.5;cursor:grabbing;background:#eef4fb;border-color:var(--border)}
.grid-col-handle{display:inline-flex;align-items:center;justify-content:center;width:18px;height:22px;color:#94a3b8;font-size:14px;letter-spacing:-2px;cursor:grab;line-height:1;flex:0 0 auto}
.grid-col-handle:active{cursor:grabbing}
.grid-col-item.dragging .grid-col-handle{cursor:grabbing}
.grid-col-label{flex:1;color:#1f2937}
.grid-col-drop-ind{position:absolute;left:0;right:0;height:2px;background:var(--accent);pointer-events:none;border-radius:2px;box-shadow:0 0 0 1px rgba(0,87,184,.25);display:none}


/* ── BUG-76: searchable native <select> (select-enhance.js) ─────────────────
   The native control keeps its box in the layout but is made invisible and
   non-interactive. NOT display:none — a display:none control cannot be focused,
   so the browser silently drops its `required` validation bubble and the field
   fails with no message. */
.wb-ss2{position:relative;display:block}
.wb-ss2-native{position:absolute;inset:0;opacity:0;pointer-events:none;z-index:-1}
.wb-ss2-btn{
  width:100%;text-align:left;background:var(--surface);border:1px solid var(--border);
  border-radius:8px;padding:8px 10px;font-size:13.5px;color:var(--text);cursor:pointer;
  display:flex;align-items:center;justify-content:space-between;gap:8px;
}
.wb-ss2-btn::after{content:'▾';color:var(--muted);font-size:11px}
.wb-ss2-btn:hover{border-color:var(--accent)}
.wb-ss2-btn:focus{outline:2px solid var(--accent);outline-offset:1px}
.wb-ss2-btn:disabled{opacity:.6;cursor:not-allowed}
.wb-ss2-panel{
  position:absolute;top:calc(100% + 3px);left:0;right:0;z-index:400;
  background:var(--surface);border:1px solid var(--border);border-radius:8px;
  box-shadow:0 6px 20px rgba(0,0,0,.13);padding:6px;
}
.wb-ss2-search{width:100%;padding:6px 8px;font-size:13px;border:1px solid var(--border);border-radius:6px}
.wb-ss2-list{max-height:220px;overflow-y:auto;margin-top:5px}
.wb-ss2-item{padding:6px 8px;font-size:13px;border-radius:6px;cursor:pointer}
.wb-ss2-item:hover{background:var(--sb-hover-bg,#eef0f6)}
.wb-ss2-item.is-sel{font-weight:600;color:var(--accent)}
.wb-ss2-empty{padding:7px 8px;font-size:12.5px;color:var(--muted)}

/* ── BUG-57: contain the horizontal scroll INSIDE the grid ─────────────────
   Third attempt, and the decision changed twice, so the reasoning matters more
   than the rule:

     1. First it was page-level overflow — reading the right-hand columns dragged
        the sidebar and header sideways. Fixed by containing the scroll here.
     2. Then the requester asked to FIT the columns instead, so the wrapper was
        joined by truncation, column hiding and table-layout:fixed.
     3. The requester has now reversed that: keep every column at its natural
        width and bring the scroll bar back — it just must belong to the GRID,
        not the page.

   So the fit-to-page machinery is gone: no table-layout:fixed, no forced column
   widths, no breakpoint hiding. Only the containment survives, which was the
   part that was right all along. Columns size to content again and the table is
   free to be wider than the viewport, because .wb-grid-scroll now scrolls.

   min-width:0 is load-bearing: this sits in a flex/grid parent where the default
   min-width:auto lets a wide child push the container instead of scrolling
   inside it — without it the wrapper is inert and the page scrolls again.
   The title= attributes added for truncation are kept: a full value on hover is
   useful whether or not the cell is clipped. */
.wb-grid-scroll{overflow-x:auto;min-width:0;max-width:100%;-webkit-overflow-scrolling:touch}
.wb-grid-scroll .table{width:max-content;min-width:100%}

/* ── BUG-73: a real tooltip for the widget "?" icons ────────────────────────
   The icons shipped carrying their explanation in the native title attribute
   only. That is not a tooltip: the browser's own bubble is slow (~1s), cannot
   be styled, does not appear on keyboard focus at all, and on some setups does
   not appear over a span with no other content. QA hovered and saw nothing.

   This renders the SAME text as a styled bubble on hover AND on focus, driven
   by data-tip so the native title can be removed (leaving both would show two
   tooltips). aria-label stays on the element, so assistive tech is unaffected
   by any of this. */
.wb-tip{position:relative}
.wb-tip::after{
  content:attr(data-tip);
  position:absolute;left:50%;bottom:calc(100% + 8px);transform:translateX(-50%);
  min-width:180px;max-width:280px;width:max-content;
  background:#0f172a;color:#fff;text-align:left;font-weight:400;
  font-size:11.5px;line-height:1.45;letter-spacing:0;text-transform:none;
  padding:7px 10px;border-radius:7px;box-shadow:0 6px 20px rgba(15,23,42,.28);
  opacity:0;visibility:hidden;transition:opacity .12s ease;z-index:400;pointer-events:none;
}
.wb-tip::before{
  content:'';position:absolute;left:50%;bottom:calc(100% + 3px);transform:translateX(-50%);
  border:5px solid transparent;border-top-color:#0f172a;
  opacity:0;visibility:hidden;transition:opacity .12s ease;z-index:401;pointer-events:none;
}
.wb-tip:hover::after,.wb-tip:focus::after,.wb-tip:focus-visible::after,
.wb-tip:hover::before,.wb-tip:focus::before,.wb-tip:focus-visible::before{opacity:1;visibility:visible}
/* Near the top of the viewport the bubble would be clipped, so flip it below. */
.wb-tip.wb-tip-below::after{bottom:auto;top:calc(100% + 8px)}
.wb-tip.wb-tip-below::before{bottom:auto;top:calc(100% + 3px);border-top-color:transparent;border-bottom-color:#0f172a}


/* ── BUG-96: the New Ticket call-to-action on My Dashboard ──────────────────
   Restyled to the requester brief: a modern CTA card rather than a flat filled
   rectangle — soft brand gradient, the icon in its own rounded badge, a headline
   with a supporting subtitle, generous padding and a lift-plus-glow on hover.

   Text and icon stay DARK on the orange. White on #f3941f measures 2.32:1; the
   dark token is 6.34:1. And the foreground is pinned rather than inherited
   because the gradient is a fixed brand colour — on a dark theme var(--text) is
   near-white and would land back at ~2:1.

   The hover is transform + box-shadow only. Animating size or border would
   reflow the dashboard grid under the cursor. */
.wb-cta-new-ticket{
  position:relative;margin:0;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:10px;min-height:170px;padding:22px;border-radius:16px;
  text-decoration:none;overflow:hidden;
  color:var(--ebos-orange-on);
  background:linear-gradient(135deg,#f7a93d 0%,var(--ebos-orange) 55%,#e8850e 100%);
  border:1px solid rgba(15,23,42,.10);
  box-shadow:0 3px 10px rgba(243,148,31,.30);
  transition:transform .16s cubic-bezier(.2,.7,.3,1),box-shadow .16s ease;
}
/* Soft highlight so the card reads as a surface, not a swatch. */
.wb-cta-new-ticket::before{
  content:;position:absolute;inset:0;
  background:radial-gradient(120% 80% at 50% -20%,rgba(255,255,255,.45),transparent 60%);
  pointer-events:none;
}
.wb-cta-new-ticket .wb-cta-badge{
  display:flex;align-items:center;justify-content:center;width:56px;height:56px;
  border-radius:50%;background:rgba(255,255,255,.55);
  box-shadow:0 2px 8px rgba(15,23,42,.12);
  transition:transform .16s cubic-bezier(.2,.7,.3,1);
}
.wb-cta-new-ticket span{font-size:20px;font-weight:800;letter-spacing:-.2px;line-height:1}
.wb-cta-new-ticket small{font-size:12.5px;font-weight:500;opacity:.8}
.wb-cta-new-ticket:hover{transform:translateY(-3px);box-shadow:0 12px 26px rgba(243,148,31,.45)}
.wb-cta-new-ticket:hover .wb-cta-badge{transform:scale(1.08) rotate(-6deg)}
.wb-cta-new-ticket:active{transform:translateY(-1px);box-shadow:0 4px 12px rgba(243,148,31,.32)}
.wb-cta-new-ticket:focus-visible{outline:3px solid var(--accent);outline-offset:3px}
@media (prefers-reduced-motion:reduce){
  .wb-cta-new-ticket,.wb-cta-new-ticket:hover,
  .wb-cta-new-ticket .wb-cta-badge,.wb-cta-new-ticket:hover .wb-cta-badge{transition:none;transform:none}
}

/* BUG-126: per-row Copy Link / Copy ID in the ticket grids (agent-only).
   Muted until hovered so two icons on every row don't compete with the data. */
.wb-row-copy button:hover{color:var(--accent,#0057b8)!important}
.wb-row-copy button:focus-visible{outline:2px solid var(--accent,#0057b8);outline-offset:1px;border-radius:3px}
