/* ─────────────────────────────────────────────────────────────────────────────
 * member-system.css — the site skin for /members
 *
 * ── WHY THIS FILE EXISTS ────────────────────────────────────────────────────
 * /members renders the SHARED template ---member-kit/templates/member/dashboard.php.
 * That template's own <style> block says, at :108-109:
 *
 *     Structural-only CSS — zero colors, zero fonts
 *     All visual styling comes from site's member-system.css via --mk-* vars
 *
 * This site had no such file. The delivered HTML contained ZERO <link> tags —
 * verified 2026-07-31 by fetching the page and grepping for `<link` (0 hits). The
 * page was therefore laid out but had no colour, no font and no surfaces: not
 * "broken", just naked, at a clean HTTP 200. Nothing in the site could detect it.
 *
 * ── 🔴 SOURCE ORDER: THIS SHEET IS PARSED *BEFORE* THE TEMPLATE'S <style> ────
 * The only hook for a stylesheet is $memberConfig['head_extra'], emitted at
 * dashboard.php:103-105 — three lines ABOVE the <style> block at :107. So for any
 * property the template also sets, equal specificity means THE TEMPLATE WINS.
 *
 * Every rule here is therefore scoped one level deeper than the template's
 * (`.mk-root .mk-btn`, specificity 0,2,0 > the template's `.mk-btn`, 0,1,0). Do not
 * "tidy" a `.mk-root ` prefix away — the declaration will silently stop applying and
 * the page will render at 200 looking subtly wrong. Custom properties are the
 * exception: `--mk-*` are declared once on :root / .mk-sidebar and the template's own
 * var() calls pick them up wherever they are declared.
 *
 * ── 🔴 EVERY var() CARRIES A LITERAL FALLBACK ───────────────────────────────
 * This network runs three competing token vocabularies and an UNDEFINED var() fails
 * SILENTLY — the whole declaration is dropped, no console error, element renders
 * unstyled. `index.css` is not loaded on this page, so --primary-pink etc. do NOT
 * exist here; they are re-declared below AND every use carries its literal.
 *
 * ── CONTRAST (computed, not eyeballed — WCAG 2.1 SC 1.4.3 / 1.4.11) ─────────
 *   #35155D on #f8f9fa ......................... 14.06:1   body text
 *   #35155D on #ffffff ......................... 14.82:1   text on cards
 *   #ffffff on #35155D ......................... 14.82:1   sidebar / topbar
 *   #35155D on #FF66B2 .......................... 5.50:1   primary button (worst
 *   #35155D on #FF8E2B .......................... 6.46:1   end of the gradient)
 *   #6B5B7E on #ffffff .......................... 6.14:1   muted / placeholder
 *   #6B5B7E on #f8f9fa .......................... 5.82:1   muted on page
 *   #6B5B7E on #F7F2FB .......................... 5.57:1   muted on surface-alt
 *   #A3175F on #ffffff .......................... 7.38:1   links
 *   #B3261E on #FFF1F0 .......................... 5.94:1   error text
 *   #166534 on #EDF9F1 .......................... 6.59:1   success text
 *   #6B5B7E on #E8E2EE .......................... 4.83:1   :disabled (exempt from
 *                                                          1.4.3 — met anyway)
 *   #ffffff on #492C6D .......................... 11.26:1  sidebar tab hover
 *   #CFC0E3 on #35155D .......................... 8.68:1   sidebar sub-text
 *   #35155D on #ffffff (focus ring) ............ 14.82:1   ≥3:1 for SC 1.4.11
 *   #FFCB2B on #35155D (focus ring on dark) ..... 9.76:1   ≥3:1 for SC 1.4.11
 *   #9A86B0 on #ffffff (input border) ........... 3.28:1   ≥3:1 for SC 1.4.11
 *
 * 🔴 --primary-pink #FF66B2 is a FILL ONLY. White on it is 2.69:1 and white on
 * --primary-orange #FF8E2B is 2.29:1 — both fail AA. index.css:127 and :493 do
 * exactly that (`color: white` on the pink→orange gradient) on the landing page.
 * That mistake is NOT copied here: the same gradient carries --dark-purple text,
 * which is 5.50:1 at its worst point and keeps the brand's look.
 * ───────────────────────────────────────────────────────────────────────────── */

