/* ==========================================================================
   Client Service Hub — WHMCS Client Area
   Child theme of Twenty-One. WHMCS 8.13.5, Bootstrap 4.5.3, FA 5.10.1.
   Loaded last, after the parent's theme.css.

   Palette taken from the live GeneratePress site, not invented.
   Layout: fixed left sidebar at >=1200px, stock horizontal header below.
   CSS only. No template overrides. Nothing removed.

   REQUIRES one admin change: set the WHMCS logo to csh1.png (the green +
   white reversed artwork). The dark-text csh2.png and the 2023 blue
   csh-logo.png both disappear against the dark sidebar.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENS
   -------------------------------------------------------------------------- */

:root {
    /* Brand ------------------------------------------------------------- */
    --csh-green:        #96DF37;  /* logo green. 8.58:1 on dark, 1.63:1 on white */
    --csh-green-hover:  #7CBF23;
    --csh-green-deep:   #4E7D16;  /* link text on light surfaces, 4.92:1 */
    --csh-green-wash:   #F2FBE6;

    /* Dark surfaces ----------------------------------------------------- */
    --csh-dark:         #2C2C2C;  /* site header/footer colour */
    --csh-dark-2:       #3F3F3F;  /* site nav-current colour, reused for active row */
    --csh-dark-3:       #383838;  /* hover row */

    /* Light surfaces ---------------------------------------------------- */
    --csh-canvas:       #EFEFEF;
    --csh-surface:      #FFFFFF;
    --csh-surface-2:    #F5F6F7;  /* rail panels — sits between #EFEFEF canvas and white content */
    --csh-line:         #DDDDDD;

    /* Text -------------------------------------------------------------- */
    --csh-heading:      #222222;  /* 15.91:1 on white */
    --csh-body:         #3A3A3A;  /* 11.37:1 on white */
    --csh-mute:         #575760;  /*  7.15:1 on white — site's own --contrast-2 */

    /* On dark ----------------------------------------------------------- */
    --csh-on-dark:      #FFFFFF;  /* 13.97:1 */
    --csh-on-dark-2:    #C9C9C9;  /*  8.43:1 */

    /* State — colour never used alone, always with a text label --------- */
    --csh-attention:    #A8641A;
    --csh-urgent:       #A6322F;

    /* Type -------------------------------------------------------------- */
    --csh-font: "Segoe UI", system-ui, -apple-system, "Helvetica Neue", sans-serif;

    /* Shape and space --------------------------------------------------- */
    --csh-sidebar:      260px;
    --csh-radius:       6px;
    --csh-rail:         3px;
    --csh-shadow:       0 1px 2px rgba(0,0,0,.05), 0 4px 12px rgba(0,0,0,.05);
    --csh-focus:        0 0 0 3px rgba(44,44,44,.45);
}

/* --------------------------------------------------------------------------
   2. FOUNDATION
   NOTE: .primary-bg-color sits on <body>. It is the page background,
   not a button class.
   -------------------------------------------------------------------------- */

body,
body.primary-bg-color {
    font-family: var(--csh-font);
    line-height: 1.6;
    color: var(--csh-body);
    background-color: var(--csh-canvas);
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6 {
    color: var(--csh-heading);
    font-weight: 700;
    line-height: 1.25;
}

a         { color: var(--csh-green-deep); text-underline-offset: 2px; }
a:hover,
a:focus   { color: var(--csh-heading); }

.table td, .table th, .tile .stat {
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

/* Focus is dark, not green — a green ring on a green button is invisible. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
.btn:focus-visible,
.tile:focus-visible {
    outline: 2px solid var(--csh-dark);
    outline-offset: 2px;
    box-shadow: var(--csh-focus);
}

/* This file uses !important in exactly three places: reduced-motion below,
   the print block, and the .ml-auto reset in the sidebar. The first two are
   deliberate — an override that loses a specificity fight is an
   accessibility failure, and print must beat every screen rule. The third is
   unavoidable: Bootstrap's .ml-auto utility is itself !important, so nothing
   else can beat it. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}

/* --------------------------------------------------------------------------
   3. HEADER — shared styling, both layouts
   -------------------------------------------------------------------------- */

html body #header.header { background-color: var(--csh-dark); border: 0; }

#header .topbar {
    background-color: transparent;
    border-top: 1px solid rgba(255,255,255,.09);
    font-size: .875rem;
    color: var(--csh-on-dark-2);
    padding: .875rem;
}
#header .topbar a             { color: var(--csh-on-dark); }
#header #accountNotifications { color: var(--csh-on-dark); }

#header .navbar,
#header .navbar.navbar-light,
#header .main-navbar-wrapper { background-color: transparent; }

/* Two logos, one WHMCS setting.

   assets/img/logo.png is shared by the client area header, invoice and
   quote PDFs, and email templates. PDFs render on white paper, so that
   file must be csh2 — the dark-text artwork. The reversed csh1 was
   invisible there: "Service" is white, on white.

   The header is the only dark surface, so it is the one that overrides,
   pulling csh1 from this theme's own assets. Done in CSS rather than
   JavaScript so it holds with scripting disabled. */
#header a.navbar-brand img.logo-img {
    max-height: 44px;
    width: auto;
    content: url("../assets/img/logo.png");
}

/* Search. The magnifier is a sibling control, so the group must not wrap
   and both halves must share a height or they detach. */
#header .input-group.search { flex-wrap: nowrap; }

