/* *****************************************************

    ** Custom Stylesheet **

    Any custom styling you want to apply should be
    defined here.

***************************************************** */

/* Custom CSS for Nexus Theme
 *
 * This file allows you to customize the theme colors and styles for the entire Nexus template.
 *
 * To customize colors:
 * - Replace the var() references with your own hex colors or other CSS values.
 * - For example, instead of --primary: #4b5563; use --primary: #your-color;
 * - You can also override any CSS properties here.
 */

:root {
    --white: #fff;

    /* Neutral shades */
    --neutral-50: #fbf9fa;
    --neutral-100: #f4f5f7;
    --neutral-200: #e4e4e7;
    --neutral-300: #d0d5dd;
    --neutral-400: #9ca3af;
    --neutral-500: #6b7280;
    --neutral-600: #4b5563;
    --neutral-700: #374151;
    --neutral-800: #1f2937;
    --neutral-900: #111827;
    --neutral-950: #030712;

    /* Neutral shades */
    /* define own pallet with brand colors */
    --primary-50: var(--neutral-50);
    --primary-100: var(--neutral-100);
    --primary-200: var(--neutral-200);
    --primary-300: var(--neutral-300);
    --primary-400: var(--neutral-400);
    --primary-500: var(--neutral-500);
    --primary-600: var(--neutral-600);
    --primary-700: var(--neutral-700);
    --primary-800: var(--neutral-800);
    --primary-900: var(--neutral-900);
    --primary-950: var(--neutral-900);

    /* Primary colors: AOIT Cloud brand green (matches aoitcloud.com --color-brand) */
    --primary: #1F7A3E;
    --primary-lifted: #195F31;
    --primary-accented: #12461F;

    /* Secondary colors */
    --secondary: var(--neutral-500);
    --secondary-lifted: var(--neutral-600);
    --secondary-accented: var(--neutral-700);

    /* Success colors */
    --success: #1F7A3E;
    --success-lifted: #195F31;
    --success-accented: #12461F;

    /* Info colors — real aoitcloud.com blue (--color-blue),
       verified against src/input.css line 32 */
    --info: #2A5FA5;
    --info-lifted: #1F477E;
    --info-accented: #163457;

    /* Notice colors — real aoitcloud.com purple
       (--color-purple), verified against input.css line 42 */
    --notice: #6B4FA0;
    --notice-lifted: #543D80;
    --notice-accented: #3D2C5C;

    /* Warning colors — real aoitcloud.com amber
       (--color-amber), verified against input.css line 37 */
    --warning: #92610A;
    --warning-lifted: #744C08;
    --warning-accented: #573906;

    /* Error colors — real aoitcloud.com red (--color-red),
       verified against input.css line 51 */
    --error: #A13A2E;
    --error-lifted: #832F25;
    --error-accented: #66241C;

    /* Grayscale colors */
    --grayscale: var(--neutral-900);
    --grayscale-lifted: var(--neutral-800);
    --grayscale-accented: var(--neutral-700);

    /* Neutral colors */
    --neutral: var(--neutral-500);
    --neutral-lifted: var(--neutral-600);
    --neutral-accented: var(--neutral-700);

    /* Text neutral colors: aoitcloud.com --color-ink family */
    --text-inverted: var(--white);
    --text-muted: #6B6E63;
    --text-lifted: #55584C;
    --text-accented: #33352C;
    --text: #14160F;

    /* Border neutral colors: aoitcloud.com --color-line family */
    --border-muted: #E4E4E7;
    --border: #D0D5DD;
    --border-lifted: #282F38;
    --border-accented: #282F38;

    /* Background neutral colors: aoitcloud.com --color-bg family */
    --bg: #FFFFFF;
    --bg-muted: #F6F7F9;
    --bg-lifted: #F6F7F9;
    --bg-accented: var(--neutral-200);
    --bg-inverted: #14160F;

    /* Additional colors */
    --yellow-200: #fff085;
    --yellow-300: #ffdf20;
    --teal-300: #46edd5;
    --teal-400: #00d5be;
    --emerald-300: #5ee9b5;
    --pink-400: #fb64b6;

    /* Additional custom properties */
    /* Font sizes */
    --text-xs: 0.625rem;
    --text-sm: 0.75rem;
    --text-md: 0.875rem;
    --text-lg: 1rem;

    /* Spacing */
    --outline-sm: 1px;
    --outline-md: 2px;
    --outline-lg: 3px;

    /* Rounding */
    --rounding-sm: 0.25rem;
    --rounding-md: 0.5rem;
    --rounding-lg: 0.75rem;

    /* Other */
    --letter-spacing: 0em;
    --disabled-opacity: 25%;
}

/* *****************************************************

    ** AOIT Cloud brand overrides **

    Nexus/Bootstrap 4.5.3 ships as PRE-COMPILED CSS
    (theme.css / all.css), not built from Sass at request
    time — no gulp/sass toolchain ships with this template
    package, so the ":root" variables above are only
    consumed by a handful of newer Nexus components
    (e.g. .card-accent-*). The actual buttons, links,
    badges, pagination, form focus states, etc. are
    hardcoded Bootstrap-blue hex values (#007bff and
    friends) baked into theme.css.

    Since this file loads LAST (see includes/head.tpl),
    plain same-specificity overrides here win the cascade
    without needing a rebuild step. If a future AOIT theme
    change moves to a real Sass build, these can be
    replaced by overriding Bootstrap's $primary variable
    at compile time instead.

    Brand source of truth: aoitcloud.com theme
    (wp-content/themes/aoit-cloud/src/input.css)
    --color-brand: #1F7A3E / --color-brand-hover: #195F31

***************************************************** */

:root {
    --aoit-brand: #1F7A3E;
    --aoit-brand-hover: #195F31;
    --aoit-brand-active: #12461F;
    --aoit-focus-ring: rgba(31, 122, 62, 0.35);
    --aoit-ink: #14160F;
    --aoit-ink-soft: #55584C;
    /* src/input.css line 18. The WordPress footer uses this, not ink-soft,
       for the address block, the column headings and the bottom bar. */
    --aoit-ink-faint: #6B6E63;
    --aoit-line: #282F38;
    --aoit-bg-soft: #F6F7F9;
    /* Brand blue, verified against src/input.css --color-blue (#2A5FA5);
       hover is the same value darkened, matching --info-lifted above. */
    --aoit-blue: #2A5FA5;
    --aoit-blue-hover: #1F477E;
    /* Accent cyan, verified against src/input.css line 26 (--color-icon) and
       its link-hover shade at line 304. This is the colour aoitcloud.com uses
       for the hover border on every card — "hover:border-icon hover:shadow-sm"
       appears on 9 and 6 elements respectively. It is NOT brand green: green
       is reserved for hover:bg-brand-hover, which is buttons only. */
    --aoit-icon: #1CA4DB;
    --aoit-icon-hover: #1683AF;
    /* Tailwind's shadow-sm, which is what those cards pair with the border.
       This is v4's two-layer value, measured from the LIVE compiled
       aoitcloud.com stylesheet — the older single-layer 0.05 value came from
       the design doc and no longer matches what the marketing site renders. */
    --aoit-shadow-sm: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1);
    --success-soft: #EAF6EA;
    --error-soft: #FBEAE7;
    --warning-soft: #FBF0DE;
    --info-soft: #E8F0FA;
    --notice-soft: #F1EDFB;
}

/* Typography: system font stack only, no embedded webfonts
   (aoitcloud.com policy, low page-weight goal) */
body,
.btn,
input,
select,
textarea,
.form-control,
.custom-select {
    font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif !important;
}
/* MarketConnect landing pages (store.css) declare their own faces directly
   on elements — "Open Sans" with a Verdana/serif fallback that actually
   rendered, since no webfont loads. Same stack as everywhere else. The
   !important + body prefix wins whether store.css loads before or after
   this file. */
body .landing-page.sitelockvpn .hero h2,
body .landing-page.marketgoo .testimonials .testimonial,
body .landing-page.nordvpn,
body .landing-page.threesixtymonitoring {
    font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif !important;
}

/* The page's own ground and default ink. theme.css paints html/body with
   var(--bg-inverted) — near-black — which showed on rubber-band overscroll
   past the white footer; and body text fell back to Bootstrap's #212529
   instead of the ink token wherever nothing more specific applied. */
html,
body {
    background-color: #fff;
}
body {
    color: var(--aoit-ink);
}

/* Input group addons (the icons on login, the currency/TLD prefixes on the
   order form) sit flush against a field, so they have to carry the same
   hairline. Left on Bootstrap's #ced4da they read as a seam of a different
   colour running down the middle of every field. */
.input-group-text {
    border: 1px solid var(--aoit-line);
    border-radius: 6px;
    background-color: var(--aoit-bg-soft);
    color: var(--aoit-ink-soft);
    font-size: 15px;
    padding: 10px 14px;
}
.input-group > .input-group-prepend > .btn,
.input-group > .input-group-append > .btn {
    border-color: var(--aoit-line);
}

/* Links. The default is the accent cyan, matching the marketing site's
   design rule: content/navigation links are the cyan icon token, and green
   is reserved for filled commit actions (buttons). Anything that should be
   green (the kb back link, promo footers, announcement titles) sets it
   explicitly and is unaffected by this default. */
a {
    color: var(--aoit-icon);
}
a:hover {
    color: var(--aoit-icon-hover);
}
/* Long-form prose contexts underline their links, same as .legal-prose /
   .post-prose on aoitcloud.com (the knowledgebase body already does this
   further down). Chrome links — nav, footer, buttons — stay bare. */
.aoit-ticket-message a,
.announcements .announcement article a {
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* Primary buttons */
.btn-primary {
    background-color: var(--aoit-brand);
    border-color: var(--aoit-brand);
}
.btn-primary:hover {
    background-color: var(--aoit-brand-hover);
    border-color: var(--aoit-brand-hover);
}
.btn-primary:focus,
.btn-primary.focus {
    background-color: var(--aoit-brand-hover);
    border-color: var(--aoit-brand-hover);
    box-shadow: 0 0 0 0.2rem var(--aoit-focus-ring);
}
.btn-primary.disabled,
.btn-primary:disabled {
    background-color: var(--aoit-brand);
    border-color: var(--aoit-brand);
}
.btn-primary:not(:disabled):not(.disabled):active,
.btn-primary:not(:disabled):not(.disabled).active,
.show > .btn-primary.dropdown-toggle {
    background-color: var(--aoit-brand-active);
    border-color: var(--aoit-brand-active);
}
.btn-primary:not(:disabled):not(.disabled):active:focus,
.btn-primary:not(:disabled):not(.disabled).active:focus,
.show > .btn-primary.dropdown-toggle:focus {
    box-shadow: 0 0 0 0.2rem var(--aoit-focus-ring);
}

/* Outline buttons: the marketing site's SECONDARY button — a 1px
   --color-line border with ink text (see the non-featured pricing-card CTA,
   "border border-line" + ink) — not a second primary. The old green-outline
   treatment filled solid green on hover, which made it read as another
   primary button. Hover matches the site's card affordance instead: the
   border moves to the accent cyan with a soft-grey fill. */
.btn-outline-primary,
body #main-body .btn-outline-primary {
    /* theme.css has its own "body #main-body .btn-outline-primary" rule
       (an ID selector, high specificity) that overrides a plain class
       rule regardless of load order — has to be matched exactly, not
       just declared once, or it silently loses on any page whose
       content sits inside #main-body (i.e. every page). */
    color: var(--aoit-ink);
    border-color: var(--aoit-line);
    background-color: transparent;
    border-radius: 6px;
}
.btn-outline-primary:hover,
body #main-body .btn-outline-primary:hover {
    background-color: var(--aoit-bg-soft);
    border-color: var(--aoit-icon);
    color: var(--aoit-ink);
}
.btn-outline-primary:focus,
.btn-outline-primary.focus {
    box-shadow: 0 0 0 0.2rem var(--aoit-focus-ring);
}

/* Text links styled as buttons */
.btn-link {
    color: var(--aoit-brand);
}
.btn-link:hover {
    color: var(--aoit-brand-hover);
}

/* Dropdowns */
.dropdown-item.active,
.dropdown-item:active {
    background-color: var(--aoit-brand);
}

/* Checkboxes, radios, switches */
.custom-control-input:checked ~ .custom-control-label::before {
    background-color: var(--aoit-brand);
    border-color: var(--aoit-brand);
}

/* Range slider */
.custom-range::-webkit-slider-thumb {
    background-color: var(--aoit-brand);
}
.custom-range::-moz-range-thumb {
    background-color: var(--aoit-brand);
}
.custom-range::-ms-thumb {
    background-color: var(--aoit-brand);
}

/* Nav pills (used in client-area sub-navigation) */
.nav-pills .nav-link.active,
.nav-pills .show > .nav-link {
    background-color: var(--aoit-brand);
}

/* Pagination */
.page-link {
    color: var(--aoit-brand);
}
.page-item.active .page-link {
    background-color: var(--aoit-brand);
    border-color: var(--aoit-brand);
}

/* Badges: .badge-primary is styled once, in the soft-tint block further
   down with the other badge colours (a solid-green duplicate here used to
   shadow it). */

/* List groups (e.g. account settings sidebar) */
.list-group-item.active {
    background-color: var(--aoit-brand);
    border-color: var(--aoit-brand);
}

/* Utility classes */
.bg-primary {
    background-color: var(--aoit-brand) !important;
}
.border-primary {
    border-color: var(--aoit-brand) !important;
}
.text-primary {
    color: var(--aoit-brand) !important;
}

/* Form fields, taken from the contact form on aoitcloud.com
   (plugins/aoit-contact-form/blocks/contact-form/render.php):

       w-full border border-line rounded-md px-3.5 py-2.5 text-[15px]
       bg-bg focus:outline-none focus:ring-2 focus:ring-brand

   The border is --color-line (#282F38), NOT a light grey. That dark hairline
   is a large part of how the marketing site's forms read, and a light grey
   border was the main reason these did not match. rounded-md is 6px,
   px-3.5/py-2.5 is 14px/10px, and focus is a 2px brand ring with the outline
   suppressed rather than Bootstrap's soft glow. */
.form-control,
.custom-select {
    border: 1px solid var(--aoit-line);
    border-radius: 6px;
    padding: 10px 14px;
    font-size: 15px;
    height: auto;
    background-color: #fff;
}
/* A <select> styled as .custom-select has appearance:none and draws its own
   chevron as a background image at the right edge, with Bootstrap reserving
   room for it via padding-right: 1.75rem. The shorthand above replaces that
   padding, so the text ran underneath the arrow: DataTables' "Show 10
   entries" control measured 17px of content box for 16px of text, i.e. no
   clearance at all. Longhand right padding, wide enough for the chevron plus
   the same 14px gutter the other side has. Plain selects are included too:
   they keep appearance:auto and draw a native arrow, which the browser places
   inside whatever right padding there is rather than reserving its own. */
.custom-select,
select.form-control {
    padding-right: 32px;
}
.form-control:focus,
.custom-select:focus {
    outline: 0;
    border-color: var(--aoit-line);
    box-shadow: 0 0 0 2px var(--aoit-brand);
}

/* *****************************************************

    ** AOIT header wordmark + footer **

    Matches wp-content/themes/aoit-cloud/header.php and
    footer.php as closely as Bootstrap 4 utility classes
    allow. No logo image yet (per Andrew, 2026) — the
    wordmark is the same two-circle SVG mark + "aoitcloud"
    text used on the WordPress site, not the WHMCS
    $companyname (that stays as the legal entity name
    everywhere else in the theme, e.g. invoices/<title>).

***************************************************** */

/* Measured against header.php: "flex items-center gap-2.5 font-bold
   text-[18px] tracking-tight" — gap-2.5 is 10px and tracking-tight is
   -0.025em, not the -0.01em that was here. */
.aoit-wordmark {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-weight: 700;
    font-size: 18px;
    letter-spacing: -0.025em;
    color: var(--aoit-ink);
    line-height: 1;
}
/* Not "inherit": .navbar-brand carries Bootstrap's #444, so inheriting made
   the header wordmark #444444 while the footer one was --aoit-ink. WordPress
   puts "text-ink" on <body> and the brand link sets no colour of its own, so
   it renders #14160F — which is what this should be too. Found while
   measuring the header to build the logo SVG. */
.navbar-brand .aoit-wordmark {
    color: var(--aoit-ink);
}

/* Dark CTA band, matches the WordPress footer's "Get in touch" section */
.aoit-cta-band {
    background: #101208;
    color: #fff;
    border-top: 1px solid #3A4250;
    text-align: center;
    padding: 64px 20px;
    /* holds the ::before grid below */
    position: relative;
}
/* The same line-grid texture the marketing site puts on this band
   (.cta-grid in wp-content/themes/aoit-cloud/src/input.css): full coverage,
   no fade, light grey at 12% so it reads as texture rather than a pattern
   competing with the text sitting on it. */
.aoit-cta-band::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(rgba(200, 200, 200, 0.12) 1px, transparent 1px),
        linear-gradient(90deg, rgba(200, 200, 200, 0.12) 1px, transparent 1px);
    background-size: 28px 28px;
    pointer-events: none;
}
.aoit-cta-inner {
    max-width: 640px;
    margin: 0 auto;
    /* above the grid, matching the "relative z-10" wrapper on the
       WordPress band */
    position: relative;
    z-index: 1;
}
.aoit-cta-eyebrow {
    font-size: 12px;
    font-weight: 600;
    /* tracking-wide = 0.025em, same as .aoit-footer-heading below — 0.05em
       was double the WordPress value here too. */
    letter-spacing: 0.025em;
    text-transform: uppercase;
    color: #8C9086;
    margin-bottom: 12px;
}
.aoit-cta-heading {
    font-size: 27px;
    font-weight: 700;
    margin-bottom: 24px;
    /* max-w-sm on the WordPress h2, so the line breaks in the same place
       instead of running the full width of the band. */
    max-width: 384px;
    margin-left: auto;
    margin-right: auto;
}
.aoit-cta-actions {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 24px;
    flex-wrap: wrap;
}
.aoit-cta-btn {
    font-size: 15px;
    font-weight: 600;
    padding: 10px 20px;
    border-radius: 6px;
    background: var(--aoit-brand);
    color: #fff;
}
.aoit-cta-btn:hover {
    background: var(--aoit-brand-hover);
    color: #fff;
}
.aoit-cta-link {
    font-size: 15px;
    font-weight: 600;
    color: #7CAEEA;
}
.aoit-cta-link:hover {
    /* White, not the darker blue: #2A5FA5 on the #101208 band measured
       ~2.5:1 — under WCAG. footer.php's band hover was fixed to white at
       the same time, so the two stay in step. */
    color: #fff;
}

/* Footer */
.aoit-footer.footer {
    background: #fff;
    border-top: 1px solid var(--aoit-line);
    padding: 44px 0;
}
/* Layout copied from footer.php, which is a flex row of two things: a fixed
   256px brand column (lg:w-64) and, beside it, the five menus in their own
   "grid grid-cols-3 gap-8" — 3 on the first row, 2 wrapping to the second.

   The WHMCS markup has all six blocks as siblings, so the same result is
   reached with one grid and the brand spanning both rows. Without that span,
   auto-placement drops Application Hosting into column 1 underneath the
   address — which is exactly why the second row did not line up with the
   first. */
.aoit-footer-columns {
    display: grid;
    grid-template-columns: 256px repeat(3, 1fr);
    gap: 40px 32px;
    margin-bottom: 32px;
}
.aoit-footer-brand {
    width: 240px;
    flex-shrink: 0;
}
/* footer.php: "font-bold text-[17px] tracking-tight" — one step smaller
   than the header wordmark. */
.aoit-footer-brand .aoit-wordmark {
    font-size: 17px;
    gap: 8px;
}
/* leading-relaxed is 1.625, and the WordPress footer uses ink-faint here
   rather than ink-soft. */
