/* ==========================================================================
   WebVibo — extras layer
   --------------------------------------------------------------------------
   Loads AFTER css/webvibo.css, which is your live stylesheet byte-for-byte.
   Nothing here changes an existing WebVibo component's appearance. It only:

     1. Contains collisions — your CSS claims Bootstrap/WHMCS class names
        (.nav-item a, .dropdown, .card-header, th, .primary, .current …).
        These were harmless while the stock nav and tabs were hidden. Now that
        they render, each needs a fence.
     2. Brands the ~194 stock templates via the Bootstrap 4 component layer,
        using your own tokens so it matches what you already have.
     3. Adds the management hub, written in your visual language.
   ========================================================================== */


/* ==========================================================================
   1. COLLISION FENCES
   ========================================================================== */

/* webvibo.css:720 — `.nav-item a{color:rgba(255,255,255,.7)}` is unscoped, and
   Bootstrap 4 uses .nav-item as the <li> of .nav-tabs / .navbar-nav. Without
   this, every inactive tab label is 70%-opacity white on a white card. */
.nav-tabs .nav-item a,
.nav-tabs .nav-link,
.navbar-nav .nav-item a,
.nav-pills .nav-item a {
  color: var(--gray-600);
}
.nav-tabs .nav-item a:hover,
.nav-tabs .nav-link:hover,
.navbar-nav .nav-item a:hover { color: var(--primary); }
.nav-tabs .nav-link.active,
.nav-tabs .nav-item.show .nav-link { color: var(--primary); }

/* webvibo.css:51 — `.sidebar{position:fixed;width:280px;…}`. WHMCS also uses
   .sidebar on the secondary sidebar and on the SSL pricing table's label
   column. Re-neutralise those two; the portal sidebar keeps the rule via
   #sidebar. */
.sidebar-secondary,
.col-md-3.sidebar,
#main-body .sidebar {
  position: static;
  width: auto;
  inset: auto;
  z-index: auto;
  background: none;
  overflow: visible;
  transform: none;
  box-shadow: none;
}

/* webvibo.css:240 — `.dropdown{position:absolute;top:60px;right:0;display:none}`
   collides head-on with Bootstrap's `.dropdown{position:relative}`. Fence it to
   the topbar user menu, which is the only place your markup uses it. */
#main-body .dropdown, .navbar .dropdown, .btn-group .dropdown, .input-group .dropdown {
  position: relative; top: auto; right: auto; display: block;
  background: none; box-shadow: none; padding: 0; min-width: 0; border-radius: 0;
}
.dropdown-menu { position: absolute; }

/* scrim behind the off-canvas sidebar (new element, no rule in your CSS) */
.scrim {
  position: fixed; inset: 0; background: rgba(15,13,27,.5);
  z-index: 199; opacity: 0; visibility: hidden; transition: .3s;
}
.scrim.show { opacity: 1; visibility: visible; }
@media (min-width: 993px) { .scrim { display: none; } }

/* webvibo.css:428 — a bare `th` selector. Keep it off stock tables. */
.table th, .dataTable th, .listtable th { font-size: inherit; }

/* webvibo.css:323–334 — single-word .primary/.secondary/.success/.warning, and
   :1357 .current. Stop them reaching Bootstrap utility markup. */
.btn.primary, .btn.secondary, .btn.success, .btn.warning,
.badge.primary, .badge.secondary, .badge.success, .badge.warning { all: revert; }

/* webvibo.css:1024/1028 — .card-header / .card-title are Bootstrap's. Your
   dashboard cards keep the styling; stock cards get theirs back. */
#main-body .card > .card-header {
  display: block;
  background: transparent;
  border-bottom: 1px solid var(--gray-200);
  padding: 1rem 1.5rem;
}
#main-body .card .card-title { font-weight: 700; font-size: 1rem; }


/* ==========================================================================
   2. BOOTSTRAP 4 / WHMCS BRIDGE
   Brands every stock template. Values taken from your own tokens.
   ========================================================================== */

#main-body .card {
  background: var(--white);
  border: 1px solid var(--gray-200);
  border-radius: 16px;
  box-shadow: none;
  margin-bottom: 1.5rem;
}
#main-body .card > .card-body { padding: 1.5rem; }
#main-body .card > .card-footer {
  background: var(--gray-50);
  border-top: 1px solid var(--gray-200);
  padding: .75rem 1.5rem;
}

.btn { border-radius: 10px; font-weight: 600; padding: .48rem 1rem; transition: .25s; }
.btn:focus, .btn.focus { box-shadow: 0 0 0 3px rgba(255,140,66,.25); }
.btn-primary {
  background: linear-gradient(135deg, var(--primary), var(--secondary));
  border-color: transparent; color: #fff;
}
.btn-primary:hover, .btn-primary:focus,
.btn-primary:not(:disabled):not(.disabled):active {
  background: linear-gradient(135deg, #f57f33, #a854e8);
  border-color: transparent; color: #fff;
  box-shadow: 0 6px 20px rgba(181,101,242,.28);
}
.btn-default, .btn-secondary {
  background: var(--white); border-color: var(--gray-200); color: var(--gray-700);
}
.btn-default:hover, .btn-secondary:hover { border-color: var(--primary); color: var(--primary); }
.btn-success { background: var(--success); border-color: var(--success); }
.btn-danger  { background: var(--danger);  border-color: var(--danger); }
.btn-warning { background: var(--warning); border-color: var(--warning); color: #fff; }
.btn-link    { color: var(--primary); }

.form-control { border: 1px solid var(--gray-200); border-radius: 10px; padding: .5rem .8rem; }
.form-control:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(255,140,66,.15); }
.form-control::placeholder { color: var(--gray-400); }
.col-form-label, .control-label { font-weight: 600; color: var(--gray-700); }
.input-group-text { background: var(--gray-100); border-color: var(--gray-200); border-radius: 10px; }
.custom-control-input:checked ~ .custom-control-label::before { background: var(--primary); border-color: var(--primary); }
.custom-select { border-radius: 10px; border-color: var(--gray-200); }
.custom-select:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(255,140,66,.15); }