#header .input-group.search .form-control,
#header .input-group.search .appended-form-control,
#header .input-group.search .prepended-form-control {
    height: 40px;
    background-color: rgba(255,255,255,.10);
    border-color: rgba(255,255,255,.20);
    color: var(--csh-on-dark);
    box-shadow: none;
}
#header .input-group.search .form-control::placeholder { color: rgba(255,255,255,.6); }

#header .input-group.search .form-control:focus {
    background-color: rgba(255,255,255,.16);
    border-color: rgba(255,255,255,.35);
}

#header .input-group.search .input-group-text,
#header .input-group.search .btn,
#header .input-group.search .input-group-prepend > * ,
#header .input-group.search .input-group-append > * {
    height: 40px;
    background-color: rgba(255,255,255,.16);
    border-color: rgba(255,255,255,.20);
    color: var(--csh-on-dark);
}

/* Cart reads as a nav row, not a floating bordered square. */
#header a.cart-btn {
    display: flex;
    align-items: center;
    gap: .5rem;
    color: var(--csh-on-dark-2);
    background: transparent;
    border: 0;
    padding: .5rem .875rem;
    border-radius: var(--csh-radius);
    font-weight: 500;
}
#header a.cart-btn:hover,
#header a.cart-btn:focus {
    background-color: var(--csh-dark-3);
    color: var(--csh-on-dark);
}
#header a.cart-btn .fa,
#header a.cart-btn .fas,
#header a.cart-btn i { font-size: 1rem; }

#header #cartItemCount.badge-info,
#header #cartItemCount {
    background-color: var(--csh-green);
    border-color: transparent;
    color: var(--csh-dark);
    font-weight: 700;
}

/* The header carries .navbar-light, so Bootstrap paints nav links
   rgba(0,0,0,.5) — dark text at half opacity, on a dark bar. Raising
   specificity was not enough; the parent forces it. This is a sanctioned
   !important: unreadable navigation is an accessibility failure, not a
   style preference. Measured 11.4:1 against #2C2C2C. */
#header.header .navbar-nav .nav-link,
#header.header .navbar-nav .nav-link:link,
#header.header .navbar-nav .nav-link:visited,
#header.header .navbar-nav .dropdown-toggle,
#header.header .navbar-nav > li > a {
    color: #E8E8E8 !important;
    font-weight: 500;
}
#header.header .navbar-nav .nav-link:hover,
#header.header .navbar-nav .nav-link:focus,
#header.header .navbar-nav > li > a:hover {
    color: #FFFFFF !important;
}

nav.master-breadcrumb {
    background: transparent;
    font-size: .875rem;
    color: var(--csh-mute);
}

/* Sticky footer. body is already the layout root for the sidebar offset,
   so it carries the column too. */
body,
body.primary-bg-color {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}
#main-body { flex: 1 0 auto; }
#footer.footer { flex-shrink: 0; }

/* --------------------------------------------------------------------------
   4. LEFT SIDEBAR — desktop only, >=1200px

   Below this width everything reverts to the stock Twenty-One horizontal
   header and Bootstrap collapse. A fixed 260px column on a phone eats the
   screen, and clients read invoices on phones.
   -------------------------------------------------------------------------- */