.aoit-footer-address {
    margin-top: 10px;
    font-size: 13px;
    color: var(--aoit-ink-faint);
    line-height: 1.625;
}
.aoit-footer-address a {
    color: var(--aoit-ink-faint);
}
.aoit-footer-address a:hover {
    color: var(--aoit-ink);
}
.aoit-footer-brand {
    grid-row: 1 / span 2;
}
.aoit-footer-group {
    min-width: 0;
}

/* Green Web Foundation image and the Cyber Essentials widget:
   "flex flex-wrap items-center gap-4 mt-4" in footer.php. The iframe carries
   its size inline there; set here instead so it is not repeated in markup. */
.aoit-footer-badges {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
    margin-top: 16px;
}
.aoit-footer-badges img {
    max-width: 200px;
    height: auto;
}
.aoit-footer-badges iframe {
    border: 0;
    width: 132px;
    height: 132px;
}

/* Below lg the marketing site stacks the brand above the menus and drops the
   menu grid to two columns, then one. */
@media (max-width: 991px) {
    .aoit-footer-columns {
        grid-template-columns: repeat(2, 1fr);
    }
    .aoit-footer-brand {
        grid-row: auto;
        grid-column: 1 / -1;
    }
}
@media (max-width: 575px) {
    .aoit-footer-columns {
        grid-template-columns: 1fr;
    }
}
.aoit-footer-heading {
    font-size: 12px;
    font-weight: 600;
    /* tracking-wide, which is 0.025em — 0.05em was double. */
    letter-spacing: 0.025em;
    text-transform: uppercase;
    color: var(--aoit-ink-faint);
    margin-bottom: 12px;
}
.aoit-footer-list {
    list-style: none;
    padding: 0;
    margin: 0;
}
/* The list inherited white from theme.css's own footer styling. Every item
   here happens to be a link and the link colour overrode it, so nothing
   looked wrong — but any plain text in a footer column would have rendered
   white on white. Set explicitly so that cannot happen. */
.aoit-footer-list,
.aoit-footer-list li {
    color: var(--aoit-ink-soft);
}
.aoit-footer-list li {
    margin-bottom: 8px;
}
.aoit-footer-list a {
    font-size: 13.5px;
    color: var(--aoit-ink-soft);
}
.aoit-footer-list a:hover {
    color: var(--aoit-ink);
}
/* A single centred column: one copyright line, with the social list under it
   when the install has any accounts configured. This was a three-across row
   (copyright / VAT / language-and-currency switcher) until the switcher was
   removed. */
.aoit-footer-bottom {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 8px;
    padding-top: 24px;
    border-top: 1px solid var(--aoit-line);
    font-size: 12px;
    color: var(--text-muted);
}
.aoit-footer-social {
    margin: 0;
    padding: 0;
}
@media (max-width: 767px) {
    .aoit-footer-brand,
    .aoit-footer-group {
        width: 100%;
    }
}

/* *****************************************************

    ** Structural redesign, not just a colour swap **

    A colour-only override still leaves the page reading
    as generic WHMCS: dark heavy top bar, boxed/shadowed
    Bootstrap cards, pill badges. This section flattens
    those shapes to match aoitcloud.com's actual visual
    language: hairline dividers, no rounded/boxed panels,
    minimal chrome. Every rule here is a same-specificity
    override of stock Nexus/Bootstrap 4 (see theme.css
    ".topbar" / ".card" / ".badge-pill" for the originals
    being overridden), so it costs nothing extra to load.

***************************************************** */

/* Top "Logged in as" bar: was a solid dark strip
   (--grayscale-accented). Flatten to match the WordPress
   header's plain white bar + hairline bottom border. */
header.header .topbar {
    background-color: #fff;
    color: var(--aoit-ink-soft);
    border-bottom: 1px solid var(--aoit-line);
    padding: 6px 0;
}
header.header .topbar .btn,
header.header .topbar .active-client .btn,
header.header .topbar .active-client .input-group-text {
    color: var(--aoit-ink-soft);
}
header.header .topbar .active-client .btn.btn-active-client span {
    border-bottom: 1px dashed var(--aoit-ink-soft);
}

/* Dashboard/account cards: this is the EXACT card recipe
   used everywhere on aoitcloud.com (see e.g.
   blocks/feature-card/render.php, blocks/pricing-card/
   render.php: "border border-line rounded-[10px] p-6",
   no shadow, plain white background) — not an
   approximation, the same border colour/radius/padding. */
.card,
.mc-promo-manage,
.mc-promo-login,
/* .primary-content .card is theme.css's own selector, at (0,2,0) with
   border-radius: var(--rounding-md) = 8px. A plain .card rule loses to it, so
   until this was added every card in the content area, i.e. nearly every card
   in the client area, was 8px while this rule claimed to be the exact 10px
   aoitcloud.com recipe. Matching the selector shape is what makes the claim
   true. */
.primary-content .card,
.primary-content .mc-promo-manage,
.primary-content .mc-promo-login {
    background-color: #fff;
    border: 1px solid var(--aoit-line);
    border-radius: 10px;
    box-shadow: none;
}
.card-header,
.card-footer {
    background-color: transparent;
}
.card-header,
.card-header:first-child {
    border-bottom: 1px solid var(--aoit-line);
    border-top-left-radius: 9px;
    border-top-right-radius: 9px;
}
.card-footer,
.card-footer:last-child {
    border-top: 1px solid var(--aoit-line);
    border-bottom-left-radius: 9px;
    border-bottom-right-radius: 9px;
}
.card-title {
    font-weight: 600;
    color: var(--aoit-ink);
}

/* Nexus's own dashboard CSS (theme.css) has a
   higher-specificity selector for the "Active
   Products/Services" widget specifically that overrides
   just its top border back to a light grey, which is why
   only that one card's top edge looked mismatched.
   Matching the exact selector so this wins instead. */
body .primary-content .client-home-cards .card,
body .primary-content .client-home-cards .mc-promo-login,
body .primary-content .client-home-cards .mc-promo-manage {
    border-top: 1px solid var(--aoit-line);
}

/* Badges: flatten from full pill to a small radius */
.badge-pill {
    border-radius: 3px;
}

/* Tables: the same grid style used for tables on
   aoitcloud.com's legal pages (see .legal-prose table in
   src/input.css) — collapsed borders in the brand line
   colour, soft-grey header background. Applies to every
   Bootstrap .table across the client area (invoices,
   service lists, ticket lists, domain lists, etc.). */
.table {
    border-collapse: collapse;
}
.table th,
.table td {
    border: 1px solid var(--aoit-line);
    vertical-align: middle;
}
.table thead th {
    background-color: var(--aoit-bg-soft, #F6F7F9);
    color: var(--aoit-ink);
    font-weight: 600;
    border-bottom: 1px solid var(--aoit-line);
}

/* Buttons: rounded-md (6px) and font-semibold, matching the marketing
   site's button classes. */
.btn {
    border-radius: 6px;
    font-weight: 600;
}
/* The marketing site's button metrics — 15px text on 10px/20px padding
   (px-5 py-2.5 text-[15px]) — replacing Bootstrap's 16px on 6px/12px.
   The guards matter: custom.css loads after theme.css, so a bare .btn
   rule here would beat theme.css's EQUALLY-specific .btn-sm/.btn-lg
   sizing on cascade order alone and every small button would inflate.
   .card-minimise (the sidebar collapse chevron) is excluded for the same
   reason — it is a bare icon, not a button-shaped control.

   :where(), NOT :not() directly on the selector: each :not(.class) adds
   class-level specificity, and a first version of this rule at (0,4,0)
   made the compact contextual buttons below impossible to win back —
   every card-header button ballooned to primary-CTA size in production.
   :where() keeps the same exclusions at (0,1,0), so cascade order still
   beats theme.css and the compact rules below still beat this. */
.btn:where(:not(.btn-sm):not(.btn-lg):not(.card-minimise)) {
    font-size: 15px;
    padding: 10px 20px;
}
/* Contextual/compact actions keep the theme's small-action metrics
   (13.5px/600 on 7px 14px — the same scale as .aoit-toggle-closed and
   the invoices-due buttons). These are in-chrome actions beside other
   content, not standalone CTAs: card-header buttons (the blue My
   Services / View All row), table-row Manage buttons (whose services
   cell is a fixed 92px), and the list-page action bars. */
.card-header .btn,
.card-header .btn.btn-default,
table.table-list .btn,
.dataTables_wrapper table.table-list .btn,
.aoit-action-bar .btn,
.aoit-action-bar .btn-group > .btn {
    font-size: 13.5px;
    padding: 7px 14px;
}
/* Keyboard focus on ANY button gets the brand ring. theme.css ships
   Bootstrap's rgba(0,123,255,.25) glow on .btn:focus and eleven variant
   rules — all (0,2,0), so these later equal-specificity rules win. (The
   order form's own stylesheets load after this file; .btn-primary and
   .btn-outline-primary carry their own ring rules above, and the known
   caveat about orderform CSS applies to the rest.) */
.btn:focus,
.btn.focus {
    box-shadow: 0 0 0 0.2rem var(--aoit-focus-ring);
}

/* *****************************************************

    ** Density and whitespace pass **

    The remaining gap after the shape/colour fixes above
    isn't shapes, it's density: a WHMCS dashboard crams
    many small boxes into one view, aoitcloud.com gives
    one idea a lot of room. Can't (and shouldn't) remove
    real account widgets, but the spacing, heading scale
    and stacked grey bars can match the site's rhythm.

***************************************************** */

/* Page title band. Modelled on the legal-page H1 band
   (template-legal.php) but DELIBERATELY diverges from it in
   two ways: white background instead of bg-soft, and the
   hero block's dot-grid texture instead of the legal band's
   rule-fade — chosen while building the client area and kept.
   Same 32px bold H1 and hairline bottom border as the site. */
.aoit-page-heading {
    background: #fff;
    /* No border-top. The nav bar directly above already carries a
       border-bottom, so having one here too stacked two 1px lines into
       what read as a single heavier 2px rule. */
    border-bottom: 1px solid var(--aoit-line);
    padding: 40px 0;
}
.aoit-page-heading .container {
    position: relative;
    z-index: 1;
}
.aoit-page-breadcrumb .breadcrumb {
    background: transparent;
    margin: 0 0 10px;
    padding: 0;
    font-size: 13px;
    color: var(--text-muted);
}
.aoit-page-heading h1 {
    font-size: 32px;
    font-weight: 700;
    letter-spacing: -0.025em;
    color: var(--aoit-ink);
    margin: 0;
    position: relative;
    z-index: 1;
}

/* Fallback plain breadcrumb bar, used only on pages that
   don't get the title band (shopping cart / homepage
   template — see header.tpl). */
.master-breadcrumb,
.master-breadcrumb .breadcrumb {
    background-color: #fff;
}
.master-breadcrumb {
    border-bottom: 1px solid var(--aoit-line);
}
.master-breadcrumb .breadcrumb {
    padding: 8px 0;
    font-size: 13px;
    color: var(--text-muted);
}

/* Line-grid texture, verbatim from src/input.css's
   ".hero-grid" (light background: linear-gradient lines
   at 28px, radial-gradient mask fading toward the right).
   Kept as its own block so it's easy to diff against the
   source if the WordPress site's version ever changes. */
.hero-grid {
    position: relative;
}
.hero-grid::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(#D6D4C4 1px, transparent 1px),
        linear-gradient(90deg, #D6D4C4 1px, transparent 1px);
    background-size: 28px 28px;
    -webkit-mask-image: radial-gradient(ellipse 92% 118% at 86% 0%, black, transparent 85%);
    mask-image: radial-gradient(ellipse 92% 118% at 86% 0%, black, transparent 85%);
    pointer-events: none;
}

/* Main content area: cards are white, so give the page
   itself the site's real soft background colour
   (--color-bg-soft: #F6F7F9, verified directly against
   wp-content/themes/aoit-cloud/src/input.css line 21 —
   NOT the per-hue --color-blue-soft, that's specific to
   VPS-hosting-page sections only) so the white boxes read
   as boxes, plus more breathing room top/bottom to match
   the WordPress site's generous section padding. */
section#main-body {
    background-color: var(--aoit-bg-soft);
    padding: 32px 0 56px;
}

/* More air between dashboard/account widgets — Nexus
   defaults to a tight 10px gap between cards. */
.primary-content .card,
.primary-content .mc-promo-manage,
.primary-content .mc-promo-login {
    margin-bottom: 24px;
}
/* 1.5rem = 24px, which is aoitcloud.com's card padding (p-6). Writing that
   on a plain .card-body was not enough: theme.css carries

       body .primary-content .card .card-body { padding: 32px }

   at (0,3,2), so every card in the CONTENT area, i.e. nearly every card in
   the client area, was 32px while this rule quietly lost. Matching the
   selector shape is what makes the 24px real.

   All FIVE of theme.css's selectors are repeated, not just the first: it also
   names the MarketConnect promo panels (.mc-promo-login / .mc-promo-manage,
   both .card-body and .content). Matching only the .card one left those
   panels at 32px while everything around them moved to 24px. */
.card-body,
body .primary-content .card .card-body,
body .primary-content .mc-promo-login .card-body,
body .primary-content .mc-promo-login .content,
body .primary-content .mc-promo-manage .card-body,
body .primary-content .mc-promo-manage .content {
    padding: 1.5rem;
}
.card-header {
    padding: 1rem 1.5rem;
}
/* Card title sizing is NOT set here. It is already settled further down the
   file: 17px in .primary-content, 14px in sidebars, with the reasoning
   recorded there. A second rule at this point would have silently competed
   with it. */

/* Main nav bar (Home / Services / Domains / ... row):
   #F6F7F9 (--aoit-bg-soft, per Andrew), black hairline
   above it separating it from the white logo/search row. */
/* The single merged header bar. Was a grey strip sitting under a separate
   white logo row; now that the two are one bar it takes the marketing
   site's header treatment instead — white, with a hairline underneath.
   To go back to grey, set background-color to var(--aoit-bg-soft). */
header.header .main-navbar-wrapper {
    background-color: #fff;
    border-top: 0;
    border-bottom: 1px solid var(--aoit-line);
    /* 14px, not the 6px this launched with: the marketing header is py-6
       (24px) around a 26px wordmark, ~74px tall, and the merged bar here
       measured only ~44-48px against it. 14px each side over the ~44px
       content row lands the two bars within a couple of pixels. */
    padding-top: 14px;
    padding-bottom: 14px;
}
/* Brand and nav share a row now, so the nav links need to sit on the
   brand's centre line rather than the top of the bar. */
header.header .main-navbar-wrapper .navbar-collapse {
    align-items: center;
}
header.header .navbar-brand {
    /* ml-10 on the WordPress <nav>. */
    margin-right: 40px;
    /* Per Andrew: the brand is a flex item in the navbar, but its own contents
       were not centred, so the wordmark sat high against the menu beside it.
       header.php does the same thing — the brand link there is
       "flex items-center". */
    display: flex;
    align-items: center;
}

/* Cart button: per Andrew, room around the icon and a gap from the account
   menu next to it.

   Qualified through .main-navbar-wrapper .toolbar because theme.css sets
   "header.header .toolbar .nav-link { padding: .5rem .75rem }" — a plain
   "header.header .cart-btn" loses to it and the padding silently does
   nothing. */
header.header .main-navbar-wrapper .toolbar .cart-btn {
    padding: 10px;
    margin-left: 10px;
}

/* Nav links. header.php gives the nav "gap-6" (24px) and the walker renders
   each item as "text-sm text-ink-soft hover:text-ink" — 14px in #55584C
   going to #14160F. WHMCS was rendering 16px in Bootstrap's #444, spaced
   40px apart, which is the mismatch in font, size and colour. */
/* The nav is already a flex row with gap:40px, so setting a margin on the
   items ADDED to that and produced 64px. Set the gap itself. */
header.header .main-navbar-wrapper .navbar-nav,
header.header #nav {
    gap: 24px;
}
/* :not(.toolbar) matters. The cart and burger live in a .navbar-nav too, so
   without it this zeroed the cart button's horizontal padding — which is
   exactly what happened when padding was later added to .cart-btn and
   appeared not to take. This rule is about the primary nav links only. */
header.header .main-navbar-wrapper .navbar-nav:not(.toolbar) .nav-link,
header.header .main-navbar-wrapper .navbar-nav:not(.toolbar) > li > a {
    padding-left: 0;
    padding-right: 0;
    font-size: 14px;
    font-weight: 400;
    color: var(--aoit-ink-soft);
}
header.header .main-navbar-wrapper .navbar-nav:not(.toolbar) .nav-link:hover,
header.header .main-navbar-wrapper .navbar-nav:not(.toolbar) .nav-link:focus,
header.header .main-navbar-wrapper .navbar-nav:not(.toolbar) > li > a:hover,
header.header .main-navbar-wrapper .navbar-nav:not(.toolbar) > li > a:focus {
    color: var(--aoit-ink);
}

/* *****************************************************

    ** Personalisation pass **

    Restructuring beyond colour/shape: the dashboard stat
    strip, status badges and "Recommended for you" upsell
    still read as stock WHMCS chrome even with the right
    colours applied to Bootstrap's defaults. This section
    changes what those components actually look like.

***************************************************** */

/* Stat strip (Services/Domains/Tickets/Invoices): each
   number gets its own real card (per Andrew — was one
   connected strip with divider lines, now matches the
   site's actual card recipe), giant faded FontAwesome
   icon dropped, and the per-stat colour-coding dropped
   too — too many stray colours on one row, per Andrew.
   Plain, bold, monochrome. */
.tiles .row.no-gutters {
    margin-left: -8px;
    margin-right: -8px;
    /* row-gap, not margin-bottom on each column — margin-bottom adds
       trailing space after the LAST row too (stacking with .tiles'
       own .mb-4 below it), row-gap only adds space BETWEEN rows when
       the tiles wrap on narrower screens. */
    row-gap: 16px;
}
.tiles .row.no-gutters > div {
    padding-left: 8px;
    padding-right: 8px;
}
.tiles .tile,
.tiles .row > div:last-child .tile {
    /* The :last-child variant matches (and beats, on specificity) a
       leftover stock Nexus rule that zeroed the border on the last tile
       — a holdover from the old connected-strip design where only a
       border-right divider was used between tiles, none needed on the
       last one. Now that tiles are separate boxed cards, that rule was
       silently stripping the last card's border entirely. */
    background-color: #fff;
    border: 1px solid var(--aoit-line);
    border-radius: 10px;
    padding: 16px 20px;
}
.tiles .tile i {
    display: none;
}
.tiles .tile .stat {
    margin-top: 0;
    font-size: 32px;
    font-weight: 700;
    color: var(--aoit-ink);
}
.tiles .tile .title {
    color: var(--aoit-ink-soft);
    letter-spacing: 0.04em;
}
.tiles .tile .highlight {
    display: none;
}
.tiles .tile {
    transition: border-color 150ms ease, box-shadow 150ms ease;
}
.tiles .tile:hover {
    /* Matches the real whole-card-link hover treatment used on
       aoitcloud.com (blocks/feature-card/render.php: "hover:border-icon
       hover:shadow-sm") — border turns --color-icon blue plus a small
       shadow, not a background-colour fill. */
    background-color: #fff;
    border-color: var(--aoit-icon);
    box-shadow: var(--aoit-shadow-sm);
}

/* Status badges (e.g. "Active" on services): swap
   solid-fill Bootstrap pills for the same soft-tint badge
   treatment used for hero badges on aoitcloud.com
   (bg-{colour}-soft + text-{colour} — see hero/render.php).
   Covers every semantic badge colour, not just success. */