:root {
    /* Brand tokens, copied from index.css:1-12. index.css is NOT loaded on this
       page, so these must be re-declared — a var() pointing at an undeclared name
       drops the entire declaration without a word. */
    --primary-pink: #FF66B2;
    --primary-yellow: #FFCB2B;
    --primary-blue: #40C4FF;
    --primary-orange: #FF8E2B;
    --dark-purple: #35155D;
    --soft-white: #f8f9fa;
    --shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.15);
    --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);

    /* Derived, page-local. Not in index.css — declared here, used here. */
    --iw-ink: #35155D;
    --iw-muted: #6B5B7E;          /* 6.14:1 on white, 5.82:1 on --soft-white */
    --iw-link: #A3175F;           /* 7.38:1 on white */
    --iw-card: #ffffff;
    --iw-line: #E7DEF0;           /* decorative hairline, never a control boundary */
    --iw-control-line: #9A86B0;   /* 3.28:1 on white — SC 1.4.11 for inputs */
    --iw-danger: #B3261E;
    --iw-danger-bg: #FFF1F0;
    --iw-warn-bg: #FFF6DC;
    --iw-disabled-bg: #E8E2EE;
    --iw-topbar-h: 68px;
    --iw-brand-gradient: linear-gradient(45deg, #FF66B2, #FF8E2B);

    /* ── The six --mk-* names the shared template actually consumes ──────────
       Verified by grepping dashboard.php for `var(--mk-`: radius (:148,186,194,
       204,220,259,304,335,490), accent (:577), success + success-bg (:590),
       surface-alt + text-muted (:591). Setting any OTHER --mk-* name would be
       invisible — the same class of bug as setting a $memberConfig key the
       template never reads. */
    --mk-radius: 14px;
    --mk-accent: #35155D;         /* focus ring on light surfaces — 14.82:1 */
    --mk-success: #166534;
    --mk-success-bg: #EDF9F1;
    --mk-surface-alt: #F7F2FB;
    --mk-text-muted: #6B5B7E;
}

/* ── Page shell ─────────────────────────────────────────────────────────────── */

html {
    box-sizing: border-box;
    -webkit-text-size-adjust: 100%;
}

*, *::before, *::after { box-sizing: inherit; }

