PageSourceSearch

https://www.knowit.pl/

html knowit.pl collected 2026-10-08 08:02:57 UTC 237,438 bytes, 1,457 lines download raw bytes

1<!DOCTYPE html><html lang="pl"><head><meta charSet="utf-8" data-next-head=""/><style data-next-head="">
2    /* Minimal Critical CSS */
3    * { margin: 0; padding: 0; box-sizing: border-box; }
4    img { max-width: 100%; height: auto; display: block; }
5    @font-face {
6      font-family: 'BagossStandard';
7      font-display: swap;
8      src: url('/static/fonts/BagossStandard-Regular.woff2') format('woff2');
9    }
10  
11    /* Header Navigation Critical CSS */
12    [data-critical="header"] {
13      position: relative;
14      z-index: 10;
15      width: 100%;
16      background: transparent;
17    }
18    
19    /* Flex container for header items */
20    [data-critical="header"] [data-critical-header="banner"] {
21      display: flex;
22      align-items: center;
23      justify-content: space-between;
24      min-height: 90px;
25      padding: 0 20px;
26    }
27    
28    @media (min-width: 768px) {
29      [data-critical="header"] [data-critical-header="banner"] {
30        padding: 0 90px;
31        min-height: 90px;
32      }
33    }
34    
35    /* Logo sizing */
36    [data-critical="header"] [data-critical-header="logo"] {
37      flex-shrink: 0;
38      display: block;
39    }
40    
41    /* Menu toggle button */
42    [data-critical="header"] [data-critical-header="menu-toggle"] {
43      background: transparent;
44      border: none;
45      cursor: pointer;
46      padding: 8px;
47      display: flex;
48      align-items: center;
49      justify-content: center;
50    }
51    
52    /* Navigation links */
53    [data-critical="header"] nav a {
54      text-decoration: none;
55      color: inherit;
56      display: flex;
57    }
58  
59    /* Hero Section Critical CSS */
60    [data-critical="hero"] {
61      position: relative;
62      z-index: 4;
63      width: 100%;
64      margin-bottom: 24px;
65    }
66    
67    @media (min-width: 768px) {
68      [data-critical="hero"] {
69        margin-bottom: 40px;
70      }
71    }
72    
73    /* Hero image container */
74    [data-critical="hero"] img {
75      width: 100%;
76      height: auto;
77      display: block;
78      border-radius: 0;
79    }
80    
81    @media (min-width: 768px) {
82      [data-critical="hero"] img {
83        border-radius: 32px;
84      }
85    }
86  
87    /* StartPage Critical CSS */
88    [data-critical="startpage"] {
89      display: block;
90      width: 100%;
91      min-height: 100vh;
92    }
93
94    [data-critical="startpage"] > * {
95      width: 100%;
96    }
97  </style>
97<script id="CookieConsent" src="https://policy.app.cookieinformation.com/uc.js" data-culture="PL" type="text/javascript" data-gcm-version="2.0" defer="" rel="preconnect" data-next-head=""></script>
97<title data-next-head="">Knowit Poland</title><meta name="description" content="Knowit to skandynawska potęga cyfrowych rozwiązań przyszłości." data-next-head=""/><meta name="referrer" content="no-referrer" data-next-head=""/><link rel="canonical" href="https://www.knowit.pl" data-next-head=""/><meta property="og:url" content="https://www.knowit.pl" data-next-head=""/><meta property="og:site_name" content="Knowit" data-next-head=""/><meta property="og:title" content="Knowit Poland" data-next-head=""/><meta name="keywords" data-next-head=""/><meta property="og:description" content="Knowit to skandynawska potęga cyfrowych rozwiązań przyszłości." data-next-head=""/><meta property="og:image" content="https://www.knowit.pl/globalassets/image-bank/gradients/afterglow-1920x1080.jpg" data-next-head=""/><meta property="twitter:site" content="Knowit" data-next-head=""/><meta property="twitter:description" content="Knowit to skandynawska potęga cyfrowych rozwiązań przyszłości." data-next-head=""/><meta property="twitter:title" content="Knowit Poland" data-next-head=""/><meta name="viewport" content="width=device-width, height=device-height initial-scale=1" data-next-head=""/><link rel="icon" href="https://www.knowit.se/contentassets/048e04e9abca42e0bd83aacf7ed0b338/knowit_favicon.png" data-next-head=""/><link rel="preload" href="/static/fonts/BagossStandard-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous"/><noscript data-n-css=""></noscript>
97<script defer="" nomodule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script>
97<script src="/_next/static/chunks/webpack-f2dc78c31cb0f729.js" defer=""></script>
97<script src="/_next/static/chunks/framework-a6e0b7e30f98059a.js" defer=""></script>
97<script src="/_next/static/chunks/main-6621de45e7c4cd71.js" defer=""></script>
97<script src="/_next/static/chunks/pages/_app-3a67dc5e63da57c3.js" defer=""></script>
97<script src="/_next/static/chunks/131-9134ec237705931e.js" defer=""></script>
97<script src="/_next/static/chunks/330-de1341b78333b8e0.js" defer=""></script>
97<script src="/_next/static/chunks/893-9a69a2035851ec29.js" defer=""></script>
97<script src="/_next/static/chunks/42-ba5811b924968070.js" defer=""></script>
97<script src="/_next/static/chunks/pages/%5B%5B...slug%5D%5D-f044b0bfcb553f0b.js" defer=""></script>
97<script src="/_next/static/azM-6MnyJRFJ_7YqFlWAP/_buildManifest.js" defer=""></script>
97<script src="/_next/static/azM-6MnyJRFJ_7YqFlWAP/_ssgManifest.js" defer=""></script>
97</head><body>
vendor: 67 bytes, line 97
97<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
97GTM-K4HQP95
vendor: 82 bytes, line 97
97" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
97<div id="__next"><style data-emotion="css-global 19sltg0">:host,:root,[data-theme]{--chakra-ring-inset:var(--chakra-empty,/*!*/ /*!*/);--chakra-ring-offset-width:0px;--chakra-ring-offset-color:#fff;--chakra-ring-color:rgba(66, 153, 225, 0.6);--chakra-ring-offset-shadow:0 0 #0000;--chakra-ring-shadow:0 0 #0000;--chakra-space-x-reverse:0;--chakra-space-y-reverse:0;--chakra-colors-transparent:transparent;--chakra-colors-current:currentColor;--chakra-colors-black:#0B0B26;--chakra-colors-white:#FFFEF6;--chakra-colors-whiteAlpha-50:rgba(255, 255, 255, 0.04);--chakra-colors-whiteAlpha-100:rgba(255, 255, 255, 0.06);--chakra-colors-whiteAlpha-200:rgba(255, 255, 255, 0.08);--chakra-colors-whiteAlpha-300:rgba(255, 255, 255, 0.16);--chakra-colors-whiteAlpha-400:rgba(255, 255, 255, 0.24);--chakra-colors-whiteAlpha-500:rgba(255, 255, 255, 0.36);--chakra-colors-whiteAlpha-600:rgba(255, 255, 255, 0.48);--chakra-colors-whiteAlpha-700:rgba(255, 255, 255, 0.64);--chakra-colors-whiteAlpha-800:rgba(255, 255, 255, 0.80);--chakra-colors-whiteAlpha-900:rgba(255, 255, 255, 0.92);--chakra-colors-blackAlpha-50:rgba(0, 0, 0, 0.04);--chakra-colors-blackAlpha-100:rgba(0, 0, 0, 0.06);--chakra-colors-blackAlpha-200:rgba(0, 0, 0, 0.08);--chakra-colors-blackAlpha-300:rgba(0, 0, 0, 0.16);--chakra-colors-blackAlpha-400:rgba(0, 0, 0, 0.24);--chakra-colors-blackAlpha-500:rgba(0, 0, 0, 0.36);--chakra-colors-blackAlpha-600:rgba(0, 0, 0, 0.48);--chakra-colors-blackAlpha-700:rgba(0, 0, 0, 0.64);--chakra-colors-blackAlpha-800:rgba(0, 0, 0, 0.80);--chakra-colors-blackAlpha-900:rgba(0, 0, 0, 0.92);--chakra-colors-gray-50:#F7FAFC;--chakra-colors-gray-100:#EDF2F7;--chakra-colors-gray-200:#E2E8F0;--chakra-colors-gray-300:#CBD5E0;--chakra-colors-gray-400:#A0AEC0;--chakra-colors-gray-500:#718096;--chakra-colors-gray-600:#4A5568;--chakra-colors-gray-700:#2D3748;--chakra-colors-gray-800:#1A202C;--chakra-colors-gray-900:#171923;--chakra-colors-red-50:#FFF5F5;--chakra-colors-red-100:#FED7D7;--chakra-colors-red-200:#FEB2B2;--chakra-colors-red-300:#FC8181;--chakra-colors-red-400:#F56565;--chakra-colors-red-500:#E53E3E;--chakra-colors-red-600:#C53030;--chakra-colors-red-700:#9B2C2C;--chakra-colors-red-800:#822727;--chakra-colors-red-900:#63171B;--chakra-colors-orange-50:#FFFAF0;--chakra-colors-orange-100:#FEEBC8;--chakra-colors-orange-200:#FBD38D;--chakra-colors-orange-300:#F6AD55;--chakra-colors-orange-400:#ED8936;--chakra-colors-orange-500:#DD6B20;--chakra-colors-orange-600:#C05621;--chakra-colors-orange-700:#9C4221;--chakra-colors-orange-800:#7B341E;--chakra-colors-orange-900:#652B19;--chakra-colors-yellow-50:#FFFFF0;--chakra-colors-yellow-100:#FEFCBF;--chakra-colors-yellow-200:#FAF089;--chakra-colors-yellow-300:#F6E05E;--chakra-colors-yellow-400:#ECC94B;--chakra-colors-yellow-500:#D69E2E;--chakra-colors-yellow-600:#B7791F;--chakra-colors-yellow-700:#975A16;--chakra-colors-yellow-800:#744210;--chakra-colors-yellow-900:#5F370E;--chakra-colors-green:#55D440;--chakra-colors-teal-50:#E6FFFA;--chakra-colors-teal-100:#B2F5EA;--chakra-colors-teal-200:#81E6D9;--chakra-colors-teal-300:#4FD1C5;--chakra-colors-teal-400:#38B2AC;--chakra-colors-teal-500:#319795;--chakra-colors-teal-600:#2C7A7B;--chakra-colors-teal-700:#285E61;--chakra-colors-teal-800:#234E52;--chakra-colors-teal-900:#1D4044;--chakra-colors-blue-50:#ebf8ff;--chakra-colors-blue-100:#bee3f8;--chakra-colors-blue-200:#90cdf4;--chakra-colors-blue-300:#63b3ed;--chakra-colors-blue-400:#4299e1;--chakra-colors-blue-500:#3182ce;--chakra-colors-blue-600:#2b6cb0;--chakra-colors-blue-700:#2c5282;--chakra-colors-blue-800:#2a4365;--chakra-colors-blue-900:#1A365D;--chakra-colors-cyan-50:#EDFDFD;--chakra-colors-cyan-100:#C4F1F9;--chakra-colors-cyan-200:#9DECF9;--chakra-colors-cyan-300:#76E4F7;--chakra-colors-cyan-400:#0BC5EA;--chakra-colors-cyan-500:#00B5D8;--chakra-colors-cyan-600:#00A3C4;--chakra-colors-cyan-700:#0987A0;--chakra-colors-cyan-800:#086F83;--chakra-colors-cyan-900:#065666;--chakra-colors-purple-50:#FAF5FF;--chakra-colors-purple-100:#E9D8FD;--chakra-colors-purple-200:#D6BCFA;--chakra-colors-purple-300:#B794F4;--chakra-colors-purple-400:#9F7AEA;--chakra-colors-purple-500:#805AD5;--chakra-colors-purple-600:#6B46C1;--chakra-colors-purple-700:#553C9A;--chakra-colors-purple-800:#44337A;--chakra-colors-purple-900:#322659;--chakra-colors-pink-50:#FFF5F7;--chakra-colors-pink-100:#FED7E2;--chakra-colors-pink-200:#FBB6CE;--chakra-colors-pink-300:#F687B3;--chakra-colors-pink-400:#ED64A6;--chakra-colors-pink-500:#D53F8C;--chakra-colors-pink-600:#B83280;--chakra-colors-pink-700:#97266D;--chakra-colors-pink-800:#702459;--chakra-colors-pink-900:#521B41;--chakra-colors-linkedin-50:#E8F4F9;--chakra-colors-linkedin-100:#CFEDFB;--chakra-colors-linkedin-200:#9BDAF3;--chakra-colors-linkedin-300:#68C7EC;
97--chakra-colors-linkedin-400:#34B3E4;--chakra-colors-linkedin-500:#00A0DC;--chakra-colors-linkedin-600:#008CC9;--chakra-colors-linkedin-700:#0077B5;--chakra-colors-linkedin-800:#005E93;--chakra-colors-linkedin-900:#004471;--chakra-colors-facebook-50:#E8F4F9;--chakra-colors-facebook-100:#D9DEE9;--chakra-colors-facebook-200:#B7C2DA;--chakra-colors-facebook-300:#6482C0;--chakra-colors-facebook-400:#4267B2;--chakra-colors-facebook-500:#385898;--chakra-colors-facebook-600:#314E89;--chakra-colors-facebook-700:#29487D;--chakra-colors-facebook-800:#223B67;--chakra-colors-facebook-900:#1E355B;--chakra-colors-messenger-50:#D0E6FF;--chakra-colors-messenger-100:#B9DAFF;--chakra-colors-messenger-200:#A2CDFF;--chakra-colors-messenger-300:#7AB8FF;--chakra-colors-messenger-400:#2E90FF;--chakra-colors-messenger-500:#0078FF;--chakra-colors-messenger-600:#0063D1;--chakra-colors-messenger-700:#0052AC;--chakra-colors-messenger-800:#003C7E;--chakra-colors-messenger-900:#002C5C;--chakra-colors-whatsapp-50:#dffeec;--chakra-colors-whatsapp-100:#b9f5d0;--chakra-colors-whatsapp-200:#90edb3;--chakra-colors-whatsapp-300:#65e495;--chakra-colors-whatsapp-400:#3cdd78;--chakra-colors-whatsapp-500:#22c35e;--chakra-colors-whatsapp-600:#179848;--chakra-colors-whatsapp-700:#0c6c33;--chakra-colors-whatsapp-800:#01421c;--chakra-colors-whatsapp-900:#001803;--chakra-colors-twitter-50:#E5F4FD;--chakra-colors-twitter-100:#C8E9FB;--chakra-colors-twitter-200:#A8DCFA;--chakra-colors-twitter-300:#83CDF7;--chakra-colors-twitter-400:#57BBF5;--chakra-colors-twitter-500:#1DA1F2;--chakra-colors-twitter-600:#1A94DA;--chakra-colors-twitter-700:#1681BF;--chakra-colors-twitter-800:#136B9E;--chakra-colors-twitter-900:#0D4D71;--chakra-colors-telegram-50:#E3F2F9;--chakra-colors-telegram-100:#C5E4F3;--chakra-colors-telegram-200:#A2D4EC;--chakra-colors-telegram-300:#7AC1E4;--chakra-colors-telegram-400:#47A9DA;--chakra-colors-telegram-500:#0088CC;--chakra-colors-telegram-600:#007AB8;--chakra-colors-telegram-700:#006BA1;--chakra-colors-telegram-800:#005885;--chakra-colors-telegram-900:#003F5E;--chakra-colors-brand-primary:#FEFBE6;--chakra-colors-brand-accent:#372BC5;--chakra-colors-brand-secondary:#372BC5;--chakra-colors-brand-start:#FFD6B8;--chakra-colors-brand-puff:#FAF6DD;--chakra-colors-brand-news:#FFEBDD;--chakra-colors-brand-case:#E9E9FF;--chakra-colors-brand-bg1:#E3EAE4;--chakra-colors-brand-bg3:#7C3647;--chakra-colors-brand-bg4:#F1F0ED;--chakra-colors-brand-bg5:#F8F6F4;--chakra-colors-brand-error:#EC1010;--chakra-colors-brand-dim:#0a0938a8;--chakra-colors-brand-border:#0a093838;--chakra-colors-brand-black:#0B0B26;--chakra-colors-brand-white:#FFFEF6;--chakra-colors-brand-green:#55D440;--chakra-colors-brand-disabled:#C4C4C4;--chakra-colors-brand-hover-news:#FFEBDD;--chakra-colors-brand-hover-case:#CFCEFF;--chakra-colors-brand-text-primary:#0B0B26;--chakra-colors-brand-text-secondary:#FFD6B8;--chakra-colors-brand-text-case:#372BC5;--chakra-colors-brand-text-text2:#D9D9D9;--chakra-colors-brand-search-global:#FFFEF6;--chakra-colors-brand-search-primary:#0B0B26;--chakra-colors-primary:#FEFBE6;--chakra-colors-accent:#372BC5;--chakra-colors-secondary:#372BC5;--chakra-colors-start:#FFD6B8;--chakra-colors-puff:#FAF6DD;--chakra-colors-news:#FFEBDD;--chakra-colors-case:#E9E9FF;--chakra-colors-bg1:#E3EAE4;--chakra-colors-bg3:#7C3647;--chakra-colors-bg4:#F1F0ED;--chakra-colors-bg5:#F8F6F4;--chakra-colors-error:#EC1010;--chakra-colors-dim:#0a0938a8;--chakra-colors-border:#0a093838;--chakra-colors-disabled:#C4C4C4;--chakra-colors-hover-news:#FFEBDD;--chakra-colors-hover-case:#CFCEFF;--chakra-colors-text-primary:#0B0B26;--chakra-colors-text-secondary:#FFD6B8;--chakra-colors-text-case:#372BC5;--chakra-colors-text-text2:#D9D9D9;--chakra-colors-search-global:#FFFEF6;--chakra-colors-search-primary:#0B0B26;--chakra-colors-heroBg:transparent;--chakra-colors-pageBg:#FEFBE6;--chakra-colors-heroHeading:#0B0B26;--chakra-colors-heroText:#0B0B26;--chakra-borders-none:0;--chakra-borders-1px:1px solid;--chakra-borders-2px:2px solid;--chakra-borders-4px:4px solid;--chakra-borders-8px:8px solid;--chakra-fonts-heading:BagossStandard,Arial;--chakra-fonts-body:BagossStandard,Arial;--chakra-fonts-mono:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--chakra-fonts-title:"BagossStandard",Arial;--chakra-fontSizes-1:0.25rem;--chakra-fontSizes-2:0.5rem;--chakra-fontSizes-3:0.75rem;--chakra-fontSizes-4:1rem;--chakra-fontSizes-5:1.25rem;--chakra-fontSizes-6:1.5rem;--chakra-fontSizes-7:1.75rem;--chakra-fontSizes-8:2rem;--chakra-fontSizes-9:2.25rem;--chakra-fontSizes-10:2.5rem;--chakra-fontSizes-12:3rem;--chakra-fontSizes-13:3.25rem;--chakra-fontSizes-14:3.5rem;--chakra-fontSizes-15:3.75rem;--chakra-fontSizes-16:4rem;--chakra-fontSizes-17:4.5rem;--chakra-fontSizes-18:5rem;--chakra-fontSizes-20:5rem;--chakra-fontSizes-24:6rem;--chakra-fontSizes-25:6.25rem;--chakra-fontSizes-28:7rem;--chakra-fontSizes-32:8rem;--chakra-fontSizes-36:9rem;--chakra-fontSizes-40:10rem;--chakra-fontSizes-44:11rem;--chakra-fontSizes-48:12rem;--chakra-fontSizes-50:12.5rem;--chakra-fontSizes-52:13rem;--chakra-fontSizes-56:14rem;--chakra-fontSizes-60:15rem;--chakra-fontSizes-64:16rem;--chakra-fontSizes-72:18rem;--chakra-fontSizes-80:20rem;--chakra-fontSizes-96:24rem;--chakra-fontSizes-3xs:0.875rem;--chakra-fontSizes-2xs:0.875rem;--chakra-fontSizes-xs:1rem;--chakra-fontSizes-sm:1.125rem;--chakra-fontSizes-md:1.25rem;--chakra-fontSizes-lg:1.375rem;--chakra-fontSizes-xl:1.5rem;--chakra-fontSizes-2xl:1.625rem;--chakra-fontSizes-3xl:2.25rem;--chakra-fontSizes-4xl:2.375rem;--chakra-fontSizes-5xl:3.125rem;--chakra-fontSizes-6xl:3.25rem;--chakra-fontSizes-7xl:4.5rem;--chakra-fontSizes-8xl:7rem;--chakra-fontSizes-9xl:8rem;--chakra-fontSizes-2-5xl:1.75rem;--chakra-fontSizes-2-75xl:1.875rem;--chakra-fontSizes-0-5:0.125rem;--chakra-fontSizes-1-5:0.375rem;--chakra-fontSizes-2-5:0.625rem;--chakra-fontSizes-3-5:0.875rem;--chakra-fontSizes-4-5:1.125rem;--chakra-fontSizes-5-5:1.375rem;--chakra-fontSizes-6-5:1.625rem;--chakra-fontSizes-8-5:2.125rem;--chakra-fontSizes-12-5:3.125rem;--chakra-fontWeights-hairline:100;--chakra-fontWeights-thin:200;--chakra-fontWeights-light:300;--chakra-fontWeights-normal:400;--chakra-fontWeights-medium:500;--chakra-fontWeights-semibold:600;--chakra-fontWeights-bold:700;--chakra-fontWeights-extrabold:800;--chakra-fontWeights-black:900;--chakra-letterSpacings-tighter:-0.05em;
97--chakra-letterSpacings-tight:-0.025em;--chakra-letterSpacings-normal:0;--chakra-letterSpacings-wide:0.025em;--chakra-letterSpacings-wider:0.05em;--chakra-letterSpacings-widest:0.1em;--chakra-lineHeights-1:0.25rem;--chakra-lineHeights-2:0.5rem;--chakra-lineHeights-3:0.75rem;--chakra-lineHeights-4:1rem;--chakra-lineHeights-5:1.25rem;--chakra-lineHeights-6:1.5rem;--chakra-lineHeights-7:1.75rem;--chakra-lineHeights-8:2rem;--chakra-lineHeights-9:2.25rem;--chakra-lineHeights-10:2.5rem;--chakra-lineHeights-12:3rem;--chakra-lineHeights-13:3.25rem;--chakra-lineHeights-14:3.5rem;--chakra-lineHeights-15:3.75rem;--chakra-lineHeights-16:4rem;--chakra-lineHeights-17:4.5rem;--chakra-lineHeights-18:5rem;--chakra-lineHeights-20:5rem;--chakra-lineHeights-24:6rem;--chakra-lineHeights-25:6.25rem;--chakra-lineHeights-28:7rem;--chakra-lineHeights-32:8rem;--chakra-lineHeights-36:9rem;--chakra-lineHeights-40:10rem;--chakra-lineHeights-44:11rem;--chakra-lineHeights-48:12rem;--chakra-lineHeights-50:12.5rem;--chakra-lineHeights-52:13rem;--chakra-lineHeights-56:14rem;--chakra-lineHeights-60:15rem;--chakra-lineHeights-64:16rem;--chakra-lineHeights-72:18rem;--chakra-lineHeights-80:20rem;--chakra-lineHeights-96:24rem;--chakra-lineHeights-normal:normal;--chakra-lineHeights-none:1;--chakra-lineHeights-shorter:1.25;--chakra-lineHeights-short:1.375;--chakra-lineHeights-base:1.5;--chakra-lineHeights-tall:1.625;--chakra-lineHeights-taller:2;--chakra-lineHeights-3xs:1rem;--chakra-lineHeights-2xs:1.125rem;--chakra-lineHeights-xs:1.25rem;--chakra-lineHeights-sm:1.5rem;--chakra-lineHeights-md:1.625rem;--chakra-lineHeights-lg:1.75rem;--chakra-lineHeights-xl:2rem;--chakra-lineHeights-2xl:2.25rem;--chakra-lineHeights-3xl:2.5rem;--chakra-lineHeights-3-5xl:2.75rem;--chakra-lineHeights-4xl:3rem;--chakra-lineHeights-4-5xl:3.125rem;--chakra-lineHeights-5xl:4.5rem;--chakra-lineHeights-6xl:4rem;--chakra-lineHeights-7xl:7rem;--chakra-lineHeights-9xl:7rem;--chakra-lineHeights-0-5:0.125rem;--chakra-lineHeights-1-5:0.375rem;--chakra-lineHeights-2-5:0.625rem;--chakra-lineHeights-3-5:0.875rem;--chakra-lineHeights-4-5:1.125rem;--chakra-lineHeights-5-5:1.375rem;--chakra-lineHeights-6-5:1.625rem;--chakra-lineHeights-8-5:2.125rem;--chakra-lineHeights-12-5:3.125rem;--chakra-radii-none:0;--chakra-radii-sm:4px;--chakra-radii-base:6px;--chakra-radii-md:0.375rem;--chakra-radii-lg:0.5rem;--chakra-radii-xl:0.75rem;--chakra-radii-2xl:1rem;--chakra-radii-3xl:1.5rem;--chakra-radii-full:9999px;--chakra-space-1:0.25rem;--chakra-space-2:0.5rem;--chakra-space-3:0.75rem;--chakra-space-4:1rem;--chakra-space-5:1.25rem;--chakra-space-6:1.5rem;--chakra-space-7:1.75rem;--chakra-space-8:2rem;--chakra-space-9:2.25rem;--chakra-space-10:2.5rem;--chakra-space-12:3rem;--chakra-space-13:3.25rem;--chakra-space-14:3.5rem;--chakra-space-15:3.75rem;--chakra-space-16:4rem;--chakra-space-17:4.5rem;--chakra-space-18:5rem;--chakra-space-20:5rem;--chakra-space-24:6rem;--chakra-space-25:6.25rem;--chakra-space-28:7rem;--chakra-space-32:8rem;--chakra-space-36:9rem;--chakra-space-40:10rem;--chakra-space-44:11rem;--chakra-space-48:12rem;--chakra-space-50:12.5rem;--chakra-space-52:13rem;--chakra-space-56:14rem;--chakra-space-60:15rem;--chakra-space-64:16rem;--chakra-space-72:18rem;--chakra-space-80:20rem;--chakra-space-96:24rem;--chakra-space-px:1px;--chakra-space-0-5:0.125rem;--chakra-space-1-5:0.375rem;--chakra-space-2-5:0.625rem;--chakra-space-3-5:0.875rem;--chakra-space-4-5:1.125rem;--chakra-space-5-5:1.375rem;--chakra-space-6-5:1.625rem;--chakra-space-8-5:2.125rem;--chakra-space-12-5:3.125rem;--chakra-shadows-xs:0 0 0 1px rgba(0, 0, 0, 0.05);--chakra-shadows-sm:0 1px 2px 0 rgba(0, 0, 0, 0.05);--chakra-shadows-base:0 1px 3px 0 rgba(0, 0, 0, 0.1),0 1px 2px 0 rgba(0, 0, 0, 0.06);--chakra-shadows-md:0 4px 6px -1px rgba(0, 0, 0, 0.1),0 2px 4px -1px rgba(0, 0, 0, 0.06);--chakra-shadows-lg:0 10px 15px -3px rgba(0, 0, 0, 0.1),0 4px 6px -2px rgba(0, 0, 0, 0.05);--chakra-shadows-xl:0 20px 25px -5px rgba(0, 0, 0, 0.1),0 10px 10px -5px rgba(0, 0, 0, 0.04);--chakra-shadows-2xl:0 25px 50px -12px rgba(0, 0, 0, 0.25);--chakra-shadows-outline:0 0 0 3px rgba(66, 153, 225, 0.6);--chakra-shadows-inner:inset 0 2px 4px 0 rgba(0,0,0,0.06);--chakra-shadows-none:none;--chakra-shadows-dark-lg:rgba(0, 0, 0, 0.1) 0px 0px 0px 1px,rgba(0, 0, 0, 0.2) 0px 5px 10px,rgba(0, 0, 0, 0.4) 0px 15px 40px;--chakra-sizes-1:0.25rem;--chakra-sizes-2:0.5rem;--chakra-sizes-3:0.75rem;--chakra-sizes-4:1rem;--chakra-sizes-5:1.25rem;--chakra-sizes-6:1.5rem;--chakra-sizes-7:1.75rem;--chakra-sizes-8:2rem;--chakra-sizes-9:2.25rem;--chakra-sizes-10:2.5rem;--chakra-sizes-12:3rem;--chakra-sizes-14:3.5rem;--chakra-sizes-16:4rem;--chakra-sizes-20:5rem;--chakra-sizes-24:6rem;--chakra-sizes-28:7rem;--chakra-sizes-32:8rem;--chakra-sizes-36:9rem;--chakra-sizes-40:10rem;--chakra-sizes-44:11rem;--chakra-sizes-48:12rem;--chakra-sizes-52:13rem;--chakra-sizes-56:14rem;--chakra-sizes-60:15rem;--chakra-sizes-64:16rem;--chakra-sizes-72:18rem;--chakra-sizes-80:20rem;--chakra-sizes-96:24rem;--chakra-sizes-px:1px;--chakra-sizes-0-5:0.125rem;--chakra-sizes-1-5:0.375rem;--chakra-sizes-2-5:0.625rem;--chakra-sizes-3-5:0.875rem;--chakra-sizes-max:max-content;
97--chakra-sizes-min:min-content;--chakra-sizes-full:100%;--chakra-sizes-3xs:14rem;--chakra-sizes-2xs:16rem;--chakra-sizes-xs:20rem;--chakra-sizes-sm:24rem;--chakra-sizes-md:28rem;--chakra-sizes-lg:32rem;--chakra-sizes-xl:36rem;--chakra-sizes-2xl:42rem;--chakra-sizes-3xl:48rem;--chakra-sizes-4xl:56rem;--chakra-sizes-5xl:64rem;--chakra-sizes-6xl:72rem;--chakra-sizes-7xl:80rem;--chakra-sizes-8xl:90rem;--chakra-sizes-prose:60ch;--chakra-sizes-container-sm:640px;--chakra-sizes-container-md:768px;--chakra-sizes-container-lg:1024px;--chakra-sizes-container-xl:1280px;--chakra-zIndices-hide:-1;--chakra-zIndices-auto:auto;--chakra-zIndices-base:0;--chakra-zIndices-docked:10;--chakra-zIndices-dropdown:1000;--chakra-zIndices-sticky:1100;--chakra-zIndices-banner:1200;--chakra-zIndices-overlay:1300;--chakra-zIndices-modal:1400;--chakra-zIndices-popover:1500;--chakra-zIndices-skipLink:1600;--chakra-zIndices-toast:1700;--chakra-zIndices-tooltip:1800;--chakra-zIndices-loaderOverlay:1900;--chakra-zIndices-loader:2000;--chakra-transition-property-common:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform;--chakra-transition-property-colors:background-color,border-color,color,fill,stroke;--chakra-transition-property-dimensions:width,height;--chakra-transition-property-position:left,right,top,bottom;--chakra-transition-property-background:background-color,background-image,background-position;--chakra-transition-easing-ease-in:cubic-bezier(0.4, 0, 1, 1);--chakra-transition-easing-ease-out:cubic-bezier(0, 0, 0.2, 1);--chakra-transition-easing-ease-in-out:cubic-bezier(0.4, 0, 0.2, 1);--chakra-transition-duration-ultra-fast:50ms;--chakra-transition-duration-faster:100ms;--chakra-transition-duration-fast:150ms;--chakra-transition-duration-normal:200ms;--chakra-transition-duration-slow:300ms;--chakra-transition-duration-slower:400ms;--chakra-transition-duration-ultra-slow:500ms;--chakra-blur-none:0;--chakra-blur-sm:4px;--chakra-blur-base:8px;--chakra-blur-md:12px;--chakra-blur-lg:16px;--chakra-blur-xl:24px;--chakra-blur-2xl:40px;--chakra-blur-3xl:64px;--chakra-breakpoints-base:0em;--chakra-breakpoints-sm:30em;
97--chakra-breakpoints-md:48em;--chakra-breakpoints-lg:62em;--chakra-breakpoints-xl:80em;--chakra-breakpoints-2xl:96em;--chakra-breakpoints-xsm:24em;}.chakra-ui-light :host:not([data-theme]),.chakra-ui-light :root:not([data-theme]),.chakra-ui-light [data-theme]:not([data-theme]),[data-theme=light] :host:not([data-theme]),[data-theme=light] :root:not([data-theme]),[data-theme=light] [data-theme]:not([data-theme]),:host[data-theme=light],:root[data-theme=light],[data-theme][data-theme=light]{--chakra-colors-chakra-body-text:var(--chakra-colors-gray-800);--chakra-colors-chakra-body-bg:var(--chakra-colors-white);--chakra-colors-chakra-border-color:var(--chakra-colors-gray-200);--chakra-colors-chakra-inverse-text:var(--chakra-colors-white);--chakra-colors-chakra-subtle-bg:var(--chakra-colors-gray-100);--chakra-colors-chakra-subtle-text:var(--chakra-colors-gray-600);--chakra-colors-chakra-placeholder-color:var(--chakra-colors-gray-500);}.chakra-ui-dark :host:not([data-theme]),.chakra-ui-dark :root:not([data-theme]),.chakra-ui-dark [data-theme]:not([data-theme]),[data-theme=dark] :host:not([data-theme]),[data-theme=dark] :root:not([data-theme]),[data-theme=dark] [data-theme]:not([data-theme]),:host[data-theme=dark],:root[data-theme=dark],[data-theme][data-theme=dark]{--chakra-colors-chakra-body-text:var(--chakra-colors-whiteAlpha-900);--chakra-colors-chakra-body-bg:var(--chakra-colors-gray-800);--chakra-colors-chakra-border-color:var(--chakra-colors-whiteAlpha-300);--chakra-colors-chakra-inverse-text:var(--chakra-colors-gray-800);--chakra-colors-chakra-subtle-bg:var(--chakra-colors-gray-700);--chakra-colors-chakra-subtle-text:var(--chakra-colors-gray-400);--chakra-colors-chakra-placeholder-color:var(--chakra-colors-whiteAlpha-400);}</style><style data-emotion="css-global fubdgu">html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:system-ui,sans-serif;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;touch-action:manipulation;}body{position:relative;min-height:100%;margin:0;font-feature-settings:"kern";}:where(*, *::before, *::after){border-width:0;border-style:solid;box-sizing:border-box;word-wrap:break-word;}main{display:block;}hr{border-top-width:1px;box-sizing:content-box;height:0;overflow:visible;}:where(pre, code, kbd,samp){font-family:SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-size:1em;}a{background-color:transparent;color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit;}abbr[title]{border-bottom:none;-webkit-text-decoration:underline;text-decoration:underline;-webkit-text-decoration:underline dotted;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;}:where(b, strong){font-weight:bold;}small{font-size:80%;}:where(sub,sup){font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sub{bottom:-0.25em;}sup{top:-0.5em;}img{border-style:none;}:where(button, input, optgroup, select, textarea){font-family:inherit;font-size:100%;line-height:1.15;margin:0;}:where(button, input){overflow:visible;}:where(button, select){text-transform:none;}:where(
98          button::-moz-focus-inner,
99          [type="button"]::-moz-focus-inner,
100          [type="reset"]::-moz-focus-inner,
101          [type="submit"]::-moz-focus-inner
102        ){border-style:none;padding:0;}fieldset{padding:0.35em 0.75em 0.625em;}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal;}progress{vertical-align:baseline;}textarea{overflow:auto;}
102:where([type="checkbox"], [type="radio"]){box-sizing:border-box;padding:0;}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{-webkit-appearance:none!important;}input[type="number"]{-moz-appearance:textfield;}input[type="search"]{-webkit-appearance:textfield;outline-offset:-2px;}input[type="search"]::-webkit-search-decoration{-webkit-appearance:none!important;}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit;}details{display:block;}summary{display:-webkit-box;display:-webkit-list-item;display:-ms-list-itembox;display:list-item;}template{display:none;}[hidden]{display:none!important;}:where(
103          blockquote,
104          dl,
105          dd,
106          h1,
107          h2,
108          h3,
109          h4,
110          h5,
111          h6,
112          hr,
113          figure,
114          p,
115          pre
116        ){margin:0;}button{background:transparent;padding:0;}fieldset{margin:0;padding:0;}:where(ol, ul){margin:0;padding:0;}textarea{resize:vertical;}:where(button, [role="button"]){cursor:pointer;}button::-moz-focus-inner{border:0!important;}table{border-collapse:collapse;}:where(h1, h2, h3, h4, h5, h6){font-size:inherit;font-weight:inherit;}:where(button, input, optgroup, select, textarea){padding:0;line-height:inherit;color:inherit;}:where(img, svg, video, canvas, audio, iframe, embed, object){display:block;}:where(img, video){max-width:100%;height:auto;}[data-js-focus-visible] :focus:not([data-focus-visible-added]):not(
117          [data-focus-visible-disabled]
118        ){outline:none;box-shadow:none;}select::-ms-expand{display:none;}:root,:host{--chakra-vh:100vh;}@supports (height: -webkit-fill-available){:root,:host{--chakra-vh:-webkit-fill-available;}}@supports (height: -moz-fill-available){:root,:host{--chakra-vh:-moz-fill-available;}}@supports (height: 100dvh){:root,:host{--chakra-vh:100dvh;}}</style><style data-emotion="css-global 14f95so">body{font-family:var(--chakra-fonts-body);color:var(--chakra-colors-black);background:var(--chakra-colors-chakra-body-bg);transition-property:background-color;transition-duration:var(--chakra-transition-duration-normal);line-height:var(--chakra-lineHeights-base);over-flow-x:hidden;font-size:var(--chakra-fontSizes-sm);}*::-webkit-input-placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*::-moz-placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*:-ms-input-placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*::placeholder{color:var(--chakra-colors-chakra-placeholder-color);}*,*::before,::after{border-color:var(--chakra-colors-chakra-border-color);}#coitable{display:none;}li{list-style-type:none;}a{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}</style><style data-emotion="css-global 19oyu6i">@font-face{font-family:'BagossStandard';font-display:swap;src:url('/static/fonts/BagossStandard-Regular.woff2') format('woff2');font-weight:300;font-style:normal;}@media (prefers-reduced-data: no-preference){link[rel="preload"][as="font"]{font-display:swap;}}</style><style data-emotion="css 1vf93pm">.css-1vf93pm{transition-property:var(--chakra-transition-property-common);transition-duration:var(--chakra-transition-duration-fast);transition-timing-function:var(--chakra-transition-easing-ease-out);cursor:pointer;-webkit-text-decoration:none;text-decoration:none;outline:2px solid transparent;outline-offset:2px;color:inherit;-webkit-transition:0.3s ease;transition:0.3s ease;display:block;position:absolute;opacity:0;z-index:-1;}.css-1vf93pm:hover,.css-1vf93pm[data-hover]{-webkit-text-decoration:none;text-decoration:none;}.css-1vf93pm:focus-visible,.css-1vf93pm[data-focus-visible]{box-shadow:var(--chakra-shadows-outline);}.css-1vf93pm:focus,.css-1vf93pm[data-focus]{opacity:1;outline:2px solid transparent;outline-offset:2px;height:auto;position:absolute;background:var(--chakra-colors-white);z-index:999;margin:auto;width:100%;text-align:center;-webkit-text-decoration:underline;text-decoration:underline;}</style><a class="chakra-link css-1vf93pm" href="#main-content">Przejdź do głównej zawartości</a><div data-focus-guard="true" tabindex="-1" style="width:1px;height:0px;padding:0;overflow:hidden;position:fixed;top:1px;left:1px"></div><div data-focus-lock-disabled="disabled" data-focus-lock="mainmenu-open"><style data-emotion="css 190qa9l">.css-190qa9l{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:0px;background:var(--chakra-colors-heroBg);}</style><header class="chakra-stack css-190qa9l" data-critical="header"><style data-emotion="css 108dgvm">.css-108dgvm{z-index:10;position:absolute;width:100%;top:0px;left:0px;background:var(--chakra-colors-heroBg);}</style><div class="css-108dgvm"><style data-emotion="css 5ypf8f">.css-5ypf8f{padding-right:20px;padding-left:20px;margin:0 auto;-webkit-box-pack:justify;
118-webkit-justify-content:space-between;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;height:5.625rem;color:var(--chakra-colors-brand-primary);width:100%;background:var(--chakra-colors-transparent);max-width:calc(1548px + 40px);}</style><div data-critical-header="banner" class="css-5ypf8f"><style data-emotion="css qjuys">.css-qjuys{transition-property:var(--chakra-transition-property-common);transition-duration:var(--chakra-transition-duration-fast);transition-timing-function:var(--chakra-transition-easing-ease-out);cursor:pointer;-webkit-text-decoration:none;text-decoration:none;outline:2px solid transparent;outline-offset:2px;-webkit-transition:0.3s ease;transition:0.3s ease;border-bottom:1px solid;border-color:var(--chakra-colors-transparent);color:var(--chakra-colors-white);}.css-qjuys:focus,.css-qjuys[data-focus]{outline:2px solid transparent;outline-offset:2px;}.css-qjuys:focus-visible,.css-qjuys[data-focus-visible]{outline-color:var(--chakra-colors-black);outline-offset:2px;outline:2px solid;box-shadow:var(--chakra-shadows-none);}.css-qjuys:hover,.css-qjuys[data-hover]{border-color:var(--chakra-colors-transparent);}</style><a class="chakra-link css-qjuys" data-critical-header="logo" href="/"><style data-emotion="css idkz9h">.css-idkz9h{border:0;clip:rect(0, 0, 0, 0);height:1px;width:1px;margin:-1px;padding:0px;overflow:hidden;white-space:nowrap;position:absolute;}</style><span class="css-idkz9h">Do strony głównej Knowit</span><style data-emotion="css 1x8gy3d">.css-1x8gy3d{width:67px;height:16px;display:inline-block;line-height:1em;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;color:var(--chakra-colors-white);vertical-align:middle;}@media screen and (min-width: 48em){.css-1x8gy3d{width:123px;height:28px;}}</style><svg viewBox="0 0 124 28" focusable="false" class="chakra-icon css-1x8gy3d" aria-hidden="true"><g clip-path="url(#clip0_11087_40938)"><path d="M103.159 4.52767C104.443 4.52767 105.42 3.54956 105.42 2.26579C105.42 0.982017 104.443 0.00390625 103.159 0.00390625C101.876 0.00390625 100.898 0.982017 100.898 2.26579C100.898 3.48842 101.937 4.52767 103.159 4.52767Z" fill="currentColor"></path><path d="M20.5402 7.09096H17.607C16.6904 7.09096 16.5682 7.21322 15.5293 8.25246L6.11866 17.7279V2.87286C6.17977 2.50606 5.87423 2.13927 5.50758 2.07814C5.44647 2.07814 5.38536 2.07814 5.32425 2.07814H0.802234C0.435584 2.01701 0.0689336 2.32267 0.00782527 2.68946C0.00782527 2.75059 0.00782527 2.81172 0.00782527 2.87286V4.89021C-0.0532831 5.257 0.252259 5.62379 0.618909 5.68492C0.680017 5.68492 0.741126 5.68492 0.802234 5.68492H2.45216V24.0245H0.802234C0.435584 23.9634 0.0689336 24.269 0.00782527 24.6358C0.00782527 24.697 0.00782527 24.7581 0.00782527 24.8192V26.8366C-0.0532831 27.2034 0.252259 27.5702 0.618909 27.6313C0.680017 27.6313 0.741126 27.6313 0.802234 27.6313H7.64637C8.01302 27.6924 8.37967 27.4479 8.44078 27.0811C8.44078 27.02 8.44078 26.9588 8.44078 26.8977V24.8192C8.50189 24.4524 8.19635 24.0856 7.8297 24.0245C7.76859 24.0245 7.70748 24.0245 7.64637 24.0245H6.05755V22.4962L9.60184 18.8894L15.8349 26.4698C16.6293 27.509 16.6293 27.509 17.8515 27.509H20.5402C20.9069 27.5702 21.2735 27.2645 21.2735 26.8977C21.2735 26.8366 21.2735 26.7754 21.2735 26.7143V24.8192C21.3346 24.4524 21.0291 24.0856 20.6624 24.0245C20.6013 24.0245 20.5402 24.0245 20.4791 24.0245H18.2792L12.1073 16.383L17.7292 10.6366H20.4791C20.8458 10.6977 21.1513 10.3921 21.2124 10.0253C21.2124 9.96416 21.2124 9.90303 21.2124 9.90303V7.82454C21.2735 7.45775 21.0291 7.09096 20.6013 7.02983C20.6625 7.09096 20.6013 7.09096 20.5402 7.09096Z" fill="currentColor"></path><path d="M44.7415 24.0265H43.0915V15.2847C43.0915 10.0884 39.7917 6.72619 34.7197 6.72619C32.5809 6.66505 30.5032 7.39864 28.9144 8.8658V7.88769C28.9755 7.5209 28.67 7.15411 28.3033 7.15411C28.2422 7.15411 28.1811 7.15411 28.12 7.15411H23.7202C23.3536 7.09298 22.9869 7.33751 22.9258 7.76543C22.9258 7.82656 22.9258 7.88769 22.9258 7.94882V9.96618C22.8647 10.333 23.1702 10.6998 23.5369 10.7609C23.598 10.7609 23.6591 10.7609 23.7202 10.7609H25.3701V24.0877H23.7202C23.3536 24.0265 22.9869 24.3322 22.9258 24.699C22.9258 24.7601 22.9258 24.8212 22.9258 24.8824V26.8997C22.9258 27.2665 23.1702 27.6333 23.598 27.6333C23.6591 27.6333 23.6591 27.6333 23.7202 27.6333H30.5643C30.931 27.6944 31.2976 27.3888 31.3587 27.022C31.3587 26.9608 31.3587 26.8997 31.3587 26.8997V24.8212C31.4199 24.4544 31.1143 24.0877 30.7477 24.0265C30.6866 24.0265 30.6254 24.0265 30.5643 24.0265H28.9755V15.896C28.9755 12.5337 31.2976 10.1496 34.5364 10.1496C37.7751 10.1496 39.5473 12.1669 39.5473 15.6514V24.0265H37.8973C37.5307 23.9654 37.164 24.271 37.164 24.699C37.164 24.7601 37.164 24.8212 37.164 24.8824V26.8997C37.1029 27.2665 37.4085 27.6333 37.7751 27.6944C37.8362 27.6944 37.8973 27.6944 37.9585 27.6944H44.8026C45.1692 27.7556 45.5359 27.4499 45.597 27.0831C45.597 27.022 45.597 26.9608 45.597 26.8997V24.8212C45.6581 24.4544 45.3526 24.0877 44.9859 24.0265C44.8637 24.0265 44.8026 24.0265 44.7415 24.0265Z" fill="currentColor"></path><path d="M55.9207 6.73047C50.1154 6.73047 45.4711 11.4376 45.4711 17.184C45.4711 17.2452 45.4711 17.3063 45.4711 17.4286C45.3489 23.175 49.9321 27.8821 55.6762 28.0044C55.7373 28.0044 55.7985 28.0044 55.8596 28.0044C61.6649 28.0044 66.3702 23.2972 66.3702 17.5508C66.3702 17.4897 66.3702 17.4286 66.3702 17.3674
118C66.4924 11.621 61.9093 6.91386 56.1651 6.7916C56.0429 6.73047 55.9818 6.73047 55.9207 6.73047ZM55.9207 24.5199C52.1319 24.5199 49.1987 21.341 49.1987 17.3063C49.1987 13.2716 52.0708 10.215 55.8596 10.215C59.6483 10.215 62.6426 13.3938 62.6426 17.4286C62.6426 21.4633 59.7094 24.5199 55.9207 24.5199Z" fill="currentColor"></path><path d="M96.7423 7.09523H89.7148C89.3482 7.0341 88.9815 7.27863 88.9204 7.70655C88.9204 7.76768 88.9204 7.82882 88.9204 7.88995V9.9073C88.8593 10.2741 89.1648 10.6409 89.5315 10.702C89.5926 10.702 89.6537 10.702 89.7148 10.702H91.3036L87.9427 21.5224L83.1762 7.70655C83.054 7.33976 82.6874 7.09523 82.3207 7.09523H80.9152C80.5486 7.09523 80.1819 7.33976 80.0597 7.70655L75.3544 21.5224L71.9934 10.6409H73.5822C73.9489 10.702 74.3155 10.3964 74.3766 10.0296C74.3766 9.96843 74.3766 9.9073 74.3766 9.84617V7.82882C74.4377 7.46203 74.1322 7.09523 73.7655 7.09523C73.7044 7.09523 73.6433 7.09523 73.5822 7.09523H66.4936C66.127 7.0341 65.7603 7.33976 65.6992 7.70655C65.6992 7.76768 65.6992 7.82882 65.6992 7.82882V9.84617C65.6381 10.213 65.9437 10.5798 66.3103 10.6409C66.3714 10.6409 66.4325 10.6409 66.4325 10.6409H68.0825L73.6433 27.0242C73.7655 27.391 74.1322 27.6356 74.4988 27.6356H76.0265C76.3932 27.6356 76.7598 27.391 76.8821 27.0242L81.5263 13.5752L86.1705 27.0242C86.2927 27.391 86.6594 27.6356 87.0261 27.6356H88.5538C88.9204 27.6356 89.2871 27.391 89.4093 27.0242L95.0312 10.6409H96.6812C97.0478 10.702 97.4145 10.3964 97.4756 10.0296C97.4756 9.96843 97.4756 9.9073 97.4756 9.9073V7.88995C97.5367 7.52316 97.2311 7.15637 96.8645 7.15637C96.8645 7.09523 96.8034 7.09523 96.7423 7.09523Z" fill="currentColor"></path><path d="M106.702 24.0287H105.052V7.88985C105.113 7.52306 104.807 7.15627 104.441 7.15627C104.38 7.15627 104.318 7.15627 104.318 7.15627H99.7964C99.4298 7.09513 99.0631 7.40079 99.0631 7.76758C99.0631 7.82872 99.0631 7.88985 99.0631 7.95098V9.96833C99.002 10.3351 99.3076 10.7019 99.6742 10.763C99.7353 10.763 99.7964 10.763 99.8576 10.763H101.507V24.0898H98.5132C98.1465 24.0287 97.7799 24.3343 97.7188 24.7011C97.7188 24.7623 97.7188 24.8234 97.7188 24.8845V26.9019C97.6577 27.2687 97.9632 27.6355 98.3298 27.6966C98.391 27.6966 98.4521 27.6966 98.5132 27.6966H106.702C107.068 27.7577 107.435 27.4521 107.496 27.0853C107.496 27.0241 107.496 26.963 107.496 26.9019V24.8234C107.557 24.4566 107.252 24.0898 106.885 24.0287C106.824 24.0287 106.763 24.0287 106.702 24.0287Z" fill="currentColor"></path><path d="M122.591 17.183H120.635C120.269 17.1219 119.902 17.4275 119.841 17.7943C119.841 17.8555 119.841 17.9166 119.841 17.9777V21.7679C119.902 23.1739 118.802 24.3966 117.396 24.4577C115.441 24.4577 114.585 23.663 114.585 21.7068V10.703H119.352C119.719 10.7641 120.085 10.4585 120.146 10.0917C120.146 10.0306 120.146 9.96943 120.146 9.9083V7.89095C120.207 7.52416 119.902 7.15736 119.535 7.15736C119.474 7.15736 119.413 7.15736 119.413 7.15736H114.647V2.93926C114.708 2.57247 114.463 2.20568 114.036 2.14455C113.974 2.14455 113.913 2.14455 113.852 2.14455H111.775C111.408 2.08342 111.041 2.38907 110.98 2.75587C110.98 2.817 110.98 2.87813 110.98 2.93926V7.2185H108.78C108.414 7.15737 108.047 7.46302 108.047 7.82982C108.047 7.89095 108.047 7.89095 108.047 7.95208V9.96943C107.986 10.3362 108.291 10.703 108.658 10.7641C108.719 10.7641 108.78 10.7641 108.841 10.7641H111.041V21.9513C111.041 25.6192 113.424 28.0033 117.152 28.0033C121.002 28.0033 123.446 25.6803 123.446 22.1347V18.0388C123.507 17.6721 123.202 17.3053 122.835 17.2441C122.774 17.183 122.713 17.183 122.591 17.183Z" fill="currentColor"></path></g><defs><clipPath id="clip0_11087_40938"><rect width="123.455" height="28" fill="currentColor"></rect></clipPath></defs></svg></a><style data-emotion="css i9yqnx">.css-i9yqnx{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;color:var(--chakra-colors-white);gap:var(--chakra-space-4);-webkit-box-pack:right;-ms-flex-pack:right;-webkit-justify-content:right;justify-content:right;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:var(--chakra-colors-heroBg);width:100%;height:100%;}</style><div flex-wrap="wrap" class="css-i9yqnx"><style data-emotion="css 1cyhlyk">.css-1cyhlyk{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;
118-webkit-justify-content:center;justify-content:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;white-space:nowrap;vertical-align:middle;outline:2px solid transparent;outline-offset:2px;line-height:var(--chakra-lineHeights-lg);border-radius:0px;font-weight:var(--chakra-fontWeights-normal);transition-property:var(--chakra-transition-property-common);transition-duration:var(--chakra-transition-duration-normal);border:var(--chakra-borders-none);variant:primary;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;height:44px;min-width:var(--chakra-sizes-8);font-size:var(--chakra-fontSizes-xs);-webkit-padding-start:var(--chakra-space-1);padding-inline-start:var(--chakra-space-1);-webkit-padding-end:var(--chakra-space-1);padding-inline-end:var(--chakra-space-1);padding-top:var(--chakra-space-1);padding-bottom:var(--chakra-space-1);background:var(--chakra-colors-transparent);-webkit-transition:-webkit-transform 0.3s ease;transition:transform 0.3s ease;color:var(--chakra-colors-white);overflow:hidden;}@media screen and (min-width: 48em){.css-1cyhlyk{line-height:var(--chakra-lineHeights-xl);font-size:var(--chakra-fontSizes-sm);}}.css-1cyhlyk:disabled,.css-1cyhlyk[disabled],.css-1cyhlyk[aria-disabled=true],.css-1cyhlyk[data-disabled]{opacity:0.2;cursor:pointer;box-shadow:var(--chakra-shadows-none);background-color:var(--chakra-colors-brand-bg5);}.css-1cyhlyk:hover,.css-1cyhlyk[data-hover]{-webkit-text-decoration:underline;text-decoration:underline;text-underline-offset:13px;text-decoration-thickness:1px;}.css-1cyhlyk:hover:disabled,.css-1cyhlyk[data-hover]:disabled,.css-1cyhlyk:hover[disabled],.css-1cyhlyk[data-hover][disabled],.css-1cyhlyk:hover[aria-disabled=true],.css-1cyhlyk[data-hover][aria-disabled=true],.css-1cyhlyk:hover[data-disabled],.css-1cyhlyk[data-hover][data-disabled]{background:initial;background-color:var(--chakra-colors-brand-bg5);opacity:0.2;}.css-1cyhlyk:focus,.css-1cyhlyk[data-focus]{outline:2px solid transparent;outline-offset:2px;}.css-1cyhlyk:focus-visible,.css-1cyhlyk[data-focus-visible]{outline-color:var(--chakra-colors-black);outline-offset:2px;outline:2px solid;box-shadow:var(--chakra-shadows-none);}</style><button type="button" class="chakra-button css-1cyhlyk" role="group"><style data-emotion="css ide1f0">.css-ide1f0{line-height:var(--chakra-lineHeights-lg);font-size:var(--chakra-fontSizes-sm);}@media screen and (min-width: 48em){.css-ide1f0{line-height:var(--chakra-lineHeights-xl);font-size:var(--chakra-fontSizes-xl);}}</style><span class="chakra-text css-ide1f0">Szukaj</span><style data-emotion="css 1hzyiq5">.css-1hzyiq5{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;-webkit-margin-start:0.5rem;margin-inline-start:0.5rem;}</style><span class="chakra-button__icon css-1hzyiq5"><style data-emotion="css onkibi">.css-onkibi{width:1em;height:1em;display:inline-block;line-height:1em;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;color:currentColor;vertical-align:middle;}</style><svg viewBox="0 0 20 20" focusable="false" class="chakra-icon css-onkibi" aria-hidden="true"><path fill="none" stroke="currentColor" stroke-width="1.425" d="M13.7618 13.7618C10.8615 16.662 6.15926 16.662 3.259 13.7618C0.358748 10.8615 0.358748 6.15926 3.259 3.259C6.15926 0.358748 10.8615 0.358748 13.7618 3.259C16.662 6.15926 16.662 10.8615 13.7618 13.7618Z"></path><line x1="13.7537" y1="13.4232" x2="18.4933" y2="18.1628" stroke="currentColor" stroke-width="1.425"></line></svg></span></button><style data-emotion="css qyag7q">.css-qyag7q{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;white-space:nowrap;vertical-align:middle;outline:2px solid transparent;outline-offset:2px;line-height:var(--chakra-lineHeights-lg);border-radius:0px;font-weight:var(--chakra-fontWeights-normal);transition-property:var(--chakra-transition-property-common);transition-duration:var(--chakra-transition-duration-normal);border:var(--chakra-borders-none);variant:primary;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;height:44px;min-width:var(--chakra-sizes-8);font-size:var(--chakra-fontSizes-xs);-webkit-padding-start:var(--chakra-space-1);padding-inline-start:var(--chakra-space-1);-webkit-padding-end:var(--chakra-space-1);padding-inline-end:var(--chakra-space-1);padding-top:var(--chakra-space-1);padding-bottom:var(--chakra-space-1);background:var(--chakra-colors-transparent);-webkit-transition:-webkit-transform 0.3s ease;transition:transform 0.3s ease;color:var(--chakra-colors-white);}@media screen and (min-width: 48em){.css-qyag7q{line-height:var(--chakra-lineHeights-xl);font-size:var(--chakra-fontSizes-sm);}}.css-qyag7q:disabled,.css-qyag7q[disabled],.css-qyag7q[aria-disabled=true],.css-qyag7q[data-disabled]{opacity:0.2;cursor:pointer;box-shadow:var(--chakra-shadows-none);background-color:var(--chakra-colors-brand-bg5);}.css-qyag7q:hover,.css-qyag7q[data-hover]{-webkit-text-decoration:underline;text-decoration:underline;text-underline-offset:13px;text-decoration-thickness:1px;}.css-qyag7q:hover:disabled,.css-qyag7q[data-hover]:disabled,.css-qyag7q:hover[disabled],.css-qyag7q[data-hover][disabled],.css-qyag7q:hover[aria-disabled=true],.css-qyag7q[data-hover][aria-disabled=true],.css-qyag7q:hover[data-disabled],.css-qyag7q[data-hover][data-disabled]{background:initial;background-color:var(--chakra-colors-brand-bg5);opacity:0.2;}.css-qyag7q:focus,.css-qyag7q[data-focus]{outline:2px solid transparent;outline-offset:2px;}.css-qyag7q:focus-visible,.css-qyag7q[data-focus-visible]{outline-color:var(--chakra-colors-black);outline-offset:2px;outline:2px solid;box-shadow:var(--chakra-shadows-none);}</style><button type="button" class="chakra-button css-qyag7q" role="group" data-critical-header="menu-toggle" id="mainmenu-openbtn" aria-expanded="false" aria-controls="disclosure-:R4pf6:"><span class="chakra-text css-ide1f0">Menu</span><span class="chakra-button__icon css-1hzyiq5"><svg viewBox="0 0 27 24" focusable="false" class="chakra-icon css-onkibi" aria-hidden="true"><rect x="0.800049" y="1.0293" width="25.6" height="3.2" fill="currentColor"></rect><rect x="0.800049" y="10.6294" width="25.6" height="3.2" fill="currentColor"></rect><rect x="0.800049" y="20.2295" width="25.6" height="3.2" fill="currentColor"></rect></svg></span></button></div></div></div></header></div><div data-focus-guard="true" tabindex="-1" style="width:1px;height:0px;padding:0;overflow:hidden;position:fixed;top:1px;left:1px"></div><style data-emotion="css t8p16t">.css-t8p16t{position:relative;z-index:4;}</style><div class="css-t8p16t"><style data-emotion="css 22294g">.css-22294g{overflow-x:hidden;width:100%;height:100%;z-index:4;background:var(--chakra-colors-pageBg);}</style><main id="main-content" tabindex="-1" class="css-22294g"><div class="StartPage css-0"><div data-critical="startpage" class="css-0"><style data-emotion="css 1k83qh1">.css-1k83qh1{position:relative;height:100%;min-width:100%;background-color:#0B0B26;color:var(--chakra-colors-brand-primary);padding-bottom:var(--chakra-space-6);}@media screen and (min-width: 48em){.css-1k83qh1{min-width:100vw;padding-bottom:var(--chakra-space-8);}}</style><div class="css-1k83qh1"><style data-emotion="css 1fsunuh">.css-1fsunuh{padding-top:var(--chakra-space-20);width:100%;}</style><div class="css-1fsunuh"><style data-emotion="css 2yirbu">.css-2yirbu{padding-right:20px;padding-left:20px;margin:0 auto;padding-bottom:0px;
118max-width:calc(1548px + 40px);padding-top:0px;}</style><div class="css-2yirbu"><style data-emotion="css 189o32x">.css-189o32x{font-family:var(--chakra-fonts-heading);font-weight:385;font-size:25px;line-height:32px;letter-spacing:0%;vertical-align:middle;text-align:start;width:100%;max-width:100%;padding-top:var(--chakra-space-2);padding-bottom:var(--chakra-space-4);text-wrap:balance;}@media screen and (min-width: 48em){.css-189o32x{font-size:40px;line-height:50px;padding-top:var(--chakra-space-7);}}@media screen and (min-width: 62em){.css-189o32x{max-width:80%;}}</style><h1 class="chakra-heading css-189o32x" data-epi-edit="heading">Building the future takes a whole set of digitalization skills. Welcome to our world.</h1><style data-emotion="css idkz9h">.css-idkz9h{border:0;clip:rect(0, 0, 0, 0);height:1px;width:1px;margin:-1px;padding:0px;overflow:hidden;white-space:nowrap;position:absolute;}</style><span class="css-idkz9h"><style data-emotion="css 1ro5nve">.css-1ro5nve{font-size:var(--chakra-fontSizes-2xl);line-height:var(--chakra-lineHeights-xl);width:80%;margin:0px;}@media screen and (min-width: 48em){.css-1ro5nve{font-size:2.5rem;line-height:var(--chakra-lineHeights-4-5xl);margin:0 auto;}}</style><p class="chakra-text css-1ro5nve" data-epi-edit="preamble">Shaping a new future for your business takes a whole set of digitalization skills. We’ve got these skills. And we combine them to also create a sustainable and humane society. Welcome to our world.</p></span><style data-emotion="css 1w1vbxm">.css-1w1vbxm{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:start;-ms-flex-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start;}</style><div class="css-1w1vbxm"><style data-emotion="css w70rt0">.css-w70rt0{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:0.5rem;position:relative;width:100%;max-width:80%;padding-top:0px;padding-bottom:var(--chakra-space-4);}@media screen and (min-width: 48em){.css-w70rt0{padding-top:var(--chakra-space-3);padding-bottom:var(--chakra-space-8);}}</style><div class="chakra-stack css-w70rt0"><style data-emotion="css wq8yt1">.css-wq8yt1{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:var(--chakra-space-2);}@media screen and (min-width: 48em){.css-wq8yt1{-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;gap:var(--chakra-space-16);}}</style><ul class="css-wq8yt1"><li style="list-style-type:none"><style data-emotion="css od9ok6">.css-od9ok6{position:relative;-webkit-transition:-webkit-transform 0.3s ease;transition:transform 0.3s ease;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;font-weight:400;color:inherit;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;}.css-od9ok6 a[href]:not(.chakra-linkbox__overlay),.css-od9ok6 abbr[title]{position:relative;z-index:1;}</style><div role="group" class="chakra-linkbox css-od9ok6"><style data-emotion="css jwcswi">.css-jwcswi{position:static;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;border:var(--chakra-borders-none);border-bottom:1px solid transparent;border-color:var(--chakra-colors-transparent);-webkit-transition:inherit;transition:inherit;color:inherit;padding:0px;}.css-jwcswi::before{content:'';cursor:inherit;display:block;position:absolute;top:0px;left:0px;z-index:0;width:100%;height:100%;}[role=group]:hover .css-jwcswi,[role=group][data-hover] .css-jwcswi,[data-group]:hover .css-jwcswi,[data-group][data-hover] .css-jwcswi,.group:hover .css-jwcswi,.group[data-hover] .css-jwcswi{border-color:none;}.css-jwcswi:focus,.css-jwcswi[data-focus]{outline:2px solid transparent;outline-offset:2px;}.css-jwcswi:focus-visible,.css-jwcswi[data-focus-visible]{outline-color:var(--chakra-colors-black);outline-offset:2px;outline:2px solid;box-shadow:var(--chakra-shadows-none);}</style><a class="chakra-linkbox__overlay css-jwcswi" href="https://www.knowit.pl/Projekty/">Projekty</a><style data-emotion="css 5whgb6">.css-5whgb6{width:1em;height:1em;display:inline-block;line-height:1em;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;color:inherit;vertical-align:middle;opacity:1;margin-left:var(--chakra-space-3);-webkit-transition:inherit;transition:inherit;}[role=group]:hover .css-5whgb6,[role=group][data-hover] .css-5whgb6,[data-group]:hover .css-5whgb6,[data-group][data-hover] .css-5whgb6,.group:hover .css-5whgb6,.group[data-hover] .css-5whgb6{-webkit-transform:translateX(0.25rem);-moz-transform:translateX(0.25rem);-ms-transform:translateX(0.25rem);transform:translateX(0.25rem);}</style><svg viewBox="0 0 20 20" focusable="false" class="chakra-icon css-5whgb6" aria-hidden="true"><path d="M10.6364 2.35791C13.5455 5.26782 16.6667 8.10115 20 10.8579C16.4848 13.787 13.3636 16.6203 10.6364 19.3579L8.90909 17.7211L13.0606 14.1603C13.9697 13.3754 14.899 12.6766 15.8485 12.064C14.6364 12.0257 13.4141 12.0066 12.1818 12.0066H0V9.70926H12.1818C13.4141 9.70926 14.596 9.78584 15.7273 9.93899L13.0606 7.58426L8.90909 3.99473L10.6364 2.35791Z" fill="currentColor"></path></svg></div></li><li style="list-style-type:none"><div role="group" class="chakra-linkbox css-od9ok6"><a class="chakra-linkbox__overlay css-jwcswi" href="https://www.knowit.pl/wiadomosci/">Wiadomości</a><svg viewBox="0 0 20 20" focusable="false" class="chakra-icon css-5whgb6" aria-hidden="true"><path d="M10.6364 2.35791C13.5455 5.26782 16.6667 8.10115 20 10.8579C16.4848 13.787 13.3636 16.6203 10.6364 19.3579L8.90909 17.7211L13.0606 14.1603C13.9697 13.3754 14.899 12.6766 15.8485 12.064C14.6364 12.0257 13.4141 12.0066 12.1818 12.0066H0V9.70926H12.1818C13.4141 9.70926 14.596 9.78584 15.7273 9.93899L13.0606 7.58426L8.90909 3.99473L10.6364 2.35791Z" fill="currentColor"></path></svg></div></li></ul></div></div></div><div class="css-2yirbu"><style data-emotion="css msiela">.css-msiela{position:relative;overflow:hidden;border-radius:20px;padding:var(--chakra-space-5);height:50vh;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;
118-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;text-align:center;color:var(--chakra-colors-white);}</style><div class="css-msiela"><div><div id="animated-hero" style="position: absolute; inset: 0;"><canvas id="animated-hero__canvas" style="position: absolute; inset: 0; width: 100%; height: 100%;"></canvas>
119<div id="animated-hero__footer" class="auto-ink" style="text-align: start; position: absolute; bottom: 35px; left: 48px; max-width: 50%; color: #fff; z-index: 10; font-size: 20px; line-height: 28px; transition: color 0.25s linear;"><span id="animated-hero__status"> Design inspired by the Nordic sky above <span class="status-cluster" style="display: inline-flex; align-items: baseline; gap: 0.35em;"> Knowit, <span id="animated-hero__city">&bull;</span> <button id="animated-hero__rnd" aria-label="Randomize" style="width: 20px; height: 20px; background: none; border: none; padding: 0; cursor: pointer; color: inherit; transition: color 0.25s linear;"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewbox="0 0 15 18" fill="none" style="color: inherit; transition: color 0.25s linear;"> <path d="M7.87226 2.60254L5.98456 7.7373L5.04608 7.39258L6.44257 3.59082C5.59154 3.71764 4.77195 4.01502 4.03534 4.46875L3.8371 4.5957C2.85307 5.25325 2.07198 6.171 1.58026 7.24414L1.48554 7.45996C1.00255 8.62603 0.877087 9.90957 1.12323 11.1475L1.17304 11.3789C1.44599 12.5272 2.03258 13.5792 2.86933 14.416L3.03925 14.5801C3.90403 15.3831 4.97646 15.9311 6.1369 16.1621L6.3703 16.2041C7.53554 16.3913 8.73218 16.2526 9.82538 15.7998L10.0412 15.7051C11.1144 15.2134 12.0321 14.4323 12.6896 13.4482L12.8166 13.25C13.4357 12.2449 13.7648 11.0859 13.7648 9.90234H14.7648C14.7648 11.2713 14.3842 12.6119 13.6682 13.7744L13.5207 14.0039C12.7602 15.142 11.6994 16.0455 10.4582 16.6143L10.2072 16.7236C8.94267 17.2473 7.55895 17.408 6.21112 17.1914L5.94257 17.1436C4.60016 16.8765 3.35996 16.2414 2.35956 15.3125L2.1623 15.123C1.19449 14.1552 0.516127 12.9385 0.200381 11.6104L0.141787 11.3428C-0.142932 9.91105 0.00319747 8.42681 0.561709 7.07812L0.671084 6.82715C1.23985 5.586 2.14331 4.52515 3.28144 3.76465L3.51093 3.61719C4.11638 3.24426 4.77047 2.9629 5.45136 2.77832L2.39276 1.6543 2.73749 0.714844 7.87226 2.60254Z" style="fill: currentColor; transition: fill 0.25s linear, stroke 0.25s linear;"></path> </svg> </button> </span> </span></div>
120<div id="animated-hero__met" class="auto-ink" style="position: absolute; bottom: 35px; right: 48px; display: flex; align-items: center; gap: 19px; color: #fff; z-index: 10; font-size: 20px; line-height: 28px; transition: color 0.25s linear;">
121<div class="met-group" style="display: flex; align-items: center;"><svg xmlns="http://www.w3.org/2000/svg" width="23" height="16" viewbox="0 0 23 16" fill="none" style="color: inherit; transition: color 0.25s linear;"> <path d="M18.296 7.013C18.4372 5.61392 18.0324 4.21484 17.1609 3.09201C16.2894 1.96918 15.0157 1.20567 13.5919 0.951853C12.1675 0.697521 10.6975 0.972242 9.47212 1.72097C8.24675 2.4702 7.3558 3.63839 6.97569 4.99466C6.26273 4.89782 5.53663 4.9447 4.84309 5.13227C4.14955 5.31932 3.50275 5.64297 2.94361 6.08333C2.38448 6.5237 1.92455 7.07058 1.59222 7.69087C1.25988 8.31115 1.06251 8.99056 1.01263 9.6878C0.962758 10.385 1.06091 11.0849 1.30084 11.7439C1.54129 12.4029 1.91878 13.0063 2.40966 13.5181C2.90055 14.0293 3.49435 14.437 4.15482 14.7158C4.81476 14.9946 5.52719 15.1389 6.24698 15.1394H17.7972C18.8682 15.1399 19.8994 14.7433 20.679 14.0303C21.4592 13.3178 21.9291 12.3422 21.9926 11.3045C22.0561 10.2663 21.7091 9.24388 21.0219 8.44623C20.3346 7.64858 19.3597 7.13583 18.296 7.013Z" stroke="currentColor" stroke-width="1.26004" style="stroke: currentColor; transition: stroke 0.25s linear;"></path> </svg>
122<div id="animated-hero__weather" style="margin-left: 6px;">
123<div id="animated-hero__weather-track" style="display: flex; align-items: center; gap: 19px;"><span id="animated-hero__temp">&bull;</span> <span id="animated-hero__wind">&bull;</span> <span id="animated-hero__time">&bull;</span></div>
124</div>
125</div>
126</div>
127<script>
128    if (!window.__heroCanvasLoaded) {
129      window.__heroCanvasLoaded = true;
130      (function () {
131        window.addEventListener("load", () => {
132          const clamp = (x, a = 0, b = 1) => Math.max(a, Math.min(b, x));
133          const lerp = (a, b, t) => a + (b - a) * t;
134          const sigmoid = (x) => 1 / (1 + Math.exp(-x));
135          const tanh = Math.tanh;
136          const parseISO = (s) => new Date(s);
137
138          function hexToRgbNorm(hex) {
139            return {
140              r: parseInt(hex.slice(1, 3), 16) / 255,
141              g: parseInt(hex.slice(3, 5), 16) / 255,
142              b: parseInt(hex.slice(5, 7), 16) / 255,
143            };
144          }
145
146          // Colour conversions
147          function hslToHex(h, s, l) {
148            h /= 360;
149            s /= 100;
150            l /= 100;
151            let r, g, b;
152            if (s === 0) {
153              r = g = b = l;
154            } else {
155              const hue2rgb = (p, q, t) => {
156                if (t < 0) t += 1;
157                if (t > 1) t -= 1;
158                if (t < 1 / 6) return p + (q - p) * 6 * t;
159                if (t < 1 / 2) return q;
160                if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
161                return p;
162              };
163              const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
164              const p = 2 * l - q;
165              r = hue2rgb(p, q, h + 1 / 3);
166              g = hue2rgb(p, q, h);
167              b = hue2rgb(p, q, h - 1 / 3);
168            }
169            const toHex = (x) => {
170              const hex = Math.round(x * 255).toString(16);
171              return hex.length === 1 ? "0" + hex : hex;
172            };
173            return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
174          }
175
176          function hexToHsl(hex) {
177            const r = parseInt(hex.slice(1, 3), 16) / 255;
178            const g = parseInt(hex.slice(3, 5), 16) / 255;
179            const b = parseInt(hex.slice(5, 7), 16) / 255;
180            const max = Math.max(r, g, b);
181            const min = Math.min(r, g, b);
182            let h, s;
183            const l = (max + min) / 2;
184            if (max === min) {
185              h = s = 0;
186            } else {
187              const d = max - min;
188              s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
189              switch (max) {
190                case r:
191                  h = (g - b) / d + (g < b ? 6 : 0);
192                  break;
193                case g:
194                  h = (b - r) / d + 2;
195                  break;
196                default:
197                  h = (r - g) / d + 4;
198              }
199              h /= 6;
200            }
201            return { h: h * 360, s: s * 100, l: l * 100 };
202          }
203
204          const REFERENCE_PALETTES = {
205            CR: {
206              name: "CloudyRain",
207              bands: [
208                { hue: [240, 255], sat: [50, 65], light: [85, 95] },
209                { hue: [250, 265], sat: [45, 60], light: [70, 80] },
210                { hue: [250, 270], sat: [50, 70], light: [55, 65] },
211                { hue: [220, 240], sat: [65, 85], light: [45, 60] },
212                { hue: [180, 195], sat: [45, 65], light: [50, 65] },
213                { hue: [210, 230], sat: [70, 85], light: [35, 45] },
214              ],
215            },
216            HR: {
217              name: "HeavyRain",
218              bands: [
219                { hue: [115, 125], sat: [80, 95], light: [45, 60] },
220                { hue: [210, 230], sat: [50, 70], light: [55, 70] },
221                { hue: [240, 255], sat: [45, 65], light: [50, 65] },
222                { hue: [220, 235], sat: [55, 75], light: [45, 55] },
223                { hue: [185, 200], sat: [50, 70], light: [40, 55] },
224                { hue: [230, 250], sat: [80, 95], light: [25, 40] },
225              ],
226            },
227            EV: {
228              name: "Evening",
229              bands: [
230                { hue: [200, 215], sat: [65, 80], light: [40, 55] },
231                { hue: [175, 190], sat: [55, 75], light: [50, 65] },
232                { hue: [215, 235], sat: [40, 60], light: [60, 75] },
233                { hue: [240, 255], sat: [35, 55], light: [65, 75] },
234                { hue: [200, 220], sat: [25, 40], light: [80, 90] },
235              ],
236            },
237            MD: {
238              name: "MiddayClear",
239              bands: [
240                { hue: [235, 250], sat: [70, 85], light: [30, 45] },
241                { hue: [265, 280], sat: [45, 65], light: [40, 55] },
242                { hue: [290, 310], sat: [35, 55], light: [55, 70] },
243                { hue: [15, 30], sat: [50, 70], light: [60, 75] },
244                { hue: [270, 285], sat: [20, 35], light: [70, 85] },
245                { hue: [210, 225], sat: [35, 55], light: [65, 80] },
246              ],
247            },
248            AG: {
249              name: "Afterglow",
250              bands: [
251                { hue: [0, 15], sat: [10, 20], light: [85, 95] },
252                { hue: [20, 35], sat: [45, 65], light: [55, 70] },
253                { hue: [280, 300], sat: [40, 60], light: [50, 65] },
254                { hue: [250, 265], sat: [75, 90], light: [35, 50] },
255                { hue: [25, 40], sat: [35, 55], light: [65, 80] },
256              ],
257            },
258            SD: {
259              name: "SummerDusk",
260              bands: [
261                { hue: [250, 265], sat: [65, 80], light: [40, 55] },
262                { hue: [280, 295], sat: [45, 65], light: [50, 65] },
263                { hue: [310, 330], sat: [40, 60], light: [60, 75] },
264                { hue: [340, 355], sat: [35, 55], light: [65, 80] },
265                { hue: [10, 25], sat: [30, 50], light: [70, 85] },
266                { hue: [0, 15], sat: [15, 30], light: [80, 90] },
267              ],
268            },
269            CL: {
270              name: "Cloudy",
271              bands: [
272                { hue: [250, 265], sat: [25, 40], light: [85, 95] },
273                { hue: [255, 270], sat: [35, 50], light: [65, 80] },
274                { hue: [260, 275], sat: [40, 55], light: [55, 70] },
275                { hue: [250, 265], sat: [25, 40], light: [85, 95] },
276              ],
277            },
278            AU: {
279              name: "Aurora",
280              bands: [
281                { hue: [240, 260], sat: [70, 90], light: [10, 20] },
282                { hue: [120, 140], sat: [60, 80], light: [35, 50] },
283                { hue: [160, 180], sat: [50, 70], light: [40, 55] },
284                { hue: [280, 300], sat: [60, 80], light: [35, 50] },
285                { hue: [300, 320], sat: [65, 85], light: [30, 45] },
286              ],
287            },
288          };
289
290          const defaultFeeling = {
291            warmth: 0,
292            warmth_change: 0,
293            humidity: 0,
294            gloom: 0,
295            brightness: 0,
296            rain_intensity: 0,
297            rain_amount: 0,
298            precip_form: "none",
299            windiness: 0,
300            pressure_trend: 0,
301            sun_elevation: 0,
302            golden: 0,
303            twilight: 0,
304            night: 0,
305            uv: 0,
306          };
307
308          function generateHash(obj) {
309            let hash = 2166136261;
310            const str = JSON.stringify(obj, Object.keys(obj).sort());
311            for (let i = 0; i < str.length; i++) {
312              hash ^= str.charCodeAt(i);
313              hash = Math.imul(hash, 16777619);
314            }
315            return Math.abs(hash);
316          }
317
318          function buildGradient(feel) {
319            const hash = generateHash(feel);
320            const hashBytes = Array.from(
321              { length: 32 },
322              (_, i) => (hash * (i + 1) * 9999) & 0xff
323            );
324
325            // Derived parameters
326            const storm = clamp(feel.rain_intensity * 0.7 + feel.gloom * 0.3);
327            const drama =
328              storm * 0.4 +
329              feel.windiness * 0.3 +
330              Math.abs(feel.pressure_trend) * 0.3;
331            const serenity =
332              (1 - drama) * (1 - feel.rain_intensity) * feel.brightness;
333            const melancholy =
334              feel.gloom * feel.humidity * (1 - feel.brightness);
335            const electric =
336              (feel.rain_intensity > 0.7 ? feel.rain_intensity : 0) +
337              feel.twilight * feel.golden;
338            const mystical =
339              feel.twilight * (1 - feel.rain_intensity) * feel.humidity;
340            const haziness = feel.humidity * feel.gloom * (1 - feel.windiness);
341            const pressureDir = Math.sign(feel.pressure_trend);
342            const tempDrift = (feel.warmth_change + 1) / 2;
343            const gold = Math.max(feel.golden, feel.twilight);
344
345            const derived = {
346              storm,
347              drama,
348              serenity,
349              melancholy,
350              electric,
351              mystical,
352              haziness,
353              pressureDir,
354              tempDrift,
355              gold,
356            };
357
358            const palette = selectPalette(feel, derived, hashBytes[0]);
359
360            const stopData = generateStops(feel, derived, hashBytes);
361            const colors = generateColors(
362              feel,
363              derived,
364              palette,
365              stopData,
366              hashBytes
367            );
368
369            return validateAndCorrect({ colors, stops: stopData.stops }, feel);
370
371            function selectPalette(feel, d) {
372              if (feel.night === 1 && d.storm < 0.4 && feel.twilight < 0.2)
373                return REFERENCE_PALETTES.AU;
374              if (d.storm >= 0.5) return REFERENCE_PALETTES.HR;
375              if (d.gold >= 0.5)
376                return feel.gloom < 0.4
377                  ? REFERENCE_PALETTES.AG
378                  : REFERENCE_PALETTES.SD;
379              if (feel.brightness >= 0.6 && feel.gloom <= 0.3)
380                return REFERENCE_PALETTES.MD;
381              if (feel.rain_intensity > 0) return REFERENCE_PALETTES.CR;
382              if (feel.gloom > 0.4) return REFERENCE_PALETTES.CL;
383              return feel.warmth < 0.4
384                ? REFERENCE_PALETTES.EV
385                : REFERENCE_PALETTES.SD;
386            }
387
388            function generateStops(feel, d, hb) {
389              // Determine stop count
390              let count =
391                6 +
392                (d.drama > 0.7) -
393                (d.haziness > 0.7) +
394                (feel.windiness > 0.8) +
395                (d.mystical > 0.6);
396              count = Math.max(4, Math.min(8, count));
397
398              let pattern = "balanced";
399              if (d.drama > 0.6) pattern = "dramatic";
400              else if (d.serenity > 0.7) pattern = "flowing";
401              else if (d.electric > 0.6) pattern = "horizon";
402              else if (d.melancholy > 0.6) pattern = "weighted";
403
404              // base stops generator map
405              const gens = {
406                dramatic: (c) => {
407                  const s = [0];
408                  const z1 = 0.35 + (hb[5] / 255) * 0.1;
409                  const z2 = 0.65 + (hb[6] / 255) * 0.1;
410                  if (c <= 5) s.push(z1, z1 + 0.06, 1);
411                  else if (c === 6) s.push(0.2, z1, z1 + 0.05, z2, 1);
412                  else if (c === 7)
413                    s.push(0.15, z1, z1 + 0.05, 0.5, z2, z2 + 0.05, 1);
414                  else s.push(0.1, 0.25, z1, z1 + 0.05, 0.55, z2, z2 + 0.05, 1);
415                  return s;
416                },
417                flowing: (c) =>
418                  Array.from({ length: c }, (_, i) => i / (c - 1)),
419                horizon: (c) => {
420                  const h = 0.4 + feel.sun_elevation * 0.2;
421                  const s = [0, h - 0.05, h + 0.05, 1];
422                  if (c <= 4) return s;
423                  const before = Math.floor((c - 3) / 2);
424                  const after = c - 3 - before;
425                  const add = [];
426                  for (let i = 1; i <= before; i++)
427                    add.push(h * (i / (before + 1)));
428                  add.push(h - 0.04, h + 0.04);
429                  for (let i = 1; i <= after; i++)
430                    add.push(h + (1 - h) * (i / (after + 1)));
431                  add.push(1);
432                  return [0, ...add];
433                },
434                weighted: (c) => {
435                  const w = 0.7;
436                  const s = [0];
437                  for (let i = 1; i < c - 1; i++) {
438                    const t = i / (c - 1);
439                    const eased = t * t * (3 - 2 * t);
440                    s.push(eased * w + t * (1 - w));
441                  }
442                  s.push(1);
443                  return s;
444                },
445                balanced: (c) => {
446                  const acc = 0.3 + (hb[7] / 255) * 0.4;
447                  return Array.from({ length: c }, (_, i) => {
448                    let p = i / (c - 1);
449                    if (i > 0 && i < c - 1 && Math.abs(p - acc) < 0.15)
450                      p = acc + (p - acc) * 0.5;
451                    return p;
452                  });
453                },
454              };
455
456              let stops = gens[pattern](count);
457
458              // Jitter & skew
459              stops = stops.map((s, i) =>
460                i === 0 || i === stops.length - 1
461                  ? s
462                  : clamp(s + (hb[i + 8] / 255 - 0.5) * 0.03 * feel.windiness)
463              );
464              const skew = pressureDir * 0.05 + (tempDrift - 0.5) * 0.03;
465              stops = stops.map((s, i) =>
466                i === 0 || i === stops.length - 1
467                  ? s
468                  : clamp(s + skew * (1 - Math.abs(2 * s - 1)))
469              );
470
471              return { stops, pattern, count };
472            }
473
474            function generateColors(feel, d, palette, stopData, hb) {
475              const assignments = assignBands(palette, stopData, d, hb);
476              return assignments.map((bandIdx, i) =>
477                generateColorFromBand(palette.bands[bandIdx], i)
478              );
479
480              function assignBands(palette, sd, d, hb) {
481                const bCount = palette.bands.length;
482                const a = [];
483                if (palette.name === "Aurora") {
484                  a.push(0);
485                  for (let i = 1; i < sd.count - 1; i++) {
486                    const t = (i - 1) / (sd.count - 2);
487                    a.push(1 + Math.floor(t * (bCount - 1)));
488                  }
489                  a.push(0);
490                  return a;
491                }
492                for (let i = 0; i < sd.count; i++) {
493                  if (
494                    sd.pattern === "dramatic" &&
495                    d.drama > 0.5 &&
496                    i > 0 &&
497                    sd.stops[i] - sd.stops[i - 1] < 0.08
498                  ) {
499                    a.push((a[i - 1] + Math.floor(bCount / 2)) % bCount);
500                  } else {
501                    const prog = sd.stops[i];
502                    const base = Math.floor(prog * (bCount - 1));
503                    const varOff = hb[i + 12] / 255 < 0.3 ? 1 : 0;
504                    const band = clamp(
505                      base + (hb[i + 13] % 2 ? varOff : -varOff),
506                      0,
507                      bCount - 1
508                    );
509                    a.push(band);
510                  }
511                }
512                return a;
513              }
514
515              function generateColorFromBand(band, i) {
516                let hue = lerp(band.hue[0], band.hue[1], hb[i + 16] / 255);
517                let sat = lerp(band.sat[0], band.sat[1], hb[i + 17] / 25
5175);
518                let light = lerp(
519                  band.light[0],
520                  band.light[1],
521                  hb[i + 18] / 255
522                );
523
524                // Weather tweaks
525                hue += (feel.warmth - 0.5) * 12; // warmth shift
526                if (feel.rain_intensity && hue >= 180 && hue <= 200)
527                  sat +=
528                    feel.rain_intensity *
529                    15 *
530                    Math.pow(feel.rain_intensity, 0.3);
531                sat = Math.max(30, sat - d.haziness * 15);
532                light = Math.min(95, light + feel.brightness ** 2 * 15);
533                if (d.gold && hue >= 10 && hue <= 40) {
534                  sat += d.gold * 20;
535                  light += d.gold * 10;
536                }
537                if (feel.night && i !== 0 && i !== stopData.count - 1)
538                  light = Math.max(35, light);
539                if (
540                  stopData.pattern === "dramatic" &&
541                  i &&
542                  stopData.stops[i] - stopData.stops[i - 1] < 0.08
543                )
544                  sat = Math.min(85, sat + 20);
545                if (feel.precip_form === "snow") {
546                  if (hue >= 115 && hue <= 140) {
547                    hue += 40;
548                    sat *= 0.7;
549                  }
550                  sat = Math.min(70, sat);
551                  light += 5;
552                }
553                if (feel.gloom > 0.5)
554                  light = 50 + (light - 50) * (1 - feel.gloom * 0.4);
555                if (!feel.night && light < 35) light = 35;
556                if (sat < 40 && light < 65) light = 65;
557
558                return hslToHex(
559                  ((hue % 360) + 360) % 360,
560                  clamp(sat, 0, 100),
561                  clamp(light, 0, 100)
562                );
563              }
564            }
565
566            function validateAndCorrect(data, feel) {
567              let { colors, stops } = data;
568              const hsls = colors.map(hexToHsl);
569              const spans = {
570                hue:
571                  Math.max(...hsls.map((c) => c.h)) -
572                  Math.min(...hsls.map((c) => c.h)),
573                sat:
574                  Math.max(...hsls.map((c) => c.s)) -
575                  Math.min(...hsls.map((c) => c.s)),
576                light:
577                  Math.max(...hsls.map((c) => c.l)) -
578                  Math.min(...hsls.map((c) => c.l)),
579              };
580
581              const interest =
582                spans.hue >= 30 ||
583                spans.sat >= 40 ||
584                spans.light >= 40 ||
585                stops.some((s, i) => i && s - stops[i - 1] <= 0.08);
586              if (!interest) {
587                const maxSatIdx = hsls.reduce(
588                  (m, c, i, arr) => (c.s > arr[m].s ? i : m),
589                  0
590                );
591                const minSatIdx = hsls.reduce(
592                  (m, c, i, arr) => (c.s < arr[m].s ? i : m),
593                  0
594                );
595                hsls[maxSatIdx].s = Math.min(85, hsls[maxSatIdx].s + 25);
596                hsls[minSatIdx].s = Math.max(30, hsls[minSatIdx].s - 15);
597                colors[maxSatIdx] = hslToHex(
598                  hsls[maxSatIdx].h,
599                  hsls[maxSatIdx].s,
600                  hsls[maxSatIdx].l
601                );
602                colors[minSatIdx] = hslToHex(
603                  hsls[minSatIdx].h,
604                  hsls[minSatIdx].s,
605                  hsls[minSatIdx].l
606                );
607              }
608
609              // Forbidden color combinations
610              const forb = [
611                [
612                  [115, 140],
613                  [0, 40],
614                ],
615                [
616                  [115, 140],
617                  [340, 360],
618                ],
619                [
620                  [60, 80],
621                  [280, 300],
622                ],
623              ];
624              for (let i = 1; i < colors.length; i++) {
625                const a = hsls[i - 1].h;
626                const b = hsls[i].h;
627                forb.forEach(([r1, r2]) => {
628                  if (
629                    (a >= r1[0] && a <= r1[1] && b >= r2[0] && b <= r2[1]) ||
630                    (a >= r2[0] && a <= r2[1] && b >= r1[0] && b <= r1[1])
631                  ) {
632                    const bridge = hslToHex(270, 30, 70);
633                    colors.splice(i, 0, bridge);
634                    stops.splice(i, 0, (stops[i - 1] + stops[i]) / 2);
635                    hsls.splice(i, 0, hexToHsl(bridge));
636                  }
637                });
638              }
639
640              // Green needs blue/purple
641              if (
642                hsls.some((c) => c.h >= 115 && c.h <= 140) &&
643                !hsls.some((c) => c.h >= 200 && c.h <= 280)
644              ) {
645                colors = colors.map((col) => {
646                  const hsl = hexToHsl(col);
647                  if (hsl.h >= 115 && hsl.h <= 140) {
648                    hsl.h = 180 + (hsl.h - 115) * 0.8;
649                    return hslToHex(hsl.h, hsl.s, hsl.l);
650                  }
651                  return col;
652                });
653              }
654
655              // Day‑light constraints
656              if (!feel.night) {
657                colors = colors.map((col) => {
658                  const hsl = hexToHsl(col);
659                  if (hsl.l < 35) hsl.l = 35;
660                  if (hsl.s < 40 && hsl.l < 65) hsl.l = 65;
661                  return hslToHex(hsl.h, hsl.s, hsl.l);
662                });
663              }
664
665              // Ensure ≥5 % stop gap & bounds
666              for (let i = 1; i < stops.length; i++) {
667                if (stops[i] - stops[i - 1] < 0.05) {
668                  const adj = (0.05 - (stops[i] - stops[i - 1])) / 2;
669                  if (i - 2 >= 0 && stops[i - 1] - stops[i - 2] < 0.05 + adj)
670                    stops[i] += adj * 2;
671                  else {
672                    stops[i - 1] -= adj;
673                    stops[i] += adj;
674                  }
675                }
676              }
677              stops = stops.map((s, idx) => clamp(s, 0, 1));
678              stops[0] = 0;
679              stops[stops.length - 1] = 1;
680
681              return { colors, stops };
682            }
683          }
684
685          // Weather "feel"
686          function calcFeel(agg, sun, nowT) {
687            const sunriseT = new Date(sun.properties.sunrise.time);
688            const sunsetT = new Date(sun.properties.sunset.time);
689            const elevFrac = solarElevationFrac(nowT, sunriseT, sunsetT);
690            const golden = clamp(1 - Math.abs(elevFrac - 0.08) / 0.08);
691            const twilight = clamp(1 - Math.abs(nowT - sunsetT) / 4.5e6);
692            const night = elevFrac <= 0 ? 1 : 0;
693            const AT = apparentTemp(agg.Tbar, agg.RHbar, agg.WSbar);
694            const warm = warmthScore(AT);
695            const warmChange = tanh(agg.deltaT / 4);
696            const humidityFeel = muggyIndex(agg.DPbar);
697            const windFeel =
698              sigmoid((agg.WSbar - 2) / 3) * (agg.Tbar < 10 ? 1.2 : 1);
699            const cloudFrac = agg.CCbar / 100;
700            const brightness = elevFrac * (1 - cloudFrac);
701            const gloom = clamp(1.2 * cloudFrac * (1 - elevFrac));
702            const rainIntensity = agg.PR1 > 0 ? sigmoid(agg.PR1max / 3) : 0;
703            const rainAmount = tanh(agg.PR6sum / 24);
704            const precipForm =
705              agg.Tbar <= 0
706                ? "snow"
707                : agg.Tbar < 2 && agg.RHbar > 90
708                ? "sleet"
709                : "rain";
710            const uvNorm = clamp(agg.UV / 11);
711            return {
712              warmth: warm,
713              warmth_change: warmChange,
714              humidity: humidityFeel,
715              gloom,
716              brightness,
717              rain_intensity: rainIntensity,
718              rain_amount: rainAmount,
719              precip_form: precipForm,
720              windiness: windFeel,
721              pressure_trend: tanh(agg.deltaP3h / 2),
722              sun_elevation: elevFrac,
723              golden,
724              twilight,
725              night,
726              uv: uvNorm,
727            };
728          }
729
730          function apparentTemp(T, RH, WS) {
731            const e = (RH / 100) * 6.105 * Math.exp((17.27 * T) / (237.7 + T));
732            return T + 0.33 * e - 0.7 * WS - 4.0;
733          }
734          function muggyIndex(dp) {
735            return clamp((dp - 10) / 14);
736          }
737          function warmthScore(AT) {
738            return clamp(sigmoid((AT - 15) / 10));
739          }
740          function solarElevationFrac(now, sunrise, sunset) {
741            const len = sunset - sunrise || 1;
742            const f = clamp((now - sunrise) / len);
743            return Math.sin(Math.PI * f);
744          }
745
746          async function fetchForecast(lat, lon) {
747            const fcRes = await fetch(
748              `https://api.met.no/weatherapi/locationforecast/2.0/complete?lat=${lat}&lon=${lon}`
749            );
750            if (!fcRes.ok) throw Error(`locationforecast ${fcRes.status}`);
751            const fc = await fcRes.json();
752            const sunRes = await fetch(
753              `https://api.met.no/weatherapi/sunrise/3.0/sun?lat=${lat}&lon=${lon}&date=${new Date()
754                .toISOString()
755                .slice(0, 10)}`
756            );
757            if (!sunRes.ok) throw Error(`sunrise ${sunRes.status}`);
758            const sun = await sunRes.json();
759            const start = new Date();
760            start.setUTCHours(0, 0, 0, 0);
761            const end = new Date(start);
762            end.setUTCDate(end.getUTCDate() + 1);
763            const pts = fc.properties.timeseries.filter((p) => {
764              const t = parseISO(p.time);
765              return t >
765= start && t < end;
766            });
767            const pull = (f) =>
768              pts.map((p) => p.data.instant.details[f] ?? null);
769            const mean = (a) => a.reduce((s, v) => s + v, 0) / a.length;
770            const agg = {
771              Tbar: mean(pull("air_temperature")),
772              DPbar: mean(pull("dew_point_temperature")),
773              RHbar: mean(pull("relative_humidity")),
774              Pbar: mean(pull("air_pressure_at_sea_level")),
775              CCbar: mean(pull("cloud_area_fraction")),
776              WSbar: mean(pull("wind_speed")),
777              UV: mean(pull("ultraviolet_index_clear_sky")),
778              PR1: pts[0].data.next_1_hours?.details?.precipitation_amount ?? 0,
779              PR1max: Math.max(
780                ...pts.map(
781                  (p) => p.data.next_1_hours?.details?.precipitation_amount ?? 0
782                )
783              ),
784              PR6sum: pts
785                .filter((_, i) => i % 6 === 0)
786                .reduce(
787                  (s, p) =>
788                    s +
789                    (p.data.next_6_hours?.details?.precipitation_amount ?? 0),
790                  0
791                ),
792              deltaP3h:
793                pull("air_pressure_at_sea_level").slice(-1)[0] -
794                pull("air_pressure_at_sea_level").slice(-4)[0],
795              deltaT:
796                mean(pull("air_temperature").slice(pts.length / 2)) -
797                mean(pull("air_temperature").slice(0, pts.length / 2)),
798            };
799            const nowT = parseISO(pts[0].time);
800            const feeling = calcFeel(agg, sun, nowT);
801            const first = pts[0].data.instant.details;
802            const p1h = pts[0].data.next_1_hours?.details ?? {};
803            return {
804              temp: first.air_temperature,
805              wind: first.wind_speed,
806              clouds: first.cloud_area_fraction / 100,
807              humidity: first.relative_humidity / 100,
808              precipAmount: p1h.precipitation_amount ?? 0,
809              precipType:
810                feeling.precip_form === "snow"
811                  ? "snow"
812                  : (p1h.precipitation_amount ?? 0) > 0
813                  ? "rain"
814                  : "none",
815              uvIndex: first.ultraviolet_index_clear_sky,
816              timeISO: pts[0].time,
817              sunriseISO: sun.properties.sunrise.time,
818              sunsetISO: sun.properties.sunset.time,
819              feeling,
820            };
821          }
822
823          const TIME_SCALE = 0.53,
824            WIND_SCALE = 3,
825            NOISE_FREQ = 0.45,
826            CLOUD_DETAIL = 0.65,
827            LERP = 0.05,
828            MAX_STOPS = 8,
829            MAX_GAPS = MAX_STOPS - 1;
830
831          const status = document.getElementById("animated-hero__status");
832          const cityEl = document.getElementById("animated-hero__city");
833          const tempEl = document.getElementById("animated-hero__temp");
834          const windEl = document.getElementById("animated-hero__wind");
835          const timeEl = document.getElementById("animated-hero__time");
836          const footer = document.getElementById("animated-hero__footer");
837          const rndBtn = document.getElementById("animated-hero__rnd");
838          const rndSvg = rndBtn.querySelector("svg");
839          const met = document.getElementById("animated-hero__met");
840          const weather = document.getElementById("animated-hero__weather");
841          const track = document.getElementById("animated-hero__weather-track");
842
843          const canv = document.getElementById("animated-hero__canvas");
844          const gl = canv.getContext("webgl");
845
846          let tickId = null;
847
848          let lowerContrast = "#fff";
849          let upperContrast = "#fff";
850
851          const deskCSS = {
852            footer: footer.style.cssText,
853            rndBtn: rndBtn.style.cssText,
854            rndSvg: rndSvg.style.cssText,
855            met: met.style.cssText,
856            weather: weather.style.cssText,
857            track: track.style.cssText,
858          };
859
860          function resize() {
861            canv.width = canv.clientWidth * devicePixelRatio;
862            canv.height = canv.clientHeight * devicePixelRatio;
863            gl.viewport(0, 0, canv.width, canv.height);
864            applyResponsive();
865          }
866          addEventListener("resize", resize);
867          resize();
868
869          const vs = `attribute vec2 p;varying vec2 vUv;void main(){vUv=(p+1.)*.5;gl_Position=vec4(p,0,1);} `;
870          const noise = `//	Simplex 3D Noise 
871        //	by Ian McEwan, Stefan Gustavson (https://github.com/stegu/webgl-noise)
872        //
873        vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);}
874        vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;}
875
876        float snoise(vec3 v){ 
877        const vec2  C = vec2(1.0/6.0, 1.0/3.0) ;
878        const vec4  D = vec4(0.0, 0.5, 1.0, 2.0);
879
880        // First corner
881        vec3 i  = floor(v + dot(v, C.yyy) );
882        vec3 x0 =   v - i + dot(i, C.xxx) ;
883
884        // Other corners
885        vec3 g = step(x0.yzx, x0.xyz);
886        vec3 l = 1.0 - g;
887        vec3 i1 = min( g.xyz, l.zxy );
888        vec3 i2 = max( g.xyz, l.zxy );
889
890        //  x0 = x0 - 0. + 0.0 * C 
891        vec3 x1 = x0 - i1 + 1.0 * C.xxx;
892        vec3 x2 = x0 - i2 + 2.0 * C.xxx;
893        vec3 x3 = x0 - 1. + 3.0 * C.xxx;
894
895        // Permutations
896        i = mod(i, 289.0 ); 
897        vec4 p = permute( permute( permute( 
898                    i.z + vec4(0.0, i1.z, i2.z, 1.0 ))
899                + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) 
900                + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));
901
902        // Gradients
903        // ( N*N points uniformly over a square, mapped onto an octahedron.)
904        float n_ = 1.0/7.0; // N=7
905        vec3  ns = n_ * D.wyz - D.xzx;
906
907        vec4 j = p - 49.0 * floor(p * ns.z *ns.z);  //  mod(p,N*N)
908
909        vec4 x_ = floor(j * ns.z);
910        vec4 y_ = floor(j - 7.0 * x_ );    // mod(j,N)
911
912        vec4 x = x_ *ns.x + ns.yyyy;
913        vec4 y = y_ *ns.x + ns.yyyy;
914        vec4 h = 1.0 - abs(x) - abs(y);
915
916        vec4 b0 = vec4( x.xy, y.xy );
917        vec4 b1 = vec4( x.zw, y.zw );
918
919        vec4 s0 = floor(b0)*2.0 + 1.0;
920        vec4 s1 = floor(b1)*2.0 + 1.0;
921        vec4 sh = -step(h, vec4(0.0));
922
923        vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;
924        vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;
925
926        vec3 p0 = vec3(a0.xy,h.x);
927        vec3 p1 = vec3(a0.zw,h.y);
928        vec3 p2 = vec3(a1.xy,h.z);
929        vec3 p3 = vec3(a1.zw,h.w);
930
931        //Normalise gradients
932        vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
933        p0 *= norm.x;
934        p1 *= norm.y;
935        p2 *= norm.z;
936        p3 *= norm.w;
937
938        // Mix final noise value
939        vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
940        m = m * m;
941        return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), 
942                                        dot(p2,x2), dot(p3,x3) ) );
943        }\n`;
944          const fs = `precision mediump float;varying vec2 vUv;uniform vec2 iResolution;uniform float iTime,uTimeScale,uWindScale,uNoiseFreq,uCloudDetail;uniform float uCloudCover,uWindNorm,uWindOffset;uniform vec3 uColor[${MAX_STOPS}];uniform float uStops[${
945            MAX_STOPS - 1
946          }];uniform float uStopCount;${noise}
947vec3 pal(float t){vec3 col=uColor[0];float prev=0.;int cnt=int(uStopCount+0.5);for(int i=1;i<${MAX_STOPS};i++){if(i>=cnt)break;float edge=smoothstep(prev,uStops[i-1],t);col=mix(col,uColor[i],edge);prev=uStops[i-1];}return col;}
948vec3 toSRGB(vec3 v){return pow(v,vec3(1./2.2));}
949void main(){vec2 uv=vUv;float t=iTime*uTimeScale;float base=snoise(vec3(uv*0.8*uNoiseFreq,t*0.1));vec2 wuv=uv;wuv.x-=uWindOffset;vec2 wind=vec2(snoise(vec3(wuv*2.*uNoiseFreq+t*0.2,t*0.5)),snoise(vec3(wuv*2.*uNoiseFreq-t*0.05,t*0.2)));uv+=wind*(pow(uWindNorm,0.7)*0.15+0.02)*uWindScale;uv.x+=base*0.05*uNoiseFreq;float cloudEff=max(uCloudCover,uWindNorm*0.5);float g=uv.y+snoise(vec3(uv*uCloudDetail*mix(1.,3.,cloudEff),t*0.1))*0.2*cloudEff;g=clamp(g,0.,1.);g+=sin(uv.y*10.*uNoiseFreq+t*0.2+base*2.*uNoiseFreq)*0.02;g=clamp(g,0.,1.);gl_FragColor=vec4(toSRGB(pal(g)),1.);} `;
950
951          function sh(type, src) {
952            const s = gl.createShader(type);
953            gl.shaderSource(s, src);
954            gl.compileShader(s);
955            if (!gl.getShaderParameter(s, gl.COMPILE_STATUS))
956              throw gl.getShaderInfoLog(s);
957            return s;
958          }
959          const prog = gl.createProgram();
960          gl.attachShader(prog, sh(gl.VERTEX_SHADER, vs));
961          gl.attachShader(prog, sh(gl.FRAGMENT_SHADER, fs));
962          gl.linkProgram(prog);
963          if (!gl.getProgramParameter(prog, gl.LINK_STATUS))
964            throw gl.getProgramInfoLog(prog);
965          gl.useProgram(prog);
966
967          const buf = gl.createBuffer();
968          gl.bindBuffer(gl.ARRAY_BUFFER, buf);
969          gl.bufferData(
970            gl.ARRAY_BUFFER,
971            new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),
972            gl.STATIC_DRAW
973          );
974          const loc = gl.getAttribLocation(prog, "p");
975          gl.enableVertexAttribArray(loc);
976          gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0);
977
978          const uni = {
979            res: gl.getUniformLocation(prog, "iResolution"),
980            time: gl.getUniformLocation(prog, "iTime"),
981            cloud: gl.getUniformLocation(prog, "uCloudCover"),
982            windNorm: gl.getUniformLocation(prog, "uWindNorm"),
983            windOff: gl.getUniformLocation(prog, "uWindOffset"),
984            stopCount: gl.getUniformLocation(prog, "uStopCount"),
985            stops: gl.getUniformLocation(prog, "uStops"),
986            colors: gl.getUniformLocation(prog, "uColor[0]"),
987            timeScale: gl.getUniformLocation(prog, "uTimeScale"),
988            windScale: gl.getUniformLocation(prog, "uWindScale"),
989            noiseFreq: gl.getUniformLocation(prog, "uNoiseFreq"),
990            cloudDet: gl.getUniformLocation(prog, "uCloudDetail"),
991          };
992          gl.uniform1f(uni.timeScale, TIME_SCALE);
993          gl.uniform1f(uni.windScale, WIND_SCALE);
994          gl.uniform1f(uni.noiseFreq, NOISE_FREQ);
995          gl.uniform1f(uni.cloudDet, CLOUD_DETAIL);
996
997          let anim = {
998            colors: Array.from({ length: MAX_STOPS }, () => ({
999              r: 1,
1000              g: 1,
1001              b: 1,
1002            })),
1003            stops: new Float32Array(MAX_GAPS).fill(1),
1004            stopCount: 4,
1005            cloud: 0,
1006            wind: 0.2,
1007          };
1008          let target = { ...anim };
1009          let windOffset = 0;
1010
1011          function uploadColors() {
1012            const flat = [];
1013            for (const c of anim.colors) {
1014              flat.push(c.r, c.g, c.b);
1015            }
1016            gl.uniform3fv(uni.colors, new Float32Array(flat));
1017          }
1018          function uploadStops() {
1019            gl.uniform1fv(uni.stops, anim.stops);
1020          }
1021          function uploadStatics() {
1022            gl.uniform1f(uni.stopCount, anim.stopCount);
1023            gl.uniform1f(uni.cloud, anim.cloud);
1024            gl.uniform1f(uni.windNorm, anim.wind);
1025          }
1026
1027          function applyResponsive() {
1028            const MOBILE_MAX = 600;
1029
1030            function desktop() {
1031              footer.style.cssText = deskCSS.footer;
1032              rndBtn.style.cssText = deskCSS.rndBtn;
1033              rndSvg.style.cssText = deskCSS.rndSvg;
1034              met.style.cssText = deskCSS.met;
1035              weather.style.cssText = deskCSS.weather;
1036              track.style.cssText = deskCSS.track;
1037              stopTicker();
1038              applyInk();
1039            }
1040
1041            function mobile() {
1042              footer.style.cssText = `
1043            ${deskCSS.footer}
1044            top:30px; bottom:auto; left:20px;
1045            font-size:16px; line-height:25px; max-width:60vw;`;
1046
1047              rndBtn.style.cssText = `${deskCSS.rndBtn} width:16px; height:16px;`;
1048              rndSvg.style.cssText = `${deskCSS.rndSvg} width:16px; height:16px;`;
1049
1050              met.style.cssText = `
1051            ${deskCSS.met}
1052            left:20px; right:auto; bottom:30px;
1053            font-size:16px; line-height:25px;`;
1054
1055              weather.style.cssText = `
1056            ${deskCSS.weather}
1057            overflow:hidden;
1058            height:${track.firstElementChild.offsetHeight}px;`;
1059
1060              track.style.cssText = `
1061            display:flex;
1062            flex-direction:column;
1063            gap:6px;
1064            will-change:transform;
1065            transform:translateY(0);`;
1066              startTicker();
1067              applyInk(true);
1068            }
1069
1070            (window.innerWidth <= MOBILE_MAX ? mobile : desktop)();
1071          }
1072
1073          function startTicker() {
1074            if (tickId) return;
1075
1076            tickId = setInterval(() => {
1077              track.style.transition = "transform .35s ease-out";
1078              track.style.transform = `translateY(-${track.firstElementChild.offsetHeight + 6}px)`;
1079
1080              track.addEventListener(
1081                "transitionend",
1082                function f() {
1083                  track.removeEventListener("transitionend", f);
1084
1085                  track.appendChild(track.firstElementChild);
1086
1087                  track.style.transition = "none";
1088                  track.style.transform = "translateY(0)";
1089                  void track.offsetHeight;
1090                },
1091                { once: true }
1092              );
1093            }, 5000);
1094          }
1095
1096          function stopTicker() {
1097            clearInterval(tickId);
1098            tickId = null;
1099            track.style.transition = "none";
1100            track.style.transform = "translateY(0)";
1101          }
1102
1103          const offices = [
1104            {
1105              city: "Stockholm",
1106              lat: 59.3293,
1107              lon: 18.0686,
1108              tz: "Europe/Stockholm",
1109            },
1110            {
1111              city: "Göteborg",
1112              lat: 57.7075,
1113              lon: 11.9675,
1114              tz: "Europe/Stockholm",
1115            },
1116            {
1117              city: "Malmö",
1118              lat: 55.6058,
1119              lon: 13.0358,
1120              tz: "Europe/Stockholm",
1121            },
1122            {
1123              city: "Jönköping",
1124              lat: 57.7828,
1125              lon: 14.1606,
1126              tz: "Europe/Stockholm",
1127            },
1128            {
1129              city: "Karlstad",
1130              lat: 59.3783,
1131              lon: 13.5042,
1132              tz: "Europe/Stockholm",
1133            },
1134            {
1135              city: "Karlskrona",
1136              lat: 56.1612,
1137              lon: 15.5869,
1138              tz: "Europe/Stockholm",
1139            },
1140            {
1141              city: "Linköping",
1142              lat: 58.4109,
1143              lon: 15.6216,
1144              tz: "Europe/Stockholm",
1145            },
1146            {
1147              city: "Luleå",
1148              lat: 65.5848,
1149              lon: 22.1547,
1150              tz: "Europe/Stockholm",
1151            },
1152            { city: "Lund", lat: 55.7047, lon: 13.191, tz: "Europe/Stockholm" },
1153            {
1154              city: "Borlänge",
1155              lat: 60.4847,
1156              lon: 15.426,
1157              tz: "Europe/Stockholm",
1158            },
1159            {
1160              city: "Gävle",
1161              lat: 60.6749,
1162              lon: 17.1413,
1163              tz: "Europe/Stockholm",
1164            },
1165            {
1166              city: "Helsingborg",
1167              lat: 56.0465,
1168              lon: 12.6945,
1169              tz: "Europe/Stockholm",
1170            },
1171            {
1172              city: "Sundsvall",
1173              lat: 62.3908,
1174              lon: 17.3069,
1175              tz: "Europe/Stockholm",
1176            },
1177            {
1178              city: "Uppsala",
1179              lat: 59.8586,
1180              lon: 17.6389,
1181              tz: "Europe/Stockholm",
1182            },
1183            {
1184              city: "Örebro",
1185              lat: 59.2741,
1186              lon: 15.2066,
1187              tz: "Europe/Stockholm",
1188            },
1189            {
1190              city: "Trollhättan",
1191              lat: 58.2837,
1192              lon: 12.2886,
1193              tz: "Europe/Stockholm",
1194            },
1195            { city: "Oslo", lat: 59.9139, lon: 10.7522, tz: "Europe/Oslo" },
1196            { city: "Bergen", lat: 60.3928, lon: 5.3239, tz: "Europe/Oslo" },
1197            { city: "Stavanger", lat: 58.969, lon: 5.7331, tz: "Europe/Oslo" },
1198            {
1199              city: "Kristiansand",
1200              lat: 58.1467,
1201              lon: 7.9956,
1202              tz: "Europe/Oslo",
1203            },
1204            { city: "Arendal", lat: 58.4614, lon: 8.772, tz: "Europe/Oslo" },
1205            { city: "Hamar", lat: 60.7945, lon: 11.067, tz: "Europe/Oslo" },
1206            {
1207              city: "København",
1208              lat: 55.6761,
1209              lon: 12.5683,
1210              tz: "Europe/Copenhagen",
1211            },
1212            {
1213              city: "Aarhus",
1214              lat: 56.1629,
1215              lon: 10.2039,
1216              tz: "Europe/Copenhagen",
1217            },
1218            {
1219              city: "Helsinki",
1220              lat: 60.1699,
1221              lon: 24.9384,
1222              tz: "Europe/Helsinki",
1223            },
1224            {
1225              city: "Tampere",
1226              lat: 61.4978,
1227              lon: 23.761,
1228              tz: "Europe/Helsinki",
1229            },
1230            {
1231              city: "Turku",
1232              lat: 60.4518,
1233              lon: 22.2673,
1234              tz: "Europe/Helsinki",
1235            },
1236            { city: "Oulu", lat: 65.0121, lon: 25.4651, tz: "Europe/Helsinki" },
1237            {
1238              city: "Warszawa",
1239              lat: 52.2297,
1240              lon: 21.0122,
1241              tz: "Europe/Warsaw",
1242            },
1243            {
1244              city: "Bydgoszcz",
1245              lat: 53.1235,
1246              lon: 18.0084,
1247              tz: "Europe/Warsaw",
1248            },
1249            { city: "Łódź", lat: 51.7592, lon: 19.455, tz: "Europe/Warsaw" },
1250            { city: "Bremen", lat: 53.0793, lon: 8.8017, tz: "Europe/Berlin" },
1251            {
1252              city: "Umeå",
1253              lat: 63.8274,
1254              lon: 20.2699,
1255              tz: "Europe/Stockholm",
1256            },
1257            {
1258              city: "Östersund",
1259              lat: 63.1743,
1260              lon: 14.6411,
1261              tz: "Europe/Stockholm",
1262            },
1263            {
1264              city: "Viby",
1265              lat: 56.1188,
1266              lon: 10.1399,
1267              tz: "Europe/Copenhagen",
1268            },
1269            {
1270              city: "Aalborg",
1271              lat: 57.0465,
1272              lon: 9.9225,
1273              tz: "Europe/Copenhagen",
1274            },
1275            {
1276              city: "Trondheim",
1277              lat: 63.4302,
1278              lon: 10.3829,
1279              tz: "Europe/Oslo",
1280            },
1281            { city: "Ålesund", lat: 62.4712, lon: 6.158, tz: "Europe/Oslo" },
1282          ];
1283          let lastIdx = -1;
1284          function pickOffice() {
1285            let i;
1286            do i = Math.floor(Math.random() * offices.length);
1287            while (i === lastIdx);
1288            lastIdx = i;
1289            return offices[i];
1290          }
1291          async function load() {
1292            const office = pickOffice();
1293            try {
1294              const wx = await fetchForecast(office.lat, office.lon);
1295              cityEl.textContent = office.city;
1296
1297              const timeStr = new Date().toLocaleTimeString("sv-SE", {
1298                hour: "2-digit",
1299                minute: "2-digit",
1300                hour12: false,
1301                timeZone: office.tz,
1302              });
1303
1304              // Update individual elements using textContent
1305              tempEl.textContent = wx.temp + "ºC";
1306              windEl.textContent = wx.wind + " m/s";
1307              timeEl.textContent = timeStr;
1308
1309              const pal = buildGradient(wx.feeling);
1310              // pad/trim
1311              while (pal.colors.length < MAX_STOPS)
1312                pal.colors.push(pal.colors[pal.colors.length - 1]);
1313              const cArr = pal.colors.slice(0, MAX_STOPS).map(hexToRgbNorm);
1314              target.colors = cArr;
1315              const st = pal.stops.slice(1);
1316              while (st.length < MAX_GAPS) st.push(1);
1317              target.stops = Float32Array.from(st);
1318              target.stopCount = pal.colors.length;
1319              target.cloud = wx.clouds;
1320              target.wind = clamp(wx.wind / 16, 0.02, 1);
1321
1322              sampleInk(pal);
1323            } catch (e) {
1324              status.textContent = "Error: " + e.message;
1325            }
1326          }
1327          (function initPlaceholder() {
1328            const pal = buildGradient(defaultFeeling);
1329
1330            // pad/trim to MAX_STOPS
1331            while (pal.colors.length < MAX_STOPS)
1332              pal.colors.push(pal.colors[pal.colors.length - 1]);
1333
1334            target.colors = pal.colors.slice(0, MAX_STOPS).map(hexToRgb
1334Norm);
1335            const st = pal.stops.slice(1);
1336            while (st.length < MAX_GAPS) st.push(1);
1337            target.stops = Float32Array.from(st);
1338            target.stopCount = pal.colors.length;
1339            target.cloud = 0;
1340            target.wind = 0.2;
1341
1342            sampleInk(pal);
1343          })();
1344          document.getElementById("animated-hero__rnd").onclick = load;
1345          load();
1346
1347          let prev = performance.now();
1348          function step(ts) {
1349            const dt = (ts - prev) / 1000;
1350            prev = ts;
1351            // interpolate colours
1352            for (let i = 0; i < MAX_STOPS; i++) {
1353              anim.colors[i].r = lerp(
1354                anim.colors[i].r,
1355                target.colors[i].r,
1356                LERP
1357              );
1358              anim.colors[i].g = lerp(
1359                anim.colors[i].g,
1360                target.colors[i].g,
1361                LERP
1362              );
1363              anim.colors[i].b = lerp(
1364                anim.colors[i].b,
1365                target.colors[i].b,
1366                LERP
1367              );
1368            }
1369            // interpolate stops
1370            for (let i = 0; i < MAX_GAPS; i++) {
1371              anim.stops[i] = lerp(anim.stops[i], target.stops[i], LERP);
1372            }
1373            anim.stopCount = lerp(anim.stopCount, target.stopCount, LERP);
1374            anim.cloud = lerp(anim.cloud, target.cloud, LERP);
1375            anim.wind = lerp(anim.wind, target.wind, LERP);
1376            windOffset += (0.1 + 0.75 * anim.wind) * TIME_SCALE * dt;
1377
1378            uploadColors();
1379            uploadStops();
1380            uploadStatics();
1381            gl.uniform2f(uni.res, canv.width, canv.height);
1382            gl.uniform1f(uni.time, ts / 1000);
1383            gl.uniform1f(uni.windOff, windOffset);
1384
1385            gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
1386            requestAnimationFrame(step);
1387          }
1388          uploadColors();
1389          uploadStops();
1390          uploadStatics();
1391
1392          function luminance(r, g, b) {
1393            // WCAG relative luminance
1394            return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;
1395          }
1396          function bestInk(r, g, b) {
1397            return luminance(r, g, b) > 0.53 ? "#000" : "#fff";
1398          }
1399
1400          function contrastFor(hex1, hex2) {
1401            const avg = [hex1, hex2]
1402              .map(hexToRgbNorm)
1403              .reduce(
1404                (a, c) => ({ r: a.r + c.r, g: a.g + c.g, b: a.b + c.b }),
1405                {
1406                  r: 0,
1407                  g: 0,
1408                  b: 0,
1409                }
1410              );
1411
1412            return bestInk(avg.r * 127.5, avg.g * 127.5, avg.b * 127.5);
1413          }
1414
1415          function sampleInk(pal) {
1416            lowerContrast = contrastFor(pal.colors[0], pal.colors[1]);
1417            upperContrast = contrastFor(
1418              pal.colors[pal.colors.length - 2],
1419              pal.colors[pal.colors.length - 1]
1420            );
1421            applyInk();
1422          }
1423
1424          function applyInk(mobile = false) {
1425            if (mobile) {
1426              footer.style.color = upperContrast;
1427              met.style.color = lowerContrast;
1428            } else {
1429              footer.style.color = lowerContrast;
1430              met.style.color = lowerContrast;
1431            }
1432          }
1433
1434          requestAnimationFrame(step);
1435        });
1436        window.addEventListener("pagehide", () => {
1437          window.__heroCanvasLoaded = false;
1438        });
1439      })();
1440    }
1441  </script>
1441
1442</div></div></div></div></div></div><style data-emotion="css j74872">.css-j74872{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:var(--chakra-space-12);}</style><div class="chakra-stack css-j74872"><section class="VideoBlock css-0"><style data-emotion="css whh5e5">.css-whh5e5{opacity:1;}</style><div class="css-whh5e5"><style data-emotion="css 1bbe9dr">.css-1bbe9dr{padding-top:0px;height:100%;}</style><div class="css-1bbe9dr"><style data-emotion="css 1gekn55">.css-1gekn55{padding-right:20px;padding-left:20px;margin:0 auto;height:100%;z-index:3;position:unset;max-width:calc(1150px + 40px);padding-bottom:0px;padding-top:var(--chakra-space-12);}@media screen and (min-width: 48em){.css-1gekn55{padding-top:var(--chakra-space-20);}}</style><div class="css-1gekn55"><style data-emotion="css 1ndkq8v">.css-1ndkq8v{position:relative;width:100%;}.css-1ndkq8v>*:not(style){overflow:hidden;position:absolute;top:0px;right:0px;bottom:0px;left:0px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;height:100%;}.css-1ndkq8v>img,.css-1ndkq8v>video{object-fit:cover;}.css-1ndkq8v::before{height:0px;content:"";display:block;padding-bottom:56.25%;}</style><div class="chakra-aspect-ratio css-1ndkq8v"><iframe style="border-radius:32px" src="https://www.youtube-nocookie.com/embed/YhoIC9E7G_g?enablejsapi=1&amp;rel=0" title="youtube-player" allow="" allowfullscreen="" referrerPolicy="strict-origin-when-cross-origin"></iframe></div></div></div></div></section><section class="CaseListingBlock css-0"><style data-emotion="css 7iaepa">.css-7iaepa{opacity:1;background:var(--chakra-colors-brand-case);border-radius:0px;}</style><div class="css-7iaepa"><div class="css-1bbe9dr"><style data-emotion="css w0s7sf">.css-w0s7sf{padding-right:20px;padding-left:20px;margin:0 auto;height:100%;z-index:3;position:unset;max-width:calc(1150px + 40px);padding-bottom:var(--chakra-space-12);padding-top:var(--chakra-space-12);}@media screen and (min-width: 48em){.css-w0s7sf{padding-bottom:var(--chakra-space-20);padding-top:var(--chakra-space-20);}}</style><div class="css-w0s7sf"><style data-emotion="css uqh2vk">.css-uqh2vk{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:var(--chakra-space-10);width:100%;}</style><div class="chakra-stack css-uqh2vk"><style data-emotion="css 8atqhb">.css-8atqhb{width:100%;}</style><div class="css-8atqhb"><style data-emotion="css 2jgdd6">.css-2jgdd6{position:relative;border-radius:32px;width:100%;}.css-2jgdd6 a[href]:not(.chakra-linkbox__overlay),.css-2jgdd6 abbr[title]{position:relative;z-index:1;}</style><article role="group" class="chakra-linkbox css-2jgdd6"><style data-emotion="css 189zp68">.css-189zp68{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:var(--chakra-space-2);width:100%;margin-bottom:var(--chakra-space-4);}</style><div class="chakra-stack css-189zp68"><style data-emotion="css qd8ok0">.css-qd8ok0{position:relative;background-color:var(--chakra-colors-transparent);border-radius:2rem;max-height:720px;}.css-qd8ok0>*:not(style){overflow:hidden;position:absolute;top:0px;right:0px;bottom:0px;left:0px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;height:100%;}.css-qd8ok0>img,.css-qd8ok0>video{object-fit:cover;}.css-qd8ok0::before{height:0px;content:"";display:block;padding-bottom:56.25%;}</style><div class="chakra-aspect-ratio css-qd8ok0"><img alt="" loading="lazy" decoding="async" data-nimg="fill" style="position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;object-fit:cover;color:transparent;border-radius:0.75rem;background-size:cover;background-position:50% 50%;background-repeat:no-repeat;background-image:url(&quot;data:image/svg+xml;charset=utf-8,%3Csvg xmlns=&#x27;http://www.w3.org/2000/svg&#x27; %3E%3Cfilter id=&#x27;b&#x27; color-interpolation-filters=&#x27;
1442sRGB&#x27;%3E%3CfeGaussianBlur stdDeviation=&#x27;20&#x27;/%3E%3CfeColorMatrix values=&#x27;1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 100 -1&#x27; result=&#x27;s&#x27;/%3E%3CfeFlood x=&#x27;0&#x27; y=&#x27;0&#x27; width=&#x27;100%25&#x27; height=&#x27;100%25&#x27;/%3E%3CfeComposite operator=&#x27;out&#x27; in=&#x27;s&#x27;/%3E%3CfeComposite in2=&#x27;SourceGraphic&#x27;/%3E%3CfeGaussianBlur stdDeviation=&#x27;20&#x27;/%3E%3C/filter%3E%3Cimage width=&#x27;100%25&#x27; height=&#x27;100%25&#x27; x=&#x27;0&#x27; y=&#x27;0&#x27; preserveAspectRatio=&#x27;xMidYMid slice&#x27; style=&#x27;filter: url(%23b);&#x27; href=&#x27;https://www.knowit.pl/globalassets/image-bank/removed-from-the-root/inteligentny-kask.png?width=10&#x27;/%3E%3C/svg%3E&quot;)" sizes="
1443    (max-width: 48em) 100vw,
1444    (max-width: 62em) 100vw,
1445    1150px
1446  " srcSet="/_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fglobalassets%2Fimage-bank%2Fremoved-from-the-root%2Finteligentny-kask.png&amp;w=640&amp;q=75 640w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fglobalassets%2Fimage-bank%2Fremoved-from-the-root%2Finteligentny-kask.png&amp;w=750&amp;q=75 750w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fglobalassets%2Fimage-bank%2Fremoved-from-the-root%2Finteligentny-kask.png&amp;w=828&amp;q=75 828w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fglobalassets%2Fimage-bank%2Fremoved-from-the-root%2Finteligentny-kask.png&amp;w=1080&amp;q=75 1080w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fglobalassets%2Fimage-bank%2Fremoved-from-the-root%2Finteligentny-kask.png&amp;w=1200&amp;q=75 1200w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fglobalassets%2Fimage-bank%2Fremoved-from-the-root%2Finteligentny-kask.png&amp;w=1920&amp;q=75 1920w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fglobalassets%2Fimage-bank%2Fremoved-from-the-root%2Finteligentny-kask.png&amp;w=2048&amp;q=75 2048w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fglobalassets%2Fimage-bank%2Fremoved-from-the-root%2Finteligentny-kask.png&amp;w=3840&amp;q=75 3840w" src="/_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fglobalassets%2Fimage-bank%2Fremoved-from-the-root%2Finteligentny-kask.png&amp;w=3840&amp;q=75"/></div><style data-emotion="css 1bx6qgl">.css-1bx6qgl{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin-top:var(--chakra-space-2);-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}</style><div class="css-1bx6qgl"><style data-emotion="css k008qs">.css-k008qs{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}</style><div class="css-k008qs"></div><style data-emotion="css 18bct4s">.css-18bct4s{width:1em;height:1em;display:inline-block;line-height:1em;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;color:currentColor;vertical-align:middle;margin-top:0px;-webkit-transition:0.3s ease;transition:0.3s ease;font-size:var(--chakra-fontSizes-xs);}@media screen and (min-width: 48em){.css-18bct4s{margin-top:var(--chakra-space-2);font-size:var(--chakra-fontSizes-md);}}[role=group]:hover .css-18bct4s,[role=group][data-hover] .css-18bct4s,[data-group]:hover .css-18bct4s,[data-group][data-hover] .css-18bct4s,.group:hover .css-18bct4s,.group[data-hover] .css-18bct4s{-webkit-transform:translateX(0.25rem);-moz-transform:translateX(0.25rem);-ms-transform:translateX(0.25rem);transform:translateX(0.25rem);}</style><svg viewBox="0 0 20 20" focusable="false" class="chakra-icon css-18bct4s" aria-hidden="true"><path d="M10.6364 2.35791C13.5455 5.26782 16.6667 8.10115 20 10.8579C16.4848 13.787 13.3636 16.6203 10.6364 19.3579L8.90909 17.7211L13.0606 14.1603C13.9697 13.3754 14.899 12.6766 15.8485 12.064C14.6364 12.0257 13.4141 12.0066 12.1818 12.0066H0V9.70926H12.1818C13.4141 9.70926 14.596 9.78584 15.7273 9.93899L13.0606 7.58426L8.90909 3.99473L10.6364 2.35791Z" fill="currentColor"></path></svg></div><style data-emotion="css uabxse">.css-uabxse{font-family:var(--chakra-fonts-heading);line-height:var(--chakra-lineHeights-xl);font-weight:var(--chakra-fontWeights-normal);font-size:var(--chakra-fontSizes-2xl);-webkit-transition:0.3s ease;transition:0.3s ease;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}@media screen and (min-width: 48em){.css-uabxse{line-height:var(--chakra-lineHeights-5xl);font-size:var(--chakra-fontSizes-6xl);}}[role=group]:hover .css-uabxse,[role=group][data-hover] .css-uabxse,[data-group]:hover .css-uabxse,[data-group][data-hover] .css-uabxse,.group:hover .css-uabxse,.group[data-hover] .css-uabxse{border-color:inherit;}</style><h2 class="chakra-heading css-uabxse"><style data-emotion="css 1h5w00s">.css-1h5w00s{position:static;z-index:10;}.css-1h5w00s::before{content:'';cursor:inherit;display:block;position:absolute;top:0px;left:0px;z-index:0;width:100%;height:100%;}.css-1h5w00s:focus,.css-1h5w00s[data-focus]{outline:2px solid transparent;outline-offset:2px;}.css-1h5w00s:focus-visible,.css-1h5w00s[data-focus-visible]{outline-color:var(--chakra-colors-black);outline-offset:2px;outline:2px solid;box-shadow:var(--chakra-shadows-none);display:inline-block;}.css-1h5w00s:hover,.css-1h5w00s[data-hover]{-webkit-text-decoration:underline;text-decoration:underline;}</style><a class="chakra-linkbox__overlay css-1h5w00s" href="/Projekty/inteligentny-kask-zadba-o-bezpieczestwo-na-budowie/">Inteligentny kask. Bezpieczeństwo pracowników na budowie</a></h2></div></article></div><style data-emotion="css v2ebsb">.css-v2ebsb{max-width:100%;width:100%;position:relative;}.css-v2ebsb .slider-frame{overflow:hidden!important;}.css-v2ebsb .slider-control-bottomcenter ul{top:4rem!important;}.css-v2ebsb .slider-control-bottomcenter .paging-item{padding:0 6px;}.css-v2ebsb .slider-control-bottomcenter .paging-item svg{width:100%;height:100%;fill:#C4C4C4;}.css-v2ebsb .slider-control-bottomcenter .paging-item.active svg{fill:#372BC5;}.css-v2ebsb .slider-control-bottomcenter .paging-item button{width:0.8rem;height:0.8rem;}@media screen and (min-width: 62em){.css-v2ebsb{width:calc(100% + 20px);}}@media screen and (max-width: 62em){.css-v2ebsb{margin-bottom:4rem;}}.css-v2ebsb .slider-container{width:100%;}
1446.css-v2ebsb.carousel-controls-after{position:relative;}.css-v2ebsb.carousel-controls-after .slide>div>div>div>div{margin-bottom:80px;}.css-v2ebsb.carousel-controls-after .slider-container+div{position:absolute;top:680px;}@media (width <= 768px){.css-v2ebsb.carousel-controls-after .slider-container+div{top:385px;}}</style><div overflow="hidden" class="css-v2ebsb"><div class="slider-container" style="position:relative"><div aria-live="polite" aria-atomic="true" style="position:absolute;width:1px;height:1px;overflow:hidden;padding:0;margin:-1px;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0" tabindex="-1">Slide 1 of 2</div><div class="slider-frame" style="overflow:hidden;width:100%;position:relative;outline:none;touch-action:pan-y;height:auto;transition:height 300ms ease-in-out;will-change:height;user-select:none" aria-label="carousel-slider" role="region" tabindex="-1"><div class="slider-list" style="width:166.66666666666669%;text-align:left;user-select:auto;display:flex"><div class="slide slide-current slide-visible" style="width:50%;height:auto;padding:0 0px;opacity:1"><style data-emotion="css gds9a0">.css-gds9a0{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;transition-delay:0s;opacity:1;}</style><div class="css-gds9a0"><style data-emotion="css 11uxmi8">.css-11uxmi8{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin-right:20px;width:100%;max-width:100%;}</style><div class="css-11uxmi8"><style data-emotion="css 1isv5wi">.css-1isv5wi{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1 1 calc(50% - 20px);-ms-flex:1 1 calc(50% - 20px);flex:1 1 calc(50% - 20px);}</style><div class="css-1isv5wi"><article role="group" class="chakra-linkbox css-2jgdd6"><style data-emotion="css 1nqar3d">.css-1nqar3d{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:var(--chakra-space-2);width:100%;margin-bottom:0px;}</style><div class="chakra-stack css-1nqar3d"><div class="chakra-aspect-ratio css-qd8ok0"><img alt="" loading="lazy" decoding="async" data-nimg="fill" style="position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;object-fit:cover;color:transparent;border-radius:0.75rem;background-size:cover;background-position:50% 50%;background-repeat:no-repeat;background-image:url(&quot;data:image/svg+xml;charset=utf-8,%3Csvg xmlns=&#x27;http://www.w3.org/2000/svg&#x27; %3E%3Cfilter id=&#x27;b&#x27; color-interpolation-filters=&#x27;sRGB&#x27;%3E%3CfeGaussianBlur stdDeviation=&#x27;20&#x27;/%3E%3CfeColorMatrix values=&#x27;1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 100 -1&#x27; result=&#x27;s&#x27;/%3E%3CfeFlood x=&#x27;0&#x27; y=&#x27;0&#x27; width=&#x27;100%25&#x27; height=&#x27;100%25&#x27;/%3E%3CfeComposite operator=&#x27;out&#x27; in=&#x27;s&#x27;/%3E%3CfeComposite in2=&#x27;SourceGraphic&#x27;/%3E%3CfeGaussianBlur stdDeviation=&#x27;20&#x27;/%3E%3C/filter%3E%3Cimage width=&#x27;100%25&#x27; height=&#x27;100%25&#x27; x=&#x27;0&#x27; y=&#x27;0&#x27; preserveAspectRatio=&#x27;xMidYMid slice&#x27; style=&#x27;filter: url(%23b);&#x27; href=&#x27;https://www.knowit.pl/contentassets/c07011616e6d4783a2e7cee62039a012/app-connect-800x450.jpg?width=10&#x27;/%3E%3C/svg%3E&quot;)" sizes="
1447    (max-width: 48em) 100vw,
1448    (max-width: 62em) 100vw,
1449    580px
1450  " srcSet="/_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fcontentassets%2Fc07011616e6d4783a2e7cee62039a012%2Fapp-connect-800x450.jpg&amp;w=640&amp;q=75 640w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fcontentassets%2Fc07011616e6d4783a2e7cee62039a012%2Fapp-connect-800x450.jpg&amp;w=750&amp;q=75 750w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fcontentassets%2Fc07011616e6d4783a2e7cee62039a012%2Fapp-connect-800x450.jpg&amp;w=828&amp;q=75 828w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fcontentassets%2Fc07011616e6d4783a2e7cee62039a012%2Fapp-connect-800x450.jpg&amp;w=1080&amp;q=75 1080w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fcontentassets%2Fc07011616e6d4783a2e7cee62039a012%2Fapp-connect-800x450.jpg&amp;w=1200&amp;q=75 1200w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fcontentassets%2Fc07011616e6d4783a2e7cee62039a012%2Fapp-connect-800x450.jpg&amp;w=1920&amp;q=75 1920w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fcontentassets%2Fc07011616e6d4783a2e7cee62039a012%2Fapp-connect-800x450.jpg&amp;w=2048&amp;q=75 2048w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fcontentassets%2Fc07011616e6d4783a2e7cee62039a012%2Fapp-connect-800x450.jpg&amp;w=3840&amp;q=75 3840w" src="/_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fcontentassets%2Fc07011616e6d4783a2e7cee62039a012%2Fapp-connect-800x450.jpg&amp;w=3840&amp;q=75"/></div><div class="css-1bx6qgl"><div class="css-k008qs"><style data-emotion="css n0kerw">.css-n0kerw{font-size:var(--chakra-fontSizes-3xs);line-height:var(--chakra-lineHeights-3xs);letter-spacing:1.68px;text-transform:uppercase;}@media screen and (min-width: 48em){.css-n0kerw{font-size:var(--chakra-fontSizes-2xs);line-height:var(--chakra-lineHeights-xs);}}</style><p class="chakra-text css-n0kerw">Husqvarna</p></div><svg viewBox="0 0 20 20" focusable="false" class="chakra-icon css-18bct4s" aria-hidden="true"><path d="M10.6364 2.35791C13.5455 5.26782 16.6667 8.10115 20 10.8579C16.4848 13.787 13.3636 16.6203 10.6364 19.3579L8.90909 17.7211L13.0606 14.1603C13.9697 13.3754 14.899 12.6766 15.8485 12.064C14.6364 12.0257 13.4141 12.0066 12.1818 12.0066H0V9.70926H12.1818C13.4141 9.70926 14.596 9.78584 15.7273 9.93899L13.0606 7.58426L8.90909 3.99473L10.6364 2.35791Z" fill="currentColor"></path></svg></div><style data-emotion="css eim6vu">.css-eim6vu{font-family:var(--chakra-fonts-heading);font-size:var(--chakra-fontSizes-5);line-height:var(--chakra-lineHeights-xl);font-weight:400;-webkit-transition:0.3s ease;transition:0.3s ease;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}@media screen and (min-width: 48em){.css-eim6vu{font-size:var(--chakra-fontSizes-2-5xl);line-height:var(--chakra-lineHeights-3xl);}}[role=group]:hover .css-eim6vu,[role=group][data-hover] .css-eim6vu,[data-group]:hover .css-eim6vu,[data-group][data-hover] .css-eim6vu,.group:hover .css-eim6vu,.group[data-hover] .css-eim6vu{border-color:inherit;}</style><h2 class="chakra-heading css-eim6vu"><a class="chakra-linkbox__overlay css-1h5w00s" href="/Projekty/husqvarna---autonomiczna-kosiarka/">Husqvarna - autonomiczna kosiarka</a></h2></div></article></div></div></div></div><div class="slide slide-visible" style="width:50%;height:auto;padding:0 0px;opacity:1"><div class="css-gds9a0"><div class="css-11uxmi8"><div class="css-1isv5wi"><article role="group" class="chakra-linkbox css-2jgdd6"><div class="chakra-stack css-1nqar3d"><div class="chakra-aspect-ratio css-qd8ok0"><img alt="" loading="lazy" decoding="async" data-nimg="fill" style="position:absolute;height:100%;width:100%;left:0;top:0;right:0;bottom:0;object-fit:cover;color:transparent;border-radius:0.75rem;background-size:cover;background-position:50% 50%;background-repeat:no-repeat;background-image:url(&quot;data:image/svg+xml;charset=utf-8,%3Csvg xmlns=&#x27;http://www.w3.org/2000/svg&#x27; %3E%3Cfilter id=&#x27;b&#x27; color-interpolation-filters=&#x27;
1450sRGB&#x27;%3E%3CfeGaussianBlur stdDeviation=&#x27;20&#x27;/%3E%3CfeColorMatrix values=&#x27;1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 100 -1&#x27; result=&#x27;s&#x27;/%3E%3CfeFlood x=&#x27;0&#x27; y=&#x27;0&#x27; width=&#x27;100%25&#x27; height=&#x27;100%25&#x27;/%3E%3CfeComposite operator=&#x27;out&#x27; in=&#x27;s&#x27;/%3E%3CfeComposite in2=&#x27;SourceGraphic&#x27;/%3E%3CfeGaussianBlur stdDeviation=&#x27;20&#x27;/%3E%3C/filter%3E%3Cimage width=&#x27;100%25&#x27; height=&#x27;100%25&#x27; x=&#x27;0&#x27; y=&#x27;0&#x27; preserveAspectRatio=&#x27;xMidYMid slice&#x27; style=&#x27;filter: url(%23b);&#x27; href=&#x27;https://www.knowit.pl/contentassets/da71dc45d94e4690a90b048f2e664b7b/hiab-1920x1080.jpg?width=10&#x27;/%3E%3C/svg%3E&quot;)" sizes="
1451    (max-width: 48em) 100vw,
1452    (max-width: 62em) 100vw,
1453    580px
1454  " srcSet="/_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fcontentassets%2Fda71dc45d94e4690a90b048f2e664b7b%2Fhiab-1920x1080.jpg&amp;w=640&amp;q=75 640w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fcontentassets%2Fda71dc45d94e4690a90b048f2e664b7b%2Fhiab-1920x1080.jpg&amp;w=750&amp;q=75 750w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fcontentassets%2Fda71dc45d94e4690a90b048f2e664b7b%2Fhiab-1920x1080.jpg&amp;w=828&amp;q=75 828w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fcontentassets%2Fda71dc45d94e4690a90b048f2e664b7b%2Fhiab-1920x1080.jpg&amp;w=1080&amp;q=75 1080w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fcontentassets%2Fda71dc45d94e4690a90b048f2e664b7b%2Fhiab-1920x1080.jpg&amp;w=1200&amp;q=75 1200w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fcontentassets%2Fda71dc45d94e4690a90b048f2e664b7b%2Fhiab-1920x1080.jpg&amp;w=1920&amp;q=75 1920w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fcontentassets%2Fda71dc45d94e4690a90b048f2e664b7b%2Fhiab-1920x1080.jpg&amp;w=2048&amp;q=75 2048w, /_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fcontentassets%2Fda71dc45d94e4690a90b048f2e664b7b%2Fhiab-1920x1080.jpg&amp;w=3840&amp;q=75 3840w" src="/_next/image/?url=https%3A%2F%2Fwww.knowit.pl%2Fcontentassets%2Fda71dc45d94e4690a90b048f2e664b7b%2Fhiab-1920x1080.jpg&amp;w=3840&amp;q=75"/></div><div class="css-1bx6qgl"><div class="css-k008qs"><p class="chakra-text css-n0kerw">HIAB</p></div><svg viewBox="0 0 20 20" focusable="false" class="chakra-icon css-18bct4s" aria-hidden="true"><path d="M10.6364 2.35791C13.5455 5.26782 16.6667 8.10115 20 10.8579C16.4848 13.787 13.3636 16.6203 10.6364 19.3579L8.90909 17.7211L13.0606 14.1603C13.9697 13.3754 14.899 12.6766 15.8485 12.064C14.6364 12.0257 13.4141 12.0066 12.1818 12.0066H0V9.70926H12.1818C13.4141 9.70926 14.596 9.78584 15.7273 9.93899L13.0606 7.58426L8.90909 3.99473L10.6364 2.35791Z" fill="currentColor"></path></svg></div><h2 class="chakra-heading css-eim6vu"><a class="chakra-linkbox__overlay css-1h5w00s" href="/Projekty/hiab-julia---konserwacja-predyktywna/">HIAB Julia - konserwacja predyktywna</a></h2></div></article></div></div></div></div></div></div></div></div></div><style data-emotion="css bxm9v3">.css-bxm9v3{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;margin-top:var(--chakra-space-8);}</style><div class="css-bxm9v3"><style data-emotion="css 13abcv5">.css-13abcv5{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;white-space:nowrap;vertical-align:middle;outline:2px solid transparent;outline-offset:2px;line-height:var(--chakra-lineHeights-lg);border-radius:8px;font-weight:var(--chakra-fontWeights-normal);transition-property:var(--chakra-transition-property-common);transition-duration:var(--chakra-transition-duration-normal);border:var(--chakra-borders-none);variant:primary;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;-webkit-transition:0.3s ease;transition:0.3s ease;height:52px;min-width:var(--chakra-sizes-12);font-size:var(--chakra-fontSizes-xs);-webkit-padding-start:0px;padding-inline-start:0px;-webkit-padding-end:0px;padding-inline-end:0px;padding-top:var(--chakra-space-4);padding-bottom:var(--chakra-space-4);background:var(--chakra-colors-transparent);color:inherit;border-bottom:unset;}@media screen and (min-width: 48em){.css-13abcv5{line-height:var(--chakra-lineHeights-xl);height:64px;font-size:var(--chakra-fontSizes-sm);}}.css-13abcv5:disabled,.css-13abcv5[disabled],.css-13abcv5[aria-disabled=true],.css-13abcv5[data-disabled]{opacity:0.2;cursor:pointer;box-shadow:var(--chakra-shadows-none);background-color:var(--chakra-colors-brand-bg5);}.css-13abcv5:hover,.css-13abcv5[data-hover]{border-bottom:unset;}.css-13abcv5:focus,.css-13abcv5[data-focus]{outline:2px solid transparent;outline-offset:2px;}.css-13abcv5:focus-visible,.css-13abcv5[data-focus-visible]{outline-color:var(--chakra-colors-black);outline-offset:2px;outline:2px solid;box-shadow:var(--chakra-shadows-none);}</style><a class="chakra-button css-13abcv5" href="/Projekty/">Wszystkie projekty<style data-emotion="css 1hzyiq5">
1454.css-1hzyiq5{display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;-webkit-margin-start:0.5rem;margin-inline-start:0.5rem;}</style><span class="chakra-button__icon css-1hzyiq5"><style data-emotion="css 1wq3x2a">.css-1wq3x2a{width:1em;height:1em;display:inline-block;line-height:1em;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;color:currentColor;vertical-align:middle;}[role=group]:hover .css-1wq3x2a,[role=group][data-hover] .css-1wq3x2a,[data-group]:hover .css-1wq3x2a,[data-group][data-hover] .css-1wq3x2a,.group:hover .css-1wq3x2a,.group[data-hover] .css-1wq3x2a{display:block;}</style><svg viewBox="0 0 19 18" focusable="false" class="chakra-icon css-1wq3x2a" aria-hidden="true"><path d="M8.61914 17.3791L8.6476 13.3589V9.91478H5.15907C3.67952 9.91478 2.12668 9.81621 0.744141 9.6908L0.744173 7.81665H8.6476V4.54881C8.6476 3.15145 8.75196 1.68488 8.88475 0.37915L10.8691 0.379181V7.81665L14.451 7.81665C15.9306 7.81665 17.3616 7.94209 18.7441 8.0675L18.7441 9.94165L14.4874 9.91478H10.8691L10.8691 13.3245C10.8691 14.7219 10.7363 16.0734 10.6035 17.3792L8.61914 17.3791Z" fill="currentColor"></path></svg></span></a></div></div></div></div></section><section class="NewsListingBlock css-0"><div class="css-whh5e5"><div class="css-1bbe9dr"><style data-emotion="css 16pwwvi">.css-16pwwvi{padding-right:20px;padding-left:20px;margin:0 auto;height:100%;z-index:3;position:unset;max-width:calc(1548px + 40px);padding-bottom:0px;padding-top:0px;}</style><div class="css-16pwwvi"><div class="css-0"><div class="css-whh5e5"><div class="css-1bbe9dr"><style data-emotion="css k7nhbn">.css-k7nhbn{padding-right:0px;padding-left:0px;margin:0 auto;height:100%;z-index:3;position:unset;max-width:calc(1665px + 40px);padding-bottom:0px;padding-top:0px;}</style><div class="css-k7nhbn"><style data-emotion="css 9pwddg">.css-9pwddg{font-family:var(--chakra-fonts-heading);font-size:var(--chakra-fontSizes-sm);line-height:var(--chakra-lineHeights-3xl);font-weight:400;margin-bottom:var(--chakra-space-8);}@media screen and (min-width: 48em){.css-9pwddg{font-size:var(--chakra-fontSizes-xl);margin-bottom:var(--chakra-space-17);}}</style><h2 class="chakra-heading css-9pwddg">Wiadomości</h2><style data-emotion="css cg4t14">.css-cg4t14{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:0px;max-width:1285px;}</style><div class="chakra-stack css-cg4t14"><style data-emotion="css 53dhxj">.css-53dhxj{position:relative;padding-top:var(--chakra-space-8);padding-bottom:var(--chakra-space-8);width:100%;border-bottom:var(--chakra-borders-1px);border-color:rgba(10, 9, 56, 0.22);}.css-53dhxj a[href]:not(.chakra-linkbox__overlay),.css-53dhxj abbr[title]{position:relative;z-index:1;}@media screen and (min-width: 48em){.css-53dhxj{padding-top:var(--chakra-space-4);padding-bottom:var(--chakra-space-4);}}</style><div role="group" class="chakra-linkbox css-53dhxj"><style data-emotion="css zuvz7m">.css-zuvz7m{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-basis:90%;-ms-flex-preferred-size:90%;flex-basis:90%;gap:var(--chakra-space-4);}@media screen and (min-width: 48em){.css-zuvz7m{-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;gap:0px;}}</style><div class="css-zuvz7m"><style data-emotion="css kui65n">
1454.css-kui65n{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;gap:var(--chakra-space-2);min-width:131px;}@media screen and (min-width: 48em){.css-kui65n{gap:0px;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}}</style><div class="chakra-stack css-kui65n"><style data-emotion="css 1a7s3os">.css-1a7s3os{font-size:var(--chakra-fontSizes-3xs);line-height:var(--chakra-lineHeights-3xs);}@media screen and (min-width: 48em){.css-1a7s3os{font-size:var(--chakra-fontSizes-3xs);line-height:var(--chakra-lineHeights-3xs);}}</style><time class="chakra-text css-1a7s3os">01.10.2025</time><style data-emotion="css eqjygn">.css-eqjygn{font-size:var(--chakra-fontSizes-3xs);line-height:var(--chakra-lineHeights-3xs);color:var(--chakra-colors-brand-dim);}@media screen and (min-width: 48em){.css-eqjygn{font-size:var(--chakra-fontSizes-3xs);line-height:var(--chakra-lineHeights-3xs);}}</style><p class="chakra-text css-eqjygn">Artykuł</p></div><style data-emotion="css 1ufrzn0">.css-1ufrzn0{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}</style><div class="css-1ufrzn0"><style data-emotion="css jg008c">.css-jg008c{font-family:var(--chakra-fonts-heading);font-size:var(--chakra-fontSizes-5);line-height:var(--chakra-lineHeights-xl);font-weight:400;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}@media screen and (min-width: 48em){.css-jg008c{font-size:var(--chakra-fontSizes-2-5xl);line-height:var(--chakra-lineHeights-3xl);}}[role=group]:hover .css-jg008c,[role=group][data-hover] .css-jg008c,[data-group]:hover .css-jg008c,[data-group][data-hover] .css-jg008c,.group:hover .css-jg008c,.group[data-hover] .css-jg008c{border-color:var(--chakra-colors-black);}</style><h3 class="chakra-heading css-jg008c"><style data-emotion="css 1opl5mm">.css-1opl5mm{position:static;}.css-1opl5mm::before{content:'';cursor:inherit;display:block;position:absolute;top:0px;left:0px;z-index:0;width:100%;height:100%;}.css-1opl5mm:focus,.css-1opl5mm[data-focus]{outline:2px solid transparent;outline-offset:2px;}.css-1opl5mm:focus-visible,.css-1opl5mm[data-focus-visible]{outline-color:var(--chakra-colors-black);outline-offset:2px;outline:2px solid;box-shadow:var(--chakra-shadows-none);}.css-1opl5mm:hover,.css-1opl5mm[data-hover]{-webkit-text-decoration:underline;text-decoration:underline;}</style><a class="chakra-linkbox__overlay css-1opl5mm" href="/wiadomosci/knowit-poland-na-targach-eot-2025/">Knowit Poland na targach EOT – Electronics of Tomorrow 2025</a></h3><style data-emotion="css 3el9k5">.css-3el9k5{width:1em;height:1em;display:inline-block;line-height:1em;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;color:var(--chakra-colors-black);vertical-align:middle;margin:4px;z-index:0;-webkit-transition:0.3s ease;transition:0.3s ease;}[role=group]:hover .css-3el9k5,[role=group][data-hover] .css-3el9k5,[data-group]:hover .css-3el9k5,[data-group][data-hover] .css-3el9k5,.group:hover .css-3el9k5,.group[data-hover] .css-3el9k5{-webkit-transform:translateX(0.5rem);-moz-transform:translateX(0.5rem);-ms-transform:translateX(0.5rem);transform:translateX(0.5rem);}</style><svg viewBox="0 0 20 20" focusable="false" class="chakra-icon css-3el9k5" aria-hidden="true"><path d="M10.6364 2.35791C13.5455 5.26782 16.6667 8.10115 20 10.8579C16.4848 13.787 13.3636 16.6203 10.6364 19.3579L8.90909 17.7211L13.0606 14.1603C13.9697 13.3754 14.899 12.6766 15.8485 12.064C14.6364 12.0257 13.4141 12.0066 12.1818 12.0066H0V9.70926H12.1818C13.4141 9.70926 14.596 9.78584 15.7273 9.93899L13.0606 7.58426L8.90909 3.99473L10.6364 2.35791Z" fill="currentColor"></path></svg></div></div></div></div><div class="chakra-stack css-cg4t14"><div role="group" class="chakra-linkbox css-53dhxj"><div class="css-zuvz7m"><div class="chakra-stack css-kui65n"><time class="chakra-text css-1a7s3os">09.09.2025</time><p class="chakra-text css-eqjygn">Artykuł</p></div><div class="css-1ufrzn0"><h3 class="chakra-heading css-jg008c"><a class="chakra-linkbox__overlay css-1opl5mm" href="/wiadomosci/knowit-poland-na-mspo-2025-w-kielcach/">Knowit Poland na MSPO 2025 w Kielcach</a></h3><svg viewBox="0 0 20 20" focusable="false" class="chakra-icon css-3el9k5" aria-hidden="true"><path d="M10.6364 2.35791C13.5455 5.26782 16.6667 8.10115 20 10.8579C16.4848 13.787 13.3636 16.6203 10.6364 19.3579L8.90909 17.7211L13.0606 14.1603C13.9697 13.3754 14.899 12.6766 15.8485 12.064C14.6364 12.0257 13.4141 12.0066 12.1818 12.0066H0V9.70926H12.1818C13.4141 9.70926 14.596 9.78584 15.7273 9.93899L13.0606 7.58426L8.90909 3.99473L10.6364 2.35791Z" fill="currentColor"></path></svg></div></div></div></div><div class="chakra-stack css-cg4t14"><div role="group" class="chakra-linkbox css-53dhxj"><div class="css-zuvz7m"><div class="chakra-stack css-kui65n"><time class="chakra-text css-1a7s3os">05.06.2025</time><p class="chakra-text css-eqjygn">Artykuł</p></div><div class="css-1ufrzn0"><h3 class="chakra-heading css-jg008c"><a class="chakra-linkbox__overlay css-1opl5mm" href="/wiadomosci/knowit-otrzymuje-specjalizacj-microsoft-azure-analytics-i-odnawia-certyfikat-azure-expert-msp/">Knowit otrzymuje specjalizację Microsoft Azure Analytics i odnawia certyfikat Azure Expert MSP</a></h3><svg viewBox="0 0 20 20" focusable="false" class="chakra-icon css-3el9k5" aria-hidden="true"><path d="M10.6364 2.35791C13.5455 5.26782 16.6667 8.10115 20 10.8579C16.4848 13.787 13.3636 16.6203 10.6364 19.3579L8.90909 17.7211L13.0606 14.1603C13.9697 13.3754 14.899 12.6766 15.8485 12.064C14.6364 12.0257 13.4141 12.0066 12.1818 12.0066H0V9.70926H12.1818C13.4141 9.70926 14.596 9.78584 15.7273 9.93899L13.0606 7.58426L8.90909 3.99473L10.6364 2.35791Z" fill="currentColor"></path></svg></div></div></div></div><div class="css-bxm9v3"><a class="chakra-button css-13abcv5" href="/wiadomosci/">Pokaż wszystko<span class="chakra-button__icon css-1hzyiq5"><svg viewBox="0 0 19 18" focusable="false" class="chakra-icon css-1wq3x2a" aria-hidden="true"><path d="M8.61914 17.3791L8.6476 13.3589V9.91478H5.15907C3.67952 9.91478 2.12668 9.81621 0.744141 9.6908L0.744173 7.81665H8.6476V4.54881C8.6476 3.15145 8.75196 1.68488 8.88475 0.37915L10.8691 0.379181V7.81665L14.451 7.81665C15.9306 7.81665 17.3616 7.94209 18.7441 8.0675L18.7441 9.94165L14.4874 9.91478H10.8691L10.8691 13.3245C10.8691 14.7219 10.7363 16.0734 10.6035 17.3792L8.61914 17.3791Z" fill="currentColor"></path></svg></span></a></div></div></div></div></div></div></div></div></section></div></div></div></main></div>
1454<style data-emotion="css zwhlfi">.css-zwhlfi{background:var(--chakra-colors-pageBg);padding-top:var(--chakra-space-20);}</style><footer class="css-zwhlfi"><style data-emotion="css 1uhmzk7">.css-1uhmzk7{opacity:1;background:var(--chakra-colors-brand-black);color:var(--chakra-colors-brand-primary);}</style><div class="css-1uhmzk7"><style data-emotion="css 1bbe9dr">.css-1bbe9dr{padding-top:0px;height:100%;}</style><div class="css-1bbe9dr"><style data-emotion="css l409r1">.css-l409r1{padding-right:20px;padding-left:20px;margin:0 auto;height:100%;z-index:3;position:unset;max-width:calc(1548px + 40px);padding-bottom:0px;padding-top:var(--chakra-space-12);}@media screen and (min-width: 48em){.css-l409r1{padding-top:var(--chakra-space-20);}}</style><div class="css-l409r1"><style data-emotion="css vxj34e">.css-vxj34e{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:var(--chakra-space-10);padding-bottom:var(--chakra-space-14);}@media screen and (min-width: 62em){.css-vxj34e{gap:24px;}}</style><div class="chakra-stack css-vxj34e"><style data-emotion="css 2bxxq6">.css-2bxxq6{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:var(--chakra-space-10);}@media screen and (min-width: 62em){.css-2bxxq6{-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;gap:0px;}}</style><div class="css-2bxxq6"><style data-emotion="css nf9oxa">.css-nf9oxa{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding-right:0px;-webkit-flex-basis:100%;-ms-flex-preferred-size:100%;flex-basis:100%;}@media screen and (min-width: 62em){.css-nf9oxa{padding-right:8%;-webkit-flex-basis:38%;-ms-flex-preferred-size:38%;flex-basis:38%;}}</style><div class="css-nf9oxa"><style data-emotion="css 1vethzo">.css-1vethzo{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:start;-ms-flex-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:16px;height:100%;margin-top:0px;max-width:100%;}@media screen and (min-width: 62em){.css-1vethzo{height:calc(100% - 64px);max-width:-webkit-fit-content;max-width:-moz-fit-content;max-width:fit-content;}}</style><div class="chakra-stack css-1vethzo"><style data-emotion="css njvf2l">.css-njvf2l{font-family:var(--chakra-fonts-heading);line-height:2rem;font-weight:var(--chakra-fontWeights-normal);font-size:var(--chakra-fontSizes-6-5);color:var(--chakra-colors-brand-primary);margin-top:-10px;}@media screen and (min-width: 48em){.css-njvf2l{line-height:var(--chakra-lineHeights-4-5xl);font-size:var(--chakra-fontSizes-3xl);}}</style><h2 class="chakra-heading css-njvf2l">Become one of us</h2><style data-emotion="css 1b8zsyi">.css-1b8zsyi{line-height:var(--chakra-lineHeights-lg);font-size:var(--chakra-fontSizes-2xs);color:var(--chakra-colors-brand-primary);}@media screen and (min-width: 48em){.css-1b8zsyi{line-height:var(--chakra-lineHeights-xl);}}@media screen and (min-width: 62em){.css-1b8zsyi{font-size:var(--chakra-fontSizes-sm);}}</style><p class="chakra-text css-1b8zsyi">Wspólnie z naszymi klientami opracowujemy rozwiązania cyfrowe, które ułatwiają ich i nasze codzienne życie. Chcemy, żebyś do nas dołączył! </p><style data-emotion="css en61s0">.css-en61s0{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin-top:0px;}</style><div class="css-en61s0"><style data-emotion="css feed4f">.css-feed4f{position:relative;-webkit-transition:-webkit-transform 0.3s ease;transition:transform 0.3s ease;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;font-size:var(--chakra-fontSizes-sm);font-weight:400;color:var(--chakra-colors-brand-primary);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;}.css-feed4f a[href]:not(.chakra-linkbox__overlay),.css-feed4f abbr[title]{position:relative;z-index:1;}@media screen and (min-width: 62em){.css-feed4f{font-size:var(--chakra-fontSizes-xl);}}</style><div role="group" class="chakra-linkbox css-feed4f"><style data-emotion="css 18lx61o">.css-18lx61o{position:static;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;border:var(--chakra-borders-none);border-bottom:1px solid transparent;border-color:var(--chakra-colors-transparent);-webkit-transition:inherit;transition:inherit;color:var(--chakra-colors-brand-primary);padding:0px;}.css-18lx61o::before{content:'';cursor:inherit;display:block;position:absolute;top:0px;left:0px;z-index:0;width:100%;height:100%;}[role=group]:hover .css-18lx61o,[role=group][data-hover] .css-18lx61o,[data-group]:hover .css-18lx61o,[data-group][data-hover] .css-18lx61o,.group:hover .css-18lx61o,.group[data-hover] .css-18lx61o{border-color:none;}.css-18lx61o:focus,.css-18lx61o[data-focus]{outline:2px solid transparent;outline-offset:2px;}.css-18lx61o:focus-visible,.css-18lx61o[data-focus-visible]{outline-color:var(--chakra-colors-black);outline-offset:2px;outline:2px solid;box-shadow:var(--chakra-shadows-none);}</style><a title="Dołącz do nas!" class="chakra-linkbox__overlay css-18lx61o" href="https://www.knowit.pl/">Dołącz do nas!</a><style data-emotion="css ak75ar">.css-ak75ar{width:1em;height:1em;display:inline-block;line-height:1em;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;color:var(--chakra-colors-brand-primary);vertical-align:middle;opacity:1;margin-left:var(--chakra-space-3);-webkit-transition:inherit;transition:inherit;}[role=group]:hover .css-ak75ar,[role=group][data-hover] .css-ak75ar,[data-group]:hover .css-ak75ar,[data-group][data-hover] .css-ak75ar,.group:hover .css-ak75ar,.group[data-hover] .css-ak75ar{-webkit-transform:translateX(0.25rem);-moz-transform:translateX(0.25rem);-ms-transform:translateX(0.25rem);transform:translateX(0.25rem);}</style><svg viewBox="0 0 20 20" focusable="false" class="chakra-icon css-ak75ar" aria-hidden="true"><path d="M10.6364 2.35791C13.5455 5.26782 16.6667 8.10115 20 10.8579C16.4848 13.787 13.3636 16.6203 10.6364 19.3579L8.90909 17.7211L13.0606 14.1603C13.9697 13.3754 14.899 12.6766 15.8485 12.064C14.6364 12.0257 13.4141 12.0066 12.1818 12.0066H0V9.70926H12.1818C13.4141 9.70926 14.596 9.78584 15.7273 9.93899L13.0606 7.58426L8.90909 3.99473L10.6364 2.35791Z" fill="currentColor"></path></svg></div></div></div></div><style data-emotion="css 1iojrxl">.css-1iojrxl{opacity:0.6;border:0;border-style:solid;border-bottom-width:1px;width:100%;border-color:var(--chakra-colors-brand-primary);}</style><hr aria-orientation="horizontal" class="chakra-divider css-1iojrxl"/><style data-emotion="css izw0ek">.css-izw0ek{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;-webkit-flex-basis:100%;-ms-flex-preferred-size:100%;flex-basis:100%;}@media screen and (min-width: 62em){.css-izw0ek{-webkit-flex-basis:62%;-ms-flex-preferred-size:62%;flex-basis:62%;}}</style><div class="css-izw0ek"><style data-emotion="css 1x78qm6">.css-1x78qm6{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:var(--chakra-space-10);-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;}</style><div class="css-1x78qm6"><style data-emotion="css 1h8ljdg">.css-1h8ljdg{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:var(--chakra-space-6);width:50%;min-width:152px;-webkit-flex:1;-ms-flex:1;flex:1;}@media screen and (min-width: 48em){.css-1h8ljdg{width:100%;}}</style><div class="chakra-stack css-1h8ljdg"><style data-emotion="css e141q0">.css-e141q0{font-size:var(--chakra-fontSizes-2xs);line-height:var(--chakra-lineHeights-sm);text-transform:uppercase;color:var(--chakra-colors-brand-primary);letter-spacing:1.7px;}@media screen and (min-width: 48em){.css-e141q0{font-size:var(--chakra-fontSizes-2xs);line-height:22px;}}</style><h3 class="chakra-text css-e141q0">Kontakt</h3><style data-emotion="css 11nrrcx">.css-11nrrcx{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:var(--chakra-space-3);}</style><div class="chakra-stack css-11nrrcx"><style data-emotion="css 1sdrz3g">.css-1sdrz3g{max-width:47.25rem;font-size:14px;line-height:1.75rem;}@media screen and (min-width: 48em){.css-1sdrz3g{font-size:1.125rem;line-height:2rem;}}.css-1sdrz3g ol,.css-1sdrz3g ul{padding-left:20px;margin-block-end:20px;}.css-1sdrz3g ul li{list-style-type:disc;}.css-1sdrz3g ol li{list-style-type:decimal;}.css-1sdrz3g a{-webkit-transition:0.3s ease;transition:0.3s ease;}.css-1sdrz3g p,.css-1sdrz3g p span{font-size:14px;}.css-1sdrz3g p:not(:last-child){margin-bottom:20px;}.css-1sdrz3g span{font-size:inherit;line-height:inherit;}.css-1sdrz3g div{font-size:inherit!important;margin-left:inherit!important;line-height:inherit!important;}.css-1sdrz3g table{width:100%!important;overflow-x:auto;overflow-y:hidden;font-size:16px;}.css-1sdrz3g table tr{padding-left:16px;padding-right:16px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;height:96px!important;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border-bottom:0.5px solid black;}.css-1sdrz3g table tr td,.css-1sdrz3g table tr th{height:auto!important;text-align:right!important;padding:8px;box-sizing:border-box;text-align:center;}@media screen and (max-width: 80em){.css-1sdrz3g table tr td:not(first-of-type),.css-1sdrz3g table tr th:not(first-of-type){white-space:nowrap;}}.css-1sdrz3g table tr td:first-of-type,.css-1sdrz3g table tr th:first-of-type{text-align:left!important;white-space:wrap;}.CasePage .css-1sdrz3g table{width:100%!important;font-size:16px;height:auto!important;}.CasePage .css-1sdrz3g table tr{height:auto!important;border-bottom:0;display:table-row;}.CasePage .css-1sdrz3g table tr:first-of-type td{padding-top:0;border-bottom:3px solid black;}.CasePage .css-1sdrz3g table td{padding:24px 12px;
1454height:auto!important;border-bottom:1px solid black;text-align:left!important;}.CasePage .css-1sdrz3g table td:last-child{text-align:center!important;}.CasePage .css-1sdrz3g table td:first-child{padding-left:0;}</style><div font-size="14px" class="css-1sdrz3g"><p><style data-emotion="css 15l3799">.css-15l3799{transition-property:var(--chakra-transition-property-common);transition-duration:var(--chakra-transition-duration-fast);transition-timing-function:var(--chakra-transition-easing-ease-out);cursor:pointer;outline:2px solid transparent;outline-offset:2px;color:inherit;-webkit-transition:0.3s ease;transition:0.3s ease;border-bottom:1px solid;border-color:var(--chakra-colors-transparent);-webkit-text-decoration:underline;text-decoration:underline;text-underline-offset:5px;}.css-15l3799:focus,.css-15l3799[data-focus]{outline:2px solid transparent;outline-offset:2px;}.css-15l3799:focus-visible,.css-15l3799[data-focus-visible]{outline-color:var(--chakra-colors-black);outline-offset:2px;outline:2px solid;box-shadow:var(--chakra-shadows-none);}.css-15l3799:hover,.css-15l3799[data-hover]{border-color:none;-webkit-text-decoration:none;text-decoration:none;}</style><a class="chakra-link css-15l3799" href="mailto:[email protected]">[email protected]</a> </p>
1455<p>Hrubieszowska 2 <br/>PL-01-209 Warszawa</p>
1456<p><strong>Knowit Poland sp. z o.o.</strong></p>
1457<p>KRS 0000036076, <br/>NIP: 9511789996. <br/>Sąd Rejonowy dla m.st. Warszawy w Warszawie, XIII Wydzial Gospodarczy Krajowego Rejestru Sądowego. Kapital zakladowy: <br/>1 251 200 PLN, siedziba: <br/>ul. Hrubieszowska 2, 01-209 Warszawa </p></div></div></div><div class="chakra-stack css-1h8ljdg"><h3 class="chakra-text css-e141q0">Spółka</h3><style data-emotion="css 1153lrp">.css-1153lrp{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:var(--chakra-space-5);}</style><ul class="chakra-stack css-1153lrp"><li><style data-emotion="css 1n6k91h">.css-1n6k91h{transition-property:var(--chakra-transition-property-common);transition-duration:var(--chakra-transition-duration-fast);transition-timing-function:var(--chakra-transition-easing-ease-out);cursor:pointer;outline:2px solid transparent;outline-offset:2px;-webkit-transition:0.3s ease;transition:0.3s ease;border-bottom:1px solid;border-color:var(--chakra-colors-transparent);font-size:14px;color:var(--chakra-colors-brand-primary);-webkit-text-decoration:underline;text-decoration:underline;text-underline-offset:5px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}.css-1n6k91h:focus,.css-1n6k91h[data-focus]{outline:2px solid transparent;outline-offset:2px;}.css-1n6k91h:focus-visible,.css-1n6k91h[data-focus-visible]{outline-color:var(--chakra-colors-black);outline-offset:2px;outline:2px solid;box-shadow:var(--chakra-shadows-none);}.css-1n6k91h:hover,.css-1n6k91h[data-hover]{border-color:none;-webkit-text-decoration:none;text-decoration:none;}</style><a class="chakra-link css-1n6k91h" title="O Knowit" href="https://www.knowit.pl/o-knowit/">O Knowit</a></li><li><a target="_blank" class="chakra-link css-1n6k91h" title="Informacje Finansowe (EN)" href="https://www.knowit.pl/investor-relations/">Informacje Finansowe (EN)</a></li><li><a class="chakra-link css-1n6k91h" title="Kariera" href="https://www.knowit.pl/kariera/">Kariera</a></li><li><a class="chakra-link css-1n6k91h" title="Zrównoważony rozwój" href="https://www.knowit.pl/o-knowit/zrownowazony-rozwoj/">Zrównoważony rozwój</a></li><li><a class="chakra-link css-1n6k91h" title="Kontakt" href="https://www.knowit.pl/kontakt/">Kontakt</a></li></ul></div><div class="chakra-stack css-1h8ljdg"><h3 class="chakra-text css-e141q0">Usługi</h3><ul class="chakra-stack css-1153lrp"><li><a class="chakra-link css-1n6k91h" title="Product i service development" href="https://www.knowit.pl/co-oferujemy/product-i-service-development/">Product i service development</a></li><li><a class="chakra-link css-1n6k91h" title="Application management" href="https://www.knowit.pl/co-oferujemy/application-management/">Application management</a></li><li><a class="chakra-link css-1n6k91h" title="Cloud, Data &amp; AI" href="https://www.knowit.pl/co-oferujemy/cloud-data/">Cloud, Data &amp; AI</a></li><li><a class="chakra-link css-1n6k91h" title="Web, Mobile i E-commerce" href="https://www.knowit.pl/co-oferujemy/web-mobile-i-e-commerce/">Web, Mobile i E-commerce</a></li><li><a class="chakra-link css-1n6k91h" title="Green House - Hub Innowacji" href="https://www.knowit.pl/co-oferujemy/green-house-hub-innowacji/">Green House - Hub Innowacji</a></li><li><a class="chakra-link css-1n6k91h" title="Nasi klienci" href="https://www.knowit.pl/Projekty/">Nasi klienci</a></li></ul></div></div></div></div><hr aria-orientation="horizontal" class="chakra-divider css-1iojrxl"/><style data-emotion="css 29zybq">.css-29zybq{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;
1457-webkit-justify-content:space-between;justify-content:space-between;gap:var(--chakra-space-5);font-size:14px;}@media screen and (min-width: 62em){.css-29zybq{-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;gap:var(--chakra-space-2);}}</style><div class="css-29zybq"><style data-emotion="css siapkm">.css-siapkm{width:100%;}@media screen and (min-width: 62em){.css-siapkm{width:50%;}}</style><div class="css-siapkm"><style data-emotion="css 7x3r43">.css-7x3r43{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:start;-ms-flex-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-box-flex-wrap:wrap;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;gap:var(--chakra-space-4);color:var(--chakra-colors-brand-primary);}</style><ul class="chakra-stack css-7x3r43"><style data-emotion="css rdwj84">.css-rdwj84{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;gap:var(--chakra-space-4);}</style><li class="css-rdwj84"><style data-emotion="css xhjgcp">.css-xhjgcp{transition-property:var(--chakra-transition-property-common);transition-duration:var(--chakra-transition-duration-fast);transition-timing-function:var(--chakra-transition-easing-ease-out);cursor:pointer;outline:2px solid transparent;outline-offset:2px;color:inherit;-webkit-transition:0.3s ease;transition:0.3s ease;border-bottom:1px solid;border-color:var(--chakra-colors-transparent);text-underline-offset:5px;-webkit-text-decoration:underline;text-decoration:underline;font-size:14px;}.css-xhjgcp:focus,.css-xhjgcp[data-focus]{outline:2px solid transparent;outline-offset:2px;}.css-xhjgcp:focus-visible,.css-xhjgcp[data-focus-visible]{outline-color:var(--chakra-colors-black);outline-offset:2px;outline:2px solid;box-shadow:var(--chakra-shadows-none);}.css-xhjgcp:hover,.css-xhjgcp[data-hover]{border-color:none;-webkit-text-decoration:none;text-decoration:none;}</style><a class="chakra-link css-xhjgcp" title="Cookies" href="https://www.knowit.pl/misc/polityka-plikow-cookie/">Cookies</a></li><li class="css-rdwj84"><style data-emotion="css 91s7d4">.css-91s7d4{width:1em;height:1em;display:inline-block;line-height:1em;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;color:var(--chakra-colors-brand-primary);vertical-align:middle;font-size:8px;}</style><svg viewBox="0 0 11 10" focusable="false" class="chakra-icon css-91s7d4" aria-hidden="true"><path d="M4.49001 1.83152C4.55688 2.43942 4.74634 3.14864 5.0584 3.95918L2.98545 2.65218L1.34715 1.61875L0.0432003 3.41206L2.11615 4.23273C2.74026 4.45563 3.50926 4.65826 4.42314 4.84063C3.50926 5.18511 2.74026 5.47893 2.11615 5.72209L0.00976562 6.48197L1.31372 8.30568L2.95201 7.27225C3.50926 6.92777 4.11108 6.45158 4.75749 5.84367C4.62375 6.73526 4.53459 7.48501 4.49001 8.09291L4.2894 9.64307H6.73013L6.52952 8.09291C6.44036 7.48501 6.23976 6.77579 5.9277 5.96526C6.73013 6.51237 7.40997 6.94803 7.96721 7.27225L9.63894 8.36647L10.9429 6.57316L8.90338 5.75249C8.27927 5.52959 7.51027 5.33709 6.59639 5.17498C7.51027 4.8305 8.27927 4.53668 8.90338 4.29352L11.0098 3.50325L9.70581 1.67954L8.03408 2.74337C7.47684 3.06758 6.87501 3.54378 6.22861 4.17194C6.36235 3.28035 6.46265 2.5306 6.52952 1.9227L6.73013 0.342155H4.2894L4.49001 1.83152Z" fill="currentColor"></path></svg><a class="chakra-link css-xhjgcp" title="Obsługa danych osobowych" href="https://www.knowit.pl/misc/prywatnosci/">Obsługa danych osobowych</a></li><li class="css-rdwj84"><svg viewBox="0 0 11 10" focusable="false" class="chakra-icon css-91s7d4" aria-hidden="true"><path d="M4.49001 1.83152C4.55688 2.43942 4.74634 3.14864 5.0584 3.95918L2.98545 2.65218L1.34715 1.61875L0.0432003 3.41206L2.11615 4.23273C2.74026 4.45563 3.50926 4.65826 4.42314 4.84063C3.50926 5.18511 2.74026 5.47893 2.11615 5.72209L0.00976562 6.48197L1.31372 8.30568L2.95201 7.27225C3.50926 6.92777 4.11108 6.45158 4.75749 5.84367C4.62375 6.73526 4.53459 7.48501 4.49001 8.09291L4.2894 9.64307H6.73013L6.52952 8.09291C6.44036 7.48501 6.23976 6.77579 5.9277 5.96526C6.73013 6.51237 7.40997 6.94803 7.96721 7.27225L9.63894 8.36647L10.9429 6.57316L8.90338 5.75249C8.27927 5.52959 7.51027 5.33709 6.59639 5.17498C7.51027 4.8305 8.27927 4.53668 8.90338 4.29352L11.0098 3.50325L9.70581 1.67954L8.03408 2.74337C7.47684 3.06758 6.87501 3.54378 
14576.22861 4.17194C6.36235 3.28035 6.46265 2.5306 6.52952 1.9227L6.73013 0.342155H4.2894L4.49001 1.83152Z" fill="currentColor"></path></svg><a target="_blank" rel="noopener noreferrer" class="chakra-link css-xhjgcp" href="https://knowit.whistlelink.com/">Serwis Wistleblower</a></li><li class="css-rdwj84"> <svg viewBox="0 0 11 10" focusable="false" class="chakra-icon css-91s7d4" aria-hidden="true"><path d="M4.49001 1.83152C4.55688 2.43942 4.74634 3.14864 5.0584 3.95918L2.98545 2.65218L1.34715 1.61875L0.0432003 3.41206L2.11615 4.23273C2.74026 4.45563 3.50926 4.65826 4.42314 4.84063C3.50926 5.18511 2.74026 5.47893 2.11615 5.72209L0.00976562 6.48197L1.31372 8.30568L2.95201 7.27225C3.50926 6.92777 4.11108 6.45158 4.75749 5.84367C4.62375 6.73526 4.53459 7.48501 4.49001 8.09291L4.2894 9.64307H6.73013L6.52952 8.09291C6.44036 7.48501 6.23976 6.77579 5.9277 5.96526C6.73013 6.51237 7.40997 6.94803 7.96721 7.27225L9.63894 8.36647L10.9429 6.57316L8.90338 5.75249C8.27927 5.52959 7.51027 5.33709 6.59639 5.17498C7.51027 4.8305 8.27927 4.53668 8.90338 4.29352L11.0098 3.50325L9.70581 1.67954L8.03408 2.74337C7.47684 3.06758 6.87501 3.54378 6.22861 4.17194C6.36235 3.28035 6.46265 2.5306 6.52952 1.9227L6.73013 0.342155H4.2894L4.49001 1.83152Z" fill="currentColor"></path></svg><style data-emotion="css 1p4b2zl">.css-1p4b2zl{line-height:var(--chakra-lineHeights-lg);text-align:start;width:100%;display:block;font-size:14px;color:var(--chakra-colors-brand-primary);}@media screen and (min-width: 48em){.css-1p4b2zl{line-height:var(--chakra-lineHeights-xl);}}@media screen and (min-width: 62em){.css-1p4b2zl{width:auto;}}</style><p class="chakra-text css-1p4b2zl">© Knowit Poland 2026</p></li></ul></div></div></div></div></div></div></footer><span></span><span id="__chakra_env" hidden=""></span></div>
1457<script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"slug":"","contentLink":{"id":5,"workId":0,"guidValue":"7148f4e8-99da-42cd-a928-ace346534c74","url":"https://www.knowit.pl/"},"name":"Start","contentType":["Page","StartPage"],"parentLink":{"id":1,"workId":0,"guidValue":"43f936c9-9b23-4ea3-97b2-61c538ad07c9","url":"https://www.knowit.eu/"},"routeSegment":"start","url":"https://www.knowit.pl/","created":"2023-09-20T11:41:03Z","startPublish":"2023-09-20T11:41:30Z","searchPageLink":{"id":13,"workId":0,"guidValue":"22624de0-9cc4-4c10-a4fa-702494af81e9","url":"https://www.knowit.pl/szukaj/","expanded":{"contentLink":{"id":13,"workId":0,"guidValue":"22624de0-9cc4-4c10-a4fa-702494af81e9","url":"https://www.knowit.pl/szukaj/"},"name":"Szukaj","contentType":["Page","SearchPage"],"parentLink":{"id":5,"workId":0,"guidValue":"7148f4e8-99da-42cd-a928-ace346534c74","url":"https://www.knowit.pl/"},"routeSegment":"szukaj","url":"https://www.knowit.pl/szukaj/","created":"2023-10-02T12:29:35Z","startPublish":"2023-10-02T12:29:50Z","metaTitle":"Szukaj","heading":"Szukaj","noResultsText":"Wyszukiwanie nie przyniosło żadnych wyników"}},"metaTitle":"Knowit Poland","partialHeading":"Let's reshape it","heading":"Building the future takes a whole set of digitalization skills. Welcome to our world.","partialPreamble":"Shaping a new future for your business takes a whole set of digitalization skills. We’ve got these skills. And we combine them to also create a sustainable and humane society. Welcome to our world.","metaDescription":"Knowit to skandynawska potęga cyfrowych rozwiązań przyszłości.","preamble":"Shaping a new future for your business takes a whole set of digitalization skills. We’ve got these skills. And we combine them to also create a sustainable and humane society. Welcome to our world.","partialImage":{"id":18294,"workId":0,"guidValue":"5cac93ac-5230-42cd-858a-fc48fbfc3e98","url":"https://www.knowit.pl/globalassets/image-bank/gradients/afterglow-1920x1080.jpg","expanded":{"contentLink":{"id":18294,"workId":0,"guidValue":"5cac93ac-5230-42cd-858a-fc48fbfc3e98","url":"https://www.knowit.pl/globalassets/image-bank/gradients/afterglow-1920x1080.jpg"},"name":"Afterglow-1920x1080.jpg","contentType":["Image","Media","ImageFile"],"parentLink":{"id":18283,"workId":0,"guidValue":"ce8c9f92-4d8c-45b7-94da-e710f14b0955","url":"https://www.knowit.pl/globalassets/image-bank/gradients/"},"routeSegment":"afterglow-1920x1080.jpg","url":"https://www.knowit.pl/globalassets/image-bank/gradients/afterglow-1920x1080.jpg","created":"2024-03-06T09:38:23Z","startPublish":"2024-03-06T09:38:23Z","thumbnail":{"id":"epi.fx.blob://default/5cac93ac523042cd858afc48fbfc3e98/f21e61b8facd40268509759846bb32b2_Thumbnail.png","url":"https://www.knowit.pl/globalassets/image-bank/gradients/afterglow-1920x1080.jpg/Thumbnail"},"mimeType":"image/jpeg","fileSize":99200,"fileExtension":"jpg"}},"heroContentArea":[{"displayOption":"","contentLink":{"id":30816,"workId":0,"guidValue":"0e375737-0b6e-4207-9fd2-2a45149be8f6","expanded":{"contentLink":{"id":30816,"workId":0,"guidValue":"0e375737-0b6e-4207-9fd2-2a45149be8f6"},"name":"Animation script","contentType":["Block","ScriptContainerBlock"],"parentLink":{"id":6,"workId":0,"guidValue":"bccf851d-3950-4313-9898-b570c47cdb78","url":"https://www.knowit.pl/contentassets/bccf851d395043139898b570c47cdb78/"},"created":"2025-06-12T06:57:34Z","startPublish":"2025-06-12T06:57:34Z","mainBody":"\u003cdiv id=\"animated-hero\" style=\"position: absolute; inset: 0;\"\u003e\u003ccanvas id=\"animated-hero__canvas\" style=\"position: absolute; inset: 0; width: 100%; height: 100%;\"\u003e\u003c/canvas\u003e\n\u003cdiv id=\"animated-hero__footer\" class=\"auto-ink\" style=\"text-align: start; position: absolute; bottom: 35px; left: 48px; max-width: 50%; color: #fff; z-index: 10; font-size: 20px; line-height: 28px; transition: color 0.25s linear;\"\u003e\u003cspan id=\"animated-hero__status\"\u003e Design inspired by the Nordic sky above \u003cspan class=\"status-cluster\" style=\"display: inline-flex; align-items: baseline; gap: 0.35em;\"\u003e Knowit, \u003cspan id=\"animated-hero__city\"\u003e\u0026bull;\u003c/span\u003e \u003cbutton id=\"animated-hero__rnd\" aria-label=\"Randomize\" style=\"width: 20p
1457x; height: 20px; background: none; border: none; padding: 0; cursor: pointer; color: inherit; transition: color 0.25s linear;\"\u003e \u003csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewbox=\"0 0 15 18\" fill=\"none\" style=\"color: inherit; transition: color 0.25s linear;\"\u003e \u003cpath d=\"M7.87226 2.60254L5.98456 7.7373L5.04608 7.39258L6.44257 3.59082C5.59154 3.71764 4.77195 4.01502 4.03534 4.46875L3.8371 4.5957C2.85307 5.25325 2.07198 6.171 1.58026 7.24414L1.48554 7.45996C1.00255 8.62603 0.877087 9.90957 1.12323 11.1475L1.17304 11.3789C1.44599 12.5272 2.03258 13.5792 2.86933 14.416L3.03925 14.5801C3.90403 15.3831 4.97646 15.9311 6.1369 16.1621L6.3703 16.2041C7.53554 16.3913 8.73218 16.2526 9.82538 15.7998L10.0412 15.7051C11.1144 15.2134 12.0321 14.4323 12.6896 13.4482L12.8166 13.25C13.4357 12.2449 13.7648 11.0859 13.7648 9.90234H14.7648C14.7648 11.2713 14.3842 12.6119 13.6682 13.7744L13.5207 14.0039C12.7602 15.142 11.6994 16.0455 10.4582 16.6143L10.2072 16.7236C8.94267 17.2473 7.55895 17.408 6.21112 17.1914L5.94257 17.1436C4.60016 16.8765 3.35996 16.2414 2.35956 15.3125L2.1623 15.123C1.19449 14.1552 0.516127 12.9385 0.200381 11.6104L0.141787 11.3428C-0.142932 9.91105 0.00319747 8.42681 0.561709 7.07812L0.671084 6.82715C1.23985 5.586 2.14331 4.52515 3.28144 3.76465L3.51093 3.61719C4.11638 3.24426 4.77047 2.9629 5.45136 2.77832L2.39276 1.6543 2.73749 0.714844 7.87226 2.60254Z\" style=\"fill: currentColor; transition: fill 0.25s linear, stroke 0.25s linear;\"\u003e\u003c/path\u003e \u003c/svg\u003e \u003c/button\u003e \u003c/span\u003e \u003c/span\u003e\u003c/div\u003e\n\u003cdiv id=\"animated-hero__met\" class=\"auto-ink\" style=\"position: absolute; bottom: 35px; right: 48px; display: flex; align-items: center; gap: 19px; color: #fff; z-index: 10; font-size: 20px; line-height: 28px; transition: color 0.25s linear;\"\u003e\n\u003cdiv class=\"met-group\" style=\"display: flex; align-items: center;\"\u003e\u003csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"23\" height=\"16\" viewbox=\"0 0 23 16\" fill=\"none\" style=\"color: inherit; transition: color 0.25s linear;\"\u003e \u003cpath d=\"M18.296 7.013C18.4372 5.61392 18.0324 4.21484 17.1609 3.09201C16.2894 1.96918 15.0157 1.20567 13.5919 0.951853C12.1675 0.697521 10.6975 0.972242 9.47212 1.72097C8.24675 2.4702 7.3558 3.63839 6.97569 4.99466C6.26273 4.89782 5.53663 4.9447 4.84309 5.13227C4.14955 5.31932 3.50275 5.64297 2.94361 6.08333C2.38448 6.5237 1.92455 7.07058 1.59222 7.69087C1.25988 8.31115 1.06251 8.99056 1.01263 9.6878C0.962758 10.385 1.06091 11.0849 1.30084 11.7439C1.54129 12.4029 1.91878 13.0063 2.40966 13.5181C2.90055 14.0293 3.49435 14.437 4.15482 14.7158C4.81476 14.9946 5.52719 15.1389 6.24698 15.1394H17.7972C18.8682 15.1399 19.8994 14.7433 20.679 14.0303C21.4592 13.3178 21.9291 12.3422 21.9926 11.3045C22.0561 10.2663 21.7091 9.24388 21.0219 8.44623C20.3346 7.64858 19.3597 7.13583 18.296 7.013Z\" stroke=\"currentColor\" stroke-width=\"1.26004\" style=\"stroke: currentColor; transition: stroke 0.25s linear;\"\u003e\u003c/path\u003e \u003c/svg\u003e\n\u003cdiv id=\"animated-hero__weather\" style=\"margin-left: 6px;\"\u003e\n\u003cdiv id=\"animated-hero__weather-track\" style=\"display: flex; align-items: center; gap: 19px;\"\u003e\u003cspan id=\"animated-hero__temp\"\u003e\u0026bull;\u003c/span\u003e \u003cspan id=\"animated-hero__wind\"\u003e\u0026bull;\u003c/span\u003e \u003cspan id=\"animated-hero__time\"\u003e\u0026bull;\u003c/span\u003e\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\u003cscript\u003e\n    if (!window.__heroCanvasLoaded) {\n      window.__heroCanvasLoaded = true;\n      (function () {\n        window.addEventListener(\"load\", () =\u003e {\n          const clamp = (x, a = 0, b = 1) =\u003e Math.max(a, Math.min(b, x));\n          const lerp = (a, b, t) =\u003e a + (b - a) * t;\n          const sigmoid = (x) =\u003e 1 / (1 + Math.exp(-x));\n          const tanh = Math.tanh;\n          const parseISO = (s) =\u003e new Date(s);\n\n          function hexToRgbNorm(hex) {\n            return {\n              r: parseInt(hex.slice(1, 3), 16) / 25
14575,\n              g: parseInt(hex.slice(3, 5), 16) / 255,\n              b: parseInt(hex.slice(5, 7), 16) / 255,\n            };\n          }\n\n          // Colour conversions\n          function hslToHex(h, s, l) {\n            h /= 360;\n            s /= 100;\n            l /= 100;\n            let r, g, b;\n            if (s === 0) {\n              r = g = b = l;\n            } else {\n              const hue2rgb = (p, q, t) =\u003e {\n                if (t \u003c 0) t += 1;\n                if (t \u003e 1) t -= 1;\n                if (t \u003c 1 / 6) return p + (q - p) * 6 * t;\n                if (t \u003c 1 / 2) return q;\n                if (t \u003c 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n                return p;\n              };\n              const q = l \u003c 0.5 ? l * (1 + s) : l + s - l * s;\n              const p = 2 * l - q;\n              r = hue2rgb(p, q, h + 1 / 3);\n              g = hue2rgb(p, q, h);\n              b = hue2rgb(p, q, h - 1 / 3);\n            }\n            const toHex = (x) =\u003e {\n              const hex = Math.round(x * 255).toString(16);\n              return hex.length === 1 ? \"0\" + hex : hex;\n            };\n            return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n          }\n\n          function hexToHsl(hex) {\n            const r = parseInt(hex.slice(1, 3), 16) / 255;\n            const g = parseInt(hex.slice(3, 5), 16) / 255;\n            const b = parseInt(hex.slice(5, 7), 16) / 255;\n            const max = Math.max(r, g, b);\n            const min = Math.min(r, g, b);\n            let h, s;\n            const l = (max + min) / 2;\n            if (max === min) {\n              h = s = 0;\n            } else {\n              const d = max - min;\n              s = l \u003e 0.5 ? d / (2 - max - min) : d / (max + min);\n              switch (max) {\n                case r:\n                  h = (g - b) / d + (g \u003c b ? 6 : 0);\n                  break;\n                case g:\n                  h = (b - r) / d + 2;\n                  break;\n                default:\n                  h = (r - g) / d + 4;\n              }\n              h /= 6;\n            }\n            return { h: h * 360, s: s * 100, l: l * 100 };\n          }\n\n          const REFERENCE_PALETTES = {\n            CR: {\n              name: \"CloudyRain\",\n              bands: [\n                { hue: [240, 255], sat: [50, 65], light: [85, 95] },\n                { hue: [250, 265], sat: [45, 60], light: [70, 80] },\n                { hue: [250, 270], sat: [50, 70], light: [55, 65] },\n                { hue: [220, 240], sat: [65, 85], light: [45, 60] },\n                { hue: [180, 195], sat: [45, 65], light: [50, 65] },\n                { hue: [210, 230], sat: [70, 85], light: [35, 45] },\n              ],\n            },\n            HR: {\n              name: \"HeavyRain\",\n              bands: [\n                { hue: [115, 125], sat: [80, 95], light: [45, 60] },\n                { hue: [210, 230], sat: [50, 70], light: [55, 70] },\n                { hue: [240, 255], sat: [45, 65], light: [50, 65] },\n                { hue: [220, 235], sat: [55, 75], light: [45, 55] },\n                { hue: [185, 200], sat: [50, 70], light: [40, 55] },\n                { hue: [230, 250], sat: [80, 95], light: [25, 40] },\n              ],\n            },\n            EV: {\n              name: \"Evening\",\n              bands: [\n                { hue: [200, 215], sat: [65, 80], light: [40, 55] },\n                { hue: [175, 190], sat: [55, 75], light: [50, 65] },\n                { hue: [215, 235], sat: [40, 60], light: [60, 75] },\n                { hue: [240, 255], sat: [35, 55], light: [65, 75] },\n                { hue: [200, 220], sat: [25, 40], light: [80, 90] },\n              ],\n            },\n            MD: {\n              name: \"MiddayClear\",\n              bands: [\n                { hue: [235, 250], sat: [70, 85], light: [30, 45] },\n                { hue: [265, 280], sat: [45, 65], light: [40, 55] },\n                { hue: [290, 310], sat: [35, 55], light: [55, 70] },\n                { hue: [15, 30], sat: [50, 70], light: [60, 75] },\n                { hue: [270, 285], sat: [20, 35], light: [70, 85] },\n                { hue: [210, 225], sat: [35, 55], light: [65, 80] },\n              ],\n            },\n            AG: {\n              name: \"Afterglow\",\n              bands: [\n                { hue: [0, 15], sat: [10, 20], light: [85, 95] },\n                { hue: [20, 35], sat: [45, 65], light: [55, 70] },\n                { hue: [280, 300], sat: [40, 60], light: [50, 65] },\n                { hue: [250, 265], sat: [75, 90], light: [35, 50] },\n                { hue: [25, 40], sat: [35, 55], light: [65, 80] },\n              ],\n            },\n            SD: {\n              name: \"SummerDusk\",\n              bands: [\n                { hue: [250, 265], sat: [65, 80], light: [40, 55] },\n                { hue: [280, 295], sat: [45, 65], light: [50, 65] },\n                { hue: [310, 330], sat: [40, 60], light: [60, 75] },\n                { hue: [340, 355], sat: [35, 55], light: [65, 80] },\n                { hue: [10, 25], sat: [30, 50], light: [70, 85] },\n                { hue: [0, 15], sat: [15, 30], light: [80, 90] },\n              ],\n            },\n            CL: {\n              name: \"Cloudy\",\n              bands: [\n                { hue: [250, 265], sat: [25, 40], light: [85, 95] }
1457,\n                { hue: [255, 270], sat: [35, 50], light: [65, 80] },\n                { hue: [260, 275], sat: [40, 55], light: [55, 70] },\n                { hue: [250, 265], sat: [25, 40], light: [85, 95] },\n              ],\n            },\n            AU: {\n              name: \"Aurora\",\n              bands: [\n                { hue: [240, 260], sat: [70, 90], light: [10, 20] },\n                { hue: [120, 140], sat: [60, 80], light: [35, 50] },\n                { hue: [160, 180], sat: [50, 70], light: [40, 55] },\n                { hue: [280, 300], sat: [60, 80], light: [35, 50] },\n                { hue: [300, 320], sat: [65, 85], light: [30, 45] },\n              ],\n            },\n          };\n\n          const defaultFeeling = {\n            warmth: 0,\n            warmth_change: 0,\n            humidity: 0,\n            gloom: 0,\n            brightness: 0,\n            rain_intensity: 0,\n            rain_amount: 0,\n            precip_form: \"none\",\n            windiness: 0,\n            pressure_trend: 0,\n            sun_elevation: 0,\n            golden: 0,\n            twilight: 0,\n            night: 0,\n            uv: 0,\n          };\n\n          function generateHash(obj) {\n            let hash = 2166136261;\n            const str = JSON.stringify(obj, Object.keys(obj).sort());\n            for (let i = 0; i \u003c str.length; i++) {\n              hash ^= str.charCodeAt(i);\n              hash = Math.imul(hash, 16777619);\n            }\n            return Math.abs(hash);\n          }\n\n          function buildGradient(feel) {\n            const hash = generateHash(feel);\n            const hashBytes = Array.from(\n              { length: 32 },\n              (_, i) =\u003e (hash * (i + 1) * 9999) \u0026 0xff\n            );\n\n            // Derived parameters\n            const storm = clamp(feel.rain_intensity * 0.7 + feel.gloom * 0.3);\n            const drama =\n              storm * 0.4 +\n              feel.windiness * 0.3 +\n              Math.abs(feel.pressure_trend) * 0.3;\n            const serenity =\n              (1 - drama) * (1 - feel.rain_intensity) * feel.brightness;\n            const melancholy =\n              feel.gloom * feel.humidity * (1 - feel.brightness);\n            const electric =\n              (feel.rain_intensity \u003e 0.7 ? feel.rain_intensity : 0) +\n              feel.twilight * feel.golden;\n            const mystical =\n              feel.twilight * (1 - feel.rain_intensity) * feel.humidity;\n            const haziness = feel.humidity * feel.gloom * (1 - feel.windiness);\n            const pressureDir = Math.sign(feel.pressure_trend);\n            const tempDrift = (feel.warmth_change + 1) / 2;\n            const gold = Math.max(feel.golden, feel.twilight);\n\n            const derived = {\n              storm,\n              drama,\n              serenity,\n              melancholy,\n              electric,\n              mystical,\n              haziness,\n              pressureDir,\n              tempDrift,\n              gold,\n            };\n\n            const palette = selectPalette(feel, derived, hashBytes[0]);\n\n            const stopData = generateStops(feel, derived, hashBytes);\n            const colors = generateColors(\n              feel,\n              derived,\n              palette,\n              stopData,\n              hashBytes\n            );\n\n            return validateAndCorrect({ colors, stops: stopData.stops }, feel);\n\n            function selectPalette(feel, d) {\n              if (feel.night === 1 \u0026\u0026 d.storm \u003c 0.4 \u0026\u0026 feel.twilight \u003c 0.2)\n                return REFERENCE_PALETTES.AU;\n              if (d.storm \u003e= 0.5) return REFERENCE_PALETTES.HR;\n              if (d.gold \u003e= 0.5)\n                return feel.gloom \u003c 0.4\n                  ? REFERENCE_PALETTES.AG\n                  : REFERENCE_PALETTES.SD;\n              if (feel.brightness \u003e= 0.6 \u0026\u0026 feel.gloom \u003c= 0.3)\n                return REFERENCE_PALETTES.MD;\n              if (feel.rain_intensity \u003e 0) return REFERENCE_PALETTES.CR;\n              if (feel.gloom \u003e 0.4) return REFERENCE_PALETTES.CL;\n              return feel.warmth \u003c 0.4\n                ? REFERENCE_PALETTES.EV\n                : REFERENCE_PALETTES.SD;\n            }\n\n            function generateStops(feel, d, hb) {\n              // Determine stop count\n              let count =\n                6 +\n                (d.drama \u003e 0.7) -\n                (d.haziness \u003e 0.7) +\n                (feel.
1457windiness \u003e 0.8) +\n                (d.mystical \u003e 0.6);\n              count = Math.max(4, Math.min(8, count));\n\n              let pattern = \"balanced\";\n              if (d.drama \u003e 0.6) pattern = \"dramatic\";\n              else if (d.serenity \u003e 0.7) pattern = \"flowing\";\n              else if (d.electric \u003e 0.6) pattern = \"horizon\";\n              else if (d.melancholy \u003e 0.6) pattern = \"weighted\";\n\n              // base stops generator map\n              const gens = {\n                dramatic: (c) =\u003e {\n                  const s = [0];\n                  const z1 = 0.35 + (hb[5] / 255) * 0.1;\n                  const z2 = 0.65 + (hb[6] / 255) * 0.1;\n                  if (c \u003c= 5) s.push(z1, z1 + 0.06, 1);\n                  else if (c === 6) s.push(0.2, z1, z1 + 0.05, z2, 1);\n                  else if (c === 7)\n                    s.push(0.15, z1, z1 + 0.05, 0.5, z2, z2 + 0.05, 1);\n                  else s.push(0.1, 0.25, z1, z1 + 0.05, 0.55, z2, z2 + 0.05, 1
1457);\n                  return s;\n                },\n                flowing: (c) =\u003e\n                  Array.from({ length: c }, (_, i) =\u003e i / (c - 1)),\n                horizon: (c) =\u003e {\n                  const h = 0.4 + feel.sun_elevation * 0.2;\n                  const s = [0, h - 0.05, h + 0.05, 1];\n                  if (c \u003c= 4) return s;\n                  const before = Math.floor((c - 3) / 2);\n                  const after = c - 3 - before;\n                  const add = [];\n                  for (let i = 1; i \u003c= before; i++)\n                    add.push(h * (i / (before + 1)));\n                  add.push(h - 0.04, h + 0.04);\n                  for (let i = 1; i \u003c= after; i++)\n                    add.push(h + (1 - h) * (i / (after + 1)));\n                  add.push(1);\n                  return [0, ...add];\n                },\n                weighted: (c) =\u003e {\n                  const w = 0.7;\n                  const s = [0];\n                  for (let i = 1; i \u003c c - 1; i++) {\n                    const t = i / (c - 1);\n                    const eased = t * t * (3 - 2 * t);\n                    s.push(eased * w + t * (1 - w));\n                  }\n                  s.push(1);\n                  return s;\n                },\n                balanced: (c) =\u003e {\n                  const acc = 0.3 + (hb[7] / 255) * 0.4;\n                  return Array.from({ length: c }, (_, i) =\u003e {\n                    let p = i / (c - 1);\n                    if (i \u003e 0 \u0026\u0026 i \u003c c - 1 \u0026\u0026 Math.abs(p - acc) \u003c 0.15)\n                      p = acc + (p - acc) * 0.5;\n                    return p;\n                  });\n                },\n              };\n\n              let stops = gens[pattern](count);\n\n              // Jitter \u0026 skew\n              stops = stops.map((s, i) =\u003e\n                i === 0 || i === stops.length - 1\n                  ? s\n                  : clamp(s + (hb[i + 8] / 255 - 0.5) * 0.03 * feel.windiness)\n              );\n              const skew = pressureDir * 0.05 + (tempDrift - 0.5) * 0.03;\n              stops = stops.map((s, i) =\u003e\n                i === 0 || i === stops.length - 1\n                  ? s\n                  : clamp(s + skew * (1 - Math.abs(2 * s - 1)))\n              );\n\n              return { stops, pattern, count };\n            }\n\n            function generateColors(feel, d, palette, stopData, hb) {\n              const assignments = assignBands(palette, stopData, d, hb);\n              return assignments.map((bandIdx, i) =\u003e\n                generateColorFromBand(palette.bands[bandIdx], i)\n              );\n\n              function assignBands(palette, sd, d, hb) {\n                const bCount = palette.bands.length;\n                const a = [];\n                if (palette.name === \"Aurora\") {\n                  a.push(0);\n                  for (let i = 1; i \u003c sd.count - 1; i++) {\n                    const t = (i - 1) / (sd.count - 2);\n                    a.push(1 + Math.floor(t * (bCount - 1)));\n                  }\n                  a.push(0);\n                  return a;\n                }\n                for (let i = 0; i \u003c sd.count; i++) {\n                  if (\n                    sd.pattern === \"dramatic\" \u0026\u0026\n                    d.drama \u003e 0.5 \u0026\u0026\n                    i \u003e 0 \u0026\u0026\n                    sd.stops[i] - sd.stops[i - 1] \u003c 0.08\n                  ) {\n                    a.push((a[i - 1] + Math.floor(bCount / 2)) % bCount);\n                  } else {\n                    const prog = sd.stops[i];\n                    const base = Math.floor(prog * (bCount - 1));\n                    const varOff = hb[i + 12] / 255 \u003c 0.3 ? 1 : 0;\n                    const band = clamp(\n                      base + (hb[i + 13] % 2 ? varOff : -varOff),\n                      0,\n                      bCount - 1\n                    );\n                    a.push(band);\n                  }\n                }\n                return a;\n              }\n\n              function generateColorFromBand(band, i) {\n                let hue = lerp(band.hue[0], band.hue[1], hb[i + 16] / 255);\n                let sat = lerp(band.sat[0], band.sat[1], hb[i + 17] / 25
14575);\n                let light = lerp(\n                  band.light[0],\n                  band.light[1],\n                  hb[i + 18] / 255\n                );\n\n                // Weather tweaks\n                hue += (feel.warmth - 0.5) * 12; // warmth shift\n                if (feel.rain_intensity \u0026\u0026 hue \u003e= 180 \u0026\u0026 hue \u003c= 200)\n                  sat +=\n                    feel.rain_intensity *\n                    15 *\n                    Math.pow(feel.rain_intensity, 0.3);\n                sat = Math.max(30, sat - d.haziness * 15);\n                light = Math.min(95, light + feel.brightness ** 2 * 15);\n                if (d.gold \u0026\u0026 hue \u003e= 10 \u0026\u0026 hue \u003c= 40) {\n                  sat += d.gold * 20;\n                  light += d.gold * 10;\n                }\n                if (feel.night \u0026\u0026 i !== 0 \u0026\u0026 i !== stopData.count - 1)\n                  light = Math.max(35, light);\n                if (\n                  stopData.pattern === \"dramatic\" \u0026\u0026\n                  i \u0026\u0026\n                  stopData.stops[i] - stopData.stops[i - 1] \u003c 0.08\n                )\n                  sat = Math.min(85, sat + 20);\n                if (feel.precip_form === \"snow\") {\n                  if (hue \u003e= 115 \u0026\u0026 hue \u003c= 140) {\n                    hue += 40;\n                    sat *= 0.7;\n                  }\n                  sat = Math.min(70, sat);\n                  light += 5;\n                }\n                if (feel.gloom \u003e 0.5)\n                  light = 50 + (light - 50) * (1 - feel.gloom * 0.4);\n                if (!feel.night \u0026\u0026 light \u003c 35) light = 35;\n                if (sat \u003c 40 \u0026\u0026 light \u003c 65) light = 65;\n\n                return hslToHex(\n                  ((hue % 360) + 360) % 360,\n                  clamp(sat, 0, 100),\n                  clamp(light, 0, 100)\n                );\n              }\n            }\n\n            function validateAndCorrect(data, feel) {\n              let { colors, stops } = data;\n              const hsls = colors.map(hexToHsl);\n              const spans = {\n                hue:\n                  Math.max(...hsls.map((c) =\u003e c.h)) -\n                  Math.min(...hsls.map((c) =\u003e c.h)),\n                sat:\n                  Math.max(...hsls.map((c) =\u003e c.s)) -\n                  Math.min(...hsls.map((c) =\u003e c.s)),\n                light:\n                  Math.max(...hsls.map((c) =\u003e c.l)) -\n                  Math.min(...hsls.map((c) =\u003e c.l)),\n              };\n\n              const interest =\n                spans.hue \u003e= 30 ||\n                spans.sat \u003e= 40 ||\n                spans.light \u003e= 40 ||\n                stops.some((s, i) =\u003e i \u0026\u0026 s - stops[i - 1] \u003c= 0.08);\n              if (!interest) {\n                const maxSatIdx = hsls.reduce(\n                  (m, c, i, arr) =\u003e (c.s \u003e arr[m].s ? i : m),\n                  0\n                );\n                const minSatIdx = hsls.reduce(\n                  (m, c, i, arr) =\u003e (c.s \u003c arr[m].s ? i : m),\n                  0\n                );\n                hsls[maxSatIdx].s = Math.min(85, hsls[maxSatIdx].s + 25);\n                hsls[minSatIdx].s = Math.max(30, hsls[minSatIdx].s - 15);\n                colors[maxSatIdx] = hslToHex(\n                  hsls[maxSatIdx].h,\n                  hsls[maxSatIdx].s,\n                  hsls[maxSatIdx].l\n                );\n                colors[minSatIdx] = hslToHex(\n                  hsls[minSatIdx].h,\n                  hsls[minSatIdx].s,\n                  hsls[minSatIdx].l\n                );\n              }\n\n              // Forbidden color combinations\n              const forb = [\n                [\n                  [115, 140],\n                  [0, 40],\n                ],\n                [\n                  [115, 140],\n                  [340, 360],\n                ],\n                [\n                  [60, 80],\n                  [280, 300],\n                ],\n              ];\n              for (let i = 1; i \u003c colors.length;
1457 i++) {\n                const a = hsls[i - 1].h;\n                const b = hsls[i].h;\n                forb.forEach(([r1, r2]) =\u003e {\n                  if (\n                    (a \u003e= r1[0] \u0026\u0026 a \u003c= r1[1] \u0026\u0026 b \u003e= r2[0] \u0026\u0026 b \u003c= r2[1]) ||\n                    (a \u003e= r2[0] \u0026\u0026 a \u003c= r2[1] \u0026\u0026 b \u003e= r1[0] \u0026\u0026 b \u003c= r1[1])\n                  ) {\n                    const bridge = hslToHex(270, 30, 70);\n                    colors.splice(i, 0, bridge);\n                    stops.splice(i, 0, (stops[i - 1] + stops[i]) / 2);\n                    hsls.splice(i, 0, hexToHsl(bridge));\n                  }\n                });\n              }\n\n              // Green needs blue/purple\n              if (\n                hsls.some((c) =\u003e c.h \u003e= 115 \u0026\u0026 c.h \u003c= 140) \u0026\u0026\n                !hsls.some((c) =\u003e c.h \u003e= 200 \u0026\u0026 c.h \u003c= 280)\n              ) {\n                colors = colors.map((col) =\u003e {\n                  const hsl = hexToHsl(col);\n                  if (hsl.h \u003e= 115 \u0026\u0026 hsl.h \u003c= 140) {\n                    hsl.h = 180 + (hsl.h - 115) * 0.8;\n                    return hslToHex(hsl.h, hsl.s, hsl.l);\n                  }\n                  return col;\n                });\n              }\n\n              // Day‑light constraints\n              if (!feel.night) {\n                colors = colors.map((col) =\u003e {\n                  const hsl = hexToHsl(col);\n                  if (hsl.l \u003c 35) hsl.l = 35;\n                  if (hsl.s \u003c 40 \u0026\u0026 hsl.l \u003c 65) hsl.l = 65;\n                  return hslToHex(hsl.h, hsl.s, hsl.l);\n                });\n              }\n\n              // Ensure ≥5 % stop gap \u0026 bounds\n              for (let i = 1; i \u003c stops.length; i++) {\n                if (stops[i] - stops[i - 1] \u003c 0.05) {\n                  const adj = (0.05 - (stops[i] - stops[i - 1])) / 2;\n                  if (i - 2 \u003e= 0 \u0026\u0026 stops[i - 1] - stops[i - 2] \u003c 0.05 + adj)\n                    stops[i] += adj * 2;\n                  else {\n                    stops[i - 1] -= adj;\n                    stops[i] += adj;\n                  }\n                }\n              }\n              stops = stops.map((s, idx) =\u003e clamp(s, 0, 1));\n              stops[0] = 0;\n              stops[stops.length - 1] = 1;\n\n              return { colors, stops };\n            }\n          }\n\n          // Weather \"feel\"\n          function calcFeel(agg, sun, nowT) {\n            const sunriseT = new Date(sun.properties.sunrise.time);\n            const sunsetT = new Date(sun.properties.sunset.time);\n            const elevFrac = solarElevationFrac(nowT, sunriseT, sunsetT);\n            const golden = clamp(1 - Math.abs(elevFrac - 0.08) / 0.08);\n            const twilight = clamp(1 - Math.abs(nowT - sunsetT) / 4.5e6);\n            const night = elevFrac \u003c= 0 ? 1 : 0;\n            const AT = apparentTemp(agg.Tbar, agg.RHbar, agg.WSbar);\n            const warm = warmthScore(AT);\n            const warmChange = tanh(agg.deltaT / 4);\n            const humidityFeel = muggyIndex(agg.DPbar);\n            const windFeel =\n              sigmoid((agg.WSbar - 2) / 3) * (agg.Tbar \u003c 10 ? 1.2 : 1);\n            const cloudFrac = agg.CCbar / 100;\n            const brightness = elevFrac * (1 - cloudFrac);\n            const gloom = clamp(1.2 * cloudFrac * (1 - elevFrac));\n            const rainIntensity = agg.PR1 \u003e 0 ? sigmoid(agg.PR1max / 3) : 0;\n            const rainAmount = tanh(agg.PR6sum / 24);\n            const precipForm =\n              agg.Tbar \u003c= 0\n                ? \"snow\"\n                : agg.Tbar \u003c 2 \u0026\u0026 agg.RHbar \u003e 90\n                ? \"sleet\"\n                : \"rain\";\n            const uvNorm = clamp(agg.UV / 11);\n            return {\n              warmth: warm,\n              warmth_change: warmChange,\n              humidity: humidityFeel,\n              gloom,\n              brightness,\n              rain_intensity: rainIntensity,\n              rain_amount: rainAmount,\n              precip_form: precipForm,\n              windiness: windFeel,\n              pressure_trend: tanh(agg.deltaP3h / 2),\n              sun_elevation: elevFrac,\n              golden,\n              twilight,\n              night,\n              uv: uvNorm,\n            };\n          }\n\n          function apparentTemp(T, RH, WS) {\n            const e = (RH / 100) * 6.105 * Math.exp((17.27 * T) / (237.7 + T));\n            return T + 0.33 * e - 0.7 * WS - 4.0;\n          }\n          function muggyIndex(dp) {\n            return clamp((dp - 10) / 14);\n          }\n          function warmthScore(AT) {\n            return clamp(sigmoid((AT - 15) / 10));\n          }\n          function solarElevationFrac(now, sunrise, sunset) {\n            const len = sunset - sunrise || 1;\n            const f = clamp((now - sunrise) / len);\n            return Math.sin(Math.PI * f);\n          }\n\n          async function fetchForecast(lat, lon) {\n            const fcRes = await fetch(\n              `https://api.met.no/weatherapi/locationforecast/2.0/complete?lat=${lat}\u0026lon=${lon}`\n            );\n            if (!fcRes.ok) throw Error(`locationforecast ${fcRes.status}`);\n            const fc = await fcRes.json();\n            const sunRes = await fetch(\n              `https://api.met.no/weatherapi/sunrise/3.0/sun?lat=${lat}\u0026lon=${lon}\u0026date=${new Date()\n                .toISOString()\n                .slice(0, 10)}`\n            );\n            if (!sunRes.ok) throw Error(`sunrise ${sunRes.status}`);\n            const sun = await sunRes.json();\n            const start = new Date();\n            start.setUTCHours(0, 0, 0, 0);\n            const end = new Date(start);\n            end.setUTCDate(end.getUTCDate() + 1);\n            const pts = fc.properties.timeseries.filter((p) =\u003e {\n              const t = parseISO(p.time);\n              return t \u003e= start \u0026\u0026 t \u003c end;\n            });\n            const pull = (f) =\u003e\n              pts.map((p) =\u003e p.data.instant.details[f] ?? null);\n            const mean = (a) =\u003e a.reduce((s, v) =\u003e s + v, 0) / a.length;
1457\n            const agg = {\n              Tbar: mean(pull(\"air_temperature\")),\n              DPbar: mean(pull(\"dew_point_temperature\")),\n              RHbar: mean(pull(\"relative_humidity\")),\n              Pbar: mean(pull(\"air_pressure_at_sea_level\")),\n              CCbar: mean(pull(\"cloud_area_fraction\")),\n              WSbar: mean(pull(\"wind_speed\")),\n              UV: mean(pull(\"ultraviolet_index_clear_sky\")),\n              PR1: pts[0].data.next_1_hours?.details?.precipitation_amount ?? 0,\n              PR1max: Math.max(\n                ...pts.map(\n                  (p) =\u003e p.data.next_1_hours?.details?.precipitation_amount ?? 0\n                )\n              ),\n              PR6sum: pts\n                .filter((_, i) =\u003e i % 6 === 0)\n                .reduce(\n                  (s, p) =\u003e\n                    s +\n                    (p.data.next_6_hours?.details?.precipitation_amount ?? 0),\n                  0\n                ),\n              deltaP3h:\n                pull(\"air_pressure_at_sea_level\").slice(-1)[0] -\n                pull(\"air_pressure_at_sea_level\").slice(-4)[0],\n              deltaT:\n                mean(pull(\"air_temperature\").slice(pts.length / 2)) -\n                mean(pull(\"air_temperature\").slice(0, pts.length / 2)),\n            };\n            const nowT = parseISO(pts[0].time);\n            const feeling = calcFeel(agg, sun, nowT);\n            const first = pts[0].data.instant.details;\n            const p1h = pts[0].data.next_1_hours?.details ?? {};\n            return {\n              temp: first.air_temperature,\n              wind: first.wind_speed,\n              clouds: first.cloud_area_fraction / 100,\n              humidity: first.relative_humidity / 100,\n              precipAmount: p1h.precipitation_amount ?? 0,\n              precipType:\n                feeling.precip_form === \"snow\"\n                  ? \"snow\"\n                  : (p1h.precipitation_amount ?? 0) \u003e 0\n                  ? \"rain\"\n                  : \"none\",\n              uvIndex: first.ultraviolet_index_clear_sky,\n              timeISO: pts[0].time,\n              sunriseISO: sun.properties.sunrise.time,\n              sunsetISO: sun.properties.sunset.time,\n              feeling,\n            };\n          }\n\n          const TIME_SCALE = 0.53,\n            WIND_SCALE = 3,\n            NOISE_FREQ = 0.45,\n            CLOUD_DETAIL = 0.65,\n            LERP = 0.05,\n            MAX_STOPS = 8,\n            MAX_GAPS = MAX_STOPS - 1;\n\n          const status = document.getElementById(\"animated-hero__status\");\n          const cityEl = document.getElementById(\"animated-hero__city\");\n          const tempEl = document.getElementById(\"animated-hero__temp\");\n          const windEl = document.getElementById(\"animated-hero__wind\");\n          const timeEl = document.getElementById(\"animated-hero__time\");\n          const footer = document.getElementById(\"animated-hero__footer\");\n          const rndBtn = document.getElementById(\"animated-hero__rnd\");\n          const rndSvg = rndBtn.querySelector(\"svg\");\n          const met = document.getElementById(\"animated-hero__met\");\n          const weather = document.getElementById(\"animated-hero__weather\");\n          const track = document.getElementById(\"animated-hero__weather-track\");\n\n          const canv = document.getElementById(\"animated-hero__canvas\");\n          const gl = canv.getContext(\"webgl\");\n\n          let tickId = null;\n\n          let lowerContrast = \"#fff\";\n          let upperContrast = \"#fff\";\n\n          const deskCSS = {\n            footer: footer.style.cssText,\n            rndBtn: rndBtn.style.cssText,\n            rndSvg: rndSvg.style.cssText,\n            met: met.style.cssText,\n            weather: weather.style.cssText,\n            track: track.style.cssText,\n          };\n\n          function resize() {\n            canv.width = canv.clientWidth * devicePixelRatio;\n            canv.height = canv.clientHeight * devicePixelRatio;\n            gl.viewport(0, 0, canv.width, canv.height);\n            applyResponsive();\n          }\n          addEventListener(\"resize\", resize);\n          resize();\n\n          const vs = `attribute vec2 p;varying vec2 vUv;void main(){vUv=(p+1.)*.5;gl_Position=vec4(p,0,1);} `;\n          const noise = `//\tSimplex 3D Noise \n        //\tby Ian McEwan, Stefan Gustavson (https://github.com/stegu/webgl-noise)\n        //\n        vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);}\n        vec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;}\n\n        float snoise(vec3 v){ \n        const vec2  C = vec2(1.0/6.0, 1.0/3.0) ;\n        const vec4  D = vec4(0.0, 0.5, 1.0, 2.0);
1457\n\n        // First corner\n        vec3 i  = floor(v + dot(v, C.yyy) );\n        vec3 x0 =   v - i + dot(i, C.xxx) ;\n\n        // Other corners\n        vec3 g = step(x0.yzx, x0.xyz);\n        vec3 l = 1.0 - g;\n        vec3 i1 = min( g.xyz, l.zxy );\n        vec3 i2 = max( g.xyz, l.zxy );\n\n        //  x0 = x0 - 0. + 0.0 * C \n        vec3 x1 = x0 - i1 + 1.0 * C.xxx;\n        vec3 x2 = x0 - i2 + 2.0 * C.xxx;\n        vec3 x3 = x0 - 1. + 3.0 * C.xxx;\n\n        // Permutations\n        i = mod(i, 289.0 ); \n        vec4 p = permute( permute( permute( \n                    i.z + vec4(0.0, i1.z, i2.z, 1.0 ))\n                + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) \n                + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));\n\n        // Gradients\n        // ( N*N points uniformly over a square, mapped onto an octahedron.)\n        float n_ = 1.0/7.0; // N=7\n        vec3  ns = n_ * D.wyz - D.xzx;\n\n        vec4 j = p - 49.0 * floor(p * ns.z *ns.z);  //  mod(p,N*N)\n\n        vec4 x_ = floor(j * ns.z);\n        vec4 y_ = floor(j - 7.0 * x_ );    // mod(j,N)\n\n        vec4 x = x_ *ns.x + ns.yyyy;\n        vec4 y = y_ *ns.x + ns.yyyy;\n        vec4 h = 1.0 - abs(x) - abs(y);\n\n        vec4 b0 = vec4( x.xy, y.xy );\n        vec4 b1 = vec4( x.zw, y.zw );\n\n        vec4 s0 = floor(b0)*2.0 + 1.0;\n        vec4 s1 = floor(b1)*2.0 + 1.0;\n        vec4 sh = -step(h, vec4(0.0));\n\n        vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;\n        vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;\n\n        vec3 p0 = vec3(a0.xy,h.x);\n        vec3 p1 = vec3(a0.zw,h.y);\n        vec3 p2 = vec3(a1.xy,h.z);\n        vec3 p3 = vec3(a1.zw,h.w);\n\n        //Normalise gradients\n        vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n        p0 *= norm.x;\n        p1 *= norm.y;\n        p2 *= norm.z;\n        p3 *= norm.w;\n\n        // Mix final noise value\n        vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n        m = m * m;\n        return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), \n                                        dot(p2,x2), dot(p3,x3) ) );\n        }\\n`;\n          const fs = `precision mediump float;varying vec2 vUv;uniform vec2 iResolution;uniform float iTime,uTimeScale,uWindScale,uNoiseFreq,uCloudDetail;uniform float uCloudCover,uWindNorm,uWindOffset;uniform vec3 uColor[${MAX_STOPS}];uniform float uStops[${\n            MAX_STOPS - 1\n          }];uniform float uStopCount;${noise}\nvec3 pal(float t){vec3 col=uColor[0];float prev=0.;int cnt=int(uStopCount+0.5);for(int i=1;i\u003c${MAX_STOPS};i++){if(i\u003e=cnt)break;float edge=smoothstep(prev,uStops[i-1],t);col=mix(col,uColor[i],edge);prev=uStops[i-1];}return col;}\nvec3 toSRGB(vec3 v){return pow(v,vec3(1./2.2));}\nvoid main(){vec2 uv=vUv;float t=iTime*uTimeScale;float base=snoise(vec3(uv*0.8*uNoiseFreq,t*0.1));vec2 wuv=uv;wuv.x-=uWindOffset;vec2 wind=vec2(snoise(vec3(wuv*2.*uNoiseFreq+t*0.2,t*0.5)),snoise(vec3(wuv*2.*uNoiseFreq-t*0.05,t*0.2)));uv+=wind*(pow(uWindNorm,0.7)*0.15+0.02)*uWindScale;uv.x+=base*0.05*uNoiseFreq;float cloudEff=max(uCloudCover,uWindNorm*0.5);float g=uv.y+snoise(vec3(uv*uCloudDetail*mix(1.,3.,cloudEff),t*0.1))*0.2*cloudEff;g=clamp(g,0.,1.);g+=sin(uv.y*10.*uNoiseFreq+t*0.2+base*2.*uNoiseFreq)*0.02;g=clamp(g,0.,1.);gl_FragColor=vec4(toSRGB(pal(g)),1.);} `;\n\n          function sh(type, src) {\n            const s = gl.createShader(type);\n            gl.shaderSource(s, src);\n            gl.compileShader(s);\n            if (!gl.getShaderParameter(s, gl.COMPILE_STATUS))\n              throw gl.getShaderInfoLog(s);\n            return s;\n          }\n          const prog = gl.createProgram();\n          gl.attachShader(prog, sh(gl.VERTEX_SHADER, vs));\n          gl.attachShader(prog, sh(gl.FRAGMENT_SHADER, fs));\n          gl.linkProgram(prog);\n          if (!gl.getProgramParameter(prog, gl.LINK_STATUS))\n            throw gl.getProgramInfoLog(prog);\n          gl.useProgram(prog);\n\n          const buf = gl.createBuffer();\n          gl.bindBuffer(gl.ARRAY_BUFFER, buf);\n          gl.bufferData(\n            gl.ARRAY_BUFFER,\n            new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]),\n            gl.STATIC_DRAW\n          );\n          const loc = gl.getAttribLocation(prog, \"p\");\n          gl.enableVertexAttribArray(loc);\n          gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0);\n\n          const uni = {\n            res: gl.getUniformLocation(prog, \"iResolution\"),\n            time: gl.getUniformLocation(prog, \"iTime\"),\n            cloud: gl.getUniformLocation(prog, \"uCloudCover\"),\n            windNorm: gl.getUniformLocation(prog, \"uWindNorm\"),\n            windOff: gl.getUniformLocation(prog, \"uWindOffset\"),\n            stopCount: gl.getUniformLocation(prog, \"uStopCount\"),\n            stops: gl.getUniformLocation(prog, \"uStops\"),\n            colors: gl.getUniformLocation(prog, \"uColor[0]\"),\n            timeScale: gl.getUniformLocation(prog, \"uTimeScale\"),\n            windScale: gl.getUniformLocation(prog, \"uWindScale\"),\n            noiseFreq: gl.getUniformLocation(prog, \"uNoiseFreq\"),\n            cloudDet: gl.getUniformLocation(prog, \"uCloudDetail\"),\n          };\n          gl.uniform1f(uni.timeScale, TIME_SCALE);\n          gl.uniform1f(uni.windScale, WIND_SCALE);\n          gl.uniform1f(uni.noiseFreq, NOISE_FREQ);\n          gl.uniform1f(uni.cloudDet, CLOUD_DETAIL);\n\n          let anim = {\n            colors: Array.from({ length: MAX_STOPS }, () =\u003e ({\n              r: 1,\n              g: 1,\n              b: 1,\n            })),\n            stops: new Float32Array(MAX_GAPS).fill(1),\n            stopCount: 4,\n            cloud: 0,\n            wind: 0.2,\n          };\n          let target = { ...anim };\n          let windOffset = 0;\n\n          function uploadColors() {\n            const flat = [];\n            for (const c of anim.colors) {\n              flat.push(c.r, c.g, c.b);\n            }\n            gl.uniform3fv(uni.colors, new Float32Array(flat));\n          }
1457\n          function uploadStops() {\n            gl.uniform1fv(uni.stops, anim.stops);\n          }\n          function uploadStatics() {\n            gl.uniform1f(uni.stopCount, anim.stopCount);\n            gl.uniform1f(uni.cloud, anim.cloud);\n            gl.uniform1f(uni.windNorm, anim.wind);\n          }\n\n          function applyResponsive() {\n            const MOBILE_MAX = 600;\n\n            function desktop() {\n              footer.style.cssText = deskCSS.footer;\n              rndBtn.style.cssText = deskCSS.rndBtn;\n              rndSvg.style.cssText = deskCSS.rndSvg;\n              met.style.cssText = deskCSS.met;\n              weather.style.cssText = deskCSS.weather;\n              track.style.cssText = deskCSS.track;\n              stopTicker();\n              applyInk();\n            }\n\n            function mobile() {\n              footer.style.cssText = `\n            ${deskCSS.footer}\n            top:30px; bottom:auto; left:20px;\n            font-size:16px; line-height:25px; max-width:60vw;`;\n\n              rndBtn.style.cssText = `${deskCSS.rndBtn} width:16px; height:16px;`;\n              rndSvg.style.cssText = `${deskCSS.rndSvg} width:16px; height:16px;`;\n\n              met.style.cssText = `\n            ${deskCSS.met}\n            left:20px; right:auto; bottom:30px;\n            font-size:16px; line-height:25px;`;\n\n              weather.style.cssText = `\n            ${deskCSS.weather}\n            overflow:hidden;\n            height:${track.firstElementChild.offsetHeight}px;`;\n\n              track.style.cssText = `\n            display:flex;\n            flex-direction:column;\n            gap:6px;\n            will-change:transform;\n            transform:translateY(0);`;\n              startTicker();\n              applyInk(true);\n            }\n\n            (window.innerWidth \u003c= MOBILE_MAX ? mobile : desktop)();\n          }\n\n          function startTicker() {\n            if (tickId) return;\n\n            tickId = setInterval(() =\u003e {\n              track.style.transition = \"transform .35s ease-out\";\n              track.style.transform = `translateY(-${track.firstElementChild.offsetHeight + 6}px)`;\n\n              track.addEventListener(\n                \"transitionend\",\n                function f() {\n                  track.removeEventListener(\"transitionend\", f);\n\n                  track.appendChild(track.firstElementChild);\n\n                  track.style.transition = \"none\";\n                  track.style.transform = \"translateY(0)\";\n                  void track.offsetHeight;\n                },\n                { once: true }\n              );\n            }, 5000);\n          }\n\n          function stopTicker() {\n            clearInterval(tickId);\n            tickId = null;\n            track.style.transition = \"none\";\n            track.style.transform = \"translateY(0)\";\n          }\n\n          const offices = [\n            {\n              city: \"Stockholm\",\n              lat: 59.3293,\n              lon: 18.0686,\n              tz: \"Europe/Stockholm\",\n            },\n            {\n              city: \"Göteborg\",\n              lat: 57.7075,\n              lon: 11.9675,\n              tz: \"Europe/Stockholm\",\n            },\n            {\n              city: \"Malmö\",\n              lat: 55.6058,\n              lon: 13.0358,\n              tz: \"Europe/Stockholm\",\n            },\n            {\n              city: \"Jönköping\",\n              lat: 57.7828,\n              lon: 14.1606,\n              tz: \"Europe/Stockholm\",\n            },\n            {\n              city: \"Karlstad\",\n              lat: 59.3783,\n              lon: 13.5042,\n              tz: \"Europe/Stockholm\",\n            },\n            {\n              city: \"Karlskrona\",\n              lat: 56.1612,\n              lon: 15.5869,\n              tz: \"Europe/Stockholm\",\n            },\n            {\n              city: \"Linköping\",\n              lat: 58.4109,\n              lon: 15.6216,\n              tz: \"Europe/Stockholm\",\n            },\n            {\n              city: \"Luleå\",\n              lat: 65.5848,\n              lon: 22.1547,\n              tz: \"Europe/Stockholm\",\n            },\n            { city: \"Lund\", lat: 55.7047, lon: 13.191, tz: \"Europe/Stockholm\" },\n            {\n              city: \"Borlänge\",\n              lat: 60.4847,\n              lon: 15.426,\n              tz: \"Europe/Stockholm\",\n            },\n            {\n              city: \"Gävle\",\n              lat: 60.6749,\n              lon: 17.1413,\n              tz: \"Europe/Stockholm\",\n            },\n            {\n              city: \"Helsingborg\",\n              lat: 56.0465,\n              lon: 12.6945,\n              tz: \"Europe/Stockholm\",\n            },\n            {\n              city: \"Sundsvall\",\n              lat: 62.3908,\n              lon: 17.3069,\n              tz: \"Europe/Stockholm\",\n            },\n            {\n              city: \"Uppsala\",\n              lat: 59.8586,\n              lon: 17.6389,\n              tz: \"Europe/Stockholm\",\n            },\n            {\n              city: \"Örebro\",\n              lat: 59.2741,\n              lon: 15.2066,\n              tz: \"Europe/Stockholm\",\n            },\n            {\n              city: \"Trollhättan\",\n              lat: 58.2837,\n              lon: 12.2886,\n              tz: \"Europe/Stockholm\",\n            },\n            { city: \"Oslo\", lat: 59.9139, lon: 10.7522, tz: \"Europe/Oslo\" },\n            { city: \"Bergen\", lat: 60.3928, lon: 5.3239, tz: \"Europe/Oslo\" },\n            { city: \"Stavanger\", lat: 58.969, lon: 5.7331, tz: \"Europe/Oslo\" },\n            {\n              city: \"Kristiansand\",\n              lat: 58.1467,\n              lon: 7.9956,\n              tz: \"Europe/Oslo\",\n            }
1457,\n            { city: \"Arendal\", lat: 58.4614, lon: 8.772, tz: \"Europe/Oslo\" },\n            { city: \"Hamar\", lat: 60.7945, lon: 11.067, tz: \"Europe/Oslo\" },\n            {\n              city: \"København\",\n              lat: 55.6761,\n              lon: 12.5683,\n              tz: \"Europe/Copenhagen\",\n            },\n            {\n              city: \"Aarhus\",\n              lat: 56.1629,\n              lon: 10.2039,\n              tz: \"Europe/Copenhagen\",\n            },\n            {\n              city: \"Helsinki\",\n              lat: 60.1699,\n              lon: 24.9384,\n              tz: \"Europe/Helsinki\",\n            },\n            {\n              city: \"Tampere\",\n              lat: 61.4978,\n              lon: 23.761,\n              tz: \"Europe/Helsinki\",\n            },\n            {\n              city: \"Turku\",\n              lat: 60.4518,\n              lon: 22.2673,\n              tz: \"Europe/Helsinki\",\n            },\n            { city: \"Oulu\", lat: 65.0121, lon: 25.4651, tz: \"Europe/Helsinki\" },\n            {\n              city: \"Warszawa\",\n              lat: 52.2297,\n              lon: 21.0122,\n              tz: \"Europe/Warsaw\",\n            },\n            {\n              city: \"Bydgoszcz\",\n              lat: 53.1235,\n              lon: 18.0084,\n              tz: \"Europe/Warsaw\",\n            },\n            { city: \"Łódź\", lat: 51.7592, lon: 19.455, tz: \"Europe/Warsaw\" },\n            { city: \"Bremen\", lat: 53.0793, lon: 8.8017, tz: \"Europe/Berlin\" },\n            {\n              city: \"Umeå\",\n              lat: 63.8274,\n              lon: 20.2699,\n              tz: \"Europe/Stockholm\",\n            },\n            {\n              city: \"Östersund\",\n              lat: 63.1743,\n              lon: 14.6411,\n              tz: \"Europe/Stockholm\",\n            },\n            {\n              city: \"Viby\",\n              lat: 56.1188,\n              lon: 10.1399,\n              tz: \"Europe/Copenhagen\",\n            },\n            {\n              city: \"Aalborg\",\n              lat: 57.0465,\n              lon: 9.9225,\n              tz: \"Europe/Copenhagen\",\n            },\n            {\n              city: \"Trondheim\",\n              lat: 63.4302,\n              lon: 10.3829,\n              tz: \"Europe/Oslo\",\n            },\n            { city: \"Ålesund\", lat: 62.4712, lon: 6.158, tz: \"Europe/Oslo\" },\n          ];\n          let lastIdx = -1;\n          function pickOffice() {\n            let i;\n            do i = Math.floor(Math.random() * offices.length);\n            while (i === lastIdx);\n            lastIdx = i;\n            return offices[i];\n          }\n          async function load() {\n            const office = pickOffice();\n            try {\n              const wx = await fetchForecast(office.lat, office.lon);\n              cityEl.textContent = office.city;\n\n              const timeStr = new Date().toLocaleTimeString(\"sv-SE\", {\n                hour: \"2-digit\",\n                minute: \"2-digit\",\n                hour12: false,\n                timeZone: office.tz,\n              });\n\n              // Update individual elements using textContent\n              tempEl.textContent = wx.temp + \"ºC\";\n              windEl.textContent = wx.wind + \" m/s\";\n              timeEl.textContent = timeStr;\n\n              const pal = buildGradient(wx.feeling);\n              // pad/trim\n              while (pal.colors.length \u003c MAX_STOPS)\n                pal.colors.push(pal.colors[pal.colors.length - 1]);\n              const cArr = pal.colors.slice(0, MAX_STOPS).map(hexToRgbNorm);\n              target.colors = cArr;\n              const st = pal.stops.slice(1);\n              while (st.length \u003c MAX_GAPS) st.push(1);\n              target.stops = Float32Array.from(st);\n              target.stopCount = pal.colors.length;\n              target.cloud = wx.clouds;\n              target.wind = clamp(wx.wind / 16, 0.02, 1);\n\n              sampleInk(pal);\n            } catch (e) {\n              status.textContent = \"Error: \" + e.message;\n            }\n          }\n          (function initPlaceholder() {\n            const pal = buildGradient(defaultFeeling);\n\n            // pad/trim to MAX_STOPS\n            while (pal.colors.length \u003c MAX_STOPS)\n              pal.colors.push(pal.colors[pal.colors.length - 1]);\n\n            target.colors = pal.colors.slice(0, MAX_STOPS).map(hexToRgb
1457Norm);\n            const st = pal.stops.slice(1);\n            while (st.length \u003c MAX_GAPS) st.push(1);\n            target.stops = Float32Array.from(st);\n            target.stopCount = pal.colors.length;\n            target.cloud = 0;\n            target.wind = 0.2;\n\n            sampleInk(pal);\n          })();\n          document.getElementById(\"animated-hero__rnd\").onclick = load;\n          load();\n\n          let prev = performance.now();\n          function step(ts) {\n            const dt = (ts - prev) / 1000;\n            prev = ts;\n            // interpolate colours\n            for (let i = 0; i \u003c MAX_STOPS; i++) {\n              anim.colors[i].r = lerp(\n                anim.colors[i].r,\n                target.colors[i].r,\n                LERP\n              );\n              anim.colors[i].g = lerp(\n                anim.colors[i].g,\n                target.colors[i].g,\n                LERP\n              );\n              anim.colors[i].b = lerp(\n                anim.colors[i].b,\n                target.colors[i].b,\n                LERP\n              );\n            }\n            // interpolate stops\n            for (let i = 0; i \u003c MAX_GAPS; i++) {\n              anim.stops[i] = lerp(anim.stops[i], target.stops[i], LERP);\n            }\n            anim.stopCount = lerp(anim.stopCount, target.stopCount, LERP);\n            anim.cloud = lerp(anim.cloud, target.cloud, LERP);\n            anim.wind = lerp(anim.wind, target.wind, LERP);\n            windOffset += (0.1 + 0.75 * anim.wind) * TIME_SCALE * dt;\n\n            uploadColors();\n            uploadStops();\n            uploadStatics();\n            gl.uniform2f(uni.res, canv.width, canv.height);\n            gl.uniform1f(uni.time, ts / 1000);\n            gl.uniform1f(uni.windOff, windOffset);\n\n            gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n            requestAnimationFrame(step);\n          }\n          uploadColors();\n          uploadStops();\n          uploadStatics();\n\n          function luminance(r, g, b) {\n            // WCAG relative luminance\n            return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;\n          }\n          function bestInk(r, g, b) {\n            return luminance(r, g, b) \u003e 0.53 ? \"#000\" : \"#fff\";\n          }\n\n          function contrastFor(hex1, hex2) {\n            const avg = [hex1, hex2]\n              .map(hexToRgbNorm)\n              .reduce(\n                (a, c) =\u003e ({ r: a.r + c.r, g: a.g + c.g, b: a.b + c.b }),\n                {\n                  r: 0,\n                  g: 0,\n                  b: 0,\n                }\n              );\n\n            return bestInk(avg.r * 127.5, avg.g * 127.5, avg.b * 127.5);\n          }\n\n          function sampleInk(pal) {\n            lowerContrast = contrastFor(pal.colors[0], pal.colors[1]);\n            upperContrast = contrastFor(\n              pal.colors[pal.colors.length - 2],\n              pal.colors[pal.colors.length - 1]\n            );\n            applyInk();\n          }\n\n          function applyInk(mobile = false) {\n            if (mobile) {\n              footer.style.color = upperContrast;\n              met.style.color = lowerContrast;\n            } else {\n              footer.style.color = lowerContrast;\n              met.style.color = lowerContrast;\n            }\n          }\n\n          requestAnimationFrame(step);\n        });\n        window.addEventListener(\"pagehide\", () =\u003e {\n          window.__heroCanvasLoaded = false;\n        });\n      })();\n    }\n  \u003c/script\u003e\n\u003c/div\u003e"}}}],"mainContentArea":[{"youtubeVideoSrc":"https://www.youtube.com/watch?v=YhoIC9E7G_g\u0026t=29s","vimeoVideoSrc":null,"contentType":"VideoBlock","contentGuid":"0dfc0436-e72f-4205-926a-982d3c0a1535","blockId":null},{"heading":"Nasze projekty","cases":[{"clientLabel":null,"industryLabels":["Budownictwo i nieruchomości"],"switchBlockColors":false,"cultureSpecificSubTopicCategories":null,"partialImageStartPage":null,"schemaData":{"kind":"creativeWork","schemaData":null},"heading":"Inteligentny kask. Bezpieczeństwo pracowników na budowie","preamble":"Skoncentrowany wokół potrzeby podniesienia bezpieczeństwa w środowisku placu budowy projekt zrealizowano w ramach Innovation Zone.","image":"/globalassets/image-bank/removed-from-the-root/inteligentny-kask.png","icon":null,"url":"/Projekty/inteligentny-kask-zadba-o-bezpieczestwo-na-budowie/","contentAdmin":null},{"clientLabel":"Husqvarna","industryLabels":["Produkcja"],"switchBlockColors":false,"cultureSpecificSubTopicCategories":null,"partialImageStartPage":null,"schemaData":{"kind":"creativeWork","schemaData":null},"heading":"Husqvarna - autonomiczna kosiarka","preamble":"Grupa Husqvarna jest światowym liderem w produkcji urządzeń elektrycznych do użytku na zewnątrz, w tym pił łańcuchowych, przycinarek, automatycznych kosiarek i traktorów ogrodowych.","image":"/contentassets/c07011616e6d4783a2e7cee62039a012/app-connect-800x450.jpg","
1457icon":null,"url":"/Projekty/husqvarna---autonomiczna-kosiarka/","contentAdmin":null},{"clientLabel":"HIAB","industryLabels":["Transport i logistyka"],"switchBlockColors":false,"cultureSpecificSubTopicCategories":null,"partialImageStartPage":null,"schemaData":{"kind":"creativeWork","schemaData":null},"heading":"HIAB Julia - konserwacja predyktywna","preamble":"HIAB jest wiodącym, światowym dostawcą urządzeń z dziedziny przeładunku drogowego i częścią Cargotec Corporation. W 1947 roku wynalazł pierwszy na świecie hydrauliczny dźwig samojezdny. Inne, znane produkty firmy to żurawie cargo, żurawie leśne i recyklingowe, podwieszane wózki widłowe, urządzenia do wymiany nadwozi, jak również platformy załadunkowe.","image":"/contentassets/da71dc45d94e4690a90b048f2e664b7b/hiab-1920x1080.jpg","icon":null,"url":"/Projekty/hiab-julia---konserwacja-predyktywna/","contentAdmin":null}],"buttonLinkItem":{"buttonLink":"/Projekty/","buttonText":"Wszystkie projekty"},"casePageLabel":"Projekt","contentType":"CaseListingBlock","contentGuid":"dbfb1fa2-2e89-45ab-8229-607667f44274","blockId":null},{"heading":"Wiadomości","news":[{"heading":"Knowit Poland na targach EOT – Electronics of Tomorrow 2025","published":"01.10.2025","label":"Artykuł","url":"/wiadomosci/knowit-poland-na-targach-eot-2025/","category":0,"hideDateAndTime":false},{"heading":"Knowit Poland na MSPO 2025 w Kielcach","published":"09.09.2025","label":"Artykuł","url":"/wiadomosci/knowit-poland-na-mspo-2025-w-kielcach/","category":0,"hideDateAndTime":false},{"heading":"Knowit otrzymuje specjalizację Microsoft Azure Analytics i odnawia certyfikat Azure Expert MSP","published":"05.06.2025","label":"Artykuł","url":"/wiadomosci/knowit-otrzymuje-specjalizacj-microsoft-azure-analytics-i-odnawia-certyfikat-azure-expert-msp/","category":0,"hideDateAndTime":false}],"buttonLinkItem":{"buttonLink":"/wiadomosci/","buttonText":"Pokaż wszystko"},"contentType":"NewsListingBlock","contentGuid":"f37f58ac-8673-4387-b831-895b45147bb7","blockId":null}],"photographer":"Fotograf","schemaInput":{"kind":"organization"},"breadcrumbs":[{"name":"Start","url":"/","isSelected":true}],"schemaData":null,"ENVIRONMENT":"production","app":{"footerData":{"heading":"Become one of us","preamble":"Wspólnie z naszymi klientami opracowujemy rozwiązania cyfrowe, które ułatwiają ich i nasze codzienne życie. Chcemy, żebyś do nas dołączył! ","infoButton":{"src":"https://www.knowit.pl/","title":"Dołącz do nas!"},"copyright":"© Knowit Poland 2026","footerNavigation":[{"columnText":"Kontakt","columnLink":null,"phoneNumber":null,"emailAddress":null,"contactField":"\u003cp\u003e\u003ca href=\"mailto:[email protected]\"\[email protected]\u003c/a\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eHrubieszowska 2\u0026nbsp;\u003cbr /\u003ePL-01-209 Warszawa\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eKnowit Poland sp. z o.o.\u003c/strong\u003e\u003c/p\u003e\n\u003cp\u003eKRS 0000036076, \u003cbr /\u003eNIP: 9511789996. \u003cbr /\u003eSąd Rejonowy dla m.st. Warszawy w Warszawie, XIII Wydzial Gospodarczy Krajowego Rejestru Sądowego. Kapital zakladowy:\u0026nbsp;\u003cbr /\u003e1 251 200 PLN,\u0026nbsp;siedziba: \u003cbr /\u003eul. Hrubieszowska 2, 01-209 Warszawa\u0026nbsp;\u003c/p\u003e","links":null},{"columnText":"Spółka","columnLink":null,"phoneNumber":null,"emailAddress":null,"contactField":null,"links":[{"url":"https://www.knowit.pl/o-knowit/","title":"O Knowit","target":null,"rel":null,"name":"O Knowit"},{"url":"https://www.knowit.pl/investor-relations/","title":"Informacje Finansowe (EN)","target":"_blank","rel":null,"name":"Informacje Finansowe (EN)"},{"url":"https://www.knowit.pl/kariera/","title":"Kariera","target":null,"rel":null,"name":"Kariera"},{"url":"https://www.knowit.pl/o-knowit/zrownowazony-rozwoj/","title":"Zrównoważony rozwój","target":null,"rel":null,"name":"Zrównoważony rozwój"},{"url":"https://www.knowit.pl/kontakt/","title":"Kontakt","target":null,"rel":null,"name":"Kontakt"}]},{"columnText":"Usługi","columnLink":null,"phoneNumber":null,"emailAddress":null,"contactField":null,"links":[{"url":"https://www.knowit.pl/co-oferujemy/product-i-service-development/","title":"Product i service development","target":null,"rel":null,"name":"Product i service development"},{"url":"https://www.knowit.pl/co-oferujemy/application-management/","title":"Application management","target":null,"rel":null,"name":"Application management"},{"url":"https://www.knowit.pl/co-oferujemy/cloud-data/","title":"Cloud, Data \u0026 AI","target":null,"rel":null,"name":"Cloud, Data \u0026 AI"},{"url":"https://www.knowit.pl/co-oferujemy/web-mobile-i-e-commerce/","title":"Web, Mobile i E-commerce","target":null,"rel":null,"name":"Web, Mobile i E-commerce"},{"url":"https://www.knowit.pl/co-oferujemy/green-house-hub-innowacji/","title":"Green House - Hub Innowacji","target":null,"rel":null,"name":"Green House - Hub Innowacji"},{"url":"https://www.knowit.pl/Projekty/","title":"Nasi klienci","target":null,"rel":null,"name":"Nasi klienci"}]}],"footerLinks":[{"url":"https://www.knowit.pl/misc/polityka-plikow-cookie/","title":"Cookies","target":null,"name":"Cookies","textUnderlineOffset":"5px","textDecoration":"underline"},{"url":"https://www.knowit.pl/misc/prywatnosci/","title":"Obsługa danych osobowych","target":null,"name":"Obsługa danych osobowych","textUnderlineOffset":"5px","textDecoration":"underline"},{"url":"https://knowit.whistlelink.com/","title":null,"target":"_blank","name":"Serwis Wistleblower","textUnderlineOffset":"5px","textDecoration":"underline"}],"socialmediaLinks":[]},"headerData":{"navigation":null,"priorityLinks":[{"url":"https://www.knowit.pl/Projekty/","title":"Projekty","target":"","name":null},{"url":"https://www.knowit.pl/wiadomosci/","title":"Wiadomości","target":"","name":null}],"headerLogo":"https://www.knowit.se/contentassets/048e04e9abca42e0bd83aacf7ed0b338/logotype-knowit-digital-white_large.svg","favicon":"https://www.knowit.se/contentassets/048e04e9abca42e0bd83aacf7ed0b338/knowit_favicon.png"},"megamenu":{"priorityLinks":[{"name":"Co oferujemy","url":"https://www.knowit.pl/co-oferujemy/","secondaryTitle":"Co oferujemy","childPages":[{"name":"Product i service development","url":"https://www.knowit.pl/co-oferujemy/product-i-service-development/","childPages":[{"name":"Embedded, IoT i Connectivity","url":"https://www.knowit.pl/co-oferujemy/product-i-service-development/embedded-iot-i-connectivity/","childPages":null},{"name":"Aplikacje mobilne i webowe","url":"https://www.knowit.pl/co-oferujemy/product-i-service-development/aplikacje-mobilne-i-webowe/","childPages":null}]},{"name":"Application management","url":"https://www.knowit.pl/co-oferujemy/application-management/","childPages":[{"name":"Automatyzacja","url":"https://www.knowit.pl/co-oferujemy/application-management/automatyzacja/","childPages":null},{"name":"Utrzymanie aplikacji","url":"https://www.knowit.pl/co-oferujemy/application-management/utrzymanie-aplikacji/","childPages":null},{"name":"Testowanie","url":"https://www.knowit.pl/co-oferujemy/application-management/testowanie/","childPages":null}]},{"name":"Cloud \u0026 Data","url":"https://www.knowit.pl/co-oferujemy/cloud-data/","childPages":[{"name":"Cloud","url":"https://www.knowit.pl/co-oferujemy/cloud-data/cloud/","childPages":null},{"name":"Data","url":"https://www.knowit.pl/co-oferujemy/cloud-data/data/","childPages":null}]},{"name":"Web, Mobile i E-commerce","url":"https://www.knowit.pl/co-oferujemy/web-mobile-i-e-commerce/","childPages":null},{"name":"Green House - Hub Innowacji","url":"https://www.knowit.pl/co-oferujemy/green-house-hub-innowacji/","childPages":[{"name":"Digitalization Strategy","url":"https://www.knowit.pl/co-oferujemy/green-house-hub-innowacji/digitalization-strategy/","childPages":null},{"name":"Discovery","url":"https://www.knowit.pl/co-oferujemy/green-house-hub-innowacji/discovery/","childPages":null},{"name":"PoC","url":"https://www.knowit.pl/co-oferujemy/green-house-hub-innowacji/poc/","childPages":null}]},{"name":"Modele współpracy","url":"https://www.knowit.pl/co-oferujemy/modele-wspolpracy/","childPages":null},{"name":"AI","url":"https://www.knowit.pl/co-oferujemy/ai/","childPages":[{"name":"Ragit wirtualny asystent AI","url":"https://www.knowit.pl/co-oferujemy/ai/ragit-wirtualny-asystent-ai/","childPages":null}]}]},{"name":"Projekty","url":"https://www.knowit.pl/Projekty/","secondaryTitle":null,"childPages":null},{"name":"Kariera","url":"https://www.knowit.pl/kariera/","secondaryTitle":null,"childPages":null}],"secondaryLinks":[{"name":"O Knowit","url":"https://www.knowit.pl/o-knowit/"},{"name":"Wiadomości","url":"https://www.knowit.pl/wiadomosci/"},{"name":"Kontakt","url":"https://www.knowit.pl/kontakt/"},{"name":"Blog","url":"https://blog.knowit.eu/"}],"countrySelectionLinks":[{"url":"https://www.knowit.de/","title":"DE - Deutschland","target":"_self","rel":null,"name":"DE - Deutschland"},{"url":"https://www.knowit.dk/","title":"DK - Denmark","target":"_self","rel":null,"name":"DK - Denmark"},{"url":"https://www.knowit.eu/","title":"EU - Global","target":"_self","rel":null,"name":"EU - Global"},{"url":"https://www.knowit.fi/","title":"FI - Suomi","target":"_self","rel":null,"name":"FI - Suomi"},{"url":"https://www.knowit.no/","title":"NO - Norge","target":"_self","rel":null,"name":"NO - Norge"},{"url":"https://www.knowit.pl/","title":"PL - Polska","target":"_self","rel":null,"name":"PL - Polska"},{"url":"https://www.knowit.se/","title":"SE - Sverige","target":"_self","rel":null,"name":"SE - Sverige"}],"quickLinks":[],"openMegaMenuText":"Menu","closeMegaMenuText":"Zamknij","countrySelectionMegaMenuText":"Kraj","backButtonText":"Z powrotem"},"generalTexts":{"relatedLinksText":"Powiązane linki","skipNavigationText":"Przejdź do głównej zawartości","ariaLabelText":"Do strony głównej Knowit"},"llmRichText":null,"searchSettings":{"searchLink":{"url":"https://www.knowit.pl/szukaj/","title":"Szukaj"},"noResultsTextSearchPage":"Wyszukiwanie nie przyniosło żadnych wyników","searchLabel":"Szukaj","
1457srCloseLabel":"Zamknij","placeholderText":"Przeszukaj knowit.pl","resultText":"Wyniki","batchText":"Załaduj więcej"},"IMAGE_URL":"https://www.knowit.pl","IMAGE_HOST":"https://kest01mstrc9jb4prod.dxcloud.episerver.net","locale":"pl","isStartPage":true,"host":"https://www.knowit.pl","instrumentationKey":"a7755278-880f-41e9-a09d-f91442e32100"},"locale":"pl","host":"https://www.knowit.pl"},"__N_SSP":true},"page":"/[[...slug]]","query":{},"buildId":"azM-6MnyJRFJ_7YqFlWAP","isFallback":false,"isExperimentalCompile":false,"dynamicIds":[3848],"gssp":true,"scriptLoader":[{"id":"gtm-script","strategy":"afterInteractive","dangerouslySetInnerHTML":{"__html":"\n            (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':\n            new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],\n            j=d.createElement(s),dl=l!='dataLayer'?'\u0026l='+l:'';j.async=true;j.src=\n            'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);\n            })(window,document,'script','dataLayer','GTM-K4HQP95');\n            "}}]}</script>
1457</body></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.