.badge-success {
    background-color: var(--success-soft, #EAF6EA);
    color: var(--success-accented);
}
.badge-danger {
    background-color: var(--error-soft, #FBEAE7);
    color: var(--error-accented);
}
.badge-warning {
    background-color: var(--warning-soft, #FBF0DE);
    color: var(--warning-accented);
}
.badge-info {
    background-color: var(--info-soft, #E8F0FA);
    color: var(--info-accented);
}
.badge-primary {
    background-color: var(--success-soft);
    color: var(--success-accented);
}

/* "Recommended for you" upsell panels: addon modules
   (SiteLock, 360 Monitoring, etc.) render their own CTA
   buttons using WHMCS's generic .bg-color-* utility
   classes (see theme.css) — these already resolve through
   the same --success/--info/--warning/--notice/--error
   tokens remapped above, so addon buttons now use the
   real brand palette automatically instead of each
   module's own arbitrary colour, without needing to touch
   markup we don't control. Just flatten the button shape
   to match the site's rounded-md buttons. */
.client-home-cards .btn {
    border-radius: 6px;
    font-weight: 600;
}

/* Sidebar consolidation: "Your Info" / "Contacts" /
   "Shortcuts" as three separately-boxed stacks read as
   bureaucratic next to how sparse aoitcloud.com is. Each
   item stays its own real .card (see includes/sidebar.tpl
   for why — preserves the existing collapse/minimise JS
   scoping), but overlapping borders + squared-off middle
   corners makes the group of them read as one panel. */
.aoit-sidebar-group .card.card-sidebar {
    /* Bootstrap's .mb-3 utility (already on this element in
       the markup) sets margin-bottom with !important, which
       beats a plain declaration — has to be matched here or
       the "merge" never actually closes the gap. */
    margin-bottom: -1px !important;
    border-radius: 0;
}
.aoit-sidebar-group .card.card-sidebar:first-of-type {
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
}
.aoit-sidebar-group .card.card-sidebar:last-of-type {
    border-bottom-left-radius: 10px;
    border-bottom-right-radius: 10px;
    margin-bottom: 24px !important;
}

/* Main nav links (Home / Services / Domains / ...): Nexus
   sets margin-top:8px / margin-bottom:20px on the <ul> by
   default, which unbalances the bar's vertical centring. */
header.header .navbar-nav {
    margin-top: 0;
    margin-bottom: 0;
}

/* *****************************************************

    ** Dashboard hierarchy redesign **

    Goes with the restructured clientareahome.tpl: an
    urgent banner for overdue invoices, a featured card
    for active services, and a tighter grid for everything
    secondary — real visual priority instead of a flat grid
    of equal-weight boxes.

***************************************************** */

/* Overdue Invoices: a slim single-line notice above the
   stat tiles (was a large full card below them, with a
   cramped/broken-looking "Pay Now" pill — fixed to a
   proper-sized button here). */
.aoit-urgent-notice {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    background-color: var(--error-soft);
    border: 1px solid var(--error);
    border-radius: 10px;
    padding: 12px 20px;
    margin-bottom: 20px;
    font-size: 14px;
    color: var(--error-accented);
}
/* Amber variant, for "needs attention soon" rather than "overdue now" —
   currently Domains Expiring Soon. Same shape, warning palette. */
.aoit-urgent-notice.is-warning {
    background-color: var(--warning-soft);
    border-color: var(--warning);
    color: var(--warning-accented);
}
.aoit-urgent-notice.is-warning .aoit-urgent-notice-btn {
    background-color: var(--warning);
}
.aoit-urgent-notice.is-warning .aoit-urgent-notice-btn:hover {
    background-color: var(--warning-accented);
}
.aoit-urgent-notice-text {
    display: flex;
    align-items: center;
}
.aoit-urgent-notice-text i {
    margin-right: 8px;
    flex-shrink: 0;
}
.aoit-urgent-notice-text p {
    margin: 0;
}
.aoit-urgent-notice-btn {
    flex-shrink: 0;
    display: inline-block;
    padding: 8px 16px;
    border-radius: 6px;
    background-color: var(--error);
    color: #fff;
    font-size: 13.5px;
    font-weight: 600;
    white-space: nowrap;
}
.aoit-urgent-notice-btn:hover {
    background-color: var(--error-accented);
    color: #fff;
}

.aoit-featured-panel {
    margin-bottom: 24px;
}
/* Qualified with .primary-content so this outranks the generic
   ".primary-content .card-title" 17px rule further down the file — same
   specificity would let the later rule win and flatten the emphasis. */
.primary-content .aoit-featured-panel .card-title {
    font-size: 20px;
}
/* This used to widen only the sides, to 1.75rem/28px, and let the vertical
   padding come from .card-body, which at the time was theme.css's 32px. Now
   that card bodies are the intended 24px the asymmetry would read as a
   mistake, so the panel takes the same 24px as every other card. Restore the
   two padding-left/right lines if it should be roomier than its neighbours. */
/* "Active" status badge, per row: makes sense on the full
   Services list (which shows every status), redundant
   here since this widget only ever lists active services.
   Scoped to this panel only — the badge markup itself
   (includes/active-products-services-item.tpl) is shared
   with that full list page, so it stays visible there. */
.aoit-featured-panel .div-service-status {
    display: none;
}
/* The "View More..." link at the bottom sits inside
   WHMCS's own server-rendered body HTML, which we don't
   control — but the divider line above it is this card's
   own footer border (see the global .card-footer rule),
   which only looked wrong here because there's no actual
   footer content of ours below it. */
.aoit-featured-panel .card-footer {
    border-top: none;
    padding-top: 0;
    padding-bottom: 0;
}

.aoit-tools-grid {
    display: grid;
    /* Single column, full width (Andrew, 2026). Went three -> two -> one:
       these widgets hold a sentence or a small form, so side-by-side
       columns bought dead space rather than density, and the narrower
       tracks made addon panels with internal columns wrap awkwardly.
       Full width also lets those panels use their own two-column layout
       properly instead of fighting the grid track. */
    grid-template-columns: 1fr;
    gap: 20px;
}
/* Card-header buttons (My Services, View All, More Details, Open New
   Ticket, ...). WHMCS gives each panel an arbitrary colour of its own and
   renders the header button with a matching bg-color-* utility
   (gold / teal / pink / blue / ...), so a row of cards came out as a
   scattered rainbow. Pinned to brand blue everywhere instead, per Andrew.

   Scoped to .card-header rather than .client-home-cards so it covers EVERY
   card on the site (dashboard, sidebar, service/domain detail pages), not
   just the dashboard widgets.

   !important is required on the background: WHMCS puts bg-color-* directly
   on the element and theme.css declares some of those with !important
   themselves, so extra specificity alone does not win. */
.card-header .btn,
.card-header .btn.btn-default {
    background-color: var(--aoit-blue) !important;
    border-color: var(--aoit-blue) !important;
    color: #fff !important;
    border-radius: 6px;
    font-weight: 600;
}
.card-header .btn:hover,
.card-header .btn:focus,
.card-header .btn.btn-default:hover,
.card-header .btn.btn-default:focus {
    background-color: var(--aoit-blue-hover) !important;
    border-color: var(--aoit-blue-hover) !important;
    color: #fff !important;
}
/* The collapse chevron on sidebar cards must stay a bare icon, not become
   a blue pill. */
.card-header .card-minimise,
.card-header .btn.card-minimise {
    background-color: transparent !important;
    border-color: transparent !important;
    color: var(--aoit-ink-soft) !important;
}
.aoit-tools-grid .card {
    margin-bottom: 0;
}
/* No font-size here on purpose: dashboard panels take the same 17px as
   panels on every other page (see the .primary-content .card-title rule
   further down), so the two do not drift apart. The featured "Your
   Services" panel keeps its larger 20px as deliberate emphasis. */
.aoit-tools-grid .card-header,
.aoit-tools-grid .card-body {
    padding: 0.85rem 1.25rem;
}

/* *****************************************************

    ** My Services — list rows (.table-services) **

    Turns the DataTables table on clientareaproducts.tpl
    into the same list-row pattern the dashboard's "Your
    Services" panel uses, without giving up the table
    element (and with it DataTables' search, sorting,
    pagination, status filter and stateSave).

    SPECIFICITY, read before editing:
    theme.css styles this table through two selector
    families that both outrank a plain ".table-services":
      table.table-list tbody td               (0,1,3)
      .dataTables_wrapper table.table-list ... (0,2,3)
    The second only matches once DataTables has wrapped
    the table at runtime, so a rule that looks correct on
    a static page can still lose on the real page. Every
    rule below therefore qualifies with BOTH classes the
    element carries (table.table-list.table-services), and
    the badge rules additionally list a .dataTables_wrapper
    variant, so they win before and after initialisation.

    Column indices, which the flex `order` values below
    rearrange visually:
      0 SSL  1 product  2 price  3 due  4 status  5 button

***************************************************** */

/* Toggle above the table for revealing closed services. */
.aoit-services-toolbar {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 12px;
}
.aoit-toggle-closed {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: #fff;
    border: 1px solid var(--aoit-line);
    border-radius: 6px;
    padding: 7px 14px;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--aoit-ink);
    cursor: pointer;
}
.aoit-toggle-closed:hover {
    background: var(--aoit-bg-soft);
}
.aoit-toggle-closed.is-showing {
    border-color: var(--aoit-brand);
    color: var(--aoit-brand);
}
.aoit-toggle-count {
    display: inline-block;
    min-width: 20px;
    padding: 1px 6px;
    border-radius: 3px;
    background: var(--aoit-bg-soft);
    font-size: 12px;
    font-weight: 600;
    color: var(--aoit-ink-soft);
    text-align: center;
}
.aoit-toggle-closed.is-showing .aoit-toggle-count {
    background: var(--success-soft);
    color: var(--success-accented);
}

/* The table itself: one bordered card, rows as flex lines. The
   .dataTables_wrapper variant is required because theme.css sets its own
   border and border-radius on that scoped selector once DataTables runs. */
table.table-list.table-services,
.dataTables_wrapper table.table-list.table-services {
    background: #fff;
    border: 1px solid var(--aoit-line);
    border-radius: 10px;
    border-collapse: separate;
    border-spacing: 0;
    overflow: hidden;
}

/* THE COLUMN HEADER IS HIDDEN, and that is a deliberate trade.
   Once rows are flex lines their cells no longer line up with table
   columns, so a header row cannot label anything - it just floats above
   unrelated content. Hiding it costs DataTables' click-to-sort; search,
   pagination, the sidebar status filter and the closed-services toggle all
   still work, because those act on the data rather than the layout. */
table.table-list.table-services thead,
.dataTables_wrapper table.table-list.table-services thead {
    display: none;
}

/* tbody MUST leave the table formatting context.
   A display:flex <tr> inside a display:table-row-group <tbody> gets wrapped
   in an anonymous table cell and shrinks to fit its content, so every row
   collapsed into a narrow column on the left of the page. This did not show
   up in a static test harness because DataTables also sizes the table at
   runtime; it only appeared on the real logged-in page. */
table.table-list.table-services tbody,
.dataTables_wrapper table.table-list.table-services tbody {
    display: block;
    width: 100%;
}

table.table-list.table-services tbody tr {
    width: 100%;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px 16px;
    padding: 14px 24px;
    border-bottom: 1px solid var(--border-muted);
    cursor: pointer;
    transition: background-color 120ms ease;
}
table.table-list.table-services tbody tr:last-child {
    border-bottom: 0;
}
table.table-list.table-services tbody tr:hover {
    background-color: var(--aoit-bg-soft);
}
/* Zero the stock 10px/8px cell padding — the row owns spacing now. */
table.table-list.table-services tbody td,
.dataTables_wrapper table.table-list.table-services tbody td {
    display: block;
    border: 0;
    padding: 0;
    font-size: 14px;
    line-height: 1.45;
}

/* FIXED COLUMN WIDTHS, so rows line up with each other.
   With auto-width cells every row laid out to its own content: prices,
   dates and buttons landed at different x positions on each line and the
   Manage button wrapped onto a second row whenever a product name ran
   long. Each cell below therefore gets a fixed basis and only the product
   column flexes. Widths must total under the content well (~855px beside
   the sidebar): 30 + 120 + 190 + 86 + 96 plus four 20px gaps leaves about
   250px for the product name. */
table.table-list.table-services tbody tr {
    flex-wrap: nowrap;
}

/* SSL indicator. The width is reserved whether or not an icon renders, so
   a row without one still aligns with the rows that have one. */
table.table-list.table-services tbody td:first-child {
    order: 1;
    flex: 0 0 30px;
    line-height: 0;
    text-align: left;
}

/* Product name + domain take whatever is left. */
.table-services .cell-product {
    order: 2;
    flex: 1 1 auto;
    min-width: 0;
    text-align: left;
}
/* Truncate rather than wrap. A long domain wrapping to a second line made
   that row taller than its neighbours, which is most of what made the list
   look ragged. min-width:0 on .cell-product is what lets ellipsis work
   inside a flex item. The whole row links to the service, so the full value
   is one click away. */
.table-services .service-name {
    display: block;
    font-weight: 700;
    font-size: 15px;
    color: var(--aoit-ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.table-services .service-domain {
    display: block;
    font-size: 13.5px;
    color: var(--aoit-ink-soft);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Price and renewal date sit together as right-aligned metadata. */
.table-services .cell-price {
    order: 3;
    flex: 0 0 100px;
    text-align: right;
}
.table-services .service-price {
    font-weight: 600;
    color: var(--aoit-ink);
    font-variant-numeric: tabular-nums;
}
.table-services .service-cycle {
    display: block;
    font-size: 12.5px;
    color: var(--aoit-ink-soft);
}
.table-services .cell-due {
    order: 4;
    /* Wide enough for the longest rendered date, e.g.
       "Saturday, September 19th, 2026". */
    flex: 0 0 190px;
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.table-services .service-due-label {
    display: none;
}
.table-services .service-due {
    font-size: 13.5px;
    color: var(--aoit-ink-soft);
}

.table-services .cell-status {
    order: 5;
    flex: 0 0 80px;
    text-align: center;
}
.table-services .cell-action {
    order: 6;
    flex: 0 0 92px;
    text-align: right;
}

/* Status pills: soft-tint treatment (matching the hero badges on
   aoitcloud.com) instead of the stock solid fills. The base rule has to
   outrank theme.css's "body .dataTables_wrapper table.table-list .label.status",
   hence the wrapper-qualified second selector on each. */
table.table-list.table-services .label.status,
.dataTables_wrapper table.table-list.table-services .label.status {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 3px;
    font-size: 12px;
    font-weight: 600;
    background: var(--aoit-bg-soft);
    color: var(--aoit-ink-soft);
}
table.table-list.table-services .label.status.status-active,
table.table-list.table-services .label.status.status-completed,
.dataTables_wrapper table.table-list.table-services .label.status.status-active,
.dataTables_wrapper table.table-list.table-services .label.status.status-completed {
    background: var(--success-soft);
    color: var(--success-accented);
}
table.table-list.table-services .label.status.status-pending,
table.table-list.table-services .label.status.status-pending-transfer,
table.table-list.table-services .label.status.status-pending-registration,
table.table-list.table-services .label.status.status-suspended,
.dataTables_wrapper table.table-list.table-services .label.status.status-pending,
.dataTables_wrapper table.table-list.table-services .label.status.status-pending-transfer,
.dataTables_wrapper table.table-list.table-services .label.status.status-pending-registration,
.dataTables_wrapper table.table-list.table-services .label.status.status-suspended {
    background: var(--warning-soft);
    color: var(--warning-accented);
}
table.table-list.table-services .label.status.status-terminated,
table.table-list.table-services .label.status.status-cancelled,
table.table-list.table-services .label.status.status-expired,
table.table-list.table-services .label.status.status-fraud,
.dataTables_wrapper table.table-list.table-services .label.status.status-terminated,
.dataTables_wrapper table.table-list.table-services .label.status.status-cancelled,
.dataTables_wrapper table.table-list.table-services .label.status.status-expired,
.dataTables_wrapper table.table-list.table-services .label.status.status-fraud {
    background: var(--error-soft);
    color: var(--error-accented);
}

/* Small screens: metadata drops under the product name rather than being
   squeezed onto one line. (DataTables Responsive is switched off for this
   table — see noResponsive in clientareaproducts.tpl.) */
@media (max-width: 767px) {
    /* (thead is hidden at every width now, not just here.) */
    table.table-list.table-services tbody tr {
        gap: 8px 16px;
        padding: 16px;
    }
    .table-services .cell-product {
        flex: 1 1 100%;
    }
    .table-services .cell-price,
    .table-services .cell-due {
        text-align: left;
    }
    .table-services .service-due-label {
        display: inline;
        font-size: 12.5px;
        color: var(--aoit-ink-soft);
    }
    .table-services .cell-action {
        margin-left: auto;
    }
}

/* *****************************************************

    ** MarketConnect addon panels (360 Monitoring, SiteLock) **

    These panels are rendered by the addon modules themselves, so their
    markup is not ours and their styling arrives from three places at once:
    the module's own inline styles, Nexus rules, and nothing else.

    ROOT CAUSE worth knowing: Nexus ships compensating styles for the 360
    panel, but every one of them is scoped to ".client-home-cards" — the
    wrapper the stock dashboard puts around its panel grid. Our rebuilt
    clientareahome.tpl uses .aoit-tools-grid instead, so all 36 of those
    rules are dormant. That is why the metric row rendered at its raw
    inline "font-size: 1.5em" with sentence-case labels, rather than the
    small uppercase treatment Nexus intended.

    Re-adding the .client-home-cards class would revive those rules, but it
    would also revive its generic card/list-group layout, which we have
    already replaced wholesale. Cheaper and more predictable to restate
    just the panel-specific bits here, on-brand.

***************************************************** */

/* The metric row carries an inline "font-size: 1.5em", so the override has
   to be !important; children then inherit a sane base to size against. */
div[menuitemname="ThreesixtymonitoringLogin"] .threesixtymonitoring-metrics-row {
    font-size: 1rem !important;
    margin-bottom: 16px !important;
}

/* Numbers and labels get the same treatment as the main dashboard stat
   tiles: bold ink figure, small uppercase muted label. Deliberately a size
   down from those tiles, since this is a secondary card. */
div[menuitemname="ThreesixtymonitoringLogin"] .threesixtymonitoring-metric {
    font-size: 22px;
    font-weight: 700;
    line-height: 1.2;
    color: var(--aoit-ink);
    font-variant-numeric: tabular-nums;
}
div[menuitemname="ThreesixtymonitoringLogin"] .threesixtymonitoring-title {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--aoit-ink-soft);
}

/* The module paints three decorative underlines in its own magenta ramp
   (#902a6d / #af3362 / #ce3b56). Hidden rather than recoloured: the main
   stat tiles had their coloured underlines removed for the same reason,
   so keeping them here would reintroduce exactly the scattered-colour
   look those were dropped to fix. */
div[menuitemname="ThreesixtymonitoringLogin"] .threesixtymonitoring-highlight,
div[menuitemname="ThreesixtymonitoringLogin"] .threesixtymonitoring-highlight-servers,
div[menuitemname="ThreesixtymonitoringLogin"] .threesixtymonitoring-highlight-monitors,
div[menuitemname="ThreesixtymonitoringLogin"] .threesixtymonitoring-highlight-alerts {
    display: none;
}

/* Vendor logos ship at full size and dominate the card. Applies to every
   MarketConnect SSO panel, so SiteLock's oversized padlock is covered too. */
/* Vendor artwork (SiteLock padlock, 360 logo) removed per Andrew: it is
   stock clipart that carries no information the card title does not
   already give, and it was the main reason these cards ran tall. */
.panel-mc-sso img {
    display: none;
}
/* Hiding the image leaves its column occupying half the row, squeezing the
   form into the remainder. Collapse whichever column held the image and let
   the sibling take the full width. Targeted with :has() rather than
   :first-child because only 360's markup has been seen — the image is not
   guaranteed to be the first column in every MarketConnect panel. If a
   browser lacks :has() the rule is simply skipped, leaving an empty
   half-column rather than a broken layout. */
.panel-mc-sso .row > [class*="col-"]:has(img) {
    display: none;
}
.panel-mc-sso .row:has(> [class*="col-"] img) > [class*="col-"]:not(:has(img)) {
    flex: 0 0 100%;
    max-width: 100%;
}

/* Keep the panel body tidy: centre the vendor column, stop the form
   controls stretching to odd widths. */
.panel-mc-sso .row {
    align-items: center;
}
.panel-mc-sso select.form-control {
    margin-bottom: 8px;
}
/* "Powered by: Sitelock(TM)" / "Powered by: WebPros(TM)" hidden per Andrew.
   NOTE: vendor attribution can be a condition of the MarketConnect reseller
   terms for these products. To restore, swap display:none back to block —
   the rest of the styling is kept here ready for that. */
.panel-mc-sso small {
    display: none;
    margin-top: 8px;
    font-size: 11.5px;
    color: var(--text-muted);
}

/* The vendor Manage button ships as .btn-default (grey). Brand green, to
   match every other primary action in the client area. Scoped to these
   panels so .btn-default stays neutral everywhere else. */
.panel-mc-sso .btn,
.panel-mc-sso .btn.btn-default,
.panel-mc-sso .btn-service-sso {
    background-color: var(--aoit-brand);
    border-color: var(--aoit-brand);
    color: #fff;
    border-radius: 6px;
    font-weight: 600;
}
.panel-mc-sso .btn:hover,
.panel-mc-sso .btn.btn-default:hover,
.panel-mc-sso .btn:focus,
.panel-mc-sso .btn.btn-default:focus {
    background-color: var(--aoit-brand-hover);
    border-color: var(--aoit-brand-hover);
    color: #fff;
}

/* *****************************************************

    ** Heading scale **

    Bootstrap ships 2.5 / 2 / 1.75 / 1.5rem at font-weight 500. The
    marketing site is bolder and tighter: every heading is 700 with
    negative tracking, on a smaller scale. Applied globally here rather
    than per template, because the ~290 heading tags across the theme
    carry no consistent classes to hook onto (118 bare <h4>, 78 bare
    <h3>, 67 bare <h2>) — a global scale is the only change that reaches
    all of them without editing every file.

    Sizes follow the design system:
      h1 32  page title, and the in-content title on cart pages where the
              title band is suppressed ($inShoppingCart)
      h2 25  section heading
      h3 19
      h4 16
      card title 15.5 / 600

    More specific rules already set elsewhere still win — the featured
    panel's 20px card title, the tools grid's 15px, and .aoit-cta-heading
    at 27px are all left alone.

***************************************************** */

h1, .h1,
h2, .h2,
h3, .h3,
h4, .h4,
h5, .h5,
h6, .h6 {
    font-weight: 700;
    color: var(--aoit-ink);
    letter-spacing: -0.025em;
    /* Stops a two-line heading leaving one orphaned word. */
    text-wrap: balance;
}

h1, .h1 { font-size: 32px; }
h2, .h2 { font-size: 25px; }
h3, .h3 { font-size: 19px; }
h4, .h4 { font-size: 16px; }
h5, .h5 { font-size: 15px; }
h6, .h6 { font-size: 14px; }

/* Card titles are headings in the markup (mostly h3), so they need their
   own size or they inherit the h3 step and dwarf the card. */
/* Card titles are headings in the markup (mostly h3), so without their own
   size they inherit the h3 step and dwarf the card.

   Nexus sizes them by context and that hierarchy is worth keeping — a panel
   heading in main content should outrank a sidebar widget's. What is not
   worth keeping is the scale: theme.css uses 22px in .primary-content, which
   is an outlier against a 32px page title and 25px section heading, and it
   left dashboard panels (15px) inconsistent with every other page's (22px).
   Unified to 17px, with sidebars staying deliberately smaller. */
.card-title {
    font-weight: 600;
    letter-spacing: normal;
}
.primary-content .card-title {
    font-size: 17px;
}
.sidebar .card-title {
    font-size: 14px;
}

/* Modal titles ship as h4 at Bootstrap's 500 weight. */
.modal-title {
    font-size: 18px;
    font-weight: 700;
    letter-spacing: -0.025em;
}

/* Panel/section headings inside the order form and cart. The order form
   is a separate template (templates/orderforms/standard_cart) with its own
   stylesheet, so it is reached by element rather than by a class of ours. */
#order-standard_cart h1,
#order-standard_cart h2 {
    font-weight: 700;
    color: var(--aoit-ink);
    letter-spacing: -0.025em;
}

/* Headings that sit on a dark ground must not inherit the ink colour, or
   they disappear. Covers the closing CTA band and any inverted panel. */
.aoit-cta-band h1,
.aoit-cta-band h2,
.aoit-cta-band h3,
.bg-inverted h1,
.bg-inverted h2,
.bg-inverted h3 {
    color: #fff;
}

/* *****************************************************

    ** Order form: "Order Now" buttons **

    theme.css:13492 paints these with var(--bg-inverted), which our palette
    defines as the ink colour, so the most important commit action in the
    whole product rendered near-black:

      body #order-standard_cart .products .product footer .btn-order-now {
        background: var(--bg-inverted);

    That selector is (1,4,2) - one ID, four classes - so no plain .btn rule
    could reach it. Matched exactly here; custom.css loads after theme.css,
    so equal specificity wins.

    Green because ordering commits the action, per the site-wide rule
    (green commits, blue navigates).

    NOTE the two order-form stylesheets that load AFTER this file
    (orderforms/standard_cart/all.min.css and orderforms/nexus_cart/
    custom.css) were checked and define nothing for .btn-order-now, so they
    do not undo this. If a future WHMCS update changes that, these rules
    would need moving into an order-form template of our own.

***************************************************** */

body #order-standard_cart .products .product footer .btn-order-now {
    background: var(--aoit-brand);
    border-color: var(--aoit-brand);
    color: #fff;
}
body #order-standard_cart .products .product footer .btn-order-now:hover,
body #order-standard_cart .products .product footer .btn-order-now:focus,
body #order-standard_cart .cart-body .products .product .btn-order-now:focus {
    background: var(--aoit-brand-hover);
    border-color: var(--aoit-brand-hover);
    color: #fff;
}

/* *****************************************************

    ** My Services: status pills + promo row **

    The sidebar is not rendered on this page (see header.tpl), so its two
    useful parts moved into the content: the "View" status filter became the
    pills below, and the MarketConnect promos became a four-across row under
    the table. The "Actions" panel was dropped: both of its entries were
    removed at Andrew's request, which left it empty.

***************************************************** */

.aoit-services-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 16px;
}
.aoit-status-pill {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: #fff;
    border: 1px solid var(--aoit-line);
    border-radius: 999px;
    padding: 6px 14px;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--aoit-ink);
    cursor: pointer;
    transition: background-color 120ms ease, border-color 120ms ease;
}
.aoit-status-pill:hover:not(:disabled) {
    background: var(--aoit-bg-soft);
}
.aoit-status-pill.is-active {
    background: var(--aoit-brand);
    border-color: var(--aoit-brand);
    color: #fff;
}
/* A status with nothing in it stays visible but inert, so the row of pills
   does not reflow as an account's mix of services changes. */
.aoit-status-pill:disabled {
    opacity: 0.45;
    cursor: default;
}
.aoit-pill-count {
    font-variant-numeric: tabular-nums;
    font-size: 12px;
    opacity: 0.75;
}
.aoit-status-pill.is-active .aoit-pill-count {
    opacity: 0.9;
}

/* Four across, collapsing rather than squashing. auto-fit with a 240px
   minimum gives 4 on a full-width page and fewer as it narrows. */
.aoit-service-promos {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 20px;
    margin-top: 28px;
    /* stretch, not start: cards in a row share a height so the row reads as
       a set, and each card's "Learn more" footer lines up with its
       neighbours' instead of floating at its own content height. */
    align-items: stretch;
}
.aoit-service-promos .aoit-promo-card {
    margin-bottom: 0;
    display: flex;
    flex-direction: column;
}
/* Body grows so the footer is pinned to the bottom of every card. */
.aoit-service-promos .aoit-promo-card .card-body {
    flex: 1 1 auto;
    text-align: center;
    font-size: 13.5px;
}

/* Each promo's body is a single <a> containing an <img> and a <span> as
   inline siblings, so by default the description wraps AROUND the logo
   ("Protect your" beside it, the rest underneath). Stacking the anchor
   puts the image above the text and centres both. */
.aoit-service-promos .aoit-promo-card .card-body a {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    /* The markup carries an inline style="font-weight: 300", so this needs
       to be !important to bring the text back to the site's weight. */
    font-weight: 400 !important;
    color: var(--aoit-ink-soft);
    text-decoration: none;
}
.aoit-service-promos .aoit-promo-card .card-body a:hover {
    color: var(--aoit-ink);
}

/* Vendor artwork arrives at wildly different aspect ratios (a tall shield,
   a wide wordmark, a square tile). Constraining height as well as width,
   with object-fit, makes them occupy a consistent block across the row. */
.aoit-service-promos .aoit-promo-card img {
    display: block;
    /* FIXED height, not max-height. With max-height each logo kept its own
       natural height (a wide wordmark ends up far shorter than a tall
       shield), so the description below it started at a different point in
       every card. A fixed 56px band with object-fit:contain letterboxes each
       logo instead, so the text baselines line up across the row. */
    height: 56px;
    width: auto;
    max-width: 140px;
    object-fit: contain;
}

/* Footer: one quiet call to action, consistent across every card. */
.aoit-service-promos .aoit-promo-card .card-footer {
    text-align: center;
    font-size: 13.5px;
    font-weight: 600;
}
.aoit-service-promos .aoit-promo-card .card-footer a {
    color: var(--aoit-brand);
}
.aoit-service-promos .aoit-promo-card .card-footer a:hover {
    color: var(--aoit-brand-hover);
}
.aoit-service-promos .aoit-promo-card .btn {
    width: 100%;
}


/* *****************************************************

    Service overview  (clientareaproductdetails.tpl)

    Rebuild of the stock two-column overview card, which set every
    fact as a centred <h4> label with bare text beneath it — no
    separation between one fact and the next, and no common left
    edge to read down. Replaced with an identity strip, a tinted
    billing summary, and a quiet detail grid. See the comment at the
    top of the template for the reasoning.

***************************************************** */

/* --- Identity strip ------------------------------------------------ */

.aoit-service-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 16px 24px;
    padding-bottom: 18px;
    border-bottom: 1px solid var(--neutral-200);
}
.aoit-service-ident {
    display: flex;
    align-items: center;
    gap: 16px;
    /* min-width:0 so a long product name wraps inside the flex item
       rather than forcing the strip wider than the card. */
    min-width: 0;
}

