frappe.pages['makap-portal'].on_page_load = function (wrapper) { var page = frappe.ui.make_app_page({ parent: wrapper, title: 'MAKAP Portal', single_column: true, }); render_portal(page); }; function render_portal(page) { inject_style(); var esc = function (v) { return String(v == null ? '—' : v).replace(/[&<>"']/g, function (c) { return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c]; }); }; var clean = function (s) { return (s || '').replace(/\s+/g, ' ').trim(); }; var canCreate = function (doctype) { return frappe.model.can_create(doctype); }; var canDelete = function (doctype) { return frappe.model.can_delete(doctype); }; var deleteRecord = function (doctype, name, onDone) { frappe.confirm( __('Delete {0} {1}? This cannot be undone.', [doctype, frappe.utils.escape_html(name)]), function () { frappe.call({ method: 'frappe.client.delete', args: { doctype: doctype, name: name }, freeze: true, callback: function () { frappe.show_alert({ message: __('Deleted {0}', [name]), indicator: 'green' }); if (onDone) onDone(); } }); } ); }; var ROUTES = { 'Onboarding requests': 'Customer Onboarding Request', 'Customer': 'Customer', 'Contact': 'Contact', 'Opportunity': 'Opportunity', 'Quotation': 'Quotation', 'Sales order': 'Sales Order', 'Packaging specs': 'Packaging Specification', 'Material structures': 'Material Structure', 'Critical acceptance': 'Critical Acceptance Requirement', 'Item': 'Item', 'Operation': 'Operation', 'Work order': 'Work Order', 'Production plan': 'Production Plan', 'Material request': 'Material Request', 'Purchase order': 'Purchase Order', 'Purchase receipt': 'Purchase Receipt', 'Quality inspection': 'Quality Inspection', 'Delivery note': 'Delivery Note', 'Sales invoice': 'Sales Invoice', 'Payment entry': 'Payment Entry', 'Purchase invoice': 'Purchase Invoice', 'Order closure & margin': 'Order Closure And Margin View', 'User': 'User', 'UOM': 'UOM' }; var SIDEBAR_HTML = '
Overview
' + '
Dashboard
' + '
Customer & commercial · M1–2
' + '
Onboarding requests0
' + '
CustomerERPNext
' + '
ContactERPNext
' + '
OpportunityERPNext
' + '
QuotationERPNext
' + '
Sales orderERPNext
' + '
Specification & prepress · M3
' + '
Packaging specs0
' + '
Material structuresChild table
' + '
Critical acceptanceChild table
' + '
ItemERPNext
' + '
Production & planning · M4
' + '
OperationERPNext
' + '
Work orderERPNext
' + '
Production planERPNext
' + '
Materials & inventory · M5
' + '
Material requestERPNext
' + '
Purchase orderERPNext
' + '
Purchase receiptERPNext
' + '
Quality · M6
' + '
Quality inspectionERPNext
' + '
Fulfilment & billing · M8
' + '
Delivery noteERPNext
' + '
Sales invoiceERPNext
' + '
Payment entryERPNext
' + '
Purchase invoiceERPNext
' + '
Operating control
' + '
Order closure & margin0 Open
' + '
Reference & lookups
' + '
UserFrappe core
' + '
UOMSetup
'; var HERO_HTML = '
' + '

Welcome back, 👋

' + '

Here\'s what\'s happening across MAKAP Uganda\'s manufacturing workflow.

' + '
' + '
' + '
Onboarding requests
0
' + '
Packaging specifications
0
' + '
Approved for manufacture
0
' + '
Critical requirements tracked
0
' + '
'; page.main.html( '
' + '
' + SIDEBAR_HTML + '
' + '
' + HERO_HTML + '
' + '
' ); var $sidebar = page.main.find('#mkp-sidebar'); var $content = page.main.find('#mkp-content'); var ORIGINAL_CONTENT = $content.html(); /* ---- identity ---- */ var fullName = frappe.session.user_fullname || frappe.session.user || 'User'; page.main.find('#mkp-user').text(fullName); /* ---- collapsible groups ---- */ (function wrapGroups() { var labels = $sidebar.find('.mkp-nav-group-label').toArray(); labels.forEach(function (label, index) { var $label = $(label); var $group = $('
'); $label.before($group); $group.append($label); var next = $group.next(); while (next.length && !next.hasClass('mkp-nav-group-label') && !next.hasClass('mkp-nav-group')) { var after = next.next(); $group.append(next); next = after; } }); $sidebar.find('.mkp-nav-group-label').each(function () { var $label = $(this); var $group = $label.parent(); $label.attr('tabindex', 0).on('click', function () { $group.toggleClass('mkp-collapsed'); }); $label.on('keydown', function (e) { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); $label.click(); } }); }); })(); /* ---- KPI cards ---- */ frappe.call({ method: 'makap_backend.makap_backend.portal_api.get_portal_dashboard', callback: function (r) { var k = r.message && r.message.kpis; if (!k) return; var values = [k.onboarding_requests, k.packaging_specifications, k.approved_for_manufacture, k.critical_requirements_tracked]; page.main.find('.mkp-stat-card .mkp-stat-value').each(function (i) { if (values[i] !== undefined) $(this).text(Number(values[i] || 0).toLocaleString()); }); } }); function markActive($item) { $sidebar.find('.mkp-nav-item').removeClass('mkp-selected'); $item.addClass('mkp-selected'); } function showDashboard() { $content.html(ORIGINAL_CONTENT); $sidebar.find('.mkp-nav-item').removeClass('mkp-selected'); } /* ---- generic in-portal panel ---- */ function genericApi(doctype) { return '/api/resource/' + encodeURIComponent(doctype) + '?fields=' + encodeURIComponent(JSON.stringify(['*'])) + '&limit_page_length=25&order_by=modified%20desc'; } function renderGeneric(doctype, label, rows) { var fields = rows.length ? Object.keys(rows[0]).filter(function (k) { return ['name', 'owner', 'creation', 'modified', 'modified_by', 'docstatus', 'idx', '_user_tags', '_comments', '_assign', '_liked_by'].indexOf(k) === -1; }).slice(0, 6) : []; var cols = ['name'].concat(fields); var allowDelete = canDelete(doctype); $content.html( '
' + '
' + '

Selected module

' + esc(label) + '

' + rows.length + ' live records from Frappe

' + '
' + '' + (canCreate(doctype) ? '' : '') + '
' + '
' + '' + '' + cols.map(function (x) { return ''; }).join('') + (allowDelete ? '' : '') + '' + '' + (rows.length ? rows.map(function (r) { return '' + cols.map(function (x, i) { return ''; }).join('') + (allowDelete ? '' : '') + ''; }).join('') : '') + '' + '
' + esc(x.replaceAll('_', ' ')) + '
' + esc(r[x]) + '
No records found
' + '
' ); $content.find('#mkp-generic-back').on('click', showDashboard); $content.find('#mkp-generic-new').on('click', function () { frappe.new_doc(doctype); }); $content.find('td.mkp-link').on('click', function () { frappe.set_route('Form', doctype, $(this).data('name')); }); $content.find('.mkp-del').on('click', function (e) { e.stopPropagation(); var name = $(this).data('name'); deleteRecord(doctype, name, function () { showGeneric($sidebar.find('.mkp-nav-item.mkp-selected'), doctype, label); }); }); } function showGeneric($item, doctype, label) { markActive($item); $content.html('
Loading ' + esc(label) + '…
'); fetch(genericApi(doctype), { credentials: 'same-origin' }) .then(function (r) { return r.json(); }) .then(function (j) { if (j.exc) throw new Error(); renderGeneric(doctype, label, j.data || []); }) .catch(function () { $content.html('
Unable to load ' + esc(label) + '. Check your Frappe permissions.
'); }); } /* ---- onboarding panel ---- */ function loadOnboardingRequests() { var $loading = $content.find('#mkp-onboarding-loading'); var $table = $content.find('#mkp-onboarding-table'); if (!$loading.length || !$table.length) return; $loading.show(); $table.html(''); var fields = ['name', 'organisation_name', 'trading_name', 'contact_name', 'email_id', 'customer_type', 'location', 'onboarding_status', 'customer_match_result', 'portal_access_status', 'creation']; fetch('/api/resource/Customer%20Onboarding%20Request?fields=' + encodeURIComponent(JSON.stringify(fields)) + '&limit_page_length=50&order_by=modified%20desc', { credentials: 'same-origin' }) .then(function (r) { return r.json(); }) .then(function (result) { $loading.hide(); var rows = result.data || []; if (!rows.length) { $table.html('
No onboarding requests found.
'); return; } var allowDelete = canDelete('Customer Onboarding Request'); $table.html( '' + (allowDelete ? '' : '') + '' + rows.map(function (row) { return '' + '' + '' + '' + '' + '' + '' + '' + (allowDelete ? '' : '') + ''; }).join('') + '
RequestOrganisationContactEmailLocationStatusCustomer match
' + esc(row.organisation_name) + '' + esc(row.contact_name) + '' + esc(row.email_id) + '' + esc(row.location) + '' + esc(row.onboarding_status) + '' + esc(row.customer_match_result) + '
' ); $table.find('td.mkp-link').on('click', function () { frappe.set_route('Form', 'Customer Onboarding Request', $(this).data('name')); }); $table.find('.mkp-del').on('click', function (e) { e.stopPropagation(); deleteRecord('Customer Onboarding Request', $(this).data('name'), loadOnboardingRequests); }); }) .catch(function () { $loading.hide(); $table.html('
Unable to load onboarding requests. Check your Frappe permissions.
'); }); } function showOnboarding($item) { markActive($item); $content.html( '
' + '
' + '

Customer & commercial · M1–2

Customer onboarding

Live onboarding requests from Frappe.

' + '' + '
' + '
' + (canCreate('Customer Onboarding Request') ? '' : '') + '' + '' + '
' + '
Loading onboarding requests…
' + '
' + '
' ); $content.find('#mkp-onboarding-dashboard').on('click', showDashboard); $content.find('#mkp-onboarding-refresh').on('click', loadOnboardingRequests); $content.find('#mkp-onboarding-new').on('click', function () { frappe.new_doc('Customer Onboarding Request'); }); $content.find('#mkp-onboarding-list').on('click', function () { frappe.set_route('List', 'Customer Onboarding Request'); }); loadOnboardingRequests(); } /* ---- customer panel ---- */ var customerApi = '/api/resource/Customer'; var customerType = 'All', customerStatus = 'All', customerSearch = ''; function customerCount(filters) { var p = new URLSearchParams({ fields: JSON.stringify(['name']), filters: JSON.stringify(filters || []), limit_page_length: '1', limit_start: '0' }); return fetch(customerApi + '?' + p.toString(), { credentials: 'same-origin' }).then(function (r) { return r.json(); }).then(function (r) { return Number((r.data && r.data.length) || 0); }); } function customerQuery() { var filters = []; if (customerType !== 'All') filters.push(['customer_type', '=', customerType]); if (customerStatus === 'Active') filters.push(['disabled', '=', 0]); if (customerStatus === 'Disabled') filters.push(['disabled', '=', 1]); var params = new URLSearchParams({ fields: JSON.stringify(['name', 'customer_name', 'customer_type', 'customer_group', 'territory', 'tax_id', 'mobile_no', 'email_id', 'disabled', 'creation', 'modified']), filters: JSON.stringify(filters), limit_page_length: '50', order_by: 'modified desc' }); return fetch(customerApi + '?' + params.toString(), { credentials: 'same-origin' }).then(function (r) { return r.json(); }).then(function (r) { return r.data || []; }); } function customerCard(label, value, filterValue, active) { return '
' + label + '' + Number(value || 0).toLocaleString() + '
'; } function renderCustomerRows(rows) { var term = customerSearch.toLowerCase(); var data = term ? rows.filter(function (x) { return Object.values(x).join(' ').toLowerCase().indexOf(term) !== -1; }) : rows; var cols = ['name', 'customer_name', 'customer_type', 'customer_group', 'territory', 'tax_id', 'mobile_no', 'email_id', 'disabled']; var allowDelete = canDelete('Customer'); $content.find('#mkp-customer-table').html(data.length ? '' + cols.map(function (x) { return ''; }).join('') + (allowDelete ? '' : '') + '' + data.map(function (x) { return '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + (allowDelete ? '' : '') + ''; }).join('') + '
' + x.replaceAll('_', ' ') + '
' + esc(x.customer_name) + '' + esc(x.customer_type) + '' + esc(x.customer_group) + '' + esc(x.territory) + '' + esc(x.tax_id) + '' + esc(x.mobile_no) + '' + esc(x.email_id) + '' + (x.disabled ? 'Disabled' : 'Active') + '
' : '
No customers match your filters.
' ); $content.find('td.mkp-link[data-name]').on('click', function () { customerDetail($(this).data('name')); }); $content.find('.mkp-del').on('click', function (e) { e.stopPropagation(); deleteRecord('Customer', $(this).data('name'), renderCustomerList); }); } function wireCustomerList() { $content.find('#mkp-customer-dashboard').on('click', showDashboard); $content.find('#mkp-customer-refresh').on('click', renderCustomerList); $content.find('#mkp-customer-new').on('click', function () { frappe.new_doc('Customer'); }); $content.find('#mkp-customer-type').on('change', function () { customerType = this.value; renderCustomerList(); }); $content.find('#mkp-customer-status').on('change', function () { customerStatus = this.value; renderCustomerList(); }); var t; $content.find('#mkp-customer-search').on('input', function () { customerSearch = this.value; clearTimeout(t); t = setTimeout(renderCustomerList, 250); }); $content.find('.mkp-customer-card').on('click', function () { var f = $(this).data('filter'); if (f === 'Company' || f === 'Individual') { customerType = f; customerStatus = 'All'; } else if (f) { customerStatus = f; customerType = 'All'; } else { customerType = 'All'; customerStatus = 'All'; } renderCustomerList(); }); } function renderCustomerList() { var $customerItem = $sidebar.find('.mkp-nav-item').filter(function () { return clean($(this).text()).indexOf('Customer') === 0; }).first(); if ($customerItem.length) markActive($customerItem); $content.html('
Loading customers…
'); Promise.all([ customerCount(), customerCount([['customer_type', '=', 'Company']]), customerCount([['customer_type', '=', 'Individual']]), customerCount([['disabled', '=', 0]]), customerCount([['disabled', '=', 1]]), customerQuery() ]).then(function (results) { var all = results[0], companies = results[1], individuals = results[2], active = results[3], disabled = results[4], rows = results[5]; $content.html( '
' + '

Customer & commercial · M1–2

Customers

Live customer records from Frappe.

' + '
' + (canCreate('Customer') ? '' : '') + '
' + '
' + customerCard('Total customers', all, '', customerStatus === 'All' && customerType === 'All') + customerCard('Companies', companies, 'Company', customerType === 'Company') + customerCard('Individuals', individuals, 'Individual', customerType === 'Individual') + customerCard('Active customers', active, 'Active', customerStatus === 'Active') + customerCard('Disabled customers', disabled, 'Disabled', customerStatus === 'Disabled') + '
' + '
' + '' + '' + '' + '
' + '
' + '
' ); renderCustomerRows(rows); wireCustomerList(); }).catch(function () { $content.html('
Unable to load customers. Check your Frappe permissions.
'); }); } function customerDetail(name) { $content.html('
Loading customer…
'); var p = new URLSearchParams({ fields: JSON.stringify(['*']) }); fetch(customerApi + '/' + encodeURIComponent(name) + '?' + p.toString(), { credentials: 'same-origin' }) .then(function (r) { return r.json(); }) .then(function (j) { var x = j.data || {}; var $customerItem = $sidebar.find('.mkp-nav-item').filter(function () { return clean($(this).text()).indexOf('Customer') === 0; }).first(); if ($customerItem.length) markActive($customerItem); var rowsHtml = [ ['Customer ID', x.name], ['Customer name', x.customer_name], ['Customer type', x.customer_type], ['Customer group', x.customer_group], ['Territory', x.territory], ['Tax ID', x.tax_id], ['Email', x.email_id], ['Mobile', x.mobile_no], ['Website', x.website], ['Default currency', x.default_currency], ['Payment terms', x.payment_terms], ['Credit limit', x.credit_limit], ['Created', x.creation], ['Modified', x.modified] ].map(function (pair) { return '
' + pair[0] + '' + esc(pair[1]) + '
'; }).join(''); $content.html( '
' + '

Customer profile

' + esc(x.customer_name || x.name) + '

' + esc(x.name) + ' · ' + (x.disabled ? 'Disabled' : 'Active') + '

' + '
' + (canDelete('Customer') ? '' : '') + '
' + '
' + rowsHtml + '
' ); $content.find('#mkp-customer-back').on('click', renderCustomerList); $content.find('#mkp-customer-detail-refresh').on('click', function () { customerDetail(name); }); $content.find('#mkp-customer-open-form').on('click', function () { frappe.set_route('Form', 'Customer', name); }); $content.find('#mkp-customer-detail-delete').on('click', function () { deleteRecord('Customer', name, renderCustomerList); }); }) .catch(function () { $content.html('
Unable to load this customer.
'); }); } /* ---- wire every nav item to exactly one handler ---- */ $sidebar.find('.mkp-nav-item').each(function () { var $item = $(this); var text = clean($item.text()); if (text.indexOf('Dashboard') === 0) { $item.css('cursor', 'pointer').on('click', function () { showDashboard(); }); return; } if (text.indexOf('Onboarding requests') === 0) { $item.css('cursor', 'pointer').on('click', function () { showOnboarding($item); }); return; } if (text.indexOf('Customer') === 0) { $item.css('cursor', 'pointer').on('click', function () { renderCustomerList(); }); return; } var key = Object.keys(ROUTES).filter(function (name) { return text.indexOf(name) === 0; })[0]; if (!key) return; var doctype = ROUTES[key]; $item.css('cursor', 'pointer').on('click', function () { showGeneric($item, doctype, key); }); }); } function inject_style() { if (document.getElementById('mkp-portal-style')) return; var css = '.mkp-page{display:flex;align-items:flex-start;gap:20px;}' + '.mkp-sidebar{width:240px;flex:0 0 240px;background:#0F1B2D;color:#C9D3E5;border-radius:10px;padding:16px 10px;position:sticky;top:10px;align-self:flex-start;max-height:calc(100vh - 100px);overflow-y:auto;}' + '.mkp-nav-group-label{font-size:11px;text-transform:uppercase;letter-spacing:.07em;color:#6D7A93;padding:12px 8px 4px;font-weight:700;cursor:pointer;user-select:none;}' + '.mkp-nav-group-label::after{content:"⌄";float:right;opacity:.7;transition:transform .15s ease;}' + '.mkp-nav-group.mkp-collapsed .mkp-nav-group-label::after{transform:rotate(-90deg);}' + '.mkp-nav-group.mkp-collapsed .mkp-nav-item{display:none !important;}' + '.mkp-nav-item{display:flex;align-items:center;gap:9px;padding:7px 8px;border-radius:7px;font-size:12.5px;font-weight:500;color:#B7C1D6;margin-bottom:1px;}' + '.mkp-nav-item svg{flex:0 0 15px;width:15px;height:15px;opacity:.8;}' + '.mkp-nav-item.mkp-active,.mkp-nav-item.mkp-selected{background:#2E6BE6;color:#fff;}' + '.mkp-nav-item.mkp-active svg,.mkp-nav-item.mkp-selected svg{opacity:1;}' + '.mkp-nav-item.mkp-dim{color:#7C87A0;}' + '.mkp-nav-item:hover{background:#1d3554;color:#fff;cursor:pointer;}' + '.mkp-nav-tag{margin-left:auto;font-size:9.5px;font-weight:700;padding:1px 6px;border-radius:20px;white-space:nowrap;}' + '.mkp-tag-count{background:#1B2C46;color:#8FB4FF;}' + '.mkp-nav-item.mkp-selected .mkp-tag-count{background:rgba(255,255,255,.22);color:#fff;}' + '.mkp-tag-child{background:#1B2C46;color:#7C87A0;}' + '.mkp-tag-erp{background:transparent;color:#5A6685;font-weight:600;}' + '.mkp-content{flex:1;min-width:0;}' + '.mkp-hero{background:linear-gradient(115deg,#E7EEFF 0%,#DCE9FF 42%,#E4F3EA 100%);border-radius:14px;padding:24px 26px;margin-bottom:18px;border:1px solid #DCE4F5;}' + '.mkp-hero h1{font-size:21px;font-weight:800;margin:0 0 6px;color:#12182B;}' + '.mkp-hero p{margin:0;font-size:13px;color:#3E4A63;}' + '.mkp-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;}' + '.mkp-stat-card{background:#fff;border:1px solid #E7EAF1;border-radius:12px;padding:16px;}' + '.mkp-stat-label{font-size:11.5px;color:#5B6478;font-weight:500;margin-bottom:10px;}' + '.mkp-stat-value{font-size:23px;font-weight:800;color:#12182B;}' + '@media(max-width:1100px){.mkp-stats{grid-template-columns:repeat(2,1fr);}}' + '@media(max-width:800px){.mkp-page{flex-direction:column;}.mkp-sidebar{width:100%;position:static;max-height:none;}}' + '.mkp-loading{padding:60px 20px;text-align:center;color:#69748b;font-size:14px;}' + '.mkp-right-view{max-width:1100px;}' + '.mkp-eyebrow{margin:0 0 4px;font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:#8B93A8;font-weight:600;}' + '.mkp-right-head{display:flex;justify-content:space-between;align-items:end;margin-bottom:18px;gap:12px;flex-wrap:wrap;}' + '.mkp-right-head h1{margin:0 0 4px;font-size:22px;color:#12182B;}' + '.mkp-right-head p{margin:0;color:#69748b;font-size:13px;}' + '.mkp-btn{border:1px solid #dfe4ed;background:#fff;border-radius:8px;padding:8px 13px;font-weight:600;font-size:12.5px;cursor:pointer;color:#26324b;}' + '.mkp-btn-primary{background:#2e6be6;border-color:#2e6be6;color:#fff;}' + '.mkp-btn-danger{background:#fff;border-color:#f3c6cf;color:#c23f60;}' + '.mkp-btn-danger:hover{background:#fff0f2;}' + '.mkp-icon-btn{border:none;background:transparent;cursor:pointer;font-size:13px;padding:4px 8px;border-radius:6px;opacity:.7;}' + '.mkp-icon-btn:hover{opacity:1;background:#fff0f2;}' + '.mkp-actions{display:flex;gap:8px;margin-bottom:14px;flex-wrap:wrap;}' + '.mkp-table{width:100%;border-collapse:collapse;background:#fff;border:1px solid #e7eaf1;border-radius:10px;overflow:hidden;font-size:12.5px;}' + '.mkp-table th{text-align:left;text-transform:uppercase;font-size:9.5px;letter-spacing:.07em;color:#7d879a;padding:12px;border-bottom:1px solid #e7eaf1;white-space:nowrap;}' + '.mkp-table td{padding:12px;border-bottom:1px solid #f0f2f6;white-space:nowrap;}' + '.mkp-table tr:hover{background:#f8faff;}' + '.mkp-link{color:#2e6be6;font-weight:700;cursor:pointer;}' + '.mkp-customer-summary{display:grid;grid-template-columns:repeat(5,1fr);gap:10px;margin-bottom:14px;}' + '@media(max-width:900px){.mkp-customer-summary{grid-template-columns:repeat(3,1fr);}}' + '@media(max-width:600px){.mkp-customer-summary{grid-template-columns:repeat(2,1fr);}}' + '.mkp-customer-card{background:#fff;border:1px solid #e7eaf1;border-radius:10px;padding:12px 14px;cursor:pointer;}' + '.mkp-customer-card.mkp-active{border-color:#2e6be6;box-shadow:0 0 0 2px #dbe6ff;}' + '.mkp-customer-card small{display:block;color:#707b91;font-size:10.5px;margin-bottom:6px;}' + '.mkp-customer-card strong{font-size:21px;letter-spacing:-.03em;color:#12182B;}' + '.mkp-toolbar{background:#fff;border:1px solid #e7eaf1;border-radius:10px;padding:10px;display:flex;gap:8px;margin-bottom:12px;flex-wrap:wrap;}' + '.mkp-toolbar input,.mkp-toolbar select{border:1px solid #dfe4ed;border-radius:7px;padding:8px 10px;font:inherit;font-size:12.5px;background:#fff;}' + '.mkp-toolbar input{flex:1;min-width:180px;}' + '.mkp-status{padding:4px 9px;border-radius:20px;font-size:10.5px;font-weight:700;background:#eaf8f0;color:#1f8a5c;}' + '.mkp-status-off{background:#fff0f2;color:#c23f60;}' + '.mkp-customer-profile{display:grid;grid-template-columns:repeat(2,1fr);gap:12px;margin-top:18px;}' + '@media(max-width:600px){.mkp-customer-profile{grid-template-columns:1fr;}}' + '.mkp-customer-profile div{background:#f7f9fc;border-radius:8px;padding:11px;}' + '.mkp-customer-profile small{display:block;color:#7d879a;text-transform:uppercase;letter-spacing:.06em;font-size:9.5px;margin-bottom:4px;}' + '.mkp-customer-profile span{font-size:12.5px;color:#12182B;}' + '.mkp-back-btn{margin-bottom:14px;}'; var style = document.createElement('style'); style.id = 'mkp-portal-style'; style.textContent = css; document.head.appendChild(style); }