/* theme_v2 - shell classes the template renders from JS, written as CSS.
 *
 * global.css (shipped with the template) owns the design system and most shell
 * classes (.app .sidebar .header .content .btn .card .dropdown .dd-item .avatar).
 * This file adds the few pieces the template built with inline styles inside
 * shell.js - brand block, system switcher, breadcrumb, user button - plus the
 * overrides that make v1's page-body markup sit correctly inside the new shell.
 *
 * Loads LAST, so it wins over both bootstrap and global.css.
 */

/* ===== Shell scaffolding ===== */
.app{display:flex;min-height:100vh;background:var(--bg)}
.main{flex:1;min-width:0;display:flex;flex-direction:column}
.content{flex:1;padding:22px}
/* THE PAGE GETS THE WHOLE WIDTH. It was capped at 1440 and centred, which on
   any wider screen paid for a tidy measure with two empty gutters - and the
   page head, which is not inside a sheet, ran to the full width anyway, so the
   heading and its buttons ended level with nothing below them.

   The cap only ever helped the pages that are reading matter. Those set their
   own measure on their own container (see .inv-shell in components.css); the
   rest - tables, tabs, section grids - are laid out in columns and get wider,
   not longer, which is the whole point of a wide screen. A shell-level cap
   cannot tell the two apart, so it is the page's decision to make.

   .content still pads by 22px, so nothing touches the window edge. */
.wrap{max-width:none;margin:0}
body{background:var(--bg);color:var(--text);font-family:var(--font);font-size:14px;margin:0}

/* ===== Icon glyphs sit on the baseline unless told otherwise =====
 * The Material Icons stylesheet ships `display:inline-block;font-size:24px` and
 * no vertical-align, so an icon dropped beside plain text rides a third of a
 * line above it and stretches the line box to 24px. Inside a flex or grid
 * container vertical-align is ignored, so this only reaches the inline cases -
 * which are exactly the ones that were out of line. */
.material-icons-outlined,.material-icons{vertical-align:middle}

/* ===== Sidebar ===== */
.sidebar{width:var(--sidebar-w);flex:0 0 var(--sidebar-w);background:var(--surface);border-inline-end:1px solid var(--border);display:flex;flex-direction:column}
.sidebar.collapsed{display:none}
/* min-height, not height: the system name is whatever $gdata.system.title says,
   and "Merchant Management System" wraps to three lines once the drawer's close
   button takes its share of the row. A fixed height clipped the first line. */
.sidebar-brand{display:flex;align-items:center;gap:10px;min-height:var(--header-h);padding:9px 16px;border-bottom:1px solid var(--border);text-decoration:none;color:inherit}
.brand-mark{width:32px;height:32px;border-radius:10px;background:var(--accent-soft);color:var(--accent);font-size:16px;font-weight:800;font-family:Georgia,serif;display:grid;place-items:center;text-transform:uppercase}
.brand-text{min-width:0}
/* two lines at most, then ellipsis - a long system name must not push the
   whole nav down the drawer */