/* iCheck — replaces the recoloured blue.png sprites so a vendor asset refresh
   can't revert them. Used by 9 forms including every payment screen. */
.icheckbox_square-blue, .iradio_square-blue {
  background: var(--white) !important;
  border: 1px solid var(--gray-300) !important;
  border-radius: 4px; width: 20px !important; height: 20px !important;
}
.iradio_square-blue { border-radius: 50%; }
.icheckbox_square-blue.checked, .iradio_square-blue.checked {
  background: var(--primary) !important; border-color: var(--primary) !important;
}
.icheckbox_square-blue.checked::after {
  content: "\2713"; color: #fff; font-size: 13px; font-weight: 700;
  display: block; text-align: center; line-height: 18px;
}
.iradio_square-blue.checked::after {
  content: ""; display: block; width: 8px; height: 8px;
  border-radius: 50%; background: #fff; margin: 5px auto;
}

.nav-tabs { border-bottom: 1px solid var(--gray-200); }
.nav-tabs .nav-link {
  border: 0; border-bottom: 2px solid transparent; border-radius: 0;
  padding: .7rem 1rem; font-weight: 600; background: transparent;
}
.nav-tabs .nav-link:hover { border-bottom-color: var(--gray-300); }
.nav-tabs .nav-link.active { border-bottom-color: var(--primary); }
.tab-content.product-details-tab-container {
  background: var(--white);
  border: 1px solid var(--gray-200); border-top: 0;
  border-radius: 0 0 16px 16px; padding: 1.5rem;
}

.list-group-item { border-color: var(--gray-100); color: var(--gray-700); padding: .65rem 1rem; }
.list-group-item-action:hover { background: var(--gray-50); color: var(--primary); }
.list-group-item.active {
  background: linear-gradient(135deg, var(--primary), var(--secondary));
  border-color: transparent; color: #fff;
}
.list-group-item.active .sidebar-menu-item-icon { color: #fff; }
.sidebar-menu-item-wrapper { display: flex; align-items: center; gap: .75rem; }
.sidebar-menu-item-icon { color: var(--gray-500); width: 1.05rem; text-align: center; }
.sidebar-menu-item-label { flex: 1; min-width: 0; }
.card-sidebar { border-radius: 14px; border: 1px solid var(--gray-200); overflow: hidden; }
.card-sidebar > .card-header { background: var(--gray-50); padding: .75rem 1rem; }
.card-minimise { color: var(--gray-400); cursor: pointer; font-size: .8rem; }

.badge { border-radius: 999px; font-weight: 700; padding: .3em .62em; }
.badge-primary { background: var(--primary); }
.badge-success { background: var(--success); }
.badge-danger  { background: var(--danger); }
.badge-warning { background: var(--warning); color: #fff; }
.label, span.status { display: inline-block; border-radius: 999px; padding: .28rem .68rem; font-size: .74rem; font-weight: 700; }
.status-active, .status-paid, .status-open, .status-answered, .status-completed { background: #e7f8f2; color: #067a5c; }
.status-pending, .status-unpaid, .status-draft, .status-customer-reply         { background: #fef4e3; color: #96620a; }
.status-suspended, .status-overdue, .status-fraud                              { background: #fdeceb; color: #a3201a; }
.status-terminated, .status-cancelled, .status-closed, .status-expired         { background: #eeeef1; color: #5d5b6b; }

.alert { border: 1px solid transparent; border-left-width: 3px; border-radius: 10px; padding: 1rem 1.5rem; }
.alert-success { background: #e7f8f2; border-color: var(--success); color: #056247; }
.alert-info    { background: #e8f0fe; border-color: #3b82f6;        color: #1d4ed8; }
.alert-warning { background: #fef4e3; border-color: var(--warning); color: #8a5100; }
.alert-danger, .alert-error { background: #fdeceb; border-color: var(--danger); color: #a3201a; }
.network-issue-alert { border-radius: 0; border-left-width: 0; border-top-width: 3px; margin: 0; }

.table thead th {
  border-top: 0; border-bottom: 1px solid var(--gray-200);
  font-size: .7rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--gray-500); padding: .75rem 1rem;
}
.table td { border-top: 1px solid var(--gray-100); padding: .75rem 1rem; vertical-align: middle; }
.table-hover tbody tr:hover { background: var(--gray-50); }
.dataTables_wrapper .dataTables_filter input {
  border: 1px solid var(--gray-200); border-radius: 999px; padding: .4rem .9rem;
}
.dataTables_wrapper .dataTables_filter input:focus { border-color: var(--primary); outline: 0; }
.dataTables_wrapper .dataTables_info { color: var(--gray-600); font-size: .85rem; }
.page-link { color: var(--gray-700); border-color: var(--gray-200); border-radius: 10px !important; margin: 0 2px; }
.page-link:hover { background: var(--gray-100); color: var(--primary); }
.page-item.active .page-link {
  background: linear-gradient(135deg, var(--primary), var(--secondary));
  border-color: transparent; color: #fff;
}
.view-filter-btns .list-group-item.active { background: linear-gradient(135deg, var(--primary), var(--secondary)); border-color: transparent; }

.modal-content { border: 0; border-radius: 20px; box-shadow: 0 24px 60px rgba(15,13,27,.22); }
.modal-header { border-bottom: 1px solid var(--gray-200); padding: 1rem 1.5rem; }
.modal-footer { border-top: 1px solid var(--gray-200); padding: .75rem 1.5rem; }
.item-selector .item {
  display: block; padding: .6rem .75rem; border-radius: 10px;
  border: 1px solid var(--gray-200); margin-bottom: .5rem;
  color: var(--gray-700); text-align: center;
}
.item-selector .item.active, .item-selector .item:hover { border-color: var(--primary); color: var(--primary); }

.progress { border-radius: 999px; background: var(--gray-100); height: .6rem; }
.progress-bar { background: linear-gradient(135deg, var(--primary), var(--secondary)); }
.btn-return-to-admin { background: linear-gradient(135deg, var(--primary), var(--secondary)); color: #fff; border: 0; }
.text-primary   { color: var(--primary) !important; }
.border-primary { border-color: var(--primary) !important; }


/* ==========================================================================
   3. MANAGEMENT HUB  — new component, written in your visual language
   ========================================================================== */

.hub-title {
  display: flex; align-items: center; gap: .6rem;
  font-size: 1.05rem; font-weight: 800; color: var(--gray-900);
  margin: 2rem 0 1rem;
}
.hub-title i { color: var(--primary); }

.hub {
  display: grid; gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
  margin-bottom: 1.5rem;
}
.hub-card {
  background: var(--white); border-radius: 20px;
  box-shadow: 0 10px 25px rgba(0,0,0,.05);
  overflow: hidden; display: flex; flex-direction: column;
  transition: .25s;
}
.hub-card:hover { box-shadow: 0 16px 38px rgba(181,101,242,.14); }
.hub-head {
  display: flex; align-items: center; gap: .8rem;
  padding: 1.1rem 1.4rem; border-bottom: 1px solid var(--gray-200);
}
.hub-head h3 { font-size: .98rem; font-weight: 800; margin: 0; color: var(--gray-900); }
.hub-icon {
  width: 38px; height: 38px; flex: none; border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: .85rem;
}
.hub-links { display: flex; flex-direction: column; padding: .5rem; flex: 1; }
.hub-links a {
  display: flex; align-items: center; gap: .8rem;
  padding: .6rem .8rem; border-radius: 12px;
  color: var(--gray-700); font-size: .89rem; text-decoration: none;
  transition: .25s;
}
.hub-links a:hover {
  background: var(--gray-50); color: var(--primary); text-decoration: none;
  transform: translateX(4px);
}
.hub-links a > i:first-child { width: 1.1rem; text-align: center; color: var(--gray-400); flex: none; }
.hub-links a:hover > i:first-child { color: var(--primary); }
.hub-links a span { flex: 1; min-width: 0; }
.hub-links a .chev { color: var(--gray-300); font-size: .7rem; opacity: 0; transition: .25s; }
.hub-links a:hover .chev { opacity: 1; }

/* per-row action group in the sites table */
.row-actions { display: flex; gap: .5rem; justify-content: flex-end; flex-wrap: wrap; }
@media (max-width: 768px) { .row-actions { justify-content: flex-start; } }

/* PanelAlpha SSO entry point in the topbar */
.sso-btn {
  display: inline-flex; align-items: center; gap: .5rem;
  height: 45px; padding: 0 1rem; border-radius: 14px;
  background: linear-gradient(135deg, var(--primary), var(--secondary));
  color: #fff; font-weight: 700; font-size: .88rem;
  text-decoration: none; flex: none; transition: .25s;
}
.sso-btn:hover { color: #fff; text-decoration: none; box-shadow: 0 6px 20px rgba(181,101,242,.3); transform: translateY(-1px); }
@media (max-width: 768px) { .sso-label { display: none; } .sso-btn { padding: 0; width: 45px; justify-content: center; } }

/* empty state for the sites table */
.sites-empty { text-align: center; color: var(--gray-600); padding: 3rem 1.5rem; }
.sites-empty i { font-size: 1.8rem; color: var(--gray-300); display: block; margin-bottom: .75rem; }

/* main-body container. Keeps Bootstrap's real `.container` (WHMCS JS measures it)
   while widening it for the portal shell, which already spends 280px on the rail. */
#main-body > .container.wv-container { max-width: 1440px; width: 100%; }

@media (prefers-reduced-motion: reduce) {
  .hub-links a:hover, .sso-btn:hover { transform: none; }
}


/* ==========================================================================
   4. SMALL GAPS
   Components your markup emitted but nothing defined — including .back-btn
   and .gradient-pink, which lived in inline <style> blocks that are now gone.
   ========================================================================== */

/* was in header.tpl's inline <style> */
.back-btn {
  display: inline-flex; align-items: center; gap: .6rem;
  background: linear-gradient(135deg, var(--primary), var(--accent));
  color: #fff; padding: .6rem 1.2rem; border: none; border-radius: 12px;
  cursor: pointer; font-size: .9rem; font-weight: 600; transition: .25s;
  text-decoration: none;
}
.back-btn:hover { transform: translateY(-2px); color: #fff; text-decoration: none; }
.back-btn i { transition: transform .25s; }
.back-btn:hover i { transform: translateX(-4px); }

/* referenced by homepage.tpl but never defined */
.gradient-pink { background: linear-gradient(135deg, #f25cce, #b565f2); }
.gradient-blue { background: linear-gradient(135deg, #3b82f6, #6366f1); }

/* sidebar renderer wrappers */
.nav-items  { display: block; }
.nav-label  { flex: 1; min-width: 0; }
.nav-badge  { flex: none; margin-left: auto; }
.nav-badge .badge { background: rgba(255,255,255,.16); color: #fff; }
.nav-item.active .nav-badge .badge { background: rgba(0,0,0,.22); }
.nav-item.disabled > a { opacity: .4; pointer-events: none; }
.sidebar-nav-body, .sidebar-nav-foot { padding: .5rem 1rem; color: rgba(255,255,255,.6); font-size: .85rem; }
.sidebar-nav-foot { border-top: 1px solid rgba(255,255,255,.08); }
/* your .nav-item rule targets the div; these anchors must fill it */
#sidebar .nav-item > a {
  display: flex; align-items: center; gap: .8rem;
  color: inherit; text-decoration: none; width: 100%;
}
#sidebar .nav-item > a:hover { color: inherit; text-decoration: none; }

/* topbar user block + dropdown separator */
.user-meta { display: none; }
@media (min-width: 768px) { .user-meta { display: block; } }
.notif-divider { height: 1px; background: var(--gray-200); margin: .4rem 0; list-style: none; }
.dropdown li { list-style: none; }
.dropdown li a {
  display: flex; align-items: center; gap: .7rem;
  padding: .55rem 1rem; color: var(--gray-700); font-size: .89rem; text-decoration: none;
}
.dropdown li a:hover { background: var(--gray-50); color: var(--primary); text-decoration: none; }
.dropdown li a i { width: 1.1rem; text-align: center; color: var(--gray-400); }

/* quick actions laid out horizontally now the chart panel is gone */
.action-list-row { flex-direction: row; flex-wrap: wrap; }
.action-list-row > .action-item { flex: 1 1 240px; }

/* footer region — there was no <footer> anywhere before */
.site-footer {
  border-top: 1px solid var(--gray-200);
  padding: 1.5rem;
  color: var(--gray-600); font-size: .85rem;
  display: flex; flex-wrap: wrap; gap: .75rem 1.5rem;
  align-items: center; justify-content: space-between;
}
.site-footer nav { display: flex; flex-wrap: wrap; gap: 1rem; }
.site-footer a { color: var(--gray-600); }
.site-footer a:hover { color: var(--primary); }

/* logged-out landing block on homepage.tpl */
.hero {
  background: var(--white); border-radius: 20px;
  padding: 3rem 2rem; margin-bottom: 1.5rem; text-align: center;
  box-shadow: 0 10px 25px rgba(0,0,0,.05);
  background-image: radial-gradient(120% 140% at 50% -20%, rgba(255,140,66,.10), transparent 60%);
}
.hero h2 { font-size: clamp(1.5rem, 4vw, 2.2rem); font-weight: 800; margin: 0 0 .75rem; }
.hero p  { color: var(--gray-600); margin: 0 auto 1.5rem; max-width: 46ch; }
.hero-actions { display: flex; flex-wrap: wrap; gap: .75rem; justify-content: center; }


/* ==========================================================================
   5. LAYOUT FIXES FOUND BY RENDERING THE LIVE PAGE
   ========================================================================== */

/* `.tiles` was only ever a marker class — the original markup got its grid from
   Bootstrap `row g-4` + `col-6 col-xl-3`. This build drops those wrappers, so
   without this the four stat tiles stack full-width down the page. */
.tiles {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1.25rem;
  margin-bottom: 1.5rem;
}
@media (max-width: 1200px) { .tiles { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 560px)  { .tiles { grid-template-columns: 1fr; } }

/* the tiles are much shorter now they sit side by side */
.tiles .tile-card { padding: 1.25rem 1.25rem; }
.tiles .tile-stat { font-size: 1.9rem; margin: .35rem 0 .5rem; }
.tiles .tile-badge { margin-top: 0; }

/* the hub reads better at 3 across on a wide viewport */
@media (min-width: 1500px) { .hub { grid-template-columns: repeat(3, minmax(0,1fr)); } }

/* `.chart-card` carries its own 1.5rem padding, so a nested `.card-header` /
   `.card-body` double-pads and the header rule sits inset. Let the header span. */
.chart-card { padding: 0; }
.chart-card > .card-header { padding: 1.1rem 1.4rem; margin: 0; }
.chart-card > .card-body   { padding: 1.4rem; }
.chart-card > div[style*="overflow-x"] { padding: 0; }
.chart-card .sites-table { margin: 0; }
.chart-card .sites-table thead th:first-child,
.chart-card .sites-table tbody td:first-child { padding-left: 1.4rem; }
.chart-card .sites-table thead th:last-child,
.chart-card .sites-table tbody td:last-child  { padding-right: 1.4rem; }
.chart-card .action-list { padding: 1.4rem; }


/* ---- density pass (measured from a headless render of the live page) ---- */

/* your .sites-table carries padding:1.5rem AND border-spacing:0 .75rem on top of
   1rem cell padding — inside a .chart-card that already pads, it left ~50px of
   dead space above and below the single row. */
.chart-card .sites-table { padding: 0; border-spacing: 0; }
.chart-card .sites-table thead th { padding: .75rem 1rem; }
.chart-card .sites-table tbody td { padding: .85rem 1rem; }

/* grid children stretch to the tallest sibling, so a 3-link card next to a
   7-link card grew a large void. Let each card take its natural height. */
.hub { align-items: start; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }

/* quick actions: 3 across instead of wrapping 2 + 1 */
.action-list-row > .action-item { flex: 1 1 190px; }
.chart-card .action-list-row { padding: 1.2rem 1.4rem; gap: .9rem; }
.action-item { padding: .85rem 1rem; }

/* WHMCS home panels are widget-shaped, not link lists — give them their own
   rhythm and stop them inheriting the link-card min-height. */
.panels-grid { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.panels-grid .hub-card { padding-bottom: .25rem; }
.panels-grid .list-group-item { border-radius: 0; }

.hub-title { margin-top: 2.25rem; }
.hub-links { padding: .35rem .5rem .6rem; }
.hub-links a { padding: .5rem .8rem; }

/* ---- spacing pass 2 ---- */

/* your .chart-card has no bottom margin, so stacked cards butt together and
   read as one merged block. */
.chart-card { margin-bottom: 1.5rem; }
.hub-card .card-body { padding: 1rem 1.25rem; }

/* WHMCS home panels: their bodies can contain an un-sized <canvas> (the
   wvWpMetrics hook does). Without a cap it reserves a large empty band. */
.panels-grid canvas { max-height: 150px; display: block; }
.panels-grid .card-body > div { padding: 0 !important; }
.panels-grid .btn { margin-top: .25rem; }

/* NB: do not use align-self:stretch here — it defeats .hub{align-items:start}
   and re-creates the voids next to any short panel. */


/* ---- polish pass 3 (from rendering dashboard, product details, invoices) ---- */

/* the topbar search rendered as a bare input: your .search-bar pill styling was
   never on the element. Cover both the class and the form for safety. */
.search-container form,
.search-container .search-bar {
  display: flex; align-items: center; gap: .6rem;
  background: var(--gray-100); border: 1px solid transparent;
  border-radius: 20px; padding: .55rem 1rem; transition: .2s;
}
.search-container form:focus-within { background: #fff; border-color: var(--primary); }
.search-container input {
  border: 0; background: none; outline: 0; width: 100%; font-size: .92rem;
  color: var(--gray-900); padding: 0;
}
.search-container button {
  border: 0; background: none; color: var(--gray-500); cursor: pointer;
  padding: 0; flex: none; line-height: 1;
}
.search-container button:hover { color: var(--primary); }
.search-container i { color: var(--gray-500); flex: none; }

/* Back was a full-strength gradient competing with the page title for a
   secondary action. Make it quiet. */
.back-btn {
  background: #fff; border: 1px solid var(--gray-200); color: var(--gray-700);
  padding: .45rem .9rem; font-size: .85rem; box-shadow: none;
}
.back-btn:hover { background: #fff; border-color: var(--primary); color: var(--primary); transform: none; }

/* page heading + breadcrumb sit better as one block */
.welcome-section { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem 1rem; margin-bottom: 1.25rem; }
.welcome-section h1, .welcome-section .welcome-text { margin: 0; font-size: 1.6rem; font-weight: 800; letter-spacing: -.02em; }
.welcome-section .breadcrumb { margin: 0; }

/* the right rail is short on most pages; sticking it stops the long empty
   column reading as a layout fault */
@media (min-width: 992px) {
  .sidebar-secondary { position: sticky; top: 90px; align-self: flex-start; }
}

/* stock label/value rows inside a narrow column stack and centre; keep them
   readable as a two-column pair instead */
#main-body .tab-content .row > [class*="col-sm-"] { text-align: left; }
#main-body .tab-content h4 { font-size: .78rem; letter-spacing: .06em; text-transform: uppercase; color: var(--gray-500); margin-bottom: .15rem; }

/* The wvWpMetrics hook renders <canvas id="wvWpChart"> and its three metrics are
   currently empty (—), so the chart never initialises and the canvas reserves a
   large blank band. Chart.js writes inline width/height on the element when it
   does initialise, so key the visibility off that: hidden when dead, shown when
   the hook starts returning data. No template change needed either way. */
.panels-grid canvas:not([style]) { display: none; }
.panels-grid canvas { max-height: 150px; }


/* ==========================================================================
   6. IA REALIGNMENT — match Six / Twenty-One structure, keep WebVibo styling
   --------------------------------------------------------------------------
   Research finding: both stock themes render $primaryNavbar as the main menu
   and put $primarySidebar / $secondarySidebar in a contextual column. This
   build rendered $primaryNavbar nowhere, which is why a hardcoded "hub" had to
   be invented to fill the gap. The rail now carries the real menu; the hub is
   gone; the dashboard is tiles + panels, as both stock themes do.
   ========================================================================== */

/* the rail now holds real menu sections, so tighten the rhythm */
.sidebar-nav .nav-section + .nav-section { margin-top: 1.1rem; }
.sidebar-nav .nav-section-single + .nav-section-single { margin-top: 0; }
.sidebar-nav .nav-section-title {
  display: flex; align-items: center; gap: .5rem;
  font-size: .66rem; font-weight: 700; letter-spacing: .13em;
  text-transform: uppercase; color: rgba(255,255,255,.34);
  padding: 0 1rem; margin-bottom: .3rem;
}
.sidebar-nav .nav-section-title .badge { margin-left: auto; background: rgba(255,255,255,.14); }
.sidebar-nav .nav-divider { height: 1px; background: rgba(255,255,255,.08); margin: .4rem 1rem; }
#sidebar .nav-item > a { font-size: .9rem; }
#sidebar .nav-item .nav-icon { opacity: .75; font-size: .82rem; }
#sidebar .nav-item.active > a .nav-icon,
#sidebar .nav-item > a:hover .nav-icon { opacity: 1; }
#sidebar .nav-badge { margin-left: auto; }
#sidebar .nav-badge .badge { background: rgba(255,255,255,.16); color: #fff; font-size: .68rem; }

/* contextual sidebars now sit together in the right column */
.sidebar-secondary .card-sidebar + .card-sidebar { margin-top: 1rem; }

/* ---- home panels, rendered with the stock contract ---- */
.wv-panels { margin-top: .25rem; }
.wv-panels-cols { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 1.5rem; align-items: start; }
@media (max-width: 1400px) { .wv-panels-cols { grid-template-columns: 1fr; } }
.wv-panels-col { display: flex; flex-direction: column; gap: 1.5rem; }
.wv-panels-full { display: flex; flex-direction: column; gap: 1.5rem; }
.wv-panels-full:not(:empty) { margin-bottom: 1.5rem; }

.wv-panel-card {
  background: var(--white); border-radius: 20px;
  box-shadow: 0 10px 25px rgba(0,0,0,.05);
  overflow: hidden; position: relative;
}
.wv-panel-card .wv-panel-head {
  display: flex; align-items: center; gap: .75rem; justify-content: space-between;
  padding: 1.05rem 1.35rem; border-bottom: 1px solid var(--gray-200);
}
.wv-panel-card .wv-panel-head h3 {
  display: flex; align-items: center; gap: .55rem;
  font-size: .96rem; font-weight: 800; margin: 0; color: var(--gray-900);
}
.wv-panel-card .wv-panel-head h3 > i { color: var(--primary); }
.wv-panel-card .wv-panel-body { padding: 1.1rem 1.35rem; }
.wv-panel-card .wv-panel-foot { padding: .85rem 1.35rem; border-top: 1px solid var(--gray-200); background: var(--gray-50); }
.wv-panel-card .list-group-item { padding: .7rem 1.35rem; border-color: var(--gray-100); }
.wv-panel-card canvas:not([style]) { display: none; }
.wv-panel-card canvas { max-height: 150px; }
.wv-panel-card .wv-panel-body > div { padding: 0 !important; }

/* colour accents WHMCS panels declare via getExtra('color') */
.wv-panel-card::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 3px; background: transparent; }
.wv-panel-card.accent-blue::before   { background: #3b82f6; }
.wv-panel-card.accent-green::before  { background: var(--success); }
.wv-panel-card.accent-red::before    { background: var(--danger); }
.wv-panel-card.accent-gold::before,
.wv-panel-card.accent-orange::before { background: var(--primary); }
.wv-panel-card.accent-purple::before { background: var(--secondary); }

.addon-output { margin-bottom: 1.5rem; }

/* ---- rail density + panel header fixes (from render) ---- */

/* the real menu is ~16 items; the original 3-item spacing made it scroll */
/* your #sidebar .nav-item pads the wrapper AND my anchor padded again, so every
   row was ~2x taller than it needed to be. All padding lives on the anchor. */
#sidebar .nav-item { padding: 0; }
#sidebar .nav-item > a { padding: .46rem 1rem; gap: .65rem; line-height: 1.35; }
#sidebar .nav-item > a,
#sidebar .nav-item { border: 0; box-shadow: none; }
.sidebar-nav { padding: .5rem .6rem 2rem; }
.sidebar-nav .nav-section + .nav-section { margin-top: .9rem; }
.sidebar-nav .nav-section-title { margin-bottom: .15rem; padding: 0 1rem; }
/* NB: do not indent icon-less labels — at 280px it forces two-line wraps. */

/* panel header button wrapped onto two lines and collided with the title */
.wv-panel-card .wv-panel-head h3 { min-width: 0; }
.wv-panel-card .wv-panel-head h3 span { overflow-wrap: anywhere; }
.wv-panel-card .wv-panel-head > .action-btn {
  flex: none; white-space: nowrap; align-self: flex-start;
}


/* contextual sidebar cards are expanded again now that .container has a real
   width; give them WebVibo's card treatment */
.sidebar-secondary .card-sidebar { box-shadow: 0 10px 25px rgba(0,0,0,.05); border: 0; }
.sidebar-secondary .card-sidebar > .card-header { background: #fff; border-bottom: 1px solid var(--gray-200); }
.sidebar-secondary .card-sidebar .card-title { font-size: .84rem; font-weight: 800; letter-spacing: .02em; text-transform: none; color: var(--gray-900); }
.sidebar-secondary .list-group-item { padding: .6rem 1.1rem; font-size: .88rem; }

/* cart badge is always in the DOM (WHMCS JS targets #cartItemCount); hide at zero */
#cartItemCount.is-empty { display: none; }

/* ---- topbar dropdown panels ----
   Driven by $secondaryNavbar, so the item count is whatever WHMCS + addons
   supply (9 here). Needs to stay compact and scroll rather than run off-screen. */
.topbar-actions .dropdown {
  padding: .35rem; min-width: 236px; max-width: 280px;
  max-height: min(70vh, 520px); overflow-y: auto; overscroll-behavior: contain;
}
.topbar-actions .dropdown li a {
  padding: .45rem .7rem; font-size: .875rem; line-height: 1.35;
  border-radius: 8px; gap: .6rem;
}
.topbar-actions .dropdown li a i { font-size: .82rem; }
/* the divider <li> inherits .dropdown li padding, which paints the background as a
   thick band instead of a hairline. Zero it explicitly. */
.topbar-actions .notif-divider {
  height: 1px; min-height: 0; padding: 0; margin: .3rem .5rem;
  background: var(--gray-200); border: 0; display: block;
}
.topbar-actions .notif-empty { padding: .9rem .7rem; font-size: .86rem; }
.topbar-actions .notif-footer { padding: .4rem .7rem 0; }
/* PanelAlpha injects an inline-styled span for its SSO link; keep it on one line */
.topbar-actions .dropdown li a span { overflow: hidden; text-overflow: ellipsis; }

/* admin masquerade / admin-logged-in return button — deliberately loud so it is
   never mistaken for part of the client UI */
.admin-return {
  display: inline-flex; align-items: center; gap: .5rem; flex: none;
  height: 45px; padding: 0 .95rem; border-radius: 14px;
  background: var(--gray-900); color: #fff; font-weight: 700; font-size: .85rem;
  text-decoration: none; border: 1px solid rgba(255,255,255,.12);
}
.admin-return:hover { background: #000; color: #fff; text-decoration: none; }
.admin-return i { font-size: .85rem; }
@media (max-width: 900px) { .admin-return span { display: none; } .admin-return { padding: 0; width: 45px; justify-content: center; } }

/* ---- LOGO SIZING ----
   The original theme capped this from an inline <style> in header.tpl
   (.sidebar-logo img { max-width:50% }) which was removed when styles moved out
   of templates. Bootstrap does NOT set a global img max-width, and the admin
   logo is 3254x1068, so with no cap it rendered at natural size — enormous on
   mobile. Constrain on both axes so any logo the admin uploads fits. */
.sidebar-logo { min-width: 0; gap: .5rem; }
.sidebar-logo > a { display: block; min-width: 0; flex: 0 1 auto; line-height: 0; }
.sidebar-logo img {
  display: block;
  max-width: 100%;
  width: auto;
  height: auto;
  max-height: 40px;
  object-fit: contain;
  object-position: left center;
}
@media (max-width: 992px) { .sidebar-logo img { max-height: 36px; } }

/* ==========================================================================
   7. ORDER FORM — product group / pricing cards
   --------------------------------------------------------------------------
   templates/orderforms/standard_cart is a separate template set the theme does
   not own, and its stylesheet loads AFTER this one, so equal specificity loses.
   Every rule here is prefixed with `body` purely to outrank it.

   Its layout is: grey header bar, .product-desc floated left at 60%, footer
   floated right at 40%. That reads as a data row, not a pricing card, so the
   floats are unwound into a vertical card.

   NB: WHMCS emits a separate .row per PAIR of products (2 rows x col-md-6 here),
   so a single 4-across row is not achievable from CSS — 2-up is the markup.
   ========================================================================== */

body #order-standard_cart .products { margin: 0; }
body #order-standard_cart .products .row { margin-inline: -.6rem; }
body #order-standard_cart .products [class*="col-"] { padding-inline: .6rem; }

body #order-standard_cart .products .product {
  display: flex; flex-direction: column; height: 100%;
  padding: 0; margin: 0 0 1.2rem;
  background: var(--white);
  border: 1px solid var(--gray-200);
  border-radius: 20px;
  box-shadow: 0 10px 25px rgba(0,0,0,.05);
  overflow: hidden;
  transition: .25s;
}
body #order-standard_cart .products .product:hover {
  transform: translateY(-3px);
  box-shadow: 0 16px 38px rgba(181,101,242,.16);
  border-color: transparent;
}

body #order-standard_cart .products .product header {
  position: static; margin: 0;
  padding: 1.05rem 1.35rem .9rem;
  background: transparent;
  border-bottom: 1px solid var(--gray-200);
  text-align: center;
}
body #order-standard_cart .products .product header span {
  font-size: 1.05rem; font-weight: 800; letter-spacing: -.01em; color: var(--gray-900);
}

/* unwind the 60% left float */
body #order-standard_cart .products .product div.product-desc {
  float: none; width: 100%; flex: 1;
  padding: 1.1rem 1.35rem;
  text-align: center;
  color: var(--gray-600); font-size: .9rem; line-height: 1.85;
}
body #order-standard_cart .products .product div.product-desc p { margin: 0; }
body #order-standard_cart .products .product div.product-desc ul { margin: 0; padding: 0; list-style: none; }

/* unwind the 40% right float */
body #order-standard_cart .products .product footer {
  float: none; width: 100%; margin: 0;
  padding: 0 1.35rem 1.35rem;
  font-size: 1em; text-align: center;
}
body #order-standard_cart .products .product div.product-pricing {
  margin-bottom: .9rem; font-size: .82rem; color: var(--gray-600);
}
body #order-standard_cart .products .product div.product-pricing .price {
  display: block; font-size: 1.7rem; font-weight: 800;
  letter-spacing: -.03em; color: var(--gray-900); line-height: 1.2;
}
body #order-standard_cart .products .product footer .btn {
  display: flex; align-items: center; justify-content: center; gap: .5rem;
  width: 100%; float: none;
  background: linear-gradient(135deg, var(--primary), var(--secondary));
  border: 0; color: #fff; font-weight: 700;
  border-radius: 12px; padding: .68rem 1rem; font-size: .92rem;
  white-space: nowrap;
}
body #order-standard_cart .products .product footer .btn:hover {
  color: #fff; box-shadow: 0 6px 20px rgba(181,101,242,.3);
}

body #order-standard_cart .header-lined { margin-bottom: 1.4rem; }

/* ==========================================================================
   8. RESPONSIVE PASS
   --------------------------------------------------------------------------
   Audited every client-area page at a true 430px viewport (headless Chrome
   clamps --window-size to 500px, so pages were laid out inside a fixed-width
   iframe to get a real mobile layout). Findings and fixes below.
   ========================================================================== */

/* ---- ROOT CAUSE: .main-content is a flex child of .portal-container, and a
   flex item defaults to min-width:auto — it refuses to shrink below its
   content. Wide DataTables therefore pushed it to 464–529px inside a 430px
   viewport, and the topbar, content area and footer all inherited that width.
   This single declaration fixes horizontal overflow on every page. ---- */
.portal-container { min-width: 0; max-width: 100%; }
.main-content { min-width: 0; max-width: 100%; }
.dashboard-content { min-width: 0; max-width: 100%; }
#main-body, #main-body > .container { min-width: 0; max-width: 100%; }

/* ---- wide content must scroll inside its own box, never widen the page ---- */
.dataTables_wrapper,
#main-body .table-responsive,
.listtable {
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
#main-body table { max-width: 100%; }
.dashboard-content pre,
.dashboard-content code { overflow-x: auto; max-width: 100%; }
/* long unbroken strings (domains, API keys, URLs) must not stretch the page */
.dashboard-content .site-url,
.dashboard-content .breadcrumb,
.wv-panel-card .list-group-item { overflow-wrap: anywhere; }

/* ---- header row: h1 + breadcrumb was measured at 454–490px ---- */
.welcome-section { min-width: 0; max-width: 100%; }
.welcome-section .breadcrumb { flex-wrap: wrap; min-width: 0; }
@media (max-width: 640px) {
  .welcome-section h1, .welcome-section .welcome-text { font-size: 1.25rem; }
  .welcome-section .breadcrumb { font-size: .78rem; }
}

/* ---- topbar: flex children must be allowed to shrink ---- */
.topbar { min-width: 0; max-width: 100%; }
.search-container { min-width: 0; }
.topbar-actions { min-width: 0; flex-wrap: nowrap; }
@media (max-width: 560px) {
  /* keep the row to: menu, SSO, cart, avatar — drop the rest rather than wrap */
  .topbar-actions > a[data-target="#modalChooseLanguage"] { display: none; }
  .topbar { gap: .4rem; padding: 0 .75rem; }
}

/* ---- footer ---- */
.site-footer { min-width: 0; max-width: 100%; padding: 1.25rem; }
.site-footer nav { gap: .75rem 1rem; }
@media (max-width: 640px) { .site-footer { flex-direction: column; align-items: flex-start; gap: .75rem; } }

/* ---- TOUCH TARGETS (audit flagged 36px and below) ---- */
#sidebarToggle { width: 44px; height: 44px; display: none; align-items: center; justify-content: center; }
@media (max-width: 992px) { #sidebarToggle { display: flex; } }
.menu-btn { min-width: 44px; min-height: 44px; }
@media (max-width: 992px) {
  /* WHMCS DataTables length/filter controls render at 31px */
  .dataTables_wrapper select.custom-select,
  .dataTables_wrapper select.custom-select-sm,
  .dataTables_wrapper input[type="search"] { min-height: 40px; }
  #main-body .btn:not(.btn-xs) { min-height: 40px; display: inline-flex; align-items: center; justify-content: center; }
  .list-group-item-action { min-height: 42px; display: flex; align-items: center; }
  .action-btn { min-height: 40px; }
}

/* ---- ORDER FORM: the Categories / Actions selects were vertically clipped.
   Their rule sets padding:10px 12px on a <select> that Bootstrap gives a fixed
   height, so the text was cut through the middle. ---- */
body #order-standard_cart .sidebar-collapsed select.form-control,
body #order-standard_cart select.custom-select,
body #order-standard_cart .sidebar-collapsed .panel-body select {
  height: auto;
  min-height: 44px;
  line-height: 1.4;
  padding: .6rem 2rem .6rem .8rem;
  text-overflow: ellipsis;
  max-width: 100%;
}
/* the panel clipped anything taller than itself */
body #order-standard_cart .sidebar-collapsed .panel.card.panel-default { overflow: visible; }
body #order-standard_cart .sidebar-collapsed .panel-body.card-body { overflow: visible; }
body #order-standard_cart { max-width: 100%; overflow-x: hidden; }
body #order-standard_cart .header-lined h1 { overflow-wrap: anywhere; }
@media (max-width: 640px) {
  body #order-standard_cart .header-lined h1 { font-size: 1.6rem; }
}

/* ---- TOUCH TARGETS, identified individually rather than blanket-inflated ----
   Measured at 430px. Left alone deliberately: iCheck radios and
   bootstrap-switch inputs, whose visible control is the styled wrapper, not the
   13–25px input the audit sees. */
@media (max-width: 992px) {
  /* primary navigation: was 34px */
  #sidebar .nav-item > a { min-height: 44px; padding-block: .55rem; }
  .sidebar-logo > a { min-height: 44px; display: flex; align-items: center; }

  /* footer nav: was 22px */
  .site-footer nav a { display: inline-flex; align-items: center; min-height: 40px; padding-inline: .15rem; }

  /* breadcrumbs: was 20px */
  .welcome-section .breadcrumb-item a,
  .welcome-section .breadcrumb-item { display: inline-flex; align-items: center; min-height: 32px; }

  /* panel "View More…": was 19px */
  .wv-panel-foot .btn-view-more,
  .wv-panel-card .btn-view-more { display: inline-flex; align-items: center; min-height: 40px; }

  /* native checkboxes render at 13px; enlarge and keep the label tappable */
  #main-body input[type="checkbox"].form-check-input,
  #main-body input[type="radio"].form-check-input { width: 18px; height: 18px; }
  #main-body .form-check-label,
  #main-body label.form-check-label { display: inline-flex; align-items: center; min-height: 32px; gap: .4rem; }
}

/* wide data tables scroll inside their own box on small screens; give the
   scroll affordance a visible edge so it does not look truncated */
@media (max-width: 992px) {
  .dataTables_wrapper { position: relative; }
  .dataTables_wrapper table { min-width: 100%; }
}