/* A 48px tile, not the stock 60px-font black disc in a 30px-padded grey
   box — which was the single largest element on the page while carrying
   the least information on it. */
.aoit-service-icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: 8px;
    background: var(--aoit-bg-soft);
    color: var(--aoit-blue);
    font-size: 20px;
}
.aoit-service-titles {
    min-width: 0;
}
.aoit-service-titles h2 {
    margin: 0;
    font-size: 22px;
    font-weight: 700;
    line-height: 1.25;
    color: var(--aoit-ink);
    word-break: break-word;
}
.aoit-service-titles p {
    margin: 3px 0 0;
    font-size: 13.5px;
    color: var(--aoit-ink-soft);
}
.aoit-service-head-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 12px;
    margin-left: auto;
}

/* Same soft-tint status treatment as the rows on My Services, so a
   service reads the same in the list and on its own page. The stock
   .status-* rules in theme.css are solid fills; these selectors carry
   two classes so they outrank them without !important. */
.aoit-service-status {
    display: inline-block;
    padding: 5px 12px;
    border-radius: 3px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    background: var(--aoit-bg-soft);
    color: var(--aoit-ink-soft);
}
.aoit-service-status.status-active,
.aoit-service-status.status-completed {
    background: var(--success-soft);
    color: var(--success-accented);
}
.aoit-service-status.status-pending,
.aoit-service-status.status-pending-transfer,
.aoit-service-status.status-suspended {
    background: var(--warning-soft);
    color: var(--warning-accented);
}
.aoit-service-status.status-terminated,
.aoit-service-status.status-cancelled,
.aoit-service-status.status-expired,
.aoit-service-status.status-fraud,
.aoit-service-status.status-closed {
    background: var(--error-soft);
    color: var(--error-accented);
}

.aoit-service-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
/* Blue for the secondary action, matching the card-header buttons.
   Both Upgrade and Renew were .btn-success / .btn-primary in stock,
   which now resolve to the same brand green, so the two sat side by
   side as identical buttons. */
.aoit-btn-blue,
.btn.aoit-btn-blue {
    background-color: var(--aoit-blue);
    border-color: var(--aoit-blue);
    color: #fff;
}
.aoit-btn-blue:hover,
.aoit-btn-blue:focus,
.btn.aoit-btn-blue:hover,
.btn.aoit-btn-blue:focus {
    background-color: var(--aoit-blue-hover);
    border-color: var(--aoit-blue-hover);
    color: #fff;
}
/* Cancellation stays reachable but stops being the loudest thing on the
   page. It is still offered a second time in the sidebar's Actions
   panel, so a full-width red block here was both dominant and
   duplicated. Turns solid red on hover, so the destructive intent is
   unmistakable at the moment of clicking. */
.aoit-btn-quiet-danger,
.btn.aoit-btn-quiet-danger {
    background-color: #fff;
    border-color: var(--error);
    color: var(--error);
}
.aoit-btn-quiet-danger:hover,
.aoit-btn-quiet-danger:focus,
.btn.aoit-btn-quiet-danger:hover,
.btn.aoit-btn-quiet-danger:focus {
    background-color: var(--error);
    border-color: var(--error);
    color: #fff;
}
.aoit-service-actions .btn.disabled {
    pointer-events: none;
}

/* --- Facts --------------------------------------------------------- */

/* The billing tier is flex with content-sized cells, NOT an equal-column
   grid. Equal columns were tried first and broke on the real page: this
   page keeps its sidebar, so the content well is ~830px, which gives three
   equal cells about 210px each — enough for "£486.68 GBP" but not for a
   date in WHMCS's verbose format ("Saturday, September 19th, 2026"), which
   wrapped to two lines at 20px while its neighbours stayed on one. The
   date format is a client setting, so it cannot be shortened from here.
   Content sizing lets the date take the room it needs and the short values
   give it up. Hairline separators keep them reading as distinct facts
   rather than one run-on line. */
.aoit-service-billing {
    display: flex;
    flex-wrap: wrap;
    gap: 16px 30px;
    margin: 20px 0 0;
    padding: 18px 22px;
    background: var(--aoit-bg-soft);
    border-radius: 6px;
}
.aoit-service-billing .aoit-fact + .aoit-fact {
    padding-left: 30px;
    border-left: 1px solid var(--neutral-300);
}

/* The detail tier keeps equal columns: its values are set at 15px and fit
   comfortably, and an aligned grid reads more calmly for reference data.
   auto-fit because the cell count varies (first payment amount only shows
   when it differs from the recurring amount, quantity only when supported
   and greater than one). */
.aoit-service-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 18px 28px;
    margin: 22px 0 0;
    padding: 0 22px;
}
.aoit-fact {
    margin: 0;
    min-width: 0;
}
.aoit-fact dt {
    margin: 0 0 4px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--aoit-ink-soft);
}
.aoit-fact dd {
    margin: 0;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.35;
    color: var(--aoit-ink);
    word-break: break-word;
}
/* The billing tier is set larger so the amount and the date are legible
   at a glance from the top of the page. tabular-nums keeps the digits on
   a common width, which matters when two amounts sit side by side. */
.aoit-service-billing .aoit-fact dd {
    font-size: 20px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.aoit-service-suspend {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: 22px 0 0;
    padding: 12px 16px;
    border-radius: 6px;
    background: var(--warning-soft);
    color: var(--warning-accented);
    font-size: 14px;
}

/* Narrow: the billing row stacks, so the separators between facts would
   land on the left edge of wrapped items instead of between them. Dropped
   in favour of a horizontal rule, which is what a stacked list wants. */
@media (max-width: 767px) {
    .aoit-service-billing {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
        gap: 16px 20px;
    }
    .aoit-service-billing .aoit-fact + .aoit-fact {
        padding-left: 0;
        border-left: 0;
    }
}

@media (max-width: 575px) {
    .aoit-service-head-meta {
        margin-left: 0;
    }
    .aoit-service-facts {
        gap: 16px 20px;
        padding: 0;
    }
    .aoit-service-billing {
        padding: 16px;
    }
    .aoit-service-billing .aoit-fact dd {
        font-size: 18px;
    }
    .aoit-service-titles h2 {
        font-size: 19px;
    }
}


/* *****************************************************

    Record tables  (My Invoices, My Quotes)

    The generic .table rule further up gives every cell a full
    1px box in the brand line colour. That came from the legal
    pages on aoitcloud.com, where a small static table wants
    visible cells — but on a 259-row invoice list it reads as a
    spreadsheet grid, and combined with theme.css centring every
    cell there is no column edge to follow down the page.

    .table-records keeps the table (invoices and quotes are
    genuinely tabular, unlike the services list, whose content is
    a product name with metadata hanging off it) and strips it
    back to horizontal rules only.

***************************************************** */

.table.table-records th,
.table.table-records td {
    border: 0;
    border-bottom: 1px solid var(--neutral-200);
}
.table.table-records thead th {
    background: transparent;
    border-bottom: 2px solid var(--aoit-line);
    padding: 10px 12px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--aoit-ink-soft);
}
.table.table-records tbody td {
    padding: 12px;
    font-size: 13.5px;
    color: var(--aoit-ink);
}
.table.table-records tbody tr:last-child td {
    border-bottom: 0;
}

/* Left by default, amounts right, so figures line up on their last
   digit. Has to outrank theme.css's
   "body .dataTables_wrapper table.table-list td { text-align: center }",
   hence the wrapper-qualified duplicates — the same pattern the services
   list needed. */
table.table-list.table-records th,
table.table-list.table-records td,
body .dataTables_wrapper table.table-list.table-records th,
body .dataTables_wrapper table.table-list.table-records td {
    text-align: left;
}
table.table-list.table-records th.cell-amount,
table.table-list.table-records td.cell-amount,
body .dataTables_wrapper table.table-list.table-records th.cell-amount,
body .dataTables_wrapper table.table-list.table-records td.cell-amount {
    text-align: right;
    font-variant-numeric: tabular-nums;
}
table.table-list.table-records th.cell-action,
table.table-list.table-records td.cell-action,
body .dataTables_wrapper table.table-list.table-records th.cell-action,
body .dataTables_wrapper table.table-list.table-records td.cell-action {
    text-align: right;
    white-space: nowrap;
}
.table.table-records td.cell-ref {
    font-weight: 600;
}

/* The whole row is clickable (clickableSafeRedirect), so it needs to look
   it. Outranks theme.css's ".table-list > tbody > tr:hover > td". */
.table-list.table-records > tbody > tr:hover > td,
body .dataTables_wrapper table.table-list.table-records > tbody > tr:hover > td {
    background-color: var(--aoit-bg-soft);
}

/* Same soft-tint status pills as the services list. Scoped selectors
   duplicated with the DataTables wrapper prefix for the same reason as
   above. */