@media (min-width: 1200px) {

    #header.header {
        position: fixed;
        top: 0; left: 0; bottom: 0;
        width: var(--csh-sidebar);
        display: flex;
        flex-direction: column;
        overflow-y: auto;
        overflow-x: hidden;
        z-index: 1030;
        padding: 0;
    }

    /* Containers inside the sidebar must not impose a grid width, and must
       not add their own gutter — .navbar already supplies it. Doubling the
       two pushed the search field ~17px past the column edge. */
    #header .container {
        max-width: none;
        width: 100%;
        padding-left: 0;
        padding-right: 0;
    }

    /* Unwind Bootstrap's horizontal navbar layout. */
    #header .navbar {
        display: block;
        padding: .875rem;
        width: 100%;
    }

    #header .navbar > .container { padding-left: 0; padding-right: 0; }

    #header .topbar { order: 3; margin-top: auto; padding: .875rem; }
    #header .topbar > .container { padding-left: 0; padding-right: 0; }
    #header .topbar > .container > .d-flex { flex-wrap: wrap; row-gap: .5rem; }
    #header .topbar .btn-active-client,
    #header .topbar .input-group.active-client { width: 100%; }

    /* Logo block */
    #header a.navbar-brand {
        display: block;
        margin: .5rem 0 1rem;
        padding: 0;
    }
    #header a.navbar-brand img.logo-img { max-width: 100%; max-height: 40px; }

    /* Search and cart stack under the logo */
    #header .input-group.search { margin-bottom: .75rem; }
    #header a.cart-btn { padding-left: 0; }

    /* The collapse is already flex at xl via .navbar-expand-xl. Its two
       child lists (ul#nav and ul.navbar-nav.ml-auto) sit in a row by
       default — this is what stacks them. Missing in v3. */
    #header #mainNavbar.navbar-collapse {
        flex-direction: column;
        align-items: stretch;
        width: 100%;
    }

    #header .navbar-expand-xl .navbar-nav {
        flex-direction: column;
        flex-wrap: nowrap;
        width: 100%;
    }

    #header ul#nav,
    #header ul.navbar-nav { width: 100%; }

    /* Nothing inside a 260px column may carry a grid width. The search
       field and cart button overflowed the sidebar edge in v3. */
    #header .navbar > .container,
    #header .topbar > .container { max-width: 100%; width: 100%; }

    #header .input-group.search,
    #header .input-group.search .form-control,
    #header a.cart-btn {
        width: 100%;
        max-width: 100%;
        min-width: 0;
    }

    #header .input-group.search .form-control { flex: 1 1 auto; }
    #header a.cart-btn { display: flex; align-items: center; justify-content: flex-start; }

    /* autoCollapse still runs even with every item exempt: it calls
       removeClass('d-none') on the More container before finding no
       eligible children. That leaves an empty dropdown visible. The hook
       makes it purposeless, so hide it outright. */
    #header #nav .collapsable-dropdown { display: none; }

    /* Account menu to the TOP of the column. In a sidebar the first thing
       you see should be who you are signed in as. */
    #header ul.navbar-nav.ml-auto {
        margin-left: 0 !important;
        margin-top: 0;
        margin-bottom: 1rem;
        order: -1;
        padding-bottom: 1rem;
        border-bottom: 1px solid rgba(255,255,255,.09);
    }

    /* The greeting stands alone above the account menu. It is still a link
       to the dashboard — a dead anchor in the tab order helps nobody — but
       it is styled as what it is: a line of text saying who you are. */
    #header ul.navbar-nav > li.csh-greeting > .nav-link {
        padding: .25rem .875rem .75rem;
        font-size: 1.0625rem;
        font-weight: 700;
        color: #FFFFFF !important;
        border-left-color: transparent;
    }
    #header ul.navbar-nav > li.csh-greeting > .nav-link:hover {
        background: transparent;
        text-decoration: underline;
    }
    #header ul.navbar-nav > li.csh-greeting { margin-bottom: .25rem; }

    /* The account menu itself reads like every other section toggle. */
    #header ul.navbar-nav.ml-auto > li:not(.csh-greeting) > .nav-link {
        font-weight: 600;
    }

    #header .navbar-nav .nav-item { width: 100%; }

    #header .navbar-nav .nav-item { margin-bottom: .125rem; }
    #header .navbar-nav > li { margin-bottom: .125rem; }

    #header .navbar-nav .nav-link {
        display: block;
        width: 100%;
        padding: .6875rem .875rem;
        border-radius: var(--csh-radius);
        border-left: var(--csh-rail) solid transparent;
        transition: background-color .12s ease, color .12s ease;
    }

    #header .navbar-nav .nav-link:hover,
    #header .navbar-nav .nav-link:focus {
        background-color: var(--csh-dark-3);
        color: var(--csh-on-dark);
    }

    /* Active section.

       navbar.tpl renders <li class="d-block no-collapse dropdown"> — there
       is no .nav-item class on it. Every rule written against
       .nav-item.active has therefore never matched, which is why the menu
       kept collapsing even though the hook was setting active correctly. */
    #header .navbar-nav > li.active > .nav-link,
    #header .navbar-nav > li.active > a {
        background-color: var(--csh-dark-2);
        border-left-color: var(--csh-green);
        color: var(--csh-on-dark);
        box-shadow: none;
    }

    /* Sections stay closed, and the one you are in opens. Showing every
       item at once made the column long enough that the thing you wanted
       was as hard to find as it had been behind a click.

       The active class comes from the priority-101 passes in
       clientNavigation.php — navbar.tpl never calls isCurrent() itself, so
       without those hooks nothing here can match. */
    #header .navbar-nav > li.active > .dropdown-menu { display: block; }

    /* Support stays open regardless of where you are. It is the section a
       client reaches for when something is wrong, and a click is a cost paid
       exactly when they are least patient. Every other section still opens
       only when active.

       Note: this forces the menu open, so Support cannot be clicked shut.
       That matches how the active section already behaves.

       Originally commit 2cc60e7; lost when a7059a3 replaced the whole file;
       restored in v7.2. */
    #header .navbar-nav > li.csh-group-support > .dropdown-menu { display: block; }

    #header .navbar-nav .dropdown-item.active {
        background-color: var(--csh-dark-2);
        color: var(--csh-on-dark);
        box-shadow: inset 2px 0 0 var(--csh-green);
    }

    /* Sub-menus open inline rather than floating off the column edge.
       A single hairline rail down the left tells you these items belong to
       the parent above them — replacing the stray divider that was showing
       through from the parent theme. */
    #header .dropdown-menu {
        position: static;
        float: none;
        width: 100%;
        background: transparent;
        border: 0;
        border-left: 1px solid rgba(255,255,255,.14);
        border-radius: 0;
        box-shadow: none;
        margin: .125rem 0 .375rem 1.125rem;
        padding: 0;
    }

    #header .dropdown-menu .dropdown-item {
        padding: .4375rem .75rem;
        font-size: .9375rem;
        line-height: 1.4;
        white-space: normal;
        border-radius: 0 var(--csh-radius) var(--csh-radius) 0;
        color: #C9C9C9;
    }

    #header .dropdown-menu .dropdown-item:hover,
    #header .dropdown-menu .dropdown-item:focus {
        background-color: var(--csh-dark-3);
        color: var(--csh-on-dark);
    }

    #header .dropdown-menu .dropdown-item.active,
    #header .dropdown-menu .dropdown-item:active {
        background-color: var(--csh-dark-2);
        color: var(--csh-on-dark);
    }

    /* The parent theme's dividers read as random floating lines once the
       menu is vertical and inline. The rail above does that job now. */
    #header .dropdown-menu .dropdown-divider,
    #header .dropdown-menu .nav-divider { display: none; }

    /* Caret sits at the right edge of the row, not jammed against the text. */
    #header .navbar-nav .dropdown-toggle { position: relative; padding-right: 2rem; }
    #header .navbar-nav .dropdown-toggle::after {
        position: absolute;
        right: .875rem;
        top: 50%;
        margin-top: -2px;
    }

    /* Search: the input group broke onto two rows in v3.2 because the
       group was allowed to wrap inside the narrow column. */
    #header .input-group.search {
        flex-wrap: nowrap;
        margin-bottom: .75rem;
    }
    #header .input-group.search .form-control,
    #header .input-group.search .appended-form-control,
    #header .input-group.search .prepended-form-control {
        background-color: rgba(255,255,255,.10);
        border-color: rgba(255,255,255,.20);
        color: var(--csh-on-dark);
        height: 40px;
    }
    #header .input-group.search .input-group-text,
    #header .input-group.search .btn {
        height: 40px;
        background-color: rgba(255,255,255,.16);
        border-color: rgba(255,255,255,.20);
        color: var(--csh-on-dark);
    }

    /* Make room for the column.

       v3.3 and v3.4 did this by adding margin-left to three named elements.
       Content kept appearing underneath the sidebar anyway, because that
       approach only protects the elements you thought to name — anything
       else WHMCS renders at the top level slips through.

       Offsetting <body> instead means every descendant is inside the
       remaining space by construction. The sidebar is position:fixed, so it
       is measured against the viewport and unaffected by body padding. */
    body,
    body.primary-bg-color { padding-left: var(--csh-sidebar); }

    nav.master-breadcrumb,
    #main-body,
    #footer.footer { margin-left: 0; }

    /* Fluid content.

       header.tpl writes <div class="{if !$skipMainBodyContainer}container{/if}">
       — so on order forms and some cart steps the class is absent entirely
       and any rule targeting #main-body > .container matches nothing. That
       is why those pages kept their own width while everything else went
       fluid. Targeting the child div directly covers both cases. */
    #main-body > div,
    nav.master-breadcrumb > .container,
    #footer.footer > .container {
        max-width: none;
        width: 100%;
        padding-left: 1.75rem;
        padding-right: 1.75rem;
    }

    /* Sticky footer is handled by the body flex column in section 14. */

    /* Grid rows must not exceed the space that remains. */
    #main-body > div > .row { max-width: 100%; }
    #main-body .col-lg-4.col-xl-3,
    #main-body .col-lg-8.col-xl-9 { min-width: 0; }
}

