[{"data":1,"prerenderedAt":2654},["ShallowReactive",2],{"i-lucide:chevron-down":3,"i-lucide:search":8,"i-lucide:sun":10,"i-lucide:moon":12,"i-lucide:arrow-right":14,"i-lucide:menu":16,"i-lucide:mail":18,"i-simple-icons:x":20,"i-simple-icons:linkedin":22,"i-simple-icons:dribbble":25,"i-simple-icons:github":27,"blog-\u002Fblog\u002Fbn\u002Fevent-loop-settimeout-zero":29,"blog-related-\u002Fblog\u002Fbn\u002Fevent-loop-settimeout-zero":814,"i-lucide:chevron-right":2640,"i-lucide:calendar":2642,"i-lucide:clock":2644,"i-lucide:link":2646,"i-lucide:type":2648,"i-lucide:component":2650,"i-lucide:briefcase":2652},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,24,false,"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m6 9l6 6l6-6\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":9},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m21 21l-4.34-4.34\"\u002F>\u003Ccircle cx=\"11\" cy=\"11\" r=\"8\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":11},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"4\"\u002F>\u003Cpath d=\"M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32l1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":13},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":15},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 12h14m-7-7l7 7l-7 7\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":17},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 5h16M4 12h16M4 19h16\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":19},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m22 7l-8.991 5.727a2 2 0 0 1-2.009 0L2 7\"\u002F>\u003Crect width=\"20\" height=\"16\" x=\"2\" y=\"4\" rx=\"2\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":21},"\u003Cpath fill=\"currentColor\" d=\"M14.234 10.162L22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299l-.929-1.329L3.076 1.56h3.182l5.965 8.532l.929 1.329l7.754 11.09h-3.182z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":23,"hidden":24},"\u003Cpath fill=\"currentColor\" d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037c-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85c3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.06 2.06 0 0 1-2.063-2.065a2.064 2.064 0 1 1 2.063 2.065m1.782 13.019H3.555V9h3.564zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0z\"\u002F>",true,{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":26},"\u003Cpath fill=\"currentColor\" d=\"M12 24C5.385 24 0 18.615 0 12S5.385 0 12 0s12 5.385 12 12s-5.385 12-12 12m10.12-10.358c-.35-.11-3.17-.953-6.384-.438c1.34 3.684 1.887 6.684 1.992 7.308a10.28 10.28 0 0 0 4.395-6.87zm-6.115 7.808c-.153-.9-.75-4.032-2.19-7.77l-.066.02c-5.79 2.015-7.86 6.025-8.04 6.4a10.16 10.16 0 0 0 6.29 2.166c1.42 0 2.77-.29 4-.814zm-11.62-2.58c.232-.4 3.045-5.055 8.332-6.765q.202-.067.405-.12q-.392-.879-.832-1.74C7.17 11.775 2.206 11.71 1.756 11.7l-.004.312c0 2.633.998 5.037 2.634 6.855zm-2.42-8.955c.46.008 4.683.026 9.477-1.248a66 66 0 0 0-3.8-5.928a10.28 10.28 0 0 0-5.676 7.17zM9.6 2.052c.282.38 2.145 2.914 3.822 6c3.645-1.365 5.19-3.44 5.373-3.702A10.2 10.2 0 0 0 12 1.764c-.825 0-1.63.1-2.4.285zm10.335 3.483c-.218.29-1.935 2.493-5.724 4.04c.24.49.47.985.68 1.486c.08.18.15.36.22.53c3.41-.43 6.8.26 7.14.33c-.02-2.42-.88-4.64-2.31-6.38z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":28},"\u003Cpath fill=\"currentColor\" d=\"M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"\u002F>",{"id":30,"title":31,"author":32,"body":35,"category":799,"cover":800,"coverAlt":31,"date":801,"description":802,"draft":6,"extension":803,"featured":6,"lang":804,"meta":805,"navigation":24,"path":806,"readingTime":159,"seo":807,"stem":808,"tags":809,"__hash__":813},"blog\u002Fblog\u002Fbn\u002Fevent-loop-settimeout-zero.md","setTimeout(fn, 0) সাথে সাথে চলে না কেন",{"name":33,"role":34},"নাফিস রহমান","ডিজাইন সিস্টেম লিড",{"type":36,"value":37,"toc":791},"minimark",[38,42,171,181,184,189,192,208,211,260,263,267,270,275,307,313,335,338,348,359,363,370,418,425,431,469,472,476,485,575,589,594,598,601,609,612,618,751,763,767,777,787],[39,40,41],"p",{},"এই কোডটার আউটপুট কী হবে?",[43,44,49],"pre",{"className":45,"code":46,"language":47,"meta":48,"style":48},"language-js shiki shiki-themes github-dark-dimmed github-dark-dimmed","console.log('১')\n\nsetTimeout(() => console.log('২'), 0)\n\nPromise.resolve().then(() => console.log('৩'))\n\nconsole.log('৪')\n","js","",[50,51,52,75,81,113,118,152,157],"code",{"__ignoreMap":48},[53,54,57,61,65,68,72],"span",{"class":55,"line":56},"line",1,[53,58,60],{"class":59},"sM9_K","console.",[53,62,64],{"class":63},"s-wk_","log",[53,66,67],{"class":59},"(",[53,69,71],{"class":70},"szYpP","'১'",[53,73,74],{"class":59},")\n",[53,76,78],{"class":55,"line":77},2,[53,79,80],{"emptyLinePlaceholder":24},"\n",[53,82,84,87,90,94,97,99,101,104,107,111],{"class":55,"line":83},3,[53,85,86],{"class":63},"setTimeout",[53,88,89],{"class":59},"(() ",[53,91,93],{"class":92},"sEYkB","=>",[53,95,96],{"class":59}," console.",[53,98,64],{"class":63},[53,100,67],{"class":59},[53,102,103],{"class":70},"'২'",[53,105,106],{"class":59},"), ",[53,108,110],{"class":109},"sQdni","0",[53,112,74],{"class":59},[53,114,116],{"class":55,"line":115},4,[53,117,80],{"emptyLinePlaceholder":24},[53,119,121,124,127,130,133,136,138,140,142,144,146,149],{"class":55,"line":120},5,[53,122,123],{"class":109},"Promise",[53,125,126],{"class":59},".",[53,128,129],{"class":63},"resolve",[53,131,132],{"class":59},"().",[53,134,135],{"class":63},"then",[53,137,89],{"class":59},[53,139,93],{"class":92},[53,141,96],{"class":59},[53,143,64],{"class":63},[53,145,67],{"class":59},[53,147,148],{"class":70},"'৩'",[53,150,151],{"class":59},"))\n",[53,153,155],{"class":55,"line":154},6,[53,156,80],{"emptyLinePlaceholder":24},[53,158,160,162,164,166,169],{"class":55,"line":159},7,[53,161,60],{"class":59},[53,163,64],{"class":63},[53,165,67],{"class":59},[53,167,168],{"class":70},"'৪'",[53,170,74],{"class":59},[39,172,173,174,177,178,180],{},"উত্তর ",[50,175,176],{},"১ ৪ ৩ ২","। ",[50,179,86],{},"-এ ০ মিলিসেকেন্ড দেওয়া সত্ত্বেও সেটা সবার শেষে চলে, এমনকি এমন একটা প্রমিসের পরেও যেটা তার পরে লেখা হয়েছে।",[39,182,183],{},"\"০ মানে এখনই নয়\" — এইটুকু মনে রাখলে কাজ চলে যায়, কিন্তু কেন নয় সেটা জানলে আর মুখস্থ করতে হয় না।",[185,186,188],"h2",{"id":187},"কল-স্ট্যাক-আগে-শেষ-হয়","কল স্ট্যাক আগে শেষ হয়",[39,190,191],{},"জাভাস্ক্রিপ্ট সিঙ্গল-থ্রেডেড। যেকোনো মুহূর্তে একটাই জিনিস চলে, আর সেটা কল স্ট্যাকের উপরের ফাংশনটা।",[39,193,194,195,199,200,203,204,207],{},"ইভেন্ট লুপ কোনো কিছু তুলে নেওয়ার আগে ",[196,197,198],"strong",{},"স্ট্যাক পুরো খালি হওয়া লাগে","। তাই উপরের কোডে ",[50,201,202],{},"console.log('১')"," আর ",[50,205,206],{},"console.log('৪')"," — যেগুলো সিঙ্ক্রোনাস — আগে চলবেই। বাকি সবকিছু সারিতে অপেক্ষা করে।",[39,209,210],{},"এখান থেকেই সবচেয়ে সাধারণ বাগটা আসে:",[43,212,214],{"className":45,"code":213,"language":47,"meta":48,"style":48},"\u002F\u002F ব্রাউজার এই পুরো লুপটা শেষ না হওয়া পর্যন্ত জমে থাকে\nfor (let i = 0; i \u003C 1e9; i++) {}\n",[50,215,216,222],{"__ignoreMap":48},[53,217,218],{"class":55,"line":56},[53,219,221],{"class":220},"s0RzX","\u002F\u002F ব্রাউজার এই পুরো লুপটা শেষ না হওয়া পর্যন্ত জমে থাকে\n",[53,223,224,227,230,233,236,239,242,245,248,251,254,257],{"class":55,"line":77},[53,225,226],{"class":92},"for",[53,228,229],{"class":59}," (",[53,231,232],{"class":92},"let",[53,234,235],{"class":59}," i ",[53,237,238],{"class":92},"=",[53,240,241],{"class":109}," 0",[53,243,244],{"class":59},"; i ",[53,246,247],{"class":92},"\u003C",[53,249,250],{"class":109}," 1e9",[53,252,253],{"class":59},"; i",[53,255,256],{"class":92},"++",[53,258,259],{"class":59},") {}\n",[39,261,262],{},"স্ট্যাক খালি না হলে ইভেন্ট লুপ কিছুই করতে পারে না — ক্লিক হ্যান্ডলার চলবে না, রেন্ডারও হবে না। \"পেজ হ্যাং করে আছে\" মানে বেশিরভাগ সময় \"স্ট্যাক খালি হচ্ছে না\"।",[185,264,266],{"id":265},"দুইটা-আলাদা-সারি","দুইটা আলাদা সারি",[39,268,269],{},"স্ট্যাক খালি হলে ইভেন্ট লুপ যা দেখে, তা একটা সারি নয় — দুইটা, আর তাদের অগ্রাধিকার আলাদা।",[39,271,272],{},[196,273,274],{},"মাইক্রোটাস্ক সারি",[276,277,278,291,297,302],"ul",{},[279,280,281,284,285,284,288],"li",{},[50,282,283],{},"Promise.then"," \u002F ",[50,286,287],{},".catch",[50,289,290],{},".finally",[279,292,293,296],{},[50,294,295],{},"await","-এর পরের অংশ",[279,298,299],{},[50,300,301],{},"queueMicrotask",[279,303,304],{},[50,305,306],{},"MutationObserver",[39,308,309,312],{},[196,310,311],{},"ম্যাক্রোটাস্ক সারি"," (স্পেকে \"টাস্ক\")",[276,314,315,323,326,329],{},[279,316,317,319,320],{},[50,318,86],{},", ",[50,321,322],{},"setInterval",[279,324,325],{},"DOM ইভেন্ট (click, input)",[279,327,328],{},"নেটওয়ার্ক কলব্যাক",[279,330,331,334],{},[50,332,333],{},"requestAnimationFrame"," (আলাদা ধাপে, রেন্ডারের আগে)",[39,336,337],{},"নিয়মটা এক লাইনে:",[339,340,341],"blockquote",{},[39,342,343,344,347],{},"প্রতিটা ম্যাক্রোটাস্কের পর, ",[196,345,346],{},"পুরো"," মাইক্রোটাস্ক সারি খালি করা হয় — তারপর পরের ম্যাক্রোটাস্ক।",[39,349,350,351,354,355,358],{},"তাই ",[50,352,353],{},"৩"," (প্রমিস, মাইক্রোটাস্ক) ",[50,356,357],{},"২","-এর (টাইমআউট, ম্যাক্রোটাস্ক) আগে চলে। ০ মিলিসেকেন্ড লেখা থাকলেও সেটা অন্য সারিতে, আর ওই সারির পালা পরে।",[185,360,362],{"id":361},"পুরো-শব্দটা-গুরুত্বপূর্ণ","\"পুরো\" শব্দটা গুরুত্বপূর্ণ",[39,364,365,366,369],{},"মাইক্রোটাস্ক সারি খালি করার সময় নতুন মাইক্রোটাস্ক যোগ হলে সেগুলোও ",[196,367,368],{},"একই দফায়"," চলে। এটা সুবিধা, আবার ফাঁদও:",[43,371,373],{"className":45,"code":372,"language":47,"meta":48,"style":48},"function loop() {\n  Promise.resolve().then(loop)\n}\nloop() \u002F\u002F পেজ জমে যায়\n",[50,374,375,386,402,407],{"__ignoreMap":48},[53,376,377,380,383],{"class":55,"line":56},[53,378,379],{"class":92},"function",[53,381,382],{"class":63}," loop",[53,384,385],{"class":59},"() {\n",[53,387,388,391,393,395,397,399],{"class":55,"line":77},[53,389,390],{"class":109},"  Promise",[53,392,126],{"class":59},[53,394,129],{"class":63},[53,396,132],{"class":59},[53,398,135],{"class":63},[53,400,401],{"class":59},"(loop)\n",[53,403,404],{"class":55,"line":83},[53,405,406],{"class":59},"}\n",[53,408,409,412,415],{"class":55,"line":115},[53,410,411],{"class":63},"loop",[53,413,414],{"class":59},"() ",[53,416,417],{"class":220},"\u002F\u002F পেজ জমে যায়\n",[39,419,420,421,424],{},"এখানে কোনো ইনফিনিট ",[50,422,423],{},"while"," নেই, তবু ব্রাউজার আর কিছু করতে পারে না — সারিটা কখনো খালি হয় না, তাই লুপ কখনো পরের ধাপে যায় না।",[39,426,427,428,430],{},"একই কোড ",[50,429,86],{}," দিয়ে লিখলে পেজ সচল থাকে:",[43,432,434],{"className":45,"code":433,"language":47,"meta":48,"style":48},"function loop() {\n  setTimeout(loop, 0)\n}\nloop() \u002F\u002F চলতেই থাকে, কিন্তু পেজ ব্যবহারযোগ্য\n",[50,435,436,444,456,460],{"__ignoreMap":48},[53,437,438,440,442],{"class":55,"line":56},[53,439,379],{"class":92},[53,441,382],{"class":63},[53,443,385],{"class":59},[53,445,446,449,452,454],{"class":55,"line":77},[53,447,448],{"class":63},"  setTimeout",[53,450,451],{"class":59},"(loop, ",[53,453,110],{"class":109},[53,455,74],{"class":59},[53,457,458],{"class":55,"line":83},[53,459,406],{"class":59},[53,461,462,464,466],{"class":55,"line":115},[53,463,411],{"class":63},[53,465,414],{"class":59},[53,467,468],{"class":220},"\u002F\u002F চলতেই থাকে, কিন্তু পেজ ব্যবহারযোগ্য\n",[39,470,471],{},"কারণ প্রতিটা ম্যাক্রোটাস্কের মাঝে ব্রাউজার রেন্ডার করার সুযোগ পায়।",[185,473,475],{"id":474},"await-আসলে-কী","await আসলে কী",[39,477,478,480,481,484],{},[50,479,295],{}," নতুন কিছু নয় — এটা ",[50,482,483],{},".then","-এর সিনট্যাক্স।",[43,486,488],{"className":45,"code":487,"language":47,"meta":48,"style":48},"async function run() {\n  console.log('ক')\n  await null \u002F\u002F ← এখানেই ফাংশনটা থামে\n  console.log('খ') \u002F\u002F ← এই অংশটা মাইক্রোটাস্ক\n}\n\nrun()\nconsole.log('গ')\n",[50,489,490,503,517,528,545,549,553,561],{"__ignoreMap":48},[53,491,492,495,498,501],{"class":55,"line":56},[53,493,494],{"class":92},"async",[53,496,497],{"class":92}," function",[53,499,500],{"class":63}," run",[53,502,385],{"class":59},[53,504,505,508,510,512,515],{"class":55,"line":77},[53,506,507],{"class":59},"  console.",[53,509,64],{"class":63},[53,511,67],{"class":59},[53,513,514],{"class":70},"'ক'",[53,516,74],{"class":59},[53,518,519,522,525],{"class":55,"line":83},[53,520,521],{"class":92},"  await",[53,523,524],{"class":109}," null",[53,526,527],{"class":220}," \u002F\u002F ← এখানেই ফাংশনটা থামে\n",[53,529,530,532,534,536,539,542],{"class":55,"line":115},[53,531,507],{"class":59},[53,533,64],{"class":63},[53,535,67],{"class":59},[53,537,538],{"class":70},"'খ'",[53,540,541],{"class":59},") ",[53,543,544],{"class":220},"\u002F\u002F ← এই অংশটা মাইক্রোটাস্ক\n",[53,546,547],{"class":55,"line":120},[53,548,406],{"class":59},[53,550,551],{"class":55,"line":154},[53,552,80],{"emptyLinePlaceholder":24},[53,554,555,558],{"class":55,"line":159},[53,556,557],{"class":63},"run",[53,559,560],{"class":59},"()\n",[53,562,564,566,568,570,573],{"class":55,"line":563},8,[53,565,60],{"class":59},[53,567,64],{"class":63},[53,569,67],{"class":59},[53,571,572],{"class":70},"'গ'",[53,574,74],{"class":59},[39,576,577,578,177,581,584,585,588],{},"আউটপুট ",[50,579,580],{},"ক গ খ",[50,582,583],{},"await null"," — যেখানে অপেক্ষা করার মতো কিছুই নেই — তবু ফাংশনটা থামে, বাকিটা মাইক্রোটাস্ক হিসেবে সারিতে যায়, আর ",[50,586,587],{},"গ"," আগে চলে।",[39,590,350,591,593],{},[50,592,295],{},"-এর পরের প্রতিটা লাইন কার্যত একটা কলব্যাকের ভেতরে। সিরিয়ালি লেখা যায় বলে এটা ভুলে যাওয়া সহজ।",[185,595,597],{"id":596},"রেন্ডারিং-কোথায়","রেন্ডারিং কোথায়",[39,599,600],{},"ব্রাউজার সাধারণত প্রতি ফ্রেমে একবার রেন্ডার করে — মোটামুটি ১৬.৭ms পরপর, ৬০Hz-এ। ধাপটা এরকম:",[43,602,607],{"className":603,"code":605,"language":606},[604],"language-text","ম্যাক্রোটাস্ক → মাইক্রোটাস্ক (সব) → rAF কলব্যাক → স্টাইল → লেআউট → পেইন্ট\n","text",[50,608,605],{"__ignoreMap":48},[39,610,611],{},"দুইটা ব্যবহারিক ফল:",[39,613,614,617],{},[196,615,616],{},"এক"," — একই টিকে DOM বদলে আবার পড়লে ব্রাউজার জোর করে লেআউট হিসাব করে (layout thrashing):",[43,619,621],{"className":45,"code":620,"language":47,"meta":48,"style":48},"\u002F\u002F খারাপ — প্রতি ধাপে জোর করে reflow\nfor (const el of items) {\n  el.style.height = el.offsetHeight + 10 + 'px'\n}\n\n\u002F\u002F ভালো — আগে সব পড়ুন, তারপর সব লিখুন\nconst heights = items.map((el) => el.offsetHeight)\nitems.forEach((el, i) => (el.style.height = heights[i] + 10 + 'px'))\n",[50,622,623,628,646,668,672,676,681,711],{"__ignoreMap":48},[53,624,625],{"class":55,"line":56},[53,626,627],{"class":220},"\u002F\u002F খারাপ — প্রতি ধাপে জোর করে reflow\n",[53,629,630,632,634,637,640,643],{"class":55,"line":77},[53,631,226],{"class":92},[53,633,229],{"class":59},[53,635,636],{"class":92},"const",[53,638,639],{"class":109}," el",[53,641,642],{"class":92}," of",[53,644,645],{"class":59}," items) {\n",[53,647,648,651,653,656,659,662,665],{"class":55,"line":83},[53,649,650],{"class":59},"  el.style.height ",[53,652,238],{"class":92},[53,654,655],{"class":59}," el.offsetHeight ",[53,657,658],{"class":92},"+",[53,660,661],{"class":109}," 10",[53,663,664],{"class":92}," +",[53,666,667],{"class":70}," 'px'\n",[53,669,670],{"class":55,"line":115},[53,671,406],{"class":59},[53,673,674],{"class":55,"line":120},[53,675,80],{"emptyLinePlaceholder":24},[53,677,678],{"class":55,"line":154},[53,679,680],{"class":220},"\u002F\u002F ভালো — আগে সব পড়ুন, তারপর সব লিখুন\n",[53,682,683,685,688,691,694,697,700,704,706,708],{"class":55,"line":159},[53,684,636],{"class":92},[53,686,687],{"class":109}," heights",[53,689,690],{"class":92}," =",[53,692,693],{"class":59}," items.",[53,695,696],{"class":63},"map",[53,698,699],{"class":59},"((",[53,701,703],{"class":702},"siJwO","el",[53,705,541],{"class":59},[53,707,93],{"class":92},[53,709,710],{"class":59}," el.offsetHeight)\n",[53,712,713,716,719,721,723,725,728,730,732,735,737,740,742,744,746,749],{"class":55,"line":563},[53,714,715],{"class":59},"items.",[53,717,718],{"class":63},"forEach",[53,720,699],{"class":59},[53,722,703],{"class":702},[53,724,319],{"class":59},[53,726,727],{"class":702},"i",[53,729,541],{"class":59},[53,731,93],{"class":92},[53,733,734],{"class":59}," (el.style.height ",[53,736,238],{"class":92},[53,738,739],{"class":59}," heights[i] ",[53,741,658],{"class":92},[53,743,661],{"class":109},[53,745,664],{"class":92},[53,747,748],{"class":70}," 'px'",[53,750,151],{"class":59},[39,752,753,756,757,759,760,762],{},[196,754,755],{},"দুই"," — অ্যানিমেশন ",[50,758,86],{}," দিয়ে নয়, ",[50,761,333],{}," দিয়ে। rAF রেন্ডার ধাপের ঠিক আগে চলে, তাই ফ্রেম মিস হয় না।",[185,764,766],{"id":765},"০-আসলে-০-নয়","০ আসলে ০ নয়",[39,768,769,770,772,773,776],{},"শেষ একটা খুঁটিনাটি: HTML স্পেক অনুযায়ী নেস্টেড ",[50,771,86],{}," পাঁচ স্তরের পর সর্বনিম্ন ",[196,774,775],{},"৪ মিলিসেকেন্ড"," ক্ল্যাম্প হয়। ব্যাকগ্রাউন্ড ট্যাবে ব্রাউজার এটা আরও বাড়িয়ে ১০০০ms-ও করে দিতে পারে।",[39,778,779,780,783,784,786],{},"অর্থাৎ ",[50,781,782],{},"setTimeout(fn, 0)"," মানে \"যত দ্রুত সম্ভব\" নয়, মানে \"পরের টাস্ক হিসেবে, সুবিধামতো\"। এখনই দরকার হলে ",[50,785,301],{}," আছে — কিন্তু তাতে ব্রাউজার রেন্ডার করার সুযোগ পায় না, যেটা প্রায়ই আপনি চাইছিলেন।",[788,789,790],"style",{},"html pre.shiki code .sM9_K, html code.shiki .sM9_K{--shiki-default:#ADBAC7;--shiki-dark:#ADBAC7}html pre.shiki code .s-wk_, html code.shiki .s-wk_{--shiki-default:#DCBDFB;--shiki-dark:#DCBDFB}html pre.shiki code .szYpP, html code.shiki .szYpP{--shiki-default:#96D0FF;--shiki-dark:#96D0FF}html pre.shiki code .sEYkB, html code.shiki .sEYkB{--shiki-default:#F47067;--shiki-dark:#F47067}html pre.shiki code .sQdni, html code.shiki .sQdni{--shiki-default:#6CB6FF;--shiki-dark:#6CB6FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s0RzX, html code.shiki .s0RzX{--shiki-default:#768390;--shiki-dark:#768390}html pre.shiki code .siJwO, html code.shiki .siJwO{--shiki-default:#F69D50;--shiki-dark:#F69D50}",{"title":48,"searchDepth":83,"depth":83,"links":792},[793,794,795,796,797,798],{"id":187,"depth":77,"text":188},{"id":265,"depth":77,"text":266},{"id":361,"depth":77,"text":362},{"id":474,"depth":77,"text":475},{"id":596,"depth":77,"text":597},{"id":765,"depth":77,"text":766},"web-development","\u002Fcovers\u002Fblog\u002Fbn\u002Fevent-loop-settimeout-zero.webp","2026-06-11","ম্যাক্রোটাস্ক, মাইক্রোটাস্ক আর রেন্ডারিং — ইভেন্ট লুপের ধাপগুলো জানলে অ্যাসিঙ্ক কোডের ক্রম আর অনুমান করতে হয় না।","md","bn",{},"\u002Fblog\u002Fbn\u002Fevent-loop-settimeout-zero",{"title":31,"description":802},"blog\u002Fbn\u002Fevent-loop-settimeout-zero",[810,811,812],"JavaScript","ইভেন্ট লুপ","অ্যাসিঙ্ক","H5TYNXXsO4KpEMqYBcmOopomo78ZO1gTGVkxRro95nQ",[815,1779,2470],{"id":816,"title":817,"author":818,"body":821,"category":1766,"cover":1767,"coverAlt":817,"date":1768,"description":1769,"draft":6,"extension":803,"featured":24,"lang":804,"meta":1770,"navigation":24,"path":1771,"readingTime":987,"seo":1772,"stem":1773,"tags":1774,"__hash__":1778},"blog\u002Fblog\u002Fbn\u002Fbangla-typography-on-the-web.md","ওয়েবে বাংলা টাইপোগ্রাফি — যে সমস্যাগুলো নিয়ে কেউ লেখে না",{"name":819,"role":820},"তাসনিম আরা","প্রোডাক্ট ডিজাইনার",{"type":36,"value":822,"toc":1756},[823,826,829,833,836,880,887,1005,1012,1017,1020,1064,1067,1070,1129,1132,1136,1139,1146,1197,1204,1211,1214,1312,1319,1323,1330,1341,1411,1414,1418,1421,1459,1467,1471,1474,1477,1511,1514,1521,1699,1702,1706,1713,1742,1753],[39,824,825],{},"একটা ডিজাইন সিস্টেম ল্যাটিন স্ক্রিপ্টের জন্য বানানো হলে সেটা বাংলায় ভাঙে — কিন্তু এমনভাবে ভাঙে যে প্রথম দেখায় বোঝা যায় না। পেজ লোড হয়, লেখা পড়া যায়, কিছু একটা \"ঠিক লাগছে না\" — এইটুকুই।",[39,827,828],{},"এই সাইটে বাংলা ট্র্যাক যোগ করতে গিয়ে যে পাঁচটা জিনিস আলাদা করে ঠিক করতে হয়েছিল, সেগুলোই এখানে। প্রতিটার কারণ স্ক্রিপ্টের গঠনে, রুচিতে নয়।",[185,830,832],{"id":831},"১-ফন্টে-গ্লিফই-নেই","১. ফন্টে গ্লিফই নেই",[39,834,835],{},"সবচেয়ে বড় সমস্যাটা সবচেয়ে সহজ। Inter, Geist, Satoshi — এদের কারও মধ্যে বাংলা গ্লিফ নেই। বাংলা লেখা এই ফন্টে রেন্ডার করতে দিলে ব্রাউজার fallback খোঁজে, আর সেটা যা পায় তা-ই দেখায়: সিস্টেম ফন্ট, বা টোফু বক্স।",[43,837,841],{"className":838,"code":839,"language":840,"meta":48,"style":48},"language-css shiki shiki-themes github-dark-dimmed github-dark-dimmed","\u002F* যথেষ্ট নয় *\u002F\nbody {\n  font-family: 'Inter', sans-serif;\n}\n","css",[50,842,843,848,857,876],{"__ignoreMap":48},[53,844,845],{"class":55,"line":56},[53,846,847],{"class":220},"\u002F* যথেষ্ট নয় *\u002F\n",[53,849,850,854],{"class":55,"line":77},[53,851,853],{"class":852},"sza-u","body",[53,855,856],{"class":59}," {\n",[53,858,859,862,865,868,870,873],{"class":55,"line":83},[53,860,861],{"class":109},"  font-family",[53,863,864],{"class":59},": ",[53,866,867],{"class":70},"'Inter'",[53,869,319],{"class":59},[53,871,872],{"class":109},"sans-serif",[53,874,875],{"class":59},";\n",[53,877,878],{"class":55,"line":115},[53,879,406],{"class":59},[39,881,882,883,886],{},"বাংলার জন্য আলাদা ফন্ট লাগবেই, আর সেটা ",[50,884,885],{},"subset"," ধরে আনতে হবে:",[43,888,892],{"className":889,"code":890,"language":891,"meta":48,"style":48},"language-ts shiki shiki-themes github-dark-dimmed github-dark-dimmed","fonts: {\n  defaults: { subsets: ['latin'] },\n  families: [\n    { name: 'Inter', provider: 'google' },\n    {\n      name: 'Noto Sans Bengali',\n      provider: 'google',\n      subsets: ['bengali'], \u002F\u002F গ্লোবাল ডিফল্ট latin — এখানে override না করলে\n    },                       \u002F\u002F যে ফাইলটা আসবে তাতে একটাও দরকারি গ্লিফ নেই\n  ],\n}\n","ts",[50,893,894,902,922,930,946,951,962,971,985,994,1000],{"__ignoreMap":48},[53,895,896,899],{"class":55,"line":56},[53,897,898],{"class":702},"fonts",[53,900,901],{"class":59},": {\n",[53,903,904,907,910,913,916,919],{"class":55,"line":77},[53,905,906],{"class":702},"  defaults",[53,908,909],{"class":59},": { ",[53,911,912],{"class":702},"subsets",[53,914,915],{"class":59},": [",[53,917,918],{"class":70},"'latin'",[53,920,921],{"class":59},"] },\n",[53,923,924,927],{"class":55,"line":83},[53,925,926],{"class":702},"  families",[53,928,929],{"class":59},": [\n",[53,931,932,935,937,940,943],{"class":55,"line":115},[53,933,934],{"class":59},"    { name: ",[53,936,867],{"class":70},[53,938,939],{"class":59},", provider: ",[53,941,942],{"class":70},"'google'",[53,944,945],{"class":59}," },\n",[53,947,948],{"class":55,"line":120},[53,949,950],{"class":59},"    {\n",[53,952,953,956,959],{"class":55,"line":154},[53,954,955],{"class":59},"      name: ",[53,957,958],{"class":70},"'Noto Sans Bengali'",[53,960,961],{"class":59},",\n",[53,963,964,967,969],{"class":55,"line":159},[53,965,966],{"class":59},"      provider: ",[53,968,942],{"class":70},[53,970,961],{"class":59},[53,972,973,976,979,982],{"class":55,"line":563},[53,974,975],{"class":59},"      subsets: [",[53,977,978],{"class":70},"'bengali'",[53,980,981],{"class":59},"], ",[53,983,984],{"class":220},"\u002F\u002F গ্লোবাল ডিফল্ট latin — এখানে override না করলে\n",[53,986,988,991],{"class":55,"line":987},9,[53,989,990],{"class":59},"    },                       ",[53,992,993],{"class":220},"\u002F\u002F যে ফাইলটা আসবে তাতে একটাও দরকারি গ্লিফ নেই\n",[53,995,997],{"class":55,"line":996},10,[53,998,999],{"class":59},"  ],\n",[53,1001,1003],{"class":55,"line":1002},11,[53,1004,406],{"class":59},[39,1006,1007,1008,1011],{},"শেষ লাইনটা আসল ফাঁদ। গ্লোবাল ",[50,1009,1010],{},"subsets: ['latin']"," থাকলে Noto Sans Bengali-ও latin subset নিয়ে আসবে — ফাইলটা ডাউনলোড হবে, ওজন যোগ হবে, আর একটা বাংলা অক্ষরও দেখাবে না।",[1013,1014,1016],"h3",{"id":1015},"fallback-এর-ক্রমটাও-ভাবার-বিষয়","fallback-এর ক্রমটাও ভাবার বিষয়",[39,1018,1019],{},"বাংলা পেজে ইংরেজিও থাকে — কোড, প্রোডাক্টের নাম, সংখ্যা। ব্রাউজার প্রতি-গ্লিফ ধরে fallback করে, তাই ক্রম ঠিক করে দিলে দুটোই ঠিক ফন্ট পায়:",[43,1021,1023],{"className":838,"code":1022,"language":840,"meta":48,"style":48},":lang(bn) {\n  font-family: 'Noto Sans Bengali', 'Inter', ui-sans-serif, sans-serif;\n}\n",[50,1024,1025,1037,1060],{"__ignoreMap":48},[53,1026,1027,1030,1032,1034],{"class":55,"line":56},[53,1028,1029],{"class":109},":lang",[53,1031,67],{"class":59},[53,1033,804],{"class":109},[53,1035,1036],{"class":59},") {\n",[53,1038,1039,1041,1043,1045,1047,1049,1051,1054,1056,1058],{"class":55,"line":77},[53,1040,861],{"class":109},[53,1042,864],{"class":59},[53,1044,958],{"class":70},[53,1046,319],{"class":59},[53,1048,867],{"class":70},[53,1050,319],{"class":59},[53,1052,1053],{"class":109},"ui-sans-serif",[53,1055,319],{"class":59},[53,1057,872],{"class":109},[53,1059,875],{"class":59},[53,1061,1062],{"class":55,"line":83},[53,1063,406],{"class":59},[39,1065,1066],{},"Noto আগে, তাই বাংলা Noto পায়। ইংরেজি অক্ষর Noto-র ল্যাটিন সেটে আছে বটে, কিন্তু সেটা দেখতে অন্যরকম — পাতায় আলাদা রঙের মতো লাগে। Inter দ্বিতীয়তে থাকায় ল্যাটিন গ্লিফগুলো Inter-এই পড়ে।",[39,1068,1069],{},"কোড কিন্তু দুই ট্র্যাকেই ল্যাটিন থাকা উচিত:",[43,1071,1073],{"className":838,"code":1072,"language":840,"meta":48,"style":48},":lang(bn) :is(code, pre, kbd, samp) {\n  font-family: var(--font-mono);\n}\n",[50,1074,1075,1108,1125],{"__ignoreMap":48},[53,1076,1077,1079,1081,1083,1085,1088,1090,1092,1094,1096,1098,1101,1103,1106],{"class":55,"line":56},[53,1078,1029],{"class":109},[53,1080,67],{"class":59},[53,1082,804],{"class":109},[53,1084,541],{"class":59},[53,1086,1087],{"class":109},":is",[53,1089,67],{"class":59},[53,1091,50],{"class":852},[53,1093,319],{"class":59},[53,1095,43],{"class":852},[53,1097,319],{"class":59},[53,1099,1100],{"class":852},"kbd",[53,1102,319],{"class":59},[53,1104,1105],{"class":852},"samp",[53,1107,1036],{"class":59},[53,1109,1110,1112,1114,1117,1119,1122],{"class":55,"line":77},[53,1111,861],{"class":109},[53,1113,864],{"class":59},[53,1115,1116],{"class":109},"var",[53,1118,67],{"class":59},[53,1120,1121],{"class":702},"--font-mono",[53,1123,1124],{"class":59},");\n",[53,1126,1127],{"class":55,"line":83},[53,1128,406],{"class":59},[39,1130,1131],{},"একটা shell কমান্ড বাংলা ফন্টে রেন্ডার করার কোনো কারণ নেই, আর কোড ব্লকের লেআউট মনোস্পেসের গ্লিফ-প্রস্থ ধরে বানানো।",[185,1133,1135],{"id":1134},"২-মাত্রা-উপরে-নিচে-জায়গা-চায়","২. মাত্রা উপরে-নিচে জায়গা চায়",[39,1137,1138],{},"এইটা সবচেয়ে কম আলোচিত, আর সবচেয়ে বেশি চোখে লাগে।",[39,1140,1141,1142,1145],{},"বাংলায় কার-চিহ্ন বেসলাইনের উপরে আর নিচে বসে — ি, ী, ু, ূ, ৃ, ে, ৈ, ো, ৌ, রেফ, হসন্ত, যুক্তাক্ষরের নিচের অংশ। ল্যাটিন প্রোজে যে ",[50,1143,1144],{},"line-height: 1.6"," স্বাভাবিক, বাংলায় সেই মাপে পরপর দুই লাইনের চিহ্নগুলো একে অপরকে ছুঁয়ে ফেলে।",[43,1147,1149],{"className":838,"code":1148,"language":840,"meta":48,"style":48},":lang(bn) .ux-prose :is(p, li, blockquote) {\n  line-height: 1.9;\n}\n",[50,1150,1151,1181,1193],{"__ignoreMap":48},[53,1152,1153,1155,1157,1159,1161,1164,1167,1169,1171,1173,1175,1177,1179],{"class":55,"line":56},[53,1154,1029],{"class":109},[53,1156,67],{"class":59},[53,1158,804],{"class":109},[53,1160,541],{"class":59},[53,1162,1163],{"class":109},".ux-prose",[53,1165,1166],{"class":109}," :is",[53,1168,67],{"class":59},[53,1170,39],{"class":852},[53,1172,319],{"class":59},[53,1174,279],{"class":852},[53,1176,319],{"class":59},[53,1178,339],{"class":852},[53,1180,1036],{"class":59},[53,1182,1183,1186,1188,1191],{"class":55,"line":77},[53,1184,1185],{"class":109},"  line-height",[53,1187,864],{"class":59},[53,1189,1190],{"class":109},"1.9",[53,1192,875],{"class":59},[53,1194,1195],{"class":55,"line":83},[53,1196,406],{"class":59},[39,1198,1199,1200,1203],{},"কিন্তু ",[196,1201,1202],{},"সব সাইজে এক মান বসানো ভুল"," — আর এই ভুলটা আমরা করেছিলাম।",[39,1205,1206,1207,1210],{},"প্রথমে লেখা ছিল ",[50,1208,1209],{},":lang(bn) :is(h1, h2, h3) { line-height: 1.45 }","। বডি টেক্সটের মাপে এটা ঠিক। কিন্তু পেজ টাইটেল ক্ল্যাম্প হয়ে ৬৪px-এ যায় — সেখানে ১.৪৫ মানে দুই লাইনের মাঝে ৯৩px ফাঁক। দুই শব্দের একটা হেডিং দেখাচ্ছিল যেন ডাবল-স্পেসড।",[39,1212,1213],{},"টাইপ যত বড়, আনুপাতিক লিডিং তত কম দরকার। একটা fixed multiplier ঠিক উল্টোটা করে। তাই প্রতিটা ধাপে আলাদা:",[43,1215,1217],{"className":838,"code":1216,"language":840,"meta":48,"style":48},":lang(bn) {\n  --text-hero--line-height: 1.16; \u002F* ল্যাটিনের চেয়ে সামান্যই বেশি *\u002F\n  --text-section--line-height: 1.22;\n  --text-title--line-height: 1.35;\n  --text-lg--line-height: 1.75;\n  --text-base--line-height: 1.8; \u002F* পড়ার মাপে উদার *\u002F\n  --text-sm--line-height: 1.65;\n}\n",[50,1218,1219,1229,1245,1257,1269,1281,1296,1308],{"__ignoreMap":48},[53,1220,1221,1223,1225,1227],{"class":55,"line":56},[53,1222,1029],{"class":109},[53,1224,67],{"class":59},[53,1226,804],{"class":109},[53,1228,1036],{"class":59},[53,1230,1231,1234,1236,1239,1242],{"class":55,"line":77},[53,1232,1233],{"class":702},"  --text-hero--line-height",[53,1235,864],{"class":59},[53,1237,1238],{"class":109},"1.16",[53,1240,1241],{"class":59},"; ",[53,1243,1244],{"class":220},"\u002F* ল্যাটিনের চেয়ে সামান্যই বেশি *\u002F\n",[53,1246,1247,1250,1252,1255],{"class":55,"line":83},[53,1248,1249],{"class":702},"  --text-section--line-height",[53,1251,864],{"class":59},[53,1253,1254],{"class":109},"1.22",[53,1256,875],{"class":59},[53,1258,1259,1262,1264,1267],{"class":55,"line":115},[53,1260,1261],{"class":702},"  --text-title--line-height",[53,1263,864],{"class":59},[53,1265,1266],{"class":109},"1.35",[53,1268,875],{"class":59},[53,1270,1271,1274,1276,1279],{"class":55,"line":120},[53,1272,1273],{"class":702},"  --text-lg--line-height",[53,1275,864],{"class":59},[53,1277,1278],{"class":109},"1.75",[53,1280,875],{"class":59},[53,1282,1283,1286,1288,1291,1293],{"class":55,"line":154},[53,1284,1285],{"class":702},"  --text-base--line-height",[53,1287,864],{"class":59},[53,1289,1290],{"class":109},"1.8",[53,1292,1241],{"class":59},[53,1294,1295],{"class":220},"\u002F* পড়ার মাপে উদার *\u002F\n",[53,1297,1298,1301,1303,1306],{"class":55,"line":159},[53,1299,1300],{"class":702},"  --text-sm--line-height",[53,1302,864],{"class":59},[53,1304,1305],{"class":109},"1.65",[53,1307,875],{"class":59},[53,1309,1310],{"class":55,"line":563},[53,1311,406],{"class":59},[39,1313,1314,1315,1318],{},"টোকেনটা রিডিফাইন করাই যথেষ্ট, কারণ ইউটিলিটিগুলো ",[50,1316,1317],{},"line-height: var(--text-\u003Csize>--line-height)","-এ কম্পাইল হয়। কোনো সিলেক্টর লিখতে হয় না, আর ওই ধাপ ব্যবহার করা প্রতিটা এলিমেন্ট আপনাআপনি ঠিক হয়ে যায়।",[185,1320,1322],{"id":1321},"৩-uppercase-বাংলায়-একটা-no-op","৩. uppercase বাংলায় একটা no-op",[39,1324,1325,1326,1329],{},"বাংলায় বড় হাতের অক্ষর নেই। ",[50,1327,1328],{},"text-transform: uppercase"," কিছুই বদলায় না।",[39,1331,1332,1333,1336,1337,1340],{},"সমস্যা হলো, eyebrow বা badge-এর স্টাইলে ",[50,1334,1335],{},"uppercase"," একা আসে না — সাথে ",[50,1338,1339],{},"letter-spacing"," আসে। ল্যাটিনে বড় হাতের অক্ষর ফাঁক ফাঁক করে বসালে ভালো লাগে। বাংলায় ট্র্যাকিং বাড়ালে যুক্তাক্ষর টেনে আলাদা হয়ে যায়, আর লেবেলটা ভাঙা দেখায়।",[43,1342,1344],{"className":838,"code":1343,"language":840,"meta":48,"style":48},":lang(bn) :is(.ux-eyebrow, .uppercase, [class*='tracking-']) {\n  text-transform: none;\n  letter-spacing: normal;\n}\n",[50,1345,1346,1383,1395,1407],{"__ignoreMap":48},[53,1347,1348,1350,1352,1354,1356,1358,1360,1363,1365,1368,1371,1374,1377,1380],{"class":55,"line":56},[53,1349,1029],{"class":109},[53,1351,67],{"class":59},[53,1353,804],{"class":109},[53,1355,541],{"class":59},[53,1357,1087],{"class":109},[53,1359,67],{"class":59},[53,1361,1362],{"class":109},".ux-eyebrow",[53,1364,319],{"class":59},[53,1366,1367],{"class":109},".uppercase",[53,1369,1370],{"class":59},", [",[53,1372,1373],{"class":109},"class",[53,1375,1376],{"class":92},"*=",[53,1378,1379],{"class":70},"'tracking-'",[53,1381,1382],{"class":59},"]) {\n",[53,1384,1385,1388,1390,1393],{"class":55,"line":77},[53,1386,1387],{"class":109},"  text-transform",[53,1389,864],{"class":59},[53,1391,1392],{"class":109},"none",[53,1394,875],{"class":59},[53,1396,1397,1400,1402,1405],{"class":55,"line":83},[53,1398,1399],{"class":109},"  letter-spacing",[53,1401,864],{"class":59},[53,1403,1404],{"class":109},"normal",[53,1406,875],{"class":59},[53,1408,1409],{"class":55,"line":115},[53,1410,406],{"class":59},[39,1412,1413],{},"দুটোই বাতিল করা হয়েছে, নতুন করে স্টাইল করা হয়নি — ইংরেজি ট্র্যাক তার নিজের ট্রিটমেন্ট অক্ষত রাখে।",[185,1415,1417],{"id":1416},"৪-একই-px-এ-বাংলা-ছোট-দেখায়","৪. একই px-এ বাংলা ছোট দেখায়",[39,1419,1420],{},"একই ফন্ট-সাইজে বাংলার x-height ল্যাটিনের তুলনায় কম, তাই পাশাপাশি রাখলে বাংলাটা ছোট লাগে। খুব সামান্য একটা বাম্প দুই ট্র্যাককে একই ডিজাইন সিস্টেমের মতো দেখায়:",[43,1422,1424],{"className":838,"code":1423,"language":840,"meta":48,"style":48},":lang(bn) .ux-prose {\n  font-size: 1.03em;\n}\n",[50,1425,1426,1440,1455],{"__ignoreMap":48},[53,1427,1428,1430,1432,1434,1436,1438],{"class":55,"line":56},[53,1429,1029],{"class":109},[53,1431,67],{"class":59},[53,1433,804],{"class":109},[53,1435,541],{"class":59},[53,1437,1163],{"class":109},[53,1439,856],{"class":59},[53,1441,1442,1445,1447,1450,1453],{"class":55,"line":77},[53,1443,1444],{"class":109},"  font-size",[53,1446,864],{"class":59},[53,1448,1449],{"class":109},"1.03",[53,1451,1452],{"class":92},"em",[53,1454,875],{"class":59},[53,1456,1457],{"class":55,"line":83},[53,1458,406],{"class":59},[39,1460,1461,319,1463,1466],{},[50,1462,1452],{},[50,1464,1465],{},"px"," নয় — যাতে ব্যবহারকারীর নিজের ফন্ট-সাইজ সেটিং কাজ করতে থাকে।",[185,1468,1470],{"id":1469},"৫-সংখ্যার-হাইড্রেশন-মিসম্যাচ","৫. সংখ্যার হাইড্রেশন মিসম্যাচ",[39,1472,1473],{},"এইটা টাইপোগ্রাফির সমস্যা নয়, কিন্তু একই কাজ করতে গিয়ে ধরা পড়ে।",[39,1475,1476],{},"বাংলা সংখ্যা ফরম্যাট করতে স্বাভাবিক পছন্দ:",[43,1478,1480],{"className":889,"code":1479,"language":891,"meta":48,"style":48},"new Intl.NumberFormat('bn-BD').format(12480)\n",[50,1481,1482],{"__ignoreMap":48},[53,1483,1484,1487,1490,1493,1495,1498,1501,1504,1506,1509],{"class":55,"line":56},[53,1485,1486],{"class":92},"new",[53,1488,1489],{"class":59}," Intl.",[53,1491,1492],{"class":63},"NumberFormat",[53,1494,67],{"class":59},[53,1496,1497],{"class":70},"'bn-BD'",[53,1499,1500],{"class":59},").",[53,1502,1503],{"class":63},"format",[53,1505,67],{"class":59},[53,1507,1508],{"class":109},"12480",[53,1510,74],{"class":59},[39,1512,1513],{},"কিন্তু ICU বিল্ডগুলো একমত নয় — কেউ হাজার ধরে গ্রুপ করে (১২,৪৮০), কেউ লাখ ধরে (১২,৪৮০ বনাম ১,২৪৮০ ধরনের পার্থক্য)। Node-এর ICU আর ব্রাউজারের ICU আলাদা হলে সার্ভার একরকম লেখে, ক্লায়েন্ট আরেকরকম — আর prerendered পেজে সেটা সরাসরি hydration mismatch।",[39,1515,1516,1517,1520],{},"তাই গ্রুপিংটা ",[50,1518,1519],{},"en-US"," থেকে নিয়ে শুধু অঙ্কগুলো বদলানো হয়:",[43,1522,1524],{"className":889,"code":1523,"language":891,"meta":48,"style":48},"const BN_DIGITS = ['০', '১', '২', '৩', '৪', '৫', '৬', '৭', '৮', '৯']\n\nexport function formatBnNumber(value: number): string {\n  return new Intl.NumberFormat('en-US')\n    .format(value)\n    .replace(\u002F\\d\u002Fg, (d) => BN_DIGITS[Number(d)]!)\n}\n",[50,1525,1526,1585,1589,1620,1639,1649,1695],{"__ignoreMap":48},[53,1527,1528,1530,1533,1535,1538,1541,1543,1545,1547,1549,1551,1553,1555,1557,1559,1562,1564,1567,1569,1572,1574,1577,1579,1582],{"class":55,"line":56},[53,1529,636],{"class":92},[53,1531,1532],{"class":109}," BN_DIGITS",[53,1534,690],{"class":92},[53,1536,1537],{"class":59}," [",[53,1539,1540],{"class":70},"'০'",[53,1542,319],{"class":59},[53,1544,71],{"class":70},[53,1546,319],{"class":59},[53,1548,103],{"class":70},[53,1550,319],{"class":59},[53,1552,148],{"class":70},[53,1554,319],{"class":59},[53,1556,168],{"class":70},[53,1558,319],{"class":59},[53,1560,1561],{"class":70},"'৫'",[53,1563,319],{"class":59},[53,1565,1566],{"class":70},"'৬'",[53,1568,319],{"class":59},[53,1570,1571],{"class":70},"'৭'",[53,1573,319],{"class":59},[53,1575,1576],{"class":70},"'৮'",[53,1578,319],{"class":59},[53,1580,1581],{"class":70},"'৯'",[53,1583,1584],{"class":59},"]\n",[53,1586,1587],{"class":55,"line":77},[53,1588,80],{"emptyLinePlaceholder":24},[53,1590,1591,1594,1596,1599,1601,1604,1607,1610,1613,1615,1618],{"class":55,"line":83},[53,1592,1593],{"class":92},"export",[53,1595,497],{"class":92},[53,1597,1598],{"class":63}," formatBnNumber",[53,1600,67],{"class":59},[53,1602,1603],{"class":702},"value",[53,1605,1606],{"class":92},":",[53,1608,1609],{"class":109}," number",[53,1611,1612],{"class":59},")",[53,1614,1606],{"class":92},[53,1616,1617],{"class":109}," string",[53,1619,856],{"class":59},[53,1621,1622,1625,1628,1630,1632,1634,1637],{"class":55,"line":115},[53,1623,1624],{"class":92},"  return",[53,1626,1627],{"class":92}," new",[53,1629,1489],{"class":59},[53,1631,1492],{"class":63},[53,1633,67],{"class":59},[53,1635,1636],{"class":70},"'en-US'",[53,1638,74],{"class":59},[53,1640,1641,1644,1646],{"class":55,"line":120},[53,1642,1643],{"class":59},"    .",[53,1645,1503],{"class":63},[53,1647,1648],{"class":59},"(value)\n",[53,1650,1651,1653,1656,1658,1661,1664,1666,1669,1672,1675,1677,1679,1681,1684,1687,1690,1693],{"class":55,"line":154},[53,1652,1643],{"class":59},[53,1654,1655],{"class":63},"replace",[53,1657,67],{"class":59},[53,1659,1660],{"class":70},"\u002F",[53,1662,1663],{"class":109},"\\d",[53,1665,1660],{"class":70},[53,1667,1668],{"class":92},"g",[53,1670,1671],{"class":59},", (",[53,1673,1674],{"class":702},"d",[53,1676,541],{"class":59},[53,1678,93],{"class":92},[53,1680,1532],{"class":109},[53,1682,1683],{"class":59},"[",[53,1685,1686],{"class":63},"Number",[53,1688,1689],{"class":59},"(d)]",[53,1691,1692],{"class":92},"!",[53,1694,74],{"class":59},[53,1696,1697],{"class":55,"line":159},[53,1698,406],{"class":59},[39,1700,1701],{},"দেখতে হ্যাক লাগে। কিন্তু এটা deterministic, আর দুই রানটাইমে এক আউটপুট দেয় — যেটাই আসল দাবি।",[185,1703,1705],{"id":1704},"সব-মিলিয়ে","সব মিলিয়ে",[39,1707,1708,1709,1712],{},"লক্ষ্য করার মতো ব্যাপার: এর কোনোটাই \"বাংলার জন্য আলাদা ডিজাইন\" নয়। সবগুলো ",[50,1710,1711],{},":lang(bn)","-এর ভেতরে, একটা আলাদা ফাইলে, সবার শেষে ইমপোর্ট করা — যাতে ল্যাটিন ডিফল্টের উপরে জেতে।",[43,1714,1716],{"className":838,"code":1715,"language":840,"meta":48,"style":48},"@import '.\u002Fprose.css';\n\u002F* সবার শেষে, যাতে :lang(bn) আগেরগুলোকে override করে *\u002F\n@import '.\u002Fbangla.css';\n",[50,1717,1718,1728,1733],{"__ignoreMap":48},[53,1719,1720,1723,1726],{"class":55,"line":56},[53,1721,1722],{"class":92},"@import",[53,1724,1725],{"class":70}," '.\u002Fprose.css'",[53,1727,875],{"class":59},[53,1729,1730],{"class":55,"line":77},[53,1731,1732],{"class":220},"\u002F* সবার শেষে, যাতে :lang(bn) আগেরগুলোকে override করে *\u002F\n",[53,1734,1735,1737,1740],{"class":55,"line":83},[53,1736,1722],{"class":92},[53,1738,1739],{"class":70}," '.\u002Fbangla.css'",[53,1741,875],{"class":59},[39,1743,1744,1745,1748,1749,1752],{},"ইংরেজি ট্র্যাক এই ফাইলটার একটা লাইনও ছোঁয় না। আর ",[50,1746,1747],{},"\u003Chtml lang>"," ভুল হলে পুরো স্টাইলশিটটা চুপচাপ নিষ্ক্রিয় হয়ে যায় — উপসর্গ দেখায় \"বাংলা ভুল ফন্টে রেন্ডার হচ্ছে\", যেটা আসল কারণ থেকে অনেক দূরে। তাই ",[50,1750,1751],{},"lang"," অ্যাট্রিবিউটটা রুট থেকে সেট হয়, প্রতি পেজে নয়, আর একটা নতুন রুট সেটা ভুলে যেতে পারে না।",[788,1754,1755],{},"html pre.shiki code .s0RzX, html code.shiki .s0RzX{--shiki-default:#768390;--shiki-dark:#768390}html pre.shiki code .sza-u, html code.shiki .sza-u{--shiki-default:#8DDB8C;--shiki-dark:#8DDB8C}html pre.shiki code .sM9_K, html code.shiki .sM9_K{--shiki-default:#ADBAC7;--shiki-dark:#ADBAC7}html pre.shiki code .sQdni, html code.shiki .sQdni{--shiki-default:#6CB6FF;--shiki-dark:#6CB6FF}html pre.shiki code .szYpP, html code.shiki .szYpP{--shiki-default:#96D0FF;--shiki-dark:#96D0FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .siJwO, html code.shiki .siJwO{--shiki-default:#F69D50;--shiki-dark:#F69D50}html pre.shiki code .sEYkB, html code.shiki .sEYkB{--shiki-default:#F47067;--shiki-dark:#F47067}html pre.shiki code .s-wk_, html code.shiki .s-wk_{--shiki-default:#DCBDFB;--shiki-dark:#DCBDFB}",{"title":48,"searchDepth":83,"depth":83,"links":1757},[1758,1761,1762,1763,1764,1765],{"id":831,"depth":77,"text":832,"children":1759},[1760],{"id":1015,"depth":83,"text":1016},{"id":1134,"depth":77,"text":1135},{"id":1321,"depth":77,"text":1322},{"id":1416,"depth":77,"text":1417},{"id":1469,"depth":77,"text":1470},{"id":1704,"depth":77,"text":1705},"design","\u002Fcovers\u002Fblog\u002Fbn\u002Fbangla-typography-on-the-web.webp","2026-07-22","লাইন-হাইট, মাত্রার সংঘর্ষ, uppercase-এর অর্থহীনতা আর ফন্ট ফলব্যাক। ল্যাটিনের জন্য বানানো একটা ডিজাইন সিস্টেমে বাংলা বসাতে গিয়ে যা যা ঠিক করতে হয়েছিল।",{},"\u002Fblog\u002Fbn\u002Fbangla-typography-on-the-web",{"title":817,"description":1769},"blog\u002Fbn\u002Fbangla-typography-on-the-web",[1775,1776,1777],"টাইপোগ্রাফি","বাংলা","CSS","3-22xvnVCGspPollS842CYIXXRW-Q1sYELaRo6T-o3U",{"id":1780,"title":1781,"author":1782,"body":1783,"category":2457,"cover":2458,"coverAlt":1781,"date":2459,"description":2460,"draft":6,"extension":803,"featured":6,"lang":804,"meta":2461,"navigation":24,"path":2462,"readingTime":563,"seo":2463,"stem":2464,"tags":2465,"__hash__":2469},"blog\u002Fblog\u002Fbn\u002Fdesign-system-mistakes.md","ডিজাইন সিস্টেম বানানোর আগে যে ভুলগুলো এড়ানো দরকার",{"name":33,"role":34},{"type":36,"value":1784,"toc":2448},[1785,1788,1792,1795,1914,1924,1930,1934,1941,2148,2159,2162,2208,2215,2219,2228,2240,2244,2247,2297,2311,2314,2318,2321,2324,2328,2331,2422,2429,2433,2439,2442,2445],[39,1786,1787],{},"একটা ডিজাইন সিস্টেম হয় তার প্রথম রিব্র্যান্ড পার করে, নয়তো পারে না। বেশিরভাগ পারে না — আর কারণটা প্রায় সবসময় একই: সিস্টেমে দুইটা লেয়ার আছে, যেখানে দরকার ছিল তিনটা।",[185,1789,1791],{"id":1790},"দুই-লেয়ারের-ফাঁদ","দুই-লেয়ারের ফাঁদ",[39,1793,1794],{},"প্রায় প্রতিটা টোকেন সিস্টেম এইভাবে শুরু হয়। একটা প্যালেট, আর কম্পোনেন্ট যেগুলো সেটা ব্যবহার করে।",[43,1796,1798],{"className":838,"code":1797,"language":840,"meta":48,"style":48},":root {\n  --blue-500: #00d4ff;\n  --gray-900: #18181b;\n}\n\n.card {\n  background: var(--gray-900);\n  border-color: var(--gray-800);\n}\n\n.button-primary {\n  background: var(--blue-500);\n}\n",[50,1799,1800,1807,1819,1831,1835,1839,1846,1862,1878,1882,1886,1893,1909],{"__ignoreMap":48},[53,1801,1802,1805],{"class":55,"line":56},[53,1803,1804],{"class":109},":root",[53,1806,856],{"class":59},[53,1808,1809,1812,1814,1817],{"class":55,"line":77},[53,1810,1811],{"class":702},"  --blue-500",[53,1813,864],{"class":59},[53,1815,1816],{"class":109},"#00d4ff",[53,1818,875],{"class":59},[53,1820,1821,1824,1826,1829],{"class":55,"line":83},[53,1822,1823],{"class":702},"  --gray-900",[53,1825,864],{"class":59},[53,1827,1828],{"class":109},"#18181b",[53,1830,875],{"class":59},[53,1832,1833],{"class":55,"line":115},[53,1834,406],{"class":59},[53,1836,1837],{"class":55,"line":120},[53,1838,80],{"emptyLinePlaceholder":24},[53,1840,1841,1844],{"class":55,"line":154},[53,1842,1843],{"class":109},".card",[53,1845,856],{"class":59},[53,1847,1848,1851,1853,1855,1857,1860],{"class":55,"line":159},[53,1849,1850],{"class":109},"  background",[53,1852,864],{"class":59},[53,1854,1116],{"class":109},[53,1856,67],{"class":59},[53,1858,1859],{"class":702},"--gray-900",[53,1861,1124],{"class":59},[53,1863,1864,1867,1869,1871,1873,1876],{"class":55,"line":563},[53,1865,1866],{"class":109},"  border-color",[53,1868,864],{"class":59},[53,1870,1116],{"class":109},[53,1872,67],{"class":59},[53,1874,1875],{"class":702},"--gray-800",[53,1877,1124],{"class":59},[53,1879,1880],{"class":55,"line":987},[53,1881,406],{"class":59},[53,1883,1884],{"class":55,"line":996},[53,1885,80],{"emptyLinePlaceholder":24},[53,1887,1888,1891],{"class":55,"line":1002},[53,1889,1890],{"class":109},".button-primary",[53,1892,856],{"class":59},[53,1894,1896,1898,1900,1902,1904,1907],{"class":55,"line":1895},12,[53,1897,1850],{"class":109},[53,1899,864],{"class":59},[53,1901,1116],{"class":109},[53,1903,67],{"class":59},[53,1905,1906],{"class":702},"--blue-500",[53,1908,1124],{"class":59},[53,1910,1912],{"class":55,"line":1911},13,[53,1913,406],{"class":59},[39,1915,1916,1917,1919,1920,1923],{},"দেখতে পরিষ্কার। ছয় মাস ভালোই চলে। তারপর ব্র্যান্ড বদলায় — নীল থেকে সবুজ — আর তখন বোঝা যায় ",[50,1918,1906],{}," নামটাই সমস্যা। এখন হয় সবুজ রঙ একটা ",[50,1921,1922],{},"blue"," নামের ভেরিয়েবলে রাখতে হবে, নয়তো কোডবেসে ৪০০টা জায়গায় খুঁজে বদলাতে হবে।",[39,1925,1926,1927,1929],{},"আরও খারাপ ব্যাপারটা হলো ডার্ক মোড। ",[50,1928,1859],{}," ডার্ক থিমে ব্যাকগ্রাউন্ড, লাইট থিমে টেক্সট। একই টোকেন, দুইটা উল্টো ভূমিকা। কম্পোনেন্ট যখন সরাসরি প্যালেট ছোঁয়, তখন প্রতিটা কম্পোনেন্টকে জানতে হয় থিম কী — আর সেটাই সিস্টেমটার মৃত্যু।",[185,1931,1933],{"id":1932},"তৃতীয়-লেয়ারটা-ভূমিকা","তৃতীয় লেয়ারটা: ভূমিকা",[39,1935,1936,1937,1940],{},"মাঝখানে যা দরকার, সেটা রঙ নয় — ",[196,1938,1939],{},"ভূমিকা","।",[43,1942,1944],{"className":838,"code":1943,"language":840,"meta":48,"style":48},"\u002F* লেয়ার ১ — প্রিমিটিভ। কোনো প্রোডাক্ট-অর্থ নেই। *\u002F\n:root {\n  --cyan-400: #22d3ee;\n  --cyan-600: #0891b2;\n  --zinc-50: #fafafa;\n  --zinc-900: #18181b;\n}\n\n\u002F* লেয়ার ২ — সিমান্টিক। থিম অনুযায়ী বদলায়। *\u002F\n:root {\n  --surface: var(--zinc-50);\n  --foreground: var(--zinc-900);\n  --primary: var(--cyan-600);\n}\n\n[data-theme='dark'] {\n  --surface: var(--zinc-900);\n  --foreground: var(--zinc-50);\n  --primary: var(--cyan-400);\n}\n",[50,1945,1946,1951,1957,1969,1981,1993,2004,2008,2012,2017,2023,2039,2055,2071,2076,2081,2097,2112,2127,2143],{"__ignoreMap":48},[53,1947,1948],{"class":55,"line":56},[53,1949,1950],{"class":220},"\u002F* লেয়ার ১ — প্রিমিটিভ। কোনো প্রোডাক্ট-অর্থ নেই। *\u002F\n",[53,1952,1953,1955],{"class":55,"line":77},[53,1954,1804],{"class":109},[53,1956,856],{"class":59},[53,1958,1959,1962,1964,1967],{"class":55,"line":83},[53,1960,1961],{"class":702},"  --cyan-400",[53,1963,864],{"class":59},[53,1965,1966],{"class":109},"#22d3ee",[53,1968,875],{"class":59},[53,1970,1971,1974,1976,1979],{"class":55,"line":115},[53,1972,1973],{"class":702},"  --cyan-600",[53,1975,864],{"class":59},[53,1977,1978],{"class":109},"#0891b2",[53,1980,875],{"class":59},[53,1982,1983,1986,1988,1991],{"class":55,"line":120},[53,1984,1985],{"class":702},"  --zinc-50",[53,1987,864],{"class":59},[53,1989,1990],{"class":109},"#fafafa",[53,1992,875],{"class":59},[53,1994,1995,1998,2000,2002],{"class":55,"line":154},[53,1996,1997],{"class":702},"  --zinc-900",[53,1999,864],{"class":59},[53,2001,1828],{"class":109},[53,2003,875],{"class":59},[53,2005,2006],{"class":55,"line":159},[53,2007,406],{"class":59},[53,2009,2010],{"class":55,"line":563},[53,2011,80],{"emptyLinePlaceholder":24},[53,2013,2014],{"class":55,"line":987},[53,2015,2016],{"class":220},"\u002F* লেয়ার ২ — সিমান্টিক। থিম অনুযায়ী বদলায়। *\u002F\n",[53,2018,2019,2021],{"class":55,"line":996},[53,2020,1804],{"class":109},[53,2022,856],{"class":59},[53,2024,2025,2028,2030,2032,2034,2037],{"class":55,"line":1002},[53,2026,2027],{"class":702},"  --surface",[53,2029,864],{"class":59},[53,2031,1116],{"class":109},[53,2033,67],{"class":59},[53,2035,2036],{"class":702},"--zinc-50",[53,2038,1124],{"class":59},[53,2040,2041,2044,2046,2048,2050,2053],{"class":55,"line":1895},[53,2042,2043],{"class":702},"  --foreground",[53,2045,864],{"class":59},[53,2047,1116],{"class":109},[53,2049,67],{"class":59},[53,2051,2052],{"class":702},"--zinc-900",[53,2054,1124],{"class":59},[53,2056,2057,2060,2062,2064,2066,2069],{"class":55,"line":1911},[53,2058,2059],{"class":702},"  --primary",[53,2061,864],{"class":59},[53,2063,1116],{"class":109},[53,2065,67],{"class":59},[53,2067,2068],{"class":702},"--cyan-600",[53,2070,1124],{"class":59},[53,2072,2074],{"class":55,"line":2073},14,[53,2075,406],{"class":59},[53,2077,2079],{"class":55,"line":2078},15,[53,2080,80],{"emptyLinePlaceholder":24},[53,2082,2084,2086,2089,2091,2094],{"class":55,"line":2083},16,[53,2085,1683],{"class":59},[53,2087,2088],{"class":109},"data-theme",[53,2090,238],{"class":92},[53,2092,2093],{"class":70},"'dark'",[53,2095,2096],{"class":59},"] {\n",[53,2098,2100,2102,2104,2106,2108,2110],{"class":55,"line":2099},17,[53,2101,2027],{"class":702},[53,2103,864],{"class":59},[53,2105,1116],{"class":109},[53,2107,67],{"class":59},[53,2109,2052],{"class":702},[53,2111,1124],{"class":59},[53,2113,2115,2117,2119,2121,2123,2125],{"class":55,"line":2114},18,[53,2116,2043],{"class":702},[53,2118,864],{"class":59},[53,2120,1116],{"class":109},[53,2122,67],{"class":59},[53,2124,2036],{"class":702},[53,2126,1124],{"class":59},[53,2128,2130,2132,2134,2136,2138,2141],{"class":55,"line":2129},19,[53,2131,2059],{"class":702},[53,2133,864],{"class":59},[53,2135,1116],{"class":109},[53,2137,67],{"class":59},[53,2139,2140],{"class":702},"--cyan-400",[53,2142,1124],{"class":59},[53,2144,2146],{"class":55,"line":2145},20,[53,2147,406],{"class":59},[39,2149,2150,2151,2154,2155,2158],{},"খেয়াল করুন ",[50,2152,2153],{},"--primary"," দুই থিমে ",[196,2156,2157],{},"আলাদা hex","। এটা ভুল নয়, এটাই মূল কথা। ডার্ক মোডের উজ্জ্বল সায়ান সাদা ব্যাকগ্রাউন্ডে কনট্রাস্ট পরীক্ষায় ফেল করে। \"একটা ব্র্যান্ড কালার সব জায়গায়\" — এই ধারণাটাই অ্যাক্সেসিবিলিটির সাথে সাংঘর্ষিক।",[39,2160,2161],{},"কম্পোনেন্ট এখন শুধু ভূমিকা ব্যবহার করে:",[43,2163,2165],{"className":838,"code":2164,"language":840,"meta":48,"style":48},".card {\n  background: var(--surface);\n  color: var(--foreground);\n}\n",[50,2166,2167,2173,2188,2204],{"__ignoreMap":48},[53,2168,2169,2171],{"class":55,"line":56},[53,2170,1843],{"class":109},[53,2172,856],{"class":59},[53,2174,2175,2177,2179,2181,2183,2186],{"class":55,"line":77},[53,2176,1850],{"class":109},[53,2178,864],{"class":59},[53,2180,1116],{"class":109},[53,2182,67],{"class":59},[53,2184,2185],{"class":702},"--surface",[53,2187,1124],{"class":59},[53,2189,2190,2193,2195,2197,2199,2202],{"class":55,"line":83},[53,2191,2192],{"class":109},"  color",[53,2194,864],{"class":59},[53,2196,1116],{"class":109},[53,2198,67],{"class":59},[53,2200,2201],{"class":702},"--foreground",[53,2203,1124],{"class":59},[53,2205,2206],{"class":55,"line":115},[53,2207,406],{"class":59},[39,2209,2210,2211,2214],{},"রিব্র্যান্ড এখন ",[196,2212,2213],{},"লেয়ার দুইয়ের একটা এডিট","। কম্পোনেন্ট একটাও ছুঁতে হয় না।",[185,2216,2218],{"id":2217},"ভুল-১-টোকেনের-নাম-রঙ-দিয়ে-রাখা","ভুল ১ — টোকেনের নাম রঙ দিয়ে রাখা",[39,2220,2221,2224,2225,2227],{},[50,2222,2223],{},"--brand-blue"," একটা টাইম বোমা। ",[50,2226,2153],{}," নয়।",[39,2229,2230,2231,319,2233,319,2236,2239],{},"নিয়মটা সহজ: টোকেনের নামে যদি এমন কিছু থাকে যা রিব্র্যান্ডে মিথ্যা হয়ে যেতে পারে, নামটা ভুল। ",[50,2232,1922],{},[50,2234,2235],{},"large",[50,2237,2238],{},"top-nav"," — সবগুলোই কোনো না কোনো দিন মিথ্যা হয়।",[185,2241,2243],{"id":2242},"ভুল-২-বিল্ড-টাইমে-রিজলভ-করা","ভুল ২ — বিল্ড টাইমে রিজলভ করা",[39,2245,2246],{},"Tailwind v4-এ এইটা নিঃশব্দে কামড় দেয়।",[43,2248,2250],{"className":838,"code":2249,"language":840,"meta":48,"style":48},"\u002F* ভুল — টগল কাজ করা বন্ধ করে দেয় *\u002F\n@theme {\n  --color-surface: var(--surface);\n}\n\n\u002F* ঠিক *\u002F\n@theme inline {\n  --color-surface: var(--surface);\n}\n",[50,2251,2252,2257,2264,2269,2273,2277,2282,2289,2293],{"__ignoreMap":48},[53,2253,2254],{"class":55,"line":56},[53,2255,2256],{"class":220},"\u002F* ভুল — টগল কাজ করা বন্ধ করে দেয় *\u002F\n",[53,2258,2259,2262],{"class":55,"line":77},[53,2260,2261],{"class":92},"@theme",[53,2263,856],{"class":59},[53,2265,2266],{"class":55,"line":83},[53,2267,2268],{"class":59},"  --color-surface: var(--surface);\n",[53,2270,2271],{"class":55,"line":115},[53,2272,406],{"class":59},[53,2274,2275],{"class":55,"line":120},[53,2276,80],{"emptyLinePlaceholder":24},[53,2278,2279],{"class":55,"line":154},[53,2280,2281],{"class":220},"\u002F* ঠিক *\u002F\n",[53,2283,2284,2286],{"class":55,"line":159},[53,2285,2261],{"class":92},[53,2287,2288],{"class":59}," inline {\n",[53,2290,2291],{"class":55,"line":563},[53,2292,2268],{"class":59},[53,2294,2295],{"class":55,"line":987},[53,2296,406],{"class":59},[39,2298,2299,2300,2302,2303,2306,2307,2310],{},"সাধারণ ",[50,2301,2261],{}," ব্লক মানটা বিল্ড টাইমে রিজলভ করে ফেলে — অর্থাৎ ",[50,2304,2305],{},"bg-surface"," কম্পাইল হয়ে একটা fixed hex-এ পরিণত হয়। থিম অ্যাট্রিবিউট বদলালে ভেরিয়েবল বদলায়, কিন্তু ক্লাসটা আর ভেরিয়েবল পড়ছেই না। ",[50,2308,2309],{},"inline"," কি-ওয়ার্ডটা রেফারেন্সটা রানটাইম পর্যন্ত টিকিয়ে রাখে।",[39,2312,2313],{},"লক্ষণটা বিভ্রান্তিকর: থিম টগল \"কাজ করে না\", অথচ ভেরিয়েবলগুলো DevTools-এ ঠিকঠাক বদলাচ্ছে।",[185,2315,2317],{"id":2316},"ভুল-৩-অনেক-বেশি-টোকেন","ভুল ৩ — অনেক বেশি টোকেন",[39,2319,2320],{},"একটা সিস্টেমে ২০০টা স্পেসিং টোকেন থাকলে সেটা সিস্টেম নয়, সেটা একটা অভিধান। কেউ মুখস্থ করবে না, সবাই কাছাকাছি একটা বেছে নেবে, আর ফলাফল হবে ইনকনসিস্টেন্সি — ঠিক যেটা ঠেকাতে সিস্টেমটা বানানো।",[39,2322,2323],{},"কম টোকেন, কড়া নিয়ম। যদি একটা মান বছরে একবার লাগে, সেটা টোকেন নয় — সেটা ওই এক জায়গার একটা মান।",[185,2325,2327],{"id":2326},"ভুল-৪-কম্পোনেন্ট-api-টা-লিখে-না-রাখা","ভুল ৪ — কম্পোনেন্ট API-টা লিখে না রাখা",[39,2329,2330],{},"টোকেন ঠিক থাকলেও কম্পোনেন্ট যদি যা খুশি ক্লাস নেয়, সিস্টেমটা ফাঁকা। প্রতিটা ভ্যারিয়েন্ট এক জায়গায় ঘোষিত থাকা দরকার:",[43,2332,2334],{"className":889,"code":2333,"language":891,"meta":48,"style":48},"const button = tv({\n  base: 'inline-flex items-center justify-center rounded-lg',\n  variants: {\n    variant: {\n      primary: 'bg-primary text-on-primary',\n      ghost: 'bg-transparent hover:bg-surface-hover',\n    },\n    size: { sm: 'h-8 px-3', md: 'h-10 px-4' },\n  },\n})\n",[50,2335,2336,2351,2361,2366,2371,2381,2391,2396,2412,2417],{"__ignoreMap":48},[53,2337,2338,2340,2343,2345,2348],{"class":55,"line":56},[53,2339,636],{"class":92},[53,2341,2342],{"class":109}," button",[53,2344,690],{"class":92},[53,2346,2347],{"class":63}," tv",[53,2349,2350],{"class":59},"({\n",[53,2352,2353,2356,2359],{"class":55,"line":77},[53,2354,2355],{"class":59},"  base: ",[53,2357,2358],{"class":70},"'inline-flex items-center justify-center rounded-lg'",[53,2360,961],{"class":59},[53,2362,2363],{"class":55,"line":83},[53,2364,2365],{"class":59},"  variants: {\n",[53,2367,2368],{"class":55,"line":115},[53,2369,2370],{"class":59},"    variant: {\n",[53,2372,2373,2376,2379],{"class":55,"line":120},[53,2374,2375],{"class":59},"      primary: ",[53,2377,2378],{"class":70},"'bg-primary text-on-primary'",[53,2380,961],{"class":59},[53,2382,2383,2386,2389],{"class":55,"line":154},[53,2384,2385],{"class":59},"      ghost: ",[53,2387,2388],{"class":70},"'bg-transparent hover:bg-surface-hover'",[53,2390,961],{"class":59},[53,2392,2393],{"class":55,"line":159},[53,2394,2395],{"class":59},"    },\n",[53,2397,2398,2401,2404,2407,2410],{"class":55,"line":563},[53,2399,2400],{"class":59},"    size: { sm: ",[53,2402,2403],{"class":70},"'h-8 px-3'",[53,2405,2406],{"class":59},", md: ",[53,2408,2409],{"class":70},"'h-10 px-4'",[53,2411,945],{"class":59},[53,2413,2414],{"class":55,"line":987},[53,2415,2416],{"class":59},"  },\n",[53,2418,2419],{"class":55,"line":996},[53,2420,2421],{"class":59},"})\n",[39,2423,2424,2425,2428],{},"টেবিলে না থাকলে ভ্যারিয়েন্টটা ",[196,2426,2427],{},"নেই","। এটাই একমাত্র নিয়ম যেটা সিস্টেমকে দুই বছর পরেও সিস্টেম রাখে।",[185,2430,2432],{"id":2431},"যাচাই-করার-উপায়","যাচাই করার উপায়",[39,2434,2435,2436],{},"সিস্টেমটা টিকবে কি না, তার একটাই সৎ পরীক্ষা: ",[196,2437,2438],{},"প্রাইমারি রঙটা বদলে দিন।",[39,2440,2441],{},"একটা ফাইলে একটা লাইন বদলে যদি পুরো প্রোডাক্ট বদলে যায় — দুই থিমেই, কনট্রাস্ট ভেঙে না গিয়ে — তাহলে তিনটা লেয়ার ঠিক আছে। যদি খুঁজে খুঁজে বদলাতে হয়, তাহলে এখনো দুইটা লেয়ার, আর প্রথম রিব্র্যান্ডেই এটা ভাঙবে।",[39,2443,2444],{},"এই পরীক্ষাটা করতে এক দিন লাগে। রিব্র্যান্ডের পর করতে হলে এক কোয়ার্টার লাগে।",[788,2446,2447],{},"html pre.shiki code .sQdni, html code.shiki .sQdni{--shiki-default:#6CB6FF;--shiki-dark:#6CB6FF}html pre.shiki code .sM9_K, html code.shiki .sM9_K{--shiki-default:#ADBAC7;--shiki-dark:#ADBAC7}html pre.shiki code .siJwO, html code.shiki .siJwO{--shiki-default:#F69D50;--shiki-dark:#F69D50}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s0RzX, html code.shiki .s0RzX{--shiki-default:#768390;--shiki-dark:#768390}html pre.shiki code .sEYkB, html code.shiki .sEYkB{--shiki-default:#F47067;--shiki-dark:#F47067}html pre.shiki code .szYpP, html code.shiki .szYpP{--shiki-default:#96D0FF;--shiki-dark:#96D0FF}html pre.shiki code .s-wk_, html code.shiki .s-wk_{--shiki-default:#DCBDFB;--shiki-dark:#DCBDFB}",{"title":48,"searchDepth":83,"depth":83,"links":2449},[2450,2451,2452,2453,2454,2455,2456],{"id":1790,"depth":77,"text":1791},{"id":1932,"depth":77,"text":1933},{"id":2217,"depth":77,"text":2218},{"id":2242,"depth":77,"text":2243},{"id":2316,"depth":77,"text":2317},{"id":2326,"depth":77,"text":2327},{"id":2431,"depth":77,"text":2432},"design-systems","\u002Fcovers\u002Fblog\u002Fbn\u002Fdesign-system-mistakes.webp","2026-07-04","বেশিরভাগ টোকেন সিস্টেম প্রথম রিব্র্যান্ডেই ভেঙে পড়ে। কারণটা প্রায় সবসময় এক — দুইটা লেয়ার আছে, দরকার ছিল তিনটা।",{},"\u002Fblog\u002Fbn\u002Fdesign-system-mistakes",{"title":1781,"description":2460},"blog\u002Fbn\u002Fdesign-system-mistakes",[2466,2467,2468],"ডিজাইন সিস্টেম","টোকেন","Tailwind","_t10HyFYNMKbFM1KZ69e8oB9eMINx6xpy20k22vHQ5s",{"id":2471,"title":2472,"author":2473,"body":2474,"category":2627,"cover":2628,"coverAlt":2472,"date":2629,"description":2630,"draft":6,"extension":803,"featured":6,"lang":804,"meta":2631,"navigation":24,"path":2632,"readingTime":154,"seo":2633,"stem":2634,"tags":2635,"__hash__":2639},"blog\u002Fblog\u002Fbn\u002Ffreelance-rate-setting.md","ফ্রিল্যান্সিংয়ে রেট ঠিক করা — ঘণ্টার হিসাব থেকে বেরোনোর উপায়",{"name":819,"role":820},{"type":36,"value":2475,"toc":2619},[2476,2479,2482,2485,2489,2492,2495,2503,2506,2510,2513,2545,2548,2552,2555,2558,2563,2566,2570,2573,2579,2590,2593,2597,2600,2605,2608,2612],[39,2477,2478],{},"ঘণ্টায় দাম নেওয়ার একটা কাঠামোগত সমস্যা আছে, আর সেটা রেট কম না বেশি তার সাথে সম্পর্কিত নয়।",[39,2480,2481],{},"আপনি যত ভালো হবেন, একই কাজ তত দ্রুত করবেন। ঘণ্টায় বিল করলে দক্ষতা বাড়ার সরাসরি ফল হলো আয় কমা। পাঁচ বছরের অভিজ্ঞতা দিয়ে যে কাজটা তিন ঘণ্টায় করছেন, নতুন কেউ সেটা বারো ঘণ্টায় করবে — এবং চারগুণ বেশি পাবে।",[39,2483,2484],{},"এটা কোনো নৈতিক সমস্যা নয়, হিসাবের সমস্যা। আর সমাধানটা রেট বাড়ানো নয়, ইউনিট বদলানো।",[185,2486,2488],{"id":2487},"ঘণ্টা-নয়-ফল","ঘণ্টা নয়, ফল",[39,2490,2491],{},"ক্লায়েন্ট ঘণ্টা কিনছে না। সে কিনছে একটা কাজ হয়ে যাওয়া — একটা ল্যান্ডিং পেজ যেটা কনভার্ট করে, একটা ড্যাশবোর্ড যেটা তার টিম বুঝতে পারে।",[39,2493,2494],{},"তাই প্রস্তাবটা এভাবে লেখা:",[339,2496,2497],{},[39,2498,2499,2502],{},[196,2500,2501],{},"ল্যান্ডিং পেজ ডিজাইন ও বিল্ড"," — ৪টি সেকশন, রেসপন্সিভ, দুই রাউন্ড রিভিশন। ডেলিভারি ১২ কর্মদিবস। ৳XX,XXX।",[39,2504,2505],{},"\"৪০ ঘণ্টা × ৳X\" নয়। প্রথমটায় ঝুঁকি আপনার, দ্বিতীয়টায় ঝুঁকি ক্লায়েন্টের — আর ক্লায়েন্ট ঝুঁকি নিতে চায় বলেই আপনাকে ডেকেছে।",[185,2507,2509],{"id":2508},"সংখ্যা-বলার-আগে-যে-প্রশ্নগুলো","সংখ্যা বলার আগে যে প্রশ্নগুলো",[39,2511,2512],{},"দাম বলার আগে অন্তত এই কয়টার উত্তর দরকার। উত্তরগুলো না জেনে দেওয়া প্রতিটা কোটই আসলে একটা অনুমান:",[276,2514,2515,2521,2527,2533,2539],{},[279,2516,2517,2520],{},[196,2518,2519],{},"কে সিদ্ধান্ত নেবে?"," একজন, না কমিটি? অনুমোদনকারীর সংখ্যার সাথে রিভিশনের সংখ্যা প্রায় রৈখিকভাবে বাড়ে।",[279,2522,2523,2526],{},[196,2524,2525],{},"কনটেন্ট কে দেবে?"," \"আপনি লিখে দিন\" একটা আলাদা প্রজেক্ট, এবং সেটাই সবচেয়ে বেশি সময় খায়।",[279,2528,2529,2532],{},[196,2530,2531],{},"কীসের সাথে যুক্ত হবে?"," একটা বিদ্যমান কোডবেস, নাকি নতুন? পুরোনো কোডে ঢোকার সময়টা কেউ হিসাব করে না।",[279,2534,2535,2538],{},[196,2536,2537],{},"ডেডলাইনটা কার?"," কোনো ইভেন্ট বা লঞ্চের সাথে বাঁধা থাকলে বাফার বাড়াতে হবে।",[279,2540,2541,2544],{},[196,2542,2543],{},"\"শেষ\" মানে কী?"," ডিজাইন ফাইল, নাকি ডিপ্লয় করা সাইট? এই একটা প্রশ্নে প্রজেক্টের আকার দ্বিগুণ হতে পারে।",[39,2546,2547],{},"শেষ প্রশ্নটাই সবচেয়ে বেশি টাকা বাঁচায়।",[185,2549,2551],{"id":2550},"বাফারটা-লুকিয়ে-রাখবেন-না","বাফারটা লুকিয়ে রাখবেন না",[39,2553,2554],{},"সবাই বাফার রাখে। বেশিরভাগ মানুষ সেটা রেটের ভেতর লুকিয়ে রাখে, তারপর স্কোপ বাড়লে অস্বস্তিতে পড়ে।",[39,2556,2557],{},"ভালো উপায় হলো সীমাটা লিখে রাখা:",[339,2559,2560],{},[39,2561,2562],{},"দুই রাউন্ড রিভিশন অন্তর্ভুক্ত। এর পরের প্রতিটি রাউন্ড ৳X,XXX।",[39,2564,2565],{},"এটা ক্লায়েন্টের বিরুদ্ধে নয় — এটা তাকে তথ্য দেয়। এখন সে জানে তৃতীয় রাউন্ডের দাম কত, আর সিদ্ধান্তটা তার হাতে। যেসব প্রজেক্ট তিক্ত হয়, সেগুলোর প্রায় সবগুলোতেই এই লাইনটা ছিল না।",[185,2567,2569],{"id":2568},"প্রথম-সংখ্যাটা-কীভাবে-বের-করবেন","প্রথম সংখ্যাটা কীভাবে বের করবেন",[39,2571,2572],{},"একটা কাজ করা যায়: বছরে যত টাকা দরকার, সেটা থেকে পিছিয়ে হিসাব করুন।",[43,2574,2577],{"className":2575,"code":2576,"language":606},[604],"বার্ষিক লক্ষ্য              ৳১২,০০,০০০\n+ খরচ (সফটওয়্যার, ডিভাইস)     ৳১,০০,০০০\n+ কর ও অনিশ্চয়তা (~২৫%)       ৳৩,২৫,০০০\n────────────────────────────────────────\nমোট দরকার                   ৳১৬,২৫,০০০\n\nবিলযোগ্য সপ্তাহ (ছুটি ও ফাঁকা বাদে)      ৪০\nসপ্তাহে বিলযোগ্য দিন (বাকিটা সেলস, শেখা)  ৩\n────────────────────────────────────────\nবিলযোগ্য দিন                 ১২০\nদৈনিক হার                    ~৳১৩,৫০০\n",[50,2578,2576],{"__ignoreMap":48},[39,2580,2581,2582,2585,2586,2589],{},"গুরুত্বপূর্ণ সংখ্যাটা ",[196,2583,2584],{},"৫২ সপ্তাহ নয়, ৪০"," এবং ",[196,2587,2588],{},"৫ দিন নয়, ৩","। প্রস্তাব লেখা, ইমেইল, ইনভয়েস, নতুন কিছু শেখা — এগুলো কাজের অংশ, কিন্তু কেউ এর বিল দেয় না। ৫ দিন ধরে হিসাব করলে আপনি সপ্তাহে সাত দিন কাজ করেও লক্ষ্যে পৌঁছাবেন না।",[39,2591,2592],{},"এই দৈনিক হারটা ক্লায়েন্টকে বলার জন্য নয়। এটা আপনার নিজের জন্য — একটা ফিক্সড প্রাইস দেওয়ার পর যাচাই করার মাপকাঠি।",[185,2594,2596],{"id":2595},"কম-রেটে-পোর্টফোলিওর-জন্য-কাজ","কম রেটে \"পোর্টফোলিওর জন্য\" কাজ",[39,2598,2599],{},"মাঝে মাঝে যুক্তিসঙ্গত — শুরুতে, বা এমন একটা কাজ যেটা সত্যিই দেখানোর মতো হবে। কিন্তু তখনও ছাড়টা লিখে রাখুন:",[339,2601,2602],{},[39,2603,2604],{},"স্বাভাবিক মূল্য ৳XX,XXX। এই প্রজেক্টে ৳XX,XXX — কেস স্টাডি হিসেবে প্রকাশের অনুমতির বিনিময়ে।",[39,2606,2607],{},"কারণ ছাড়টা অদৃশ্য হলে সেটাই আপনার রেট হয়ে যায়। ওই ক্লায়েন্ট পরের প্রজেক্টে একই সংখ্যা আশা করবে, আর সে যাকে রেফার করবে সেও তাই করবে।",[185,2609,2611],{"id":2610},"শেষ-কথা","শেষ কথা",[39,2613,2614,2615,2618],{},"রেট নিয়ে সবচেয়ে কাজের পরিবর্তনটা আসলে সংখ্যায় নয় — সেটা হলো ",[196,2616,2617],{},"দাম বলার আগে প্রশ্ন করার অভ্যাস","। যে প্রজেক্টগুলোতে লোকসান হয়, সেগুলো কম রেটের কারণে হয় না; হয় এমন একটা স্কোপের কারণে যেটা কেউ শুরুতে লিখে রাখেনি।",{"title":48,"searchDepth":83,"depth":83,"links":2620},[2621,2622,2623,2624,2625,2626],{"id":2487,"depth":77,"text":2488},{"id":2508,"depth":77,"text":2509},{"id":2550,"depth":77,"text":2551},{"id":2568,"depth":77,"text":2569},{"id":2595,"depth":77,"text":2596},{"id":2610,"depth":77,"text":2611},"career","\u002Fcovers\u002Fblog\u002Fbn\u002Ffreelance-rate-setting.webp","2026-05-19","ঘণ্টায় দাম দিলে আপনি দ্রুত কাজ শেখার জন্য শাস্তি পান। স্কোপ, বাফার আর কীভাবে একটা সংখ্যা বলার আগে প্রশ্নগুলো করতে হয়।",{},"\u002Fblog\u002Fbn\u002Ffreelance-rate-setting",{"title":2472,"description":2630},"blog\u002Fbn\u002Ffreelance-rate-setting",[2636,2637,2638],"ফ্রিল্যান্সিং","ক্লায়েন্ট","স্কোপ","kRP5oD821PrdPuxrcbDf0LGKTSr493YDSi8EjY4gaAA",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":2641},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m9 18l6-6l-6-6\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":2643},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M8 2v3m8-3v3\"\u002F>\u003Crect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"\u002F>\u003Cpath d=\"M3 9h18\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":2645},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"10\"\u002F>\u003Cpath d=\"M12 6v6l4 2\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":2647},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"\u002F>\u003Cpath d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":2649},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 4v16M4 7V5a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2M9 20h6\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":2651},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15.536 11.293a1 1 0 0 0 0 1.414l2.376 2.377a1 1 0 0 0 1.414 0l2.377-2.377a1 1 0 0 0 0-1.414l-2.377-2.377a1 1 0 0 0-1.414 0zm-13.239 0a1 1 0 0 0 0 1.414l2.377 2.377a1 1 0 0 0 1.414 0l2.377-2.377a1 1 0 0 0 0-1.414L6.088 8.916a1 1 0 0 0-1.414 0zm6.619 6.619a1 1 0 0 0 0 1.415l2.377 2.376a1 1 0 0 0 1.414 0l2.377-2.376a1 1 0 0 0 0-1.415l-2.377-2.376a1 1 0 0 0-1.414 0zm0-13.238a1 1 0 0 0 0 1.414l2.377 2.376a1 1 0 0 0 1.414 0l2.377-2.376a1 1 0 0 0 0-1.414l-2.377-2.377a1 1 0 0 0-1.414 0z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":2653},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16\"\u002F>\u003Crect width=\"20\" height=\"14\" x=\"2\" y=\"6\" rx=\"2\"\u002F>\u003C\u002Fg>",1787597891530]