table.table-list.table-records .label.status,
.dataTables_wrapper table.table-list.table-records .label.status {
    display: inline-block;
    padding: 3px 10px;
    border-radius: 3px;
    font-size: 12px;
    font-weight: 600;
    background: var(--aoit-bg-soft);
    color: var(--aoit-ink-soft);
}
table.table-list.table-records .label.status.status-paid,
table.table-list.table-records .label.status.status-accepted,
.dataTables_wrapper table.table-list.table-records .label.status.status-paid,
.dataTables_wrapper table.table-list.table-records .label.status.status-accepted {
    background: var(--success-soft);
    color: var(--success-accented);
}
table.table-list.table-records .label.status.status-refunded,
table.table-list.table-records .label.status.status-payment-pending,
table.table-list.table-records .label.status.status-delivered,
table.table-list.table-records .label.status.status-onhold,
.dataTables_wrapper table.table-list.table-records .label.status.status-refunded,
.dataTables_wrapper table.table-list.table-records .label.status.status-payment-pending,
.dataTables_wrapper table.table-list.table-records .label.status.status-delivered,
.dataTables_wrapper table.table-list.table-records .label.status.status-onhold {
    background: var(--warning-soft);
    color: var(--warning-accented);
}
table.table-list.table-records .label.status.status-unpaid,
table.table-list.table-records .label.status.status-collections,
table.table-list.table-records .label.status.status-lost,
table.table-list.table-records .label.status.status-dead,
.dataTables_wrapper table.table-list.table-records .label.status.status-unpaid,
.dataTables_wrapper table.table-list.table-records .label.status.status-collections,
.dataTables_wrapper table.table-list.table-records .label.status.status-lost,
.dataTables_wrapper table.table-list.table-records .label.status.status-dead {
    background: var(--error-soft);
    color: var(--error-accented);
}

/* Ticket statuses, mapped onto the same three tints the other lists use:
   green for settled in the customer's favour, amber for in flight, grey for
   done. "Answered" is green because it means we have replied and the ball is
   back with them; Closed and Pending Close take the default grey. WHMCS only
   sets statusClass for its four built-in statuses, so the four this install
   has added are matched on the slug the template derives from their name. */
table.table-list.table-records .label.status.status-answered,
.dataTables_wrapper table.table-list.table-records .label.status.status-answered {
    background: var(--success-soft);
    color: var(--success-accented);
}
table.table-list.table-records .label.status.status-open,
table.table-list.table-records .label.status.status-customer-reply,
table.table-list.table-records .label.status.status-in-progress,
table.table-list.table-records .label.status.status-on-hold,
table.table-list.table-records .label.status.status-awaiting-customer-response,
.dataTables_wrapper table.table-list.table-records .label.status.status-open,
.dataTables_wrapper table.table-list.table-records .label.status.status-customer-reply,
.dataTables_wrapper table.table-list.table-records .label.status.status-in-progress,
.dataTables_wrapper table.table-list.table-records .label.status.status-on-hold,
.dataTables_wrapper table.table-list.table-records .label.status.status-awaiting-customer-response {
    background: var(--warning-soft);
    color: var(--warning-accented);
}
/* An admin-defined status carries its own colour as an inline background,
   which beats any of the tints above. Inline styles cannot set the text
   colour, so without this the label keeps the soft palette's grey ink and
   lands on top of a saturated fill (#224488 for On Hold in this install) at
   roughly 2:1 contrast. */
table.table-list.table-records .label.status.status-custom,
.dataTables_wrapper table.table-list.table-records .label.status.status-custom {
    color: #fff;
}

/* Column widths for the tickets list. Left to table-layout:auto the Status
   column took 375px, wider than any other, because "Awaiting Customer
   Response" is one long unbreakable label, and Subject was squeezed to 215px
   even though it is the column people actually read. Percentages rather than
   pixels so it still adapts, and the status chip is allowed to wrap rather
   than dictate the column. */
#tableTicketsList th:nth-child(1),
#tableTicketsList td:nth-child(1) {
    width: 18%;
}
#tableTicketsList th:nth-child(2),
#tableTicketsList td:nth-child(2) {
    width: 42%;
}
#tableTicketsList th:nth-child(3),
#tableTicketsList td:nth-child(3) {
    width: 14%;
}
#tableTicketsList th:nth-child(4),
#tableTicketsList td:nth-child(4) {
    width: 18%;
}
#tableTicketsList .label.status,
.dataTables_wrapper #tableTicketsList .label.status {
    white-space: normal;
}

/* Ticket reference and subject share a cell. The number is the quiet half,
   the subject is what people scan for, and an unread reply is the one thing
   on the page that has to catch the eye. */
.table-records .aoit-ticket-ref {
    margin-right: 8px;
    font-variant-numeric: tabular-nums;
    color: var(--aoit-ink-faint);
}
.table-records .aoit-ticket-subject {
    color: var(--aoit-ink);
}
.table-records .aoit-ticket-subject:hover {
    color: var(--aoit-brand);
    text-decoration: underline;
}
.table-records .aoit-ticket-subject.is-unread {
    font-weight: 700;
}

/* The outer 1px box and rounding theme.css puts on .table-list fights the
   hairline-rule treatment above. */
.dataTables_wrapper table.table-list.table-records,
body .dataTables_wrapper table.table-list.table-records {
    border: 0;
    border-radius: 0;
}

/* Dates arrive from WHMCS pre-formatted to the client's date setting, which
   in verbose form ("Wednesday, February 19th, 2025") is long enough to wrap
   in a five-column table beside the sidebar. Two lines is fine; a break
   mid-word is not.

   overflow-wrap MUST NOT be `anywhere` here. It was, and it collapsed the
   table: `anywhere` (unlike `break-word`) counts toward a cell's min-content
   width, so with table-layout:auto every column was free to shrink to a
   single character. The table rendered 445px wide inside an 855px content
   well with every cell seven lines deep. `break-word` wraps the one
   genuinely unbreakable value -- invoice references such as
   "aoitcloud_2026084162" -- without lying to the layout algorithm about how
   narrow a column can be. */
.table.table-records tbody td {
    word-break: normal;
    overflow-wrap: break-word;
}


/* *****************************************************

    Addons tab  (clientareaproductdetails.tpl)

***************************************************** */

.aoit-addon-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: 20px;
    align-items: stretch;
}
.aoit-addon-card {
    margin-bottom: 0;
}
.aoit-addon-card .card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}
/* Inside a card the tinted panel used on the overview would be a box in a
   box, so the fact row is reused for its layout only. */
.aoit-addon-card .aoit-service-billing {
    margin: 0;
    padding: 0;
    background: transparent;
    border-radius: 0;
}
.aoit-addon-card .aoit-service-billing .aoit-fact dd {
    font-size: 16px;
}
.aoit-addon-empty {
    margin: 0;
    color: var(--aoit-ink-soft);
}


/* Full-width list tables (opt-in via fullWidth in includes/tablelist.tpl).
   Counters the flex shrink-wrap described there: without this the table
   renders at its content width inside a much wider column. min-width:0 so a
   long cell cannot push the flex item past the column. */
.dataTables_wrapper > .listtable-full {
    flex: 1 1 100%;
    min-width: 0;
    /* On a phone these tables are wider than the viewport whatever is done
       to them -- the services rows carry fixed cell widths, and five columns
       of invoice data do not compress below about 580px. Without this the
       table pushed the whole document sideways (it already did before the
       flex fix above, since the shrink-wrapped .listtable took its
       max-content width). Scrolling inside the column keeps the page
       itself still. */
    overflow-x: auto;
}


/* *****************************************************

    On-screen invoice  (viewinvoice.tpl)

    Standalone page: it loads theme.min.css, invoice.min.css and
    then this file, so these rules land last and no !important
    is needed. Everything here is scoped to .invoice-container
    so it cannot reach the rest of the client area.

    Kept in step with invoicepdf.tpl — the page and the PDF
    downloaded from it should read as the same document.

***************************************************** */

.invoice-container {
    border: 1px solid var(--aoit-line);
    border-radius: 10px;
    padding: 48px;
    /* max-width plus auto margins, rather than invoice.css's flat
       `margin: 15px`. .container-fluid is width:100%, so a plain margin made
       the box 100% + 30px and pushed the document 15px past the viewport on
       anything under 895px. Pre-existing, but this file now owns the box. */
    max-width: 850px;
    margin: 24px auto 0;
}
@media (max-width: 895px) {
    .invoice-container {
        max-width: calc(100% - 24px);
        margin: 12px auto 0;
    }
}
@media (max-width: 767px) {
    .invoice-container {
        padding: 28px 20px;
    }
}

/* --- Head: logo and pay-to ----------------------------------------- */

.invoice-container .aoit-invoice-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 20px 32px;
    padding-bottom: 20px;
    border-bottom: 1px solid var(--neutral-200);
}
/* Height-capped, but only here — the PDF keeps WHMCS's own 75mm width and
   is correct as it is.

   The on-screen logo is $logo, the image set in WHMCS General Settings,
   which is a different and much larger file than the assets/img/logo.png
   the PDF uses. Unconstrained it rendered several hundred pixels tall,
   filling the top of the invoice and pushing the pay-to block underneath it
   instead of alongside.

   max-height with width:auto, so any aspect ratio scales proportionally into
   a consistent band; max-width keeps a very wide logo inside the column. */
.invoice-container .aoit-invoice-brand img {
    max-height: 60px;
    max-width: 100%;
    width: auto;
    height: auto;
}
.invoice-container .aoit-invoice-brand h2 {
    margin: 0;
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -0.025em;
    color: var(--aoit-ink);
}
.invoice-container .aoit-invoice-payto {
    margin: 0;
    text-align: right;
    font-size: 13px;
    font-style: normal;
    line-height: 1.5;
    color: var(--aoit-ink-soft);
}

/* Shared small-caps label, used above every block on the page. Mirrors
   .aoit-fact dt so the invoice and the service pages label things the
   same way. */
.invoice-container .aoit-fact-label {
    display: block;
    margin-bottom: 6px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--aoit-ink-soft);
}

/* --- Title and status ---------------------------------------------- */

.invoice-container .aoit-invoice-title {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px 20px;
    margin: 24px 0 0;
}
.invoice-container .aoit-invoice-title h1 {
    margin: 0;
    font-size: 26px;
    font-weight: 700;
    letter-spacing: -0.025em;
    color: var(--aoit-ink);
}

/* Replaces stock's 24px uppercase text in #cc0000 / #779500 / #ffcc00.
   Same soft-tint buckets as the invoice list and the PDF. */
.invoice-container .aoit-invoice-status {
    display: inline-block;
    padding: 6px 14px;
    border-radius: 3px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.invoice-container .aoit-invoice-status.is-neutral {
    background: var(--aoit-bg-soft);
    color: var(--aoit-ink-soft);
}
.invoice-container .aoit-invoice-status.is-success {
    background: var(--success-soft);
    color: var(--success-accented);
}
.invoice-container .aoit-invoice-status.is-warning {
    background: var(--warning-soft);
    color: var(--warning-accented);
}
.invoice-container .aoit-invoice-status.is-error {
    background: var(--error-soft);
    color: var(--error-accented);
}

/* --- Fact strip ----------------------------------------------------- */

.invoice-container .aoit-invoice-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 16px 28px;
    margin: 20px 0 0;
    padding: 18px 22px;
    background: var(--aoit-bg-soft);
    border-radius: 6px;
}
.invoice-container .aoit-fact {
    margin: 0;
    min-width: 0;
}
.invoice-container .aoit-fact dt {
    margin: 0 0 4px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--aoit-ink-soft);
}
.invoice-container .aoit-fact dd {
    margin: 0;
    font-size: 18px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--aoit-ink);
    font-variant-numeric: tabular-nums;
}

/* Now sits inside the payment-method column, directly under the gateway
   selector, so the button and the method it charges read as one control. */
.invoice-container .payment-btn-container {
    margin: 12px 0 0;
    text-align: left;
}
.invoice-container .payment-btn-container form {
    margin: 0;
}

/* --- Parties -------------------------------------------------------- */

.invoice-container .aoit-invoice-parties {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 24px 32px;
    margin: 28px 0;
}
.invoice-container .aoit-invoice-parties address {
    margin: 0;
    font-size: 13.5px;
    font-style: normal;
    line-height: 1.55;
    color: var(--aoit-ink);
}

/* --- Tables --------------------------------------------------------- */

/* These are plain Bootstrap tables, not DataTables, so they pick up the
   .table-records rules further up but none of the .dataTables_wrapper
   qualified ones. The extra declarations here cover that gap. */
.invoice-container .aoit-invoice-table {
    margin: 0 0 28px;
    width: 100%;
}
.invoice-container .aoit-invoice-table th,
.invoice-container .aoit-invoice-table td {
    border: 0;
    border-bottom: 1px solid var(--neutral-200);
    text-align: left;
    vertical-align: middle;
}
.invoice-container .aoit-invoice-table thead th {
    background: transparent;
    border-bottom: 2px solid var(--aoit-line);
    padding: 10px 12px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--aoit-ink-soft);
}
.invoice-container .aoit-invoice-table tbody td {
    padding: 12px;
    font-size: 13.5px;
    color: var(--aoit-ink);
}
.invoice-container .aoit-invoice-table th.cell-amount,
.invoice-container .aoit-invoice-table td.cell-amount {
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.invoice-container .aoit-invoice-table .aoit-sub-row td {
    background: var(--aoit-bg-soft);
    font-weight: 600;
}
/* Ink rather than brand green: green on an unpaid invoice would read as a
   paid-in-full signal. Colour is carried by the status pill only. */
.invoice-container .aoit-invoice-table .aoit-total-row td {
    background: var(--aoit-ink);
    border-bottom: 0;
    color: #fff;
    font-size: 15px;
    font-weight: 700;
}
.invoice-container .aoit-invoice-table td.aoit-empty {
    text-align: center;
    color: var(--aoit-ink-soft);
}
.invoice-container .aoit-invoice-taxnote {
    margin: -18px 0 24px;
    font-size: 12px;
    color: var(--aoit-ink-soft);
}

/* --- Actions -------------------------------------------------------- */

.invoice-container .aoit-invoice-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 8px;
}
.aoit-invoice-back {
    margin: 18px auto 40px;
    font-size: 13.5px;
}
.aoit-invoice-back a {
    color: var(--aoit-brand);
    font-weight: 600;
}

/* Print: drop the page furniture so a printed invoice is just the invoice. */
@media print {
    .invoice-container {
        border: 0;
        padding: 0;
        max-width: none;
    }
}


/* *****************************************************

    Action bar  (My Domains)

    Stock rendered the bulk actions as a joined btn-group of
    .btn-default, which theme.css draws as grey pills — the one
    control left in Bootstrap's default palette on a page where
    everything else is branded.

***************************************************** */

.aoit-action-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px 16px;
    margin-bottom: 18px;
}
.aoit-action-bar-group {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}
/* Buttons are separate, not a joined btn-group, so each reads as its own
   action. Bootstrap rounds only the outer edges of a .btn-group child, which
   would undo that, hence the explicit radius. */
.aoit-action-bar .btn,
.aoit-action-bar .btn-group > .btn {
    border-radius: 6px;
    font-weight: 600;
}
.aoit-action-bar .btn i {
    margin-right: 4px;
}
/* The dropdown caret sits closer than the icon gap above. */
.aoit-action-bar .dropdown-toggle::after {
    margin-left: 6px;
}
.aoit-action-bar .dropdown-menu {
    border: 1px solid var(--aoit-line);
    border-radius: 6px;
    padding: 4px;
}
.aoit-action-bar .dropdown-item {
    border-radius: 4px;
    font-size: 13.5px;
    padding: 8px 12px;
}
.aoit-action-bar .dropdown-item:hover,
.aoit-action-bar .dropdown-item:focus {
    background: var(--aoit-bg-soft);
    color: var(--aoit-ink);
}

@media (max-width: 767px) {
    /* Stacked rather than pushed to opposite ends, which at this width put a
       single button alone on its own line. */
    .aoit-action-bar {
        justify-content: flex-start;
    }
}


/* *****************************************************

    Invoices-due notice  (My Invoices)

    The sidebar's "N invoices due / Pay All" panel, lifted into
    a notice across the top now that the sidebar is gone from
    the list pages. Reuses .aoit-urgent-notice.is-warning from
    the dashboard so the two read as the same component; only
    the button treatment differs, because WHMCS renders its own
    markup inside the panel footer.

***************************************************** */

.aoit-invoices-due .aoit-urgent-notice-text p {
    margin: 0;
}
.aoit-invoices-due-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}
/* WHMCS supplies these buttons with its own classes (btn-dark for Pay All,
   a plain btn for Add Funds), so they are restyled by position rather than
   by class: the first is the primary action, the rest are quiet. */
.aoit-invoices-due-actions .btn {
    border-radius: 6px;
    font-size: 13.5px;
    font-weight: 600;
    padding: 8px 16px;
    white-space: nowrap;
    background-color: transparent;
    border: 1px solid var(--warning-accented);
    color: var(--warning-accented);
}
.aoit-invoices-due-actions .btn:first-child {
    background-color: var(--warning);
    border-color: var(--warning);
    color: #fff;
}
.aoit-invoices-due-actions .btn:first-child:hover,
.aoit-invoices-due-actions .btn:first-child:focus {
    background-color: var(--warning-accented);
    border-color: var(--warning-accented);
    color: #fff;
}
.aoit-invoices-due-actions .btn:hover,
.aoit-invoices-due-actions .btn:focus {
    background-color: var(--warning-accented);
    border-color: var(--warning-accented);
    color: #fff;
}


/* *****************************************************

    Domains list cells

***************************************************** */

/* The checkbox and SSL columns carry no header text, so they should be as
   narrow as their contents.

   width:1% is not a typo and must not be "corrected" to a pixel value. The
   table is table-layout:auto, where a width is only a suggestion and spare
   space is shared out proportionally: setting 34px still rendered the
   checkbox column at 88px. Under auto layout a percentage below the content
   width collapses the column to its minimum instead, which is the behaviour
   wanted here, and the freed space goes to the domain column. */
table.table-list.table-domains th.cell-check,
table.table-list.table-domains td.cell-check,
body .dataTables_wrapper table.table-list.table-domains th.cell-check,
body .dataTables_wrapper table.table-list.table-domains td.cell-check {
    width: 1%;
    white-space: nowrap;
    padding-right: 0;
    text-align: center;
}
table.table-list.table-domains th.cell-ssl,
table.table-list.table-domains td.cell-ssl,
body .dataTables_wrapper table.table-list.table-domains th.cell-ssl,
body .dataTables_wrapper table.table-list.table-domains td.cell-ssl {
    width: 1%;
    white-space: nowrap;
    text-align: center;
}
table.table-list.table-domains th.cell-action,
table.table-list.table-domains td.cell-action,
body .dataTables_wrapper table.table-list.table-domains th.cell-action,
body .dataTables_wrapper table.table-list.table-domains td.cell-action {
    width: 1%;
    white-space: nowrap;
    text-align: right;
}

/* "Visit the live site" — the job the domain name itself used to do, kept as
   a quiet icon so the name can link to management instead. */
.table.table-records.table-domains td.cell-domain .domain-visit {
    margin-left: 6px;
    font-size: 12px;
    color: var(--aoit-ink-soft);
}
.table.table-records.table-domains td.cell-domain .domain-visit:hover {
    color: var(--aoit-blue);
}
.table.table-records.table-domains td.cell-domain .domain-name {
    display: block;
    font-weight: 600;
    color: var(--aoit-ink);
}
.table.table-records.table-domains td.cell-domain .domain-name:hover {
    color: var(--aoit-brand);
}
/* Auto-renew is metadata about the domain, not a column of its own — set
   quiet, under the name, the same way the services list hangs a domain under
   a product name. */
.table.table-records.table-domains td.cell-domain .domain-autorenew {
    display: block;
    margin-top: 2px;
    font-size: 12px;
    color: var(--success-accented);
}
.table.table-records.table-domains td.cell-domain .domain-autorenew.is-off {
    color: var(--aoit-ink-soft);
}


/* Sub-heading inside an overview card — labels a group of facts (the SSL
   block, "What would you like to do today?") without competing with the
   product or domain name above it. */