/* --------------------------------------------------------------------------
   5. LAYOUT
   -------------------------------------------------------------------------- */

#main-body { padding-top: 1.75rem; padding-bottom: 3rem; }

.primary-content > h1:first-child,
.primary-content > h2:first-child { margin-top: 0; }

.sidebar .list-group-item { border-color: var(--csh-line); color: var(--csh-body); }
.sidebar .list-group-item.active {
    background-color: var(--csh-dark);
    border-color: var(--csh-dark);
    color: var(--csh-on-dark);
}

/* --------------------------------------------------------------------------
   6. DASHBOARD TILES
   -------------------------------------------------------------------------- */

.tiles a.tile {
    background: var(--csh-surface);
    border: 1px solid var(--csh-line);
    border-radius: var(--csh-radius);
    box-shadow: var(--csh-shadow);
    color: var(--csh-heading);
}
/* The tiles were links that looked like read-outs. Three things fix that:
   a cursor, a hover state that moves, and a visible affordance inside. */
.tiles a.tile {
    cursor: pointer;
    position: relative;
    transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease;
}

.tiles a.tile:hover,
.tiles a.tile:focus-visible {
    border-color: var(--csh-green);
    text-decoration: none;
    transform: translateY(-2px);
    box-shadow: 0 4px 16px rgba(0,0,0,.10);
}

/* The affordance itself, sitting beside the label. Deep green on a tint
   rather than white on brand green — at this size the label is small text
   and needs the contrast. It fills in on hover. */
.tiles a.tile .title { display: flex; align-items: center; justify-content: space-between; gap: .75rem; }

.tiles a.tile .title::after {
    content: "View";
    flex: 0 0 auto;
    padding: .1875rem .625rem;
    border: 1px solid rgba(78,125,22,.35);
    border-radius: 100px;
    background: var(--csh-green-wash);
    color: var(--csh-green-deep);
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .02em;
    text-transform: none;
    transition: background-color .12s ease, color .12s ease, border-color .12s ease;
}

.tiles a.tile:hover .title::after,
.tiles a.tile:focus-visible .title::after {
    background: var(--csh-green);
    border-color: var(--csh-green);
    color: #FFFFFF;
}
.tiles a.tile .stat  { font-weight: 700; color: var(--csh-heading); }
.tiles a.tile .title { font-size: .875rem; color: var(--csh-mute); }

.tiles a.tile .highlight.bg-color-blue  { background-color: var(--csh-green-deep); }
.tiles a.tile .highlight.bg-color-green { background-color: var(--csh-green); }
.tiles a.tile .highlight.bg-color-gold  { background-color: var(--csh-attention); }
.tiles a.tile .highlight.bg-color-red   { background-color: var(--csh-urgent); }

/* If the highlight carries text, keep it dark on the light green. */
.tiles a.tile .highlight.bg-color-green { color: var(--csh-dark); }

/* --------------------------------------------------------------------------
   7. CARDS
   -------------------------------------------------------------------------- */

