1<!doctype html> 2<html lang="en"> 3 <head> 4 <meta charset="UTF-8" /> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 6 <title>Oink AI Job Search â Explained Matches in Telegram</title> 7 <meta 8 name="description" 9 content="Oink is an AI job search assistant that checks fresh roles, scores them against your profile, and sends explained matches to Telegram." 10 /> 11 <link rel="canonical" href="https://oinkjobsearch.com/" /> 12 <meta name="theme-color" content="#f4f0e7" /> 13 <meta name="facebook-domain-verification" content="undpqz9uo35y8h5ol430ivqisbyg4p" /> 14 <link rel="icon" type="image/webp" href="/assets/pig-oink-112-v1.webp" /> 15 16 <!-- Open Graph --> 17 <meta property="og:type" content="website" /> 18 <meta property="og:site_name" content="Oink" /> 19 <meta property="og:title" content="Oink AI Job Search â Explained Matches in Telegram" /> 20 <meta 21 property="og:description" 22 content="Oink is an AI job search assistant that checks fresh roles, scores them against your profile, and sends explained matches to Telegram." 23 /> 24 <meta property="og:url" content="https://oinkjobsearch.com/" /> 25 <meta property="og:image" content="https://oinkjobsearch.com/assets/oink-social-premium-v1.jpg" /> 26 <meta property="og:image:type" content="image/jpeg" /> 27 <meta property="og:image:width" content="1200" /> 28 <meta property="og:image:height" content="630" /> 29 <meta property="og:image:alt" content="An explained Oink job match shown inside Telegram." /> 30 31 <!-- Twitter --> 32 <meta name="twitter:card" content="summary_large_image" /> 33 <meta name="twitter:title" content="Oink AI Job Search â Explained Matches in Telegram" /> 34 <meta 35 name="twitter:description" 36 content="Oink is an AI job search assistant that checks fresh roles, scores them against your profile, and sends explained matches to Telegram." 37 /> 38 <meta name="twitter:image" content="https://oinkjobsearch.com/assets/oink-social-premium-v1.jpg" /> 39 <meta name="twitter:image:alt" content="An explained Oink job match shown inside Telegram." /> 40 41 <!-- prices: this file is static, so it cannot import src/pricing.js. Keep the 42 numbers below equal to the weekly/monthly constants and TRIAL_DAYS there; 43 src/__tests__/pricing.test.js fails if they drift apart. --> 44
44<script type="application/ld+json"> 45 { 46 "@context": "https://schema.org", 47 "@graph": [ 48 { 49 "@type": "Organization", 50 "@id": "https://oinkjobsearch.com/#organization", 51 "name": "Oink", 52 "url": "https://oinkjobsearch.com/", 53 "logo": { 54 "@type": "ImageObject", 55 "url": "https://oinkjobsearch.com/assets/pig-oink-112-v1.webp", 56 "width": 112, 57 "height": 112 58 } 59 }, 60 { 61 "@type": "WebSite", 62 "@id": "https://oinkjobsearch.com/#website", 63 "name": "Oink", 64 "url": "https://oinkjobsearch.com/", 65 "description": "AI job search assistant with explained job matches in Telegram.", 66 "publisher": { "@id": "https://oinkjobsearch.com/#organization" } 67 }, 68 { 69 "@type": "WebApplication", 70 "@id": "https://oinkjobsearch.com/#application", 71 "name": "Oink AI Job Search", 72 "url": "https://oinkjobsearch.com/", 73 "description": "Oink checks fresh roles, scores them against your profile, and sends explained matches to Telegram.", 74 "applicationCategory": "BusinessApplication", 75 "publisher": { "@id": "https://oinkjobsearch.com/#organization" }, 76 "offers": [ 77 { "@type": "Offer", "name": "Weekly subscription", "price": "3", "priceCurrency": "EUR" }, 78 { "@type": "Offer", "name": "Monthly subscription", "price": "10", "priceCurrency": "EUR" } 79 ] 80 } 81 ] 82 } 83 </script>
83 84 85 <!-- Firebase also serves this build on its default *.web.app domain, which 86 Google indexes. `web.app` is a public suffix, so that origin is 87 cross-SITE from api.oinkjobsearch.com and the SameSite=Lax session 88 cookie is never sent back: every request 401s, the SPA re-mints a 89 guest, and sign-in is impossible. Bounce to the canonical origin 90 before the bundle boots. --> 91
91<script> 92 if (location.host.endsWith('.web.app')) 93 location.replace('https://oinkjobsearch.com' + location.pathname + location.search + location.hash); 94 </script>
94 95 96 <link rel="preconnect" href="https://fonts.googleapis.com"> 97 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> 98 <link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap"> 99 <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet" media="print" onload="this.media='all'"> 100 <noscript><link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet"></noscript> 101 102 <!-- Crawlable/no-JS fallback for the Atlas19 production landing. 103 The React entry removes this node as soon as it selects a screen. --> 104 <style> 105 #hero-static { 106 background: #0b4b38; 107 color: #f4e8cf; 108 font-family: var(--sans, 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif); 109 padding: clamp(28px, 8vw, 64px) clamp(16px, 5vw, 32px) clamp(32px, 6vw, 56px); 110 border-bottom: 1px solid #063829; 111 } 112 #hero-static .hero-inner { max-width: 640px; margin: 0 auto; } 113 #hero-static .hero-kicker { 114 margin: 0; 115 font-family: var(--sans, 'Inter', system-ui, sans-serif); 116 font-size: 12px; 117 text-transform: uppercase; 118 letter-spacing: 0.12em; 119 color: #f4e8cf; 120 } 121 #hero-static h1 { 122 margin: 12px 0 0; 123 font-family: var(--sans, 'Inter', system-ui, sans-serif); 124 font-weight: 700; 125 font-size: clamp(41px, 7vw, 72px); 126 line-height: 1.05; 127 letter-spacing: -0.055em; 128 } 129 #hero-static h1 em { font-family: Georgia, 'Times New Roman', serif; font-weight: 400; } 130 #hero-static .hero-sub { 131 margin: 16px 0 0; 132 font-size: clamp(15px, 2.4vw, 18px); 133 line-height: 1.55; 134 color: #c2cdb3; 135 max-width: 54ch; 136 } 137 #hero-static .hero-price { 138 margin: 20px 0 0; 139 font-family: var(--sans, 'Inter', system-ui, sans-serif); 140 font-size: 14px; 141 color: #c2cdb3; 142 } 143 #hero-static .hero-cta { margin-top: 20px; display: flex; flex-wrap: wrap; gap: 12px; } 144 #hero-static .hero-links { margin: 18px 0 0; display: flex; flex-wrap: wrap; gap: 8px 18px; font-size: 13px; } 145 #hero-static .hero-links a { color: #f4e8cf; text-underline-offset: 3px; } 146 #hero-static .hero-btn { 147 display: inline-flex; 148 align-items: center; 149 justify-content: center; 150 padding: 12px 22px; 151 border-radius: 2px; 152 font-family: var(--sans, 'Inter', sans-serif); 153 font-size: 14.5px; 154 font-weight: 600; 155 text-decoration: none; 156 border: 1px solid transparent; 157 } 158 #hero-static .hero-btn--primary { background: #f4e8cf; color: #0b4b38; } 159 #hero-static .hero-btn--primary:hover { filter: brightness(1.06); } 160 #hero-static .hero-btn--secondary { border-color: #f4e8cf; color: #f4e8cf; background: transparent; } 161 #hero-static .hero-btn--secondary:hover { background: #063829; } 162 #hero-static .hero-btn:focus-visible { outline: 2px solid #e83a20; outline-offset: 2px; } 163 #hero-static .hero-brand { display: flex; align-items: center; gap: 8px; margin: 0 0 22px; } 164 #hero-static .hero-brand img { width: 28px; height: 28px; object-fit: contain; } 165 #hero-static .hero-brand span { 166 font-family: var(--sans, 'Inter', system-ui, sans-serif); 167 font-size: 16px; 168 font-weight: 600; 169 color: #f4e8cf; 170 } 171 </style> 172
172<script type="module" crossorigin src="/assets/index-ZWiq2ivA.js"></script>
172 173 <link rel="stylesheet" crossorigin href="/assets/index-z4U-uTZu.css"> 174 <meta name="google-site-verification" content="i9F1ztuOfRcUYMAPPolBq-im445Td-MxaySiazt2_DI"> 175 </head> 176 <body data-design="atlas"> 177 <div id="hero-static"> 178 <div class="hero-inner"> 179 <div class="hero-brand"> 180 <img src="/assets/pig-oink-112-v1.webp" alt="" width="28" height="28" /> 181 <span>oink.</span> 182 </div> 183 <p class="hero-kicker">FIND YOUR NEXT ROLE</p> 184 <h1>Relevant jobs.<br /><em>In your messenger. Everyday.</em></h1> 185 <p class="hero-sub"> 186 Oink checks fresh roles against your CV and preferences and brings explained matches to Telegram. 187 See why a job fits, where it falls short, and whether it deserves your time. 188 </p> 189 <div class="hero-cta"> 190 <a data-oink-telegram-link href="https://t.me/job_search_everyday_bot?start=web_morning_brief" target="_blank" rel="noopener noreferrer" class="hero-btn hero-btn--primary">Try Oink in Telegram</a> 191 <a href="/articles/" class="hero-btn hero-btn--secondary">Read AI job-search guides</a> 192 </div> 193 <p class="hero-price">3 days free, then â¬3/week or â¬10/month</p> 194 <nav class="hero-links" aria-label="Explore Oink"> 195 <a href="/how-it-works/">How Oink works</a> 196 <a href="/job-sources/">Job sources</a> 197 <a href="/ai-job-matching/">AI matching</a> 198 <a href="/telegram-job-alerts/">Telegram alerts</a> 199 <a href="/about/">About</a> 200 </nav> 201 202 </div> 203 </div> 204 <!-- Returning signed-in visitors should not flash the anonymous fallback
205 while the application bundle loads. Storage can be unavailable 206 in hardened/private browsers, so this hint is deliberately guarded. --> 207
207<script> 208 try { 209 // Vite injects the canonical contract so this works before the app 210 // bundle arrives, without maintaining a separate source vocabulary. 211 const acquisitionContract = {"schemaVersion":2,"sourcePattern":"^[a-z0-9][a-z0-9_-]{0,59}$","telegramPrefix":"src_","defaultSource":"web_morning_brief","reservedSources":["unattributed"],"legacyPayloads":{"web_morning_brief":"web_morning_brief","ig":"instagram","ap":"apify"}}; 212 const source = (new URLSearchParams(window.location.search).get('s') || '').toLowerCase(); 213 const pattern = new RegExp(acquisitionContract.sourcePattern); 214 if (source && pattern.exec(source)?.[0] === source && !acquisitionContract.reservedSources.includes(source)) { 215 const payload = Object.hasOwn(acquisitionContract.legacyPayloads, source) 216 ? source : acquisitionContract.telegramPrefix + source; 217 document.querySelectorAll('[data-oink-telegram-link]').forEach((link) => { 218 link.href = `https://t.me/job_search_everyday_bot?start=${encodeURIComponent(payload)}`; 219 }); 220 } 221 } catch (e) {} 222 try { 223 if (localStorage.getItem('oink_hero_hidden')) document.getElementById('hero-static').hidden = true; 224 } catch (e) {} 225 </script>
225 226 <div id="root"></div> 227 </body> 228</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.