.aoit-service-subhead {
    margin: 28px 0 12px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--aoit-ink-soft);
}
.aoit-service-subhead + .aoit-service-facts {
    margin-top: 0;
}
/* The action bar sits inside a card here, not above a table, so it does not
   need the table's bottom gap. */
.aoit-service-overview .aoit-action-bar {
    margin-bottom: 0;
}

/* "Visit the live site" under a domain name, the same quiet treatment the
   domains list gives it. */
.aoit-service-titles .aoit-service-visit {
    color: var(--aoit-ink-soft);
}
.aoit-service-titles .aoit-service-visit:hover {
    color: var(--aoit-blue);
}
.aoit-service-titles .aoit-service-visit i {
    margin-left: 3px;
    font-size: 11px;
}

/* Domain statuses reach .aoit-service-status too, so they need the same
   soft-tint buckets the list uses. Expired and Transferred Away are closed
   states; Grace, Redemption and the Pendings are "needs attention". */
.aoit-service-status.status-expired,
.aoit-service-status.status-transferred-away {
    background: var(--aoit-bg-soft);
    color: var(--aoit-ink-soft);
}
.aoit-service-status.status-grace,
.aoit-service-status.status-redemption,
.aoit-service-status.status-pending-registration,
.aoit-service-status.status-pending-transfer {
    background: var(--warning-soft);
    color: var(--warning-accented);
}

/* The SSL fact group carries an image next to its value. */
.aoit-service-facts .aoit-fact dd img {
    vertical-align: -2px;
    margin-right: 4px;
}

/* On/off state as a fact value — auto-renew on the domain overview. Green
   when on, muted when off, the same read as the domains list gives it. */
.aoit-fact dd.aoit-fact-state {
    color: var(--success-accented);
}
.aoit-fact dd.aoit-fact-state.is-off {
    color: var(--aoit-ink-soft);
}
.aoit-fact dd.aoit-fact-state i {
    margin-right: 3px;
    font-size: 13px;
    vertical-align: -1px;
}


/* Advisory panel inside an overview card — currently the "no SSL detected"
   prompt on a domain. Deliberately NOT .aoit-urgent-notice: that one is red
   or amber and means something needs doing now (an overdue invoice, a domain
   about to expire). A missing certificate is worth raising but is not an
   emergency, so it takes the informational blue instead. */
.aoit-help-notice {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 12px 20px;
    margin-top: 24px;
    padding: 14px 18px;
    border-radius: 8px;
    background: var(--info-soft);
    color: var(--info-accented);
    font-size: 13.5px;
}
.aoit-help-notice-text {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    min-width: 0;
}
.aoit-help-notice-text i {
    margin-top: 2px;
    flex-shrink: 0;
}
.aoit-help-notice-text strong {
    display: block;
}
.aoit-help-notice-text p {
    margin: 2px 0 0;
    opacity: 0.9;
}
.aoit-help-notice .btn {
    flex-shrink: 0;
}


/* *****************************************************

    Toggle switches (bootstrap-switch)

    Used in four places: the SSO toggle on Account Security,
    the marketing opt-in on Account Details and on
    registration, and "do not store this card" in the payment
    form. Andrew reported all of them rendering wrong — ON
    stacked above OFF, or an empty box.

    The handles are inline-block, so if the container is ever
    narrower than the two of them together they wrap onto a
    second line — and .bootstrap-switch has overflow:hidden,
    which is why one of them came out as an empty box rather
    than as visibly broken.

    theme.css already tries to fix this at line 9569 with
    "word-wrap: initial" on .card .bootstrap-switch. That is
    the wrong property: word-wrap only controls breaking
    INSIDE a word and does nothing about inline-block children
    wrapping to a new line. white-space:nowrap is what stops
    that, and it is applied to the container itself rather
    than only inside a card, since the payment form's switch
    is not in one.

    Note this could not be reproduced locally — with the same
    stylesheets, the same script bundle and the same markup
    the widget lays out correctly, so the trigger is something
    environmental (font metrics or zoom widening the handles
    past the container width the plugin measured). The fix is
    therefore structural: make the layout impossible to break
    rather than chase the specific trigger.

***************************************************** */

.bootstrap-switch,
.bootstrap-switch .bootstrap-switch-container {
    white-space: nowrap;
}
.bootstrap-switch .bootstrap-switch-handle-on,
.bootstrap-switch .bootstrap-switch-handle-off,
.bootstrap-switch .bootstrap-switch-label {
    float: none;
    vertical-align: top;
}

/* Brand the "on" state: the widget is initialised as -success, which
   Bootstrap's own palette draws as #28a745 rather than the brand green. */
.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-success {
    background-color: var(--aoit-brand);
    border-color: var(--aoit-brand);
    color: #fff;
}
.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-success:hover {
    background-color: var(--aoit-brand-hover);
    border-color: var(--aoit-brand-hover);
}
.bootstrap-switch {
    border-radius: 6px;
}


/* My Emails: the subject is the content, the date is metadata. */
.table.table-records.table-emails td.cell-subject {
    font-weight: 600;
}
.table.table-records.table-emails td.cell-subject i {
    margin-left: 4px;
    color: var(--aoit-ink-soft);
}
.table.table-records.table-emails td.cell-date {
    color: var(--aoit-ink-soft);
}
table.table-list.table-emails th.cell-action,
table.table-list.table-emails td.cell-action,
body .dataTables_wrapper table.table-list.table-emails th.cell-action,
body .dataTables_wrapper table.table-list.table-emails td.cell-action {
    width: 1%;
    white-space: nowrap;
    text-align: right;
}


/* *****************************************************

    Order form  (templates/orderforms/standard_cart)

    OrderFormTemplate was switched from nexus_cart to
    standard_cart (Andrew, 2026). nexus_cart is not really a
    template — 50 lines of Smarty wrapping a 784KB compiled
    React bundle — so the cart view could never be themed the
    way the rest of this client area has been. Every other page
    in the order flow (configure, domains, checkout, summary)
    was ALREADY falling through to standard_cart, which is why
    the flow looked half-branded; this makes the whole flow one
    editable codebase.

    Everything here is scoped to #order-standard_cart so it
    reaches all 24 of those templates at once and cannot leak
    into the client area.

    Note the templates are Bootstrap 3 era: they use .panel /
    .panel-heading, which Bootstrap 4 dropped. Nexus re-adds
    the .card classes alongside them in its own markup, so the
    panels do get card styling — but anything targeting .panel
    alone here is deliberate, not a typo.

***************************************************** */

/* --- Page heading ---------------------------------------------------- */

/* The order form keeps the site title band, same as every other page.

   The page's own heading sits beneath it as the step within that section —
   "Configure", "Review & Checkout" under a band reading "Shopping Cart" —
   so it is set smaller than the band's 32px rather than competing with it.

   The exception is a category listing, where the band already carries the
   category name (header.tpl sets .aoit-band-is-category when it does) and
   the page would otherwise print the very same words again. The general
   sibling combinator reaches forward from the band to the content, which is
   what lets the CSS know something only the header could work out. */
.aoit-page-heading.aoit-band-is-category ~ #main-body .header-lined h1,
.aoit-page-heading.aoit-band-is-category ~ #main-body .header-lined h1.font-size-36 {
    display: none;
}
body #order-standard_cart .header-lined {
    margin: 0 0 24px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--neutral-200);
}
body #order-standard_cart .header-lined h1,
body #order-standard_cart .header-lined h1.font-size-36 {
    margin: 0;
    font-size: 22px;
    font-weight: 700;
    letter-spacing: -0.025em;
    color: var(--aoit-ink);
}
body #order-standard_cart .header-lined p {
    margin: 6px 0 0;
    font-size: 15px;
    color: var(--aoit-ink-soft);
}
/* With the heading hidden there is nothing left to rule off. */
.aoit-page-heading.aoit-band-is-category ~ #main-body .header-lined:not(:has(p)) {
    margin: 0;
    padding: 0;
    border-bottom: 0;
}

/* --- Product cards --------------------------------------------------- */

/* Selectors match theme.css's own, which qualifies these as
   "body #order-standard_cart .cart-body .products .product" — specificity
   (1,3,1). A plain "#order-standard_cart .product" loses to that and silently
   does nothing, which is exactly what happened on the first attempt: the name
   size applied (nothing else set it) while the border, radius, header tint
   and price size were all overridden. Equal specificity plus custom.css
   loading last is what wins here, not !important. */
body #order-standard_cart .cart-body .products .product,
body #order-standard_cart .products .product {
    display: flex;
    flex-direction: column;
    height: 100%;
    border: 1px solid var(--aoit-line);
    border-radius: 10px;
    background: #fff;
    overflow: hidden;
    transition: box-shadow 120ms ease;
}
body #order-standard_cart .cart-body .products .product:hover,
body #order-standard_cart .products .product:hover {
    border-color: var(--aoit-icon);
    box-shadow: var(--aoit-shadow-sm);
}

/* The product name was 14px/400 — the same weight as the feature list under
   it, so nothing said which was the title. */
body #order-standard_cart .cart-body .products .product header,
body #order-standard_cart .products .product header {
    padding: 16px 20px;
    border-bottom: 1px solid var(--neutral-200);
    background: var(--aoit-bg-soft);
    font-size: 17px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--aoit-ink);
    text-align: left;
}
body #order-standard_cart .cart-body .products .product header .qty,
body #order-standard_cart .products .product header .qty {
    display: block;
    margin-top: 2px;
    font-size: 12px;
    font-weight: 600;
    color: var(--aoit-ink-soft);
}

body #order-standard_cart .cart-body .products .product div.product-desc,
body #order-standard_cart .products .product div.product-desc {
    flex: 1 1 auto;
    /* Small bottom padding on purpose. Measured, the space between the last
       feature and the price is padding PLUS flex slack: the description grows
       to fill whatever height the equal-height row imposes. That slack is
       what keeps every price and Order Now button on the same line across a
       row, which is the point of a pricing grid, so it stays — only the
       padding is trimmed. Remove flex:1 1 auto if unaligned prices are ever
       preferred to unequal cards. */
    padding: 18px 20px 8px;
    font-size: 13.5px;
    color: var(--aoit-ink-soft);
}
body #order-standard_cart .cart-body .products .product .product-desc ul,
body #order-standard_cart .products .product .product-desc ul {
    margin: 0;
    padding: 0;
    list-style: none;
}
body #order-standard_cart .cart-body .products .product .product-desc ul li,
body #order-standard_cart .products .product .product-desc ul li {
    padding: 5px 0;
    border-bottom: 1px solid var(--neutral-200);
    color: var(--aoit-ink);
}
body #order-standard_cart .cart-body .products .product .product-desc ul li:last-child,
body #order-standard_cart .products .product .product-desc ul li:last-child {
    border-bottom: 0;
}
body #order-standard_cart .cart-body .products .product .product-desc .feature-value,
body #order-standard_cart .products .product .product-desc .feature-value {
    font-weight: 700;
    margin-right: 4px;
}

/* Footer: price and the order button, pinned to the bottom so cards in a row
   line up whatever their feature count. */
body #order-standard_cart .cart-body .products .product footer,
body #order-standard_cart .products .product footer {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px 16px;
    padding: 16px 20px;
    border-top: 1px solid var(--neutral-200);
}
body #order-standard_cart .cart-body .products .product footer .product-pricing,
body #order-standard_cart .products .product footer .product-pricing {
    font-size: 12px;
    line-height: 1.35;
    text-align: left;
    color: var(--aoit-ink-soft);
}
/* Was 16.8px/700 in a 400-weight block — the price is the single most-read
   thing on the card. */
body #order-standard_cart .cart-body .products .product footer .product-pricing .price,
body #order-standard_cart .products .product footer .product-pricing .price {
    display: block;
    font-size: 24px;
    font-weight: 700;
    line-height: 1.2;
    color: var(--aoit-ink);
    font-variant-numeric: tabular-nums;
}
body #order-standard_cart .cart-body .products .product footer .btn-order-now,
body #order-standard_cart .products .product footer .btn-order-now {
    flex-shrink: 0;
    border-radius: 6px;
    font-weight: 600;
    padding: 9px 18px;
}

/* --- Buttons --------------------------------------------------------- */

/* .btn-default is Bootstrap's grey; it appears throughout the order flow
   (currency chooser, back links, domain actions). Blue, matching the
   secondary actions in the client area. Done here rather than by editing 29
   occurrences across the templates. */
#order-standard_cart .btn-default {
    background-color: var(--aoit-blue);
    border-color: var(--aoit-blue);
    color: #fff;
}
#order-standard_cart .btn-default:hover,
#order-standard_cart .btn-default:focus {
    background-color: var(--aoit-blue-hover);
    border-color: var(--aoit-blue-hover);
    color: #fff;
}
#order-standard_cart .btn {
    border-radius: 6px;
    font-weight: 600;
}

/* --- Sidebar and panels ---------------------------------------------- */

#order-standard_cart .cart-sidebar .list-group-item.active {
    background: var(--aoit-bg-soft);
    border-color: var(--neutral-200);
    color: var(--aoit-brand);
    font-weight: 600;
}
#order-standard_cart .panel-title,
#order-standard_cart .card-header .panel-title {
    font-size: 15px;
    font-weight: 700;
    color: var(--aoit-ink);
}

/* --- Order summary ---------------------------------------------------- */

#order-standard_cart .order-summary,
#order-standard_cart .summary-container {
    border-radius: 10px;
}
#order-standard_cart .order-summary .total,
#order-standard_cart .summary-container .total {
    font-weight: 700;
    color: var(--aoit-ink);
}

/* --- Forms ------------------------------------------------------------ */

/* The order form's fields are styled by the block near the top of this file
   along with the rest of the client area. They need repeating here purely to
   win on specificity: theme.min.css carries `body #order-standard_cart
   .form-control { border-radius: 8px }` and all.min.css carries
   `#order-standard_cart .form-control { border: 1px solid #ddd }`, both of
   which outrank a bare `.form-control`. Same values as above — if you change
   the field style, change it in both places. */
body #order-standard_cart .form-control,
body #order-standard_cart .custom-select,
body #order-standard_cart .field {
    border: 1px solid var(--aoit-line);
    border-radius: 6px;
    padding: 10px 14px;
    font-size: 15px;
    height: auto;
    color: var(--aoit-ink);
    background-color: #fff;
}
body #order-standard_cart .custom-select,
body #order-standard_cart select.form-control {
    padding-right: 32px;
}
body #order-standard_cart .form-control:focus,
body #order-standard_cart .custom-select:focus,
body #order-standard_cart .field:focus {
    outline: 0;
    border-color: var(--aoit-line);
    box-shadow: 0 0 0 2px var(--aoit-brand);
}

/* Product grid gutter. Bootstrap's default 15px column padding puts 30px
   between cards, which reads as cramped now the cards have real borders and
   tinted headers. 20px each side gives 40px. The row's negative margin has to
   move with it or the grid overhangs its container. */
body #order-standard_cart .products .row {
    margin-left: -20px;
    margin-right: -20px;
    /* Vertical spacing has to live on the ROW, not on the card.
       products.tpl opens a new .row after every second product, and
       row-eq-height makes each column a flex item with the card stretched to
       height:100%. A margin-bottom on the card is then absorbed by that
       stretch — it computed as 24px and produced a measured gap of exactly
       0 between the Personal and Unlimited rows. */
    margin-bottom: 40px;
}
body #order-standard_cart .products .row:last-child {
    margin-bottom: 0;
}
body #order-standard_cart .products .row > [class*="col-"] {
    padding-left: 20px;
    padding-right: 20px;
}

/* The feature list sits tighter now the doubled <br> in the product data is
   collapsed (see products.tpl) — this keeps the two halves of the block,
   description text and the colon-separated features, on the same rhythm. */
body #order-standard_cart .cart-body .products .product .product-desc p,
body #order-standard_cart .products .product .product-desc p {
    margin: 0;
    line-height: 1.9;
}
body #order-standard_cart .cart-body .products .product .product-desc ul,
body #order-standard_cart .products .product .product-desc ul {
    margin-top: 4px;
    /* Bootstrap gives every ul a 1rem bottom margin. Combined with the
       description block's own bottom padding that left 42px of empty space
       between the last feature and the price — read as "a lot of space under
       the price". The block's padding is the only spacing wanted here. */
    margin-bottom: 0;
}


/* *****************************************************

    Domain step  (standard_cart/configureproductdomain.tpl,
    domainregister.tpl, domaintransfer.tpl)

    Stock renders the three choices — register / transfer /
    use your own — as bare radio buttons stacked inside one
    outer box, so the thing you are actually choosing between
    has no shape. Each choice becomes its own card here, and
    the selected one is marked.

***************************************************** */

/* The outer box goes; each option carries its own border instead, so the
   choices read as three things rather than one list. */
body #order-standard_cart .domain-selection-options {
    border: 0;
    border-radius: 0;
    background: transparent;
    padding: 0;
}
body #order-standard_cart .domain-selection-options .option {
    margin-bottom: 12px;
    padding: 16px 20px;
    border: 1px solid var(--aoit-line);
    border-radius: 8px;
    background: #fff;
    transition: border-color 120ms ease, background-color 120ms ease;
}
body #order-standard_cart .domain-selection-options .option:last-child {
    margin-bottom: 0;
}
body #order-standard_cart .domain-selection-options .option:hover {
    border-color: var(--aoit-icon);
    box-shadow: var(--aoit-shadow-sm);
}
/* The chosen option is marked, so the open panel below it is obviously
   attached to a choice rather than floating. :has() is doing real work here
   but degrades safely — without it every option simply keeps the resting
   border, which is exactly the stock appearance. */
body #order-standard_cart .domain-selection-options .option:has(input[type="radio"]:checked) {
    border-color: var(--aoit-brand);
    background: var(--success-soft);
}
body #order-standard_cart .domain-selection-options .option > label,
body #order-standard_cart .domain-selection-options .option > p {
    margin: 0;
    font-size: 15px;
    font-weight: 600;
    color: var(--aoit-ink);
    cursor: pointer;
}
body #order-standard_cart .domain-selection-options .option input[type="radio"] {
    margin-right: 8px;
}

/* The panel that opens under the chosen option. */
body #order-standard_cart .domain-input-group {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--neutral-200);
}
body #order-standard_cart .domain-selection-options .option:has(input:checked) .domain-input-group {
    border-top-color: rgba(31, 122, 62, 0.25);
}

/* WHMCS's AI domain search is a <textarea>, not an input, and its placeholder
   runs to three lines of example text. Given a sensible fixed height and the
   theme's field styling so it reads as one control rather than a comment box. */
body #order-standard_cart .domain-input-group textarea {
    min-height: 84px;
    padding: 10px 14px;
    border: 1px solid var(--aoit-line);
    border-radius: 6px;
    font-size: 14px;
    line-height: 1.5;
    resize: none;
}
body #order-standard_cart .domain-input-group textarea:focus {
    border-color: var(--aoit-brand);
    box-shadow: 0 0 0 0.2rem var(--aoit-focus-ring);
    outline: 0;
}

/* Include TLDs / Maximum Length / Safe Search sat tight under the field with
   no breathing room. */
body #order-standard_cart .domain-checker-advanced .domains-row + .row,
body #order-standard_cart .domain-checker-advanced .row + .row {
    margin-top: 10px;
}
body #order-standard_cart .domain-checker-advanced .multiselect {
    margin-right: 8px;
}
body #order-standard_cart .domain-input-group .input-group-text {
    background: var(--aoit-bg-soft);
    border-color: var(--aoit-line);
    color: var(--aoit-ink-soft);
}


/* *****************************************************

    Cart and checkout  (standard_cart/viewcart.tpl,
    checkout.tpl, ordersummary.tpl)

***************************************************** */

/* --- The primary CTA -------------------------------------------------- */