.card {
    background: var(--csh-surface);
    border: 1px solid var(--csh-line);
    border-radius: var(--csh-radius);
    box-shadow: var(--csh-shadow);
    margin-bottom: 1.5rem;
}

.card-header { background: transparent; border-bottom: 1px solid var(--csh-line); padding: 1rem 1.25rem; }

.card .card-title {
    font-weight: 700;
    font-size: .875rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--csh-mute);
    margin-bottom: 0;
}

.card-body   { padding: 1.25rem; }
.card-footer { background: transparent; border-top: 1px solid var(--csh-line); }

.client-home-cards .card,
.card[class*="card-accent-"] { border-left-width: var(--csh-rail); }

.card-accent-blue  { border-left-color: var(--csh-green-deep); }
.card-accent-green { border-left-color: var(--csh-green); }
.card-accent-gold  { border-left-color: var(--csh-attention); }
.card-accent-red   { border-left-color: var(--csh-urgent); }

.card .list-group-item-action { color: var(--csh-body); }
.card .list-group-item-action:hover,
.card .list-group-item-action:focus { background: var(--csh-green-wash); }

/* --------------------------------------------------------------------------
   8. BUTTONS

   Primary is white on brand green, matching the marketing site.
   Measured 1.63:1. Text is weighted heavier and targets enlarged to
   compensate as far as colour-independent means allow.
   -------------------------------------------------------------------------- */

.btn {
    font-weight: 600;
    border-radius: var(--csh-radius);
    padding: .5625rem 1.25rem;
    min-height: 44px;
    transition: background-color .12s ease, border-color .12s ease;
}

.btn-primary {
    background-color: var(--csh-green);
    border-color: var(--csh-green);
    color: #FFFFFF;
    font-weight: 700;
}

.btn-primary:hover,
.btn-primary:focus,
.btn-primary:not(:disabled):not(.disabled):active {
    background-color: var(--csh-green-hover);
    border-color: var(--csh-green-hover);
    color: #FFFFFF;
}

.btn-default,
.btn-secondary {
    background-color: var(--csh-surface);
    border-color: var(--csh-line);
    color: var(--csh-heading);
}

/* .btn-success was the deep green reserved for link text, so Update and
   Register rendered olive while Login rendered brand green — the same
   action in two colours for no reason. One green for actions. */
.btn-success {
    background-color: var(--csh-green);
    border-color: var(--csh-green);
    color: #FFFFFF;
    font-weight: 700;
}
.btn-success:hover,
.btn-success:focus,
.btn-success:not(:disabled):not(.disabled):active {
    background-color: var(--csh-green-hover);
    border-color: var(--csh-green-hover);
    color: #FFFFFF;
}

.btn-danger  { background-color: var(--csh-urgent);    border-color: var(--csh-urgent); }
.btn-warning { background-color: var(--csh-attention); border-color: var(--csh-attention); color: #fff; }

.btn-link { color: var(--csh-green-deep); }

/* --------------------------------------------------------------------------
   9. TABLES
   -------------------------------------------------------------------------- */

.table { background: var(--csh-surface); color: var(--csh-body); }

.table thead th {
    background: transparent;
    border-bottom: 2px solid var(--csh-line);
    border-top: 0;
    font-size: .8125rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--csh-mute);
    white-space: nowrap;
}

.table td { border-top: 1px solid var(--csh-line); padding: .875rem .75rem; vertical-align: middle; }
.table-hover tbody tr:hover { background: var(--csh-green-wash); }

/* --------------------------------------------------------------------------
   10. BADGES — light fills with dark text, so the green stays readable
   -------------------------------------------------------------------------- */

.badge {
    font-size: .8125rem;
    font-weight: 700;
    padding: .3125rem .625rem;
    border-radius: 100px;
    border: 1px solid transparent;
}

