﻿/* =============================================================================================
   Form Kit  —  shared design system for edit/settings screens
   ---------------------------------------------------------------------------------------------
   ONE opt-in wrapper class (`.eform`) gives any edit screen the same polished look: brand-tinted
   focus rings, grouped fieldsets, readonly-field affordances, and consistent buttons.

   Branding is GLOBAL by construction: every accent here reads the app-wide brand tokens
   (--brand / --brand-dark / --brand-soft / --brand-contrast) that _UserLayout renders once from
   Partners.Application.Common.BrandPalette. A rebrand is therefore a ONE-PLACE edit — this kit,
   the membership page, the PDF receipts and the .btn-brand helper all follow it automatically.
   The NEUTRAL palette (ink/muted/line/bg) is intentionally local + semantic (not brand) and is kept
   identical to the membership page so screens feel like one product.

   Two ways to consume it:
   • NEW screens  → use the semantic classes (.eform-card / .eform-grid / .eform-fg / .eform-control …).
   • LEGACY screens → wrap the block in `.eform`; the retrofit layer at the bottom upgrades the existing
     `.edit_input_div` + `.form-control` markup in place, so no field IDs or JS need to change.
   ============================================================================================= */

.eform {
    /* Neutral tokens are semantic (not brand) and shared with the membership page for one visual language. */
    --ef-ink: #0f172a;
    --ef-label: #334155;
    --ef-subtle: #475569;
    --ef-muted: #64748b;
    --ef-line: #e6e8ee;
    --ef-bg: #f7f8fb;
    --ef-field-bg: #fff;
    --ef-readonly: #f1f3f7;
    --ef-radius: 12px;
    --ef-danger: #dc2626;
    --ef-ok: #16a34a;
    /* TEXT-ONLY SUCCESS COLOUR. --ef-ok is 3.30:1 on white, which is fine for a badge or a border
       but fails WCAG 2.2 AA's 4.5:1 for normal-size text — and on the sessions screen the success
       line is the ONLY confirmation that a device was signed out. #15803d is 4.9:1. The danger
       colour already passes at 4.83:1, so only the success path needed this. */
    --ef-ok-text: #15803d;
    --ef-ok-bg: #ecfdf5;
    /* Danger text/fill pair for banners and destructive confirms; #b42318 is 6.17:1 on white. */
    --ef-danger-text: #b42318;
    --ef-danger-bg: #fef2f2;
    --ef-danger-line: #fecaca;
    /* Warning (amber) is semantic and per-surface by design-system rule; #b45309 is 5.0:1 on #fffbeb. */
    --ef-warn-text: #b45309;
    --ef-warn-bg: #fffbeb;
    --ef-warn-line: #fde68a;

    /* Type scale — weight carries hierarchy (headline 800 → label 700 → body 400), size steps stay small. */
    --ef-text-xs: .74rem;
    --ef-text-sm: .8rem;
    --ef-text-label: .82rem;
    --ef-text-base: .92rem;
    --ef-text-md: 1rem;
    --ef-text-xl: 1.35rem;
    --ef-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

    /* 8pt spacing rhythm (4px half-step for intra-field gaps). */
    --ef-sp-1: 4px;
    --ef-sp-2: 8px;
    --ef-sp-3: 12px;
    --ef-sp-4: 16px;
    --ef-sp-5: 24px;
    --ef-sp-6: 32px;
    --ef-sp-7: 40px;

    /* Radius ladder: 9 small control → 11 control → 14–18 container → pill. Pick the rung, never invent. */
    --ef-r-sm: 9px;
    --ef-r-md: 11px;
    --ef-r-lg: 14px;
    --ef-r-xl: 18px;
    --ef-r-pill: 999px;

    /* Elevation: hairline border separates first; shadow is a faint reinforcement, assertive only on modals. */
    --ef-shadow-rest: 0 1px 3px rgba(16, 24, 40, .06), 0 16px 40px -28px rgba(16, 24, 40, .35);
    --ef-shadow-contact: 0 1px 3px rgba(16, 24, 40, .06);
    --ef-shadow-modal: 0 24px 60px -20px rgba(16, 24, 40, .5);
    color: var(--ef-ink);
}
.eform *, .eform *::before, .eform *::after { box-sizing: border-box; }

/* ---- Section header (title + actions) ---- */
.eform-head {
    display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap;
    padding-bottom: 16px; margin-bottom: 22px; border-bottom: 1px solid var(--ef-line);
}
.eform-head-text .eform-title { font-size: 1.35rem; font-weight: 800; letter-spacing: -.02em; color: var(--ef-ink); margin: 0; }
.eform-head-text .eform-sub { color: var(--ef-muted); font-size: .9rem; margin: 4px 0 0; line-height: 1.45; }

/* ---- Card / panel ---- */
.eform-card {
    background: #fff; border: 1px solid var(--ef-line); border-radius: 18px; padding: 24px;
}

/* ---- Grouped fieldset ---- */
.eform-section + .eform-section { margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--ef-line); }
.eform-legend {
    font-size: .74rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
    color: var(--ef-muted); margin: 0 0 16px;
}

/* ---- Responsive field grid ---- */
.eform-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px 18px; }
@media (max-width: 640px) { .eform-grid { grid-template-columns: 1fr; } }

/* ---- Field group ---- */
.eform-fg { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.eform-fg.full { grid-column: 1 / -1; }
.eform-label { font-size: .82rem; font-weight: 700; color: #334155; }
.eform-label .req { color: var(--ef-danger); margin-left: 2px; }
/* Muted helper line under/above a field (e.g. the "paste a link or a handle" note). */
.eform-field-hint { margin: 0; font-size: .78rem; color: var(--ef-muted); line-height: 1.45; }
/* Live "Saves as: …" preview under a link field — shows the canonicalised URL as the user types
   (mirrors the server's ProfileLinkNormalizer; the server stays authoritative). Only appears when
   normalisation would change the input, so clean input stays uncluttered. */
.eform-link-preview { margin-top: 5px; font-size: .74rem; line-height: 1.35; word-break: break-all; display: none; }
.eform-link-preview.is-ok, .eform-link-preview.is-warn { display: block; }
.eform-link-preview.is-ok { color: #067647; }
.eform-link-preview.is-ok b { font-weight: 700; }
.eform-link-preview.is-warn { color: #b42318; }

/* ---- Controls ---- */
.eform-control {
    width: 100%; border: 1.5px solid var(--ef-line); border-radius: 11px; padding: 11px 13px;
    font-size: .92rem; color: var(--ef-ink); background: var(--ef-field-bg); font-family: inherit;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.eform-control::placeholder { color: #9aa3b2; }
.eform-control:focus {
    outline: none; border-color: var(--brand, #d6006c);
    box-shadow: 0 0 0 3px var(--brand-soft, #fdeaf3);
}
textarea.eform-control { min-height: 88px; resize: vertical; }
/* Native <select> styled like a field: custom caret (inline SVG data-URI so it needs no asset),
   room on the right for it, and the platform arrow removed. */
select.eform-select {
    appearance: none; -webkit-appearance: none; -moz-appearance: none;
    padding-right: 38px; cursor: pointer;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5 6 6.5l5-5' stroke='%2364748b' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 14px center;
}

/* Readonly / locked field: reads as deliberately not-editable, never as broken. */
.eform-control[readonly], .eform-control:disabled, .eform-readonly {
    background: #f1f3f7; color: #475569; border-color: var(--ef-line); cursor: default; box-shadow: none;
}
.eform-control[readonly]:focus { border-color: var(--ef-line); box-shadow: none; }

/* ---- Help / errors / notes ---- */
.eform-help { font-size: .78rem; color: var(--ef-muted); line-height: 1.4; }
.eform-error { font-size: .78rem; color: var(--ef-danger); font-weight: 600; }
.eform-note {
    display: flex; gap: 9px; align-items: flex-start; padding: 12px; background: var(--ef-bg);
    border-radius: 11px; color: var(--ef-muted); font-size: .8rem; line-height: 1.45;
}

/* ---- Inline control + action (e.g. reference code + Update, phone + Change) ---- */
.eform-inline { display: flex; gap: 8px; align-items: stretch; }
.eform-inline .eform-control { flex: 1 1 auto; }

/* ---- Buttons ---- */
.eform-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 7px; cursor: pointer;
    border: 1.5px solid transparent; border-radius: 11px; padding: 10px 16px; font-family: inherit;
    font-weight: 700; font-size: .9rem; line-height: 1; white-space: nowrap; text-decoration: none;
    transition: background .15s ease, color .15s ease, border-color .15s ease, filter .15s ease, opacity .15s ease;
}
.eform-btn:focus-visible { outline: 2px solid var(--brand, #d6006c); outline-offset: 2px; }
.eform-btn--brand { background: var(--brand, #d6006c); color: var(--brand-contrast, #fff); }
.eform-btn--brand:hover { filter: brightness(1.07); }
.eform-btn--ghost { background: #fff; color: var(--brand, #d6006c); border-color: var(--brand, #d6006c); }
.eform-btn--ghost:hover { background: var(--brand, #d6006c); color: var(--brand-contrast, #fff); }
.eform-btn--link { background: transparent; color: var(--brand, #d6006c); padding: 6px 4px; border: 0; }
.eform-btn--link:hover { color: var(--brand-dark, #ad0058); text-decoration: underline; }
.eform-btn--sm { padding: 8px 12px; font-size: .82rem; border-radius: 9px; }
.eform-btn[disabled] { background: #e5e7eb; color: #9ca3af; border-color: #e5e7eb; cursor: not-allowed; filter: none; }

/* ---- Status chip (Verified / etc.) ---- */
.eform-badge {
    display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px; border-radius: 999px;
    font-size: .74rem; font-weight: 800;
}
.eform-badge.is-ok { background: #ecfdf5; color: #15803d; }
.eform-badge.is-muted { background: #f1f5f9; color: #64748b; }

/* =============================================================================================
   Legacy retrofit — upgrades the existing profile-edit markup in place.
   Scoped to `.edit_input_div` so ONLY the personal-info fields are restyled; the professional-profile
   accordion / CV pickers inside the same form are left as-is (a separate module). No IDs, no structure,
   no JS touched — just appearance.
   ============================================================================================= */

/* Section header ("Update Profile" + Save) */
.eform .edit_update_user {
    align-items: center; border-bottom: 1px solid var(--ef-line); padding: 0 0 16px; margin-bottom: 22px;
}
.eform .edit_update_user h3 {
    font-size: 1.35rem !important; font-weight: 800; letter-spacing: -.02em; color: var(--ef-ink); margin: 0;
}
.eform .edit_update_user .eform-head-sub { color: var(--ef-muted); font-size: .88rem; margin: 4px 0 0; line-height: 1.4; }
.eform .edit_update_user .btn {
    background: var(--brand, #d6006c); border: 1.5px solid var(--brand, #d6006c); color: var(--brand-contrast, #fff);
    font-weight: 700; border-radius: 11px; padding: 9px 18px; font-size: .9rem; box-shadow: none;
}
.eform .edit_update_user .btn:hover { filter: brightness(1.07); }
.eform .edit_update_user .btn i { color: var(--brand-contrast, #fff) !important; }

/* Field group */
.eform .edit_input_div { display: flex; flex-direction: column; gap: 6px; padding: 8px 0; }
.eform .edit_input_div > label,
.eform .edit_input_div #email_verification > label {
    font-size: .82rem; font-weight: 700; color: #334155; margin: 0;
}
.eform .edit_input_div > label span[style*="red"] { color: var(--ef-danger) !important; }

/* Inputs / textareas / selects (incl. those nested in the phone/email wrappers) */
.eform .edit_input_div .form-control,
.eform .edit_input_div textarea.form-control {
    width: 100%; border: 1.5px solid var(--ef-line) !important; border-radius: 11px; padding: 11px 13px;
    font-size: .92rem; color: var(--ef-ink); background: #fff !important; box-shadow: none;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.eform .edit_input_div .form-control::placeholder { color: #9aa3b2; }
.eform .edit_input_div .form-control:focus {
    outline: none; border-color: var(--brand, #d6006c) !important;
    box-shadow: 0 0 0 3px var(--brand-soft, #fdeaf3);
}
.eform .edit_input_div textarea.form-control { min-height: 88px; resize: vertical; }
.eform .edit_input_div .form-control[readonly] {
    background: #f1f3f7 !important; color: #475569; border-color: var(--ef-line) !important;
    cursor: default; box-shadow: none;
}

/* select2 single-select to match the inputs */
.eform .select2-container { width: 100% !important; }
.eform .select2-container--default .select2-selection--single {
    height: auto; min-height: 44px; border: 1.5px solid var(--ef-line); border-radius: 11px; padding: 6px 8px;
    display: flex; align-items: center;
}
.eform .select2-container--default.select2-container--focus .select2-selection--single {
    border-color: var(--brand, #d6006c); box-shadow: 0 0 0 3px var(--brand-soft, #fdeaf3);
}
.eform .select2-selection__rendered { padding: 0 6px; color: var(--ef-ink); }
.eform .select2-selection__arrow { top: 50%; transform: translateY(-50%); }

/* Buttons that live inside a field (Verify Email / Change phone / Reference Update) → compact ghost/link */
.eform .edit_input_div .btn-primary {
    background: var(--brand, #d6006c); border: 1.5px solid var(--brand, #d6006c); color: var(--brand-contrast, #fff);
    font-weight: 700; border-radius: 9px; padding: 8px 14px; font-size: .82rem; box-shadow: none; margin-top: 4px;
}
.eform .edit_input_div .btn-primary:hover { filter: brightness(1.07); }
.eform .edit_input_div .btn-primary i { color: var(--brand-contrast, #fff) !important; }
.eform .edit_input_div .btn-link {
    color: var(--brand, #d6006c); font-weight: 700; text-decoration: none; font-size: .82rem; margin-top: 6px;
}
.eform .edit_input_div .btn-link:hover { color: var(--brand-dark, #ad0058); text-decoration: underline; }

/* Phone/WhatsApp +88 flag row */
.eform .edit_input_div .phn_code_part_admin p {
    display: flex; align-items: center; gap: 6px; margin: 6px 0 0; color: var(--ef-muted); font-size: .82rem; font-weight: 600;
}
.eform .edit_input_div .phn_code_part_admin img { height: 14px; border-radius: 2px; }

/* Email verified/verify row. The legacy `#email_verification .email_child` is position:absolute (an ID
   selector that out-specifies a plain class), so we must match its ID specificity to pull it back into
   normal flow BELOW the input — otherwise the Verified chip + button overlap the email field. */
.eform #email_verification { position: static; }
.eform #email_verification .email_child {
    position: static; margin-top: 8px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    justify-content: flex-start;
}
.eform #email_verification .email_child p {
    display: inline-flex; align-items: center; gap: 5px; margin: 0; padding: 3px 10px; border-radius: 999px;
    background: #ecfdf5; color: #15803d; font-size: .74rem; font-weight: 800;
}

/* Reference-partner hint + profile-url helper text */
.eform .edit_input_div small.text-muted, .eform .edit_input_div #referencePartnerHint { color: var(--ef-muted) !important; font-size: .78rem; }
.eform .edit_input_div p[style*="red"] { color: var(--ef-danger) !important; font-size: .76rem; line-height: 1.4; margin-top: 4px; }
.eform .edit_input_div #copyText { color: var(--ef-muted); font-size: .82rem; word-break: break-all; }
.eform .edit_input_div #copyText + button, .eform .edit_input_div #copyText ~ button {
    background: transparent; border: 0; color: var(--brand, #d6006c); cursor: pointer; padding: 2px 5px;
}

/* =============================================================================================
   Profile-edit page — enterprise card layout over the legacy markup (CSS-first, no field changes).
   Turns the flat, pink, full-bleed form into a contained white "settings card" with grouped
   sections, a fused phone input-group, and a single bottom action bar.
   ============================================================================================= */

/* Neutralise the legacy pink container (.get_Executive_Partner_Container background) → clean canvas. */
.eform-canvas { background: transparent !important; padding: 4px 12px 48px; }

/* The whole edit block becomes one contained white card. */
.eform-sheet {
    margin: 0 auto; max-width: 1040px; background: #fff; border: 1px solid var(--ef-line);
    border-radius: 18px; box-shadow: 0 1px 3px rgba(16,24,40,.06), 0 16px 40px -28px rgba(16,24,40,.35);
    padding: 8px 28px 26px;
}
@media (max-width: 640px) { .eform-sheet { padding: 6px 16px 18px; border-radius: 14px; } }

/* Section header rows (inserted as .col-12.eform-sec-head between field groups) */
.eform .eform-sec-head {
    font-size: .74rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
    color: var(--ef-muted); margin: 22px 0 6px; padding-top: 20px; border-top: 1px solid var(--ef-line);
}
.eform .eform-sec-head.is-first { border-top: 0; padding-top: 4px; margin-top: 4px; }

/* Phone input-group: fuse the legacy ABSOLUTE +88 prefix (order:-1 pulls the DOM-second flag to the
   left) into a seamless input-group so the two boxes stop reading as detached/broken. */
.eform #phn_code_admin { display: flex; align-items: stretch; position: static; }
.eform #phn_code_admin::after { display: none; }
.eform #phn_code_admin .phn_code_part_admin {
    position: static; order: -1; display: flex; align-items: center; padding: 0 12px; margin: 0;
    background: #f8fafc; border: 1.5px solid var(--ef-line); border-right: 0; border-radius: 11px 0 0 11px;
}
.eform #phn_code_admin .phn_code_part_admin p { margin: 0; display: flex; align-items: center; gap: 6px; font-size: .84rem; font-weight: 700; color: var(--ef-muted); }
.eform #phn_code_admin .phn_code_part_admin p span img { width: 16px !important; height: 16px !important; border-radius: 2px; }
.eform #phn_code_admin input.form-control { padding-left: 13px !important; border-radius: 0 11px 11px 0 !important; flex: 1 1 auto; }

/* Bottom action bar (the single kept Save + Back) — sits on the canvas below the card, sheet-aligned. */
.eform-actions-row { margin: 14px auto 0; max-width: 1040px; }
.eform-actions {
    display: flex; justify-content: flex-end; gap: 10px; background: #fff; border: 1px solid var(--ef-line);
    border-radius: 16px; box-shadow: 0 1px 3px rgba(16,24,40,.06); padding: 15px 22px;
}
.eform-actions .btn { border: 1.5px solid transparent; border-radius: 11px; font-weight: 700; padding: 11px 26px; font-size: .92rem; box-shadow: none; }
.eform-actions .btn i { margin-right: 6px; }
.eform-actions .btn-save { background: var(--brand, #d6006c); border-color: var(--brand, #d6006c); color: var(--brand-contrast, #fff); }
.eform-actions .btn-save:hover { filter: brightness(1.07); }
.eform-actions .btn-save i { color: var(--brand-contrast, #fff) !important; }
.eform-actions .btn-back { background: #fff; border-color: var(--ef-line); color: #475569; }
.eform-actions .btn-back:hover { background: #f1f3f7; }
.eform-actions .btn-back i { color: #475569 !important; }
@media (max-width: 560px) { .eform-actions { flex-direction: column-reverse; } .eform-actions .btn { width: 100%; } }

/* =============================================================================================
   Two-panel settings layout (Stripe / GitHub / Linear pattern): each section shows its title +
   short description in a left rail, with the fields in a comfortable right column. This is the
   single biggest lift from "generic admin form" to a world-class settings screen — it gives
   hierarchy, context, and a readable field width instead of stretched full-bleed inputs.
   ============================================================================================= */
.eform .eform-group {
    display: grid; grid-template-columns: 248px minmax(0, 1fr); gap: 40px; padding: 30px 4px; margin: 0;
}
.eform .eform-group + .eform-group { border-top: 1px solid var(--ef-line); }
.eform-group-aside h4 { font-size: 1rem; font-weight: 800; letter-spacing: -.01em; color: var(--ef-ink); margin: 0 0 5px; }
.eform-group-aside p { font-size: .85rem; line-height: 1.5; color: var(--ef-muted); margin: 0; }
.eform-group-aside .opt { color: var(--ef-muted); font-weight: 600; }
.eform-group-fields { min-width: 0; }

/* Right-column field grid */
.eform-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 18px 20px; }
.eform-grid2 .eform-fg.full { grid-column: 1 / -1; }

/* Label optional marker */
.eform-label .opt { color: var(--ef-muted); font-weight: 600; margin-left: 4px; }

/* Inline actions under a field (verify email / verified chip + change) */
.eform-actions-inline { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 2px; }
.eform-actions-inline .eform-badge i { font-size: .82rem; }

/* Stack the two panels on narrow screens */
@media (max-width: 900px) {
    .eform .eform-group { grid-template-columns: 1fr; gap: 14px; padding: 24px 0; }
    .eform-grid2 { grid-template-columns: 1fr; }
}

/* Phone input-group (semantic markup): a country-code prefix fused to the input as one control.
   The flag PNG is large natively, so it MUST be size-constrained or it blows the layout up. */
.eform-phone { display: flex; align-items: stretch; }
.eform-phone-cc {
    display: flex; align-items: center; gap: 6px; padding: 0 12px; white-space: nowrap;
    border: 1.5px solid var(--ef-line); border-right: 0; border-radius: 11px 0 0 11px;
    background: #f8fafc; color: var(--ef-muted); font-weight: 700; font-size: .84rem;
}
.eform-phone-cc img { width: 20px; height: 13px; object-fit: cover; border-radius: 2px; display: block; flex: 0 0 auto; }
.eform-phone .eform-control { border-radius: 0 11px 11px 0; flex: 1 1 auto; min-width: 0; }
.eform-phone .eform-control:focus { position: relative; z-index: 1; }

/* =============================================================================================
   Round-3 polish: section icons, select2 arrow, action-bar alignment, modal, photos, accordion.
   ============================================================================================= */

/* Section aside icon (brand-tinted chip above each section title) */
.eform-group-icon {
    width: 38px; height: 38px; border-radius: 10px; background: var(--brand-soft, #fdeaf3);
    color: var(--brand, #d6006c); display: inline-flex; align-items: center; justify-content: center; margin-bottom: 12px;
}
.eform-group-icon svg { width: 20px; height: 20px; }

/* select2 single-select — arrow vertically centred + text aligned (beats select2's own 3-class rule) */
.eform .select2-container--default .select2-selection--single { height: auto; min-height: 44px; border: 1.5px solid var(--ef-line); border-radius: 11px; padding: 6px 10px; display: flex; align-items: center; }
.eform .select2-container--default.select2-container--focus .select2-selection--single { border-color: var(--brand, #d6006c); box-shadow: 0 0 0 3px var(--brand-soft, #fdeaf3); }
.eform .select2-container--default .select2-selection--single .select2-selection__rendered { line-height: 1.5; color: var(--ef-ink); padding-left: 3px; padding-right: 26px; }
.eform .select2-container--default .select2-selection--single .select2-selection__arrow { top: 50%; right: 10px; height: 22px; transform: translateY(-50%); }

/* Profile-URL preview: inline SVG icon buttons (Font Awesome fa-copy/link render as tofu boxes here) */
.eform-url-preview button { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; }
.eform-url-preview button svg { width: 15px; height: 15px; display: block; }

/* Bottom action bar — align its card edges exactly with the sheet card (1040), not the col-gutter inset */
.eform-actions-row { margin: 16px auto 0; max-width: 1040px; padding: 0; }
.eform-actions-row > [class*="col-"] { padding: 0; }

/* Edit/verify/phone modals → enterprise styling.
   IMPORTANT: these modals live at the TOP of the page, OUTSIDE the `.eform` wrapper, so the `--ef-*`
   design tokens declared on `.eform` don't reach them (an undefined var() makes the whole declaration
   invalid → borders/labels silently drop). We re-declare the tokens on `.eform-modal` so every rule
   below resolves; fallbacks are kept too for defence-in-depth. */
.eform-modal {
    --ef-ink: #0f172a; --ef-muted: #64748b; --ef-line: #e6e8ee;
    --brand: var(--brand, #d6006c); --brand-soft: var(--brand-soft, #fdeaf3);
}
/* Modal open/close must NOT yank the page to the top (the "background scrolls up" report).
   WHY: the legacy shell scrolls the document through `body{display:flex;flex-direction:column;height:100vh}`,
   so the scrollbar lives on <html>, not <body>. When any Bootstrap modal opens it sets an inline
   `overflow:hidden` (+ scrollbar-compensating padding) on <body> to lock background scroll; against a
   FIXED-height flex body that CLIPS the overflowing children — <html> scrollHeight collapses from full-page
   to one viewport (measured 3011px → 760px), which forces the current scroll offset to 0 → the page jumps
   to the top on open, and jumps again when the lock is removed on close.
   FIX: the modal and its full-viewport backdrop are already position:fixed, so <body> never needs the lock.
   Keep body overflow visible (an `!important` stylesheet rule beats Bootstrap's non-important inline style)
   so the document never reflows and the background stays exactly where the user left it. Verified: with this
   rule <html> scrollHeight holds at full-page across open→close→reopen. */
body.modal-open { overflow: visible !important; padding-right: 0 !important; }
.eform-modal .modal-content { border: 0; border-radius: 16px; box-shadow: 0 24px 60px -20px rgba(16, 24, 40, .5); overflow: hidden; }
.eform-modal .modal-header { border-bottom: 1px solid var(--ef-line, #e6e8ee); padding: 16px 20px; align-items: center; }
/* Override legacy inline title styles (some modal titles carry an inline color:#fff / 13px that would vanish on the white header). */
.eform-modal .modal-title { color: var(--ef-ink, #0f172a) !important; font-weight: 800 !important; font-size: 1.05rem !important; }
.eform-modal .modal-header .close { background: transparent; border: 0; font-size: 1.5rem; line-height: 1; color: var(--ef-muted, #64748b); cursor: pointer; opacity: 1; }
.eform-modal .modal-body { padding: 20px 22px 22px; }
.eform-modal .modal-body .form-horizontal { margin: 0; }
/* Field labels — the CV modals nest the text in <label class="input-label"><small>…<label>*</label></small></label>.
   Only the OUTER .input-label is block; the nested red "*" <label> MUST stay inline (a blanket
   `label{display:block}` dropped the asterisk onto its own line → the modal sprawled, same bug as inline). */
.eform-modal .modal-body label { font-size: .8rem; font-weight: 700; color: #334155; margin-bottom: 6px; }
.eform-modal .modal-body .input-label { display: block; margin-bottom: 6px; line-height: 1.2; }
.eform-modal .modal-body .input-label small { font-size: .8rem; font-weight: 700; }
.eform-modal .modal-body .input-label label { display: inline; margin: 0; padding: 0; }
.eform-modal .modal-body br { display: none; }
.eform-modal .modal-body .form-group { margin-bottom: 14px; }
.eform-modal .modal-body .form-control,
.eform-modal .modal-body .form-select {
    border: 1.5px solid var(--ef-line, #e6e8ee) !important; border-radius: 11px !important; padding: 11px 13px !important;
    font-size: .9rem; min-height: 44px; background: #fff; color: var(--ef-ink, #0f172a); box-shadow: none;
}
.eform-modal .modal-body .form-control:focus,
.eform-modal .modal-body .form-select:focus { border-color: var(--brand, #d6006c) !important; box-shadow: 0 0 0 3px var(--brand-soft, #fdeaf3) !important; outline: none; }
.eform-modal .modal-body .form-control[readonly] { background: #f1f5f9; color: #475569; cursor: not-allowed; }
/* Button row (Submit + Close) — full width, brand primary + neutral ghost */
.eform-modal .modal-body > .col-md-8,
.eform-modal .modal-body > .row .col-md-8 { width: 100%; max-width: 100%; flex: 0 0 100%; display: flex; gap: 10px; padding: 4px 0 0 !important; }
.eform-modal .modal-body .btn-primary { background: var(--brand, #d6006c) !important; border: 1.5px solid var(--brand, #d6006c) !important; color: #fff !important; border-radius: 11px; font-weight: 700; padding: 10px 20px; box-shadow: none; }
.eform-modal .modal-body .btn-primary:hover { filter: brightness(1.07); }
.eform-modal .modal-body .btn-danger { border-radius: 11px; font-weight: 700; padding: 10px 20px; }
.eform-modal .modal-body .btn-default { background: #fff !important; color: #475569 !important; border: 1.5px solid var(--ef-line, #e6e8ee) !important; border-radius: 11px; font-weight: 700; padding: 10px 20px; }
.eform-modal .modal-body .btn-default:hover { background: #f1f5f9 !important; color: var(--ef-ink, #0f172a) !important; }
.eform-modal-hint { font-size: .78rem; color: var(--ef-muted, #64748b); margin: 8px 0 0; line-height: 1.45; }

/* Inline CV "Add / edit" form panel — same enterprise input look as the rest of the page
   (the panel reuses legacy .form-control/.form-group/.input-label, not the .eform-control class). */
.eform .eform-cv-form > div { padding-top: 0 !important; } /* neutralise legacy .academic_info>div 20px top pad */
.eform-cv-form .form-group { margin-bottom: 14px; }
.eform-cv-form br { display: none; } /* stray legacy <br> after the select labels — was adding an empty line */
/* Label: only the OUTER .input-label is block; the nested red "*" <label> must stay INLINE
   (a plain `label{display:block}` here dropped the asterisk onto its own line → the whole form sprawled). */
.eform-cv-form .input-label { display: block; margin: 0 0 6px; font-size: .8rem; font-weight: 700; color: #334155; line-height: 1.2; }
.eform-cv-form .input-label b { font-weight: 700; }
.eform-cv-form .input-label label { display: inline; margin: 0; padding: 0; font-weight: 700; }
.eform-cv-form .form-control, .eform-cv-form .form-select {
    border: 1.5px solid var(--ef-line, #e6e8ee); border-radius: 11px; padding: 10px 13px;
    font-size: .9rem; min-height: 44px; background: #fff; color: var(--ef-ink, #0f172a); box-shadow: none;
}
.eform-cv-form .form-control:focus, .eform-cv-form .form-select:focus { border-color: var(--brand, #d6006c); box-shadow: 0 0 0 3px var(--brand-soft, #fdeaf3); outline: none; }
/* Kendo datepicker widget → adopt the same bordered-input look, in BOTH the inline form and the modals.
   Kendo wraps the input in its own segmented .k-picker-wrap + .k-select button that clashes with the
   design, and — critically — COPIES the original input's `form-control` class onto this OUTER wrapper
   span. That inherited `form-control` gives the wrapper 11px/13px padding + 44px min-height +
   content-box sizing, so the real bordered date-pill (.k-picker-wrap) sits INSET inside a 66px-tall
   invisible padded box — pushed inward/down vs the 44px sibling fields (the "detached box" + "Year of
   Passing not aligned" reports). Neutralise the inherited box model (padding/min-height/box-sizing) so
   the wrapper collapses flush onto the picker-wrap and lines up pixel-for-pixel with the plain fields. */
.eform-cv-form .k-datepicker, .eform-cv-form span.k-datepicker, .eform-cv-form .k-widget.k-datepicker,
.eform-modal .modal-body .k-datepicker, .eform-modal .modal-body span.k-datepicker, .eform-modal .modal-body .k-widget.k-datepicker {
    display: block !important; width: 100% !important; margin: 0 !important; padding: 0 !important; min-height: 0 !important; box-sizing: border-box !important; border: 0 !important; background: transparent !important; box-shadow: none !important; vertical-align: top !important;
}
.eform-cv-form .k-picker-wrap, .eform-modal .modal-body .k-picker-wrap {
    border: 1.5px solid var(--ef-line, #e6e8ee) !important; border-radius: 11px !important; background: #fff !important;
    padding: 0 !important; height: 44px; box-sizing: border-box; display: flex; align-items: stretch; overflow: hidden; margin: 0 !important;
}
.eform-cv-form .k-picker-wrap .k-input, .eform-modal .modal-body .k-picker-wrap .k-input {
    border: 0 !important; box-shadow: none !important; padding: 0 13px !important; height: 100% !important; background: transparent !important; font-size: .9rem; color: var(--ef-ink, #0f172a);
}
.eform-cv-form .k-picker-wrap .k-select, .eform-modal .modal-body .k-picker-wrap .k-select {
    border: 0 !important; border-left: 1px solid var(--ef-line, #e6e8ee) !important; background: #f8fafc !important; color: var(--ef-muted, #64748b) !important; width: 42px; min-width: 42px; display: flex; align-items: center; justify-content: center;
}
.eform-cv-form .k-datepicker.k-state-focused .k-picker-wrap, .eform-cv-form .k-picker-wrap.k-state-focused,
.eform-modal .modal-body .k-datepicker.k-state-focused .k-picker-wrap, .eform-modal .modal-body .k-picker-wrap.k-state-focused { border-color: var(--brand, #d6006c) !important; box-shadow: 0 0 0 3px var(--brand-soft, #fdeaf3) !important; }

/* ---- Photos group (avatar + cover uploaders) ---- */
.eform-photos { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 620px) { .eform-photos { grid-template-columns: 1fr; } }
.eform-photo-card { border: 1px solid var(--ef-line); border-radius: 14px; padding: 16px; background: #fff; display: flex; flex-direction: column; }
.eform-photo-card .form_img_close_part { position: relative; height: 160px !important; border-radius: 10px; overflow: hidden; background: #f1f3f7; display: flex; align-items: center; justify-content: center; margin: 0 !important; }
.eform-photo-card .form_img_close_part img { max-width: 100%; max-height: 100%; height: auto !important; width: auto !important; object-fit: cover; }
.eform-photo-card .form_img_close_part [id$="Icon"] { position: absolute; top: 8px; right: 8px; z-index: 2; width: 26px; height: 26px; border: 0; padding: 0; border-radius: 50%; background: rgba(15,23,42,.6); color: #fff; display: inline-flex; align-items: center; justify-content: center; font-size: .85rem; cursor: pointer; }
.eform-photo-card .form_img_close_part [id$="Icon"]:hover { background: rgba(15,23,42,.8); }
.eform-photo-card .form_img_close_part [id$="Icon"]:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(255,255,255,.9), 0 0 0 5px var(--brand, #d6006c); }
.eform-photo-card p { padding: 12px 0 0 !important; margin: 0; font-weight: 700; font-size: .88rem; color: var(--ef-ink); line-height: 1.35; }
.eform-photo-card p small { display: block; font-weight: 400; color: var(--ef-muted); font-size: .76rem; margin-top: 4px; }
.eform .reg_add_image_div {
    margin-top: 12px; background: #fff; border: 1.5px solid var(--brand, #d6006c); color: var(--brand, #d6006c);
    border-radius: 11px; padding: 10px 14px; font-weight: 700; font-size: .86rem; text-align: center; cursor: pointer;
    transition: background .15s ease, color .15s ease;
}
.eform .reg_add_image_div:hover { background: var(--brand, #d6006c); color: #fff; }

/* ---- Photo uploader: larger preview, drag-drop zone, progress, inline status ---- */
.eform-photo-card .form_img_close_part { height: 190px !important; }
/* Avatar renders round (output is still a square file; the round preview matches how avatars display). */
.eform-photo-card--avatar .form_img_close_part img { width: 150px !important; height: 150px !important; border-radius: 50%; object-fit: cover; }

/* Drag-and-drop zone — also click / keyboard (Enter/Space) activatable; role="button". */
.eform-dropzone {
    margin-top: 12px; border: 1.6px dashed var(--ef-line); border-radius: 12px;
    background: #fbfcfe; padding: 14px; text-align: center; cursor: pointer;
    display: flex; flex-direction: column; align-items: center; gap: 5px;
    transition: border-color .15s ease, background .15s ease, box-shadow .15s ease;
}
.eform-dropzone:hover { border-color: var(--brand, #d6006c); background: var(--brand-soft, #fdeaf3); }
.eform-dropzone:focus-visible { outline: none; border-color: var(--brand, #d6006c); box-shadow: 0 0 0 3px rgba(214,0,108,.18); }
/* Highlight while a file is dragged over the zone. */
.eform-dropzone.is-dragover { border-style: solid; border-color: var(--brand, #d6006c); background: var(--brand-soft, #fdeaf3); }
.eform-dropzone svg { width: 22px; height: 22px; color: var(--brand, #d6006c); }
.eform-dropzone .dz-title { font-weight: 700; font-size: .84rem; color: var(--ef-ink); }
.eform-dropzone .dz-title b { color: var(--brand, #d6006c); text-decoration: underline; }
.eform-dropzone .dz-hint { font-size: .72rem; color: var(--ef-muted); }

/* Upload progress bar (driven by the real XHR upload-progress stream). */
.eform-upload-progress { margin-top: 10px; display: none; }
.eform-upload-progress.is-active { display: block; }
.eform-upload-progress .track { height: 7px; border-radius: 99px; background: var(--ef-line); overflow: hidden; }
.eform-upload-progress .bar { height: 100%; width: 0; border-radius: 99px; background: var(--brand, #d6006c); transition: width .12s linear; }
.eform-upload-progress .pct { margin-top: 4px; font-size: .72rem; font-weight: 700; color: var(--ef-muted); text-align: right; }

/* Inline status / error (aria-live) — replaces swal popups on the photo path so the user keeps context. */
.eform-photo-status { margin-top: 10px; font-size: .78rem; font-weight: 600; border-radius: 9px; line-height: 1.4; display: none; }
.eform-photo-status.is-visible { display: block; padding: 8px 11px; }
.eform-photo-status.is-error { background: #fdecec; color: #b42318; }
.eform-photo-status.is-success { background: #e7f6ed; color: #067647; }

/* Crop modal: wider dialog + a large framing stage so the user can crop precisely.
   Specificity note: the modal carries BOTH .eform-modal and .eform-crop-modal, and a later
   `.eform-modal .modal-dialog{max-width:460px}` rule would otherwise tie-break over a single-class
   selector — so we qualify with both classes to win regardless of source order. */
.eform-modal.eform-crop-modal .modal-dialog { max-width: 860px; }
.eform-crop-stage { flex: 1 1 460px; min-width: 300px; height: 58vh; max-height: 520px; min-height: 300px; overflow: hidden; display: flex; align-items: center; justify-content: center; }
.eform-crop-stage > img { max-width: 100%; max-height: 100%; display: block; }
.eform-crop-preview { width: 128px; height: 128px; overflow: hidden; border: 1px solid var(--ef-line); background: #f1f3f7; flex: 0 0 auto; }
.eform-crop-preview.is-round { border-radius: 50%; }
.eform-crop-tools { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 14px; justify-content: center; }
.eform-crop-tools button {
    border: 1px solid var(--ef-line); background: #fff; color: var(--ef-ink); width: 36px; height: 36px;
    border-radius: 9px; display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
    font-size: 1.05rem; line-height: 1; transition: border-color .15s ease, color .15s ease;
}
.eform-crop-tools button:hover { border-color: var(--brand, #d6006c); color: var(--brand, #d6006c); }
.eform-crop-tools button svg { width: 17px; height: 17px; }
.eform-crop-tools input[type=range] { accent-color: var(--brand, #d6006c); width: 130px; }

/* ---- Professional-profile "CV" cards → LinkedIn-style entry list + on-demand form ----
   Design system: each card shows saved entries as a clean read-only list; the Add form is a
   separate panel revealed only on demand (the *_info div, now form-only, toggled by the existing
   Show/Close JS). Button COLOUR is SEMANTIC, not decorative — one brand primary (Save), neutral
   secondary (Close), professional-blue Edit (navigational), red Delete (destructive), dashed-brand
   Add (create). This gives visual hierarchy + consistent meaning instead of an all-pink wall. */
.eform .accordion { --bs-accordion-border-color: var(--ef-line); }
.eform .accordion-item { border: 1px solid var(--ef-line) !important; border-radius: 14px !important; overflow: hidden; margin-bottom: 14px; background: #fff; }
.eform .accordion-header { margin: 0; }
.eform .accordion-button { background: #fbfcfe; color: var(--ef-ink); font-weight: 700; padding: 15px 18px; box-shadow: none; display: flex; align-items: baseline; gap: 10px; border-bottom: 1px solid var(--ef-line); pointer-events: none; }
.eform .accordion-button::after { display: none; } /* fake accordion: no collapse, so hide the caret */
.eform .accordion-button p { margin: 0; }
.eform .accordion-button p:first-child { font-size: .96rem; font-weight: 800; letter-spacing: -.01em; }
.eform .accordion-button p:last-child { font-size: .7rem; color: var(--ef-muted); font-weight: 700; text-transform: uppercase; letter-spacing: .05em; }
.eform .accordion-body { padding: 16px 18px 18px; }

/* Entry list */
.eform-cv-list { display: flex; flex-direction: column; }
.eform-cv-list > div > h5 { font-size: .68rem; text-transform: uppercase; letter-spacing: .06em; color: var(--ef-muted); font-weight: 800; margin: 12px 0 2px; }
.eform-cv-list > div > h5:first-child { margin-top: 0; }
.eform-cv-item { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 13px 0; border-bottom: 1px solid var(--ef-line); }
.eform-cv-item:last-child { border-bottom: 0; }
.eform-cv-item-main { min-width: 0; }
.eform-cv-title { font-size: .92rem; font-weight: 800; color: var(--ef-ink); line-height: 1.3; word-break: break-word; }
.eform-cv-sub { font-size: .82rem; color: #475569; font-weight: 600; margin-top: 2px; word-break: break-word; }
.eform-cv-meta { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.eform-cv-meta span { font-size: .73rem; color: #475569; background: #f1f5f9; border-radius: 6px; padding: 3px 9px; font-weight: 600; }
.eform-cv-actions { display: flex; gap: 8px; flex: 0 0 auto; }
.eform-cv-empty { font-size: .85rem; color: var(--ef-muted); padding: 4px 0 2px; }

/* Icon action buttons — Edit = professional blue (navigational), Delete = red (destructive) */
.eform .editBtn, .eform .deleteBtn {
    border: 1.5px solid var(--ef-line); background: #fff; border-radius: 9px; padding: 6px 11px;
    font-weight: 700; font-size: .77rem; cursor: pointer; display: inline-flex; align-items: center; gap: 5px; line-height: 1;
    transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.eform .editBtn svg, .eform .deleteBtn svg { width: 14px; height: 14px; flex: 0 0 auto; }
.eform .editBtn { color: #0a66c2; }
.eform .editBtn:hover { border-color: #0a66c2; background: #eff6ff; }
.eform .deleteBtn { color: #dc2626; }
.eform .deleteBtn:hover { border-color: #dc2626; background: #fef2f2; }

/* On-demand Add form panel (the *_info div, now form-only, hidden until Add/Edit) */
.eform-cv-form { margin-top: 14px; padding: 16px; border: 1.5px solid var(--ef-line); border-radius: 12px; background: #f8fafc; }
.eform-cv-form-title { font-size: .8rem; font-weight: 800; color: var(--ef-ink); margin-bottom: 12px; letter-spacing: -.01em; }
.eform-cv-form .input-label, .eform-cv-form label { font-size: .8rem; font-weight: 700; color: #334155; }
.eform-cv-formactions { display: flex; gap: 10px; margin-top: 4px; }

/* Save = brand solid (single primary); Close = neutral ghost (secondary) */
.eform .submitBtn { background: var(--brand, #d6006c); border: 1.5px solid var(--brand, #d6006c); color: #fff; border-radius: 11px; padding: 9px 22px; font-weight: 700; font-size: .86rem; cursor: pointer; transition: filter .15s ease, background .15s ease; }
.eform .submitBtn:hover { filter: brightness(1.07); }
.eform [id$="CloseBtn"] { background: #fff !important; color: #475569 !important; border: 1.5px solid var(--ef-line) !important; filter: none; }
.eform [id$="CloseBtn"]:hover { background: #f1f5f9 !important; color: var(--ef-ink) !important; }

/* Full-width section header (icon + title + description) for wide sections like the CV block. */
.eform .eform-fullsec { display: flex; align-items: flex-start; gap: 14px; padding: 30px 4px 6px; margin: 0; border-top: 1px solid var(--ef-line); }
.eform .eform-fullsec .eform-group-icon { margin-bottom: 0; flex: 0 0 auto; }
.eform-fullsec h4 { font-size: 1rem; font-weight: 800; letter-spacing: -.01em; color: var(--ef-ink); margin: 6px 0 3px; }
.eform-fullsec p { font-size: .85rem; line-height: 1.5; color: var(--ef-muted); margin: 0; }

/* Add button = dashed brand ghost (create affordance; deliberately lighter than the solid Save) */
.eform .addEducationBtn, .eform .addEmploymentBtn, .eform .addSkillBtn, .eform .addProjectBtn {
    margin-top: 14px; background: #fff !important; color: var(--brand, #d6006c) !important; border: 1.5px dashed var(--brand, #d6006c) !important;
    border-radius: 11px; padding: 10px 18px; font-weight: 700; font-size: .86rem; display: inline-flex;
    align-items: center; gap: 7px; cursor: pointer; transition: background .15s ease;
}
.eform .addEducationBtn svg, .eform .addEmploymentBtn svg, .eform .addSkillBtn svg, .eform .addProjectBtn svg { width: 16px; height: 16px; }
.eform .addEducationBtn:hover, .eform .addEmploymentBtn:hover, .eform .addSkillBtn:hover, .eform .addProjectBtn:hover { background: var(--brand-soft, #fdeaf3) !important; }
.eform .addEducationDiv, .eform .addEmploymentDiv, .eform .addSkillDiv, .eform .addProjectDiv { margin-top: 0; }

/* Skill/language chips (inline list) */
.eform .cv_skill > ul, .eform .cv_language > ul { list-style: none; padding: 0; margin: 6px 0 0; display: flex; flex-wrap: wrap; gap: 8px; }
.eform .cv_skill > ul > li, .eform .cv_language > ul > li { display: inline-flex; align-items: center; gap: 6px; background: #f1f5f9; border: 1px solid var(--ef-line); border-radius: 999px; padding: 5px 6px 5px 12px; }
.eform .cv_skill > ul > li > p, .eform .cv_language > ul > li > p { margin: 0; font-size: .82rem; font-weight: 700; color: var(--ef-ink); }
.eform .cv_skill > ul > li .editBtn, .eform .cv_skill > ul > li .deleteBtn, .eform .cv_language > ul > li .editBtn, .eform .cv_language > ul > li .deleteBtn { padding: 4px 6px; border-radius: 7px; }
.eform .cv_skill > h5, .eform .cv_language > h5 { font-size: .68rem !important; text-transform: uppercase; letter-spacing: .06em; color: var(--ef-muted) !important; font-weight: 800 !important; width: auto !important; margin: 0 0 2px !important; }
.eform .cv_language { margin-top: 14px; }

/* Modal dialog sizing */
.eform-modal .modal-dialog { max-width: 460px; }
.eform-modal .modal-footer { border-top: 1px solid var(--ef-line); padding: 14px 20px; }
/* CV Add/Edit dialogs are wider (2-column form). Must follow the 460px rule to win at equal specificity. */
.eform-cv-modal .modal-dialog { max-width: 620px; }
/* The CV Add dialogs reuse the inline form's Save/Close buttons (.submitBtn), which are styled under
   `.eform`; the modal is relocated to <body> (outside .eform), so restyle them in the modal context. */
.eform-modal .modal-body .submitBtn { background: var(--brand, #d6006c); border: 1.5px solid var(--brand, #d6006c); color: #fff; border-radius: 11px; padding: 10px 22px; font-weight: 700; font-size: .86rem; cursor: pointer; }
.eform-modal .modal-body .submitBtn:hover { filter: brightness(1.07); }
.eform-modal .modal-body [id$="CloseBtn"] { background: #fff !important; color: #475569 !important; border: 1.5px solid var(--ef-line, #e6e8ee) !important; filter: none; }
.eform-modal .modal-body [id$="CloseBtn"]:hover { background: #f1f5f9 !important; color: var(--ef-ink, #0f172a) !important; }

/* =============================================================================================
   Security surface (.sec-*) — the consumer auth/security screens: two-step verification hub,
   authenticator enrolment, recovery codes, and sessions & devices. One component vocabulary so
   all four screens read as one considered product; every rule resolves the .eform tokens above,
   so the surface follows a rebrand and the shared neutral palette automatically.
   ============================================================================================= */

/* ---- Page shell: one readable column on the canvas. Width encodes the screen's job. ---- */
.sec-page { margin: 0 auto; padding: var(--ef-sp-2) 0 var(--ef-sp-7); }
.sec-page--narrow { max-width: 600px; }
.sec-page--regular { max-width: 680px; }
.sec-page--wide { max-width: 860px; }

/* Touch target floor (WCAG 2.5.8): every actionable control on the security surface is ≥44px tall. */
.eform .eform-btn { min-height: 44px; }

/* ---- Neutral secondary button: slate ghost for actions that must not compete with the one
       brand-accented primary (Download / Print / Cancel / Keep-protection). ---- */
.eform-btn--quiet { background: #fff; color: var(--ef-subtle, #475569); border-color: var(--ef-line, #e6e8ee); }
.eform-btn--quiet:hover { background: var(--ef-readonly, #f1f3f7); color: var(--ef-ink, #0f172a); }

/* ---- Destructive buttons. Outline = the offer (Turn off / Sign out); solid = the confirmed,
       final act inside a confirm panel. Red is semantic, never decorative. ---- */
.eform-btn--danger-outline { background: #fff; color: var(--ef-danger-text, #b42318); border-color: var(--ef-danger-line, #fecaca); }
.eform-btn--danger-outline:hover { background: var(--ef-danger-bg, #fef2f2); border-color: var(--ef-danger, #dc2626); }
.eform-btn--danger-outline:focus-visible { outline-color: var(--ef-danger, #dc2626); }
.eform-btn--danger { background: var(--ef-danger, #dc2626); color: #fff; }
.eform-btn--danger:hover { filter: brightness(1.07); }
.eform-btn--danger:focus-visible { outline-color: var(--ef-danger, #dc2626); }

/* ---- Pending state: a form was submitted and the server is deciding. The spinner replaces the
       icon slot; the button stays its own width and cannot be double-fired. ---- */
.eform-btn.is-loading { pointer-events: none; opacity: .75; }
.eform-btn.is-loading::before {
    content: ""; width: 14px; height: 14px; border-radius: 50%;
    border: 2px solid currentColor; border-right-color: transparent;
    animation: sec-spin .7s linear infinite;
}
@keyframes sec-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .eform-btn.is-loading::before { animation: none; } }

/* ---- Banner: one-line page-level status (result of an action, rollout notice, warning).
       Icon + sentence; tinted by meaning, never by brand. ---- */
.sec-banner {
    display: flex; gap: var(--ef-sp-3); align-items: flex-start;
    border: 1px solid var(--ef-line); border-radius: var(--ef-r-lg); background: #fff;
    padding: var(--ef-sp-3) var(--ef-sp-4); margin-bottom: var(--ef-sp-4);
    font-size: var(--ef-text-sm); line-height: 1.5; color: var(--ef-subtle);
}
.sec-banner svg { flex: 0 0 auto; width: 18px; height: 18px; margin-top: 1px; }
.sec-banner strong { color: var(--ef-ink); font-weight: 700; }
.sec-banner--ok { background: var(--ef-ok-bg); border-color: #a7f3d0; color: var(--ef-ok-text); }
.sec-banner--ok strong { color: var(--ef-ok-text); }
.sec-banner--warn { background: var(--ef-warn-bg); border-color: var(--ef-warn-line); color: var(--ef-warn-text); }
.sec-banner--warn strong { color: var(--ef-warn-text); }

/* Terminal two-step-challenge bounce banner shown once on _UserLayout (expired / too many wrong codes
   / dead challenge). Reads the shared danger tokens rather than a hardcoded palette, so the semantic
   red is one edit; one centred measure, not full-bleed (L10, Rule 16). */
.mfa-bounce {
    max-width: 640px; margin: 12px auto; padding: 12px 16px;
    border: 1px solid var(--ef-danger-line); border-radius: 10px;
    background: var(--ef-danger-bg); color: var(--ef-danger-text);
    font-size: var(--ef-text-base); font-weight: 600; line-height: 1.5; text-align: center;
}

/* ---- Feature tile: icon chip + state + description + actions (the two-step hub's core). ---- */
.sec-tile { display: flex; gap: var(--ef-sp-4); align-items: flex-start; }
.sec-tile-icon {
    flex: 0 0 auto; width: 44px; height: 44px; border-radius: var(--ef-r-md);
    display: grid; place-items: center;
    background: var(--brand-soft, #fdeaf3); color: var(--brand, #d6006c);
}
.sec-tile-icon svg { width: 24px; height: 24px; }
.sec-tile-main { flex: 1 1 auto; min-width: 0; }
.sec-tile-title { display: flex; align-items: center; gap: var(--ef-sp-2); flex-wrap: wrap; }
.sec-tile-title h2 { font-size: var(--ef-text-md); font-weight: 800; letter-spacing: -.01em; color: var(--ef-ink); margin: 0; }
.sec-tile-desc { color: var(--ef-muted); font-size: var(--ef-text-base); line-height: 1.55; margin: var(--ef-sp-2) 0 0; max-width: 58ch; }
.sec-tile-actions { display: flex; gap: var(--ef-sp-3); flex-wrap: wrap; align-items: center; margin-top: var(--ef-sp-4); }
/* A form wrapper used only to make a state-changing action (e.g. Connect) a POST + anti-forgery submit
   instead of a GET link (R2-7). display:contents keeps its button as the direct flex/inline item, so the
   button lays out exactly as the anchor it replaced — the form box itself contributes no layout. */
.eform-inline-form { display: contents; }
@media (max-width: 560px) {
    /* Icon shrinks but stays beside the title — a lone icon row above the text reads as an orphan. */
    .sec-tile { gap: var(--ef-sp-3); }
    .sec-tile-icon { width: 38px; height: 38px; }
    .sec-tile-icon svg { width: 20px; height: 20px; }
    .sec-tile-actions { flex-direction: column; align-items: stretch; }
    .sec-tile-actions form { display: contents; }
    .sec-tile-actions .eform-btn { width: 100%; }
    .sec-tile-sub > .eform-btn { width: 100%; }
}

/* Sub-row inside a tile card (e.g. the recovery-codes line under the authenticator row). */
.sec-tile-sub {
    display: flex; gap: var(--ef-sp-3); align-items: flex-start; flex-wrap: wrap;
    margin-top: var(--ef-sp-5); padding-top: var(--ef-sp-4); border-top: 1px solid var(--ef-line);
}
.sec-tile-sub-main { flex: 1 1 260px; min-width: 0; }
.sec-tile-sub-main h3 { font-size: var(--ef-text-base); font-weight: 700; color: var(--ef-ink); margin: 0 0 2px; }
.sec-tile-sub-main p { font-size: var(--ef-text-sm); color: var(--ef-muted); line-height: 1.5; margin: 0; max-width: 52ch; }
/* The note under a tile's text — a precondition to enrol, or the reason an enrolled factor is not used
   at sign-in. It is a filled block, so without the gap it butts straight against the sentence above it;
   both tile shapes carry the rule because the authenticator row and the delivered rows are siblings.

   The CAP is per shape, not shared: one number in `ch` is a different width in each, because `ch`
   scales with the element's own type. In the sub-row the note and the sentence are both --ef-text-sm,
   so 52ch is literally the sentence's right edge; a shared 58ch put the tinted block ~11% PAST the
   line above it, which is the ragged edge the shared rule was written to prevent. In the main row the
   sentence is the larger --ef-text-base, so 58ch of note type lands inside its measure — never past
   it, which is the invariant here (Rule 16: one measure per surface). */
.sec-tile-main > .eform-note,
.sec-tile-sub-main > .eform-note { margin-top: var(--ef-sp-3); }
.sec-tile-main > .eform-note { max-width: 58ch; }
.sec-tile-sub-main > .eform-note { max-width: 52ch; }

/* ---- Inline destructive confirmation: replaces window.confirm with a panel that says exactly
       what will happen and offers a safe way out. Revealed in place, focus moves to its heading. ---- */
.sec-confirm {
    margin-top: var(--ef-sp-4); padding: var(--ef-sp-4);
    background: var(--ef-danger-bg); border: 1px solid var(--ef-danger-line); border-radius: var(--ef-r-lg);
}
.sec-confirm[hidden] { display: none; }
.sec-confirm h3 { font-size: var(--ef-text-base); font-weight: 800; color: var(--ef-danger-text); margin: 0 0 4px; }
.sec-confirm p { font-size: var(--ef-text-sm); color: var(--ef-subtle); line-height: 1.5; margin: 0 0 var(--ef-sp-3); max-width: 60ch; }
.sec-confirm h3:focus { outline: none; }
.sec-confirm-actions { display: flex; gap: var(--ef-sp-3); flex-wrap: wrap; }
.sec-confirm--warn { background: var(--ef-warn-bg); border-color: var(--ef-warn-line); }
.sec-confirm--warn h3 { color: var(--ef-warn-text); }
@media (max-width: 560px) { .sec-confirm-actions { flex-direction: column; } .sec-confirm-actions .eform-btn, .sec-confirm-actions form { width: 100%; } .sec-confirm-actions form .eform-btn { width: 100%; } }

/* ---- Enrolment steps: a numbered sequence (the numbers ARE the information — scan, then confirm),
       joined by a hairline rail so the eye reads one continuous procedure. ---- */
.sec-steps { list-style: none; counter-reset: sec-step; margin: 0; padding: 0; }
.sec-step { counter-increment: sec-step; position: relative; display: flex; gap: var(--ef-sp-4); padding-bottom: var(--ef-sp-6); }
.sec-step:last-child { padding-bottom: 0; }
.sec-step::before {
    content: counter(sec-step); flex: 0 0 auto; width: 28px; height: 28px; border-radius: var(--ef-r-pill);
    background: var(--brand, #d6006c); color: var(--brand-contrast, #fff);
    font-size: .82rem; font-weight: 700; line-height: 28px; text-align: center; z-index: 1;
}
.sec-step:not(:last-child)::after {
    content: ""; position: absolute; left: 13.5px; top: 32px; bottom: 4px; width: 1px; background: var(--ef-line);
}
.sec-step-body { flex: 1 1 auto; min-width: 0; padding-top: 3px; }
.sec-step-body h2 { font-size: var(--ef-text-md); font-weight: 800; letter-spacing: -.01em; color: var(--ef-ink); margin: 0 0 var(--ef-sp-1); }
.sec-step-body > p { color: var(--ef-muted); font-size: var(--ef-text-base); line-height: 1.55; margin: 0; max-width: 52ch; }

/* ---- QR panel: white with a real quiet zone (16px on every side beyond the SVG's own margin)
       so any camera locks on. Never dark-inverted, never cramped. ---- */
.sec-qr {
    display: inline-block; margin-top: var(--ef-sp-4); padding: var(--ef-sp-4);
    background: #fff; border: 1px solid var(--ef-line); border-radius: var(--ef-r-lg);
}
.sec-qr svg { display: block; width: 196px; height: 196px; }
@media (max-width: 400px) { .sec-qr svg { width: 164px; height: 164px; } }

/* ---- Manual key fallback: legible mono, grouped, with its own copy affordance. ---- */
.sec-key { margin-top: var(--ef-sp-4); }
.sec-key-label { display: block; font-size: var(--ef-text-label); font-weight: 700; color: var(--ef-label); margin: 0 0 var(--ef-sp-2); }
.sec-key-row { display: flex; gap: var(--ef-sp-2); align-items: stretch; flex-wrap: wrap; }
.sec-key-value {
    flex: 1 1 auto; min-width: 0; display: flex; align-items: center;
    font-family: var(--ef-mono); font-size: .95rem; font-weight: 600; letter-spacing: .12em;
    color: var(--ef-ink); background: var(--ef-bg); border: 1px solid var(--ef-line);
    border-radius: var(--ef-r-md); padding: 10px 14px; word-break: break-all; user-select: all;
}

/* ---- One-time-code field: large, mono, centred — unmistakably the focal input. ---- */
.sec-code-label { display: block; font-size: var(--ef-text-label); font-weight: 700; color: var(--ef-label); margin: 0 0 var(--ef-sp-2); }
.sec-code-input {
    width: 100%; max-width: 240px; min-height: 56px;
    font-family: var(--ef-mono); font-size: 1.5rem; font-weight: 700; line-height: 1;
    letter-spacing: .45em; text-indent: .45em; text-align: center;
    color: var(--ef-ink); background: #fff; caret-color: var(--brand, #d6006c);
    border: 1.5px solid var(--ef-line); border-radius: var(--ef-r-md); padding: 12px 8px;
    transition: border-color .15s ease, box-shadow .15s ease;
}
.sec-code-input::placeholder { color: #b6bfcc; letter-spacing: .45em; }
.sec-code-input:focus { outline: none; border-color: var(--brand, #d6006c); box-shadow: 0 0 0 3px var(--brand-soft, #fdeaf3); }
.sec-code-input.is-invalid { border-color: var(--ef-danger); }
.sec-code-input.is-invalid:focus { box-shadow: 0 0 0 3px var(--ef-danger-bg); }

/* Hint / error line under the code field. Error keeps a glyph so meaning survives monochrome. */
.sec-field-hint { display: flex; gap: 6px; align-items: flex-start; min-height: 20px; margin: var(--ef-sp-2) 0 0; font-size: var(--ef-text-sm); color: var(--ef-muted); line-height: 1.45; }
.sec-field-hint.is-error { color: var(--ef-danger-text); font-weight: 600; }
.sec-field-hint.is-error::before { content: "!"; font-weight: 800; flex: 0 0 auto; }

/* ---- Recovery codes: numbered mono grid. The index is muted so the code stays the figure. ---- */
.sec-codes { list-style: none; counter-reset: sec-code; margin: var(--ef-sp-4) 0 0; padding: 0; display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--ef-sp-2); }
.sec-codes li {
    counter-increment: sec-code; display: flex; align-items: center; gap: 10px;
    font-family: var(--ef-mono); font-size: .95rem; font-weight: 600; letter-spacing: .08em;
    color: var(--ef-ink); background: var(--ef-bg); border: 1px solid var(--ef-line);
    border-radius: var(--ef-r-sm); padding: 11px 14px;
}
.sec-codes li::before { content: counter(sec-code); font-size: var(--ef-text-xs); font-weight: 700; letter-spacing: 0; color: #8a94a6; min-width: 14px; text-align: right; }
@media (max-width: 480px) { .sec-codes { grid-template-columns: 1fr; } }

/* Action row + transient "Copied" acknowledgement. */
.sec-actions { display: flex; gap: var(--ef-sp-3); flex-wrap: wrap; align-items: center; margin-top: var(--ef-sp-5); }
@media (max-width: 560px) { .sec-actions { flex-direction: column; align-items: stretch; } .sec-actions .eform-btn { width: 100%; } }
.sec-copied { margin: var(--ef-sp-2) 0 0; font-size: var(--ef-text-sm); font-weight: 700; color: var(--ef-ok-text); opacity: 0; transition: opacity .15s ease; }
.sec-copied.show { opacity: 1; }
.sec-actions .sec-copied { margin: 0; }

/* The confirm form inside an enrolment step sits a beat below the step's prose. */
.sec-step-form { margin-top: var(--ef-sp-4); }

/* ---- Sessions & devices ---- */
/* Flush card: the row list draws its own internal padding, so the card contributes only the frame. */
.eform-card--flush { padding: 0; overflow: hidden; }
.sec-session-list { display: flex; flex-direction: column; }
.sec-session { display: flex; gap: var(--ef-sp-4); align-items: flex-start; padding: var(--ef-sp-4) var(--ef-sp-5); border-bottom: 1px solid var(--ef-line); }
.sec-session:last-child { border-bottom: 0; }
.sec-session.is-ended { background: #fbfcfd; }
.sec-session.is-ended .sec-session-icon { background: var(--ef-readonly); color: #8a94a6; }
.sec-session-icon {
    flex: 0 0 auto; width: 40px; height: 40px; border-radius: var(--ef-r-md);
    display: grid; place-items: center; background: var(--ef-bg); color: var(--ef-subtle);
    border: 1px solid var(--ef-line);
}
.sec-session-icon svg { width: 20px; height: 20px; }
.sec-session-main { flex: 1 1 auto; min-width: 0; }
.sec-session-name { display: flex; align-items: center; gap: var(--ef-sp-2); flex-wrap: wrap; font-size: var(--ef-text-base); font-weight: 700; color: var(--ef-ink); }
.is-ended .sec-session-name { color: var(--ef-subtle); }
.sec-session-meta { margin-top: 3px; font-size: var(--ef-text-sm); color: var(--ef-muted); line-height: 1.5; }
.sec-session-action { flex: 0 0 auto; align-self: center; }
@media (max-width: 560px) {
    .sec-session { flex-wrap: wrap; padding: var(--ef-sp-4); }
    .sec-session-main { flex-basis: calc(100% - 40px - var(--ef-sp-4)); }
    .sec-session-action { flex-basis: 100%; align-self: stretch; }
    .sec-session-action .eform-btn { width: 100%; }
}

/* Page-level footer action (Sign out everywhere else) — deliberate, not floating. */
.sec-footer-actions { display: flex; justify-content: flex-end; margin-top: var(--ef-sp-4); }
@media (max-width: 560px) { .sec-footer-actions .eform-btn { width: 100%; } }

/* Async outcome line (aria-live). Colour set by state class, never inline. */
.sec-status-line { margin-top: var(--ef-sp-3); min-height: 1.4em; font-size: var(--ef-text-base); font-weight: 600; }
.sec-status-line.is-ok { color: var(--ef-ok-text); }
.sec-status-line.is-error { color: var(--ef-danger-text); }

/* ---- Empty state: calm, informative, never a bare sentence in a box. ---- */
.sec-empty { display: flex; flex-direction: column; align-items: center; text-align: center; padding: var(--ef-sp-7) var(--ef-sp-5); }
.sec-empty-icon {
    width: 48px; height: 48px; border-radius: var(--ef-r-lg); display: grid; place-items: center;
    background: var(--ef-bg); color: var(--ef-subtle); border: 1px solid var(--ef-line); margin-bottom: var(--ef-sp-4);
}
.sec-empty-icon svg { width: 24px; height: 24px; }
.sec-empty h2 { font-size: var(--ef-text-md); font-weight: 800; color: var(--ef-ink); margin: 0 0 var(--ef-sp-1); }
.sec-empty p { font-size: var(--ef-text-base); color: var(--ef-muted); line-height: 1.55; margin: 0; max-width: 44ch; }

/* =============================================================================================
   Account deletion (.adel-*) — the public "delete your account" page and its signed-in flow.
   Every rule resolves the .eform tokens above; no colour, radius or step is invented here.
   ============================================================================================= */

/* ---- Consequence list: a heading + a sentence per row, in a bordered stack.
       A <dl> rather than a <ul>, because each row IS a term and its definition, and the two
       lists (removed / kept) are the whole substance of the page for a screen-reader user. ---- */
.adel-effects { margin: 0; }
.adel-effect { padding: var(--ef-sp-4) 0; border-top: 1px solid var(--ef-line); }
.adel-effect:first-child { padding-top: 0; border-top: 0; }
.adel-effect:last-child { padding-bottom: 0; }
.adel-effect dt {
    display: flex; gap: var(--ef-sp-2); align-items: baseline;
    font-size: var(--ef-text-base); font-weight: 800; color: var(--ef-ink); line-height: 1.4;
}
/* Cap the PROSE, not the column: the measure lives here so the card can stay full width.
   Indented by the marker's width plus its gap, so the sentence starts under its own heading
   rather than under the glyph beside it. */
.adel-effect dd {
    margin: var(--ef-sp-2) 0 0; padding-left: calc(20px + var(--ef-sp-2));
    font-size: var(--ef-text-base); color: var(--ef-subtle);
    line-height: 1.6; max-width: 66ch;
}
/* The timeline list has no markers, so its definitions align flush with their terms. */
.adel-effects--plain .adel-effect dd { padding-left: 0; }

/* Marker glyph. A shape as well as a colour, so the removed/kept distinction survives
   monochrome rendering and colour-blindness (WCAG 1.4.1) rather than resting on red vs green. */
.adel-mark {
    flex: 0 0 auto; width: 20px; height: 20px; border-radius: var(--ef-r-pill);
    display: grid; place-items: center; font-size: .72rem; font-weight: 800; line-height: 1;
    transform: translateY(2px);
}
.adel-mark--gone { background: var(--ef-danger-bg); color: var(--ef-danger-text); }
.adel-mark--kept { background: var(--ef-ok-bg); color: var(--ef-ok-text); }

/* ---- Section heading above each list. Distinct from .eform-title, which is the page's H1. ---- */
.adel-section-head { margin: 0 0 var(--ef-sp-2); }
.adel-section-head h2 {
    font-size: var(--ef-text-md); font-weight: 800; color: var(--ef-ink);
    letter-spacing: -.01em; margin: 0;
}
.adel-section-head p {
    margin: var(--ef-sp-1) 0 0; font-size: var(--ef-text-sm); color: var(--ef-muted);
    line-height: 1.5; max-width: 66ch;
}

/* ---- Stack rhythm between the page's cards. ---- */
.adel-stack > * + * { margin-top: var(--ef-sp-5); }

/* ---- The deadline, stated once and large enough to be the thing you remember. ---- */
.adel-deadline {
    display: block; font-size: var(--ef-text-xl); font-weight: 800; color: var(--ef-ink);
    letter-spacing: -.02em; margin: var(--ef-sp-1) 0 0;
}

/* ---- Confirmation field. Narrow by intent: it takes one short word, and a full-width input
       would invite a sentence. Matches .sec-code-input's reasoning on the sibling screens. ---- */
/* The INPUT is narrow, not the field group: capping the group squeezes the hint underneath it
   into a two-line ribbon, and the hint is a full sentence. */
.adel-confirm-field .eform-control {
    max-width: 260px; font-family: var(--ef-mono); letter-spacing: .08em; text-transform: none;
}
.adel-confirm-field .eform-control[aria-invalid="true"] { border-color: var(--ef-danger); }
.adel-confirm-field .sec-field-hint { max-width: 46ch; }
@media (max-width: 560px) { .adel-confirm-field .eform-control { max-width: none; } }

/* Standalone paragraph inside a card — the same measure and colour as .adel-effect dd, without
   the list row's rule and padding. Exists so a card holding one sentence needs no inline style. */
.adel-prose {
    margin: 0; font-size: var(--ef-text-base); color: var(--ef-subtle);
    line-height: 1.6; max-width: 66ch;
}
.adel-prose + .sec-tile-actions { margin-top: var(--ef-sp-4); }