/* The Checkout button rendered near-black. Two things did it: .btn-success is
   Bootstrap's #28a745 rather than the brand green, and theme.css then paints
   this specific button with

       body #order-standard_cart .text-right .btn-checkout { background: var(--bg-inverted) }

   which is the inverted (near-black) surface colour. That is the single most
   important button in the whole order flow, so it takes the brand green like
   every other primary action. Selector matches theme's shape so equal
   specificity plus custom.css loading last decides it. */
body #order-standard_cart .text-right .btn-checkout,
body #order-standard_cart .btn-checkout {
    background: var(--aoit-brand);
    border-color: var(--aoit-brand);
    color: #fff;
}
body #order-standard_cart .text-right .btn-checkout:hover,
body #order-standard_cart .btn-checkout:hover,
body #order-standard_cart .btn-checkout:focus {
    background: var(--aoit-brand-hover);
    border-color: var(--aoit-brand-hover);
    color: #fff;
}
/* .btn-lg carries its own 8px radius, which left the single most prominent
   button on the page rounder than everything around it. rounded-md is 6px
   here as everywhere else. */
body #order-standard_cart .text-right .btn-checkout,
body #order-standard_cart .btn-lg {
    border-radius: 6px;
}
/* "Continue Shopping" rendered at 10px in near-black: too small to read and
   too dark to look like the secondary action it is. .btn-link gives it button
   padding it does not need either. Sized as a proper text link, in the brand
   green used for links across the theme. */
body #order-standard_cart .btn-continue-shopping,
body #order-standard_cart .text-right .btn-continue-shopping {
    /* Block and centred under the full-width Checkout button. Its container
       is .text-right, so an inline-block link ends up hard against the right
       edge of the panel, hanging off the corner of the button above it. */
    display: block;
    width: 100%;
    margin-top: 12px;
    padding: 0;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.4;
    text-align: center;
    color: var(--aoit-brand);
    text-decoration: none;
}
body #order-standard_cart .btn-continue-shopping:hover,
body #order-standard_cart .btn-continue-shopping:focus {
    color: var(--aoit-brand-hover);
    text-decoration: underline;
}
/* Total Due Today stacked the figure above its own label, both left aligned
   and at a smaller, lighter size than the Totals line right above it — so the
   most important number in the panel read as the least important. Laid out as
   label-left / figure-right like every other row in the summary, with the
   figure given the weight its position deserves. The markup prints the amount
   first, hence the explicit order. */
body #order-standard_cart .total-due-today {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--aoit-line);
}
body #order-standard_cart .order-summary .total-due-today > span {
    order: 1;
    font-size: 13.5px;
    color: var(--aoit-ink-soft);
}
/* Only viewcart.tpl gives the figure id="totalDueToday" — configureproduct,
   domain-renewals and service-renewals print the same row with the class
   alone, where standard_cart's own "font-size: 2.3em" would otherwise take
   over and the flex order would never be set, putting the figure on the left
   and its label on the right. Same values as the #totalDueToday rule further
   down, which exists because an ID beats any number of classes; change both
   together. */
body #order-standard_cart .order-summary .total-due-today .amt {
    order: 2;
    font-size: 18px;
    font-weight: 700;
    color: var(--aoit-ink);
    font-variant-numeric: tabular-nums;
}
/* The "Add to Cart" buttons on the recommendations came through on stock
   Nexus's lime (#99BB3A), the only non-brand green left on the page. The
   .mc-promo in the selector is not decoration: standard_cart's all.min.css
   paints these with "#order-standard_cart .mc-promo .btn-add", and a rule
   without that class loses to it however many other classes it carries. */
body #order-standard_cart .mc-promo .btn-add,
body #order-standard_cart .mc-promo .btn-add:link {
    background-color: var(--aoit-brand);
    border-color: var(--aoit-brand);
    color: #fff;
}
body #order-standard_cart .mc-promo .btn-add:hover,
body #order-standard_cart .mc-promo .btn-add:focus {
    background-color: var(--aoit-brand-hover);
    border-color: var(--aoit-brand-hover);
    color: #fff;
}
/* Applying a promo code is an optional side action, but it rendered as a
   full-width solid blue bar — heavier than "Add to Cart" and competing with
   Checkout for attention. Outlined instead, so it reads as available without
   shouting, and sized to the theme's 15px/600 button text. */
body #order-standard_cart .promo .btn-default,
body #order-standard_cart .promo .btn-block.btn-default {
    background-color: #fff;
    border-color: var(--aoit-line);
    color: var(--aoit-ink);
    font-size: 15px;
    font-weight: 600;
    padding: 10px 14px;
}
body #order-standard_cart .promo .btn-default:hover,
body #order-standard_cart .promo .btn-default:focus {
    background-color: var(--aoit-brand);
    border-color: var(--aoit-brand);
    color: #fff;
}
/* The tab above it sat at 11.2px, smaller than any other label on the page. */
body #order-standard_cart .nav-tabs .nav-link {
    font-size: 13px;
    font-weight: 600;
}

/* Disabled means "you have not finished yet", not "this is broken" — keep the
   green but drop it back so it reads as waiting rather than as a dead
   control. */
body #order-standard_cart .btn-checkout.disabled,
body #order-standard_cart .btn-checkout:disabled {
    background: var(--aoit-brand);
    border-color: var(--aoit-brand);
    opacity: 0.45;
}
/* Bootstrap's own green, wherever the order form uses it. */
body #order-standard_cart .btn-success {
    background-color: var(--aoit-brand);
    border-color: var(--aoit-brand);
}
body #order-standard_cart .btn-success:hover,
body #order-standard_cart .btn-success:focus {
    background-color: var(--aoit-brand-hover);
    border-color: var(--aoit-brand-hover);
}

/* --- Order summary ---------------------------------------------------- */

/* It had no shape at all: theme.css gives it padding:0 and the page
   background, and all.min.css sets background #666 underneath that. It is
   the running total of the order and should look like a panel. */
body #order-standard_cart .order-summary,
#order-standard_cart .order-summary {
    padding: 20px 22px;
    border: 1px solid var(--aoit-line);
    border-radius: 10px;
    background-color: #fff;
}
body #order-standard_cart .order-summary h2,
body #order-standard_cart .order-summary h2.font-size-30 {
    margin: 0 0 14px;
    padding: 0 0 12px;
    /* Stock boxes this heading on all four sides, which is what still read as
       a rectangle inside the panel after .summary-container was flattened.
       A single rule underneath does the separating. */
    border: 0;
    border-bottom: 1px solid var(--neutral-200);
    border-radius: 0;
    background: transparent;
    font-size: 18px;
    font-weight: 700;
    color: var(--aoit-ink);
    text-align: left;
}
/* The totals are built from pull-left / pull-right floats. Flex puts the
   label and the figure on one line without relying on clearing, and lets the
   figure sit on tabular numerals so the column lines up. */
body #order-standard_cart .order-summary .subtotal,
body #order-standard_cart .order-summary .bordered-totals > div,
body #order-standard_cart .order-summary .recurring-totals {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 7px 0;
    font-size: 13.5px;
}
body #order-standard_cart .order-summary .subtotal .float-left,
body #order-standard_cart .order-summary .subtotal .float-right,
body #order-standard_cart .order-summary .bordered-totals .float-left,
body #order-standard_cart .order-summary .bordered-totals .float-right,
body #order-standard_cart .order-summary .recurring-totals .float-left,
body #order-standard_cart .order-summary .recurring-totals .float-right {
    float: none !important;
}
/* Each of those rows also carries .clearfix, whose ::after is display:block
   with content "". Under floats it did nothing visible; once the row became
   a flex container it became a THIRD flex item, and space-between pinned it
   to the right edge and parked the figure in the middle of the row instead.
   The gap it left varied with the label width - 61px on Subtotal, 43px on
   VAT, 35px on Totals - which is what made the column look ragged. The rows
   no longer use floats, so the pseudo has nothing left to clear. */
body #order-standard_cart .order-summary .subtotal::before,
body #order-standard_cart .order-summary .subtotal::after,
body #order-standard_cart .order-summary .bordered-totals > div::before,
body #order-standard_cart .order-summary .bordered-totals > div::after,
body #order-standard_cart .order-summary .recurring-totals::before,
body #order-standard_cart .order-summary .recurring-totals::after {
    display: none;
}
body #order-standard_cart .order-summary .float-right {
    font-variant-numeric: tabular-nums;
    text-align: right;
}
body #order-standard_cart .order-summary .bordered-totals {
    border-top: 1px solid var(--neutral-200);
    border-bottom: 1px solid var(--neutral-200);
    margin: 6px 0;
}
body #order-standard_cart .order-summary .recurring-totals {
    padding-top: 10px;
    font-weight: 700;
    font-size: 15px;
    color: var(--aoit-ink);
}

/* --- Totals and line costs -------------------------------------------- */

/* .cost rendered at 10px, which is smaller than the small print around it. */
body #order-standard_cart .cost {
    font-size: 13.5px;
    font-variant-numeric: tabular-nums;
}

/* "Total Due Today" is a Bootstrap success alert — a green box in the middle
   of the page competing with the Checkout button for attention. Quietened to
   the tinted panel used for facts elsewhere, with the figure carrying the
   weight instead of the background. */
/* This used to draw a bordered, filled box around the figure alone, which
   left "Total Due Today" stranded underneath it as a caption for a box it
   was not inside. The row now reads label-left / figure-right like Subtotal,
   VAT and Totals above it, separated by a rule rather than a panel, and the
   figure is the largest number in the summary because it is the one that
   matters. */
body #order-standard_cart #totalDueToday {
    order: 2;
    color: var(--aoit-ink);
    font-size: 18px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}
body #order-standard_cart #totalDueToday strong,
body #order-standard_cart #totalDueToday #totalCartPrice {
    font-size: 22px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* --- Checkout form ---------------------------------------------------- */

body #order-standard_cart #frmCheckout .form-group label,
body #order-standard_cart #frmCheckout label.control-label {
    font-size: 13px;
    font-weight: 600;
    color: var(--aoit-ink);
}
/* Sign-in vs sign-up switch at the top of checkout: stock uses btn-info and
   btn-warning, which land as teal and amber. */
body #order-standard_cart #btnAlreadyRegistered,
body #order-standard_cart #btnNewUserSignup {
    background-color: var(--aoit-blue);
    border-color: var(--aoit-blue);
    color: #fff;
}
body #order-standard_cart #btnAlreadyRegistered:hover,
body #order-standard_cart #btnNewUserSignup:hover {
    background-color: var(--aoit-blue-hover);
    border-color: var(--aoit-blue-hover);
    color: #fff;
}


/* *****************************************************

    Choose a department  (supportticketsubmit-stepone.tpl)

    Each department is a card and the whole card is the link,
    so a name and its description belong to each other visibly
    and the click target is the size of the choice.

***************************************************** */

.aoit-dept-intro {
    margin: 0 0 20px;
    font-size: 15px;
    color: var(--aoit-ink-soft);
}

.aoit-dept-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 16px;
    align-items: stretch;
}

/* A link, not a div with a handler: it stays keyboard reachable, works with
   middle-click and "open in new tab", and needs no JS. */
.aoit-dept-card {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 20px;
    border: 1px solid var(--aoit-line);
    border-radius: 10px;
    background: #fff;
    color: var(--aoit-ink);
    text-decoration: none;
    transition: border-color 120ms ease, box-shadow 120ms ease, background-color 120ms ease;
}
/* Matches aoitcloud.com's card convention exactly:
   "hover:border-icon hover:shadow-sm transition-colors" — the border moves to
   the accent cyan and a small shadow appears. The background does NOT change,
   and the border does not go green: on the marketing site green appears on
   hover only as bg-brand-hover, which is buttons. */
.aoit-dept-card:hover,
.aoit-dept-card:focus {
    border-color: var(--aoit-icon);
    box-shadow: var(--aoit-shadow-sm);
    color: var(--aoit-ink);
    text-decoration: none;
}
.aoit-dept-card:focus-visible {
    outline: 0;
    box-shadow: 0 0 0 0.2rem var(--aoit-focus-ring);
}

.aoit-dept-icon {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 8px;
    background: var(--aoit-bg-soft);
    color: var(--aoit-blue);
    font-size: 17px;
}
.aoit-dept-card:hover .aoit-dept-icon {
    color: var(--aoit-icon);
}

/* min-width:0 so a long description wraps inside the card rather than
   forcing the grid column wider. */
.aoit-dept-text {
    flex: 1 1 auto;
    min-width: 0;
}
.aoit-dept-name {
    display: block;
    font-size: 16px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--aoit-ink);
}
.aoit-dept-desc {
    display: block;
    margin-top: 4px;
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--aoit-ink-soft);
}

/* The arrow is decoration for the affordance, so it is aria-hidden in the
   markup and simply slides on hover. */
.aoit-dept-go {
    flex: 0 0 auto;
    margin-top: 12px;
    font-size: 13px;
    color: var(--aoit-ink-soft);
    transition: transform 120ms ease, color 120ms ease;
}
.aoit-dept-card:hover .aoit-dept-go {
    color: var(--aoit-icon);
    transform: translateX(3px);
}

@media (prefers-reduced-motion: reduce) {
    .aoit-dept-card,
    .aoit-dept-go {
        transition: none;
    }
    .aoit-dept-card:hover .aoit-dept-go {
        transform: none;
    }
}


/* *****************************************************

    Configure-product step  (standard_cart/configureproduct.tpl)

***************************************************** */

/* The summary read as a box inside a box: the panel has 20/22 padding and the
   .summary-container inside it adds another 16, so the totals sat inset from
   the heading by 36px in total. The panel is the box; the container just
   groups the rows. */
body #order-standard_cart .order-summary .summary-container {
    padding: 0;
    background: transparent;
}

/* The product being configured. Stock renders it as a bare bordered box with
   the name at body size; it is the subject of the page, so it gets the same
   header treatment as a product card. */
body #order-standard_cart .cart-body .product-info,
body #order-standard_cart .product-info {
    border: 1px solid var(--aoit-line);
    border-radius: 8px;
    padding: 16px 18px;
    background: var(--aoit-bg-soft);
}
body #order-standard_cart .product-info .product-title,
body #order-standard_cart .product-info h2 {
    font-size: 17px;
    font-weight: 700;
    color: var(--aoit-ink);
}

/* "Configurable Options" and "Additional Information" are
   div.sub-heading > span.primary-bg-color — a centred 16px/400 caption sitting
   on a rule, which reads as a divider rather than as a heading for the fields
   under it. (Written against <legend> first, which matched nothing here: the
   markup uses neither fieldset nor legend.) Same small-caps section label the
   rest of the client area uses, left-aligned with its fields. */
body #order-standard_cart .sub-heading {
    /* all.min.css builds this as a caption straddling a rule: the div is
       "height: 0" and the span is pulled up with "position: relative;
       top: -11px". Removing the rule without undoing the zero height left
       the block with no height at all, so the "(required fields...)" note
       inside it overflowed and landed on top of the Operating System label
       below — an 11px overlap. Both halves of the mechanism have to go. */
    height: auto;
    margin: 24px 0 12px;
    border: 0;
    text-align: left;
}
body #order-standard_cart .sub-heading span,
body #order-standard_cart .sub-heading .primary-bg-color {
    position: static;
    top: auto;
    display: block;
    padding: 0;
    background: transparent;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--aoit-ink-soft);
}
/* "(required fields are marked with *)" sits INSIDE that same span, so it
   inherited the small-caps treatment and rendered as 8.8px uppercase italic.
   It is a sentence, not a label. */
body #order-standard_cart .sub-heading i,
body #order-standard_cart .sub-heading small {
    display: block;
    margin-top: 4px;
    font-size: 12px;
    font-weight: 400;
    font-style: normal;
    letter-spacing: 0;
    text-transform: none;
    color: var(--aoit-ink-soft);
}

/* Stock uses Bootstrap's alert-warning for the "contact our sales team"
   prompt, which lands as #fff3cd — a yellow that appears nowhere else on the
   site. Brought onto the amber the rest of the theme uses. */
body #order-standard_cart .alert-warning.info-text-sm,
body #order-standard_cart .alert-warning {
    background-color: var(--warning-soft);
    border-color: var(--warning);
    color: var(--warning-accented);
    border-radius: 8px;
}
body #order-standard_cart .alert-warning a {
    color: var(--warning-accented);
    font-weight: 600;
    text-decoration: underline;
}


/* *****************************************************

    ** View Ticket **

    Full width, with the ticket facts across the top instead of in a sidebar
    panel. The head and the fact grid reuse .aoit-service-head and
    .aoit-service-facts from the service and domain detail pages, so all three
    detail pages open the same way.

***************************************************** */

/* No icon tile on this page, so the heading has nothing to sit beside and
   the ident block should not reserve the gap for one. */
.aoit-service-head-plain .aoit-service-ident {
    gap: 0;
}

.aoit-ticket-thread {
    margin-top: 24px;
}

/* One card per reply. Stock stacked them inside a single shadowed panel with
   only a horizontal rule between, and padded each message by 1rem on top of
   the panel's own padding. Same recipe as .card above, which is the one used
   on aoitcloud.com: --aoit-line border, 10px radius, white, no shadow. */
.aoit-ticket-reply {
    padding: 16px 18px;
    border: 1px solid var(--aoit-line);
    border-radius: 10px;
    background: #fff;
}
.aoit-ticket-reply + .aoit-ticket-reply {
    margin-top: 12px;
}
/* A staff reply is marked by taking the brand green for its whole border,
   at the same 1px as every other card. It had a fill instead, which was
   --aoit-bg-soft, the SAME colour as #main-body: contrast ratio 1.00 against
   the page behind it, so it was not a faint tint, it was no tint at all.
   A border colour costs no layout and no fill, so both kinds of card keep
   identical padding and their text starts on the same vertical line. */
.aoit-ticket-reply.is-staff {
    border-color: var(--aoit-brand);
}

.aoit-ticket-message {
    font-size: 14px;
    line-height: 1.6;
    color: var(--aoit-ink);
}
.aoit-ticket-message > *:first-child {
    margin-top: 0;
}
.aoit-ticket-message > *:last-child {
    margin-bottom: 0;
}
.aoit-ticket-ip {
    margin-top: 12px;
    font-size: 12px;
    color: var(--aoit-ink-faint);
}

/* Who and when, at the foot of the card and deliberately quiet: the message
   is what you are here to read (Andrew, 2026). Replaces stock's "Posted by
   <name> on <date>" heading above the message plus a floating requestor
   badge. */
.aoit-ticket-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 4px 12px;
    margin-top: 14px;
    padding-top: 10px;
    border-top: 1px solid var(--neutral-200);
    font-size: 12px;
    color: var(--aoit-ink-faint);
}
.aoit-ticket-author {
    font-weight: 600;
    color: var(--aoit-ink-soft);
}
/* The requestor role, which used to be a coloured badge floated to the right
   of the message. It is reference detail about the person, so it sits with
   their name rather than competing with the message. */
.aoit-ticket-role {
    padding: 2px 7px;
    border-radius: 3px;
    background: var(--aoit-bg-soft);
    font-weight: 600;
    color: var(--aoit-ink-soft);
}
.aoit-ticket-reply.is-staff .aoit-ticket-role {
    background: #fff;
}
/* Name, role and IP travel together on the left. */
.aoit-ticket-who {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 10px;
    min-width: 0;
}
.aoit-ticket-ip {
    color: var(--aoit-ink-faint);
}
.aoit-ticket-date {
    flex: 0 0 auto;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.aoit-ticket-attachments {
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--neutral-200);
    font-size: 13px;
}
/* Stock's attachment markup is a <ul> of
   <a><span><figure><i/></figure><div class="caption">name</div></span></a>,
   and figure and .caption are both block, so every attachment rendered as a
   list bullet, then the file icon on its own line, then the filename on a
   third. Each one is now a single chip: icon and name side by side, bordered
   like the rest of the theme, several per row. */