.badge-success { background: var(--csh-green-wash); border-color: rgba(78,125,22,.3);  color: var(--csh-green-deep); }
.badge-warning { background: #F7EFE4;               border-color: rgba(168,100,26,.3); color: var(--csh-attention); }
.badge-danger  { background: #F6E9E8;               border-color: rgba(166,50,47,.3);  color: var(--csh-urgent); }
.badge-info    { background: #EEEEEE;               border-color: rgba(87,87,96,.3);   color: var(--csh-mute); }

/* --------------------------------------------------------------------------
   11. FORMS
   -------------------------------------------------------------------------- */

.form-control,
.custom-select {
    border: 1px solid #CCCCCC;
    border-radius: var(--csh-radius);
    padding: .5625rem .75rem;
    color: var(--csh-heading);
    background-color: #FAFAFA;
    min-height: 44px;
}

.form-control:focus,
.custom-select:focus {
    background-color: var(--csh-surface);
    border-color: var(--csh-dark);
    box-shadow: var(--csh-focus);
}

label      { font-weight: 700; font-size: .9375rem; color: var(--csh-heading); margin-bottom: .375rem; }
.form-text { color: var(--csh-mute); font-size: .9375rem; }

.input-group-merge .input-group-text {
    background: #FAFAFA;
    border-color: #CCCCCC;
    color: var(--csh-mute);
}

/* --------------------------------------------------------------------------
   12. ALERTS
   -------------------------------------------------------------------------- */

.alert {
    border: 1px solid var(--csh-line);
    border-left: var(--csh-rail) solid var(--csh-line);
    border-radius: var(--csh-radius);
    padding: 1rem 1.125rem;
}

.alert-success { background: var(--csh-green-wash); border-left-color: var(--csh-green);     color: #2F4D10; }
.alert-warning { background: #F7EFE4;               border-left-color: var(--csh-attention); color: #6E410F; }
.alert-danger  { background: #F6E9E8;               border-left-color: var(--csh-urgent);    color: #71211F; }
.alert-info    { background: #F4F4F4;               border-left-color: var(--csh-mute);      color: var(--csh-body); }

/* --------------------------------------------------------------------------
   13. LOGIN — login.tpl, .card.mw-540 (WHMCS utility, not Bootstrap)
   -------------------------------------------------------------------------- */

.login-form .card.mw-540 {
    border: 1px solid var(--csh-line);
    border-radius: var(--csh-radius);
    box-shadow: var(--csh-shadow);
}
.login-form #inputEmail,
.login-form #inputPassword { min-height: 46px; }
.login-form #login { width: 100%; font-weight: 700; }
.login-form .btn-reveal-pw {
    background: #FAFAFA;
    border-color: #CCCCCC;
    color: var(--csh-mute);
}
.login-form .card-footer { background: transparent; }
.providerLinkingFeedback:empty { display: none; }

/* --------------------------------------------------------------------------
   14. FOOTER
   -------------------------------------------------------------------------- */

/* A footer on a billing portal is a legal necessity, not a destination.
   The dark slab competed with the sidebar for attention. */
html body #footer.footer {
    background: transparent;
    border-top: 1px solid var(--csh-line);
    color: var(--csh-mute);
    font-size: .875rem;
    padding-top: 1rem;
    padding-bottom: 1rem;
    margin-top: 2rem;
}

/* Links and copyright on one line. */
#footer.footer > .container {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .5rem 1.5rem;
}

#footer.footer ul.nav,
#footer.footer ul.list-inline {
    margin-bottom: 0 !important;
    float: none !important;
    text-align: left !important;
}

#footer.footer .nav-link   { color: var(--csh-mute); padding: 0 1rem 0 0; }
#footer.footer .nav-link:hover,
#footer.footer a:hover     { color: var(--csh-green-deep); }
#footer.footer p.copyright { color: var(--csh-mute); margin-bottom: 0; }

/* --------------------------------------------------------------------------
   15. MODALS
   -------------------------------------------------------------------------- */

#modalAjax .modal-content,
#modalChooseLanguage .modal-content {
    border: 0;
    border-radius: var(--csh-radius);
    box-shadow: 0 12px 40px rgba(0,0,0,.25);
}
#modalChooseLanguage .item-selector .item:hover { background: var(--csh-green-wash); }

/* --------------------------------------------------------------------------
   16. PRINT
   -------------------------------------------------------------------------- */

@media print {
    #header, #footer, nav.master-breadcrumb, .sidebar,
    .btn, #modalAjax, #modalChooseLanguage, #fullpage-overlay { display: none !important; }

    nav.master-breadcrumb, #main-body, #footer.footer { margin-left: 0; }

    body, body.primary-bg-color {
        padding-left: 0;
        background: #fff;
        color: #000;
        font-size: 11pt;
    }

    .card { border: 1px solid #999; border-left-width: 1px; box-shadow: none; break-inside: avoid; }
}

/* --------------------------------------------------------------------------
   17. VERIFY ON FIRST LOAD

   The sidebar rewrites Bootstrap's navbar layout, which is the highest-risk
   part of this file. Check these four before switching the live theme:

   1. Sidebar scrolls independently when the nav is long
   2. Account dropdown at the bottom opens inline, not off-screen
   3. Nothing is hidden behind the fixed column at exactly 1200px
   4. At 1199px the stock horizontal header returns intact
   -------------------------------------------------------------------------- */


/* ==========================================================================
   18. CONTEXTUAL PANELS AS A TOOLBAR

   header.tpl puts $primarySidebar in a .col-lg-4.col-xl-3 beside the
   content. A second vertical column competing with the main navigation is
   what stopped this reading as a dashboard.

   Flipping the layout row to a column moves that band above the content at
   full width — the conventional toolbar position — with no template
   override. The cart renders its own sidebar from
   orderforms/standard_cart/sidebar-categories.tpl, but both emit
   .card-sidebar, so the styling below reaches each of them.

   Panels carry no name-derived class. The only thing distinguishing
   Categories from Actions is the non-standard menuItemName attribute, which
   is a perfectly valid CSS attribute selector.
   ========================================================================== */

@media (min-width: 1200px) {

    /* Three columns: fixed nav (#header) | fluid centre | 340px rail.

       header.tpl emits the sidebar column BEFORE .primary-content, so
       `order` flips them without touching the template. Bootstrap's
       .col-* widths must be neutralised or they fight the grid.

       align-items:start keeps the rail cards at their natural height
       instead of stretching to match the centre column. */
    #main-body > div > .row {
        display: grid;
        grid-template-columns: minmax(0, 1fr) 340px;
        gap: 1.5rem;
        align-items: start;
    }

    #main-body > div > .row > .primary-content {
        order: 1;
        flex: none;
        width: auto;
        max-width: none;
        padding-left: 0;
        padding-right: 0;
    }

    #main-body > div > .row > .col-lg-4.col-xl-3 {
        order: 2;
        flex: none;
        width: auto;
        max-width: none;
        display: block;
        padding-left: 0;
        padding-right: 0;
    }

    /* Panels stack down the rail, one under another. */
    #main-body > div > .row > .col-lg-4.col-xl-3 > .sidebar {
        margin-bottom: 1.25rem;
    }
    #main-body > div > .row > .col-lg-4.col-xl-3 > .sidebar:last-child {
        margin-bottom: 0;
    }
}

