Last active
June 14, 2026 20:17
-
-
Save devbeno/dec2b5b1a039cded6033b2dbdc5a1ad0 to your computer and use it in GitHub Desktop.
Ajti
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="bs"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0,viewport-fit=cover"> | |
| <title>AjTi 27 — IT Strategy & AI</title> | |
| <meta name="description" content="AjTi 27. Vaš IT, doveden u red. Strategija, AI, sigurnost i operacije za sljedeću eru."> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet"> | |
| <style> | |
| :root{ | |
| --bg:#000; | |
| --bg-2:#0A0A0C; | |
| --paper:#F5F5F7; | |
| --paper-2:#FAFAFB; | |
| --ink:#1D1D1F; | |
| --ink-2:#424245; | |
| --muted:#86868B; | |
| --accent:#0095FF; /* Apple system blue */ | |
| --accent-2:#5856D6; /* Apple purple */ | |
| --good:#34C759; | |
| --warn:#FF9F0A; | |
| --crit:#FF3B30; | |
| --line:rgba(0,0,0,.08); | |
| --line-dark:rgba(255,255,255,.1); | |
| --sans:'Inter','SF Pro Display',-apple-system,BlinkMacSystemFont,system-ui,sans-serif; | |
| --mono:'IBM Plex Mono','SF Mono',ui-monospace,monospace; | |
| } | |
| *{margin:0;padding:0;box-sizing:border-box} | |
| html{scroll-behavior:smooth} | |
| body{background:var(--bg);color:var(--paper);font-family:var(--sans);font-size:17px;line-height:1.47; | |
| -webkit-font-smoothing:antialiased;overflow-x:hidden;font-feature-settings:"ss01","cv01"} | |
| ::selection{background:var(--accent);color:#fff} | |
| a{color:inherit;text-decoration:none} | |
| img{max-width:100%;display:block} | |
| .wrap{max-width:1100px;margin:0 auto;padding:0 22px} | |
| .wrap-wide{max-width:1440px;margin:0 auto;padding:0 22px} | |
| /* ==================== NAV (Apple-style: glass pill + separate CTA) ==================== */ | |
| .navwrap{position:fixed;top:16px;left:0;right:0;z-index:100;display:flex;justify-content:center;align-items:center; | |
| gap:10px;padding:0 16px;pointer-events:none} | |
| .navwrap > *{pointer-events:auto} | |
| nav{display:flex;align-items:center;gap:2px;padding:6px 8px; | |
| background:rgba(22,24,32,.55);backdrop-filter:blur(40px) saturate(1.8);-webkit-backdrop-filter:blur(40px) saturate(1.8); | |
| border:1px solid rgba(255,255,255,.08);border-radius:999px; | |
| box-shadow:0 12px 36px -10px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.08); | |
| font-size:13px} | |
| .logo{font-weight:680;letter-spacing:-.01em;font-size:15px;color:#fff;padding:8px 14px 8px 16px; | |
| border-right:1px solid rgba(255,255,255,.08);margin-right:6px} | |
| .logo i{font-style:normal;color:var(--accent);font-weight:680} | |
| nav .lnk{color:rgba(245,245,247,.78);padding:9px 14px;border-radius:999px;transition:color .2s,background .2s;font-weight:480;letter-spacing:-.005em} | |
| nav .lnk:hover{color:#fff;background:rgba(255,255,255,.07)} | |
| .cta{background:#fff;color:#000;padding:11px 20px;border-radius:999px;font-weight:560;transition:.2s;font-size:13.5px; | |
| box-shadow:0 12px 36px -10px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.6); | |
| border:1px solid rgba(255,255,255,.7);letter-spacing:-.005em} | |
| .cta:hover{background:var(--accent);color:#fff;border-color:transparent} | |
| @media(max-width:680px){nav .lnk{display:none}.logo{border-right:none;margin-right:0}} | |
| /* ==================== HERO ==================== */ | |
| .hero{position:relative;min-height:100vh;min-height:100dvh;display:flex;flex-direction:column;align-items:center; | |
| justify-content:center;padding:120px 22px 60px;text-align:center;overflow:hidden; | |
| background:radial-gradient(ellipse 80% 60% at 50% 30%, #1A1F3A 0%, #050610 60%, #000 100%)} | |
| .hero canvas{position:absolute;inset:0;width:100%;height:100%;z-index:0;opacity:.85} | |
| .hero-grain{position:absolute;inset:0;z-index:1;opacity:.5;pointer-events:none; | |
| background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence baseFrequency='0.85' numOctaves='3'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.06 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")} | |
| .hero-inner{position:relative;z-index:2;max-width:920px;display:flex;flex-direction:column;align-items:center} | |
| .eyebrow{font-family:var(--mono);font-size:12px;letter-spacing:.18em;text-transform:uppercase; | |
| color:var(--accent);margin-bottom:24px;font-weight:500} | |
| .hero h1{font-size:clamp(40px,7.4vw,96px);font-weight:700;letter-spacing:-.04em;line-height:1.04;color:#fff;margin-bottom:14px} | |
| .hero h1 .sub{display:block;font-size:.5em;font-weight:600;color:var(--muted);margin-top:6px;letter-spacing:-.02em;line-height:1.1} | |
| .hero h1 .grad{background:linear-gradient(120deg,#5DC9FF 0%,#A78BFA 50%,#FF9FF3 100%); | |
| -webkit-background-clip:text;background-clip:text;color:transparent;display:inline-block;padding-bottom:.05em} | |
| .hero p.lead{font-size:clamp(16px,1.3vw,19px);color:rgba(245,245,247,.72);max-width:46ch;margin:18px auto 28px;font-weight:380;line-height:1.5} | |
| .hero-cta{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin-bottom:28px} | |
| .btn{display:inline-flex;align-items:center;gap:8px;padding:13px 26px;border-radius:999px;font-weight:560;font-size:14.5px;transition:.2s;letter-spacing:-.005em} | |
| .btn-primary{background:#fff;color:#000;box-shadow:0 8px 24px -10px rgba(255,255,255,.3)} | |
| .btn-primary:hover{background:var(--accent);color:#fff;transform:translateY(-1px)} | |
| .btn-ghost{color:#fff;border:1px solid rgba(255,255,255,.22);background:rgba(255,255,255,.04)} | |
| .btn-ghost:hover{background:rgba(255,255,255,.12)} | |
| .btn-arrow{font-family:var(--mono);font-size:14px;opacity:.7} | |
| /* glass chip strip below hero copy */ | |
| .chips{display:flex;gap:6px;justify-content:center;flex-wrap:wrap} | |
| .chip{padding:7px 14px;background:rgba(255,255,255,.05);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px); | |
| border:1px solid rgba(255,255,255,.1);border-radius:999px;font-size:12.5px;color:rgba(245,245,247,.82);font-weight:460; | |
| display:inline-flex;align-items:center;gap:7px;letter-spacing:-.005em} | |
| .chip .dot{width:6px;height:6px;border-radius:50%;background:var(--accent);box-shadow:0 0 8px var(--accent)} | |
| .chip:nth-child(2) .dot{background:var(--accent-2);box-shadow:0 0 8px var(--accent-2)} | |
| .chip:nth-child(3) .dot{background:var(--good);box-shadow:0 0 8px var(--good)} | |
| .chip:nth-child(4) .dot{background:var(--warn);box-shadow:0 0 8px var(--warn)} | |
| /* ==================== HIGHLIGHTS GALLERY (horizontal cards) ==================== */ | |
| .highlights{padding:120px 0 80px;background:#000} | |
| .section-head{text-align:center;max-width:780px;margin:0 auto 64px;padding:0 22px} | |
| .section-head h2{font-size:clamp(34px,5vw,64px);font-weight:700;letter-spacing:-.035em;line-height:1.06;color:#fff;margin-bottom:14px} | |
| .section-head h2 em{font-style:normal;color:var(--muted);display:block;font-weight:600} | |
| .section-head p{color:var(--muted);font-size:clamp(15px,1.3vw,19px);max-width:54ch;margin:0 auto;font-weight:380} | |
| .h-gallery{display:flex;gap:22px;overflow-x:auto;scroll-snap-type:x mandatory;padding:0 max(22px,calc(50vw - 550px)) 60px; | |
| scrollbar-width:none} | |
| .h-gallery::-webkit-scrollbar{display:none} | |
| .h-card{flex:0 0 460px;scroll-snap-align:start;border-radius:24px;overflow:hidden;position:relative; | |
| height:580px;display:flex;flex-direction:column;justify-content:flex-end;padding:36px 32px; | |
| background:linear-gradient(180deg,#161821 0%,#0C0E16 100%);border:1px solid rgba(255,255,255,.08)} | |
| .h-card .visual{position:absolute;inset:0;z-index:0} | |
| .h-card .visual canvas{width:100%;height:100%;display:block} | |
| .h-card .copy{position:relative;z-index:2} | |
| .h-card .num{font-family:var(--mono);font-size:12px;color:var(--accent);letter-spacing:.14em;margin-bottom:12px;font-weight:500} | |
| .h-card h3{font-size:30px;font-weight:680;letter-spacing:-.025em;color:#fff;line-height:1.1;margin-bottom:10px} | |
| .h-card p{color:rgba(245,245,247,.7);font-size:15.5px;font-weight:380;line-height:1.5} | |
| .h-card.amber{background:linear-gradient(180deg,#3A1F0A 0%,#1A0F08 100%)} | |
| .h-card.amber .num{color:#FFB347} | |
| .h-card.purple{background:linear-gradient(180deg,#2A1A4A 0%,#0F0820 100%)} | |
| .h-card.purple .num{color:#B197FC} | |
| .h-card.green{background:linear-gradient(180deg,#0F2A1A 0%,#06150C 100%)} | |
| .h-card.green .num{color:#5BE584} | |
| @media(max-width:560px){.h-card{flex:0 0 calc(100vw - 60px);height:520px;padding:28px 24px}.h-card h3{font-size:26px}} | |
| /* ==================== FEATURE BAND (alternating big sections like Apple) ==================== */ | |
| .band{padding:100px 0;background:#000;position:relative;overflow:hidden} | |
| .band-light{background:var(--paper);color:var(--ink)} | |
| .band-light .section-head h2{color:var(--ink)} | |
| .band-light .section-head h2 em{color:var(--muted)} | |
| .band-light .section-head p{color:var(--ink-2)} | |
| .feature{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:60px;align-items:center; | |
| padding:60px 0;border-bottom:1px solid rgba(255,255,255,.06)} | |
| .band-light .feature{border-color:var(--line)} | |
| .feature:last-child{border-bottom:none} | |
| .feature.reverse{direction:rtl} | |
| .feature.reverse > *{direction:ltr} | |
| .feature-copy h3{font-size:clamp(28px,3.4vw,44px);font-weight:680;letter-spacing:-.03em;line-height:1.1;margin-bottom:18px;color:#fff} | |
| .band-light .feature-copy h3{color:var(--ink)} | |
| .feature-copy p{font-size:17px;color:rgba(245,245,247,.7);line-height:1.55;font-weight:380;margin-bottom:14px} | |
| .band-light .feature-copy p{color:var(--ink-2)} | |
| .feature-copy .tag{font-family:var(--mono);font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--accent);margin-bottom:14px;font-weight:500} | |
| .feature-copy ul{list-style:none;margin-top:18px} | |
| .feature-copy li{padding:9px 0;font-size:14.5px;color:rgba(245,245,247,.65);display:flex;align-items:flex-start;gap:10px;border-top:1px solid rgba(255,255,255,.06)} | |
| .band-light .feature-copy li{color:var(--ink-2);border-color:var(--line)} | |
| .feature-copy li::before{content:"";width:5px;height:5px;border-radius:50%;background:var(--accent);margin-top:9px;flex:none} | |
| .feature-visual{aspect-ratio:1/1;border-radius:28px;overflow:hidden;position:relative; | |
| background:linear-gradient(135deg,#0C0E16 0%,#1A1F2E 100%);border:1px solid rgba(255,255,255,.08)} | |
| .band-light .feature-visual{background:linear-gradient(135deg,#fff 0%,#F0F0F2 100%);border:1px solid var(--line); | |
| box-shadow:0 30px 60px -30px rgba(0,0,0,.18)} | |
| .feature-visual canvas{width:100%;height:100%;display:block} | |
| @media(max-width:860px){.feature{grid-template-columns:1fr;gap:32px;padding:48px 0}.feature.reverse{direction:ltr}} | |
| /* ==================== LIQUID GLASS DEMO CARD (the apple-style centerpiece) ==================== */ | |
| .glass-demo{position:relative;padding:140px 22px;background:#000;overflow:hidden;text-align:center} | |
| .glass-demo .bg-art{position:absolute;inset:0;z-index:0; | |
| background: | |
| radial-gradient(circle at 20% 30%, rgba(0,149,255,.45) 0%, transparent 40%), | |
| radial-gradient(circle at 80% 70%, rgba(255,90,140,.4) 0%, transparent 40%), | |
| radial-gradient(circle at 60% 20%, rgba(120,255,200,.3) 0%, transparent 40%), | |
| radial-gradient(circle at 30% 80%, rgba(255,180,80,.35) 0%, transparent 40%), | |
| #0A0610} | |
| .glass-demo .bg-grain{position:absolute;inset:0;z-index:1;opacity:.4; | |
| background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence baseFrequency='0.9' numOctaves='3'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.08 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")} | |
| .glass-demo-inner{position:relative;z-index:2;max-width:900px;margin:0 auto} | |
| .glass-demo h2{font-size:clamp(36px,5vw,64px);font-weight:700;letter-spacing:-.035em;line-height:1.05;color:#fff;margin-bottom:18px} | |
| .glass-demo h2 em{font-style:normal;background:linear-gradient(120deg,#5DC9FF 0%,#A78BFA 100%); | |
| -webkit-background-clip:text;background-clip:text;color:transparent} | |
| .glass-demo p.lead{font-size:18px;color:rgba(245,245,247,.78);max-width:48ch;margin:0 auto 56px;font-weight:380} | |
| .glass-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:16px;max-width:680px;margin:0 auto} | |
| .glass-tile{aspect-ratio:1/1;border-radius:24px;padding:22px;display:flex;flex-direction:column;justify-content:space-between; | |
| background:rgba(255,255,255,.07);backdrop-filter:blur(24px) saturate(1.6);-webkit-backdrop-filter:blur(24px) saturate(1.6); | |
| border:1px solid rgba(255,255,255,.14);text-align:left; | |
| box-shadow:0 24px 60px -28px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.2)} | |
| .glass-tile .icon{width:42px;height:42px;border-radius:12px;background:rgba(255,255,255,.12);display:flex;align-items:center;justify-content:center; | |
| font-family:var(--mono);font-size:18px;font-weight:600;color:#fff} | |
| .glass-tile h4{font-size:20px;font-weight:660;letter-spacing:-.02em;color:#fff;margin-bottom:6px} | |
| .glass-tile p{font-size:13.5px;color:rgba(245,245,247,.7);font-weight:380;line-height:1.4} | |
| .glass-tile.t1 .icon{background:rgba(0,149,255,.3);color:#5DC9FF} | |
| .glass-tile.t2 .icon{background:rgba(167,139,250,.3);color:#C4A8FF} | |
| .glass-tile.t3 .icon{background:rgba(255,90,140,.3);color:#FFA0B8} | |
| .glass-tile.t4 .icon{background:rgba(120,255,200,.3);color:#88F5C5} | |
| @media(max-width:560px){.glass-grid{grid-template-columns:1fr}.glass-tile{aspect-ratio:auto;min-height:160px}} | |
| /* ==================== "DEVICES" SHOWCASE (like Apple compatibility) ==================== */ | |
| .compat{padding:120px 0;background:var(--paper);color:var(--ink)} | |
| .compat h2{font-size:clamp(30px,3.4vw,44px);font-weight:700;letter-spacing:-.03em;line-height:1.1;margin-bottom:36px;text-align:center} | |
| .compat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;max-width:920px;margin:0 auto} | |
| .compat-item{padding:18px;background:#fff;border-radius:16px;border:1px solid var(--line);font-size:14px;font-weight:480;color:var(--ink); | |
| display:flex;align-items:center;gap:10px;transition:.2s} | |
| .compat-item:hover{transform:translateY(-2px);box-shadow:0 14px 30px -16px rgba(0,0,0,.18)} | |
| .compat-item .dot{width:7px;height:7px;border-radius:50%;background:var(--good)} | |
| .compat-item.warn .dot{background:var(--warn)} | |
| /* ==================== CTA ==================== */ | |
| .final-cta{padding:140px 22px;text-align:center;background:#000;position:relative;overflow:hidden} | |
| .final-cta::before{content:"";position:absolute;inset:0; | |
| background:radial-gradient(ellipse 60% 50% at 50% 50%, rgba(0,149,255,.25) 0%, transparent 70%)} | |
| .final-cta-inner{position:relative;z-index:2} | |
| .final-cta h2{font-size:clamp(40px,6vw,84px);font-weight:700;letter-spacing:-.04em;line-height:1.02;color:#fff;margin-bottom:22px} | |
| .final-cta h2 em{font-style:normal;color:var(--accent)} | |
| .final-cta p{color:var(--muted);font-size:18px;margin-bottom:36px} | |
| /* ==================== FOOTER ==================== */ | |
| footer{background:#000;color:var(--muted);padding:60px 0 40px;font-size:12.5px;border-top:1px solid rgba(255,255,255,.06)} | |
| .foot-grid{display:grid;grid-template-columns:2fr repeat(3,1fr);gap:40px;margin-bottom:40px} | |
| .foot-grid h5{font-size:12px;font-weight:600;color:#fff;margin-bottom:14px;text-transform:uppercase;letter-spacing:.08em} | |
| .foot-grid li{list-style:none;padding:4px 0} | |
| .foot-grid a:hover{color:#fff} | |
| .foot-grid .brand{font-family:var(--sans);font-size:22px;font-weight:700;letter-spacing:-.02em;color:#fff;margin-bottom:14px} | |
| .foot-grid .brand i{font-style:normal;color:var(--accent)} | |
| .foot-bottom{padding-top:24px;border-top:1px solid rgba(255,255,255,.06);display:flex;justify-content:space-between;flex-wrap:wrap;gap:14px;font-size:11.5px} | |
| @media(max-width:760px){.foot-grid{grid-template-columns:1fr 1fr;gap:30px}} | |
| .reveal{opacity:0;transform:translateY(30px);transition:opacity .9s cubic-bezier(.23,1,.32,1),transform .9s cubic-bezier(.23,1,.32,1)} | |
| .reveal.in{opacity:1;transform:translateY(0)} | |
| @media(prefers-reduced-motion:reduce){.reveal{opacity:1;transform:none}} | |
| </style> | |
| </head> | |
| <body> | |
| <div class="navwrap"> | |
| <nav> | |
| <a class="logo" href="#">Aj<i>Ti</i>.</a> | |
| <a class="lnk" href="#highlights">Šta je novo</a> | |
| <a class="lnk" href="#features">Discipline</a> | |
| <a class="lnk" href="#kompatibilnost">Kompatibilnost</a> | |
| </nav> | |
| <a class="cta" href="#kontakt">Zakaži assessment</a> | |
| </div> | |
| <!-- ==================== HERO ==================== --> | |
| <header class="hero"> | |
| <canvas id="heroFx"></canvas> | |
| <div class="hero-grain"></div> | |
| <div class="hero-inner"> | |
| <div class="eyebrow reveal">AjTi 27 Preview</div> | |
| <h1 class="reveal">Predstavljamo<br><span class="grad">AjTi Intelligence.</span> | |
| <span class="sub">Vaš IT, doveden u red.</span></h1> | |
| <p class="lead reveal">AjTi 27 dolazi ove jeseni. Strategija, AI, sigurnost i operacije — u jednom sistemu.</p> | |
| <div class="hero-cta reveal"> | |
| <a class="btn btn-primary" href="#kontakt">Zatraži assessment</a> | |
| <a class="btn btn-ghost" href="#highlights">Pogledaj <span class="btn-arrow">↓</span></a> | |
| </div> | |
| <div class="chips reveal"> | |
| <span class="chip"><span class="dot"></span> IT Strategy</span> | |
| <span class="chip"><span class="dot"></span> AI Integration</span> | |
| <span class="chip"><span class="dot"></span> Cyber Security</span> | |
| <span class="chip"><span class="dot"></span> FinOps & Ops</span> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- ==================== HIGHLIGHTS ==================== --> | |
| <section class="highlights" id="highlights"> | |
| <div class="section-head reveal"> | |
| <div class="eyebrow" style="color:var(--accent);justify-content:center;display:flex">Šta je novo</div> | |
| <h2>Otkrijte šta donosi AjTi 27. <em>Četiri discipline, jedan plan.</em></h2> | |
| </div> | |
| <div class="h-gallery"> | |
| <div class="h-card reveal"> | |
| <div class="visual"><canvas data-fx="grid"></canvas></div> | |
| <div class="copy"> | |
| <div class="num">01 · STRATEGIJA</div> | |
| <h3>Snimak stanja, bez uljepšavanja.</h3> | |
| <p>Skeniramo cijeli IT estate — tehnički dug, sigurnosni rizik i AI potencijal dobiju cijenu i prioritet.</p> | |
| </div> | |
| </div> | |
| <div class="h-card purple reveal"> | |
| <div class="visual"><canvas data-fx="neural"></canvas></div> | |
| <div class="copy"> | |
| <div class="num">02 · AI</div> | |
| <h3>Inteligencija ugrađena u procese.</h3> | |
| <p>Ne samo chatbot. Data platforme, LLM agenti i automatizacija toka podataka — sa mjerljivim ROI-om.</p> | |
| </div> | |
| </div> | |
| <div class="h-card amber reveal"> | |
| <div class="visual"><canvas data-fx="shield"></canvas></div> | |
| <div class="copy"> | |
| <div class="num">03 · CYBER</div> | |
| <h3>Sigurnost koja se ne raspada pod stresom.</h3> | |
| <p>Zero Trust arhitektura, NIS2 i ISO 27001 usklađenost, pentest i incident response spremnost — od dana 1.</p> | |
| </div> | |
| </div> | |
| <div class="h-card green reveal"> | |
| <div class="visual"><canvas data-fx="ops"></canvas></div> | |
| <div class="copy"> | |
| <div class="num">04 · OPS</div> | |
| <h3>Manje troškova. Više snage.</h3> | |
| <p>FinOps disciplina gasi suvišno, SRE praksa drži 99.9% uptime. Cloud bill konačno ima smisla.</p> | |
| </div> | |
| </div> | |
| <div class="h-card reveal"> | |
| <div class="visual"><canvas data-fx="result"></canvas></div> | |
| <div class="copy"> | |
| <div class="num">05 · REZULTAT</div> | |
| <h3>OPEX −27%. Uptime 99.9%.</h3> | |
| <p>Prosječan AjTi engagement vraća se u bilans za 6 mjeseci. Mjerljivo, ne na slajdovima.</p> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- ==================== LIQUID GLASS CENTERPIECE ==================== --> | |
| <section class="glass-demo"> | |
| <div class="bg-art"></div> | |
| <div class="bg-grain"></div> | |
| <div class="glass-demo-inner"> | |
| <div class="eyebrow reveal">AjTi Intelligence</div> | |
| <h2 class="reveal">Jedan sistem. <em>Četiri sloja inteligencije.</em></h2> | |
| <p class="lead reveal">Discipline ne rade odvojeno. Strategija informiše AI, AI ojačava sigurnost, sigurnost štiti operacije. AjTi 27 ih spaja u jedno.</p> | |
| <div class="glass-grid"> | |
| <div class="glass-tile t1 reveal"> | |
| <div class="icon">⌘</div> | |
| <div> | |
| <h4>Strategija</h4> | |
| <p>Roadmap vezan za biznis ciljeve, ne za trendove.</p> | |
| </div> | |
| </div> | |
| <div class="glass-tile t2 reveal"> | |
| <div class="icon">∞</div> | |
| <div> | |
| <h4>AI agenti</h4> | |
| <p>Integrisani u Messages, Mail, ERP i CRM — rade za vas.</p> | |
| </div> | |
| </div> | |
| <div class="glass-tile t3 reveal"> | |
| <div class="icon">⚡</div> | |
| <div> | |
| <h4>Zero Trust</h4> | |
| <p>Niko nije pouzdan dok ne dokaže. NIS2 spreman.</p> | |
| </div> | |
| </div> | |
| <div class="glass-tile t4 reveal"> | |
| <div class="icon">↗</div> | |
| <div> | |
| <h4>FinOps</h4> | |
| <p>Cloud bill optimizovan. Svaki euro ima vlasnika.</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- ==================== FEATURE SECTIONS (alternating) ==================== --> | |
| <section class="band band-light" id="features"> | |
| <div class="section-head reveal"> | |
| <div class="eyebrow" style="justify-content:center;display:flex">Discipline</div> | |
| <h2>AjTi u apps. <em>Korisno na pravim mjestima.</em></h2> | |
| <p>Strategija, AI, sigurnost i operacije bešavno integrisani u svakodnevni rad vašeg tima.</p> | |
| </div> | |
| <div class="wrap"> | |
| <div class="feature reveal"> | |
| <div class="feature-copy"> | |
| <div class="tag">01 · IT Strategy & Architecture</div> | |
| <h3>Tehnologija usklađena s biznisom.</h3> | |
| <p>Enterprise arhitektura spremna za AI eru — ne preprodajemo trend, gradimo ono što vraća u bilans. Svaka inicijativa ima vlasnika, KPI i kriterij gašenja ako ne isporučuje.</p> | |
| <ul> | |
| <li>Tech debt assessment sa cjenovnikom rizika</li> | |
| <li>Target operating model i organizacioni dizajn</li> | |
| <li>Vendor & sourcing strategija</li> | |
| </ul> | |
| </div> | |
| <div class="feature-visual"><canvas data-fx="strategy"></canvas></div> | |
| </div> | |
| <div class="feature reverse reveal"> | |
| <div class="feature-copy"> | |
| <div class="tag">02 · AI Integration & Data Strategy</div> | |
| <h3>AI tamo gdje donosi vrijednost.</h3> | |
| <p>Data platforme, LLM integracije i automatizacija procesa — sve sa mjerljivim ROI-om. Pilot 90 dana; ako ne pomjeri metriku, gasi se. Tako portfolio ostaje čist od "AI teatra".</p> | |
| <ul> | |
| <li>Use-case portfolio sa ROI baseline-om</li> | |
| <li>LLM fine-tuning i agent arhitektura</li> | |
| <li>Data governance i ML observability</li> | |
| </ul> | |
| </div> | |
| <div class="feature-visual"><canvas data-fx="ai"></canvas></div> | |
| </div> | |
| <div class="feature reveal"> | |
| <div class="feature-copy"> | |
| <div class="tag">03 · Cyber Security Posture</div> | |
| <h3>Sigurnost ugrađena u kod.</h3> | |
| <p>DevSecOps mentalitet: kontrole žive u CI/CD-u, ne u Excel-u. Sigurnosna postura zasnovana na riziku, od assessmenta do incident response spremnosti.</p> | |
| <ul> | |
| <li>Zero Trust arhitektura i identitet</li> | |
| <li>NIS2 / ISO 27001 / DORA usklađenost</li> | |
| <li>Pentest, red teaming, incident response</li> | |
| </ul> | |
| </div> | |
| <div class="feature-visual"><canvas data-fx="cyber"></canvas></div> | |
| </div> | |
| <div class="feature reverse reveal"> | |
| <div class="feature-copy"> | |
| <div class="tag">04 · FinOps & Operations</div> | |
| <h3>Bilansna disciplina, operativna izvrsnost.</h3> | |
| <p>Cloud troškovi pod kontrolom, ITSM automatizovan, SRE praksa drži 99.9% uptime. Kvartalni pregled OPEX-a, performansi i sigurnosnih nalaza.</p> | |
| <ul> | |
| <li>Cloud FinOps i licencna optimizacija</li> | |
| <li>Platform engineering i developer experience</li> | |
| <li>SRE, observability, incident playbooks</li> | |
| </ul> | |
| </div> | |
| <div class="feature-visual"><canvas data-fx="ops2"></canvas></div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- ==================== COMPATIBILITY ==================== --> | |
| <section class="compat" id="kompatibilnost"> | |
| <div class="wrap"> | |
| <h2 class="reveal">AjTi 27 radi s tehnologijama koje već imate.</h2> | |
| <div class="compat-grid"> | |
| <div class="compat-item reveal"><span class="dot"></span> AWS · GCP · Azure</div> | |
| <div class="compat-item reveal"><span class="dot"></span> Kubernetes & Docker</div> | |
| <div class="compat-item reveal"><span class="dot"></span> SAP · Oracle · Dynamics</div> | |
| <div class="compat-item reveal"><span class="dot"></span> Salesforce · HubSpot</div> | |
| <div class="compat-item reveal"><span class="dot"></span> Snowflake · Databricks</div> | |
| <div class="compat-item reveal"><span class="dot"></span> OpenAI · Anthropic · Mistral</div> | |
| <div class="compat-item reveal"><span class="dot"></span> Terraform & Pulumi</div> | |
| <div class="compat-item reveal"><span class="dot"></span> GitHub · GitLab · Jira</div> | |
| <div class="compat-item reveal"><span class="dot"></span> Datadog · Grafana</div> | |
| <div class="compat-item reveal"><span class="dot"></span> Okta · Auth0 · Entra ID</div> | |
| <div class="compat-item reveal warn"><span class="dot"></span> Legacy mainframe · uz plan migracije</div> | |
| <div class="compat-item reveal warn"><span class="dot"></span> On-prem ERP · uz integraciju</div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- ==================== CTA ==================== --> | |
| <section class="final-cta" id="kontakt"> | |
| <div class="final-cta-inner"> | |
| <h2 class="reveal">Spremni za <em>sljedeću eru</em><br>vašeg IT-a?</h2> | |
| <p class="reveal">Besplatan uvodni assessment. Odgovor unutar 24h. Bez obaveza.</p> | |
| <a class="btn btn-primary reveal" href="mailto:hello@ajti.example">Započni razgovor</a> | |
| </div> | |
| </section> | |
| <footer> | |
| <div class="wrap"> | |
| <div class="foot-grid"> | |
| <div> | |
| <div class="brand">Aj<i>Ti</i>.</div> | |
| <p style="max-width:32ch">IT konsalting kuća iz Sarajeva. Strategija, AI, sigurnost, operacije — bez slajdova, sa rezultatima.</p> | |
| </div> | |
| <div> | |
| <h5>Discipline</h5> | |
| <ul> | |
| <li><a href="#features">IT Strategy</a></li> | |
| <li><a href="#features">AI Integration</a></li> | |
| <li><a href="#features">Cyber Security</a></li> | |
| <li><a href="#features">FinOps & Ops</a></li> | |
| </ul> | |
| </div> | |
| <div> | |
| <h5>Firma</h5> | |
| <ul> | |
| <li><a href="#">O nama</a></li> | |
| <li><a href="#">Pristup</a></li> | |
| <li><a href="#">Karijere</a></li> | |
| <li><a href="#kontakt">Kontakt</a></li> | |
| </ul> | |
| </div> | |
| <div> | |
| <h5>Pravno</h5> | |
| <ul> | |
| <li><a href="#">Privacy</a></li> | |
| <li><a href="#">Uslovi</a></li> | |
| <li><a href="#">GDPR</a></li> | |
| <li><a href="#">NDA template</a></li> | |
| </ul> | |
| </div> | |
| </div> | |
| <div class="foot-bottom"> | |
| <span>© 2026 AjTi d.o.o. — Sve karakteristike podložne promjenama.</span> | |
| <span>Sarajevo, Bosna i Hercegovina</span> | |
| </div> | |
| </div> | |
| </footer> | |
| <script> | |
| /* ============ Reveal on scroll ============ */ | |
| const io = new IntersectionObserver((entries)=>{ | |
| entries.forEach(e=>{ if(e.isIntersecting){ e.target.classList.add('in'); io.unobserve(e.target); } }); | |
| },{threshold:.12,rootMargin:'0px 0px -40px 0px'}); | |
| document.querySelectorAll('.reveal').forEach(el=>io.observe(el)); | |
| /* ============ Hero background canvas: aurora orbs ============ */ | |
| (function hero(){ | |
| const c = document.getElementById('heroFx'); if(!c) return; | |
| const ctx = c.getContext('2d'); | |
| let w,h,dpr; | |
| function size(){ dpr=Math.min(devicePixelRatio,2); w=c.width=innerWidth*dpr; h=c.height=c.parentElement.offsetHeight*dpr; | |
| c.style.width=innerWidth+'px'; c.style.height=c.parentElement.offsetHeight+'px'; } | |
| size(); addEventListener('resize',size); | |
| const orbs = [ | |
| {x:.22,y:.35,r:.45,col:[93,201,255]}, | |
| {x:.78,y:.55,r:.40,col:[167,139,250]}, | |
| {x:.50,y:.78,r:.50,col:[255,159,243]}, | |
| {x:.65,y:.20,r:.35,col:[120,220,200]}, | |
| ]; | |
| function frame(t){ | |
| ctx.clearRect(0,0,w,h); | |
| ctx.globalCompositeOperation='lighter'; | |
| orbs.forEach((o,i)=>{ | |
| const ph = t*.0003 + i*1.7; | |
| const x = (o.x + Math.sin(ph)*.05) * w; | |
| const y = (o.y + Math.cos(ph*1.3)*.05) * h; | |
| const r = o.r * Math.min(w,h) * (1 + Math.sin(ph*2)*.06); | |
| const g = ctx.createRadialGradient(x,y,0,x,y,r); | |
| g.addColorStop(0, `rgba(${o.col[0]},${o.col[1]},${o.col[2]},0.55)`); | |
| g.addColorStop(.5, `rgba(${o.col[0]},${o.col[1]},${o.col[2]},0.18)`); | |
| g.addColorStop(1, `rgba(${o.col[0]},${o.col[1]},${o.col[2]},0)`); | |
| ctx.fillStyle = g; | |
| ctx.fillRect(0,0,w,h); | |
| }); | |
| ctx.globalCompositeOperation='source-over'; | |
| requestAnimationFrame(frame); | |
| } | |
| if(!matchMedia('(prefers-reduced-motion: reduce)').matches) requestAnimationFrame(frame); | |
| else frame(0); | |
| })(); | |
| /* ============ Highlight card visuals ============ */ | |
| function cardCanvas(canvas, kind){ | |
| const ctx = canvas.getContext('2d'); | |
| let w,h; | |
| function size(){ const r = canvas.getBoundingClientRect(); | |
| const dpr=Math.min(devicePixelRatio,2); | |
| w = canvas.width = r.width*dpr; h = canvas.height = r.height*dpr; | |
| canvas.style.width=r.width+'px'; canvas.style.height=r.height+'px'; | |
| } | |
| size(); new ResizeObserver(size).observe(canvas); | |
| const reduced = matchMedia('(prefers-reduced-motion: reduce)').matches; | |
| function frame(t){ | |
| ctx.clearRect(0,0,w,h); | |
| if(kind==='grid'){ | |
| // strategy: glowing isometric grid that pulses | |
| ctx.strokeStyle = 'rgba(93,201,255,.32)'; | |
| ctx.lineWidth = 1*Math.min(devicePixelRatio,2); | |
| const cell = w/10; | |
| for(let i=0;i<14;i++){ | |
| for(let j=0;j<14;j++){ | |
| const x = i*cell - cell*2; | |
| const y = j*cell - cell*2; | |
| const pulse = (Math.sin(t*.001 + (i+j)*.4) +1)*.5; | |
| ctx.globalAlpha = .15 + pulse*.45; | |
| ctx.beginPath(); ctx.rect(x,y,cell*.78,cell*.78); ctx.stroke(); | |
| if(pulse>.85){ | |
| ctx.fillStyle='rgba(93,201,255,'+pulse*.5+')'; | |
| ctx.fillRect(x+cell*.18,y+cell*.18, cell*.42, cell*.42); | |
| } | |
| } | |
| } | |
| ctx.globalAlpha=1; | |
| } | |
| if(kind==='neural'){ | |
| // AI: animated neural network with flowing connections | |
| const layers = [4, 6, 6, 4]; | |
| const nodes = []; | |
| const padX = w*.2; | |
| const span = w - padX*2; | |
| layers.forEach((n, li)=>{ | |
| const x = padX + (li/(layers.length-1))*span; | |
| for(let i=0;i<n;i++){ | |
| const y = (h/(n+1))*(i+1); | |
| nodes.push({x,y,li,i}); | |
| } | |
| }); | |
| // connections | |
| ctx.lineWidth = 1*Math.min(devicePixelRatio,2); | |
| for(let li=0;li<layers.length-1;li++){ | |
| const a = nodes.filter(n=>n.li===li); | |
| const b = nodes.filter(n=>n.li===li+1); | |
| a.forEach(na=>b.forEach(nb=>{ | |
| const pulse = (Math.sin(t*.002 + na.i + nb.i*1.7 + li)+1)*.5; | |
| ctx.strokeStyle = `rgba(177,151,252,${.08 + pulse*.25})`; | |
| ctx.beginPath(); ctx.moveTo(na.x,na.y); ctx.lineTo(nb.x,nb.y); ctx.stroke(); | |
| })); | |
| } | |
| // nodes | |
| nodes.forEach(n=>{ | |
| const pulse = (Math.sin(t*.003 + n.i*1.3 + n.li)+1)*.5; | |
| ctx.fillStyle = `rgba(177,151,252,${.5 + pulse*.5})`; | |
| ctx.beginPath(); ctx.arc(n.x, n.y, 4+pulse*3, 0, Math.PI*2); ctx.fill(); | |
| }); | |
| } | |
| if(kind==='shield'){ | |
| // cyber: rotating concentric arcs + lock symbol | |
| const cx=w/2, cy=h/2; | |
| ctx.translate(cx,cy); | |
| for(let i=0;i<5;i++){ | |
| ctx.rotate(t*.0003*(i%2?1:-1)*(i+1)); | |
| ctx.strokeStyle = `rgba(255,179,71,${.25 + i*.1})`; | |
| ctx.lineWidth = 2*Math.min(devicePixelRatio,2); | |
| ctx.beginPath(); | |
| ctx.arc(0,0, 40+i*28, i*.3, Math.PI*1.3+i*.3); | |
| ctx.stroke(); | |
| } | |
| ctx.setTransform(1,0,0,1,0,0); | |
| // center pulsing dot | |
| const pulse = (Math.sin(t*.003)+1)*.5; | |
| ctx.fillStyle = `rgba(255,179,71,${.6+pulse*.4})`; | |
| ctx.beginPath(); ctx.arc(cx,cy, 10+pulse*4, 0, Math.PI*2); ctx.fill(); | |
| } | |
| if(kind==='ops'){ | |
| // FinOps: descending bar chart that smoothly animates | |
| const bars = 14; | |
| const bw = w/bars*.6; | |
| const gap = w/bars*.4; | |
| for(let i=0;i<bars;i++){ | |
| const ph = t*.0008 + i*.25; | |
| const target = h*(.85 - i*.05); // descending OPEX | |
| const wave = Math.sin(ph)*8; | |
| const bh = h - target + wave; | |
| const x = i*(bw+gap) + gap/2; | |
| const grad = ctx.createLinearGradient(0, h-bh, 0, h); | |
| grad.addColorStop(0, 'rgba(91,229,132,.7)'); | |
| grad.addColorStop(1, 'rgba(91,229,132,.15)'); | |
| ctx.fillStyle = grad; | |
| ctx.fillRect(x, h-bh, bw, bh); | |
| } | |
| } | |
| if(kind==='result'){ | |
| // result: large animated number with sparkline beneath | |
| ctx.font = `${Math.min(w,h)*.34}px 'Inter',sans-serif`; | |
| ctx.fillStyle = 'rgba(93,201,255,.7)'; | |
| ctx.textAlign='center';ctx.textBaseline='middle'; | |
| const pulse = Math.sin(t*.001)*.04+1; | |
| ctx.fillText('−27%', w/2, h*.4*pulse); | |
| ctx.font = `${Math.min(w,h)*.08}px 'IBM Plex Mono',monospace`; | |
| ctx.fillStyle = 'rgba(255,255,255,.4)'; | |
| ctx.fillText('OPEX', w/2, h*.62); | |
| // sparkline | |
| ctx.strokeStyle='rgba(93,201,255,.6)';ctx.lineWidth=2*Math.min(devicePixelRatio,2); | |
| ctx.beginPath(); | |
| for(let i=0;i<=40;i++){ | |
| const xx = w*.15 + (i/40)*w*.7; | |
| const yy = h*.82 - Math.sin(i*.4+t*.002)*8 - (i/40)*h*.08; | |
| if(i===0) ctx.moveTo(xx,yy); else ctx.lineTo(xx,yy); | |
| } | |
| ctx.stroke(); | |
| } | |
| if(kind==='strategy'){ | |
| // light feature visual: dotted grid + connecting blue path | |
| ctx.fillStyle = 'rgba(0,149,255,.18)'; | |
| const dot = 3*Math.min(devicePixelRatio,2); | |
| const cs = w/16; | |
| for(let i=0;i<16;i++) for(let j=0;j<16;j++){ | |
| ctx.beginPath(); ctx.arc(cs*i+cs/2, cs*j+cs/2, dot, 0, Math.PI*2); ctx.fill(); | |
| } | |
| ctx.strokeStyle='rgba(0,149,255,.8)'; | |
| ctx.lineWidth = 3*Math.min(devicePixelRatio,2); | |
| ctx.beginPath(); | |
| ctx.moveTo(cs*1.5, cs*13.5); | |
| ctx.bezierCurveTo(cs*5, cs*4, cs*9, cs*12, cs*14.5, cs*2.5); | |
| ctx.stroke(); | |
| // dot at start and end | |
| ctx.fillStyle='rgba(0,149,255,1)'; | |
| ctx.beginPath(); ctx.arc(cs*1.5, cs*13.5, 8, 0, Math.PI*2); ctx.fill(); | |
| ctx.fillStyle='rgba(88,86,214,1)'; | |
| ctx.beginPath(); ctx.arc(cs*14.5, cs*2.5, 12, 0, Math.PI*2); ctx.fill(); | |
| // pulsing dot traversing path | |
| const tt = (t*.0004)%1; | |
| const px = cs*1.5 + (cs*13)*tt; | |
| const py = cs*13.5 + Math.sin(tt*Math.PI*2)*cs*5 - tt*cs*11; | |
| ctx.fillStyle='rgba(0,149,255,1)'; | |
| ctx.beginPath(); ctx.arc(px, py, 6, 0, Math.PI*2); ctx.fill(); | |
| } | |
| if(kind==='ai'){ | |
| // light: clean orbit with planets representing data sources | |
| const cx=w/2,cy=h/2; | |
| // orbits | |
| ctx.strokeStyle='rgba(88,86,214,.18)'; | |
| ctx.lineWidth=1.5*Math.min(devicePixelRatio,2); | |
| [0.18,0.30,0.42].forEach(r=>{ | |
| ctx.beginPath(); ctx.arc(cx,cy, w*r, 0, Math.PI*2); ctx.stroke(); | |
| }); | |
| // center brain | |
| ctx.fillStyle='rgba(88,86,214,1)'; | |
| ctx.beginPath(); ctx.arc(cx,cy, w*.06, 0, Math.PI*2); ctx.fill(); | |
| ctx.fillStyle='rgba(255,255,255,.9)'; | |
| ctx.font = `600 ${w*.05}px 'Inter'`; | |
| ctx.textAlign='center';ctx.textBaseline='middle'; | |
| ctx.fillText('AI', cx, cy); | |
| // orbiting nodes | |
| const orbits=[ | |
| {r:.18,n:3,c:'rgba(0,149,255,.85)',sp:.0006}, | |
| {r:.30,n:4,c:'rgba(88,86,214,.75)',sp:-.0004}, | |
| {r:.42,n:5,c:'rgba(91,229,132,.75)',sp:.0003}, | |
| ]; | |
| orbits.forEach(o=>{ | |
| for(let i=0;i<o.n;i++){ | |
| const a = t*o.sp + (i/o.n)*Math.PI*2; | |
| const x = cx + Math.cos(a)*w*o.r; | |
| const y = cy + Math.sin(a)*w*o.r; | |
| ctx.fillStyle=o.c; | |
| ctx.beginPath(); ctx.arc(x,y, w*.018, 0, Math.PI*2); ctx.fill(); | |
| } | |
| }); | |
| } | |
| if(kind==='cyber'){ | |
| // light: concentric protective rings | |
| const cx=w/2,cy=h/2; | |
| [0.46,0.36,0.26,0.16].forEach((r,i)=>{ | |
| ctx.strokeStyle=`rgba(${i===0?'255,59,48':'0,149,255'},${.15+i*.15})`; | |
| ctx.lineWidth=2*Math.min(devicePixelRatio,2); | |
| const offset = t*.0003*(i%2?1:-1); | |
| ctx.setLineDash([16, 10]); | |
| ctx.lineDashOffset = offset*100; | |
| ctx.beginPath(); ctx.arc(cx,cy, w*r, 0, Math.PI*2); ctx.stroke(); | |
| }); | |
| ctx.setLineDash([]); | |
| // center lock | |
| ctx.fillStyle='rgba(0,149,255,1)'; | |
| ctx.beginPath(); | |
| const lw = w*.08, lh=w*.06; | |
| ctx.fillRect(cx-lw/2, cy-lh/2, lw, lh); | |
| ctx.strokeStyle='rgba(0,149,255,1)'; | |
| ctx.lineWidth = w*.012; | |
| ctx.beginPath(); ctx.arc(cx, cy-lh/2, lw*.32, Math.PI, 0); ctx.stroke(); | |
| } | |
| if(kind==='ops2'){ | |
| // light: ascending uptime curve | |
| ctx.strokeStyle='rgba(91,229,132,.25)'; | |
| ctx.lineWidth=1*Math.min(devicePixelRatio,2); | |
| // grid | |
| for(let i=1;i<5;i++){ | |
| const y = (h/5)*i; | |
| ctx.beginPath(); ctx.moveTo(w*.1,y); ctx.lineTo(w*.9,y); ctx.stroke(); | |
| } | |
| // curve | |
| ctx.strokeStyle='rgba(91,229,132,.95)'; | |
| ctx.lineWidth=4*Math.min(devicePixelRatio,2); | |
| ctx.beginPath(); | |
| for(let i=0;i<=60;i++){ | |
| const xx = w*.1 + (i/60)*w*.8; | |
| const yy = h*.85 - (i/60)*h*.55 + Math.sin(i*.5+t*.001)*4; | |
| if(i===0) ctx.moveTo(xx,yy); else ctx.lineTo(xx,yy); | |
| } | |
| ctx.stroke(); | |
| // 99.9 label | |
| ctx.fillStyle='rgba(0,0,0,.7)'; | |
| ctx.font = `700 ${w*.09}px 'Inter'`; | |
| ctx.textAlign='left';ctx.textBaseline='top'; | |
| ctx.fillText('99.9%', w*.1, h*.12); | |
| ctx.font = `500 ${w*.03}px 'IBM Plex Mono'`; | |
| ctx.fillStyle='rgba(0,0,0,.5)'; | |
| ctx.fillText('UPTIME', w*.1, h*.23); | |
| } | |
| if(!reduced) requestAnimationFrame(frame); | |
| } | |
| requestAnimationFrame(frame); | |
| } | |
| document.querySelectorAll('canvas[data-fx]').forEach(c=>cardCanvas(c,c.dataset.fx)); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment