We built a CSS Challenge platform ![rw-book-cover](https://img.youtube.com/vi/gcpfUP9L6es/maxresdefault.jpg) We decided to host a major CSS coding battle tournament here on Syntax with 14 of the greatest CSS engineers out there and then two other competitors in that competition. That being Wes and myself competing in CSS battles. And we've been doing a lot of CSS battles here on Fridays and our uh the three devs videos with CJ Wes and I. But we wanted to take it one step further. And so we built our own CSS coding battles platform. So we're going to be talking all about how that works, the stack, how the stack works itself, what we're using for various components, why it's cool, and we're going to be diving into some of the challenges that we had getting this thing up and running. Because let me tell you, this has been a massive sprint to build our own platform from scratch just to use for this CSS coding tournament. My name is Scott Tolinsky. I'm a developer from Denver. With me as always is Wes Boss. What's up, Wes? Hey, excited to talk about this. This has been very fun to work on the last what two weeks or so. I joined in about two weeks ago and helped crank out issues. But it's it's a really cool platform. It's all local first, all syncs. It's all fast as heck since felt. Really cool. Love it. >> Yeah, [snorts] I will say it's not local first. And uh I I'm going to push back on that. [laughter] But I I do think that's an important part of this distinction here because we'll talk about why it's not local first. Uh we'll talk about the tech. it is using zero sync which definitely was a platform that was initially described as being local first but they've really kind of shifted uh that message a little bit because I don't think it really truly falls under that but I I think you saying it's local first is not a bad thing Wes I think that is uh how most people might think about this and look about it so again the MAD CSS uh March Mad CSS tournament you will find that exclusively on our YouTube channel here we have some of the the best competitive s Kevin Powell, Adam Argal, Adam Wan, Cassidy Williams, Ana Kubo, is that who you said her last name, Wes? >> I believe so. I'm not Don't Don't count me on that. >> Sorry, Anya. Uh Josh Ku. Uh we have Kyle Cook, who's also known as WebDev, uh Simplified. Uh Julia Meiosene, Ben Hong, Brie Hall, Chris Koyer, Jason Langstar, Shawn Pearson, and Amy Dutton. this thing. Besides the site being cool as hell, Wes, this tournament, >> thank you. >> CSS.com. Go check it out cuz this was a really fun site to build and we are currently working on a way to pick your own bracket. So before this thing goes live, you're going to be able to log in to madcss.com >> and pick a bracket. And if you win, if you get it, if the the winner will be will get cash prizes. It's gonna be >> cash prizes, man. >> Maybe not cash, but prizes. >> Prizes. prizes that did cost cash at one point for us to make. So yeah, that that's kind of the crux of this thing. Um, you might be having deja vu right now because we have talked about this before. This was initially born out of my hack week project. So we'll talk a little bit about why this is different than what the hackw week [music] project was. And if you want to see all of the errors in your application, you'll want to check out Sentry at centry.io/sintax. You don't want a production application out there that well, you have no visibility into in case something is blowing up and you might not even know it. So, head on over to centry.iosax. Again, we've been using this tool for a long time and it totally [music] rules. All right, real quick. The stack here, the stuff we built this on, it's using spelt kit cuz >> hold on. Can you just show what it does visually first before we get into the stack? I think that will frame it a little bit better. Yes, >> cuz people might not know what a CSS battle is. >> Uh for people who are watching on video, you'll be able to see the UI. For people who are listening, we'll do our best. You know, I don't want to uh make this only a video only episode, but a CSS battle in terms of like what this is actually doing is people have a target, which is a thing that they were are coding towards, a thing that they are trying to recreate with CSS and HTML. And the way the CSS battles works is that you code your HTML and CSS and you try to get it as close as possible to the target and the person who gets there first to dead on 100% or gets the highest score where things are closest uh is the winner. So if you're looking at this on YouTube, you see right now my code which is up here in the top left. You see the target which is over here. Then uh we have a diff view and an overlay so you can see what's different. And then you even get access to your competitor's view. So that way when you're competing and you're coding you can see how far along they are to either stress you out or calm your nerves, slow you down. Um so that's the general crux of this is uh a a target is created with either a video, an image or CSS and HTML. Right now we're just using HTML and CSS targets. And again, we are comparing uh we'll talk quite a bit about the diffing part of it because that was a huge component of this. Um and again, this whole thing works real time. I'll talk about the tech involved to make this work and what's unique about it. So, am I am I free to talk about the stack now, Wes? >> Let's talk about the stack. People understand it. I think one more thing is that like the code that is being written, you'll notice there's no there's no code part, right? And that's because I hate hate hate writing code in some little text box on a website when I'm trying to be as fast as possible because none of my shortcuts are there. None of my tab completions are there and you just you just feel weird trying to to type as quickly as you can when you don't have all of your your comforts of what you are actually used to. So the important part about this synhack that we built is that you it uses local file system access and you just use your own editor, use your own tools, you use your own completions, all of that stuff locally on your computer and then it syncs that data from your file system to the Synhax platform. >> Yeah, it's pretty cool. We'll talk about how all that works too. Uh so the stack it's built in Spelkit cuz I started it and I love Spelkit. So easy choice for me. I also we need a server and a client. So this couldn't just be a UI client. This had to be a server and a client. Um and then we used zero sync. Now zero sync is a library for doing syncing. I'll talk a lot about how zero works after we talk about this stack just so people can understand why zero is so good. But zero gives us uh real time. It gives us really fast everything. Um it's it's really what allows this application to work the way it does as easily as it does. It's a great platform. Um I also use the zero spelt bindings. This is a uh spelt bindings that I wrote myself and I'd like to think that the syntax is really nice. I'd like to think that it all works really easily and it's very meteorike in how I like to work in it. So again, it's really trying to chase that dream of of having Meteor back in my life. Uh also Drizzle, it uses uh Drizzle for database uh schemas. We do have to have a schema for zero as well, but there is a drizzle zero package that takes your drizzle schema and translates it to directly to a zero schema without you having to do anything. So Drizzle great choice. Uh zero requires Postgress as a database. So just Drizzle Postgress. We have the database hosted on superbase for no reason other than ease of simplicity of getting something up and running for my hack week project. I I host zero apps on coolify using a Postgress database there. I do among all kinds of ways. So uh superbase not required. We're not using any of Superbase's libraries here. Um >> just needs a Postgress database. >> Just needs a Postgress database. I also have the basis for the CSS using graffiti. Now, we're not using a ton of graffiti stuff, but there's a number of like really nice graffiti utilities, whether that is like stacks or splitting or those types of things that come in handy. Uh we have a whole ton of colors in here, too. But, uh in classic Wes fashion, he's not a fan of uh any of the colors, so he just um overwrote all the colors himself, which is uh maybe the most common way of working with Wes. [laughter] I I I was actually frustrated with with a lot of this because >> yeah, >> you there was no like um docs for it in the codebase. >> Um and I just didn't know what a lot of the variables were. Um, and like I'm sure I could have could have looked them up as well, but like we we were on a huge time crunch >> and I did I did use quite a bit like over all the purple on it as well as I just overrode a lot of your variables. But then like things like the font sizes Scott loves to do this like >> minmax percent. >> Oh, the font size is everything scalable and like I was like how do I make this font bigger? And like there was there was no way to do that. So we just >> Yeah, you're just Yeah, I know. It's very systematized. For sure. >> It is. It's great until you need to step outside of the system. >> That's how they work, Wes. And actually, it's so funny after our conversation about what's missing from the web, you told me we could do tabs using details and summary, and I was like, I don't know. I I went through and actually added a full-on no JavaScript tabs using details and summary in here now, too. So that exists and tool tips via popover and anchor positioning. So I've been adding stuff to this kind of as I need it and uh for me because I use this on every project. I'm very familiar with it. So it was quite easy for me to say, "Oh, let's just use my thing that I'm very familiar with." [laughter] Um I I have been working on I don't I don't know if this is like a thing that even matters anymore, but like the LLM.txt txt is like really organized now where it's like if you need a tag [clears throat] come to the tag docs. If you need a boxes go to the boxes docs. Like it tries to do a good job of making the LLM work well with it. So something I've been focusing on a little bit. Um sync server. We run the sync server on fly.io. Why? Cuz I just needed to get it up somewhere. And if we're being entirely honest, I don't love fly.io. And it's not fly's fault. it's a skill issue. I just have the hardest time finding the things I need to find on there. Whether it's the logs or the whether did this deploy work or not or why didn't it work. Like I get really frustrated and I don't like how it's all set up. But you need a container somewhere for uh the sync server to run, like a longlasting container. And I typically run these on Koolifi, but my Koolifi server is over in Germany. and I wanted it to be faster here. So I I put it on fly.io and you know what just it's something I'll change at some point but now >> it works. Yeah, there is a somebody has implemented the sync server um in the zero docs as a cloudflare worker durable object which >> is really cool. So if you need it to be long running right um the cloudflare solution to that in the serverless world is durable object. So they have a zero in their docs has a an example that you can get up and running. But like we were so crunched for time. It was just like don't touch the things that are not broken, right? >> That's how it works, right? Sometimes things just exist as loadbearing blocks that you're like, you know what, this works right now. It took me a long time to set up. I'm not going to touch it. Uh definitely will move it to Cloudflare because the the server and the UI of this is running on Cloudflare workers just via the spelt kit Cloudflare adapter. So uh the actual app is running on on Cloudflare workers and then again we use the local file system as Wes mentioned when you first enter a battle or whatever it asks for a folder it creates that folder uh for the given thing and then you have code that you could just drop into your VS code and then start coding. Um, the way that that works in the the code here I is really kind of interesting where you connect to the file system and then you're storing that file system handle in indexed DB um and then having that persist as spelt state. It is a whole thing. Um, >> it's so fast though like it like for RCSS battles it's just as fast as like using V. like it just refreshes it immediately and everything is as soon as you hit save you can see what you're working on. >> Yeah. And let's talk about how that works because it is really interesting. I have uh like if the file has been changed it is just updating a database record but because of how zeroync works it's so fast and instant. So uh how does how does zeroync work really quickly kind of like no fluff here. Um, Zero is basically a platform with a sync engine as well as a clientside library to do the queries and stuff, a serverside library to do the server side stuff and then a sync server. So the big pieces, right? So you have the client um the client has versions client versions of the queries and the mutation functions. These things run on the client and take place instantly. So when you click something like I'm going to click new battle or something, it creates that battle instantly and saves it into your client side data using the client side queries and mutations code. Then in the background connects with a websocket to the zero cache sync server. that happens so that when I save it, the database knows what data has changed and it sends a patch message to the sync server. The sync server is a longunning uh server as we mentioned and that replicates Postgress to a SQLite replica file. It then basically determines what client rows have changed since the last updates and then sends a diff to your server. So basically the sync server is handling like what has changed and what messages I need to send back and forth and it does so with like I've mentioned diffs about like just what's changed. So it's not sending a massive amount of data on everything which is one of the reasons why zero is so fast. It's incredibly fast. Uh it's incredibly fast because it stores your data locally and therefore it can load it locally very quickly. It's incredibly fast because the data that it does send is in patch messages for updates and then that sends basically a message to the API that again lives on our app. So you have two pieces the app the sync server app sends to the sync server sync server sends back to the app and the API routes. Okay, that API server is really cool because that's where it processes the queries and mutations server side. This is where like O happens. This is where permissions happen and stuff like that. The way that >> all your like database like like to be clear, zero is not a database, right? Like it's like all of your rights eventually just happen in what? Like Drizzle updates. >> Yeah. Yeah. You're pretty much just writing Drizzle code to do those. Well, actually that's not true. No, you're writing Sorry. the the those mutations Wes are happening in the exact same code that is used in the client version of that is also that same code is used in the server versions of it just being run server side. >> Yes. But how it how it actually saves it to the database is not part of of zero, right? Like it eventually zero will then translate it to what the zero drizzle adapter and then save that to the Postgress. No, the drizzle zero uh adapter is only getting giving us the schema translation. So um >> Oh, so if you wanted to access the database directly with the same schema. >> Yes, correct. >> Okay, I was wrong then. Yeah, in fact, I can even show you the database inserts are happening in a a transaction. So it this is this is actual zero code. If you're looking at the screen, you can see it. This is the zero code that is doing the insert. So it is very similar to an OM type of thing. You're doing uh TX which is the um transaction.mmutate dot the table.insinsert and you're just passing your data in there. So uh very similar to how you would do it using any kind of OM here. Really nice. Uh so the the way that O works, the way that it used to work was kind of a giant PIA. There was a the whole schema file. You had to write all of your permissions and off code in a in your schema file in a like a real hot potato way. And then there was a a zero process that you had to then apply that permissions and o stuff to your sync server itself. And the sync server was the thing that was doing all of this code. It was doing all the mutations and stuff for you. the way that they have since changed it is like, oh, you know what would be way easier than having the sync server try to manage all that stuff? Uh, if you just got to write a route that collected all of those queries or collected all of those mutations in your own application and just apply them in your own code. The reason why that's more simple is because uh you can handle O the same way that you would handle O if it if there was no sync server involved. So like >> and probably a lot of people that are are adding this to their app it maybe this is great if it's like a green field app right but if you're trying to like just add sync to an existing >> oh yeah >> database or existing application you probably already have all of your own authentication permissions code. So now you would just to incrementally adopt that. You're just creating those API routes and you're doing whatever incremental ones you want. It it's really kind of great and you are just essentially taking our off system is being done in in middleware like you typically do in a spelkit app. It's being passed along immediately to any of the routes that exist and we're just hot potatoing that into the context inside of zeroync. then zero sync has your user off stuff in context. It way simplified everything. And if our o if our our sync server and everything lived on the same uh URLs and servers, it would have been way easier because we could have just used HTTP only cookies, but we had to do the whole bearer off thing and that was obnoxious. Um [laughter] yeah. >> Oh, I should say we're using better off for this too. Better off to do the uh Google Oth and that's it. Um but better off is involved as well. Um, one question I often get about zero sync in regards to it being local first or any of that stuff is like why is it one not local first and two offline and like data conflicts and CRDT kind of stuff. So it's not local first because Zero's really moved away from the idea of it being a good platform for offline. they've kind of determined that offline for this is less useful and less where they want to go with it. So because of that local first is still always going to be the app should work purely offline. You should own your own uh data. It should be easily encrypted. It um you know there can be a sync process that syncs that data and stuff like that. Uh but I think the zero folks kind of realize that this system can still be very very impressive, very fast. Um load your data locally from that index DB while not necessarily focusing on offline or conflict resolution. Uh the way that the conflict resolution does work, so let's say Wes and I both edit the same row at the same time. uh both of the updates happen locally on our own machines. Then those messages get sent to the sync server. That server basically commits those in the order that they were received. So one of them might override the second one if it comes in afterwards. So basically what happens is I send a message, Wes sends a message, the first one that arrives gets applied first, the next one then gets applied, but then the sync server basically understands uh what the actual convergence is there and then sends the data back out to everybody. So then someone's data isn't going to be stale if we both write the same thing. >> I write I write. I think that's that's one killer feature that we haven't mentioned yet is this is all entirely real time um whenever I would make an update to anything or when like sometimes um Scott would create a new battle and then invite me and it would just immediately pop up on my dashboard without having to to do a refresh and there was no polling or anything involved there. simply just was, oh, this data has now changed. So, this view requires this data and it just immediately updates. >> Can I can I start a battle with you to kind of show that off how that works? >> Sure. Yeah. Uh, let me let me go log in here. >> Okay. Folks who are listening on audio, you're not going to be we we're not going to just like leave you hanging here. Uh, but I am going to just uh create a quick battle. I'm inviting Wes to it. his automatically shows up. And I just want to show you really quick how the file system stuff works or at least talk through it. I want to uh talk through the general saving flow so you can really truly see uh how fast and impressive this all is. So I joined a battle. It created this folder for me just by joining the battle which is the the files. You can see how many we've done to test. I'm going to drop this into uh VS Code. And you can see I have HTML and CSS just kind of here. These are the files that you will then edit for when you do the B battle. We're both locked into the battle. We can click lock in players. Okay, so I have a couple of views here. We have the referee view where it can show both people kind of side by side. Here we also have the lobby which allows you to uh press play and get going on a battle. Can I start a battle if I'm a competitor? >> Um, no. You shouldn't be able to. You might be able to, but you shouldn't be able to. >> But if I'm the referee and the competitor, >> yes, you can. That's that's how most of our testing has has worked. >> So, just to show people really quick, just generally when I'm typing in my code editor on the local file, I can do background uh background red. Save it. And you can see the moment I hit save, it updated. And then Wes is also going to be seeing those changes in real time. Wes, do you want to make a change to yours? And we can see Wes's competitor view. Um, again, the way this is working is that when I have a file save, it triggers a uh a basically a function call on zero that runs the mutation. The sync server reconciles that real time, sends the updates out to everybody. That way the first person to get to 100% is the winner. Uh and these updates you can see are just happening in real time. Our progress bars. It is really really really slick and the whole system just works really super great. Let's talk about the hack week version of this project. You may have remembered us talking about this. The way that this platform used to work is that there was voting involved. Um, there was three people going at once. And what we really needed to do is transform this from being like a three people and a subjective winner to being two people at once and an objective winner, which is uh done via diffing, which Wes is going to have to go deep on. 02.5 also changed how they do permissions and all this stuff. So, the app needed to be re and in fact, I was talking to Courtney about this. I think this would have been easier to write from scratch than it would have been to me to adapt the hack project. Between the changes in Zero, the changes in how battles are run and operated, I ended up probably rewriting most of it before you ended up getting involved, Wes. Like, yeah, >> I I should have just started from scratch and just kept the the general concepts because there was so much uh that needed to change. And then the biggest one of those changes being when you came in and brought in the diffing algorithm. Do you want to uh share a little bit about how you managed to do that? >> Yeah. Yeah. So this is one problem that we have with the CSS battles platform is that it's like you can get so close and then there's like one weird thing and I think the way that the CSS battles diffing algorithm works is that it sends your code to the server. They probably have like Chromium running. it takes a screenshot and then diffs it against the the actual target. We wanted that to h happen in browser. Um both so that any quirks between your browser or whatever are are gone because your target and your actual thing that's running, those are both running in the exact same browser. So whatever browser is actually computing the score is is going to be rendering them out exactly the same, which is really helpful. So what we did is I ended up using this package called snapdom. You may have used HTML to canvas in the past. So this there's like a way better version now called snapdom. And it essentially you just give it a uh an HTML element on the page and it will then convert that to um like a canvas and then export it as like a PNG or SVG. The way that it actually works is really interesting to me is that they take your HTML, put it inside an SVG foreign object tag, and then I think since since it's then an SVG, which is an image, you can then write the image to the canvas, right? So like it doesn't have to like do a whole bunch of I think that's how it works. There is a lot of like gotchas and stuff. I had a couple bugs that I burned a day on, but we got it all working and it it works really well. And then the actual diffing algorithm itself. Um we went through several different ways to like figure out are these things close enough, right? Um so like we tried using vectorization, you know, vectorize the images and see how close they are. And most vectorization LLMs will care about what is in the like like if there's a dog in it, right? Or if there if there's a red dress in it, and they don't necessarily care about pixels that much, right? M >> and then there's other things called SSSIM which is structural similarity index measure which is how how similar are two images to each other. Um that worked okayish but it still wasn't um good enough to making it close enough to pixel perfect cuz we we didn't want it to be pixel perfect but we wanted to be close enough whereas if you had like a weird like outline on something and that would make you lose the whole thing. So, I think we I probably went through like six or seven different iterations of it. We finally landed on >> one that had different thresholds. Um, Scott, if you Yeah, you can see the diffing engine in the bottom right here. >> Um, it has different thresholds, um, different three different algorithms in there, different weighting of different colors. If something is has like a bit of opacity in it, it weighs it weights it a little bit less. Um, and we finally landed on something where like this feels this feels really good. What else? Oh, yeah. The the big issue we had was like the simply putting the background color on one of these things would get you to like 98%. And we just it's because like a lot of times the background did account for 98% of the pixels. So, we ended up writing something where you could just punch out the background color from each of the targets and then not dock them or count them, right? It just it just takes those pixels out of the equation entirely. And then that also helps with things like box shadow and whatnot where if the box shadow wasn't perfect, it was just it was close enough and then we we'd give you some points for that. So, that was pretty fun. And then we also built these um like a diff viewer where it shows you if if you click on the diff viewer there, you can see like red is significantly different whereas like greens and blues are are not as um not losing you as many points. So if you're looking at your diff and you're you're like what should I spend time on? You go you want to go for the red stuff, right? Um and then we built this little overlay thing where you you can do it kind of like side by side. If you just click on it, you can see exactly where yours is overlaid the target. >> Yeah. And that that overlay view I think is really uh I think it's all really helpful. One of the things that I think helped with this is that we have done so many CSS battles that we were like I know what I would want different on this platform. Like I I know like what's working and what's not working for us. And that allowed us for like specifically this overlay. um you really liked the overlay and wanted it automatically, whatever, but I didn't like how it was automatic and then you came up with this idea to pull and drag. And I do love the little border and drop shadow you gave on this. And then >> I use that all the time. >> You can use that with the opacity to really dial it in. I find that the the tools to be really nice for all of this. Um I found using the dev tools to be nice in this this entire process. the the diffing stuff. I will say folks, the way that we dialed in the diffing everything was from sheer hog >> running. >> We ran so many tests and every time we did a test and we thought we had it >> like something weird would come up where like CJ would put a div >> like that would cover the entire thing and like that technically is not a background color. That's a div with a with a background color. Um, so then we had to write something else that would detect what the background color is, even if it's not the body background color. And then we also implemented uh Tailwind CSS support. So that had to that had to be thrown in there as well. Um, you had to um the sandboxing was really neat. I was like, yeah, people like like one thing you could do early on was you could just write a script tag in your HTML and then it would execute that on everybody else's computer. >> Yes. Um, and I was like, man, we got to like run this through like a sanitizer or whatever. But like iframes, these are all iframes. Iframes have a sandbox attribute where you can allow and disallow things. So what we did is we disallowed inline script tags or no, we allowed JavaScript because we needed the Tailwind um CDN to load and and and compute the Tailwind code. But then we used a um a CSP content security policy where we did a really good episode with Alex Ston from Stripe on CSP. But basically via header tags or or headers on your HTML element, you can say what resources are allowed to be loaded in. So you're only allowed to load script tags from one specific URL and that is the Tailwind um CDN for for their JavaScript library. Um, and then otherwise you're not allowed to do any inline JavaScript. You're not allowed to There's several other things you're not allowed to do. Um, and that worked out well. >> Yeah. Yeah, it really worked out well. I I think this whole thing, like I mentioned, like so much of it came down to us using it and using it and trying it and hitting bugs and hitting errors. We for an entire week were just like, "All right, every single morning we're going to use it. We're going to test it out. We're going to write down all of the the amount of bugs that we have. We're going to fix those all and we're going to come back the next day. And I think it was like so the battles were starting Monday and I think it was like Thursday that I was starting to feel maybe a little bit nervous about it because it still felt like we were logging so many things. But at that point, the diffing engine had really come together. Things had really started and I was recovering. >> Diffing engine. It was Friday at 3:00 and you guys are like, "Well, let's maybe like um change how everything works." I was like, "Guys, >> we have two hours." But l luckily we could we could reuse a lot of the other um background color stuff for the transparency. >> Yeah. And there it is tough because you you end up in this um um spot of like is it good enough? Is it going to cause problems? Like there were so many times where it felt like it was good enough, but like we wanted it to be really special, I think. And >> I think that ended up really working out because at the end of the day, the entire thing like this right here, if you're looking at the screen, you can see my diff right now says I'm at 99.31%. I would say this darn looks about 99.31%. And we spent so much time like making sure that percentage and I will say Wes spent so much time making sure that percentage matched what you would expect. Man, I I have a newfound appreciation for people that develop like like the algorithm for like like Tik Tok or or Twitter or something like that because you turn one knob >> like like that example of of those little lines right there is like, oh well, we can we can relax um like pixels that are like maybe maybe it's a one pixel diff, you know, and and if the pixel to the north and the south of it or or the east and the west of it are are bang on, then maybe we just allow that one, you know, but you turn one knob and then all of a sudden something else changes and you turn another knob and and we had so many different test cases to to go through. Um but like it really makes me appreciate people who write these algorithms for like Twitter, you know, like every week Twitter's showing you all kinds of new garbage. Yeah. >> And you're just like, man, they probably turned one knob and then all of a sudden something else is is totally out of whack. >> Yeah. Totally. I I uh some of the biggest bugs that we had besides just like dialing in the diffing, we kept getting the sync engine would just start randomly saying that you were unauthorized. And this one was tough because you never knew if it was like where the the bug was like what was the issue? Um because it's happening on the sync server and yeah, we're combing through logs and we're adding uh we have Sentry in here. We're checking Sentry and the issue ended up being that the cookie that stored our O token was longlasting and the JWT had an expiry [snorts] of 15 minutes. So if we had been working on it for 15 minutes, it would suddenly in the sync process tell you, "Oh, by the way, uh you're not authorized anymore." Um which was a tough tough bug to find. And luckily, uh, we all have good enough fundamentals that we kind of were able to break down step by step where could this be and CJ was the one that had the idea to be like, you know what, I got to check this JWT to see like what's going on here. And he discovered the 15 minutes expiry time. Um there's a a tough thing there with that expiry time because the way that the sync engine works for you to update that JWT with the sync engine in how we are doing it you would have had to like tear down and rebuild the zero client instance and that might have been fine but we were like too late in the process for me to be like oh yeah in the middle of the battle let's just tear down and rebuild the sync instance and hope that everything works fine. Uh I felt like that would have been opening up a door to potential bugs and issues. So the solution for us was just to make that JWT uh longerl lasting at least before um these battles to get through this before you know taking fix it for like a proper refresh um behind the scenes. >> Totally. >> Like like you shouldn't have to refresh the page for it to work eventually, but like >> it was close and we got her done. >> Yeah, that was a tough bug. I don't When did we push that uh update? That was like day of what? I was done on Friday when you guys had pushed it, you know, like that was after hours for for Eastern time zone. So, it was it was pretty close and we started on Monday. So, >> yeah, we did one final run through on Monday morning and the first battles started on Monday. Uh, keep in mind we had to do all of this while keeping Wes and I in the dark about the the challenges, the nature of the challenges. So, a lot of the data that we were working with, the test data and stuff like this often times were like intentionally not what we were going to be anywhere near in the tournament because we already have enough of a home field advantage from doing CSS battles with each other that like we didn't want any sort of advantage for us in this tournament. It's, you know, I I want to win. >> I speak for yourself. I want all of the advantages. >> Well, I want to I want to win fair, Wes. If I win, I want to win fair. Uh we should say at the time of recording this >> about getting knocked out. >> Yes, the battles haven't really taken place. Uh and uh so >> you'll see about an hour for my first one and I'm >> feeling a bit nervous. >> Oh, I was nervous. I think everybody's been nervous. >> We got these sick jackets, though. Um so I'm not sure when this one comes out, but the March, the beginning of March is when this will start. And I think there's five videos that will play out through the rest of March. Um, madcss.com. We have these jackets you can buy. It's really cool. Look at this syntax in the liner. It's all embroidered. We got the Mad CSS logo. We got syntax on the arm here. This is like the sickest jacket in the world. Really nice snaps, too. Big fan. So, >> it's so cool. If you want to grab one of these, go to um by the time you're listening to this, they probably won't be up in the store just yet, but stay tuned because you you'll be able to grab one. Yeah. And if you subscribe to this channel, like, subscribe, all that stuff. Uh not only are you going to get to see the battles, which are going to be a ton of fun, but you're going to get to uh be aware of that kind of stuff. There's also a really, really cool water bottle that we have for this tournament, and generally cool stuff. Um this incredible logo designed by Caitlyn Bloom on our team. Uh, we've been rocking this thing on all kinds of stuff. So, like Oh, I've been I just been Oh, yeah, baby. Look at that. Wes has got a 3D printed one, I think. Did you make that yourself? >> Yeah, I did. It surprisingly hard. >> I don't have the orange. I want to make one. >> I know. I was surp The orange is not exactly the color orange, but it was close enough. This was the first run at it, so it looks sick, though. I'm like, [snorts] this is so cool. Caitlin did an awesome job. So, while we were doing this, the rest of the syntax team was doing their own crazy amount of stuff. Whether that's like uh 3D backgrounds for the the um CD CJ has a commentator view or >> it's going to be nuts. >> It's going to be nuts. This is a fullcourt press to keep up with the basketball theme here. Uh fullcourt press on everybody doing incredible work. So, shout out to the entire syntax team for making this happen. Keep your eyes peeled for Mad CSS on YouTube. Uh, it is going to be an absolute blast and I sincerely hope that I walk away with the trophy. That is what I hope. >> I'm going to win [clears throat] easy. >> I'm not going to win. >> I would beat you. I always beat you sometimes. >> Yes. [snorts] Always. Sometimes. [gasps] >> All right. Matt CSS.com. Subscribe. It's coming in March. It's going to be amazing. Peace. Peace., We built a CSS Challenge platform, YouTube, 01kh1zhp5s1tgz3h1v05bpwsvt.