/* Below 1200px the nav is a horizontal bar, so a third column has nothing
   to be third to. Bootstrap's stock two-column behaviour returns: panels
   beside the content at lg, stacked beneath it on tablet and phone. */

/* Panel chrome, all breakpoints ------------------------------------------ */

/* Rail panels sit on a light grey, not white. The main content card is
   white and the page canvas is #EFEFEF; putting the rail between the two
   separates "what you are working on" from "where else you can go" without
   adding another border or shadow. */
.card-sidebar {
    border: 1px solid var(--csh-line);
    border-radius: var(--csh-radius);
    box-shadow: var(--csh-shadow);
    background: var(--csh-surface-2);
}

.card-sidebar > .card-header { background: transparent; }

/* Nothing in a 340px rail may push the column wider than it is.

   Long ticket subjects were overflowing rather than wrapping — "#610307 —
   Our wealth management domain nam…" ran off the right edge, taking its
   timestamp with it. A flex or grid child defaults to min-width:auto, which
   refuses to shrink below its content, so the min-width:0 below is what
   actually allows the wrap to happen. */
.card-sidebar,
.card-sidebar .card-body,
.card-sidebar .list-group,
.card-sidebar .list-group-item,
.card-sidebar .sidebar-menu-item-wrapper,
.card-sidebar .sidebar-menu-item-label {
    min-width: 0;
}

.card-sidebar .card-body,
.card-sidebar .list-group-item,
.card-sidebar .sidebar-menu-item-label {
    overflow-wrap: anywhere;
    word-break: break-word;
    white-space: normal;
}

.card-sidebar > .card-header {
    padding: .75rem 1rem;
    border-bottom: 1px solid var(--csh-line);
}

.card-sidebar .card-title {
    font-size: .8125rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--csh-mute);
}

.card-sidebar .card-minimise { color: var(--csh-mute); font-size: .75rem; }

/* Rail panels read as a menu: full-width rows, one per line.

   These were chips while the panels sat in a horizontal toolbar band above
   the content, where a wrapping row made sense. In the right-hand rail they
   read as tags instead — and people do not click tags. A stacked list says
   "these are places you can go" without anyone having to work it out.

   Rows are separated by a hairline rather than boxed, so the panel reads as
   one list rather than a stack of separate controls. */
@media (min-width: 992px) {

    .card-sidebar .list-group {
        flex-direction: column;
        flex-wrap: nowrap;
        gap: 0;
        padding: 0;
    }

    .card-sidebar .list-group-item {
        flex: 1 1 auto;
        width: 100%;
        display: block;
        border: 0;
        border-top: 1px solid var(--csh-line);
        border-radius: 0;
        padding: .75rem 1rem;
        min-height: 44px;
        font-size: .9375rem;
        color: var(--csh-body);
        background: transparent;   /* let the panel's grey show through */
        text-decoration: none;
    }

    /* The card header already draws the line above the first row. */
    .card-sidebar .list-group-item:first-child { border-top: 0; }

    .card-sidebar .list-group-item:hover,
    .card-sidebar .list-group-item:focus {
        background: var(--csh-green-wash);
        color: var(--csh-heading);
    }

    /* Current page: a green rail on the left edge, plus a weight change so
       the state is not carried by colour alone. */
    .card-sidebar .list-group-item.active {
        background: var(--csh-green-wash);
        color: var(--csh-heading);
        font-weight: 600;
        box-shadow: inset var(--csh-rail) 0 0 var(--csh-green);
    }

    .card-sidebar .list-group-item.disabled { opacity: .5; }

    .card-sidebar .sidebar-menu-item-wrapper {
        display: flex;
        align-items: center;
        gap: .625rem;
    }
    .card-sidebar .sidebar-menu-item-icon-wrapper {
        display: inline-flex;
        justify-content: center;
        width: 1.125rem;
        color: var(--csh-mute);
    }
    .card-sidebar .sidebar-menu-item-label { white-space: normal; }
    .card-sidebar .sidebar-menu-item-badge { margin-left: auto; }
}

/* --------------------------------------------------------------------------
   19. TYPE SCALE — one set of sizes across base and store pages
   -------------------------------------------------------------------------- */

#main-body h1 { font-size: 1.875rem; margin-bottom: .5rem; }
#main-body h2 { font-size: 1.375rem; }
#main-body h3 { font-size: 1.125rem; }
#main-body h4,
#main-body h5 { font-size: 1rem; }

#main-body .lead,
#main-body .header-lined + p { font-size: 1rem; color: var(--csh-mute); }

#main-body .nav-tabs .nav-link {
    color: var(--csh-mute);
    font-weight: 600;
    border-radius: var(--csh-radius) var(--csh-radius) 0 0;
}
#main-body .nav-tabs .nav-link.active { color: var(--csh-heading); }


/* --------------------------------------------------------------------------
   20. COLLAPSIBLE PANELS — pairs with includes/hooks/cshUiEnhancements.php

   The chevron has no rule in the parent's theme.css at all, so there has
   never been a visual difference between an open and a closed panel beyond
   the body vanishing. These add the missing indicator and give the header
   row the affordance the JS now grants it.
   -------------------------------------------------------------------------- */

.card-header:has(~ .collapsable-card-body),
.card:has(.card-minimise) > .card-header {
    cursor: pointer;
    user-select: none;
}