.brand-name{display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-size:13.5px;font-weight:800;letter-spacing:-.02em;line-height:1.2;color:var(--text)}
.brand-sub{display:block;font-size:10px;color:var(--text-3);font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sidebar-nav{flex:1;overflow-y:auto;padding:10px 9px}
.nav-group{font-size:10px;font-weight:800;letter-spacing:.09em;text-transform:uppercase;color:var(--text-4);padding:13px 9px 6px}
.nav-item{display:flex;align-items:center;gap:9px;padding:8px 9px;border-radius:9px;color:var(--text-2);font-size:13px;font-weight:600;text-decoration:none}
.nav-item:hover{background:var(--surface-3);color:var(--text)}
.nav-item.active{background:var(--accent-soft);color:var(--accent)}
.nav-item .label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* A square box, centred: the glyphs in the menu are not one family of shapes -
   `dashboard` fills its em box, `arrow_right` is a small triangle floated inside
   it - so only a fixed box with the glyph centred in it keeps every icon on the
   same line as its label. flex:none or a long title squeezes the icon narrow. */
.nav-ico{display:inline-flex;align-items:center;justify-content:center;flex:none;
  width:20px;height:20px;font-size:18px;line-height:1}
.sidebar-foot{padding:10px 9px;border-top:1px solid var(--border)}

/* ===== Header ===== */
.header{display:flex;align-items:center;gap:9px;height:var(--header-h);padding:0 16px;background:var(--surface);border-bottom:1px solid var(--border)}
.hdr-rel{position:relative;flex:none}
.hdr-divider{width:1px;height:24px;background:var(--border);flex:none}
.spacer{flex:1}
.chev{font-size:16px;color:var(--text-3)}
.icon-box{display:grid;place-items:center}

.sys-btn{height:36px;background:var(--surface-2);gap:7px}
.sys-mark{width:22px;height:22px;border-radius:7px;background:var(--accent-soft);color:var(--accent);font-size:12px;font-weight:800;font-family:Georgia,serif;text-transform:uppercase}
.sys-name{font-size:12.5px;font-weight:800;color:var(--accent)}
.sys-dd{width:246px}
.sys-ico{width:26px;height:26px;border-radius:8px;font-size:13px;font-weight:800;font-family:Georgia,serif}
.sys-mms{background:#fbebec;color:#b3282f}
.sys-gatee{background:#e8f1fd;color:#1668d6}
.sys-einvoice{background:#e7f5fc;color:#2f9fdc}
.dd-text{flex:1;min-width:0}
.dd-title{display:block;font-size:12.5px;font-weight:700;color:var(--text)}
.dd-sub{display:block;font-size:10.5px;color:var(--text-3);font-weight:600}
.dd-sep{height:1px;background:var(--border);margin:7px 4px}
.dd-plain{font-size:12px;font-weight:700;color:var(--text-2)}
.dd-head{padding:6px 9px 9px;border-bottom:1px solid var(--border-2);margin-bottom:6px}

.crumb{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--text-3);flex:none}
.crumb-sys{font-weight:600}
.crumb-sep{color:var(--text-4)}
.crumb-page{font-weight:700;color:var(--text)}

/* Every control in the header is 36px tall. They were 34 (.btn-icon), 36
   (.sys-btn), 38 (.user-btn) and 38.5 (.search, sized by its padding plus
   whatever line-height the input happened to have) - four heights in one row,
   which is what made the bar read as unaligned. Height, not padding, so the
   input's own metrics can no longer change it. */
.search{display:flex;align-items:center;gap:7px;margin-inline-start:12px;flex:1;max-width:320px;height:36px;padding:0 11px;border:1px solid var(--border);border-radius:10px;background:var(--surface-2)}
.search input{border:0;background:none;outline:none;flex:1;min-width:0;font:inherit;font-size:12.5px;line-height:1;color:var(--text);padding:0}
.search .material-icons-outlined{flex:none;font-size:17px;line-height:1;color:var(--text-3)}

.bell{position:relative}
.user-btn{gap:9px;height:36px}
.header .btn-icon{width:36px;height:36px}
.user-text{text-align:start;line-height:1.25;min-width:0}
.user-name{display:block;font-size:12px;font-weight:700;color:var(--text);max-width:130px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.user-mail{display:block;font-size:10px;color:var(--text-3);font-weight:600;max-width:130px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.avatar{text-transform:uppercase}
.user-dd{width:220px;inset-inline-start:auto;inset-inline-end:0}
.dropdown{position:absolute;top:calc(100% + 6px);z-index:60;background:var(--surface);border:1px solid var(--border);border-radius:12px;box-shadow:var(--sh-lg);padding:6px}
.dd-item{display:flex;align-items:center;gap:9px;padding:8px 9px;border-radius:8px;color:var(--text-2);font-size:12.5px;font-weight:600;text-decoration:none;background:none;border:0;width:100%;cursor:pointer}
.dd-item:hover{background:var(--surface-3);color:var(--text)}
.dd-item .material-icons-outlined{font-size:17px}

/* The hidden attribute must beat any display rule. */
[hidden]{display:none !important}

/* ===== v1 page bodies inside the new shell =====
   Page markup is still bootstrap. global.css already restyles .btn/.card, so
   these only correct layout artefacts from v1's own theme wrapper. */
.page-wrapper,.page-content{padding:0 !important;margin:0 !important;background:transparent !important;min-height:0 !important}
.main-wrapper,.main-content{padding:0 !important;margin:0 !important;background:transparent !important;width:auto !important}
.wrapper{display:block !important}
.page-breadcrumb{display:none}
.sidebar-wrapper,.top-header,.overlay,.switcher-wrapper,.footer,.back-to-top{display:none !important}

/* v1 tables keep every feature; just align them to the tokens. */
.table-wrapper{border:1px solid var(--border);border-radius:14px;background:var(--surface)}
/* Header row is a label strip, not a data row - it gets the tighter padding and
   a fixed line-height so its height is padding + icon box and nothing else. */
table.dynamic-table thead th{background:var(--surface-2);color:var(--text-3);font-weight:600;font-size:11.5px;
  letter-spacing:.02em;line-height:1;border-bottom:1px solid var(--border);padding:7px 12px;vertical-align:middle}
table.dynamic-table tbody td{border-bottom:1px solid var(--border-2);padding:12px 14px;color:var(--text-2);vertical-align:middle}
table.dynamic-table tbody tr:hover td{background:var(--surface-2)}

/* Sort + drag glyphs sit in the same line box as the header's text node, so they
   have to be middle-aligned boxes of a known height - left as plain baseline
   inline-blocks the 24px default of the Material Icons stylesheet pushed them a
   third of a row above the label and set the row height on its own. */
table.dynamic-table thead th .sort-icon,
table.dynamic-table thead th .drag-handle{display:inline-flex;align-items:center;justify-content:center;
  vertical-align:middle;width:15px;height:15px;line-height:1;margin:0;margin-inline-start:4px}
table.dynamic-table thead th .sort-icon .material-icons-outlined,
table.dynamic-table thead th .drag-handle .material-icons-outlined{font-size:15px;line-height:1;color:var(--text-4)}
table.dynamic-table th.sort-asc .sort-icon .material-icons-outlined,
table.dynamic-table th.sort-desc .sort-icon .material-icons-outlined{color:var(--accent)}
.pin-btn.pinned{color:var(--accent);background:var(--accent-soft)}
.filter-panel{background:var(--surface-2);border:1px solid var(--border);border-radius:14px}
.custom-checkbox{background:var(--surface);border:1px solid var(--border);border-radius:8px;color:var(--text-2)}
.custom-checkbox:hover{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}
.custom-checkbox input[type="checkbox"]{accent-color:var(--accent)}
.card-item{background:var(--surface);border:1px solid var(--border);border-radius:14px}
.card-item:hover{border-color:var(--accent)}
/* .badge moved to components.css - it is the single owner of badge styling */

/* ===== Responsive =====
 * The sidebar is a drawer below 960px. `.sidebar.collapsed{display:none}` above
 * is unconditional, so the drawer must clear that class to be visible - app.js
 * toggles `open` on mobile and `collapsed` on desktop rather than both at once,
 * which is why the menu button used to do nothing on a phone. */
/* The drawer sits ABOVE the header, so its z-index has to beat .header's 30 -
 * and the scrim has to sit between the two. Anything lower and the header
 * paints over the top of the drawer, hiding the brand. */
.sidebar-scrim{position:fixed;inset:0;z-index:110;background:rgba(11,22,28,.5);border:0;padding:0}

.sidebar-head{display:flex;align-items:center;gap:6px}
.sidebar-head .sidebar-brand{flex:1;min-width:0}
.sidebar-close{display:none;flex:none;margin-inline-end:10px}

@media (min-width:961px){ .sidebar-scrim{display:none} }

@media (max-width:960px){
/* 100dvh, not 100vh: on a phone 100vh is the height WITHOUT the browser's
   address bar, so the foot of the drawer sits below the fold until you scroll */
.sidebar{position:fixed;top:0;bottom:0;inset-inline-start:0;height:100dvh;z-index:120;
  box-shadow:var(--sh-lg);width:min(300px,86vw)}
.sidebar:not(.open){display:none}
.sidebar.open{display:flex}
.sidebar-head{position:sticky;top:0;background:var(--surface);z-index:1;border-bottom:1px solid var(--border)}
.sidebar-head .sidebar-brand{border-bottom:0}
.sidebar-close{display:inline-flex}
.sidebar-nav{overscroll-behavior:contain}
.content{padding:14px}
.search{display:none}
.user-text{display:none}
.crumb{display:none}
.header{padding:0 10px;gap:6px}
.hdr-divider{display:none}
}

/* below this the header cannot hold the system name as well */
@media (max-width:680px){
.sys-name{display:none}
.sys-btn{padding:0 8px}
.content{padding:11px}
}

/* ===== Make v1 page bodies read as the new theme =====
 * Page markup is still theme_v1's bootstrap. global.css already restyles .btn
 * and .card; these rules cover the rest of what v1 pages render, so a page
 * looks native without editing 120 templates.
 */

/* Page title block v1 renders above most content */
.breadcrumb-title,.page-title,h4.mb-0,h5.mb-0{font-size:19px;font-weight:800;letter-spacing:-.02em;color:var(--text)}
.card-header h4,.card-header h5,.card-header h6{margin:0;font-size:14.5px;font-weight:700;color:var(--text)}
.text-muted,.text-secondary{color:var(--text-3) !important}
.small,small{font-size:12.5px}

/* Cards + sections */
.card{background:var(--surface);border:1px solid var(--border);border-radius:14px;box-shadow:var(--sh-sm);margin-bottom:16px}
.card-header{background:transparent;border-bottom:1px solid var(--border);padding:13px 17px}
.card-body{padding:17px}
.card-footer{background:transparent;border-top:1px solid var(--border);padding:13px 17px}

/* Buttons - kill v1 gradients, adopt template shapes */
.btn{border-radius:9px;font-weight:600;font-size:13px;padding:8px 14px;box-shadow:none;background-image:none !important;border:1px solid transparent}
.btn-primary{background:var(--accent) !important;border-color:var(--accent) !important;color:var(--accent-fg) !important}
.btn-primary:hover{background:var(--accent-2) !important;border-color:var(--accent-2) !important}
.btn-secondary,.btn-dark,.btn-light{background:var(--surface-2) !important;border-color:var(--border) !important;color:var(--text-2) !important}
.btn-success{background:var(--good) !important;border-color:var(--good) !important;color:#fff !important}
.btn-danger{background:var(--bad) !important;border-color:var(--bad) !important;color:#fff !important}
.btn-warning{background:var(--warn) !important;border-color:var(--warn) !important;color:#fff !important}
.btn-info{background:var(--info) !important;border-color:var(--info) !important;color:#fff !important}
.btn-outline-primary{border-color:var(--accent) !important;color:var(--accent) !important;background:transparent !important}
.btn-outline-primary:hover{background:var(--accent) !important;color:var(--accent-fg) !important}
.btn-sm{padding:5px 10px;font-size:12px}
.btn i,.btn .material-icons-outlined{font-size:17px}

/* Inputs / select2 */
.form-control,.form-select,.select2-container--bootstrap-5 .select2-selection{
  border:1px solid var(--border) !important;border-radius:9px !important;background:var(--surface) !important;
  color:var(--text) !important;font-size:13px !important;padding:8px 11px !important;box-shadow:none !important;min-height:38px}
.form-control:focus,.form-select:focus{border-color:var(--accent) !important;box-shadow:0 0 0 3px var(--accent-soft) !important}
.form-control::placeholder{color:var(--text-4)}
.form-label,label{font-size:12.5px;font-weight:600;color:var(--text-2)}
.input-group-text{background:var(--surface-3);border-color:var(--border);color:var(--text-3);border-radius:9px}
.form-check-input:checked{background-color:var(--accent);border-color:var(--accent)}

/* Tabs, pagination, alerts, modals */
.nav-tabs{border-bottom:1px solid var(--border)}
.nav-tabs .nav-link{border:0;border-bottom:2px solid transparent;color:var(--text-3);font-weight:600;font-size:13px;padding:9px 13px;background:transparent}
.nav-tabs .nav-link.active{color:var(--accent);border-bottom-color:var(--accent);background:transparent}
.page-link{border-color:var(--border);color:var(--text-2);border-radius:8px;margin:0 2px;font-size:12.5px}
.page-item.active .page-link{background:var(--accent);border-color:var(--accent);color:#fff}
.alert{border:0;border-radius:10px;font-size:13px}
.alert-success{background:var(--good-soft);color:var(--good)}
.alert-danger{background:var(--bad-soft);color:var(--bad)}
.alert-warning{background:var(--warn-soft);color:var(--warn)}
.alert-info{background:var(--info-soft);color:var(--info)}
.modal-content{border:1px solid var(--border);border-radius:14px;box-shadow:var(--sh-lg)}
.modal-header,.modal-footer{border-color:var(--border)}
.list-group-item{border-color:var(--border-2);background:var(--surface);font-size:13px}
.dropdown-menu{border:1px solid var(--border);border-radius:12px;box-shadow:var(--sh-lg);padding:6px}
.dropdown-item{border-radius:8px;padding:8px 10px;font-size:13px;color:var(--text-2)}
.dropdown-item:hover{background:var(--surface-3);color:var(--text)}

/* Badges - v1 uses solid bootstrap colours; template uses soft pills */







/* Generic tables that are not the dynamic-table engine */
.table{color:var(--text-2);font-size:13px}
.table>:not(caption)>*>*{background:transparent}
.table thead th{background:var(--surface-2);color:var(--text-3);font-weight:600;font-size:12.5px;border-bottom:1px solid var(--border)}
.table tbody td{border-bottom:1px solid var(--border-2)}

/* ===== Portal launcher (/welcome) - the template's standalone page ===== */
.portal{min-height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:48px 24px;
  background:radial-gradient(1100px 540px at 50% -8%, var(--surface-2), var(--bg))}
.portal-head{display:flex;flex-direction:column;align-items:center;margin-bottom:34px}
.portal-mark{width:44px;height:44px;border-radius:13px;background:var(--ink);color:#fff}
.portal-mark .material-icons-outlined{font-size:22px;color:#fff}
.portal-title{margin:16px 0 6px;font-size:25px;font-weight:800;letter-spacing:-.03em;text-align:center;color:var(--text)}
.portal-sub{margin:0;font-size:13.5px;color:var(--text-3);text-align:center}
.portal-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(264px,1fr));gap:18px;width:100%;max-width:960px}
.sys-card{display:flex;flex-direction:column;gap:14px;padding:24px;border-radius:22px;background:var(--surface);
  border:1px solid var(--border);box-shadow:var(--sh-md);text-decoration:none;transition:transform .18s ease}
.sys-card:hover{transform:translateY(-3px)}
.sys-card-head{display:flex;align-items:center;gap:12px}
.sys-card-mark{width:46px;height:46px;border-radius:14px;font-size:22px;font-weight:800;font-family:Georgia,serif}
.sys-card-id{display:block;min-width:0}
.sys-card-name{display:block;font-size:16px;font-weight:800;letter-spacing:-.02em;color:var(--text)}
.sys-card-sub{display:block;font-size:11px;color:var(--text-3);font-weight:600}
.sys-card-desc{display:block;margin:0;font-size:12.5px;color:var(--text-2);line-height:1.55;min-height:60px}
.sys-card-btn{display:block;margin-top:auto;height:38px;line-height:38px;border-radius:9px;text-align:center;
  color:#fff;font-size:13px;font-weight:600}
.btn-mms{background:#b3282f}
.btn-gatee{background:#1668d6}
.btn-einvoice{background:#2f9fdc}
.portal-foot{display:flex;align-items:center;gap:12px;margin-top:30px}
.portal-by{font-size:11.5px;color:var(--text-4);font-weight:600}

/* ===== Sign in ===== */
.auth{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:40px 20px;
  background:radial-gradient(1100px 540px at 50% -8%, var(--surface-2), var(--bg))}
.auth-card{width:100%;max-width:392px;background:var(--surface);border:1px solid var(--border);
  border-radius:22px;box-shadow:var(--sh-md);padding:30px}
.auth-brand{display:flex;align-items:center;gap:11px;margin-bottom:22px}
.auth-mark{width:38px;height:38px;border-radius:12px;background:var(--accent-soft);color:var(--accent);
  font-size:19px;font-weight:800;font-family:Georgia,serif}
.auth-brand-name{display:block;font-size:14px;font-weight:800;letter-spacing:-.02em;color:var(--text)}
.auth-brand-sub{display:block;font-size:10.5px;color:var(--text-3);font-weight:600}
.auth-title{margin:0;font-size:23px;font-weight:800;letter-spacing:-.03em;color:var(--text)}
.auth-sub{margin:6px 0 20px;font-size:13px;color:var(--text-3)}
.auth-alert{margin-bottom:15px;padding:10px 12px;border-radius:9px;background:var(--bad-soft);color:var(--bad);font-size:12.5px}
.field{display:block;margin-bottom:15px}
.field-label{display:block;margin-bottom:6px;font-size:12.5px;font-weight:600;color:var(--text-2)}
.field .input{width:100%;padding:10px 12px;border:1px solid var(--border);border-radius:9px;background:var(--surface);
  color:var(--text);font:inherit;font-size:13.5px}
.field .input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.field-wrap{position:relative;display:block}
.field-wrap .input{padding-inline-end:42px}
.field-reveal{position:absolute;inset-block:0;inset-inline-end:0;width:40px;display:flex;align-items:center;
  justify-content:center;border:0;background:none;color:var(--text-3);cursor:pointer}
.field-reveal:hover{color:var(--accent)}
.auth-check{display:flex;align-items:center;gap:8px;margin-bottom:16px;font-size:13px;color:var(--text-2)}
.auth-submit{width:100%;justify-content:center;height:42px;font-size:14px}
.auth-by{margin:18px 0 0;text-align:center;font-size:11px;color:var(--text-4);font-weight:600}

/* ===== Logos in place of letter marks ===== */
.brand-mark img,.sys-mark img,.sys-ico img,.auth-mark img{max-width:100%;max-height:100%;object-fit:contain;display:block}
.brand-mark,.sys-mark,.sys-ico,.auth-mark{overflow:hidden;background:var(--surface-2);padding:4px}
.sys-mark{padding:3px}
.sys-ico{padding:3px}

/* Portal cards: logo + title only (no description) */
.portal-grid{max-width:840px}
.sys-card{align-items:center;text-align:center;gap:16px;padding:28px 22px}
.sys-card-logo{display:flex;align-items:center;justify-content:center;width:76px;height:76px;border-radius:20px;
  background:var(--surface-2);border:1px solid var(--border-2);padding:12px}
.sys-card-logo img{max-width:100%;max-height:100%;object-fit:contain}
.sys-card-name{font-size:17px;font-weight:800;letter-spacing:-.02em;color:var(--text)}
.sys-card-btn{width:100%}

/* ===== Page header (template's PageHeader) ===== */
.page-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:18px;flex-wrap:wrap}
.page-head-text{min-width:0}
.page-title{margin:0;font-size:21px;font-weight:800;letter-spacing:-.025em;color:var(--text)}
.page-sub{margin:5px 0 0;font-size:13px;color:var(--text-3)}
.page-head-actions{display:flex;gap:8px}

/* ===== KPI tiles ===== */
.kpi-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:14px;margin-bottom:18px}
.kpi{display:flex;flex-direction:column;gap:5px;padding:17px 18px;background:var(--surface);border:1px solid var(--border);
  border-radius:16px;box-shadow:var(--sh-sm)}
.kpi-label{font-size:11.5px;font-weight:700;color:var(--text-3);letter-spacing:.02em}
.kpi-value{font-size:26px;font-weight:800;letter-spacing:-.03em;color:var(--text);line-height:1.15}
.kpi-foot{font-size:11px;color:var(--text-4);font-weight:600}

/* ===== Card head + simple table (template's .tbl) ===== */
.card-head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;padding:15px 18px;border-bottom:1px solid var(--border)}
.card-title{margin:0;font-size:14.5px;font-weight:700;color:var(--text)}
.card-sub{margin:3px 0 0;font-size:12px;color:var(--text-3)}
.card-link{font-size:11.5px;font-weight:700;color:var(--accent);text-decoration:none;white-space:nowrap}
.tbl-wrap{overflow-x:auto}
.tbl{width:100%;border-collapse:collapse;font-size:13px}
.tbl th{padding:10px 16px;text-align:start;font-size:11.5px;font-weight:700;color:var(--text-3);background:var(--surface-2);
  border-bottom:1px solid var(--border);white-space:nowrap}
.tbl td{padding:12px 16px;border-bottom:1px solid var(--border-2);color:var(--text-2)}
.tbl tbody tr:last-child td{border-bottom:0}
.tbl tbody tr:hover td{background:var(--surface-2)}
.td-strong{font-weight:700;color:var(--text)}
.mono{font-family:var(--mono,ui-monospace,monospace);font-size:12px}
.ta-c{text-align:center}
.tbl-state{padding:26px 16px;text-align:center;color:var(--text-3)}
.chip{display:inline-block;padding:3px 10px;border-radius:999px;font-size:11.5px;font-weight:700}
.chip-good{background:var(--good-soft);color:var(--good)}
.chip-mute{background:var(--surface-3);color:var(--text-3)}

/* ===== Links used as buttons must never underline (template has none) ===== */
a.btn,a.btn:hover,a.btn:focus,.btn,.btn:hover,.btn:focus,
.sys-card,.sys-card:hover,.sidebar-brand,.sidebar-brand:hover,
.nav-item,.nav-item:hover,.dd-item,.dd-item:hover,
.card-link,.card-link:hover,.sys-card-btn{text-decoration:none !important}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;cursor:pointer;line-height:1.2}

/* ===== Status chips =====
 * global.css and the v1 bundle both define .chip, which made the status pills
 * tall, outlined and underlined. These win and keep them compact and flat. */
.chip{display:inline-flex !important;align-items:center;justify-content:center;
  padding:3px 11px !important;border:0 !important;border-radius:999px !important;
  font-size:11.5px !important;font-weight:700 !important;line-height:1.7 !important;
  text-decoration:none !important;box-shadow:none !important;min-height:0 !important;
  height:auto !important;white-space:nowrap;letter-spacing:0}
.chip-good{background:var(--good-soft) !important;color:var(--good) !important}
.chip-mute{background:var(--surface-3) !important;color:var(--text-3) !important}
.chip-bad{background:var(--bad-soft) !important;color:var(--bad) !important}
.chip-warn{background:var(--warn-soft) !important;color:var(--warn) !important}

/* ===== Header search results ===== */
.search-rel{flex:1;max-width:340px;margin-inline-start:12px}
.search-rel .search{margin-inline-start:0;max-width:none;width:100%}
.search-dd{width:100%;min-width:260px;max-height:340px;overflow-y:auto}
.search-empty{padding:12px 10px;font-size:12.5px;color:var(--text-3);text-align:center}

/* ===== Dashboard blocks that render v1 tables ===== */
.dash-block{margin-top:18px}
.dash-block .card{margin-bottom:0}

/* ===== Filter panel =====
 * v1 renders each filter as a bootstrap .input-group: a bordered .input-group-text
 * icon box followed by the field. That reads as two separate boxes. These rules
 * fuse them into one control and tidy the row.
 */
.filter-panel{background:var(--surface) !important;border:1px solid var(--border) !important;
  border-radius:16px !important;margin:0 0 16px !important;box-shadow:var(--sh-sm)}
.filter-panel.open{margin-bottom:16px !important}
.filter-panel-inner{gap:14px !important;padding:16px 18px !important;align-items:flex-end !important}

.filter-panel .filter-label,.filter-panel label{display:block;margin:0 0 6px;font-size:11px !important;
  font-weight:700 !important;letter-spacing:.06em;text-transform:uppercase;color:var(--text-3) !important}

/* One fused control instead of icon-box + field */
.filter-panel .input-group{border:1px solid var(--border);border-radius:10px;background:var(--surface);
  overflow:hidden;transition:border-color .15s ease,box-shadow .15s ease;flex-wrap:nowrap}
.filter-panel .input-group:focus-within{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.filter-panel .input-group-text{background:transparent !important;border:0 !important;border-radius:0 !important;
  color:var(--text-4) !important;padding:0 4px 0 11px !important}
.filter-panel .input-group-text .material-icons-outlined,
.filter-panel .input-group-text i{font-size:18px}
.filter-panel .form-control,.filter-panel .form-select{border:0 !important;border-radius:0 !important;
  box-shadow:none !important;background:transparent !important;padding:9px 12px 9px 8px !important;
  font-size:13px !important;min-height:40px}
.filter-panel .form-control:focus,.filter-panel .form-select:focus{box-shadow:none !important}
.filter-panel .form-control::placeholder{color:var(--text-4)}

/* Each filter keeps a sensible width instead of stretching unevenly */
.filter-panel-inner > div{flex:1 1 190px;min-width:170px;max-width:290px}

/* Actions sit at the end of the row */
.filter-panel .action-buttons{display:flex;align-items:center;gap:9px;margin-inline-start:auto !important;flex:0 0 auto}
.filter-panel .btn{height:40px;border-radius:10px;padding:0 16px;font-size:13px;white-space:nowrap}
.filter-panel .btn-link,.filter-panel .more-btn{color:var(--text-2);text-decoration:none;font-weight:700}
.filter-panel .badge{background:var(--accent-soft) !important;color:var(--accent) !important;
  font-size:11px !important;padding:2px 8px !important}

/* Toolbar above the panel (Columns / Cards / More / Apply) */
.table-container .filter-toggle-btn,.table-container .view-toggle-btn{height:38px;border-radius:10px;
  border:1px solid var(--border);color:var(--text-2);font-size:13px;font-weight:600;padding:0 14px}
.table-container .filter-toggle-btn:hover,.table-container .view-toggle-btn:hover{background:var(--surface-3);color:var(--text)}

/* ===== Modals (select-owner / select-type / select-mcc pickers) =====
 * The new shell put the modal below the chrome and clipped it: the header was
 * cut off above the viewport, the body could not scroll, and the backdrop
 * swallowed clicks so nothing was selectable.
 *
 * Force the modal above everything, make the overlay itself scrollable, and cap
 * the dialog to the viewport so long lists scroll inside it.
 */
/* The modal rules that used to live here have moved to components.css, which
   is the single owner of modal chrome and geometry. They were duplicated in
   both files and this copy carried `!important` on the dialog's margin, so it
   silently beat components.css and the dialog would not centre. Do not add
   modal rules here again. */

/* The picker renders a full table inside the modal - keep its own tools usable */
.modal .table-wrapper{max-height:none}
.modal .filter-panel{margin-bottom:14px !important}
.modal .filter-panel-inner{padding:14px !important}

/* Sidebar and header must never sit above a modal.
 *
 * Scoped to :not(.open) on purpose. This rule sits AFTER the mobile block
 * above, and a media query adds no specificity, so a bare `.sidebar{z-index:20}`
 * beat the drawer's z-index:120 and dropped it below .header's 30 - the header
 * then painted over the open drawer and hid its brand. Docked sidebar stays at
 * 20; the open drawer keeps the value the mobile block gives it. */
.sidebar:not(.open){z-index:20}
.header{position:relative;z-index:30}
.dropdown{z-index:60}

/* ===== Search filters live in .fb-item, NOT .filter-panel =====
 * .filter-panel is the column chooser. The search fields are .fb-item blocks
 * each holding an .input-group with a bordered .input-group-text icon - which
 * is why the icon rendered as its own grey box. Fuse them here.
 */
.fb-item .input-group,.fb-item .input-group-sm{border:1px solid var(--border);border-radius:10px;
  background:var(--surface);overflow:hidden;flex-wrap:nowrap;transition:border-color .15s ease,box-shadow .15s ease}
.fb-item .input-group:focus-within{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
.fb-item .input-group-text{background:transparent !important;border:0 !important;border-radius:0 !important;
  color:var(--text-4) !important;padding:0 2px 0 11px !important}
.fb-item .input-group-text i,.fb-item .input-group-text .material-icons-outlined{font-size:18px}
.fb-item .form-control,.fb-item .form-select{border:0 !important;border-radius:0 !important;background:transparent !important;
  box-shadow:none !important;padding:9px 12px 9px 8px !important;font-size:13px !important;min-height:40px}
.fb-item .form-control:focus,.fb-item .form-select:focus{box-shadow:none !important}
.fb-item .form-label{font-size:11px !important;font-weight:700 !important;letter-spacing:.05em;
  text-transform:uppercase;color:var(--text-3) !important;margin-bottom:6px !important}

/* ===== Column chooser (.filter-panel) ===== */
.filter-panel{background:var(--surface) !important;border:1px solid var(--border) !important;
  border-radius:14px !important;box-shadow:var(--sh-sm)}
.filter-panel-inner{gap:12px !important;padding:14px 16px !important;align-items:center !important}
.filter-panel .filter-label{font-size:11px !important;font-weight:700 !important;letter-spacing:.06em;
  text-transform:uppercase;color:var(--text-3) !important;white-space:nowrap}
.col-check-group{gap:8px !important}
/* each column toggle becomes a compact chip */
.col-check-group label,.col-check-group .custom-checkbox{display:inline-flex !important;align-items:center;gap:7px;
  padding:6px 11px !important;background:var(--surface) !important;border:1px solid var(--border) !important;
  border-radius:999px !important;font-size:12px !important;font-weight:600;color:var(--text-2) !important;
  text-transform:capitalize;cursor:pointer;transition:all .15s ease}
.col-check-group label:hover,.col-check-group .custom-checkbox:hover{border-color:var(--accent) !important;
  background:var(--accent-soft) !important;color:var(--accent) !important}
.col-check-group input[type="checkbox"]{accent-color:var(--accent);width:15px;height:15px;margin:0;cursor:pointer;flex:none}
.col-check-group .material-icons-outlined{font-size:14px;color:var(--text-4)}
.col-check-group .pin-btn{padding:0 !important;background:none !important;border:0 !important}

/* Consistent action buttons - no indigo, no mismatched colours */
.filter-panel .action-buttons .btn,.select-all-btn,.reset-btn{height:34px;border-radius:9px;padding:0 13px;
  font-size:12.5px;font-weight:600;border:1px solid var(--border) !important;background:var(--surface) !important;
  color:var(--text-2) !important;display:inline-flex;align-items:center;gap:6px}
.filter-panel .action-buttons .btn:hover,.select-all-btn:hover,.reset-btn:hover{
  background:var(--surface-3) !important;color:var(--text) !important;border-color:var(--border) !important}
/* v1 hardcodes indigo on the active filter toggle */
.table-container .filter-toggle-btn.active,.filter-toggle-btn.active{
  background:var(--accent) !important;border-color:var(--accent) !important;color:#fff !important}

/* ===== Column chooser - final =====
 * The generic ".filter-panel-inner > div{max-width:290px}" rule added for the
 * search bar was also hitting .col-check-group, squeezing the chips into a
 * narrow column. The chooser gets the full row back.
 *
 * JS builds each chip as:
 *   <label class="custom-checkbox"><input type=checkbox><span>Name</span>
 *   <button class="pin-btn">…</button></label>
 */
.filter-panel-inner > .col-check-group{flex:1 1 auto !important;max-width:none !important;min-width:0 !important}
.col-check-group{display:flex !important;flex-wrap:wrap !important;gap:8px !important;align-items:center}

.col-check-group .custom-checkbox{display:inline-flex !important;align-items:center !important;gap:7px !important;
  padding:5px 10px !important;background:var(--surface) !important;border:1px solid var(--border) !important;
  border-radius:999px !important;font-size:12px !important;font-weight:600 !important;
  color:var(--text-2) !important;text-transform:none !important;letter-spacing:0 !important;
  cursor:pointer;transition:all .15s ease;line-height:1.6 !important;white-space:nowrap}
.col-check-group .custom-checkbox:hover{border-color:var(--accent) !important;
  background:var(--accent-soft) !important;color:var(--accent) !important}
.col-check-group .custom-checkbox:has(input:checked){border-color:var(--accent) !important;
  background:var(--accent-soft) !important;color:var(--accent) !important}
.col-check-group .custom-checkbox input[type="checkbox"]{width:14px !important;height:14px !important;
  margin:0 !important;accent-color:var(--accent);cursor:pointer;flex:none}
.col-check-group .custom-checkbox > span{order:1;text-transform:capitalize}
.col-check-group .pin-btn{order:2;padding:0 !important;margin:0 !important;background:none !important;
  border:0 !important;line-height:0;color:var(--text-4) !important;opacity:.55}
.col-check-group .pin-btn:hover{opacity:1;color:var(--accent) !important;background:none !important}
.col-check-group .pin-btn .material-icons-outlined{font-size:14px !important}
.col-check-group .pin-btn.pinned{opacity:1;color:var(--accent) !important}

.filter-panel-inner{flex-wrap:nowrap !important}
.filter-panel .action-buttons{flex:0 0 auto;white-space:nowrap}
@media (max-width:900px){ .filter-panel-inner{flex-wrap:wrap !important} }

/* ===== Forms: section headings ===== */
.text-primary{color:var(--accent) !important}
.card-header h6,.p-4 > h6.text-uppercase{font-size:11.5px !important;font-weight:800 !important;
  letter-spacing:.08em;color:var(--accent) !important;display:flex;align-items:center;gap:6px}
.card-header h6 .material-icons-outlined,.p-4 > h6 .material-icons-outlined{font-size:17px !important;margin:0 !important}

/* ===== Composite fields (phone / mobile: code selector + number) =====
 * The markup is an .input-group holding a 40% wrapper around a custom select
 * plus a 60% input carrying inline height:31px. Those inline sizes fought the
 * form styling, so the code box dropped onto its own line and the two halves
 * never lined up. Force one row with matched heights.
 */
.input-group{display:flex !important;flex-wrap:nowrap !important;align-items:stretch !important}
.input-group > div{display:flex;align-items:stretch}
.input-group > div[style*="width:40%"],.input-group > div[style*="width: 40%"]{width:132px !important;flex:0 0 132px !important}
.input-group > input[style*="width:60%"],.input-group > input[style*="width: 60%"]{width:auto !important;flex:1 1 auto !important;height:40px !important;min-height:40px !important}
.input-group > .form-control,.input-group > .form-select{height:40px !important;min-height:40px !important}

/* the code selector must look like part of the same control */
.custom-image-select-container{height:40px !important;min-height:40px !important;width:100% !important}
.custom-image-select-container .custom-image-select-trigger,
.custom-image-select-container > div:first-child{height:40px !important;min-height:40px !important;
  display:flex !important;align-items:center;gap:6px;border:1px solid var(--border) !important;
  border-start-end-radius:0 !important;border-end-end-radius:0 !important;border-inline-end:0 !important;
  border-radius:10px 0 0 10px;background:var(--surface);padding:0 10px !important;font-size:13px;white-space:nowrap}
.input-group > input[type="tel"],.input-group > input[name="phone"],.input-group > input[name="mobile"]{
  border-start-start-radius:0 !important;border-end-start-radius:0 !important;border-radius:0 10px 10px 0 !important;
  border:1px solid var(--border) !important}
.custom-image-select-container img{max-height:16px;width:auto}

/* Form field rhythm */
.form-label.small{font-size:11.5px !important;font-weight:700 !important;letter-spacing:.04em;
  text-transform:uppercase;color:var(--text-3) !important;margin-bottom:6px !important}
.invalid-feedback{font-size:11.5px}
.p-4.border-bottom{padding:20px 22px !important}

/* ===== Custom image-select inside a composite field =====
 * ajax_script.html renders each selector as:
 *   <div class="dropdown custom-image-select-wrapper">
 *     <button class="btn btn-outline-secondary dropdown-toggle w-100">…</button>
 *     <div class="dropdown-menu">…</div><input type="hidden" name="…">
 *   </div>
 *   <div class="selected-preview … mt-2"></div>
 *
 * That trailing .selected-preview is what appeared BELOW the phone field - it
 * repeats what the button already shows. Inside an .input-group it is noise, so
 * it is hidden there and the button is joined to the number input.
 * Standalone selectors (country, currency, language) keep their preview.
 */
.input-group .custom-image-select-container,
.input-group .custom-image-select-wrapper{height:40px !important;min-height:40px !important;width:100% !important;margin:0 !important}
.input-group .custom-image-select-wrapper > .dropdown-toggle{
  height:40px !important;min-height:40px !important;padding:0 10px !important;
  border:1px solid var(--border) !important;background:var(--surface) !important;color:var(--text) !important;
  font-size:13px !important;font-weight:600 !important;white-space:nowrap;
  border-radius:10px 0 0 10px !important;border-inline-end:0 !important;box-shadow:none !important}
.input-group .custom-image-select-wrapper > .dropdown-toggle:hover{background:var(--surface-2) !important}
.input-group .custom-image-select-wrapper .dropdown-menu{min-width:260px;border:1px solid var(--border);
  border-radius:12px;box-shadow:var(--sh-lg);z-index:70}
.input-group .custom-image-select-wrapper img{max-height:15px;width:auto;margin-inline-end:6px}

/* Standalone selectors: keep the preview but tidy it */
.selected-preview:empty{display:none}
.custom-image-select-wrapper > .dropdown-toggle{height:40px;border-radius:10px;border:1px solid var(--border) !important;
  background:var(--surface) !important;color:var(--text) !important;font-size:13px;box-shadow:none !important}

/* ===================================================================
 * COMPOSITE FIELD - one shared component, defined once.
 *
 * Covers every "two things that should read as one control" in the app:
 *   - country code selector + phone/mobile number
 *   - text input + search/picker button (Entity Type, Owner, Mcc, Referrer)
 *   - any bootstrap .input-group inside a form
 *
 * Rule: the OUTER element owns the border, radius and focus ring; every child
 * is borderless and square. Fix it here and every page updates - no per-page
 * edits. Same visual language as the table filter bar.
 * =================================================================== */
.combo-field,
form .input-group,
.card .input-group{
  display:flex !important;flex-wrap:nowrap !important;align-items:stretch !important;
  width:100%;border:1px solid var(--border) !important;border-radius:10px !important;
  background:var(--surface);overflow:hidden;
  transition:border-color .15s ease,box-shadow .15s ease}

.combo-field:focus-within,
form .input-group:focus-within,
.card .input-group:focus-within{border-color:var(--accent) !important;box-shadow:0 0 0 3px var(--accent-soft) !important}

/* every child sits flush inside the shell */
.combo-field > *,
form .input-group > *,
.card .input-group > *{border:0 !important;border-radius:0 !important;box-shadow:none !important;
  min-height:40px !important;background:transparent !important;margin:0 !important}

.combo-field .form-control,.combo-field input,
form .input-group .form-control,form .input-group input,
.card .input-group .form-control,.card .input-group input{
  flex:1 1 auto !important;width:auto !important;height:40px !important;
  padding:0 12px !important;font-size:13px !important;color:var(--text)}

/* fixed-width code selector on the start edge */
.combo-field .combo-code{flex:0 0 138px !important;width:138px !important;
  border-inline-end:1px solid var(--border) !important;background:var(--surface-2) !important}
.combo-field .combo-code .custom-image-select-container,
.combo-field .combo-code .custom-image-select-wrapper{width:100% !important;height:40px !important}
.combo-field .combo-code .dropdown-toggle{width:100% !important;height:40px !important;padding:0 10px !important;
  font-size:13px !important;font-weight:600 !important;color:var(--text) !important;white-space:nowrap;
  display:flex !important;align-items:center;gap:6px;justify-content:space-between}
.combo-field .combo-code img{max-height:15px;width:auto}

/* trailing action button (search / picker) becomes part of the control */
.combo-field > .btn,
form .input-group > .btn,
.card .input-group > .btn,
form .input-group > .input-group-text,
.card .input-group > .input-group-text{
  flex:0 0 auto !important;width:44px !important;padding:0 !important;
  display:flex !important;align-items:center;justify-content:center;
  color:var(--text-3) !important;cursor:pointer}
.combo-field > .btn:hover,
form .input-group > .btn:hover,
.card .input-group > .btn:hover{background:var(--accent-soft) !important;color:var(--accent) !important}
.combo-field > .btn .material-icons-outlined,
form .input-group > .btn .material-icons-outlined,
form .input-group > .input-group-text i{font-size:18px}

/* leading icon variant keeps its muted look */
form .input-group > .input-group-text:first-child,
.card .input-group > .input-group-text:first-child{width:auto !important;padding:0 2px 0 11px !important;color:var(--text-4) !important}

/* ===================================================================
 * CORRECTION - .selected-preview is the CONTROL, not a duplicate.
 *
 * For data-template="simple" the generator renders the chosen value into
 * .selected-preview; the dropdown-toggle may be empty. Hiding it (as an earlier
 * rule here did) emptied the phone code box and left the currency preview
 * stranded at the bottom of its card.
 *
 * So: never hide it. Place it inline inside the composite field instead, and
 * keep it anchored to its own container everywhere else.
 * =================================================================== */
.combo-field .selected-preview,
form .input-group .selected-preview,
.card .input-group .selected-preview{display:flex !important;align-items:center;margin:0 !important}

/* Inside a composite field the preview becomes the code control itself */
.combo-field .combo-code{flex:0 0 auto !important;width:auto !important;min-width:132px;
  display:flex;align-items:center;background:var(--surface-2) !important;
  border-inline-end:1px solid var(--border) !important}
.combo-field .combo-code .custom-image-select-container{display:flex;align-items:center;
  height:40px !important;width:100% !important}
.combo-field .combo-code .selected-preview{height:40px;padding:0 10px;gap:6px;
  font-size:13px;font-weight:600;color:var(--text);white-space:nowrap}
.combo-field .combo-code .custom-image-select-wrapper{flex:1 1 auto;min-width:0}
.combo-field .combo-code .dropdown-toggle{height:40px !important;padding:0 10px !important;
  border:0 !important;background:transparent !important;color:var(--text) !important;
  font-size:13px !important;font-weight:600 !important;white-space:nowrap;box-shadow:none !important}

/* Standalone selectors keep the preview directly under their own field */
.custom-image-select-container{display:block;width:100%}
.custom-image-select-container .selected-preview{margin-top:6px !important;flex-wrap:wrap;gap:6px}
.custom-image-select-container .selected-preview:empty{display:none !important}
.custom-image-select-container .dropdown-toggle{width:100%;height:40px;border:1px solid var(--border) !important;
  border-radius:10px;background:var(--surface) !important;color:var(--text) !important;font-size:13px;
  display:flex;align-items:center;justify-content:space-between;gap:6px;padding:0 11px;box-shadow:none !important}
.custom-image-select-container img{max-height:15px;width:auto}

/* ===== code-select: native <select> inside a composite field ===== */
.combo-field > .code-select{flex:0 0 auto !important;width:auto !important;min-width:150px;max-width:190px;
  height:40px !important;padding:0 30px 0 11px !important;border:0 !important;border-radius:0 !important;
  border-inline-end:1px solid var(--border) !important;background:var(--surface-2) !important;
  color:var(--text) !important;font-size:13px !important;font-weight:600;cursor:pointer;
  appearance:none;-webkit-appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,var(--text-3) 50%),linear-gradient(135deg,var(--text-3) 50%,transparent 50%) !important;
  background-position:calc(100% - 16px) 18px,calc(100% - 11px) 18px !important;
  background-size:5px 5px,5px 5px !important;background-repeat:no-repeat !important}
.combo-field > .code-select:focus{outline:none;box-shadow:none !important}
.code-select{border:1px solid var(--border);border-radius:10px;height:40px;padding:0 11px;
  background:var(--surface);color:var(--text);font-size:13px}
