/* OptiTide brand theme — Navy + Orange.
   Deep Navy #0D1530 · Navy Surface #1A223F · Action Orange #FF6A00 ·
   Bright Orange #FF8C3A · Warm Cream #F5E6D3 · Off White #F7F7F8.
   Content stays light and legible; navy carries structure, orange carries action. */

:root {
    --navy: #0D1530;           /* Deep Navy — sidebar / dark surfaces / text */
    --navy-2: #1A223F;         /* Navy Surface */
    --brand: #FF6A00;          /* Action Orange — primary accent (fills/icons/large text) */
    --brand-dark: #E85F00;     /* darker orange for hover/active */
    --brand-bright: #FF8C3A;   /* Bright Orange (on dark backgrounds) */
    --brand-ink: #C2410C;      /* AA-contrast orange (~5:1 on white) for small text/links */
    --brand-gradient: linear-gradient(120deg, #FF6A00 0%, #FF8C3A 100%);
    --brand-soft: #FFE7D3;     /* light orange tint */
    --cream: #F5E6D3;

    --ink: #0D1530;
    --muted: #64748b;
    --line: #e5e7eb;
    --surface: #ffffff;
    --canvas: #F7F7F8;
    --sidebar-w: 250px;
}

body {
    background: var(--canvas);
    color: var(--ink);
    font-family: "Poppins", system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

a { color: var(--brand-ink); }
a:hover { color: var(--brand); }
/* Skip-to-content link: visually hidden until focused (keyboard users). */
.skip-link { position: absolute; left: 8px; top: -48px; z-index: 2000; background: var(--navy, #0D1530); color: #fff; padding: .55rem 1rem; border-radius: 8px; transition: top .15s; }
.skip-link:focus { top: 8px; color: #fff; }

/* --- Brand mark + wordmark ------------------------------------------------- */
.text-brand { color: var(--brand-ink) !important; }
.bg-brand { background: var(--brand) !important; }
.brand-mark {
    font-weight: 800;
    letter-spacing: -.02em;
    color: var(--ink);
    display: inline-flex;
    align-items: center;
    /* No flex gap — "Opti" and "Tide" sit flush so it reads "OptiTide". */
}
.brand-mark span { color: var(--brand); }   /* "Tide" in Action Orange */
.brand-icon { height: 1.35em; width: auto; display: inline-block; margin-right: .4rem; object-fit: contain; }

/* Real brand images (logo, wave, mascot, service icons): preserve aspect ratio,
   always contain, never cover. */
.brand-img { object-fit: contain; width: auto; height: auto; max-width: 100%; }
.brand-logo { height: 46px; width: auto; max-width: 100%; object-fit: contain; display: block; }
/* White-bg logos framed as a clean chip on dark/navy backgrounds. */
.brand-logo--chip { background: #fff; border-radius: 12px; padding: 8px 14px; }
.sidebar .brand-logo { height: 72px; width: 100%; object-fit: contain; margin: 0 auto .4rem; }
.sidebar a[href] > .brand-logo--chip, .sidebar .brand-logo--chip { display: block; }

.btn-brand,
.btn-primary {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--brand);
    --bs-btn-border-color: var(--brand);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--brand-dark);
    --bs-btn-hover-border-color: var(--brand-dark);
    --bs-btn-active-bg: var(--brand-dark);
    --bs-btn-active-border-color: var(--brand-dark);
    --bs-btn-disabled-bg: var(--brand);
    --bs-btn-disabled-border-color: var(--brand);
    border: none;
    color: #fff;
}
.btn-brand:hover, .btn-primary:hover { color: #fff; }
.btn-outline-brand {
    --bs-btn-color: var(--brand-dark);
    --bs-btn-border-color: #ffc79e;
    --bs-btn-hover-bg: var(--brand);
    --bs-btn-hover-border-color: var(--brand);
    --bs-btn-hover-color: #fff;
}
.form-control:focus, .form-select:focus {
    border-color: var(--brand);
    box-shadow: 0 0 0 .2rem rgba(255, 106, 0, .2);
}
.form-check-input:checked { background-color: var(--brand); border-color: var(--brand); }

/* --- App shell ------------------------------------------------------------- */
.app { display: flex; min-height: 100vh; }
.sidebar {
    width: var(--sidebar-w);
    flex: 0 0 var(--sidebar-w);
    background: linear-gradient(180deg, var(--navy-2), var(--navy));
    color: #cbd2e0;
    position: sticky;
    top: 0;
    height: 100vh;
    padding: 1.1rem .85rem;
    overflow-y: auto;
    border-right: 1px solid rgba(255, 255, 255, .06);
}
.sidebar .brand-mark { color: #fff; font-size: 1.35rem; }
.sidebar-brand { display: flex; align-items: center; gap: .6rem; text-decoration: none; margin-bottom: .3rem; }
.sidebar-brand-mark { background: #fff; border-radius: 10px; padding: 5px; display: inline-flex; flex: 0 0 auto; }
.sidebar-brand-mark img { height: 34px; width: 34px; object-fit: contain; display: block; }
.sidebar-brand-name { color: #fff; font-weight: 800; font-size: 1.5rem; letter-spacing: -.02em; line-height: 1; }
.sidebar .nav-section { color: #6f7690; font-size: .68rem; text-transform: uppercase; letter-spacing: .08em; margin: 1.1rem .6rem .35rem; }
.sidebar .nav-link {
    color: #c5cbd8;
    border-radius: 8px;
    padding: .5rem .65rem;
    display: flex;
    align-items: center;
    gap: .6rem;
    font-size: .92rem;
    margin-bottom: 1px;
}
.sidebar .nav-link:hover { background: rgba(255,255,255,.06); color: #fff; }
.sidebar .nav-link.active { background: var(--brand); color: #fff; }
.sidebar .nav-link i { width: 18px; text-align: center; }

.content { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.topbar {
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    padding: .7rem 1.4rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: sticky; top: 0; z-index: 20;
}
.main { padding: 1.5rem; flex: 1 1 auto; }
.page-title { font-weight: 700; font-size: 1.4rem; margin: 0; }

/* Touch targets. Most portal clients arrive on a phone, where Bootstrap's
   .btn-sm is ~31px tall — under the 44px minimum a finger needs. Raised only
   below the lg breakpoint so the dense desktop tables keep their compact rows;
   width is left alone so table action buttons don't stretch.
   .main is the shared app shell, so this lifts the admin panel on a phone too —
   intended: the same finger is tapping both. */
@media (max-width: 991.98px) {
    .main .btn {
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: .35rem;
    }
    /* A list-group row is block-level — it must fill its card, so it gets the
       height without the inline-flex the buttons above need. */
    .main .list-group-item-action { min-height: 44px; }
    .main { padding: 1rem; }
}

/* --- Cards / tables -------------------------------------------------------- */
.card { border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 1px 2px rgba(13,21,48,.04); }
.card-header { background: var(--surface); border-bottom: 1px solid var(--line); font-weight: 600; }
.stat-card .stat-value { font-size: 1.6rem; font-weight: 700; }
/* The markup uses .min-w-0 to let the text column shrink beside the fixed 44px
   icon — but Bootstrap 5 ships no such utility, so it was a no-op and a long money
   value ($12,345.67) burst the card on a col-6 phone tile. Define it, and let the
   value ellipsize rather than overflow. */
.min-w-0 { min-width: 0; }
.stat-card .stat-value { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 576px) { .stat-card .stat-value { font-size: 1.25rem; } }
.stat-card .stat-label { color: var(--muted); font-size: .82rem; text-transform: uppercase; letter-spacing: .04em; }
.stat-card .stat-icon { width: 44px; height: 44px; border-radius: 10px; display: grid; place-items: center; background: var(--brand-soft); color: var(--brand-dark); font-size: 1.2rem; }

.table > :not(caption) > * > * { padding: .7rem .75rem; }
.table thead th { color: var(--muted); font-size: .72rem; text-transform: uppercase; letter-spacing: .05em; border-bottom: 1px solid var(--line); }
.table-hover tbody tr:hover { background: #faf8f6; }

.badge-soft { background: #f1f2f4; color: #475569; font-weight: 600; }

/* --- Auth ------------------------------------------------------------------ */
.auth-wrap {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: 1.5rem;
    background:
        radial-gradient(900px 500px at 15% 0%, rgba(255, 106, 0, .22), transparent 58%),
        radial-gradient(900px 600px at 100% 100%, rgba(255, 140, 58, .16), transparent 55%),
        linear-gradient(160deg, var(--navy-2), var(--navy));
}
.auth-wrap .brand-mark { color: #fff; }
.auth-card { width: 100%; max-width: 420px; }

/* --- Marketing website ---------------------------------------------------- */
.mk { color: var(--ink); }
.mk-container { max-width: 1140px; margin: 0 auto; padding-left: 1.25rem; padding-right: 1.25rem; }
/* A Bootstrap .row pays for its gutter with negative side margins, and g-5 asks
   for 3rem — so the row takes -24px a side while this container only has 20px of
   padding to absorb it. The row escapes by 4px on each edge and the whole page
   scrolls sideways, at EVERY width, not just on a phone. (/about was doing this.)
   2.5rem is the widest gutter this container can actually hold: 40px / 2 = the
   20px padding exactly. Scoped to g-5/gx-5 because every smaller step already
   fits — overriding --bs-gutter-x for all rows would make g-1..g-4 rows wider. */
.mk-container > .row.g-5, .mk-container > .row.gx-5 { --bs-gutter-x: 2.5rem; }
.mk-section { padding: 4.5rem 0; }
.mk-section--alt { background: #f6f7f9; }
.mk-eyebrow { display: inline-block; font-size: .78rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--brand-ink); margin-bottom: .5rem; }
.mk-h2 { font-weight: 800; letter-spacing: -.02em; font-size: clamp(1.8rem, 4vw, 2.5rem); margin: 0 0 .6rem; }
.mk-lead { color: var(--muted); font-size: 1.08rem; line-height: 1.6; max-width: 640px; }
.mk-gradient-text { color: var(--brand); background: var(--brand-gradient); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }

/* Nav */
.mk-nav { position: sticky; top: 0; z-index: 40; background: rgba(255,255,255,.92); backdrop-filter: blur(10px); border-bottom: 1px solid var(--line); }
/* column-gap is a FLOOR, not a nicety: space-between alone lets the links sit
   flush against the logo the moment the row runs out of room, and the sums below
   only hold while the fonts render at the widths they were measured at. With a
   floor, a row that outgrows the container overflows on the right (obvious, and
   the CTA is the last thing out) instead of silently eating the brand. */
.mk-nav .mk-container { display: flex; align-items: center; justify-content: space-between; gap: 2rem; padding-top: .85rem; padding-bottom: .85rem; }
.mk-nav .brand-mark { font-size: 1.35rem; color: var(--ink); }
.mk-nav .brand-logo { height: 84px; }
/* Tagline logo runs bigger so the slogan is legible. */
.mk-nav .brand-logo--tagline { height: 84px; }
/* Tie the shrink to the hamburger breakpoint, not 576px. Between 577 and 991 the
   nav is already collapsed to a hamburger but the logo kept its 84px desktop
   height, so the bar was 112px tall — on a landscape phone that is a quarter of
   the screen, permanently, because the nav is sticky. */
@media (max-width: 991.98px) { .mk-nav .brand-logo, .mk-nav .brand-logo--tagline { height: 58px; } }
@media (max-width: 576px) { .mk-nav .brand-logo, .mk-nav .brand-logo--tagline { height: 52px; } }

/* Top utility bar */
.mk-topbar { background: var(--navy); color: #b9c0d4; font-size: .82rem; }
.mk-topbar .mk-container { display: flex; justify-content: space-between; align-items: center; padding-top: .4rem; padding-bottom: .4rem; }
.mk-topbar a { color: #c7ccdb; text-decoration: none; margin-right: 1.1rem; }
.mk-topbar a:hover { color: #fff; }
.mk-topbar i { color: var(--brand-bright); }
.mk-topbar-tag { color: var(--brand-bright); font-weight: 600; font-style: italic; }
.mk-ccy { display: inline-flex; align-items: center; gap: .25rem; margin-right: 1.1rem; }
.mk-ccy i { color: #c7ccdb; }
/* Vertical padding, not just horizontal: these were 36x20px targets 4px apart, and
   a mis-tap silently reprices the whole site in the other currency. */
.mk-ccy-link { margin: 0 !important; padding: .5rem; color: #9aa2b8 !important; font-weight: 600; }
.mk-ccy-link.is-active { color: var(--brand-bright) !important; text-decoration: underline; }
/* The phone-width top bar is NOT styled here. It used to be, and every rule in
   it was dead: `.mk-topbar-left, .mk-topbar-right { display: flex }` sits ~340
   lines further down with equal specificity, and media queries add no
   specificity — so the later, unconditional rule won and the bar never
   collapsed. See "Top utility bar on a phone" below, which is placed AFTER that
   declaration on purpose. */

/* Moving announcement banner */
/* Static announcement strip (replaces the old scrolling marquee) */
.mk-announce { background: var(--brand); color: #fff; font-size: .88rem; }
.mk-announce .mk-container { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: .4rem 1rem; padding-top: .5rem; padding-bottom: .5rem; text-align: center; }
.mk-announce span { font-weight: 600; }
.mk-announce a { color: #fff; text-decoration: underline; font-weight: 700; }
.mk-announce a:hover { color: #fff; opacity: .85; }
/* Trust strip under the hero */
.mk-trustbar { background: #fff; border-bottom: 1px solid var(--line); }
.mk-trustbar .mk-container { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: .6rem 1.75rem; padding-top: .9rem; padding-bottom: .9rem; }
.mk-trust-item { color: #475569; font-size: .86rem; font-weight: 600; white-space: nowrap; }
.mk-trust-item i { color: #16a34a; margin-right: .35rem; }
/* Sizing this row is unforgiving, so the numbers are written down. The container
   is max-width:1140 with 20px padding => 1100px of usable row, ALWAYS (it caps,
   so a wider screen buys nothing). The logo is 254. That leaves 846 for the
   links, and they must still clear the logo by ~32px.
   Link labels total 353 (Home 45, Services 75, Pricing 52, Company 87, Blog 33,
   Contact 61) + the CTA 193 + the auth button + 7 gaps. The auth button is the
   trap: "Login" is 92 but "Dashboard" is 137, so the row is WIDER for a signed-in
   visitor -- at the old 1.4rem gaps the logged-in row was 1120 > 1100 and collided
   at EVERY width. 1rem gaps put the worst case at 1049, leaving ~51px. Note a
   wider screen does not help (the container caps at 1140), so this one gap value
   serves every desktop width. */
.mk-nav-links { display: flex; align-items: center; gap: 1rem; }
.mk-nav-links a { color: #475569; text-decoration: none; font-weight: 600; font-size: .93rem; }
.mk-nav-links a:hover { color: var(--brand); }
/* min-width/height, not font-size: the glyph stays 1.6rem, the BOX grows. This is
   the only control that reaches navigation on a phone and it was 35x30px. */
.mk-nav-toggle { display: none; background: none; border: 0; font-size: 1.6rem; color: var(--navy); line-height: 1; padding: .1rem .3rem; cursor: pointer;
    min-width: 44px; min-height: 44px; align-items: center; justify-content: center; }
/* Below 992 the row genuinely cannot seat the links, so it becomes a hamburger.
   (992-1199 still shows the full nav — it fits once the auth button steps out;
   see the .mk-nav-login media query further down.) */
@media (max-width: 991.98px) {
    .mk-nav .mk-container { position: relative; }
    .mk-nav-toggle { display: inline-flex; }
    .mk-nav-links { position: absolute; top: 100%; left: 0; right: 0; background: #fff; flex-direction: column;
        align-items: stretch; gap: 0; padding: .5rem 1.25rem 1rem; border-bottom: 1px solid var(--line);
        box-shadow: 0 12px 22px rgba(13,21,48,.08); display: none;
        /* On a short phone in landscape the open menu is taller than the viewport;
           without this the CTA at the bottom sits off-screen with no way to reach it.
           The 100% is the NAV's height (the containing block) — it does not account
           for the utility bar sitting above the nav before you scroll, so the menu
           ran 48px past the bottom of the screen and the last row (the proposal CTA)
           could not be reached even by scrolling the menu itself. dvh so the mobile
           browser's own collapsing toolbar is counted too. */
        max-height: calc(100vh - 100% - 48px);
        max-height: calc(100dvh - 100% - 48px); overflow-y: auto; }
    .mk-nav-links.open { display: flex; }
    .mk-nav-links .mk-nav-link { display: block; padding: .7rem 0; border-bottom: 1px solid #f1f2f4; }
    .mk-nav-links .btn { margin-top: .75rem; text-align: center; }
}

/* Hero */
.mk-hero { position: relative; color: #eef1f7; overflow: hidden;
    background:
        radial-gradient(900px 500px at 12% 0%, rgba(255,106,0,.22), transparent 55%),
        radial-gradient(900px 600px at 100% 20%, rgba(255,140,58,.14), transparent 55%),
        linear-gradient(160deg, var(--navy-2) 0%, var(--navy) 60%, #080d20 100%); }
.mk-hero .mk-container { padding-top: 5rem; padding-bottom: 5rem; }
.mk-hero h1 { font-weight: 800; letter-spacing: -.03em; line-height: 1.05; font-size: clamp(2.4rem, 6vw, 4rem); margin: 1rem 0; }
.mk-hero p { color: #b9c0d4; font-size: 1.15rem; line-height: 1.6; max-width: 620px; }
.mk-hero-mascot { max-width: 100%; height: auto; object-fit: contain; background: #fff; border-radius: 22px; padding: 10px; box-shadow: 0 24px 60px rgba(0,0,0,.28); }
.mk-badge { display: inline-flex; align-items: center; gap: .5rem; padding: .35rem .95rem; border-radius: 999px;
    font-size: .78rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
    color: #ffd9bd; background: rgba(255,106,0,.15); border: 1px solid rgba(255,106,0,.4); }
.mk-hero-cta { display: flex; gap: .75rem; flex-wrap: wrap; margin-top: 1.6rem; }
.mk-hero-cta .btn-ghost { border: 1px solid rgba(255,255,255,.3); color: #eef1f7; }
.mk-hero-cta .btn-ghost:hover { background: rgba(255,255,255,.1); color: #fff; }
.mk-hero-stats { display: flex; gap: 2.2rem; flex-wrap: wrap; margin-top: 2.6rem; }
.mk-hero-stats .n { font-size: 1.5rem; font-weight: 800; }
.mk-hero-stats .l { color: #9aa2ba; font-size: .82rem; }

/* Service blocks */
.mk-service { background: var(--surface); border: 1px solid var(--line); border-radius: 16px; padding: 1.75rem; height: 100%; transition: box-shadow .18s, transform .18s; }
.mk-service:hover { box-shadow: 0 12px 34px rgba(13,21,48,.12); transform: translateY(-3px); }
.mk-service-icon { width: 52px; height: 52px; border-radius: 13px; display: grid; place-items: center; font-size: 1.4rem; color: var(--brand); background: var(--navy); margin-bottom: 1rem; }
.mk-service-icon-img { width: 60px; height: 60px; object-fit: contain; margin-bottom: 1rem; }
.mk-service h3 { font-size: 1.25rem; font-weight: 700; margin: 0 0 .5rem; }
.mk-service p { color: var(--muted); font-size: .95rem; line-height: 1.55; }
.mk-service ul { list-style: none; padding: 0; margin: .75rem 0 0; }
.mk-service li { display: flex; gap: .5rem; align-items: flex-start; font-size: .9rem; color: #475569; padding: .2rem 0; }
.mk-service li i { color: var(--brand); margin-top: .15rem; }

/* Plan / package cards */
.mk-plan { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 1.35rem; height: 100%; text-align: center; transition: box-shadow .18s, transform .18s; }
.mk-plan:hover { box-shadow: 0 10px 28px rgba(13,21,48,.10); transform: translateY(-3px); }
.mk-plan--custom { border-color: #ffc79e; background: #fff8f2; }
.mk-plan-name { font-weight: 700; margin-bottom: .4rem; }
.mk-plan-price { font-size: 1.7rem; font-weight: 800; color: var(--navy); line-height: 1.1; }
.mk-plan-per, .mk-plan-from { font-size: .8rem; font-weight: 600; color: var(--muted); }

/* Process steps */
.mk-step { text-align: center; padding: 0 .5rem; }
.mk-step-num { width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center; margin: 0 auto .8rem; font-weight: 800; color: #fff; background: var(--brand); }
.mk-step h4 { font-size: 1.05rem; font-weight: 700; margin: 0 0 .35rem; }
.mk-step p { color: var(--muted); font-size: .9rem; line-height: 1.5; margin: 0; }

/* Benefits */
.mk-benefit { display: flex; gap: .85rem; align-items: flex-start; }
.mk-benefit i { font-size: 1.5rem; color: var(--brand); }
.mk-benefit h4 { font-size: 1.02rem; font-weight: 700; margin: 0 0 .2rem; }
.mk-benefit p { color: var(--muted); font-size: .9rem; margin: 0; line-height: 1.5; }

/* CTA band */
.mk-ctaband { color: #fff; text-align: center; border-radius: 22px; padding: 3rem 1.5rem;
    background: linear-gradient(150deg, var(--navy-2), var(--navy)); border: 1px solid rgba(255,106,0,.25); }
.mk-ctaband h2 { font-weight: 800; font-size: clamp(1.7rem, 4vw, 2.4rem); margin: 0 0 .6rem; }
.mk-ctaband p { color: rgba(255,255,255,.8); max-width: 560px; margin: 0 auto 1.4rem; }
.mk-ctaband .btn { background: var(--brand); color: #fff; border: none; font-weight: 700; }
.mk-ctaband .btn:hover { background: var(--brand-dark); color: #fff; }

/* Contact */
.mk-contact-card { background: var(--surface); border: 1px solid var(--line); border-radius: 18px; padding: 2rem; }
.mk-contact-info li { display: flex; gap: .7rem; align-items: flex-start; padding: .5rem 0; color: #334155; }
.mk-contact-info i { color: var(--brand); font-size: 1.15rem; margin-top: .1rem; }

/* Footer */
.mk-footer { background: var(--navy); color: #b9c0d4; padding: 3.5rem 0 1.5rem; }
.mk-footer a { color: #b9c0d4; text-decoration: none; font-size: .9rem; }
.mk-footer a:hover { color: #fff; }
.mk-footer .brand-mark { color: #fff; }
.mk-footer h5 { color: #fff; font-size: .82rem; text-transform: uppercase; letter-spacing: .06em; margin-bottom: .9rem; }
.mk-footer .foot-links { list-style: none; padding: 0; margin: 0; }
.mk-footer .foot-links li { padding: .28rem 0; }
.mk-footer-bottom { border-top: 1px solid rgba(255,255,255,.1); margin-top: 2.5rem; padding-top: 1.25rem; color: #7c839b; font-size: .82rem; }

.money { font-variant-numeric: tabular-nums; }

/* Off-canvas sidebar at the lg boundary (<=991.98px) so the app fits at higher
   browser zoom (≈150% collapses the effective width into this band) — the
   content then gets the full width instead of being squeezed beside a 250px rail. */
.sidebar-backdrop { display: none; position: fixed; inset: 0; background: rgba(13,21,48,.55); z-index: 1049; }
.sidebar-close { display: none; }
@media (max-width: 991.98px) {
    /* visibility:hidden as well as the transform. translateX alone moves the
       drawer off-screen but leaves every link FOCUSABLE, so tabbing from the
       page ran silently through a closed menu — the focus went somewhere the
       user could not see and the page appeared to stop responding to Tab.
       visibility:hidden takes them out of the tab order; it is transitioned
       rather than switched so the slide-in still animates. */
    .sidebar { position: fixed; top: 0; left: 0; z-index: 1050; transform: translateX(-100%);
        visibility: hidden; transition: transform .2s, visibility 0s linear .2s;
        box-shadow: 0 0 40px rgba(0,0,0,.35); }
    .sidebar.open { transform: none; visibility: visible; transition: transform .2s, visibility 0s; }
    .sidebar-backdrop.show { display: block; }
    .sidebar-close { display: inline-flex; }
    .content { width: 100%; }
}

/* --- Marketing footer extras (blog/content layout) ---------------------- */
.mk-footer-about { font-size: .9rem; line-height: 1.6; color: #b9c0d4; max-width: 340px; }
.mk-footer-contact { display: flex; flex-direction: column; gap: .35rem; margin-top: .75rem; }
.mk-footer-contact a { display: inline-flex; align-items: center; gap: .45rem; }
.mk-footer-col a,
.mk-footer-col .mk-footer-note { display: block; padding: .28rem 0; word-break: break-word; }
.mk-footer-col .mk-footer-note { color: #8f97ad; font-size: .85rem; }
.mk-footer-col a i, .mk-footer-col .mk-footer-note i { width: 15px; opacity: .8; margin-right: .15rem; }
.mk-footer-tagline { color: var(--brand); font-weight: 700; font-style: italic; }

/* --- Blog --------------------------------------------------------------- */
.mk-blog-index { padding-top: 3rem; }
.mk-blog-card { display: flex; flex-direction: column; height: 100%; background: #fff; border: 1px solid #e7eaf3;
    border-radius: 16px; overflow: hidden; text-decoration: none; color: inherit; transition: transform .15s, box-shadow .15s; }
.mk-blog-card:hover { transform: translateY(-4px); box-shadow: 0 14px 34px rgba(13,21,48,.12); }
.mk-blog-card-img { height: 180px; background: linear-gradient(135deg, var(--navy), var(--brand)); background-size: cover;
    background-position: center; display: flex; align-items: center; justify-content: center; color: rgba(255,255,255,.55); font-size: 2.2rem; }
.mk-blog-card-img--sm { height: 110px; font-size: 1.5rem; }
.mk-blog-card-body { padding: 1.15rem 1.25rem 1.35rem; display: flex; flex-direction: column; gap: .5rem; }
.mk-blog-card-body h3 { font-size: 1.08rem; font-weight: 700; margin: 0; color: var(--navy); line-height: 1.35; }
.mk-blog-card-body p { font-size: .9rem; color: #5b6479; margin: 0; }
.mk-blog-cat { align-self: flex-start; display: inline-block; background: var(--brand-soft, #fff2e8); color: var(--brand);
    font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; padding: .2rem .6rem; border-radius: 999px; }
.mk-blog-meta { font-size: .82rem; color: #8a91a5; }
.mk-blog-narrow { max-width: 820px; }
.mk-blog-crumb { font-size: .85rem; color: #8a91a5; }
.mk-blog-crumb a { color: var(--brand); text-decoration: none; }
.mk-blog-crumb span { margin: 0 .1rem; }
.mk-blog-title { font-size: clamp(1.9rem, 4vw, 2.7rem); font-weight: 800; color: var(--navy); line-height: 1.15; margin: .5rem 0; }
.mk-blog-hero-img { width: 100%; border-radius: 16px; object-fit: cover; max-height: 440px; }
.mk-blog-body { font-size: 1.06rem; line-height: 1.8; color: #2c3348; }
.mk-blog-body h2 { font-size: 1.6rem; font-weight: 700; color: var(--navy); margin: 2rem 0 .8rem; }
.mk-blog-body h3 { font-size: 1.28rem; font-weight: 700; color: var(--navy); margin: 1.6rem 0 .6rem; }
.mk-blog-body p { margin: 0 0 1.1rem; }
.mk-blog-body ul, .mk-blog-body ol { margin: 0 0 1.1rem 1.2rem; }
.mk-blog-body li { margin-bottom: .5rem; }
.mk-blog-body a { color: var(--brand); }
.mk-blog-body img { max-width: 100%; border-radius: 12px; margin: 1rem 0; }
.mk-blog-body blockquote { border-left: 4px solid var(--brand); padding: .5rem 0 .5rem 1.2rem; margin: 1.4rem 0; color: #4a5266; font-style: italic; }
/* Post bodies are authored HTML, so they can contain a table or a code block that
   is simply wider than a phone — img was capped here but nothing else was, and a
   comparison table in one post scrolled the entire page sideways at 320px. Let the
   wide thing scroll inside its own box instead of taking the page with it. */
.mk-blog-body table { display: block; width: 100%; max-width: 100%; overflow-x: auto; }
.mk-blog-body pre { overflow-x: auto; max-width: 100%; }
.mk-blog-body a { overflow-wrap: anywhere; }
.mk-blog-cta { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem;
    background: var(--brand-soft, #fff2e8); border-radius: 16px; padding: 1.5rem 1.75rem; }

/* --- Project boards (kanban) -------------------------------------------- */
.board-tile:hover { box-shadow: 0 10px 26px rgba(13,21,48,.12); transform: translateY(-2px); transition: .15s; }
/* On touch there is no hover, so the ONLY way into a card was permanently hidden.
   Show it always where a fine pointer (mouse) isn't the primary input. */
@media (hover: none), (pointer: coarse) {
}

/* --- Helpdesk ticket thread --------------------------------------------- */
.tk-thread { display: flex; flex-direction: column; gap: .75rem; }
.tk-msg { border: 1px solid #e7eaf3; border-radius: 12px; padding: .8rem 1rem; background: #fff; }
.tk-msg--staff { border-left: 3px solid var(--brand, #FF6A00); }
.tk-msg--client { border-left: 3px solid #94a3b8; background: #f8fafc; }
.tk-msg--internal { border-left: 3px solid #f59e0b; background: #fffbeb; }
.tk-msg-head { display: flex; justify-content: space-between; align-items: center; gap: .5rem; margin-bottom: .35rem; }
.tk-msg-body { color: #2c3348; line-height: 1.6; white-space: normal; }

/* --- Client "My Project" cards ------------------------------------------
   The client-facing read-only face of a delivery card. Deliberately NOT
   readout for a client who never sees the board. */
.pj-card { border: 1px solid #e7eaf3; border-radius: 12px; padding: .8rem 1rem; background: #fff; }
.pj-card + .pj-card { margin-top: .75rem; }
.pj-notes { margin-top: .75rem; display: flex; flex-direction: column; gap: .5rem; }
.pj-note { border-left: 3px solid var(--brand, #FF6A00); background: #f8fafc; border-radius: 0 8px 8px 0; padding: .5rem .75rem; }
.pj-note .small { color: #2c3348; line-height: 1.55; }

/* --- Auth pages (site header + footer, blended) ------------------------- */
.auth-body { min-height: calc(100vh - 90px); display: grid; place-items: center; padding: 3.5rem 1.25rem;
    background: radial-gradient(820px 420px at 50% -8%, rgba(255,106,0,.10), transparent 60%), #f2f0ee; }
.auth-body .auth-card { width: 100%; max-width: 430px; }
.auth-body .card { border-radius: 16px; box-shadow: 0 18px 40px rgba(13,21,48,.10); }
/* Slim footer used inside the portal/app shell. */
.app-footer { border-top: 1px solid var(--line); padding: 1rem 1.5rem; color: var(--muted); font-size: .82rem;
    display: flex; flex-wrap: wrap; justify-content: space-between; gap: .5rem; }
.app-footer a { color: var(--muted); text-decoration: none; }
.app-footer a:hover { color: var(--brand); }
.app-footer .tag { color: var(--brand); font-weight: 700; font-style: italic; }

/* ============================================================
   Homepage redesign (mockup layout) — hero form, partners,
   results/case study, pricing tiers, testimonials, CTA band.
   ============================================================ */
.mk-orange { color: var(--brand); }

/* Hero: copy + mascot on the left, lead form on the right */
.mk-hero h1 { font-size: clamp(1.9rem, 3.4vw, 3rem); line-height: 1.08; }
.mk-hero-inner { display: flex; align-items: center; gap: 1rem; }
.mk-hero-copy { flex: 1 1 auto; min-width: 0; }
.mk-hero-checks { list-style: none; padding: 0; margin: 1.4rem 0 0; display: grid; gap: .5rem; }
.mk-hero-checks li { display: flex; align-items: center; gap: .55rem; color: #dfe4f0; font-weight: 600; font-size: .98rem; }
.mk-hero-checks i { color: var(--brand); font-size: 1.05rem; }
.mk-hero-mascot { flex: 0 0 240px; width: 240px; max-width: 100%; height: auto; background: none; border-radius: 0; padding: 0; box-shadow: none;
    filter: drop-shadow(0 24px 40px rgba(0,0,0,.4)); display: none; }
@media (min-width: 1200px) { .mk-hero-mascot { display: block; } }
.mk-hero-cta .btn-ghost { border: 1px solid rgba(255,255,255,.35); color: #fff; }

.mk-hero-form { background: #fff; border-radius: 18px; padding: 1.5rem; box-shadow: 0 30px 70px rgba(0,0,0,.35); }
.mk-hero-form h2 { font-size: 1.5rem; font-weight: 800; color: var(--ink); margin: 0 0 .25rem; }
.mk-hero-form-sub { color: var(--muted); font-size: .9rem; margin-bottom: 1rem; }
.mk-hero-form .form-control, .mk-hero-form .form-select { font-size: .92rem; }
.mk-hero-form-note { text-align: center; color: #16a34a; font-size: .82rem; font-weight: 600; margin-top: .7rem; }
.mk-hero-form-note i { margin-right: .25rem; }

/* Partner / trust logos strip */
.mk-partners { background: #fff; border-bottom: 1px solid var(--line); padding: 1.5rem 0; }
.mk-partners-title { text-align: center; color: var(--muted); font-size: .72rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; margin-bottom: 1rem; }
.mk-partner-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 1.25rem 2.5rem; }
.mk-partner { color: #64748b; font-weight: 800; font-size: 1.15rem; letter-spacing: -.01em; opacity: .75; filter: grayscale(1); }

/* Results / case study (navy band) */
.mk-results { background: linear-gradient(160deg, var(--navy-2), var(--navy)); color: #eef1f7; padding: 4.5rem 0; }
.mk-results-head h2 { font-weight: 800; font-size: clamp(1.6rem, 3.5vw, 2.3rem); margin: 0 0 .3rem; }
.mk-results-head p { color: #b9c0d4; }
.mk-casestudy { background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.1); border-radius: 16px; padding: 1.5rem; margin-top: 1.5rem; }
.mk-casestudy-title { font-size: 1.2rem; font-weight: 700; }
.mk-casestudy-detail { color: #9aa2ba; font-size: .9rem; margin-bottom: 1rem; }
.mk-casestudy-stats { display: flex; flex-wrap: wrap; gap: 2rem; }
.mk-casestudy-stats .n { display: block; color: var(--brand-bright); font-size: 1.8rem; font-weight: 800; line-height: 1; }
.mk-casestudy-stats .l { color: #b9c0d4; font-size: .82rem; }
.mk-casestudy-link { display: inline-block; margin-top: 1.2rem; color: var(--brand-bright); font-weight: 700; text-decoration: none; }
.mk-quote-card { background: #fff; color: var(--ink); border-radius: 16px; padding: 1.75rem; position: relative; box-shadow: 0 24px 50px rgba(0,0,0,.28); }
.mk-quote-mark { color: var(--brand); font-size: 2rem; }
.mk-quote-card p { font-size: 1.05rem; line-height: 1.6; font-weight: 500; margin: .5rem 0 1rem; }
.mk-quote-author { font-weight: 700; }
.mk-quote-author span { display: block; color: var(--muted); font-weight: 400; font-size: .85rem; }

/* Service "Learn More" link + tighter check bullets */
.mk-service-more { display: inline-block; margin-top: .9rem; color: var(--brand-ink); font-weight: 700; font-size: .88rem; text-decoration: none; }
.mk-service-more:hover { color: var(--brand); }
.mk-service li i.bi-check2 { color: #16a34a; }

/* Pricing tiers */
.mk-price-toggle { display: inline-flex; background: #e7e3df; border-radius: 999px; padding: 4px; margin-top: 1rem; }
.mk-price-toggle button { border: 0; background: none; padding: .4rem 1.2rem; border-radius: 999px; font-weight: 700; font-size: .9rem; color: var(--muted); cursor: pointer; }
.mk-price-toggle button.is-active { background: var(--brand); color: #fff; }
.mk-price-card { display: flex; flex-direction: column; background: #fff; border: 1px solid var(--line); border-radius: 16px; padding: 1.75rem 1.5rem; position: relative; }
.mk-price-card--popular { border: 2px solid var(--brand); box-shadow: 0 20px 46px rgba(255,106,0,.18); }
.mk-price-badge { position: absolute; top: -13px; left: 50%; transform: translateX(-50%); background: var(--brand); color: #fff; font-size: .72rem; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; padding: .25rem .9rem; border-radius: 999px; white-space: nowrap; }
.mk-price-name { font-weight: 800; font-size: 1.15rem; text-align: center; }
.mk-price-blurb { color: var(--muted); font-size: .84rem; text-align: center; min-height: 2.4em; margin: .3rem 0 .8rem; }
.mk-price-amount { text-align: center; margin-bottom: 1rem; }
.mk-price-num { font-size: 2.1rem; font-weight: 800; color: var(--ink); }
.mk-price-per { color: var(--muted); font-weight: 600; }
.mk-price-features { list-style: none; padding: 0; margin: 0 0 1.25rem; display: grid; gap: .5rem; }
.mk-price-features li { display: flex; gap: .5rem; align-items: flex-start; font-size: .9rem; color: #475569; }
.mk-price-features i { color: #16a34a; margin-top: .15rem; }

/* Process band */
.mk-process-section { padding: 4.5rem 0; background: linear-gradient(160deg, var(--navy-2), var(--navy)); color: #fff; }
.mk-process-section .mk-h2 { color: #fff; }
.mk-process-row { position: relative; }
.mk-process-section .mk-step { text-align: center; }
.mk-process-section .mk-step-num { width: 44px; height: 44px; border-radius: 50%; background: var(--brand); color: #fff; font-weight: 800; display: grid; place-items: center; margin: 0 auto .8rem; }
.mk-process-section .mk-step h4 { color: #fff; font-size: 1.05rem; font-weight: 700; }
.mk-process-section .mk-step p { color: #9aa2ba; font-size: .88rem; }

/* Testimonials */
.mk-testimonial { background: #fff; border: 1px solid var(--line); border-radius: 16px; padding: 1.5rem; box-shadow: 0 6px 18px rgba(13,21,48,.05); }
.mk-stars { color: #f59e0b; font-size: .9rem; margin-bottom: .6rem; }
.mk-testimonial p { font-size: .92rem; line-height: 1.55; color: #334155; }
.mk-testimonial-author { font-weight: 700; margin-top: .8rem; font-size: .92rem; }
.mk-testimonial-author span { display: block; color: var(--muted); font-weight: 400; font-size: .8rem; }

/* CTA band */
.mk-cta-band { background: linear-gradient(120deg, var(--navy-2), var(--navy)); color: #fff; padding: 3rem 0; }
.mk-cta-band h2 { font-weight: 800; font-size: clamp(1.5rem, 3vw, 2.1rem); margin: 0 0 .3rem; }
.mk-cta-band p { color: #b9c0d4; margin: 0; max-width: 620px; }

/* Contact "prefer to chat" card */
.mk-chat-card { display: flex; align-items: center; gap: 1rem; background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 1rem 1.2rem; }
.mk-chat-mascot { width: 64px; height: 64px; object-fit: contain; object-position: top; }
.mk-contact-info li { display: flex; align-items: center; gap: .6rem; padding: .35rem 0; color: #334155; }
.mk-contact-info li i { color: var(--brand); }

/* --- Redesigned public nav (top bar + dropdowns + CTA) -------------------- */
.mk-topbar-left, .mk-topbar-right { display: flex; align-items: center; gap: 1.1rem; }
.mk-topbar-left a { margin-right: 0; }
.mk-topbar-hours { color: #b9c0d4; }
.mk-topbar-hours i { color: var(--brand-bright); }
.mk-flag { font-size: 1rem; }

/* Top utility bar on a phone.
   MUST stay after the .mk-topbar-left/.mk-topbar-right display declaration above
   — that rule is unconditional, so anything earlier loses on source order no
   matter which media query it is in. That is exactly how the old ≤640px block
   died, and the bar rendered in full desktop form on every phone: 111px tall at
   320px (three rows of wrapped text, icons stranded above their own labels), and
   the right-hand group overflowed the viewport by up to 65px, which is where the
   site's horizontal scroll on EVERY page came from.
   The row is nowrap on purpose: letting it wrap is what produced the three-row
   bar. Anything that cannot fit is dropped instead, cheapest first. */
@media (max-width: 991.98px) {
    .mk-topbar { font-size: .8rem; }
    .mk-topbar .mk-container { gap: .6rem; flex-wrap: nowrap; }
    .mk-topbar-left, .mk-topbar-right { gap: .7rem; flex-wrap: nowrap; min-width: 0; }
    .mk-topbar a, .mk-topbar span { white-space: nowrap; }
    .mk-topbar a { margin-right: 0; }
    /* Redundant below 992: the hamburger menu carries the same Login/Dashboard
       button (.mk-nav-login is only hidden in the 992-1199 band). Dropping it is
       what buys the row enough width to stay on one line. */
    .mk-topbar-login { display: none; }
    /* Give the two survivors a real tap height — they were 20px tall strips. */
    .mk-topbar-left a, .mk-ccy-link { padding-top: .5rem; padding-bottom: .5rem; }
}
/* Below ~380px the phone number, the email and the currency switcher cannot
   share one row. The phone number is the action that matters on a phone, so the
   email address steps out (it is still in the footer and on /contact). */
@media (max-width: 379.98px) {
    .mk-topbar-left a[href^="mailto:"] { display: none; }
}
/* Never let the logo be the flex item that absorbs a too-tight nav row: it has
   object-fit:contain, so shrinking the box silently letterboxes the artwork to
   half size instead of overflowing visibly. Squash the gaps, not the brand. */
.mk-nav-brand { display: inline-flex; align-items: center; flex-shrink: 0; }
.mk-nav-cta { color: #fff !important; padding: .5rem 1.1rem; border-radius: 10px; font-weight: 700; font-size: .9rem; white-space: nowrap; }
/* Login sits in the main nav beside the CTA — the way IN shouldn't be less
   visible than the way to buy. */
.mk-nav-login { padding: .45rem .9rem; border-radius: 10px; font-weight: 700; font-size: .9rem; white-space: nowrap; display: inline-flex; align-items: center; gap: .35rem; }
.mk-nav-login i { font-size: 1rem; }
/* 992-1199 the row can't seat everything, so the auth button steps out: the top
   bar carries the SAME link ("Client & Staff Login" / "My Dashboard") and stays
   visible down to 640px, so the way in is never lost — whereas collapsing the
   whole nav to a hamburger would hide it on a 1366 laptop at 125% zoom (~1093 CSS
   px). This MUST live after the .mk-nav-login display declaration above: media
   queries add no specificity, so declaring it earlier in the file loses. */
@media (max-width: 1199.98px) and (min-width: 992px) {
    .mk-nav-login { display: none; }
}
.mk-nav-cta:hover { color: #fff !important; }
.mk-nav-dd { position: relative; }
.mk-nav-dd .dropdown-toggle::after { vertical-align: .1em; margin-left: .25em; }
.mk-nav-dd .dropdown-menu { border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 16px 40px rgba(13,21,48,.14); padding: .4rem; margin-top: .4rem; }
.mk-nav-dd .dropdown-item { border-radius: 8px; font-size: .9rem; font-weight: 600; color: #334155; padding: .5rem .7rem; }
.mk-nav-dd .dropdown-item:hover { background: var(--brand-soft); color: var(--brand-dark); }
/* Must track the .mk-nav-links collapse breakpoint above — if these two
   disagree, the dropdowns/CTA style for one layout while the row is in the other. */
@media (max-width: 991.98px) {
    .mk-nav-dd { width: 100%; }
    .mk-nav-dd .dropdown-menu { position: static !important; transform: none !important; box-shadow: none; border: 0; padding-left: .8rem; }
    /* Inside the hamburger these ARE the navigation — every service page and every
       company page is reached only through here — yet they were 37.6px rows
       stacked with no gap between them. */
    .mk-nav-dd .dropdown-item { min-height: 44px; display: flex; align-items: center; }
    .mk-nav-cta { display: block; text-align: center; margin-top: .6rem; }
    .mk-nav-login { display: flex; justify-content: center; margin-top: .6rem; }
}

/* Footer social icons */
.mk-footer-social { display: flex; gap: .6rem; margin-top: 1rem; }
.mk-footer-social a { width: 36px; height: 36px; border-radius: 9px; display: grid; place-items: center; background: rgba(255,255,255,.08); color: #cbd2e0 !important; font-size: 1rem; }
.mk-footer-social a:hover { background: var(--brand); color: #fff !important; }

/* Reserve the nav logo's box before the image loads (no layout shift / flicker
   while the nav "loads"). Logo art is 1342x444. */
.mk-nav .brand-logo--tagline { aspect-ratio: 1342 / 444; }

/* ============================================================
   Marketing pages (services / service detail / about / contact)
   ============================================================ */
.mk-page-hero { background: linear-gradient(160deg, var(--navy-2) 0%, var(--navy) 70%); color: #eef1f7; padding: 3.5rem 0; }
.mk-page-hero h1 { font-weight: 800; letter-spacing: -.02em; font-size: clamp(1.9rem, 4vw, 3rem); margin: .6rem 0 .8rem; }
.mk-page-hero .mk-lead { color: #b9c0d4; max-width: 760px; }
.mk-page-hero-icon { width: 56px; height: 56px; border-radius: 14px; background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.14); display: grid; place-items: center; font-size: 1.5rem; color: var(--brand-bright); margin-bottom: 1rem; }
.mk-crumbs { font-size: .82rem; color: #9aa2ba; margin-bottom: 1rem; display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.mk-crumbs a { color: #b9c0d4; text-decoration: none; }
.mk-crumbs a:hover { color: #fff; }
.mk-crumbs i { font-size: .7rem; opacity: .6; }
.mk-crumbs span { color: #fff; font-weight: 600; }

/* Feature grid (what's included) */
.mk-feature { background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 1.5rem; height: 100%; }
.mk-feature-icon { width: 46px; height: 46px; border-radius: 12px; display: grid; place-items: center; background: var(--navy); color: var(--brand); font-size: 1.2rem; margin-bottom: .9rem; }
.mk-feature h3 { font-size: 1.05rem; font-weight: 700; margin: 0 0 .35rem; }
.mk-feature p { color: var(--muted); font-size: .9rem; line-height: 1.55; margin: 0; }

/* Checklist */
.mk-checklist { list-style: none; padding: 0; margin: 0; display: grid; gap: .75rem; }
.mk-checklist li { display: flex; gap: .6rem; align-items: flex-start; font-size: 1rem; font-weight: 600; color: #334155; }
.mk-checklist i { color: #16a34a; margin-top: .15rem; }

/* Other-services links */
.mk-service-link { display: flex; align-items: center; gap: .7rem; background: #fff; border: 1px solid var(--line); border-radius: 12px; padding: .9rem 1.1rem; text-decoration: none; color: var(--ink); font-weight: 700; transition: box-shadow .18s, transform .18s; }
.mk-service-link:hover { box-shadow: 0 10px 28px rgba(13,21,48,.10); transform: translateY(-2px); color: var(--ink); }
.mk-service-link > i:first-child { color: var(--brand); font-size: 1.2rem; }
.mk-service-link-arrow { margin-left: auto; color: var(--muted); }

/* About stats */
.mk-stat .n { font-size: 1.9rem; font-weight: 800; color: var(--brand); line-height: 1; }
.mk-stat .l { color: var(--muted); font-size: .85rem; margin-top: .3rem; }

/* Top-bar login link */
.mk-topbar-login { color: #fff !important; font-weight: 600; margin-right: 0 !important; }
.mk-topbar-login i { color: var(--brand-bright); }
.mk-topbar-login:hover { color: var(--brand-bright) !important; }

/* Real-catalogue pricing bits on service pages */
.mk-price-terms { color: var(--muted); font-size: .8rem; text-align: center; margin-bottom: 1rem; }
.mk-service-from { display: inline-block; background: var(--brand-soft); color: var(--brand-dark); font-size: .82rem; font-weight: 700; padding: .15rem .6rem; border-radius: 999px; margin-bottom: .6rem; }

/* Pricing grouped by service line (real catalogue) */
.mk-price-group { margin-bottom: 2.5rem; }
.mk-price-group:last-of-type { margin-bottom: 0; }
.mk-price-group-title { font-size: 1.05rem; font-weight: 800; letter-spacing: .02em; text-transform: uppercase; color: var(--muted); margin-bottom: 1rem; padding-bottom: .5rem; border-bottom: 1px solid var(--line); }

/* ---------------------------------------------------------------------------
   Careers — job list, role page, empty state
   --------------------------------------------------------------------------- */
.mk-jobs { display: grid; gap: 1rem; }
.mk-job {
    display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap;
    background: #fff; border: 1px solid var(--line); border-radius: 14px;
    padding: 1.4rem 1.6rem; text-decoration: none; color: var(--ink);
    transition: box-shadow .18s, transform .18s, border-color .18s;
}
.mk-job:hover { box-shadow: 0 12px 32px rgba(13,21,48,.10); transform: translateY(-2px); border-color: var(--brand-soft); color: var(--ink); }
.mk-job-main { flex: 1 1 20rem; min-width: 0; }
.mk-job-title { font-size: 1.2rem; font-weight: 800; margin: 0 0 .3rem; }
.mk-job-summary { color: var(--muted); font-size: .93rem; line-height: 1.55; margin: 0 0 .6rem; }
.mk-job-meta { display: flex; flex-wrap: wrap; gap: .45rem .9rem; font-size: .82rem; color: var(--muted); font-weight: 600; }
.mk-job-meta span { display: inline-flex; align-items: center; gap: .35rem; }
.mk-job-meta i { color: var(--brand-ink); }
.mk-job-salary { color: #15803d; }
.mk-job-salary i { color: #15803d; }
.mk-job-go { display: inline-flex; align-items: center; gap: .4rem; font-weight: 700; color: var(--brand-ink); white-space: nowrap; }
.mk-job:hover .mk-job-go { color: var(--brand); }

/* Hero variant sits on the dark page-hero, so it needs light-on-dark colours */
.mk-job-meta--hero { margin-top: 1rem; color: rgba(255,255,255,.82); font-size: .88rem; }
.mk-job-meta--hero i { color: var(--brand-bright); }
.mk-job-meta--hero .mk-job-salary,
.mk-job-meta--hero .mk-job-salary i { color: #6ee7a8; }

.mk-job-body { color: #334155; font-size: 1rem; line-height: 1.75; }

.mk-job-aside { position: sticky; top: 1.5rem; background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 1.5rem; }
.mk-job-aside h3 { font-size: 1rem; font-weight: 800; margin: 0 0 1rem; }
.mk-job-aside dl { display: grid; grid-template-columns: auto 1fr; gap: .55rem 1rem; margin: 0 0 1.25rem; font-size: .9rem; }
.mk-job-aside dt { color: var(--muted); font-weight: 600; }
.mk-job-aside dd { margin: 0; font-weight: 700; text-align: right; }

.mk-job-empty { text-align: center; max-width: 44rem; margin: 0 auto; background: #fff; border: 1px dashed var(--line); border-radius: 16px; padding: 2.5rem 1.75rem; }
.mk-job-empty i { font-size: 2.25rem; color: var(--brand); }
.mk-job-empty h3 { font-size: 1.25rem; font-weight: 800; margin: .9rem 0 .5rem; }
.mk-job-empty p { color: var(--muted); line-height: 1.6; margin: 0 0 1.25rem; }

/* The aside is col-lg-5, so it stops sitting beside the body at lg (992px) —
   not 768px. Un-stick and left-align it where the columns actually stack, or
   between 768 and 992 it reads as a right-aligned orphan under the body copy. */
@media (max-width: 991.98px) {
    .mk-job-aside { position: static; }
    .mk-job-aside dd { text-align: left; }
}

@media (max-width: 767.98px) {
    .mk-job { padding: 1.15rem 1.2rem; }
}

/* ---------------------------------------------------------------------------
   How We Work — live office clock + visitor timezone comparison
   --------------------------------------------------------------------------- */
.mk-clock-card { background: #fff; border: 1px solid var(--line); border-radius: 16px; padding: 1.75rem; box-shadow: 0 12px 32px rgba(13,21,48,.06); }
.mk-clock-row { display: flex; align-items: center; justify-content: center; gap: 1.5rem; flex-wrap: wrap; }
.mk-clock { flex: 1 1 12rem; text-align: center; min-width: 0; }
.mk-clock-label { font-size: .78rem; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; display: flex; align-items: center; justify-content: center; gap: .35rem; }
.mk-clock-label i { color: var(--brand-ink); }
.mk-clock-time { font-size: clamp(1.9rem, 5vw, 2.6rem); font-weight: 800; letter-spacing: -.02em; line-height: 1.15; margin-top: .3rem; font-variant-numeric: tabular-nums; }
.mk-clock-day { font-size: .85rem; color: var(--muted); }
.mk-clock-vs { color: var(--brand); font-size: 1.4rem; flex: 0 0 auto; }
.mk-clock-verdict { margin: 1.5rem 0 0; padding: 1rem 1.15rem; border-radius: 12px; line-height: 1.6; font-size: .95rem; text-align: center; background: #f6f7f9; border: 1px solid var(--line); }
.mk-clock-verdict.is-diff { background: #ecfdf5; border-color: #a7f3d0; color: #065f46; }
.mk-clock-verdict.is-diff i { color: #059669; }
.mk-clock-verdict.is-same { background: var(--brand-soft); border-color: #fed7aa; color: #7c2d12; }
.mk-clock-verdict.is-same i { color: var(--brand-ink); }
.mk-clock-verdict:empty { display: none; }

@media (max-width: 575.98px) {
    .mk-clock-card { padding: 1.25rem; }
    .mk-clock-vs { transform: rotate(90deg); }
}

/* Sale pricing on public plan cards */
.mk-price-was { display: block; font-size: 1rem; color: var(--muted); text-decoration: line-through; line-height: 1.2; }
.mk-price-num--sale { color: #15803d; }
.mk-sale-badge {
    display: inline-flex; align-items: center; gap: .3rem; margin-top: .4rem;
    background: #dcfce7; color: #166534; border: 1px solid #86efac;
    font-size: .7rem; font-weight: 700; letter-spacing: .02em;
    padding: .15rem .5rem; border-radius: 999px; white-space: nowrap;
}
.mk-sale-badge i { font-size: .65rem; }
.mk-price-note { display: block; font-size: .72rem; color: var(--muted); margin-top: .3rem; font-weight: 600; }

/* Featured "most popular" pricing tier */
.mk-price-card { position: relative; }
.mk-price-card.is-featured { border-color: var(--brand); box-shadow: 0 12px 30px rgba(255,106,0,.16); }
.mk-price-flag {
    position: absolute; top: -.7rem; left: 50%; transform: translateX(-50%);
    background: var(--brand); color: #fff; font-size: .66rem; font-weight: 800;
    letter-spacing: .06em; text-transform: uppercase; padding: .2rem .6rem;
    border-radius: 999px; white-space: nowrap;
}

/* A step label ("Step 1") — distinct from .mk-step-num, which is a 44px circle
   sized for a single digit and would clip a word. */
.mk-step-label {
    display: inline-block; font-size: .68rem; font-weight: 800; letter-spacing: .08em;
    text-transform: uppercase; color: var(--brand-ink); background: var(--brand-soft);
    padding: .15rem .5rem; border-radius: 999px;
}

/* Hero service chips — all four lines, on the navy hero */
.mk-hero-services { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1.4rem; }
.mk-hero-service {
    display: inline-flex; align-items: center; gap: .4rem;
    padding: .4rem .8rem; border-radius: 999px;
    background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.16);
    color: #eef1f7; text-decoration: none; font-weight: 600; font-size: .85rem;
    transition: background .15s, border-color .15s, transform .15s;
}
.mk-hero-service i { color: var(--brand-bright); font-size: .95rem; }
.mk-hero-service:hover {
    background: rgba(255,106,0,.16); border-color: var(--brand);
    color: #fff; transform: translateY(-1px);
}

/* Per-plan feature ticks on the pricing card (admin-authored; empty = hidden) */
.mk-price-features { list-style: none; padding: 0; margin: .9rem 0 1.1rem; display: grid; gap: .45rem; text-align: left; }
.mk-price-features li { display: flex; align-items: flex-start; gap: .5rem; font-size: .87rem; color: #475569; line-height: 1.45; }
.mk-price-features i { color: #15803d; font-size: .9rem; flex: 0 0 auto; margin-top: .15rem; }

/* "Keep grouped, just prettier": more air between service lines + clearer group headings */
.mk-price-group + .mk-price-group { margin-top: 3rem; }
.mk-price-group-title {
    display: flex; align-items: center; gap: .75rem;
    font-size: 1.05rem; font-weight: 800; letter-spacing: .02em;
    text-transform: uppercase; color: var(--muted); margin-bottom: 1.25rem;
}
.mk-price-group-title::after { content: ""; flex: 1 1 auto; height: 1px; background: var(--line); }
.mk-price-card { padding: 1.6rem 1.35rem; }

/* ============================================================
   Mobile hardening — verified fixes (see the mobile bug sweep)
   ============================================================ */
/* iOS Safari ZOOMS the page when you focus an input whose font is < 16px, which
   feels broken and shifts the whole layout. Force every form control to 16px at
   phone widths. The .mk-hero-form override (.92rem) was a live instance. This
   only applies <=576px, so the desktop look is untouched. */
@media (max-width: 576px) {
    .form-control, .form-select, .mk-hero-form .form-control, .mk-hero-form .form-select {
        font-size: 16px;
    }
    /* NOTE: the 16px rule is also applied up to 991.98px further down — a phone in
       landscape is wider than 576px and zooms just the same. */
    /* Give tappable controls a 44px minimum height — Apple's HIG target. Small
       buttons in tight table rows are the usual offenders. */
    .btn, .form-control, .form-select { min-height: 44px; }
    /* This exemption used to be `.btn-sm, .btn-link`, which cancelled the rule
       one line above it for essentially every button in the product — the row
       actions in tables are all .btn-sm, and they are exactly the "small buttons
       in tight table rows" the comment names as the usual offenders. Narrowed to
       genuine inline TEXT links, which do need to stay inline with their
       sentence, and the table actions get a real target back below. */
    .btn-link { min-height: 0; }
    .wh td .btn-sm, .app td .btn-sm { min-height: 40px; min-width: 40px; }
    /* Adjacent row actions were touching, so a mis-tap hit the wrong verb —
       which matters most where the pair is approve/reject or edit/delete. */
    .wh td .btn + .btn, .app td .btn + .btn,
    .wh td form + form, .app td form + form { margin-left: .35rem; }
    /* Any table that forgot its wrapper still can't burst the viewport. */
    .table-responsive { -webkit-overflow-scrolling: touch; }
    /* Filter/status button groups (tickets, quotes, invoices) are 4-5 buttons that
       can't wrap and overshoot a 360-375px viewport, pushing the page sideways.
       Let them wrap. */
    .btn-group { flex-wrap: wrap; }
    /* Header toolbars laid out with d-flex gap-2 but no wrap — let their buttons
       drop to a second line rather than compress and truncate. */
    .card-header .d-flex, .page-head .d-flex { flex-wrap: wrap; }
    /* Long unbreakable strings (app URLs on the Client Apps rows, hosting domains)
       must wrap instead of shoving action buttons off-screen. */
    .text-break-mobile, .app-url, td .text-truncate { word-break: break-word; overflow-wrap: anywhere; }
}

/* A sticky nav overlays the top of any in-page anchor jump (#pricing, #packages)
   so the heading lands hidden behind it. Reserve its height. Applies at all widths
   because the nav is sticky on desktop too. */
:target { scroll-margin-top: 96px; }
[id] { scroll-margin-top: 96px; }

/* ============================================================
   Request queue + availability
   ============================================================ */

/* --- Priority stripe on a board card -----------------------------------
   delivery-board templates but never defined, so a priority a user had set
   showed nothing. Defined here once, for both boards. */

/* --- Checklist rows (delivery cards and request todos alike) -----------
   Also previously referenced-but-undefined: .cl-item on the board card page
   had no layout at all, so the tick, the label and the delete button stacked. */
.cl-item { display: flex; align-items: flex-start; gap: .5rem; padding: .3rem 0; }
.cl-item + .cl-item { border-top: 1px solid #f1f5f9; }
.cl-item-tick { display: flex; align-items: flex-start; gap: .5rem; flex: 1 1 auto; min-width: 0; }
.cl-item-text { font-size: .88rem; color: #2c3348; line-height: 1.45; cursor: pointer; }
.cl-item-text--done { color: #94a3b8; text-decoration: line-through; }
.cl-item-del { opacity: .35; padding: .1rem .35rem; line-height: 1; }
.cl-item:hover .cl-item-del { opacity: 1; }

/* --- Stage dots ------------------------------------------------------- */
.rq-dot { display: inline-block; width: .55rem; height: .55rem; border-radius: 50%; background: #94a3b8; flex: 0 0 auto; }
.rq-dot--queued { background: #94a3b8; }
.rq-dot--scoping { background: #38bdf8; }
.rq-dot--awaiting_client { background: #f59e0b; }
.rq-dot--in_progress { background: var(--brand, #FF6A00); }
.rq-dot--in_review { background: #6366f1; }
.rq-dot--revising { background: #f59e0b; }
.rq-dot--approved { background: #22c55e; }
.rq-dot--cancelled { background: #64748b; }
.rq-dot--av-online { background: #22c55e; }
.rq-dot--av-working { background: var(--brand, #FF6A00); }
.rq-dot--av-away { background: #f59e0b; }
.rq-dot--av-offline { background: #94a3b8; }

/* --- Stage-change markers in a request thread -------------------------
   A bare stage change is a marker, not a message, so it gets a line rather
   than a card — otherwise the history is mostly chrome. */
.rq-marker { display: flex; align-items: center; gap: .5rem; font-size: .82rem; color: #64748b; padding: .15rem .25rem; }
.rq-marker-dot { width: .4rem; height: .4rem; border-radius: 50%; background: #cbd5e1; flex: 0 0 auto; }

/* --- Client request rows ---------------------------------------------- */
.pj-card--action { border-color: var(--brand, #FF6A00); box-shadow: 0 0 0 1px var(--brand, #FF6A00); }

/* --- Availability badges ---------------------------------------------- */
.av-badge { display: inline-flex; align-items: center; gap: .4rem; padding: .25rem .7rem; border-radius: 999px;
    font-weight: 600; font-size: .85rem; background: #f1f5f9; color: #475569; }
.av-hero-badge { display: inline-flex; align-items: center; gap: .5rem; padding: .5rem 1.1rem; border-radius: 999px;
    font-weight: 700; font-size: 1rem; background: #f1f5f9; color: #475569; }
.av-badge--online { background: #dcfce7; color: #15803d; }
.av-badge--working { background: #fff2e8; color: #c2410c; }
.av-badge--away { background: #fef3c7; color: #92400e; }
.av-badge--offline { background: #f1f5f9; color: #475569; }

.text-brand { color: var(--brand, #FF6A00); }
.border-brand { border-color: var(--brand, #FF6A00) !important; }

/* --- API usage charts ---------------------------------------------------
   Inline SVG rather than a charting library: this app loads Bootstrap and
   nothing else, and a JS bundle to draw thirty bars would be the heaviest
   thing on the page. */
.usage-chart-svg { width: 100%; height: 140px; display: block; }
.usage-chart-svg rect { transition: opacity .12s; }
.usage-chart-svg rect:hover { opacity: .72; }

/* --- Command palette ----------------------------------------------------
   Ctrl-K from any admin page. Sits above everything including the sidebar
   backdrop (z-index 1080 is Bootstrap's toast layer; this must beat it). */
.cp-backdrop { position: fixed; inset: 0; background: rgba(13,21,48,.45); z-index: 1090;
    display: flex; align-items: flex-start; justify-content: center; padding: 8vh 1rem 1rem; }
.cp-backdrop[hidden] { display: none; }
.cp-panel { width: 100%; max-width: 40rem; background: #fff; border-radius: 14px;
    box-shadow: 0 24px 60px rgba(13,21,48,.28); overflow: hidden; display: flex; flex-direction: column;
    max-height: 78vh; }
.cp-input-wrap { display: flex; align-items: center; gap: .6rem; padding: .85rem 1rem; border-bottom: 1px solid #e7eaf3; }
.cp-input { flex: 1 1 auto; border: 0; outline: 0; font-size: 1rem; color: #1f2637; background: transparent; }
.cp-esc { font-size: .65rem; background: #eef1f7; color: #5b6479; border-radius: 4px; padding: .1rem .35rem; }
.cp-results { overflow-y: auto; padding: .35rem 0; }
.cp-group { font-size: .66rem; text-transform: uppercase; letter-spacing: .07em; color: #94a3b8;
    padding: .6rem 1rem .25rem; font-weight: 700; }
.cp-item { display: flex; align-items: center; gap: .7rem; padding: .5rem 1rem; text-decoration: none;
    color: #1f2637; }
.cp-item.is-active { background: var(--brand-soft, #fff2e8); }
.cp-item i { color: #94a3b8; flex: 0 0 auto; }
.cp-item.is-active i { color: var(--brand, #FF6A00); }
.cp-item-body { display: flex; flex-direction: column; min-width: 0; }
.cp-item-label { font-size: .9rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cp-item-sub { font-size: .75rem; color: #64748b; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cp-hint { padding: 1.25rem 1rem; color: #94a3b8; font-size: .85rem; text-align: center; }
.cp-foot { display: flex; gap: 1rem; padding: .5rem 1rem; border-top: 1px solid #e7eaf3;
    font-size: .7rem; color: #94a3b8; }
.cp-foot kbd { background: #eef1f7; color: #5b6479; border-radius: 3px; padding: 0 .25rem; margin-right: .15rem; }

/* --- Overview grid ------------------------------------------------------
   Every tile is a link (see the page's comment: a number you can't click is
   a dead end), so the hover affordance matters more than usual. */
.ov-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: .75rem; }
.ov-stat { display: block; padding: .6rem .75rem; border: 1px solid #e7eaf3; border-radius: 10px;
    text-decoration: none; color: inherit; background: #fff; transition: .12s; }
a.ov-stat:hover { border-color: var(--brand, #FF6A00); box-shadow: 0 2px 10px rgba(13,21,48,.08); }
.ov-stat-label { font-size: .68rem; text-transform: uppercase; letter-spacing: .05em; color: #94a3b8; font-weight: 700; }
.ov-stat-value { font-size: 1.45rem; font-weight: 700; color: #1f2637; line-height: 1.2; margin-top: .15rem; }
.ov-stat-hint { font-size: .7rem; color: #64748b; margin-top: .1rem; }

/* --- Access vault + command library -------------------------------------- */
/* Commands are read as code and copied as code, so they get a code surface:
   monospace, wrapping (a long rsync line must not scroll a card sideways), and
   enough contrast to scan a list of them quickly. */
.cmd-body { background: #0f172a; color: #e2e8f0; border-radius: 8px; padding: .55rem .7rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .8rem;
    white-space: pre-wrap; word-break: break-all; margin: 0; }
.cmd-row { border: 1px solid #e7eaf3; border-radius: 10px; padding: .6rem .7rem; }
.cmd-row + .cmd-row { margin-top: .5rem; }
.copy-btn { transition: background-color .15s ease, color .15s ease; }

/* ==========================================================================
   WHMCS-style admin shell
   ==========================================================================
   Replaces the 33-link sidebar rail with a brand bar + horizontal grouped
   menu, which is how WHMCS arranges an admin and why it scales past a dozen
   screens: the rail had to scroll, and scrolling navigation hides itself.

   Scoped to body.wh so the client portal and public site are untouched.
   ========================================================================== */

.wh {
    --wh-bar: #0D1530;          /* brand bar — the existing deep navy */
    --wh-menu: #16203f;         /* menu bar, one step lighter so the two read as separate */
    --wh-menu-hover: #22305c;
    --wh-panel: #ffffff;
    --wh-line: #dfe3ea;
    --wh-ink: #1f2637;
    --wh-muted: #5b6479;        /* AA on white (#94a3b8 was 2.6:1 and failed) */
    background: #eef1f5;
}

.wh-shell { width: 100%; max-width: 1600px; margin: 0 auto; padding: 0 1rem; }

/* --- brand bar ---------------------------------------------------------- */
.wh-brandbar { background: var(--wh-bar); color: #fff; }
.wh-brandbar .wh-shell { display: flex; align-items: center; justify-content: space-between; gap: 1rem; min-height: 56px; }
.wh-brand { display: flex; align-items: center; gap: .55rem; color: #fff; text-decoration: none; font-weight: 700; }
.wh-brand img { height: 26px; width: auto; }
.wh-brand small { color: #93a0bd; font-weight: 500; font-size: .74rem; border-left: 1px solid #33406a; padding-left: .55rem; }
.wh-brandbar-actions { display: flex; align-items: center; gap: .5rem; }

.wh-btn-ghost { background: rgba(255,255,255,.10); border: 1px solid rgba(255,255,255,.18); color: #fff; }
.wh-btn-ghost:hover, .wh-btn-ghost:focus { background: rgba(255,255,255,.18); color: #fff; }

/* --- menu bar ----------------------------------------------------------- */
.wh-menubar { background: var(--wh-menu); border-bottom: 3px solid var(--brand); }
.wh-menu { display: flex; flex-wrap: wrap; list-style: none; margin: 0; padding: 0; }
.wh-menu > li { position: relative; }

.wh-menu-link {
    display: inline-flex; align-items: center; gap: .4rem;
    padding: .7rem .85rem; color: #cdd5e6; text-decoration: none;
    background: none; border: 0; font-size: .875rem; font-weight: 500; white-space: nowrap;
}
.wh-menu-link:hover { background: var(--wh-menu-hover); color: #fff; }

/* Current section. A left/bottom bar plus a colour change, not colour alone —
   colour alone is invisible to anyone who cannot distinguish it. */
.wh-menu-link.current { color: #fff; background: var(--wh-menu-hover); box-shadow: inset 0 -3px 0 var(--brand-bright); }
.wh-menu-link i { opacity: .9; }
.wh-menu .dropdown-menu { margin-top: 0; border-radius: 0 0 6px 6px; border-color: var(--wh-line); min-width: 15rem; }
.wh-menu .dropdown-item { display: flex; align-items: center; gap: .55rem; padding: .45rem .9rem; font-size: .875rem; }
.wh-menu .dropdown-item i { width: 16px; text-align: center; color: var(--wh-muted); }
.wh-menu .dropdown-item.active { background: var(--brand-soft); color: var(--brand-ink); font-weight: 600; }
.wh-menu .dropdown-item.active i { color: var(--brand-ink); }

.wh-menu-toggle { display: none; background: none; border: 0; color: #cdd5e6; padding: .6rem .2rem; font-size: .9rem; }

/* The menu wrapper carries Bootstrap's .collapse so the mobile toggle can drive
   it, and .collapse is display:none until something adds .show. On desktop
   nothing ever does — the toggle button is hidden above 992px — so without this
   the entire menu was invisible on every desktop screen while the strip it
   lives in still rendered. Bootstrap's own navbar solves this with
   .navbar-expand-lg; this is the same idea for a bar that is not a .navbar. */
@media (min-width: 992px) {
    .wh-menu-collapse { display: block !important; }
}

/* --- page ---------------------------------------------------------------- */
.wh-body { padding-bottom: 1.5rem; }
/* align-items:flex-start, not center: once a subtitle exists the two sides are
   different heights, and centring floats the action button against the middle
   of a two-line block. flex-wrap so a long title and its actions stack on a
   phone rather than crushing each other. */
.wh-pagehead { display: flex; align-items: flex-start; justify-content: space-between;
    flex-wrap: wrap; gap: .5rem 1rem; padding: 1rem 0 .75rem; }
.wh-pagetitle { font-size: 1.3rem; font-weight: 700; margin: 0; color: var(--wh-ink); }
.wh-crumb { margin: 0 0 .1rem; font-size: .72rem; font-weight: 600; letter-spacing: .04em;
    text-transform: uppercase; color: var(--wh-muted); }
.wh-pagesub { margin: .2rem 0 0; font-size: .875rem; color: var(--wh-muted); max-width: 70ch; }
.wh-pageactions { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem; }
.wh-main { min-height: 50vh; }
.wh-footer { display: flex; justify-content: space-between; flex-wrap: wrap; gap: .5rem;
    margin-top: 1.5rem; padding-top: .85rem; border-top: 1px solid var(--wh-line);
    font-size: .78rem; color: var(--wh-muted); }

/* --- panels: the WHMCS look for the cards already in every view ---------- */
.wh .card { border: 1px solid var(--wh-line); border-radius: 6px; box-shadow: 0 1px 2px rgba(16,24,40,.04); }
.wh .card-header {
    background: #f6f8fb; border-bottom: 1px solid var(--wh-line);
    font-weight: 600; font-size: .82rem; text-transform: uppercase; letter-spacing: .03em;
    color: #3b4459; padding: .6rem .9rem;
}
.wh .card-body { padding: .9rem; }

/* Denser tables — an admin is read, not browsed. */
.wh .table { font-size: .875rem; }
.wh .table > thead > tr > th {
    background: #f6f8fb; border-bottom: 2px solid var(--wh-line);
    font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; color: #3b4459; font-weight: 700;
}
.wh .table > tbody > tr:hover { background: #f9fbfd; }
.wh .table > :not(caption) > * > * { padding: .55rem .6rem; }

/* --- accessibility fixes the audit confirmed ----------------------------- */

/* SCOPE NOTE. These were `.wh`-only, which is the admin shell — so the client
   portal and the /hr staff area, both of which wrap their content in `.app`,
   opted out of the readable button colour, the focus ring and the muted-text
   fix. That put the VAs' own Clock In button at 2.87:1, on the one screen built
   for the newest and least-trained users in the system.
   `.app` is added alongside `.wh` rather than making these global, because the
   public marketing site deliberately uses the bright orange on large display
   type, where the contrast ratio does hold. */

/* White on #FF6A00 is 2.87:1 and fails AA. --brand-ink is the same hue at ~5:1,
   so the button stays orange and becomes readable. The BRIGHT orange is kept
   for large display type and for accents on dark, where the ratio holds. */
.wh .btn-brand, .wh .btn-primary,
.app .btn-brand, .app .btn-primary {
    --bs-btn-bg: var(--brand-ink); --bs-btn-border-color: var(--brand-ink);
    --bs-btn-hover-bg: #a8360a; --bs-btn-hover-border-color: #a8360a;
    --bs-btn-active-bg: #a8360a; --bs-btn-active-border-color: #a8360a;
    --bs-btn-color: #fff; --bs-btn-hover-color: #fff; --bs-btn-active-color: #fff;
    background-color: var(--brand-ink); border-color: var(--brand-ink); color: #fff;
}
.wh .btn-outline-brand, .app .btn-outline-brand {
    --bs-btn-color: var(--brand-ink); --bs-btn-border-color: var(--brand-ink);
    --bs-btn-hover-bg: var(--brand-ink); --bs-btn-hover-border-color: var(--brand-ink); --bs-btn-hover-color: #fff;
    color: var(--brand-ink); border: 1px solid var(--brand-ink); }
/* The literal `color` above beats Bootstrap's --bs-btn-hover-color variable, so
   on hover the fill went brand-ink while the label stayed brand-ink and the
   text disappeared into the button. Stated explicitly rather than left to the
   variable it was already overriding. */
.wh .btn-outline-brand:hover, .wh .btn-outline-brand:focus, .wh .btn-outline-brand:active,
.app .btn-outline-brand:hover, .app .btn-outline-brand:focus, .app .btn-outline-brand:active {
    background-color: var(--brand-ink); border-color: var(--brand-ink); color: #fff;
}
.wh a, .app a { color: var(--brand-ink); }
.wh a:hover, .app a:hover { color: #a8360a; }
/* The sidebar in the portal and /hr is dark; brand-ink on navy is unreadable,
   so those links keep whatever the sidebar rules already give them. */
.app .sidebar a, .app .sidebar a:hover { color: inherit; }

/* There was no visible focus ring anywhere in the admin, so a keyboard user had
   no way to tell where they were. */
.wh :focus-visible, .app :focus-visible { outline: 3px solid var(--brand-bright); outline-offset: 2px; border-radius: 3px; }
.wh-menubar :focus-visible, .wh-brandbar :focus-visible, .app .sidebar :focus-visible { outline-color: #fff; }

/* #94a3b8 on white is 2.6:1. These are labels people are meant to read. */
.wh .text-muted, .wh .form-text, .wh .ov-stat-label, .wh .cp-group,
.app .main .text-muted, .app .main .form-text { color: var(--wh-muted) !important; }

/* Bootstrap's #ffc107 on white is 1.63:1 — and on the Overview these are the
   only figures that mean "act on this now", so the least readable numbers on
   the page were the urgent ones. Text only; the badge fills are unaffected. */
.wh .text-warning, .app .main .text-warning { color: #a16207 !important; }

/* --- responsive ---------------------------------------------------------- */
@media (max-width: 991.98px) {
    .wh-menu-toggle { display: inline-flex; align-items: center; gap: .4rem; }
    .wh-menu-collapse { width: 100%; }
    .wh-menu { flex-direction: column; padding-bottom: .5rem; }
    .wh-menu-link { width: 100%; justify-content: flex-start; }
    /* Collapse hides with display:none, so nothing inside stays in the tab order
       while off-screen — the failure the old translateX(-100%) drawer had. */
    .wh-menu .dropdown-menu { position: static; float: none; border: 0; background: rgba(0,0,0,.18); margin: 0 0 .25rem .75rem; }
    .wh-menu .dropdown-item { color: #cdd5e6; }
    .wh-menu .dropdown-item:hover { background: rgba(255,255,255,.08); color: #fff; }
}

@media print {
    .wh-brandbar, .wh-menubar, .wh-footer { display: none !important; }
}

/* --- WHMCS shell, round two: logo, header search, stat tiles -------------- */

/* The real logo is 1342x444 and carries the wordmark, so it is sized by height
   and stands alone — no text beside it to disagree with the artwork. */
.wh-brand img { height: 30px; width: auto; display: block; }
.wh-brand { gap: .65rem; }
.wh-brand small { color: #93a0bd; font-weight: 500; font-size: .72rem; border-left: 1px solid #33406a; padding-left: .6rem; }

/* Header search. Reads as a field, behaves as a button — see the partial. */
.wh-brandbar .wh-shell { gap: .75rem; }
.wh-brandbar-search { flex: 1 1 auto; max-width: 520px; min-width: 0; }
.wh-search {
    display: flex; align-items: center; gap: .55rem; width: 100%;
    background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.2);
    color: #dbe2f0; border-radius: 6px; padding: .42rem .7rem;
    font-size: .85rem; text-align: left; cursor: text;
}
.wh-search:hover { background: rgba(255,255,255,.18); border-color: rgba(255,255,255,.32); }
.wh-search .wh-search-text { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #b9c4da; }
.wh-search-kbd { font-size: .65rem; background: rgba(255,255,255,.16); color: #dbe2f0;
    border-radius: 4px; padding: .05rem .35rem; border: 0; }

@media (max-width: 767.98px) {
    /* Keep the icon, drop the prompt — the bar is too tight for both. */
    .wh-brandbar-search { flex: 0 0 auto; }
    .wh-search .wh-search-text { display: none; }
}

/* --- stat tiles: the WHMCS at-a-glance row ------------------------------- */
.wh .stat-card {
    border: 1px solid var(--wh-line); border-top: 3px solid var(--brand);
    border-radius: 6px; transition: box-shadow .15s, transform .15s;
}
.wh a:hover > .stat-card { box-shadow: 0 4px 14px rgba(16,24,40,.10); transform: translateY(-1px); }
.wh .stat-card .card-body { padding: .8rem .9rem; }
.wh .stat-icon {
    width: 40px; height: 40px; flex: 0 0 40px; border-radius: 8px;
    display: flex; align-items: center; justify-content: center;
    background: var(--brand-soft); color: var(--brand-ink); font-size: 1.05rem;
}
.wh .stat-value { font-size: 1.35rem; font-weight: 700; line-height: 1.15; color: var(--wh-ink); }
.wh .stat-label { font-size: .7rem; text-transform: uppercase; letter-spacing: .05em;
    color: var(--wh-muted); font-weight: 700; margin-top: .1rem; }

/* Colour the row left to right so the tiles are distinguishable at a glance
   rather than five identical orange bars. Money reads green, trouble reads red. */
.wh .stat-card { border-top-color: #2563eb; }
.wh .stat-card .stat-icon { background: #e8efff; color: #1d4ed8; }
.wh .col-6:nth-child(2) .stat-card, .wh .col-6:nth-child(3) .stat-card { border-top-color: #16a34a; }
.wh .col-6:nth-child(2) .stat-icon, .wh .col-6:nth-child(3) .stat-icon { background: #e7f6ec; color: #15803d; }
.wh .col-6:nth-child(4) .stat-card { border-top-color: #d97706; }
.wh .col-6:nth-child(4) .stat-icon { background: #fef3e2; color: #b45309; }
.wh .col-6:nth-child(5) .stat-card { border-top-color: #dc2626; }
.wh .col-6:nth-child(5) .stat-icon { background: #fdecec; color: #b91c1c; }

/* --- page header: room for the primary action ---------------------------- */
.wh-pagehead { border-bottom: 1px solid var(--wh-line); margin-bottom: 1rem; }
.wh-pagetitle { display: flex; align-items: center; gap: .5rem; }

/* Buttons in a card header should not tower over the header text. */
.wh .card-header .btn-sm { padding: .2rem .5rem; font-size: .78rem; }

/* The logo artwork is dark navy on transparent — it was drawn for light
   backgrounds, and on the navy brand bar "Opti" and the tagline vanished
   entirely, leaving only the orange "Tide" legible. Same white chip the public
   footer already uses to stand it on dark. Fixing this in CSS rather than
   asking for a reversed export keeps one logo file as the single source. */
.wh-brand { background: #fff; border-radius: 8px; padding: 5px 10px; }
.wh-brand img { height: 26px; }
.wh-brand small {
    /* Now sitting on white, so the light-on-dark treatment would disappear. */
    color: #5b6479; border-left-color: #d7dbe4;
}

/* Which project board a request belongs to.
   Live (a card exists) is a link and reads as one; pending is flat and muted,
   because "this will go to Web Design" and "this IS on Web Design, click to see
   it" are different facts and looking identical made the tag useless. */
/* Selector carries `a` because the shell's `.wh a { color: var(--brand-ink) }`
   is (0,1,1) and would otherwise outrank a bare class, painting this tag rust —
   which reads as a warning rather than a link to the board. */

/* ==========================================================================
   Touch and small-screen corrections.
   Deliberately at the END of the file. Everything below has to beat an
   unconditional declaration written earlier, and a media query adds no
   specificity — the only lever left is source order. This file has already lost
   that argument twice (the ≤640px top bar, the ≤576px stat tiles), so new
   mobile rules go here rather than next to the thing they correct.
   ========================================================================== */

/* The chat bubble is position:fixed at z-index 1080; the nav is z-index 40. With
   the hamburger menu open its rows run the full width of the screen, so the
   bubble sat on top of the right-hand end of "Company" and "Blog" and swallowed
   taps meant for them. Lift the nav over the widget only while the menu is
   actually open, so the chat panel still wins the rest of the time. */
.mk-nav:has(.mk-nav-links.open) { z-index: 1085; }

@media (max-width: 991.98px) {
    /* iOS Safari zooms the viewport when you focus an input under 16px and does
       NOT zoom back out on blur. The rule for this already existed but stopped at
       576px — a phone held sideways is 780-932px wide and zooms exactly the same.
       (The chat box is NOT fixed here: partials/chat-widget.php carries its own
       <style> in the body, which is later in source order than this file and would
       win. It is fixed in that partial instead.) */
    .form-control, .form-select,
    .mk-hero-form .form-control, .mk-hero-form .form-select { font-size: 16px; }

    /* The footer is 16 stacked links; at .28rem padding they were 30px rows with
       no dead space between them, so Terms / Privacy / Refund were three flush
       targets. Desktop density is untouched. */
    .mk-footer-col a, .mk-footer-contact a,
    .mk-footer .foot-links a { min-height: 44px; display: flex; align-items: center; }
    .mk-footer .foot-links li { padding: 0; }
}

/* A tap on a touch screen leaves :hover latched until you tap something else, so
   every card the visitor touched stayed lifted 3-4px with a drop shadow while
   they scrolled — the page looked like it had stuck buttons all over it. The
   existing (hover:none) block covers one admin selector; these are the public
   ones. */
@media (hover: none), (pointer: coarse) {
    .mk-service:hover, .mk-plan:hover, .mk-blog-card:hover,
    .mk-service-link:hover, .mk-job:hover { transform: none; box-shadow: none; }
}

/* .66rem is 10.6px — under the 12px floor for body-adjacent text, and this is the
   label that steers the whole pricing decision. */
.mk-price-flag { font-size: .75rem; }

/* The four "Learn More About …" links are the routes into the four things the
   business actually sells, and they were 21px-tall strips. The extra height is
   absorbed into the margin-top that was already there, so nothing moves. */
@media (max-width: 991.98px) {
    .mk-service-more { display: inline-flex; align-items: center; min-height: 44px; margin-top: .4rem; }
}

/* The anchor reserve has to clear the sticky nav, and the nav is not one height:
   112px from 992px up, 86px below it. A single 96px value cleared neither
   properly — it was 16px short on desktop, where /services#pricing lands. */
:target { scroll-margin-top: 96px; }
[id] { scroll-margin-top: 96px; }
@media (min-width: 992px) {
    :target { scroll-margin-top: 124px; }
    [id] { scroll-margin-top: 124px; }
}

/* calc(100vh - 90px) assumed 90px of chrome above the sign-in card. The public
   top bar + nav is 134px on a phone, so the card's box ran 44px past the bottom
   of the screen and /login scrolled for no reason. dvh so the mobile browser's
   own toolbar counts. */
@media (max-width: 991.98px) {
    .auth-body { min-height: calc(100vh - 134px); min-height: calc(100dvh - 134px); }
}

/* ==========================================================================
   WHMCS-style client area (body.wh.wh-client) — additions on top of the admin
   shell above. At the end of the file on purpose: everything here only adds
   selectors, and the shell rules it leans on are all earlier in source order.
   ========================================================================== */

/* "Hello, Name!" sits on the right of the menu bar, where WHMCS puts it. */
@media (min-width: 992px) {
    .wh-client .wh-menu-account { margin-left: auto; }
    .wh-client .wh-menu-account .dropdown-menu { right: 0; left: auto; }
}

/* The brand bar has no search slot in the client area, so the brand hugs the
   left and the actions the right without a 520px gap between them. */
.wh-client .wh-brandbar .wh-shell { justify-content: space-between; }

/* `.wh a` (0,1,1) outranks `.wh-menu-link` (0,1,0), so the two menu entries
   that are plain links — Home here, Dashboard and Overview in the admin — went
   orange while the dropdown buttons beside them stayed grey. */
.wh a.wh-menu-link { color: #cdd5e6; }
.wh a.wh-menu-link:hover, .wh a.wh-menu-link:focus, .wh a.wh-menu-link.current { color: #fff; }

/* The brand-bar ghost button is an <a>, and `.wh a` paints links brand-ink —
   which on the navy bar made "Open Ticket" the only orange text in the chrome.
   White, like the button it sits next to in the admin. */
.wh-client a.wh-btn-ghost, .wh-client a.wh-btn-ghost:hover, .wh-client a.wh-btn-ghost:focus { color: #fff; text-decoration: none; }

/* The Invoices tile carries the money: amber when something is owing, red
   when it is overdue, green only when there is nothing to pay. The generic
   left-to-right colouring above would paint it green regardless. */
.wh-client .stat-card.is-owing { border-top-color: #d97706; }
.wh-client .stat-card.is-owing .stat-icon { background: #fef3e2; color: #b45309; }
.wh-client .stat-card.is-overdue { border-top-color: #dc2626; }
.wh-client .stat-card.is-overdue .stat-icon { background: #fdecec; color: #b91c1c; }

/* Side panel details. */
.wh-client .wh-info { font-size: .9rem; line-height: 1.45; }

/* Status pills: WHMCS colours a status, never just words it. Bootstrap's
   warning fill is yellow on dark text and reads fine; its info fill is pale
   cyan on dark, which does not — Sent invoices use the brand-ink tint. */
.wh-client .badge.text-bg-info { background-color: #e8efff !important; color: #1d4ed8 !important; }
.wh-client .badge.text-bg-primary { background-color: #1d4ed8 !important; }

/* Stat tile note under the label. */
.wh-client .stat-card .small { font-size: .74rem; }