.card:has(.card-minimise) > .card-header:hover { background-color: var(--csh-green-wash); }

.card-header[role="button"]:focus-visible {
    outline: 2px solid var(--csh-dark);
    outline-offset: -2px;
}

/* Chevron points up when open, down when closed. */
.card-minimise {
    transition: transform .15s ease;
    padding: .375rem;
    margin: -.375rem;
}
.card-minimise.minimised { transform: rotate(180deg); }


/* --------------------------------------------------------------------------
   21. MENU GROUPS AND NOTIFICATIONS

   Group headings are drawn with ::before rather than added as menu entries.
   A real entry would sit in the tab order and be announced as a link, and a
   heading is neither focusable nor a link. The classes come from the
   priority-1 pass in clientNavigation.php.
   -------------------------------------------------------------------------- */

@media (min-width: 1200px) {

    #header .navbar-nav > li[class*="csh-group-"] { margin-top: 1.75rem; }

    /* Headings were too small to function as headings, and sat further left
       than the items below them because the nav-link carries a 3px rail the
       ::before does not. Matching that offset lines them up. */
    #header .navbar-nav > li[class*="csh-group-"]::before {
        display: block;
        padding: 0 .875rem .5rem calc(.875rem + var(--csh-rail));
        font-size: .8125rem;
        font-weight: 700;
        letter-spacing: .08em;
        text-transform: uppercase;
        color: rgba(255,255,255,.55);
        pointer-events: none;
    }

    #header .navbar-nav > li.csh-group-manage::before   { content: "Manage"; }
    #header .navbar-nav > li.csh-group-support::before  { content: "Support"; }
    #header .navbar-nav > li.csh-group-projects::before { content: "Projects"; }

    /* The first group needs no gap — the account block above it already
       provides the separation. Support now leads. */
    #header .navbar-nav > li.csh-group-support { margin-top: .25rem; }

    /* Sub-items of an always-open menu are secondary, not equal. */
    #header .navbar-nav > li > .dropdown-menu .dropdown-item { font-size: .9375rem; }
}

/* Notifications. The flag is the indicator — colouring it red is what makes
   it read as something needing attention rather than a label. */
#header #accountNotifications .fa-flag,
#header #accountNotifications .far,
#header #accountNotifications .fas {
    color: var(--csh-urgent);
}

#header #accountNotifications {
    font-weight: 600;
    color: var(--csh-on-dark);
}

/* ==========================================================================
   APPEND THIS TO THE END OF custom.css — do not replace the file.
   The Support-open rule from commit 2cc60e7 must survive.
   ========================================================================== */

/* --------------------------------------------------------------------------
   22. OTHER PROPERTIES — pairs with CSH_EXTERNAL_LINKS in clientNavigation.php

   These leave the portal, so they are set apart from the working menu above
   rather than sitting among it. Quieter by default, and marked with an
   outbound arrow so nobody clicks one mid-task expecting to stay put.
   -------------------------------------------------------------------------- */

@media (min-width: 1200px) {

    #header .navbar-nav > li.csh-group-more::before { content: "More from us"; }

    #header .navbar-nav > li.csh-external > .nav-link {
        color: #B8B8B8 !important;
        font-weight: 400;
    }

    #header .navbar-nav > li.csh-external > .nav-link:hover,
    #header .navbar-nav > li.csh-external > .nav-link:focus {
        color: #FFFFFF !important;
    }

    /* Outbound marker. Content is decorative, so it is hidden from assistive
       technology — target="_blank" is already announced by screen readers. */
    #header .navbar-nav > li.csh-external > .nav-link::after {
        content: "↗";
        margin-left: .375rem;
        font-size: .8125rem;
        opacity: .55;
        speak: never;
    }
}

/* --------------------------------------------------------------------------
   23. DASHBOARD QUICK ACTIONS — pairs with cshUiEnhancements.php

   Inserted after .tiles on the client area home page. Two actions, one
   obvious: raise a ticket, or go to the ones you already have.

   The primary button uses DARK text on brand green, not white. White on
   #96DF37 measures 1.63:1, under every WCAG threshold; #2C2C2C on the same
   green is 8.58:1. Same colour, readable label — this is what the cart
   badge already does.
   -------------------------------------------------------------------------- */

.csh-quick-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
    margin: 0 0 1.5rem;
}

.csh-quick-actions .btn {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    min-height: 44px;
}

.csh-quick-actions .csh-qa-primary,
.csh-quick-actions .csh-qa-primary:link,
.csh-quick-actions .csh-qa-primary:visited {
    background-color: var(--csh-green);
    border-color: var(--csh-green);
    color: var(--csh-dark);
    font-weight: 700;
}

.csh-quick-actions .csh-qa-primary:hover,
.csh-quick-actions .csh-qa-primary:focus {
    background-color: var(--csh-green-hover);
    border-color: var(--csh-green-hover);
    color: var(--csh-dark);
}

.csh-quick-actions .csh-qa-secondary,
.csh-quick-actions .csh-qa-secondary:link,
.csh-quick-actions .csh-qa-secondary:visited {
    background-color: var(--csh-surface);
    border-color: var(--csh-line);
    color: var(--csh-heading);
    font-weight: 600;
}

.csh-quick-actions .csh-qa-secondary:hover,
.csh-quick-actions .csh-qa-secondary:focus {
    border-color: var(--csh-green-deep);
    color: var(--csh-heading);
}