body {
    margin: 0;
    font-family: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    font-size: 16px;
    line-height: 1.6;
    color: var(--iw-ink, #35155D);
    /* Echoes index.css:413 `.booking` — white falling into the faintest pink. */
    background-color: var(--soft-white, #f8f9fa);
    background-image: linear-gradient(170deg, #FDF1F8 0%, var(--soft-white, #f8f9fa) 46%);
    background-repeat: no-repeat;
    background-attachment: fixed;
    -webkit-font-smoothing: antialiased;
}

/* `body .mk-root` (0,1,1) beats the template's `.mk-root` (0,1,0). Without the
   topbar subtracted, 100vh + a 68px bar always overflows by exactly the bar. */
body .mk-root {
    min-height: calc(100vh - var(--iw-topbar-h, 68px));
}

/* ── Site top bar (includes/members-nav.php — rendered via $memberConfig['nav_include'],
      dashboard.php:630-632, OUTSIDE .mk-root) ───────────────────────────────── */

.iw-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.75rem 1.5rem;
    /* Same colour as the landing page's nav (index.css:71) and its footer, so the
       account pages open and close on the same colour as everything else. */
    background: var(--dark-purple, #35155D);
    padding: 0.75rem 5%;
    min-height: var(--iw-topbar-h, 68px);
}

.iw-topbar-logo img {
    display: block;
    height: 44px;
    width: auto;
    /* The logo art is dark-on-transparent; index.css:81-88 sits it on a white pill
       for exactly this reason. */
    background: #ffffff;
    border-radius: 999px;
    padding: 6px 16px;
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
    transition: var(--transition, all 0.3s ease);
}

.iw-topbar-logo img:hover { transform: scale(1.04); }

.iw-topbar-links {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1.5rem;
}

.iw-topbar-links a {
    position: relative;
    /* 14.82:1 on --dark-purple. Never --dark-purple here: that is 1:1. */
    color: #ffffff;
    text-decoration: none;
    font-weight: 600;
    font-size: 0.9rem;
    letter-spacing: 1px;
    text-transform: uppercase;
    padding: 0.25rem 0;
}

.iw-topbar-links a::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: -3px;
    height: 2px;
    width: 0;
    /* Fill only — pink is never text on a light surface here. */
    background: var(--primary-pink, #FF66B2);
    transition: var(--transition, all 0.3s ease);
}

.iw-topbar-links a:hover::after,
.iw-topbar-links a:focus-visible::after { width: 100%; }

.iw-topbar a:focus-visible {
    /* 9.76:1 against the bar — comfortably over the 3:1 SC 1.4.11 floor. */
    outline: 3px solid var(--primary-yellow, #FFCB2B);
    outline-offset: 3px;
    border-radius: 4px;
}

/* ── Where am I, and does this link take me out of it? ────────────────────────
 *
 * The same three classes brand.css defines for the public/hub/admin bars, restated
 * here because brand.css IS NOT LOADED ON /members — this sheet is the whole skin
 * for this page. A class "defined in the other file" renders as bare text at a clean
 * HTTP 200; this site has already shipped `.iw-pill` that way on three admin screens.
 *
 *   yellow  #FFCB2B  you are here, or this takes you further IN   9.76:1 on the bar
 *   blue    #40C4FF  this takes you OUT to the public site        7.45:1 on the bar
 *
 * 🔴 SPECIFICITY, twice over. `.iw-topbar-links a` is (0,1,1), so a bare
 * `.iw-nav-exit` (0,1,0) would lose. And this whole sheet is parsed BEFORE the kit
 * template's own <style> (see this file's header), so equal specificity loses there
 * too. Every rule below is a descendant of `.iw-topbar`, (0,2,0). Do not flatten it.
 */

.iw-surface-tag {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    /* 9.76:1 — a label is real text, so it takes the full 4.5:1, not the 3:1 floor. */
    color: var(--dark-purple, #35155D);
    background: var(--primary-yellow, #FFCB2B);
    padding: 0.2rem 0.5rem;
    border-radius: 999px;
    flex-shrink: 0;
    align-self: center;
}

.iw-topbar .iw-nav-console,
.iw-topbar .iw-nav-exit {
    border: 1px solid currentColor;
    border-radius: 999px;
    padding: 0.3rem 0.7rem;
    /* The plain topbar links are uppercase with 1px tracking; a pill at that tracking
       is noticeably wider than its text and crowds the 320px row. */
    letter-spacing: 0.02em;
    font-size: 0.8rem;
    line-height: 1.25;
    transition: var(--transition, all 0.3s ease);
}

/* 🔴 `.iw-topbar-links a::after` is ALREADY TAKEN: it is the absolutely-positioned
   2px underline that sweeps to 100% on hover. A pill has its own fill, so on a
   console pill it is switched off — and on an exit pill it is REPURPOSED into the ↗,
   which means every inherited property of the sweep has to be undone by hand. Setting
   only `content` leaves a zero-width, 2px-tall, absolutely-positioned glyph: invisible,
   at a clean 200. */
.iw-topbar .iw-nav-console::after { display: none; }

.iw-topbar .iw-nav-exit::after {
    content: '\00a0\2197';
    position: static;
    width: auto;
    height: auto;
    background: none;
    transition: none;
}

.iw-topbar .iw-nav-console { color: var(--primary-yellow, #FFCB2B); }
.iw-topbar .iw-nav-console:hover {
    background: var(--primary-yellow, #FFCB2B);
    color: var(--dark-purple, #35155D);            /* 9.76:1 */
    border-color: var(--primary-yellow, #FFCB2B);
}
.iw-topbar .iw-nav-console:active { transform: translateY(1px); }
.iw-topbar .iw-nav-console:focus-visible {
    outline: 3px solid var(--primary-yellow, #FFCB2B);
    outline-offset: 3px;
}

.iw-topbar .iw-nav-exit { color: var(--primary-blue, #40C4FF); }
.iw-topbar .iw-nav-exit:hover {
    background: var(--primary-blue, #40C4FF);
    color: var(--dark-purple, #35155D);            /* 7.45:1 */
    border-color: var(--primary-blue, #40C4FF);
}
.iw-topbar .iw-nav-exit:active { transform: translateY(1px); }
.iw-topbar .iw-nav-exit:focus-visible {
    outline: 3px solid var(--primary-yellow, #FFCB2B);
    outline-offset: 3px;
}

/* The ways out are a group, not a scattering. It wraps onto its own row at 320px
   rather than pushing the bar sideways. */
.iw-nav-exit-group {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 0.6rem;
}

@media (min-width: 48rem) {
    .iw-topbar .iw-nav-exit-group {
        border-left: 1px solid rgba(255, 255, 255, 0.28);
        padding-left: 1rem;
    }
}

/* ── Logged-out: the auth card ──────────────────────────────────────────────── */

.mk-root .mk-auth {
    padding: clamp(1.5rem, 5vw, 3.5rem) 1rem;
}

.mk-root .mk-auth-logo { margin-bottom: 1.75rem; }

.mk-root .mk-auth-logo img {
    max-height: 64px;
    background: #ffffff;
    border-radius: 999px;
    padding: 8px 22px;
    box-shadow: var(--shadow, 0 8px 32px 0 rgba(31, 38, 135, 0.15));
}

/* Segmented pill, mirroring the landing page's 999px button language
   (index.css:85, :129, :183). Visible below 640px; the template hides it above
   that and shows both panels side by side (dashboard.php:594-625). */
.mk-root .mk-auth-nav {
    border-radius: 999px;
    background: #ffffff;
    padding: 5px;
    gap: 4px;
    box-shadow: var(--shadow, 0 8px 32px 0 rgba(31, 38, 135, 0.15));
}

.mk-root .mk-auth-tab {
    border-radius: 999px;
    font-family: inherit;
    font-size: 0.9rem;
    font-weight: 700;
    color: var(--iw-muted, #6B5B7E);       /* 6.14:1 on white */
    background: transparent;
    transition: var(--transition, all 0.3s ease);
}

.mk-root .mk-auth-tab:hover {
    color: var(--iw-ink, #35155D);          /* 14.82:1 */
    background: var(--mk-surface-alt, #F7F2FB);
}

.mk-root .mk-auth-tab--active,
.mk-root .mk-auth-tab--active:hover {
    background: var(--iw-brand-gradient, linear-gradient(45deg, #FF66B2, #FF8E2B));
    color: var(--dark-purple, #35155D);     /* 5.50:1 at the pink end */
    box-shadow: 0 4px 15px rgba(255, 102, 178, 0.3);
}

/* Each form in the logged-out state is its own card. Above 640px the template turns
   .mk-auth-card into a two-column grid, so this yields two side-by-side cards
   (Sign In | Create Account) rather than one slab with an invisible seam. */
.mk-root .mk-auth .mk-form {
    background: var(--iw-card, #ffffff);
    border-radius: 30px;                    /* index.css:456 `.booking-form` */
    box-shadow: var(--shadow, 0 8px 32px 0 rgba(31, 38, 135, 0.15));
    padding: clamp(1.5rem, 4vw, 2.25rem);
    gap: 1.1rem;
}

/* Above 640px the tab nav is hidden by the template, so each column must name
   itself or the visitor cannot tell Sign In from Create Account. Real text, read
   by screen readers, hidden below 640px where the tabs already label the form. */
@media (min-width: 640px) {
    /* 🔴 The kit gives the two forms `grid-row: 1` explicitly (dashboard.php:614-622)
       but gives .mk-auth-logo only `grid-column: 1 / -1` (:610-612). Auto-placement
       then puts the logo in row TWO — it renders UNDERNEATH both cards, even though
       it is first in the DOM. Pin both rows here. */
    .mk-root .mk-auth-card .mk-auth-logo {
        grid-column: 1 / -1;
        grid-row: 1;
    }
    .mk-root .mk-auth-card .mk-form[data-member-action="login"],
    .mk-root .mk-auth-card .mk-form[data-member-action="forgot-password"] {
        grid-column: 1;
        grid-row: 2;
    }
    .mk-root .mk-auth-card .mk-form[data-member-action="register"] {
        grid-column: 2;
        grid-row: 2;
    }
    .mk-root .mk-auth-card .mk-divider,
    .mk-root .mk-auth-card .mk-social-btns {
        grid-column: 1 / -1;
        grid-row: 3;
    }

    .mk-root .mk-auth .mk-form[data-member-action]::before {
        display: block;
        font-size: 1.35rem;
        font-weight: 800;
        line-height: 1.2;
        color: var(--iw-ink, #35155D);      /* 14.82:1 on the white card */
        margin-bottom: 0.35rem;
    }
    .mk-root .mk-auth .mk-form[data-member-action="login"]::before {
        content: 'Sign In';
    }
    .mk-root .mk-auth .mk-form[data-member-action="register"]::before {
        content: 'Create Account';
    }
    .mk-root .mk-auth .mk-form[data-member-action="forgot-password"]::before {
        content: 'Reset Your Password';
    }
}

.mk-root .mk-auth .mk-form p {
    color: var(--iw-muted, #6B5B7E);        /* 5.57:1+ — the p carries an inline
                                               font-size only, not a colour */
}

/* ── Fields ─────────────────────────────────────────────────────────────────── */

.mk-root .mk-label {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-weight: 700;
    font-size: 0.875rem;
    color: var(--iw-ink, #35155D);          /* 14.82:1 */
}

/* The "Forgot?" control lives INSIDE the password <label> and relies on
   margin-left:auto from an inline style (dashboard.php:671) — which only does
   anything if the label is a flex container. It is, above. */

.mk-root .mk-input,
.mk-root .mk-textarea,
.mk-root .mk-select {
    font-family: inherit;
    font-size: 1rem;
    line-height: 1.4;
    color: var(--iw-ink, #35155D);
    background: #ffffff;
    /* 3.28:1 against the card — SC 1.4.11 wants ≥3:1 for a control boundary.
       A 1px #eee hairline (index.css:476) is 1.1:1 and does not qualify. */
    border: 2px solid var(--iw-control-line, #9A86B0);
    padding: 0.7rem 0.9rem;
    transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
}

.mk-root .mk-select {
    /* Native arrow, recoloured to the ink rather than replaced. */
    appearance: none;
    -webkit-appearance: none;
    background-image:
        url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath fill='none' stroke='%2335155D' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' d='M1 1l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.9rem center;
    padding-right: 2.4rem;
}

.mk-root .mk-input::placeholder,
.mk-root .mk-textarea::placeholder {
    /* 6.14:1. ::placeholder is NOT exempt from SC 1.4.3 — a pale grey placeholder
       is a real contrast failure, and this network has shipped one before. */
    color: var(--iw-muted, #6B5B7E);
    opacity: 1;
}

.mk-root .mk-input:hover,
.mk-root .mk-textarea:hover,
.mk-root .mk-select:hover { border-color: #7B6392; }

.mk-root .mk-input:focus,
.mk-root .mk-input:focus-visible,
.mk-root .mk-textarea:focus,
.mk-root .mk-select:focus {
    outline: 3px solid var(--mk-accent, #35155D);   /* 14.82:1 on white */
    outline-offset: 2px;
    border-color: var(--dark-purple, #35155D);
    box-shadow: 0 0 0 4px rgba(255, 102, 178, 0.22);
}

/* File input (avatar) — the template gives it class="mk-input". */
.mk-root .mk-input[type="file"] { padding: 0.55rem 0.7rem; }

.mk-root .mk-input[type="file"]::file-selector-button {
    font: inherit;
    font-weight: 700;
    border: none;
    border-radius: 999px;
    padding: 0.35rem 0.9rem;
    margin-right: 0.75rem;
    cursor: pointer;
    background: var(--mk-surface-alt, #F7F2FB);
    color: var(--iw-ink, #35155D);          /* 12.75:1 */
}

.mk-root .mk-input[readonly],
.mk-root .mk-input:disabled,
.mk-root .mk-textarea:disabled,
.mk-root .mk-select:disabled {
    background: var(--iw-disabled-bg, #E8E2EE);
    color: var(--iw-muted, #6B5B7E);        /* 4.83:1 — 1.4.3 exempts disabled
                                               controls; met regardless */
    cursor: not-allowed;
    border-color: #C7BAD6;
}

.mk-root .mk-field input[type="checkbox"] {
    width: 1.15rem;
    height: 1.15rem;
    /* Dark purple, not pink: a checked control is a UI component and needs ≥3:1.
       #FF66B2 on white is 2.29:1 and would fail; #35155D is 14.82:1. */
    accent-color: var(--dark-purple, #35155D);
    flex-shrink: 0;
}

.mk-root .mk-field input[type="checkbox"]:focus-visible {
    outline: 3px solid var(--mk-accent, #35155D);
    outline-offset: 2px;
}

/* ── Error state — colour AND a message ─────────────────────────────────────
   The template has no per-field error slot: failures arrive as a .mk-status-msg
   toast with role="alert" (dashboard.php:1200-1209). That is a message, but it is
   not attached to the field that is wrong. These rules add that, in text.

   :user-invalid, not :invalid — :invalid matches an untouched empty required field
   and would paint every form red before the visitor has typed anything.
   A browser without :has() or :user-invalid drops these rules and falls back to the
   toast, which is still a message. Colour is never the only carrier. */

.mk-root .mk-input:user-invalid,
.mk-root .mk-textarea:user-invalid,
.mk-root .mk-input[aria-invalid="true"],
.mk-root .mk-textarea[aria-invalid="true"] {
    border-color: var(--iw-danger, #B3261E);
    background: var(--iw-danger-bg, #FFF1F0);
}

.mk-root .mk-input:user-invalid:focus,
.mk-root .mk-input[aria-invalid="true"]:focus {
    box-shadow: 0 0 0 4px rgba(179, 38, 30, 0.18);
}

.mk-root .mk-field:has(> .mk-input:user-invalid)::after,
.mk-root .mk-field:has(> .mk-textarea:user-invalid)::after,
.mk-root .mk-field:has(> .mk-input[aria-invalid="true"])::after {
    content: 'Please check this field before continuing.';
    display: block;
    font-size: 0.8125rem;
    font-weight: 600;
    line-height: 1.4;
    color: var(--iw-danger, #B3261E);       /* 6.54:1 on white, 5.94:1 on the tint */
}

.mk-root .mk-field:has(> input[type="email"].mk-input:user-invalid)::after {
    content: 'Enter a valid email address — for example you@example.com.';
}

.mk-root .mk-field:has(> input[type="password"].mk-input:user-invalid)::after {
    /* Matches the minlength="8" the template puts on every password input. */
    content: 'Your password must be at least 8 characters.';
}

/* ── Buttons — four states, disabled included ──────────────────────────────── */

.mk-root .mk-btn {
    font-family: inherit;
    font-weight: 700;
    border-radius: 999px;                   /* index.css:129 `.btn-booking` */
    padding: 0.7rem 1.4rem;
    transition: var(--transition, all 0.3s ease);
    color: var(--iw-ink, #35155D);
    background: transparent;
}

.mk-root .mk-btn--primary {
    background: var(--iw-brand-gradient, linear-gradient(45deg, #FF66B2, #FF8E2B));
    /* 🔴 --dark-purple, NOT white. White on this gradient is 2.69:1 → 2.29:1 and
       fails AA; index.css:127 and :493 do that on the landing page. Dark purple is
       5.50:1 at the gradient's worst (pink) end. */
    color: var(--dark-purple, #35155D);
    box-shadow: 0 4px 15px rgba(255, 102, 178, 0.3);
    padding: 0.85rem 1.5rem;
    font-size: 1rem;
}

.mk-root .mk-btn--primary:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(255, 102, 178, 0.4);
}

.mk-root .mk-btn--primary:active {
    transform: translateY(0);
    box-shadow: 0 2px 8px rgba(255, 102, 178, 0.35) inset;
}

.mk-root .mk-btn--primary:disabled,
.mk-root .mk-btn--primary[aria-disabled="true"] {
    background: var(--iw-disabled-bg, #E8E2EE);
    color: var(--iw-muted, #6B5B7E);        /* 4.83:1 */
    box-shadow: none;
    transform: none;
    cursor: not-allowed;
}

.mk-root .mk-btn--ghost {
    color: var(--iw-ink, #35155D);          /* 14.82:1 on white */
    background: transparent;
}

.mk-root .mk-btn--ghost:hover {
    background: var(--mk-surface-alt, #F7F2FB);
    color: var(--iw-link, #A3175F);         /* 7.38:1 on white, 6.9:1 on #F7F2FB */
}

.mk-root .mk-btn--ghost:active { background: #EDE4F5; }

.mk-root .mk-btn--ghost:disabled,
.mk-root .mk-btn--ghost[aria-disabled="true"] {
    color: #8E829C;
    background: transparent;
    cursor: not-allowed;
}

/* `<a class="mk-btn">` (dashboard.php:973, :1041) — an anchor, not a <button>. */
.mk-root a.mk-btn {
    background: var(--mk-surface-alt, #F7F2FB);
    color: var(--iw-ink, #35155D);          /* 12.75:1 */
    border: 2px solid var(--iw-line, #E7DEF0);
}

.mk-root a.mk-btn:hover {
    border-color: var(--primary-pink, #FF66B2);
    color: var(--iw-link, #A3175F);
}

/* The template's own focus rule is `.mk-btn:focus-visible` (0,2,0) and it is parsed
   AFTER this file — so raising the ring to 3px needs 0,3,0. */
.mk-root .mk-btn:focus-visible,
.mk-root .mk-tab:focus-visible,
.mk-root .mk-auth-tab:focus-visible,
.mk-root .mk-social-btn:focus-visible {
    outline: 3px solid var(--mk-accent, #35155D);
    outline-offset: 2px;
}

/* ── Social sign-in (show_social is false on this site — styled so a future flip
      is not another unstyled surface) ─────────────────────────────────────── */

.mk-root .mk-divider {
    color: var(--iw-muted, #6B5B7E);        /* 5.82:1 on the page */
    font-weight: 600;
}

.mk-root .mk-divider::before,
.mk-root .mk-divider::after { background: var(--iw-line, #E7DEF0); }

.mk-root .mk-social-btns { margin-top: 0.25rem; }

.mk-root .mk-social-btn {
    background: #ffffff;
    color: var(--iw-ink, #35155D);          /* 14.82:1 */
    border: 2px solid var(--iw-control-line, #9A86B0);
    border-radius: 999px;
    font-family: inherit;
    font-weight: 700;
}

.mk-root .mk-social-btn:hover {
    border-color: var(--dark-purple, #35155D);
    background: var(--mk-surface-alt, #F7F2FB);
}

/* ── Logged-in: sidebar ─────────────────────────────────────────────────────── */

.mk-root .mk-dashboard {
    min-height: calc(100vh - var(--iw-topbar-h, 68px));
}

.mk-root .mk-sidebar {
    /* The template pins this to top:0/height:100vh; with a 68px bar above, that
       slides the sidebar under it and leaves a 68px overhang at the bottom. */
    top: var(--iw-topbar-h, 68px);
    height: calc(100vh - var(--iw-topbar-h, 68px));
    background: var(--dark-purple, #35155D);
    color: #ffffff;                          /* 14.82:1 */
    /* Declaring the accent HERE rescopes the template's own focus rule
       (dashboard.php:573-579, `outline: 2px solid var(--mk-accent)`), which would
       otherwise draw dark purple on dark purple — a 1:1 invisible focus ring. */
    --mk-accent: #FFCB2B;                    /* 9.76:1 against the sidebar */
}

.mk-root .mk-dashboard-header {
    border-bottom: 1px solid rgba(255, 255, 255, 0.14);
}

.mk-root .mk-dashboard-logo {
    background: #ffffff;
    padding: 3px;
}

.mk-root .mk-dashboard-site-name {
    color: #ffffff;                          /* 14.82:1 */
    font-size: 0.95rem;
    font-weight: 800;
}

.mk-root .mk-tab-nav { padding-top: 0.75rem; }

.mk-root .mk-tab {
    font-family: inherit;
    color: #ffffff;                          /* 14.82:1 */
    border-radius: 999px;
    padding: 0.6rem 0.95rem;
    transition: background-color 0.2s ease, color 0.2s ease;
}

.mk-root .mk-tab:hover {
    background: rgba(255, 255, 255, 0.10);   /* white on the blend #492C6D = 11.26:1 */
}

.mk-root .mk-tab:active { background: rgba(255, 255, 255, 0.16); }

.mk-root .mk-tab--active,
.mk-root .mk-tab--active:hover {
    background: var(--iw-brand-gradient, linear-gradient(45deg, #FF66B2, #FF8E2B));
    color: var(--dark-purple, #35155D);      /* 5.50:1 */
    font-weight: 700;
}

.mk-root .mk-tab-icon { opacity: 0.95; }

.mk-root .mk-user-footer {
    border-top: 1px solid rgba(255, 255, 255, 0.14);
}

.mk-root .mk-user-info { min-width: 0; }

.mk-root .mk-avatar {
    background: var(--iw-brand-gradient, linear-gradient(45deg, #FF66B2, #FF8E2B));
    color: var(--dark-purple, #35155D);      /* 5.50:1 on the initial */
}

.mk-root .mk-main .mk-avatar--lg {
    box-shadow: var(--shadow, 0 8px 32px 0 rgba(31, 38, 135, 0.15));
}

.mk-root .mk-display-name { color: #ffffff; }               /* 14.82:1 */

.mk-root .mk-user-email { color: #CFC0E3; }                 /* 8.68:1 */

.mk-root .mk-sidebar .mk-btn,
.mk-root .mk-sidebar .mk-btn--ghost {
    color: #ffffff;
    background: transparent;
    border: none;
    padding: 0.4rem;
}

.mk-root .mk-sidebar .mk-btn--ghost:hover {
    background: rgba(255, 255, 255, 0.14);
    color: var(--primary-yellow, #FFCB2B);   /* 9.76:1 */
}

/* ── Logged-in: main panel ──────────────────────────────────────────────────── */

.mk-root .mk-main { padding: clamp(1rem, 4vw, 2.5rem); }

.mk-root .mk-main-inner { max-width: 720px; }

.mk-root .mk-panel { color: var(--iw-ink, #35155D); }

.mk-root .mk-panel-title {
    font-size: clamp(1.4rem, 4vw, 1.9rem);
    font-weight: 800;
    color: var(--iw-ink, #35155D);           /* 14.06:1 on the page background */
}

.mk-root .mk-main .mk-section {
    background: var(--iw-card, #ffffff);
    border-radius: 24px;
    box-shadow: var(--shadow, 0 8px 32px 0 rgba(31, 38, 135, 0.15));
    padding: clamp(1.25rem, 3vw, 1.75rem);
}

.mk-root .mk-section-title {
    color: var(--iw-ink, #35155D);           /* 14.82:1 on the card */
    letter-spacing: 0.06em;
}

/* Underline the section titles in brand pink — a fill, never text. */
.mk-root .mk-section-title::after {
    content: '';
    display: block;
    width: 42px;
    height: 3px;
    margin-top: 0.5rem;
    border-radius: 999px;
    background: var(--iw-brand-gradient, linear-gradient(45deg, #FF66B2, #FF8E2B));
}

.mk-root .mk-main p { color: var(--iw-muted, #6B5B7E); }    /* 6.14:1 on the card */

.mk-root .mk-main small {
    display: block;
    margin-top: 0.35rem;
    font-size: 0.8125rem;
    color: var(--iw-muted, #6B5B7E);                        /* 6.14:1 */
}

.mk-root .mk-main a:not(.mk-btn) {
    color: var(--iw-link, #A3175F);                         /* 7.38:1 */
    text-decoration: underline;
    text-underline-offset: 2px;
}

.mk-root .mk-main a:not(.mk-btn):hover { color: var(--dark-purple, #35155D); }

/* ── Connections rows ───────────────────────────────────────────────────────── */

.mk-root .mk-connection-row + .mk-connection-row {
    border-top: 1px solid var(--iw-line, #E7DEF0);
}

.mk-root .mk-connection-icon {
    background: var(--mk-surface-alt, #F7F2FB);
    border-radius: 12px;
}

.mk-root .mk-connection-info { min-width: 0; }

.mk-root .mk-connection-label { color: var(--iw-ink, #35155D); }   /* 14.82:1 */

.mk-root .mk-connection-detail { color: var(--iw-muted, #6B5B7E); } /* 6.14:1 */

/* ── Badges (2FA state and anything else that reuses them) ──────────────────── */

.mk-root .mk-badge { font-family: inherit; }

/* .mk-badge--ok / .mk-badge--muted are the template's own rules and already read
   --mk-success, --mk-success-bg, --mk-surface-alt and --mk-text-muted, all
   declared at the top of this file. #166534 on #EDF9F1 = 6.59:1;
   #6B5B7E on #F7F2FB = 5.57:1. Restating them here would only risk drift. */

/* ── Status toasts ──────────────────────────────────────────────────────────── */

.mk-root .mk-status-area { max-width: min(360px, calc(100vw - 2rem)); }

.mk-root .mk-status-msg {
    font-family: inherit;
    background: #ffffff;
    color: var(--iw-ink, #35155D);                          /* 14.82:1 */
    border-left: 5px solid var(--dark-purple, #35155D);
    border-radius: 14px;
    box-shadow: 0 10px 30px rgba(31, 38, 135, 0.25);
}

.mk-root .mk-status-msg[data-type="success"] {
    background: var(--mk-success-bg, #EDF9F1);
    color: var(--mk-success, #166534);                      /* 6.59:1 */
    border-left-color: var(--mk-success, #166534);
}

.mk-root .mk-status-msg[data-type="error"] {
    background: var(--iw-danger-bg, #FFF1F0);
    color: var(--iw-danger, #B3261E);                       /* 5.94:1 */
    border-left-color: var(--iw-danger, #B3261E);
}

.mk-root .mk-status-msg[data-type="warning"] {
    background: var(--iw-warn-bg, #FFF6DC);
    color: var(--iw-ink, #35155D);                          /* 12.9:1 */
    border-left-color: var(--primary-orange, #FF8E2B);
}

.mk-root .mk-status-msg[data-type="info"] {
    background: var(--mk-surface-alt, #F7F2FB);
    color: var(--iw-ink, #35155D);                          /* 12.75:1 */
    border-left-color: var(--primary-blue, #40C4FF);
}

/* ── Spinner + screen-reader-only text ─────────────────────────────────────── */

.mk-root .mk-spinner {
    /* The template sets border-width/style but no colour, which renders a full
       ring rather than an arc. Transparent top makes it read as motion. */
    border-color: currentColor;
    border-top-color: transparent;
    opacity: 0.75;
}

.mk-root .mk-sr-only { color: inherit; }

/* ── Narrow screens: 320px is the floor ────────────────────────────────────── */

@media (max-width: 640px) {
    :root { --iw-topbar-h: 60px; }

    .iw-topbar {
        justify-content: center;
        padding: 0.6rem 1rem;
        gap: 0.5rem 1rem;
    }

    .iw-topbar-logo img { height: 36px; padding: 5px 12px; }

    .iw-topbar-links { gap: 1rem; justify-content: center; }

    .iw-topbar-links a { font-size: 0.8rem; letter-spacing: 0.5px; }

    /* Its own centred row. Squeezed onto the account nav's line it is the thing that
       pushes this bar past 320px, and the overflow hides behind the header rather
       than showing as a scrollbar. */
    .iw-topbar .iw-nav-exit-group {
        flex-basis: 100%;
        justify-content: center;
        gap: 0.4rem 0.5rem;
    }

    /* Sticky/height pinning is off below 640px (the template turns the sidebar into
       a horizontal bar), so undo the desktop offsets rather than leave dead calc. */
    .mk-root .mk-sidebar {
        top: auto;
        height: auto;
        border-bottom: 1px solid rgba(255, 255, 255, 0.14);
    }

    .mk-root .mk-tab { padding: 0.5rem 0.85rem; font-size: 0.85rem; }

    .mk-root .mk-auth-logo img { max-height: 52px; }

    .mk-root .mk-main .mk-section { border-radius: 20px; }

    .mk-root .mk-auth .mk-form { border-radius: 24px; }
}

@media (max-width: 360px) {
    /* At 320px the two-up password/confirm grid is already single-column
       (dashboard.php:569). What is left to protect is horizontal overflow. */
    .mk-root .mk-auth { padding-left: 0.75rem; padding-right: 0.75rem; }

    .mk-root .mk-auth .mk-form { padding: 1.1rem; }

    .mk-root .mk-auth-tab { padding: 0.55rem 0.5rem; font-size: 0.8rem; }

    .iw-topbar-links { gap: 0.75rem; }

    .iw-topbar-links a { font-size: 0.75rem; }

    .iw-topbar .iw-nav-console,
    .iw-topbar .iw-nav-exit { font-size: 0.72rem; padding: 0.28rem 0.55rem; }
}

/* ── Motion ─────────────────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
    .mk-root .mk-btn--primary:hover { transform: none; }
    .iw-topbar-logo img:hover { transform: none; }
}