.aoit-ticket-attachments .attachment-list {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 10px 0 0;
    padding: 0;
    list-style: none;
}
.aoit-ticket-attachments .attachment-list li {
    margin: 0;
}
.aoit-ticket-attachments .attachment-list li > a,
.aoit-ticket-attachments .attachment-list li > span {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    max-width: 100%;
    padding: 6px 12px;
    border: 1px solid var(--aoit-line);
    border-radius: 6px;
    background: #fff;
    color: var(--aoit-ink);
    text-decoration: none;
}
.aoit-ticket-attachments .attachment-list li > a > span {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}
.aoit-ticket-attachments .attachment-list li > a:hover {
    border-color: var(--aoit-icon);
    box-shadow: var(--aoit-shadow-sm);
}
.aoit-ticket-attachments .attachment-list figure {
    flex: 0 0 auto;
    margin: 0;
    color: var(--aoit-ink-faint);
}
.aoit-ticket-attachments .attachment-list .caption {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* A removed attachment is not a link, so it should not look like one. */
.aoit-ticket-attachments .attachment-list li > span {
    color: var(--aoit-ink-faint);
    border-style: dashed;
}
.aoit-ticket-rating {
    margin-top: 12px;
}

/* The reply form, flattened to match the cards above it rather than
   Bootstrap's shadowed panel. */
/* The reply form is a .card, and the generic .card rule already gives it the
   site's border, radius and no shadow. All it needs here is the gap above. */
#ticketReplyContainer {
    margin-top: 24px;
}
#ticketReplyContainer .card-title {
    font-size: 15px;
    font-weight: 700;
    color: var(--aoit-ink);
}


/* *****************************************************

    ** Knowledgebase **

***************************************************** */

/* The article excerpts were invisible: theme.css sets

       .kb-article-item small { color: var(--bg-lifted) }

   which paints the text in a BACKGROUND token. Nexus never defines
   --bg-lifted itself, so the value comes from the palette at the top of this
   file, where it is #F6F7F9 — measured at 1.07:1 against the white card, i.e.
   not faint, unreadable. It is not a reveal-on-hover trick either: the row's
   hover background is the same token, so the text would stay invisible on
   hover too. Matching theme.css's selector shape to override it. */
.kb-article-item small,
.list-group .kb-article-item small {
    color: var(--aoit-ink-soft);
    font-size: 13px;
    line-height: 1.5;
}
/* The article rows are Bootstrap list-group items, so they came with
   rgba(0,0,0,.125) rules rather than the theme's own. */
.kb-article-item,
.list-group-flush .kb-article-item {
    border-color: var(--neutral-200);
    color: var(--aoit-ink);
}
.kb-article-item:hover {
    background-color: var(--aoit-bg-soft);
}

/* The article list rows came through on Bootstrap's list-group defaults:
   16px text, which is two steps above the 13.5-14px the rest of the client
   area uses for list and table content. Horizontal padding matches the card's
   own 24px so the row text lines up with the card title above it. */
.kb-article-item,
.list-group-flush .kb-article-item {
    padding: 14px 24px;
    font-size: 14px;
}
.kb-article-item small,
.list-group .kb-article-item small {
    /* Stock sets a 12px margin on all four sides, which pushed the excerpt in
       from the left independently of the 25px indent meant to line it up
       under the title. Top spacing only. */
    margin: 6px 0 0;
}

/* Back to the index: a navigation link, not a button. */
.aoit-kb-back {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 4px;
    font-size: 14px;
    font-weight: 600;
    color: var(--aoit-brand);
}
.aoit-kb-back:hover {
    color: var(--aoit-brand-hover);
    text-decoration: underline;
}

/* Category cards: 8px from theme.css, against the 10px every other card on
   the site uses. */
.card.kb-category,
.primary-content .card.kb-category {
    border-radius: 10px;
}
.kb-category .card-body {
    color: var(--aoit-ink);
}
.kb-category:hover {
    border-color: var(--aoit-icon);
    box-shadow: var(--aoit-shadow-sm);
}

/* The search box is an .input-group-lg, which brings Bootstrap's own 16px
   text, 8px radius and .5rem/1rem padding — none of which match the fields
   used everywhere else. Sized to the standard field, with the group's outer
   corners rounded and the seam between input and button left square. */
/* Same specificity story as the button below: Bootstrap sizes the input
   through ".input-group-lg > .form-control", which pins an explicit
   height (1.5em + 1rem + 2px = 40.5px) and left the input 4px shorter than
   the button beside it. */
.kb-search .form-control,
.kb-search.input-group-lg > .form-control {
    height: auto;
    padding: 10px 14px;
    font-size: 15px;
    line-height: 1.5;
    border-top-left-radius: 6px;
    border-bottom-left-radius: 6px;
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}
/* Bootstrap sizes this button through
   ".input-group-lg > .input-group-append > .btn" (0,3,0), so a .kb-search .btn
   rule at (0,2,0) loses on font-size and radius even though it wins on
   padding. Matching the shape and adding the group class settles it. */
.kb-search .btn,
.kb-search.input-group-lg > .input-group-append > .btn {
    padding: 10px 22px;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.5;
    border-top-right-radius: 6px;
    border-bottom-right-radius: 6px;
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}


/* *****************************************************

    ** Empty / policy states **

    A page whose whole content is one message: registration disabled, and
    anywhere else the same shape is wanted later. Deliberately NOT an alert:
    red says something went wrong, and a settled policy has not gone wrong.

***************************************************** */

.aoit-empty-state {
    max-width: 520px;
    margin: 8px auto 32px;
    padding: 32px 24px;
    border: 1px solid var(--aoit-line);
    border-radius: 10px;
    background: #fff;
    text-align: center;
}
.aoit-empty-state-title {
    margin: 0 0 10px;
    font-size: 20px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--aoit-ink);
}
.aoit-empty-state-text {
    margin: 0 auto;
    max-width: 42ch;
    font-size: 14px;
    line-height: 1.6;
    color: var(--aoit-ink-soft);
}
.aoit-empty-state-actions {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    margin-top: 22px;
}
.aoit-empty-state-link {
    font-size: 14px;
    font-weight: 600;
    color: var(--aoit-brand);
}
.aoit-empty-state-link:hover {
    color: var(--aoit-brand-hover);
    text-decoration: underline;
}


/* *****************************************************

    ** Login **

***************************************************** */

.aoit-login-intro {
    margin: 0 0 24px;
    font-size: 14px;
    color: var(--aoit-ink-soft);
}
.aoit-login-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    margin-top: 4px;
}
.aoit-login-remember {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-size: 14px;
    color: var(--aoit-ink-soft);
    cursor: pointer;
}
.aoit-login-remember .form-check-input {
    position: static;
    margin: 0;
}


/* *****************************************************

    ** Announcements **

***************************************************** */

/* Post titles rendered at 32px, the exact size of the page's own h1, so each
   item in the list competed with the page heading. 19px is the theme's h3
   step and puts them a clear level below it. They stay brand green because
   they are links. */
.announcements .announcement h2 {
    margin: 0 0 6px;
    font-size: 19px;
    font-weight: 700;
    line-height: 1.3;
}
.announcements .announcement h2 a {
    color: var(--aoit-brand);
}
.announcements .announcement h2 a:hover {
    color: var(--aoit-brand-hover);
    text-decoration: underline;
}
.announcements .announcement .list-inline {
    margin-bottom: 10px;
    font-size: 13px;
}

/* Stock Nexus styles the excerpt as a pull quote:

       .announcements .announcement article {
           padding: 1rem;
           background-color: var(--bg-lifted);
           border-left: 4px solid var(--border-lifted);
       }

   A heavy left bar and a tinted panel is the convention for quoting someone
   else. This is your own summary of your own announcement, so it should read
   as body text. The tint was also --bg-lifted, the same #F6F7F9 as the page
   behind the card, which is the third place that token has turned up being
   used for something it is not. */
.announcements .announcement article,
body .announcements .announcement article {
    margin-bottom: 12px;
    padding: 0;
    border-left: 0;
    background: transparent;
    font-size: 14px;
    line-height: 1.6;
    color: var(--aoit-ink-soft);
}

/* Items were separated by 65px of nothing. A rule and less air reads as a
   list rather than as several pages stacked up. */
.announcements .announcement {
    /* Stock carries a 64px bottom margin on every item, which stacked on top
       of the separator spacing below and left 88px between posts. The rule
       does the separating now. */
    margin-bottom: 0;
}
.announcements .announcement + .announcement {
    margin-top: 24px;
    padding-top: 24px;
    border-top: 1px solid var(--neutral-200);
}


/* Knowledgebase article body.

   This is the only long-form prose in the client area, and it was running on
   Bootstrap defaults: 16px text in a stray #474747, 35px between paragraphs,
   20px between list items, and an h3 at 24px against the article's own 25px
   title, so a section heading inside the article was almost the same size as
   the article itself.

   The scale below is aoitcloud.com's .legal-prose, copied value for value
   from wp-content/themes/aoit-cloud/src/input.css rather than approximated:
   15px/1.75 ink-soft body, 21px section headings, 16.5px sub-headings, 1rem
   between paragraphs, 0.375rem between list items, blue underlined links.
   The article headings are author-written, so h2 and h3 both map to the
   section step and h4/h5 to the sub-step. */
.aoit-kb-article-title {
    margin: 0 0 6px;
    font-size: 25px;
    font-weight: 700;
    line-height: 1.25;
    color: var(--aoit-ink);
}
.knowledgebase-article-body {
    font-size: 15px;
    line-height: 1.75;
    color: var(--aoit-ink-soft);
}
.knowledgebase-article-body h2,
.knowledgebase-article-body h3 {
    margin: 2.5rem 0 0.75rem;
    font-size: 21px;
    font-weight: 700;
    color: var(--aoit-ink);
}
.knowledgebase-article-body h4,
.knowledgebase-article-body h5 {
    margin: 1.75rem 0 0.5rem;
    font-size: 16.5px;
    font-weight: 700;
    color: var(--aoit-ink);
}
.knowledgebase-article-body > *:first-child {
    margin-top: 0;
}
.knowledgebase-article-body p {
    margin: 0 0 1rem;
}
.knowledgebase-article-body ul,
.knowledgebase-article-body ol {
    margin: 0 0 1rem 1.25rem;
    padding: 0;
}
.knowledgebase-article-body ul {
    list-style: disc;
}
.knowledgebase-article-body ol {
    list-style: decimal;
}
.knowledgebase-article-body li {
    margin-bottom: 0.375rem;
}
.knowledgebase-article-body a {
    color: var(--aoit-icon);
    text-decoration: underline;
    text-underline-offset: 2px;
}
.knowledgebase-article-body a:hover {
    color: var(--aoit-icon-hover);
}
.knowledgebase-article-body img {
    max-width: 100%;
    height: auto;
}


/* *****************************************************

    ** Bootstrap alert tints → brand palette **

    Stock alerts arrive in Bootstrap's own pastel set
    (#d4edda, #f8d7da, ...), which appears nowhere else in
    the design system. Mapped onto the same soft-tint +
    accented-text pairs every badge and status label uses,
    so a WHMCS-core-rendered alert reads as part of the
    theme. (The order form's alert-warning rule above is
    more specific and unaffected.)

***************************************************** */

.alert-success {
    background-color: var(--success-soft);
    border-color: var(--success);
    color: var(--success-accented);
}
.alert-danger {
    background-color: var(--error-soft);
    border-color: var(--error);
    color: var(--error-accented);
}
.alert-warning {
    background-color: var(--warning-soft);
    border-color: var(--warning);
    color: var(--warning-accented);
}
.alert-info {
    background-color: var(--info-soft);
    border-color: var(--info);
    color: var(--info-accented);
}
.alert a,
.alert .alert-link {
    color: inherit;
    font-weight: 600;
    text-decoration: underline;
}

/* Bootstrap's .text-muted is #6c757d !important — a grey from outside the
   palette. The ink-faint token, matching what the marketing site uses for
   secondary text. !important because Bootstrap's own rule carries it. */
.text-muted {
    color: var(--aoit-ink-faint) !important;
}


/* *****************************************************

    ** Dark mode **

    The marketing site fully auto-darkens via
    prefers-color-scheme (see src/input.css: every token has
    a -night value and body carries dark: variants). Until
    this block the client area stayed permanently light — a
    dark-OS customer crossed from a #101208 site into a
    white app. Same night palette, same source of truth.

    Mechanism: the theme's own vars are remapped to the
    -night values, which converts every var-driven rule
    above automatically; the rules below then repaint the
    surfaces this file sets as literal white, and the spots
    where a remapped "-accented" text colour is used as a
    solid hover FILL get a darker fill instead (bright
    pastel + white text would fail).

    Verified on the public pages (login, register, store,
    homepage); logged-in pages share the same components.
    KNOWN LIMIT: MarketConnect landing pages (store.css)
    hardcode their own light backgrounds and stay light.

***************************************************** */

@media (prefers-color-scheme: dark) {
    :root {
        color-scheme: dark;

        --aoit-ink: #F2F1E9;
        --aoit-ink-soft: #B7B9AC;
        --aoit-ink-faint: #868A76;
        --aoit-line: #3A4250;
        --aoit-bg-soft: #171912;

        --text: #F2F1E9;
        --text-lifted: #B7B9AC;
        --text-muted: #868A76;
        --text-accented: #F2F1E9;
        --text-inverted: #101208;

        --bg: #101208;
        --bg-muted: #171912;
        --bg-lifted: #171912;
        --bg-accented: #1E2118;

        --border-lifted: #3A4250;
        --border-accented: #3A4250;
        /* Nexus's own light hairlines, made translucent light rather than
           given invented dark hues. */
        --border-muted: rgba(242, 241, 233, 0.14);
        --border: rgba(242, 241, 233, 0.2);
        --neutral-200: rgba(242, 241, 233, 0.14);
        --neutral-300: rgba(242, 241, 233, 0.2);

        /* Family tints: the -soft-night pairs from input.css, with the
           bright -night hues as the text on them. */
        --success-soft: #16281B;
        --info-soft: #17233A;
        --warning-soft: #2E2410;
        --notice-soft: #241C33;
        --error-soft: #2E1712;
        --success-accented: #5FCB7E;
        --info-accented: #7CAEEA;
        --warning-accented: #E3A73E;
        --notice-accented: #A78BDA;
        --error-accented: #E8796A;
    }

    /* Ground and default ink. Cards are #101208 on the #171912 content
       well, the same soft-section/plain-card relationship the marketing
       site uses in dark. */
    html,
    body {
        background-color: #101208;
    }
    body {
        color: var(--aoit-ink);
    }

    /* Chrome */
    header.header .topbar,
    header.header .main-navbar-wrapper,
    .aoit-page-heading,
    .master-breadcrumb,
    .master-breadcrumb .breadcrumb,
    .aoit-footer.footer {
        background-color: #101208;
    }
    .hero-grid::before {
        background-image:
            linear-gradient(#333527 1px, transparent 1px),
            linear-gradient(90deg, #333527 1px, transparent 1px);
    }

    /* White surfaces → card-dark */
    .card,
    .mc-promo-manage,
    .mc-promo-login,
    .primary-content .card,
    .primary-content .mc-promo-manage,
    .primary-content .mc-promo-login,
    .tiles .tile,
    .tiles .row > div:last-child .tile,
    .tiles .tile:hover,
    .aoit-toggle-closed,
    .aoit-status-pill,
    table.table-list.table-services,
    .dataTables_wrapper table.table-list.table-services,
    .aoit-dept-card,
    .aoit-ticket-reply,
    .aoit-empty-state,
    .aoit-btn-quiet-danger,
    .btn.aoit-btn-quiet-danger,
    body #order-standard_cart .cart-body .products .product,
    body #order-standard_cart .products .product,
    body #order-standard_cart .domain-selection-options .option,
    body #order-standard_cart .order-summary,
    #order-standard_cart .order-summary,
    body #order-standard_cart .promo .btn-default,
    body #order-standard_cart .promo .btn-block.btn-default {
        background-color: #101208;
    }

    /* Form fields */
    .form-control,
    .custom-select,
    body #order-standard_cart .form-control,
    body #order-standard_cart .custom-select,
    body #order-standard_cart .field {
        background-color: #101208;
        color: var(--aoit-ink);
    }
    .form-control::placeholder {
        color: var(--aoit-ink-faint);
    }
    /* Bootstrap's select chevron is a near-black inline SVG. */
    .custom-select {
        background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23B7B9AC' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E");
    }
    .custom-control-input:not(:checked) ~ .custom-control-label::before {
        background-color: #171912;
        border-color: var(--aoit-line);
    }

    /* Bootstrap components that hardcode white */
    .dropdown-menu {
        background-color: #171912;
        border-color: var(--aoit-line);
    }
    .dropdown-item {
        color: var(--aoit-ink-soft);
    }
    .dropdown-item:hover,
    .dropdown-item:focus {
        background-color: rgba(242, 241, 233, 0.06);
        color: var(--aoit-ink);
    }
    .dropdown-divider {
        border-color: var(--aoit-line);
    }
    .modal-content {
        background-color: #171912;
        color: var(--aoit-ink);
    }
    .modal-header,
    .modal-footer {
        border-color: var(--aoit-line);
    }
    .close {
        color: var(--aoit-ink);
        text-shadow: none;
    }
    .page-link {
        background-color: #101208;
        border-color: var(--aoit-line);
        color: #5FCB7E;
    }
    .page-item.disabled .page-link {
        background-color: #101208;
        border-color: var(--aoit-line);
        color: var(--aoit-ink-faint);
    }
    .list-group-item {
        background-color: #101208;
        border-color: var(--neutral-200);
        color: var(--aoit-ink);
    }
    .breadcrumb-item + .breadcrumb-item::before {
        color: var(--aoit-ink-faint);
    }
    .bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-default,
    .bootstrap-switch .bootstrap-switch-label {
        background-color: #171912;
        color: var(--aoit-ink-soft);
    }

    /* Accent text that was a mid-blue fill colour in light: as TEXT on dark
       it takes the night blue (the fills themselves — card-header buttons,
       aoit-btn-blue — keep their solid blue with white text). */
    .aoit-service-icon,
    .aoit-dept-icon {
        color: #7CAEEA;
    }
    .aoit-ticket-reply.is-staff .aoit-ticket-role {
        background: #171912;
    }

    /* Quiet-danger outline: the light-mode #A13A2E text reads as mud on
       dark; the night red, going solid on hover as before. */
    .aoit-btn-quiet-danger,
    .btn.aoit-btn-quiet-danger {
        border-color: #E8796A;
        color: #E8796A;
    }
    .aoit-btn-quiet-danger:hover,
    .aoit-btn-quiet-danger:focus,
    .btn.aoit-btn-quiet-danger:hover,
    .btn.aoit-btn-quiet-danger:focus {
        background-color: var(--error);
        border-color: var(--error);
        color: #fff;
    }

    /* Where "-accented" is used as a solid hover FILL, the dark remap above
       would put white text on a bright pastel. The -lifted step of each hue
       is the dark-safe fill. */
    .aoit-urgent-notice-btn:hover {
        background-color: var(--error-lifted);
    }
    .aoit-urgent-notice.is-warning .aoit-urgent-notice-btn:hover {
        background-color: var(--warning-lifted);
    }
    .aoit-invoices-due-actions .btn:hover,
    .aoit-invoices-due-actions .btn:focus,
    .aoit-invoices-due-actions .btn:first-child:hover,
    .aoit-invoices-due-actions .btn:first-child:focus {
        background-color: var(--warning-lifted);
        border-color: var(--warning-lifted);
        color: #fff;
    }

    /* The invoice total band inverts: light band on the dark document. */
    .invoice-container .aoit-invoice-table .aoit-total-row td {
        background: #F2F1E9;
        color: #101208;
    }
}
