Jump to content

All Activity

This stream auto-updates

  1. Today
  2. by: Temani Afif Fri, 30 May 2025 13:45:43 +0000 Ready for the second part? We are still exploring the shape() function, and more precisely, the arc command. I hope you took the time to digest the first part because we will jump straight into creating more shapes! As a reminder, the shape() function is only supported in Chrome 137+ and Safari 18.4+ as I’m writing this in May 2025. Sector shape Another classic shape that can also be used in pie-like charts. It’s already clear that we have one arc. As for the points, we have two points that don’t move and one that moves depending on how much the sector is filled. The code will look like this: .sector { --v: 35; /* [0 100]*/ aspect-ratio: 1; clip-path: shape(from top, arc to X Y of R, line to center); } We define a variable that will control the filling of the sector. It has a value between 0 and 100. To draw the shape, we start from the top, create an arc until the point (X, Y), and then we move to the center. Yes! Unlike the polygon() function, we have keywords for the particular cases such as top, bottom, left, etc. It’s exactly like background-position that way. I don’t think I need to detail this part as it’s trivial, but it’s good to know because it can make your shape a bit easier to read. The radius of the arc should be equal to 50%. We are working with a square element and the sector, which is a portion of a circle, need to fill the whole element so the radius is equal to half the width (or height).1 As for the point, it’s placed within that circle, and its position depends on the V value. You don’t want a boring math explanation, right? No need for it, here is the formula of X and Y: X = 50% + 50% * sin(V * 3.6deg) Y = 50% - 50% * cos(V * 3.6deg) Our code becomes: .sector { --v: 35; /* [0 100] */ aspect-ratio: 1; clip-path: shape(from top, arc to calc(50% + 50% * sin(var(--v) * 3.6deg)) calc(50% - 50% * cos(var(--v) * 3.6deg)) of 50%, line to center); } CodePen Embed Fallback Hmm, the result is not good, but there are no mistakes in the code. Can you figure out what we are missing? It’s the size and direction of the arc! Remember what I told you in the last article? You will always have trouble with them, but if we try the different combinations, we can easily fix the issue. In our case, we need to use: small cw. CodePen Embed Fallback Better! Let’s try it with more values and see how the shape behaves: CodePen Embed Fallback Oops, some values are good, but others not so much. The direction needs to be clockwise, but maybe we should use large instead of small? Let’s try: CodePen Embed Fallback Still not working. The issue here is that we are moving one point of the arc based on the V value, and this movement creates a different configuration for the arc command. Here is an interactive demo to better visualize what is happening: CodePen Embed Fallback When you update the value, notice how large cw always tries to follow the largest arc between the points, while small cw tries to follow the smallest one. When the value is smaller than 50, small cw gives us a good result. But when it’s bigger than 50, the large cw combination is the good one. I know, it’s a bit tricky and I wanted to study this particular example to emphasize the fact that we can have a lot of headaches working with arcs. But the more issues we face, the better we get at fixing them. The solution in this case is pretty simple. We keep the use of large cw and add a border-radius to the element. If you check the previous demo, you will notice that even if large cw is not producing a good result, it’s filling the area we want. All we need to do is clip the extra space and a simple border-radius: 50% will do the job! CodePen Embed Fallback I am keeping the box-shadow in there so we can see the arc, but we can clearly see how border-radius is making a difference on the main shape. There is still one edge case we need to consider. When the value is equal to 100, both points of the arc will have the same coordinates, which is logical since the sector is full and we have a circle. But when it’s the case, the arc will do nothing by definition and we won’t get a full circle. To fix this, we can limit the value to, for example, 99.99 to avoid reaching 100. It’s kind of hacky, but it does the job. .sector { --v: 35; /* [0 100]*/ --_v: min(99.99, var(--v)); aspect-ratio: 1; clip-path: shape(from top, arc to calc(50% + 50% * sin(var(--_v) * 3.6deg)) calc(50% - 50% * cos(var(--_v) * 3.6deg)) of 50% large cw, line to center); border-radius: 50%; } Now our shape is perfect! And don’t forget that you can apply it to image elements: CodePen Embed Fallback Arc shape Similar to the sector shape, we can also create an arc shape. After all, we are working with the arc command, so we have to do it. We already have half the code since it’s basically a sector shape without the inner part. We simply need to add more commands to cut the inner part. .arc { --v: 35; --b: 30px; --_v: min(99.99, var(--v)); aspect-ratio: 1; clip-path: shape(from top, arc to calc(50% + 50% * sin(var(--_v) * 3.6deg)) calc(50% - 50% * cos(var(--_v) * 3.6deg)) of 50% cw large, line to calc(50% + (50% - var(--b)) * sin(var(--_v) * 3.6deg)) calc(50% - (50% - var(--b)) * cos(var(--_v) * 3.6deg)), arc to 50% var(--b) of calc(50% - var(--b)) large ); border-radius: 50%; } From the sector shape, we remove the line to center piece and replace it with another line command that moves to a point placed on the inner circle. If you compare its coordinates with the previous point, you will see an offset equal to --b, which is a variable that defines the arc’s thickness. Then we draw an arc in the opposite direction (ccw) until the point 50% var(--b), which is also a point with an offset equal to --b from the top. I am not defining the direction of the second arc since, by default, the browser will use ccw. CodePen Embed Fallback Ah, the same issue we hit with the sector shape is striking again! Not all the values are giving a good result due to the same logic we saw earlier, and, as you can see, border-radius is not fixing it. This time, we need to find a way to conditionally change the size of the arc based on the value. It should be large when V is bigger than 50, and small otherwise. Conditions in CSS? Yes, it’s possible! First, let’s convert the V value like this: --_f: round(down, var(--_v), 50) The value is within the range [0 99.99] (don’t forget that we don’t want to reach the value 100). We use round() to make sure it’s always equal to a multiple of a specific value, which is 50 in our case. If the value is smaller than 50, the result is 0, otherwise it’s 50. There are only two possible values, so we can easily add a condition. If --_f is equal to 0 we use small; otherwise, we use large: .arc { --v: 35; --b: 30px; --_v: min(99.99, var(--v)); --_f: round(down,var(--_v), 50); --_c: if(style(--_f: 0): small; else: large); clip-path: shape(from top, arc to calc(50% + 50% * sin(var(--_v) * 3.6deg)) calc(50% - 50% * cos(var(--_v) * 3.6deg)) of 50% cw var(--_c), line to calc(50% + (50% - var(--b)) * sin(var(--_v) * 3.6deg)) calc(50% - (50% - var(--b)) * cos(var(--_v) * 3.6deg)), arc to 50% var(--b) of calc(50% - var(--b)) var(--_c) ); } I know what you are thinking, but let me tell you that the above code is valid. You probably don’t know it yet, but CSS has recently introduced inline conditionals using an if() syntax. It’s still early to play with it, but we have found a perfect use case for it. Here is a demo that you can test using Chrome Canary: CodePen Embed Fallback Another way to express conditions is to rely on style queries that have better support: .arc { --v: 35; --b: 30px; --_v: min(99.99, var(--v)); --_f: round(down, var(--_v), 50); aspect-ratio: 1; container-name: arc; } .arc:before { content: ""; clip-path: shape(from top, arc to calc(50% + 50% * sin(var(--_v) * 3.6deg)) calc(50% - 50% * cos(var(--_v) * 3.6deg)) of 50% cw var(--_c, large), line to calc(50% + (50% - var(--b)) * sin(var(--_v) * 3.6deg)) calc(50% - (50% - var(--b)) * cos(var(--_v) * 3.6deg)), arc to 50% var(--b) of calc(50% - var(--b)) var(--_c, large) ); @container style(--_f: 0) { --_c: small } } The logic is the same but, this feature requires a parent-child relation, which is why I am using a pseudo-element. By default, the size will be large, and if the value of --_f is equal to 0, we switch to small. CodePen Embed Fallback Note that we have to register the variable --_f using @property to be able to either use the if() function or style queries. Did you notice another subtle change I have made to the shape? I removed border-radius and I applied the conditional logic to the first arc. Both have the same issue, but border-radius can fix only one of them while the conditional logic can fix both, so we can optimize the code a little. Arc shape with rounded edges What about adding rounded edges to our arc? It’s better, right? Can you see how it’s done? Take it as a small exercise and update the code from the previous examples to add those rounded edges. I hope you are able to find it by yourself because the changes are pretty straightforward — we update one line command with an arc command and we add another arc command at the end. clip-path: shape(from top, arc to calc(50% + 50% * sin(var(--_v) * 3.6deg)) calc(50% - 50% * cos(var(--_v) * 3.6deg)) of 50% cw var(--_c, large), arc to calc(50% + (50% - var(--b)) * sin(var(--_v) * 3.6deg)) calc(50% - (50% - var(--b)) * cos(var(--_v) * 3.6deg)) of 1% cw, arc to 50% var(--b) of calc(50% - var(--b)) var(--_c, large), arc to top of 1% cw ); If you do not understand the changes, get out a pen and paper, then draw the shape to better see the four arcs we are drawing. Previously, we had two arcs and two lines, but now we are working with arcs instead of lines. And did you remember the trick of using a 1% value for the radius? The new arcs are half circles, so we can rely on that trick where you specify a tiny radius and the browser will do the job for you and find the correct value! CodePen Embed Fallback Conclusion We are done — enough about the arc command! I had to write two articles that focus on this command because it’s the trickiest one, but I hope it’s now clear how to use it and how to handle the direction and size thing, as that is probably the source of most headaches. By the way, I have only studied the case of circular arcs because, in reality, we can specify two radii and draw elliptical ones, which is even more complex. Unless you want to become a shape() master, you will rarely need elliptical arcs, so don’t bother yourself with them. Until the next article, I wrote an article for Frontend Masters where you can create more fancy shapes using the arc command that is a good follow-up to this one. Footnotes (1) The arc command is defined to draw elliptical arcs by taking two radii, but if we define one radius value, it means that the vertical and horizontal radius will use that same value and we have circular arcs. When it’s a length, it’s trivial, but when we use percentages, the value will resolve against the direction-agnostic size, which is equal to the length of the diagonal of the box, divided by sqrt(2). In our case, we have a square element so 50% of the direction-agnostic size will be equal to 50% of sqrt(Width² + Height²)/sqrt(2). And since both width and height are equal, we end with 50% of the width (or the height). ⮑ Better CSS Shapes Using shape() — Part 2: More on Arcs originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.
  3. by: Abhishek Prakash Fri, 30 May 2025 17:30:45 +0530 An interesting development came from Microsoft as it released a new terminal-based editor with open source license. I kind of liked it at first glance until I tried my hands on a shell script written in this editor and then I ran into: The issue is that it added the classic Windows-style line endings, which is not liked by UNIX-like systems. I knew it was too good to be true to have something perfect for Linux from Microsoft 🤦 Here are the highlights of this edition : Open-source notification Inbox infrastructureListmonk newsletterHistorical view of system resource utilizationBang bang... shebangAnd memes, news and tools to discover🚀 Level up your coding skills and build your own botsHarness the power of machine learning to create digital agents and more with hot courses like Learning LangChain, The Developer's Playbook for Large Language Model Security, Designing Large Language Model Applications, and more. Part of the purchase goes to Code for America! Check out the ebook bundle here. Humble Tech Book Bundle: Machine Learning, AI, and Bots by O’Reilly 2025Master machine learning with this comprehensive library of coding and programming courses from the pros at O’Reilly.Humble Bundle       This post is for subscribers only Subscribe now Already have an account? Sign in
  4. Yesterday
  5. by: Abhishek Prakash Thu, 29 May 2025 04:29:31 GMT Important thing first. Ubuntu 20.04 LTS version will be reaching its end of life on 31st May. It was released in April 2020 and had a standard support of five years. Please check your Ubuntu version and if you are using 20.04, you can: Do a fresh installation of Ubuntu 24.04 LTS to get the latest packages.Upgrade to Ubuntu 22.04 LTS from your existing 20.04 installation, keeping your files intact.Opt for Ubuntu Pro, which will ensure you get essential security patches until 2030 but no new software.Ubuntu 20.04 LTS is Reaching End of Life — Here are Your OptionsUpgrade or sign-up for extended support before it is too late!It's FOSS NewsSourav RudraTime to plan your update. 💬 Let's see what else you get in this edition A new Linux kernel release.File permission in Linux.GNU Taler payment system being approved for Swiss use.And other Linux news, tips, and, of course, memes!This edition of FOSS Weekly is supported by PikaPods.❇️ PikaPods: Enjoy Self-hosting Hassle-freePikaPods allows you to quickly deploy your favorite open source software. All future updates are handled automatically by PikaPods while you enjoy using the software. PikaPods also share revenue with the original developers of the software. You get a $5 free credit to try it out and see if you can rely on PikaPods. PikaPods - Instant Open Source App HostingRun the finest Open Source web apps from $1.20/month, fully managed, no tracking, no ads, full privacy. Self-hosting was never this convenient.Instant Open Source App Hosting📰 Linux and Open Source NewsGNU Taler has officially entered the Swiss market.Linux kernel 6.15 is here with a Rust-based NVIDIA driver.SteamOS now officially supports more handhelds than just the Steam Deck.Qt has introduced Qt Bridges, a new piece of tech for bridging Qt applications with other frameworks and programming languages.Rhino Linux's new UBXI KDE Desktop doesn't disappoint. Hands-On with Rhino Linux’s New UBXI KDE 6 DesktopRhino Linux’s first UBXI port is here!It's FOSS NewsSourav Rudra🧠 What We’re Thinking AboutCarmen from Mission Libre has started a petition to get Qualcomm to release fully-free drivers for their in-production chipsets. If the petition is signed by 5,000 people, a hardcopy of the petition and signatures will be mailed to Qualcomm's head office. We can get 5,000 signatures, can't we? Home | Tell Qualcomm: Publish Free Drivers for Modern Wi-Fi Chipsets!Tell Qualcomm: Publish Free Drivers for Modern Wi-Fi Chipsets!🧮 Linux Tips, Tutorials and MoreVS Code on Arch is possible and easy.Understand the concept of file permission. It's a must-know for Linux users.Want more from Obsidian? Our plugin guide can be helpful.Looking for some note taking apps suggestion? We have an extensive list. Top 16 Best Note Taking Apps For Linux [2025]Plenty of amazing note-taking apps for Linux. Here’s what we recommend you to check out.It's FOSSAnkush Das Why should you opt for It's FOSS Plus membership: ✅ Ad-free reading experience ✅ Badges in the comment section and forum ✅ Supporting creation of educational Linux materials Join It's FOSS Plus 👷 Homelab and Maker's CornerWhile it is a proprietary piece of hardware, Flexbar can be a nice addition to your Linux setup. Miss Apple’s Touch Bar? Flexbar Brings This Experience to LinuxWhile Apple has discontinued the Touch Bar, Linux users can now enjoy the same experience with Flexbar.It's FOSS NewsSourav RudraAlso, learn a thing or two about MCP servers, the latest buzzword in the (AI) tech world. ✨ Apps HighlightIf you ever wanted to run an operating system inside your browser, then Puter is the solution for you. It is open source and can be self-hosted as well. Puter is a Complete, Fully Functional OS that Runs in Your Web BrowserRun an operating system straight from your browser.It's FOSS NewsSourav RudraAn It's FOSS reader created an FFmpeg AAC Audio Encoder Plugin for DaVinci Resolve. This will help you get effortless AAC audio encoding on Linux if you use DaVinci Resolve video editor. 📽️ Videos I am Creating for YouI tried Microsoft's new terminal editor on Linux! I hate to admit it but I liked what I saw here. This is an excellent approach. I wonder why Linux didn't have something like this before. See it in action 👇 Subscribe to It's FOSS YouTube Channel🧩 Quiz TimeCan you identify all the GitHub alternatives in this puzzle? GitHub Alternatives: PuzzleSolve this puzzle by figuring out the alternatives to GitHub!It's FOSSAnkush Das💡 Quick Handy TipIn Xfce, you can use the panel item "Directory Menu" to get quick access to files from anywhere. This is like the Places extension in GNOME, but better. In the configuration menu for it, provide the file extension in the following format *.txt;*.jsonc as shown in the screenshot above to access the files quickly. Clicking on those files opens it in the default app. 🤣 Meme of the WeekThe ricing never stops! 👨‍💻 🗓️ Tech TriviaOn May 27, 1959, MIT retired the Whirlwind computer, a groundbreaking machine famous for pioneering real-time computing and magnetic core memory. 🧑‍🤝‍🧑 FOSSverse CornerProFOSSer Sheila is having an issue with MX Linux, can you help? MX Linux / XFCE missing desktop background image!I am at a loss as to how to fix a new issue on MX-Linux Xfce that started about 30 min ago. I was working on things and my windows are always only expanded far enough right so that I can still see my Conky (top-right on desktop). I clicked outside the window on Conky and it disappeared. So did the background image. Later, switching workspaces, I found the same was true on all of them and when I right clicked on the desktop, no context menu. I went in to the desktop settings and tried to apply a…It's FOSS CommunitySheila_Flanagan❤️ With loveShare it with your Linux-using friends and encourage them to subscribe (hint: it's here). Share the articles in Linux Subreddits and community forums. Follow us on Google News and stay updated in your News feed. Opt for It's FOSS Plus membership and support us 🙏 Enjoy FOSS 😄
  6. Last week
  7. by: Women in Tech Wed, 28 May 2025 21:38:08 +0000 In this Q&A, we sit down with Tina Schniebs, Board Treasurer for Women in Technology (WIT) and a digital finance risk management Deputy Director at Ridgeline International. She shares her insights on the Leadership Foundry, her journey through the program and advice for women considering board service. Tina Schniebs, WIT Treasurer and Chair, Finance Committee Can you start by telling us a bit about your roles with WIT and Ridgeline International? At WIT, I serve as the Board Treasurer, overseeing the Finance Committee and ensuring our financials run smoothly. In my day job, I work in digital finance risk management, where I teach, consult and speak on how digitizing finance impacts our everyday lives and our federal, defense and intelligence communities – and how they can use technology, both offensively and defensively, to achieve their mission objectives. What is the Leadership Foundry and how did you get involved? WIT’s mission is to empower women in technology from the classroom to the boardroom, guiding women from early career stages through executive leadership and board service. The Leadership Foundry fulfills the second part of that mission. When I first heard about it, I had just started a business. I was heavily focused on getting it up and running, so I knew I was not yet in a position to take on a board seat within the company that we had grown. The program seemed like a great opportunity to better understand what board service entails and get connected with other organizations that are looking for board members with experience bringing up a small business successfully. How has the program evolved over time and how did the new certification enhance your experience? I first joined during COVID, which was challenging due to the virtual format, but the program has since evolved to include a board certification, providing a clear focus on preparing participants for actual board roles. The changes that they made for this new cohort really nailed down the point of the experience – it’s not just learning what being a board member is like, but actually wanting to be on a board and being prepared to do it. While the certification isn't strictly necessary, it adds value by clearly defining the purpose of the Leadership Foundry for participants. It provides a structured curriculum and connects participants with a network of people as part of the National Association of Certified Directors (NACD), helping women access board opportunities. It’s not just about learning what a board is; it's about preparing to serve on one. Can you describe the structure of the Leadership Foundry program? The program includes monthly in-person meetings featuring guest speakers with board experience, covering topics like private company boards, venture funding and public board challenges. There’s also a weekly virtual study group to discuss the certification material, fostering a collaborative learning environment. My cohort was small, with just six women, which allowed for close networking. My cohort of women were very much ready to do board service, or had done some sort of board service in the past. So they were very focused on, I want a public company board seat – I'm looking for access to that board seat. How do I get that? What's the networking that I need to do? What does public company service look like versus private company service? What's the difference between a non-profit board and a for-profit board? How did the program help you grow professionally? The most transformative aspect was learning to shift my mindset from executive decision-making to board-level thinking. Being an executive doesn't necessarily prepare you for a board role, where the focus is on risk management and strategic oversight rather than day-to-day operations. Networking with accomplished women in my cohort and hearing firsthand accounts from experienced board members were also invaluable. In fact, I did a think tank event with one of the ladies from the cohort, Theresa Caragol, about risk management and things that we learned about each other. I think it's also given me a lot more confidence in stepping up to the table and saying: I have a voice too. I understand this stuff. I went through this training program, so I know what I'm talking about. I know that this is what we're supposed to be doing, rather than just relying on your instincts. It gives you a little bit more certainty in the guidance that you're providing to the organization. How did the program push you outside of your comfort zone? How did it help you address challenges unique to women in leadership? The industry I've been in for 23 years is male dominated, and I was the only woman at our company for the first 13 months. It was very comfortable in that position, but being with this cohort of women helped me to better understand what their challenges are and how they navigated their career fields to get where they were. One of the speakers that joined us, for instance, was a man that is doing venture funding in the seed capital rounds. It came up during that discussion that there is less funding provided to women, and particularly minority women, in the seed funding fields. That really opened a neuron chain for me. I didn't realize that there was that kind of bias because as a financial advisor, you look at the balance, your profitability or the numbers. I'm a big advocate of financial privacy – if the applications were filled out in a way where you couldn't see the biographic information of the person actually filing the application, wouldn’t that make the playing field more fair? Companies should only be quantitatively evaluating a company for their growth potential, not qualitatively evaluating the employees or the founders. The certification test was also tough, requiring a shift in thinking from executive to risk manager. The test involves scenario-based questions with a unique scoring system where answering incorrectly hurts your score, but not answering at all has no impact. It was a challenging format, but it reinforced the mindset shift the program aims to teach. What advice would you give to women considering applying to join the Leadership Foundry? It's important to understand why you want to pursue board service. The program is ideal for those with executive experience who are ready to make the transition, not for middle managers or those still considering their career direction. If you want to get in and you think that the Leadership Foundry is the right step for you, you need to focus on the reasons that you want to be a director or a board member – what is the thing that you want to do next in your career and why? Board service, in a lot of situations, is a part time position and it doesn't pay. And if it does pay, you've bought stock, or you had to financially invest in the company that you're getting on the board for. So you really have to think, am I willing to split my time between their full time job and a board position? If you're unsure, there are resources to help you decide if board service is right for you. But we also need a space for women within WIT to ask the questions: What is board service? How does it work? Is it right for me? Is this the next step in my career that I actually want to take? Or do I want to specialize in my area? Do I want to go into executive leadership? Do you have a risk mindset? Do you have the kind of a mindset that puts you in a position to make hard decisions outside of what an executive would make? That's a consideration that you need to make, because board service is not for everybody. It’s okay to be a subject matter expert or operator without pursuing executive or board roles. We need to emphasize that career satisfaction comes from finding the right path, not necessarily following traditional progressions. Ready to take your career to the next level? Applications for The Leadership Foundry are now open! Apply Now
  8. by: Adnan Shabbir Wed, 28 May 2025 05:55:55 +0000 Ubuntu 25.04, codenamed Plucky Puffin, released in April 2025, is an interim release supported for 9 months (until Jan 2026). Ubuntu 25.04 is equipped with experimental features that will be tested until the next LTS, 26.04, and if declared stable, these features will be carried forward and may be part of Ubuntu 26.04, the next Ubuntu LTS in line. In today’s guide, I’ll give you a brief overview of Ubuntu 25.04, what it looks like, and what other features are included in the development and testing. Outline: What’s New in Ubuntu 25.04 Codenamed Plucky Puffin? GNOME 48 Kernel .14 Security Center Updated apt Installation Interface Well-Being HDR Display – High Dynamic Range Other Notable Updates in Ubuntu 25.04 How to Upgrade to Ubuntu 25.04 Conclusion What’s New in Ubuntu 25.04 Codenamed Plucky Puffin? With every interim release (just like Ubuntu 25.04), there comes a list of new features to be tested and some improvements to existing functionalities. This time we are focusing on Ubuntu 25.04, some major as well as minor updates will be provided: GNOME 48 Ubuntu 24.04 is based on GNOME 46, whereas at the moment of writing this post, Ubuntu 25.04 is being experimented with GNOME 48. As of now, GNOME 48 is more modern and graphics-friendly, which is always, i.e., the latest version is supposed to overcome the deficiency of the previous GNOME version and improve over time. Kernel 6.14 The kernel is the central nervous system of Linux, i.e., a bridge between the hardware and the software. Ubuntu 25.04 comes with a Kernel 6.14 (Upstream), i.e., developed and maintained by Linus Torvalds and the Linux kernel maintainers. The first official release of Ubuntu 24.04 contained the Kernel 6.8. However, Ubuntu 24.04.2 is now updated to the Linux Kernel 6.11. Security Center Although Ubuntu is an open-source OS and is more secure than other OSs. However, to align with this top-tech era, Ubuntu might be seeking some additional application support. These applications require some permissions that a user has to give for smooth functionality. To deal with such permissions, Ubuntu has released a Security Center in this release, so that users may turn on or off the permissions. Here’s the initial interface of the Security Center, where you can see that the feature is experimental at the moment. If you enable it, the strictly confined apps request permissions. The app permissions can be checked in the settings, i.e., “Settings > Apps” Updated apt Installation Interface An interactive UI for the apt-based installations and uninstallations: Uninstalling: Well-Being This is about the well-being of the Ubuntu lovers. The users can enable it and set the following features: Screen Time: Set the average screen time usage. Eyesight Reminder: A reminder to look away from the screen. Movement Reminder: A reminder to move around. Document Viewer (PDF Viewer) Ubuntu 25.04 is now equipped with a built-in Document Viewer for various types of files. You can open a variety of files on this viewer, i.e., PDF, comic books, DjVU, and TIFF documents. Here’s the document viewer: HDR Display – High Dynamic Range High Dynamic Range (HDR) is a state-of-the-art technology to provide better display with advanced coloring sense of the HDR technology. This is one of the significant additions in this update list. If you have an HDR monitor, now, you can attach it to your Ubuntu 25.04 to experience HDR displays. Head over to “Settings > Display > HDR” to manage it. Other Notable Updates in Ubuntu 25.04 Color to Color Management: The Color section in the “Settings” has been replaced with Color Management in the Settings. Timezone in Events: Ubuntu 25.04 provides timezone support while creating events in the calendar. Here’s how you can locate it in the Calendar app of Ubuntu 25.04: JPEG XL Image Support: JPEG XL is an image type (an enhanced JPEG), and now it is supported by Ubuntu and providing a better experience for the users. Notification Grouping: Ubuntu 25.04 has now offered a notification grouping inside the notifications, making it easier for users to navigate through multiple notifications. Yaru Theme: The icon and theme experience is better than the previous releases. The icons are now more dynamic and are well integrated with the accent color support. Updated Network Manager: Ubuntu 25.04 has an updated Network Manager 1.52, whereas Ubuntu 24.04.2 (released parallel to Ubuntu 25.04) has 1.46. The significant change is that Network Manager 1.52 is more aligned towards IPv6 as compared to the 1.46 version. Chrony (Network Time Protocol): Ubuntu 25.04 has adopted Chrony as its Network Time Protocol client (SUSE and RHEL inspired), which synchronizes the system time as per the NTP servers, i.e., a GPS receiver. Until now, Ubuntu has been using “systemd-timesync” as its Network Time Protocol client, which is also known as SNTP (Simple Network Time Protocol). The SNTP synchronizes the system clock with the remote server and has less accuracy when compared with Chrony (Full NTP). What is NTP? The purpose of the NTP is to synchronize the clocks of the systems over a network to ensure the security, performance, event coordination, and logging. NTP ensures the time sync is as accurate as possible, i.e., in milliseconds / submilliseconds. Developer Tools and Libraries: Since Ubuntu is well-liked in the developer community, the Ubuntu contributors continuously work on providing updated tools. Ubuntu 25.04 is equipped with updated tools, i.e., Python, GCC, Rust, and Go. Similarly, a few of the developers associated libraries are also upgraded, i.e., glibc, binutils, and OpenSSL. Gaming Support (NVIDIA Dynamic Boost): The NVIDIA dynamic boost enables the gamer to manage the power between the CPU and GPU. This is now enabled by default in Ubuntu 25.04. System Monitor’s Interface: Ubuntu’s system monitor shows information about the processes, resources, and file systems. In Ubuntu 25.04, there is a slight change in the interface of the Ubuntu System Monitor. For instance, the info inside the processes tab is restricted to, i.e., ID, CPU, Memory, Disk Write, and Disk Read. Here’s the interface where you can see this. However, in older versions, the Processes tab has some additional info for each process: That’s all from the notable features of Ubuntu 25.04. Would you like to upgrade your Ubuntu to Ubuntu 25.04? How to Upgrade to Ubuntu 25.04 Plucky Puffin If you are using any other release of Ubuntu (Ubuntu 25.10 or Ubuntu 24.04), you can easily upgrade to Ubuntu 25.04. Let’s go through the steps to upgrade: Important Note: If you are using a Ubuntu LTS release other than Ubuntu 24.04, then you have to first upgrade to Ubuntu 24.04: Upgrade Ubuntu to the Latest LTS Once upgraded to Ubuntu 24.04, you are now ready to follow the steps below and upgrade to Ubuntu 24.10. Step 1: Upgrade Your Ubuntu to Ubuntu 24.10 Since it is an interim release, you must have the previous release installed to get Ubuntu 25.04. Here’s how you can upgrade to Ubuntu 24.10: Update and upgrade the system repositories: sudo apt update && sudo apt upgrade Note: It is recommended to use “sudo apt autoremove” after update/upgrade, to clean up the system from any useless dependencies/packages that are not required. If you are using Ubuntu 24.04 LTS, then you have to enable the non-LTS release upgrade. For that, open the release-upgrader file in an editor: sudo nano /etc/update-manager/release-upgrades Now, change the “Prompt” parameter’s value from “lts” to “normal”, as can be seen below: Start the upgrade using the do-release-upgrade command: sudo do-release-upgrade Here you go: Press “y” to proceed with the installation: While upgrading, you will be prompted several times asking for acceptance of the changes being processed: Step 2: Upgrade to Ubuntu 25.04 Once you are in Ubuntu 24.10, use the do-release command again to upgrade to Ubuntu 25.04: sudo do-release-upgrade Note: If you get any prompt like “please install all updates available for your release”, then use the command “sudo apt dist-upgrade” and reboot to fix it. Here’s the Ubuntu 25.04: That’s all from this guide. Conclusion Ubuntu 25.04, codenamed “Plucky Puffin”, is an interim Ubuntu release supported for 9 months. Ubuntu 25.04, released in April 2025, features the updated GNOME (48), updated Kernel (6.14), an improved apt version (3.0), and a security center. Other features include the HDR display, enhanced color management, timezone support in events, etc. This post briefly lists the notable features of Ubuntu 25.04 and also explains the process to upgrade to Ubuntu 25.04. FAQS How Long Will Ubuntu 25.04 be Supported? Ubuntu 25.04 will be supported until January 2026. Since Ubuntu 25.04 is an interim release and an Ubuntu interim release is supported for 9 months after its release. Is Ubuntu 25.04 LTS? No, Ubuntu 25.04 is an interim release, not an LTS. The current latest LTS is Ubuntu 24.04 codenamed Noble Numba, and the next in line LTS is Ubuntu 26.04. How to Upgrade to Ubuntu 25.04? First, upgrade to Ubuntu 24.04, then to 24.10, and from there, you can upgrade to Ubuntu 25.10.
  9. by: Abhishek Prakash Wed, 28 May 2025 03:29:07 GMT There are two main choices for getting VS Code on Arch Linux: Install Code - OSS from Arch repositoriesInstall Microsoft's VS Code from AURI know. It's confusing. Let me clear the air for you. VS Code is an open source project but the binaries Microsoft distributes are not open source. They have telemetry enabled in it. Code - OSS is the actual open source version of VS Code. Think of Code - OSS as Chromium browser and VS Code as Google Chrome (which is based on Chromium browser). Another thing here is that some extensions will only work in VS Code, not in the de-Micorsoft Code - OSS. This is why you should think it through if you want to use Microsoft's VS Code or its 100% open sourced version. Let me show you the steps for both installation. Method 1: Install Code - OSS ✅ Open source version of Microsoft VS Code ✅ Easy to install with a quick pacman command ❌ Some extensions may not workThis is simple. All you have to do is to ensure that your Arch system is updated: pacman -SyuAnd then install Code - OSS with: pacman -S codeIt cannot be simpler than this, can it? As I mentioned earlier, you may find some extensions that do not work in the open source version of Code. Also, I had noticed earlier that Ctrl+C - Ctrl+V was not working for copy paste. Instead, it was defaulted to Ctrl+Shift+C and Ctrl+Shift+V for reasons not known to me. I had not made any changes to key bindings or had opted for a Vim plugin. Removing Code OSSRemoval is equally simple: sudo pacman -R codeMethod 2: Install the actual Microsoft's VS Code✅ Popular Microsoft VS Code that is used by most people ✅ Access to all proprietary features and extensions in the marketplace ❌ Installation may take effort if you don't have an AUR helperIf you don't care too much about ethics, open source principles and just want to code without thinking it too much, go with VS Code. There are a couple of VS Code offerings available in the AUR but the official one is this. Before installing it, you should remove Code OSS sudo pacman -R codeIf you have an AUR helper like yay already installed, use it like this: yay -S visual-studio-code-binOtherwise, install yay first and then use it to install the desired package. Don't be deceived by the pretty looking screenshot above. I was using a different theme in VS Code. RemovalYou can use your AUR helper or the super reliable pacman command to remove Microsoft VS Code from Arch Linux. sudo pacman -R visual-studio-code-binI let you enjoy your preferred version of VS Code on Arch Linux. Please feel free to use the comment section if you have questions or suggestions.
  10. Blogger posted a blog entry in Linux Tips
    by: Abhishek Prakash Tue, 27 May 2025 21:57:07 +0530 Paste your YAML content or upload a file to validate syntax. Scroll down to see the details on the errors, if any. YAML Validator Tool
  11. by: Daniel Schwarz Tue, 27 May 2025 13:02:32 +0000 The reading-flow and reading-order proposed CSS properties are designed to specify the source order of HTML elements in the DOM tree, or in simpler terms, how accessibility tools deduce the order of elements. You’d use them to make the focus order of focusable elements match the visual order, as outlined in the Web Content Accessibility Guidelines (WCAG 2.2). To get a better idea, let’s just dive in! (Oh, and make sure that you’re using Chrome 137 or higher.) reading-flow reading-flow determines the source order of HTML elements in a flex, grid, or block layout. Again, this is basically to help accessibility tools provide the correct focus order to users. The default value is normal (so, reading-flow: normal). Other valid values include: flex-visual flex-flow grid-rows grid-columns grid-order source-order Let’s start with the flex-visual value. Imagine a flex row with five links. Assuming that the reading direction is left-to-right (by the way, you can change the reading direction with the direction CSS property), that’d look something like this: CodePen Embed Fallback Now, if we apply flex-direction: row-reverse, the links are displayed 5-4-3-2-1. The problem though is that the focus order still starts from 1 (tab through them!), which is visually wrong for somebody that reads left-to-right. CodePen Embed Fallback But if we also apply reading-flow: flex-visual, the focus order also becomes 5-4-3-2-1, matching the visual order (which is an accessibility requirement!): <div> <a>1</a> <a>2</a> <a>3</a> <a>4</a> <a>5</a> </div> div { display: flex; flex-direction: row-reverse; reading-flow: flex-visual; } CodePen Embed Fallback To apply the default flex behavior, reading-flow: flex-flow is what you’re looking for. This is very akin to reading-flow: normal, except that the container remains a reading flow container, which is needed for reading-order (we’ll dive into this in a bit). For now, let’s take a look at the grid-y values. In the grid below, the grid items are all jumbled up, and so the focus order is all over the place. CodePen Embed Fallback We can fix this in two ways. One way is that reading-flow: grid-rows will, as you’d expect, establish a row-by-row focus order: <div> <a>1</a> <a>2</a> <a>3</a> <a>4</a> <a>5</a> <a>6</a> <a>7</a> <a>8</a> <a>9</a> <a>10</a> <a>11</a> <a>12</a> </div> div { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 100px; reading-flow: grid-rows; a:nth-child(2) { grid-row: 2 / 4; grid-column: 3; } a:nth-child(5) { grid-row: 1 / 3; grid-column: 1 / 3; } } CodePen Embed Fallback Or, reading-flow: grid-columns will establish a column-by-column focus order: CodePen Embed Fallback reading-flow: grid-order will give us the default grid behavior (i.e., the jumbled up version). This is also very akin to reading-flow: normal (except that, again, the container remains a reading flow container, which is needed for reading-order). There’s also reading-flow: source-order, which is for flex, grid, and block containers. It basically turns containers into reading flow containers, enabling us to use reading-order. To be frank, unless I’m missing something, this appears to make the flex-flow and grid-order values redundant? reading-order reading-order sort of does the same thing as reading-flow. The difference is that reading-order is for specific flex or grid items, or even elements in a simple block container. It works the same way as the order property, although I suppose we could also compare it to tabindex. Note: To use reading-order, the container must have the reading-flow property set to anything other than normal. I’ll demonstrate both reading-order and order at the same time. In the example below, we have another flex container where each flex item has the order property set to a different random number, making the order of the flex items random. Now, we’ve already established that we can use reading-flow to determine focus order regardless of visual order, but in the example below we’re using reading-order instead (in the exact same way as order): div { display: flex; reading-flow: source-order; /* Anything but normal */ /* Features at the end because of the higher values */ a:nth-child(1) { /* Visual order */ order: 567; /* Focus order */ reading-order: 567; } a:nth-child(2) { order: 456; reading-order: 456; } a:nth-child(3) { order: 345; reading-order: 345; } a:nth-child(4) { order: 234; reading-order: 234; } /* Features at the beginning because of the lower values */ a:nth-child(5) { order: -123; reading-order: -123; } } CodePen Embed Fallback Yes, those are some rather odd numbers. I’ve done this to illustrate how the numbers don’t represent the position (e.g., order: 3 or reading-order: 3 doesn’t make it third in the order). Instead, elements with lower numbers are more towards the beginning of the order and elements with higher numbers are more towards the end. The default value is 0. Elements with the same value will be ordered by source order. In practical terms? Consider the following example: div { display: flex; reading-flow: source-order; a:nth-child(1) { order: 1; reading-order: 1; } a:nth-child(5) { order: -1; reading-order: -1; } } CodePen Embed Fallback Of the five flex items, the first one is the one with order: -1 because it has the lowest order value. The last one is the one with order: 1 because it has the highest order value. The ones with no declaration default to having order: 0 and are thus ordered in source order, but otherwise fit in-between the order: -1 and order: 1 flex items. And it’s the same concept for reading-order, which in the example above mirrors order. However, when reversing the direction of flex items, keep in mind that order and reading-order work a little differently. For example, reading-order: -1 would, as expected, and pull a flex item to the beginning of the focus order. Meanwhile, order: -1 would pull it to the end of the visual order because the visual order is reversed (so we’d need to use order: 1 instead, even if that doesn’t seem right!): div { display: flex; flex-direction: row-reverse; reading-flow: source-order; a:nth-child(5) { /* Because of row-reverse, this actually makes it first */ order: 1; /* However, this behavior doesn’t apply to reading-order */ reading-order: -1; } } CodePen Embed Fallback reading-order overrides reading-flow. If we, for example, apply reading-flow: flex-visual, reading-flow: grid-rows, or reading-flow: grid-columns (basically, any declaration that does in fact change the reading flow), reading-order overrides it. We could say that reading-order is applied after reading-flow. What if I don’t want to use flexbox or grid layout? Well, that obviously rules out all of the flex-y and grid-y reading-flow values; however, you can still set reading-flow: source-order on a block element and then manipulate the focus order with reading-order (as we did above). How does this relate to the tabindex HTML attribute? They’re not equivalent. Negative tabindex values make targets unfocusable and values other than 0 and -1 aren’t recommended, whereas a reading-order declaration can use any number as it’s only contextual to the reading flow container that contains it. For the sake of being complete though, I did test reading-order and tabindex together and reading-order appeared to override tabindex. Going forward, I’d only use tabindex (specifically, tabindex="-1") to prevent certain targets from being focusable (the disabled attribute will be more appropriate for some targets though), and then reading-order for everything else. Closing thoughts Being able to define reading order is useful, or at least it means that the order property can finally be used as intended. Up until now (or rather when all web browsers support reading-flow and reading-order, because they only work in Chrome 137+ at the moment), order hasn’t been useful because we haven’t been able to make the focus order match the visual order. What We Know (So Far) About CSS Reading Order originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.
  12. by: Abhishek Prakash Tue, 27 May 2025 01:53:31 GMT How do you get help in the Linux command line? On Linux, there are man pages that come preloaded with any distribution. The man pages are basically help pages which you can access using the terminal. You get an instruction manual when you purchase a new gadget, right? It is just like that. If you want to know what a command does, just use the 'man' keyword followed by the command you would like to know about. While it may seem pretty straightforward, the user experience is a bit dull, as it is all a bunch of text without any decorations or any other features. There are some man page alternatives that have tried to modernize the user experience, or give a specific focus to the man pages for particular users. Let me share my quick experience with them. Subscribe to It's FOSS YouTube Channel1. QmanQman is a modern manual page viewer with navigation, scrolling, hyperlink, and table of contents support. It aims to be fast and offer a couple of features at the same time being a terminal-focused tool. Qman terminal interfaceKey Features: Index page that displays all manual pages available on the system, sorted alphabetically and organized by section.Hyperlinks to other manual pages, URLs and email addresses.Table of Contents for each man pagesIncremental search for manual pages and free page text search.Mouse supportNavigation historyOn-line helpFully configurable using an INI-style config fileQman Command Working InstallationThis supports Arch Linux for easy installation using the following command: yay -Syu qmanFor other systems, you need to build it from source Qman2. TLDRLove cheat sheets? So, you do not have to waste your time scrolling through a barrage of descriptions? That's what TLDR helps you with. It gives short and actionable information for commands to follow. TLDR workingKey Features: Community-maintained help pages.Simpler, more approachable complement to traditional man pages.Help pages focused on practical examplesTL;DR stands for "Too Long; Didn't Read". It originated as Internet slang, where it is used to indicate that a long text (or parts of it) has been skipped as too lengthy.Installation🚧You cannot have tldr and tealdeer installed at the same time.If you need to install Snap for Ubuntu, here is the command to do that: sudo snap install tldrFor Arch Linux and Fedora, the commands are (respectively): sudo pacman -Syu tldr sudo dnf install tldrtldr3. TealdeerIf you want TLDR tool, but built on Rust, Tealdeer should be your pick. Simplified, example based and community-driven man pages. Tealdeer workingI noticed an interesting thing about the project's name and I'll quote it here below from their GitHub page: If you pronounce "tldr" in English, it sounds somewhat like "tealdeer". Hence the project name 😄InstallationIt is available on Debian, Arch Linux, and Fedora repos: sudo apt install tealdeer sudo pacman -Syu tealdeer sudo dnf install tealdeerThere are static binary builds for Linux only. You can also install via cargo: cargo install tealdeerOnce installed, run the command below to update the cache: tldr --updateTo get shell completion in bash: cp completion/bash_tealdeer /usr/share/bash-completion/completions/tldrTealdeer4. Navi Cheat SheetIf you favored a cheat sheet, and want an interactive UI to complement the same, Navi Cheat Sheet is the answer. Navi Interactive Cheat Sheet Key Features: Browse through cheat sheets and execute commands.Set up your own config fileChange colorsCan be either used as a command or as a shell widget (à la Ctrl-R).InstallIn Arch Linux and Fedora, use the commands below: sudo pacman -Syu navi sudo dnf install naviYou can also try using Homebrew: brew install naviOnce installed, run navi. It will suggest a command to add a default set of cheat sheets. Run it: navi repo add denisidoro/cheatsAdd Default Set of Cheat Sheets in Navi Navi GitHub5. Cheat.shIf your focus is only on Cheat sheets, and get the best of community-driven inputs for the same, Cheat.sh is the perfect terminal tool for you. Cheat.sh Working using Local Shell Instance Key Features: Simple interfaceCovers 56 programming languages, several DBMSes, and more than 1000 most important UNIX/Linux commands.No installation needed, but can be installed for offline usage.Has a convenient command line client, cht.shCan be used directly from code editorsSupports a special stealth mode where it can be used fully invisibly without ever touching a key and making sounds.InstallationYou can install it using Curl with the following commands: curl cheat.sh/tar curl cht.sh/curl curl https://cheat.sh/rsync curl https://cht.sh/trTo install locally, first install rlwrap and most. PATH_DIR="$HOME/<a-directory-that-is-in-PATH>" mkdir -p "$PATH_DIR" curl https://cht.sh/:cht.sh > "$PATH_DIR/cht.sh" chmod +x "$PATH_DIR/cht.sh"Cheat.sh6. The MOST PagerAlright, if you are like me, and probably not looking for anything fancy, but just a colorful man page, you can use the Most pager. Most as PagerMOST is a powerful paging program. Supports multiple windows and can scroll left and right. It keeps the same good-old man page look with added colors. Installsudo apt install most sudo dnf install most sudo pacman -Syu mostOnce installed, edit ~/~.bashrc: nano ~/.bashrcTo add the line: export PAGER='most'For the latest most versions, color may not appear by default. In that case, below line to ~/.bashrc. export GROFF_NO_SGR=1Most7. Yelp or GNOME HelpConsidering you are using a distribution powered by GNOME desktop, you just need to search for the GNOME Help app from the menu. You can also access the same via the terminal using the command yelp. Using GNOME Help (Yelp) to view man pages Press CTRL to open the search bar and type the command that you want when using the terminal interface. man:<command> # For example man:manOr, if you are in a browser, go to the address bar (CTRL+L). Here, enter man:man. When asked to open the link in help, click on it. Opening man page from a browser GNOME Help (Yelp)Bonus: Use a terminal with built-in AIAI is everywhere, even in your terminal. The proximity of AI in the tool lets you quickly use them. There are a few terminals that come with built-in AI agents to help you get all sorts of help; from simple command suggestion to full-fledged deployment plans. You may use them too if you are an AI aficionado. Warp is one such terminal which is not open source but hugely popular among modern Linux users. Get Warp (Partner link)Wrapping UpWhile you have It's FOSS along with the traditional man pages to learn what most commands do on Linux, there are alternatives to man pages which could enhance your learning experience. If you prefer a GUI, GNOME Help should be helpful or any similar equivalent pre-installed on your distribution. For terminal-based solutions, there are a couple you can try. Take a look at the feature set they offer, and install what you like the most. What do you prefer the most? Let me know in the comments below!
  13. by: Chris Coyier Mon, 26 May 2025 15:54:28 +0000 This is a great story from Dan North about “The Worst Programmer I know”, Tim MacKinnon. It’s a story about measuring developer performance with metrics: Scared? Maybe you can guess. Tim was very bad at metrics. Why? Maybe you can guess again. Tim wasn’t playing that game, he was a true senior developer in the sense that he nurtured his team. Every organization is different though. Mercifully in the situation above, Dan protected Tim. But we can all imagine a situation where Tim was fired because of this silly measurement system. (That always reminds me of Cathy O’Neils Weapons of Math Destruction). Getting to know how the organization works, so you can work within it, is another approach that Cindy Sridharan advocates for. See: How to become a more effective engineer. Different organizations will have different paths to these answers. I’ll pluck off a few bullet points: Figure out who matters, what they care about, and how to effectively get things done. And don’t wait! Another one I like in this realm of being a truly effective developer is Artem Zakirullin’s Cognitive load is what matters. A good developer can write code that themselves and others can read without being so complex that, well, you run out of mental capacity. That tracks for me. I start tracing how code works, and I’m all good and have it in my head, then it feels like right at the fifth logical jump, my brain just dumps it all out and I’m lost. I suspect it’s a talent of really great programmers that they can hold a bit more in their head, but it’s not smart to assume that of your fellow developers. And remember that even the very smart appreciate things that are very simple and clear, perhaps especially. You know what strikes me as a smart developer move? When they work together even across organizations. It’s impressive to me to see Standard Schema an effort by all the people who work on any library that deals with JavaScript/TypeScript schemas to make them easier to use and implement. There are heaps of libraries and tools that already support it, so I’d call that a big success. I see Zod released Mini recently, which uses functions instead of methods, making it tree-shakable, but otherwise works exactly the same. Likely a nod to Validbot which was always the “Zod but smaller” choice. Another thing I think is smart: seeing what developers are already doing and making that thing better. Like, I’m sure there are very fancy exotic ways to debug JavaScript in powerful ways. But we all know most of us just console.log() stuff. So I like how Microsoft is like, let’s just make that better with console.context(). This allows for better filtering and styling of messages and such, which would surely be welcome. Might as well steal formatting strings from Node as well.
  14. by: Abhishek Kumar Mon, 26 May 2025 14:31:56 +0530 I see a lot of posts on my Twitter (or X) feed debating the merits of ditching cloud services in favor of homelab self-hosted setups just like I tried hosting Wikipedia and the Arch wiki. Some even suggest using bare-metal servers for professional environments. Source: Fireship on XWhile these posts often offer intriguing tools and perspectives, I can't help but notice a pattern: companies lean heavily on cloud services until something goes catastrophically wrong, like Google Cloud accidentally deleting customer data. Source: Ars TechnicaHowever, let’s be real, human error can occur anywhere. Whether in the cloud or on-premises, mistakes are universal. So, no, I’m not here to tell you to migrate your production services to a makeshift homelab server and become the next Antoine from Silicon Valley. But if you’re wondering why people even homelab in the era of AWS and Hetzner, I’m here to make the case: it’s fun, empowering, and yes, sometimes even practical. 1. Cost control over timeCloud services are undeniably convenient, but they often come with hidden costs. I still remember during my initial days here at It's FOSS, and Abhishek messaged me reminding me to delete any unused or improperly configured Linode instances. That’s the thing with cloud services, you pay for convenience, and if you’re not meticulous, it can snowball. Source: Mike Shoebox on XA homelab, on the other hand, is a one-time investment. You can repurpose an old PC or buy retired enterprise servers at a fraction of their original cost. Sure, there are ongoing power costs, but for many setups, especially with efficient hardware like Raspberry Pi clusters, this remains manageable. I'll take this opportunity to share my favorite AWS meme. 2. Learning and experimentationIf you’re in tech, be it as a sysadmin, developer, or DevOps engineer, having a homelab is like owning a personal playground. Want to deploy Kubernetes? Experiment with LXC containers? Test Ansible playbooks? You can break things, fix them, and learn along the way without worrying about production outages or cloud charges. For me, nothing beats the thrill of running Proxmox on an old Laptop with a Core i5, 8 GB of RAM, and a 1 TB hard drive. It’s modest (you might've seen that poor machine in several of my articles), but I’ve used it to spin up VMs, host Docker containers, and even test self-hosted alternatives to popular SaaS tools. 3. Privacy and ownershipWhen your data resides in the cloud, you trust the provider with its security and availability. But breaches happen, and privacy-conscious individuals might balk at the idea of sensitive information being out of their direct control. With a homelab, you own your data. Want a cloud backup? Use tools like Nextcloud. Need to share documents easily? Host your own FileBrowser. This setup isn’t just practical, it’s liberating. Sure, there’s a learning curve and it could be steep for many. Thankfully, we also have plug-and-play solutions like CasaOS, which we covered in a previous article. All you need to do is head to the app store, select 'install,' and everything will be taken care of for you. 4. Practical home usesHomelabs aren’t just for tech experiments. They can serve real-world purposes, often replacing expensive commercial solutions: Media servers: Host your own movie library with Jellyfin or Plex. No subscription fees, no geo-restrictions, and no third-party tracking, as long as you have the media on your computer.Home security: Set up a CCTV network with open-source tools like ZoneMinder. Add AI-powered object detection, and you’ve built a system that rivals professional offerings at a fraction of the cost.Family productivity: Create centralized backups with Nextcloud or run remote desktop environments for family members. You become the go-to tech person for your household, but in a rewarding way.For my parents, I host an Immich instance for photo management and a Jellyfin instance for media streaming on an old family desktop. Since the server is already running, I also use it as my offsite backup solution, just to be safe. 😅 📋If you are into self-hosting, always make multiple instances of data backup in different locations/systems/medium. Follow the golden rule of 3-2-1 backup.9 Dashboard Tools to Manage Your Homelab EffectivelySee which server is running what services with the help of a dashboard tool for your homelab.It's FOSSAbhishek KumarWhat about renting a VPS for cloud computing?I completely understand that renting a VPS can be a great choice for many. It offers flexibility, ease of use, and eliminates the need to manage physical hardware. These days, most VPS providers like AWS, Oracle, and others offer a 1-year free tier to attract users and encourage them to explore their platforms. This is a fantastic opportunity for beginners or those testing the waters with cloud hosting. I’ve also heard great things about Hetzner, especially their competitive pricing, which makes them an excellent option for those on a budget. In fact, I use Nanode myself to experiment with a DNS server. This setup spares me the hassle of port forwarding, especially since I’m behind CGNAT. If you’re interested in hosting your own projects or services but face similar limitations, I’ve covered a guide on Cloudflare Tunnels that you can consult, it’s a handy workaround for these challenges. Personally, I believe gatekeeping is one of the worst things in the tech community. No one should dictate how or where you host your projects. Mix and match! Host some services on your own systems, build something from scratch, or rent a VPS for convenience. Just be mindful of what you’re hosting like ensuring no misconfigured recursive function is running loose and keep exploring what suits your needs best. My journey into homelabMy journey into homelabbing and self-hosting started out of necessity. When I was in university, I didn’t have the budget for monthly cloud server subscriptions, domain hosting, or cloud storage. That limitation pushed me to learn how to piece things together: finding free tools, configuring them to fit my needs, diving into forum discussions, helping others solve specific issues, and eagerly waiting for new releases and features. This constant tinkering became an endless cycle of learning, often without even realizing it. And that’s the beauty of it. Whether you’re self-hosting on a VPS or your homelab, every step is a chance to explore, experiment, and grow. So, don’t feel constrained by one approach. The freedom to create, adapt, and learn is what makes this space so exciting. Wrapping upAt the end of the day, whether you choose to build a homelab, rent a VPS, or even dabble in both, it’s all about finding what works best for you. There’s no one-size-fits-all approach here. For me, homelabbing started as a necessity during my university days, but over time, it became a passion, a way to learn, experiment, and create without boundaries. Sure, there are challenges, misconfigured services, late nights debugging, and the occasional frustration, but those moments are where the real learning happens. Renting a VPS has its perks too. It’s quick, convenient, and often more practical for certain projects. I’ve come to appreciate the balance of using both approaches, hosting some things locally for the sheer fun of it and using VPS providers when it makes sense. It’s not about choosing sides; it’s about exploring the possibilities and staying curious. If you’re someone who enjoys tinkering, building, and learning by doing, I’d encourage you to give homelabbing a try. Start small, experiment, and let your curiosity guide you. And if you prefer the convenience of a VPS or a mix of both, that’s perfectly fine too. At the end of the day, it’s your journey, your projects, and your learning experience. So, go ahead, spin up that server, configure that service, or build something entirely new. The world of self-hosting is vast, and the possibilities are endless. Happy tinkering!
  15. by: Sreenath Mon, 26 May 2025 00:50:21 GMT Obsidian has emerged as a powerful and flexible knowledge management tool, despite NOT being an open source product. Using plugins is just one of the many tips that you can follow to get the most out of Obsidian. However, there is a small catch when it comes to compatibility. If you have used several Obsidian-specific plugins, then your notes may not be fully compatible in other plain markdown editors. In this article, we will take a look at Plugins in Obsidian, how you can install it, and also some essential plugins that can make your learning more effective. But first, a quick heads-up: Obsidian offers two types of plugins: Core Plugins: These are officially developed and maintained by the Obsidian team. While limited in number, they are stable and deeply integrated.Community Plugins: Created by users in the Obsidian community, these plugins offer a wide variety of features, although they aren’t officially supported by the core team.🚧Note that some plugins may make your Markdown notes fully readable only in Obsidian. This can be a vendor lock in. Use plugins only according to your needs.Using the core pluginsCore plugins are officially built by Obsidian. They will come pre-installed. So, naturally, that is the recommended method of installation when it comes to plugins. Core plugins are displayed in Obsidian settings page. Click on the settings gear icon at the bottom of the Obsidian app window to go to the settings. Click on the Settings gearIn the settings, select Core Plugins to view the Core plugins. Select Core PluginsMost of the core plugins are enabled when you install the Obsidian app. But some plugins will be disabled by default. I have included a brief description under each plugin to know what the plugin does and enable/disable as needed. Suggested Read 📖 13 Useful Tips on Organizing Notes Better With ObsidianUtilize Obsidian knowledge tool more effectively with these helpful tips and tweaks.It's FOSSSreenathUsing the community pluginsI’ve found that community plugins are one of the best ways to boost Obsidian’s capabilities. There’s a massive collection to choose from, and at the time of writing this, there are 2,430 community plugins available for installation. These plugins are built by third-party developers and go through an initial review process before being listed. However, since they have the same level of access as Obsidian itself, it’s important to be cautious. If privacy and security are essential for your work, I suggest doing a bit of homework before installing any plugin, just to be safe. Disable the restricted modeTo protect you from unofficial plugins, Obsidian starts with a restricted mode, where the community plugins are disabled. To install community plugins, you need to disable the restricted mode first, just like the auto blocker in some Android phones to block app installations from unauthorized sources. Go to the Obsidian settings and select the Community Plugins option. Here, click on the "Turn on community plugins" button. Turn on community pluginsThis will disable the restricted mode. And, you are all set! 😄 Install community pluginsOnce the restricted mode is disabled, you can browse for community plugins and get them installed. Click on the Browse buttonUse the Browse button to go to the plugins page, as shown in the screenshot above. You will reach the plugins store, that lists 2000+ plugins. Do not worry about the numbers, just search for what you need, or browse through some suggested options, just like I did. Plugins StoreWhen you have spotted a plugin that matches your need, click on it. Now, to install that plugin, use the Install button. Click on the Install buttonOnce installed, you can see two additional buttons called Enable and Uninstall. As the name suggests, they are for enabling a plugin or uninstalling a plugin. Enable/Uninstall a pluginThis can be done more efficiently from the Obsidian settings. For this, go to the Settings → Community plugins → Installed plugins. Here, use the toggle button to enable a plugin. Enable Plugins in SettingsThis section lists all the installed community plugins. You can enable/disable, uninstall, access plugin settings, assign a keybinding, or donate to that particular plugin. Manually install plugins🚧I do not recommend this method, since most of the plugins are available in Obsidian store and have gone through an initial review.Even though not recommended, if you want to install a plugin, manually, for version compatibility or other personal reasons, make sure to source it from the official repositories or websites. If it is on GitHub, go to the release page of the plugin GitHub repository and download main.js, manifest.json, and style.css files. Download Plugin filesNow, create a directory with the name of the project in the <Your-obsidian-vault>/.obsidian/plugins directory. Press CTRL+H to view hidden files. Paste plugin contentsIn my case, I tried Templater. Next, I transfer the downloaded files to this project directory. Now, open Obsidian and go to the Settings → Community plugins and enable the new plugin. Enable manually installed pluginInstall beta version of pluginsThis is not for regular users, but for those who want to be testers and reviewers of beta plugins. I usually do this to test interesting things or help with the development of plugins I believe in. We are using the BRAT (Beta Reviewers Auto-Update Tool) to install and update beta versions of Obsidian plugins. First, install the BRAT plugin from the Obsidian plugins store and enable it. Install BRAT PluginNow, go to the GitHub repository of the plugin you want to install the beta version of. Copy the URL of the repository. Select the BRAT plugin from Settings → Community plugins and click on the “Add beta plugin” button. Click on the "Add beta plugin" buttonHere, add the GitHub URL, select a version from the list, and click on the Add Plugin button. Add URL and select versionYou can see that the plugin has been added with BRAT. Since we selected a specific version, it is shown as frozen and cannot be updated. Select Latest as version to get updates. Beta plugin added using BRATUpdate pluginsTo update community plugins, go to Obsidian settings and select Community plugins. Here, click on the Check for updates button. If there is an update available, it will notify you. There is an update available for one plugin.Click on Update All to update all the plugins that have an update available. Or, scroll down and update individual plugins by clicking on the Update button. Move community pluginsYou can copy selected or all plugins from your directory to another vault to avoid installing everything from scratch. Go to the <your-obsidian-vault>/.obsidian/plugins directory. Now, copy directories of those plugins you want to use in another vault. Copy those directories to your new plugin directory for your other vault (or the newer vault) <your-new-vault>/.obsidian/plugins directory. If there is no plugins directory in the new vault, create one. Once you open the new vault, you will be asked to trust the plugins. If it is you, who copied all the folders and no others are involved, click on the "Trust author and enable plugins" button. Or you can use the "Browse Vault in restricted mode" and then enable the plugins by going to Settings → Community plugins → Turn on Community plugins → Enable plugins. Plugin security notificationIn both cases, you don't have to install the plugin from scratch. Don't forget to enable the plugins through Settings → Community plugins to start using them. Remove a pluginRemoving a plugin is easy. Go to the community plugins in settings and click on the delete button (bin icon) adjacent to the plugin you want to remove. Remove a pluginOr, if you just want to disable all community plugins, you can turn on the restricted mode. Click on the Turn on and reload button in community plugins settings. Turn on restricted modeSo, if you turn off the restricted mode, all the installed plugins will be enabled. Pretty easy, I know, right? Another way to remove plugins is to delete specific folders in the plugins directory, but it is unnecessary unless you are testing something specific. 🚧Don't use this method for everything since it is safer to do so from within Obsidian.Go to the <your-obsiidian-vault>/.obsidian/plugins directory and remove the directory that has the name of the plugin you want to remove. Now open Obsidian and you won't see that plugin. Voila! Enjoy using ObsidianI have shared many more Obsidian tips to improve your experience with this wonderful too. 13 Useful Tips on Organizing Notes Better With ObsidianUtilize Obsidian knowledge tool more effectively with these helpful tips and tweaks.It's FOSSSreenathPlugin is just part of how you can go beyond the obvious and default Obsidian offering. I hope you found this tutorial helpful. Enjoy.
  16. Earlier
  17. by: Abhishek Prakash Fri, 23 May 2025 18:40:52 +0530 Linux doesn't get easier. You just get better at it. This is what I always suggest to beginners. The best way to learn Linux (or any new skill for that matter) is to start using it. The more you use it, the better you get at it 💪 Here are the highlights of this edition : Master splitting windows in VimEssential YAML conceptsCheckcleAnd more tools, tips and memes for youThis edition of LHB Linux Digest newsletter is supported by PikaPods.🚀 Self-hosting on autopilotPikaPods allows you to quickly deploy your favorite open source software. All future updates and backups are handled automatically by PikaPods while you enjoy using the software. Wondering if you should rely on it? You get $5 free credit, so try it out and test it yourself. PikaPods - Instant Open Source App HostingRun the finest Open Source web apps from $1.20/month, fully managed, no tracking, no ads, full privacy. Self-hosting was never this convenient.Instant Open Source App Hosting       This post is for subscribers only Subscribe now Already have an account? Sign in
  18. by: Temani Afif Fri, 23 May 2025 13:02:32 +0000 Creating CSS Shapes is a classic and one of my favorite exercise. Indeed, I have one of the biggest collections of CSS Shapes from where you can easily copy the code of any shape. I also wrote an extensive guide on how to create them: The Modern Guide For Making CSS Shapes. Even if I have detailed most of the modern techniques and tricks, CSS keeps evolving, and new stuff always emerges to simplify our developer life. Recently, clip-path was upgraded to have a new shape() value. A real game changer! Before we jump in, it’s worth calling out that the shape() function is currently only supported in Chrome 137+ and Safari 18.4+ as I’m writing this in May 2025. What is shape()? Let me quote the description from the official specification: In other words, we have the SVG features in the CSS side that we can combine with existing features such as var(), calc(), different units, etc. SVG is already good at drawing complex shapes, so imagine what is possible with something more powerful. If you keep reading the spec, you will find: And guess what? I already created an online converter from SVG to CSS. Save this tool because it will be very handy. If you are already good at creating SVG shapes or you have existing codes, no need to reinvent the wheel. You paste your code in the generator, and you get the CSS code that you can easily tweak later. Let’s try with the CSS-Tricks logo. Here is the SVG I picked from the website: <svg width="35px" height="35px" viewBox="0 0 362.62 388.52" > <path d="M156.58,239l-88.3,64.75c-10.59,7.06-18.84,11.77-29.43,11.77-21.19,0-38.85-18.84-38.85-40C0,257.83,14.13,244.88,27.08,239l103.6-44.74L27.08,148.34C13,142.46,0,129.51,0,111.85,0,90.66,18.84,73,40,73c10.6,0,17.66,3.53,28.25,11.77l88.3,64.75L144.81,44.74C141.28,20,157.76,0,181.31,0s40,18.84,36.5,43.56L206,149.52l88.3-64.75C304.93,76.53,313.17,73,323.77,73a39.2,39.2,0,0,1,38.85,38.85c0,18.84-12.95,30.61-27.08,36.5L231.93,194.26,335.54,239c14.13,5.88,27.08,18.83,27.08,37.67,0,21.19-18.84,38.85-40,38.85-9.42,0-17.66-4.71-28.26-11.77L206,239l11.77,104.78c3.53,24.72-12.95,44.74-36.5,44.74s-40-18.84-36.5-43.56Z"></path> </svg> You take the value inside the d attribute, paste it in the converter, and boom! You have the following CSS: .shape { aspect-ratio: 0.933; clip-path: shape(from 43.18% 61.52%,line by -24.35% 16.67%,curve by -8.12% 3.03% with -2.92% 1.82%/-5.2% 3.03%,curve by -10.71% -10.3% with -5.84% 0%/-10.71% -4.85%,curve to 7.47% 61.52% with 0% 66.36%/3.9% 63.03%,line by 28.57% -11.52%,line to 7.47% 38.18%,curve to 0% 28.79% with 3.59% 36.67%/0% 33.33%,curve to 11.03% 18.79% with 0% 23.33%/5.2% 18.79%,curve by 7.79% 3.03% with 2.92% 0%/4.87% 0.91%,line by 24.35% 16.67%,line to 39.93% 11.52%,curve to 50% 0% with 38.96% 5.15%/43.51% 0%,smooth by 10.07% 11.21% with 11.03% 4.85%,line to 56.81% 38.48%,line by 24.35% -16.67%,curve to 89.29% 18.79% with 84.09% 19.7%/86.36% 18.79%,arc by 10.71% 10% of 10.81% 10.09% small cw,curve by -7.47% 9.39% with 0% 4.85%/-3.57% 7.88%,line to 63.96% 50%,line to 92.53% 61.52%,curve by 7.47% 9.7% with 3.9% 1.51%/7.47% 4.85%,curve by -11.03% 10% with 0% 5.45%/-5.2% 10%,curve by -7.79% -3.03% with -2.6% 0%/-4.87% -1.21%,line to 56.81% 61.52%,line by 3.25% 26.97%,curve by -10.07% 11.52% with 0.97% 6.36%/-3.57% 11.52%,smooth by -10.07% -11.21% with -11.03% -4.85%,close); } Note that you don’t need to provide any viewBox data. The converter will automatically find the smallest rectangle for the shape and will calculate the coordinates of the points accordingly. No more viewBox headaches and no need to fight with overflow or extra spacing! CodePen Embed Fallback Here is another example where I am applying the shape to an image element. I am keeping the original SVG so you can compare both shapes. CodePen Embed Fallback When to use shape() I would be tempted to say “all the time” but in reality, not. In my guide, I distinguish between two types of shapes: The ones with only straight lines and the ones with curves. Each type can either have repetition or not. In the end, we have four categories of shapes. If we don’t have curves and we don’t have repetition (the easiest case), then clip-path: polygon() should do the job. If we have a repetition (with or without curves), then mask is the way to go. With mask, we can rely on gradients that can have a specific size and repeat, but with clip-path we don’t have such options. If you have curves and don’t have a repetition, the new shape() is the best option. Previously, we had to rely on mask since clip-path is very limited, but that’s no longer the case. Of course, these are not universal rules, but my own way to identify which option is the most suitable. At the end of the day, it’s always a case-by-case basis as we may have other things to consider, such as the complexity of the code, the flexibility of the method, browser support, etc. Let’s draw some shapes! Enough talking, let’s move to the interesting part: drawing shapes. I will not write a tutorial to explain the “complex” syntax of shape(). It will be boring and not interesting. Instead, we will draw some common shapes and learn by practice! Rectangle Take the following polygon: clip-path: polygon( 0 0, 100% 0, 100% 100%, 0 100% ); Technically, this will do nothing since it will draw a rectangle that already follows the element shape which is a rectangle, but it’s still the perfect starting point for us. Now, let’s write it using shape(). clip-path: shape( from 0 0, line to 100% 0, line to 100% 100%, line to 0 100% ); The code should be self-explanatory and we already have two commands. The from command is always the first command and is used only once. It simply specifies the starting point. Then we have the line command that draws a line to the next point. Nothing complex so far. We can still write it differently like below: clip-path: shape( from 0 0, hline to 100%, vline to 100%, hline to 0 ); Between the points 0 0 and 100% 0, only the first value is changing which means we are drawing a horizontal line from 0 0 to 100% 0, hence the use of hline to 100% where you only need to specify the horizontal offset. It’s the same logic using vline where we draw a vertical line between 100% 0 and 100% 100%. I won’t advise you to draw your shape using hline and vline because they can be tricky and are a bit difficult to read. Always start by using line and then if you want to optimize your code you can replace them with hline or vline when applicable. We have our first shape and we know the commands to draw straight lines: CodePen Embed Fallback Circular Cut-Out Now, let’s try to add a circular cut-out at the top of our shape: For this, we are going to rely on the arc command, so let’s understand how it works. If we have two points, A and B, there are exactly two circles with a given radius that intersect with both points like shown in the figure. The intersection gives us four possible arcs we can draw between points A and B. Each arc is defined by a size and a direction. There is also the particular case where the radius is equal to half the distance between A and B. In this case, only two arcs can be drawn and the direction will decide which one. The syntax will look like this: clip-path: shape( from Xa Ya, arc to Xb Yb of R [large or small] [cw or ccw] ); Let’s add this to our previous shape. No need to think about the values. Instead, let’s use random ones and see what happens: clip-path: shape( from 0 0, arc to 40% 0 of 50px, line to 100% 0, line to 100% 100%, line to 0 100% ); CodePen Embed Fallback Not bad, we can already see the arc between 0 0 and 40% 0. Notice how I didn’t define the size and direction of the arc. By default, the browser will use small and ccw. Let’s explicitly define the size and direction to see the four different cases: CodePen Embed Fallback Hmm, it’s working for the first two blocks but not the other ones. Quite strange, right? Actually, everything is working fine. The arcs are drawn outside the element area so nothing is visible. If you add some box-shadow, you can see them: CodePen Embed Fallback Arcs can be tricky due to the size and direction thing, so get ready to be confused. If that happens, remember that you have four different cases, and trying all of them will help you find which one you need. Now let’s try to be accurate and draw half a circle with a specific radius placed at the center: We can define the radius as a variable and use what we have learned so far: .shape { --r: 50px; clip-path: shape( from 0 0, line to calc(50% - var(--r)) 0, arc to calc(50% + var(--r)) 0 of var(--r), line to 100% 0, line to 100% 100%, line to 0 100% ); } CodePen Embed Fallback It’s working fine, but the code can still be optimized. We can replace all the line commands with hline and vline like below: .shape { --r: 50px; clip-path: shape(from 0 0, hline to calc(50% - var(--r)), arc to calc(50% + var(--r)) 0 of var(--r), hline to 100%, vline to 100%, hline to 0 ); } We can also replace the radius with 1%: .shape { --r: 50px; clip-path: shape(from 0 0, hline to calc(50% - var(--r)), arc to calc(50% + var(--r)) 0 of 1%, hline to 100%, vline to 100%, hline to 0 ); } When you define a small radius (smaller than half the distance between both points), no circle can meet the condition we explained earlier (an intersection with both points), so we cannot draw an arc. This case falls within an error handling where the browser will scale the radius until we can have a circle that meets the condition. Instead of considering this case as invalid, the browser will fix “our mistake” and draw an arc. This error handling is pretty cool as it allows us to simplify our shape() function. Instead of specifying the exact radius, I simply put a small value and the browser will do the job for me. This trick only works when the arc we want to draw is half a circle. Don’t try to apply it with any arc command because it won’t always work. Another optimization is to update the following: arc to calc(50% + var(--r)) 0 of 1%, …with this: arc by calc(2 * var(--r)) 0 of 1%, Almost all the commands can either use a to directive or a by directive. The first one defines absolute coordinates like the one we use with polygon(). It’s the exact position of the point we are moving to. The second defines relative coordinates which means we need to consider the previous point to identify the coordinates of the next point. In our case, we are telling the arc to consider the previous point (50% - R) 0 and move by 2*R 0, so the final point will be (50% - R + 2R) (0 + 0), which is the same as (50% + R) 0. .shape { --r: 50px; clip-path: shape(from 0 0, hline to calc(50% - var(--r)), arc by calc(2 * var(--r)) 0 of 1px, hline to 100%, vline to 100%, hline to 0 ); } This last optimization is great because if we want to move the cutout from the center, we only need to update one value: the 50%. .shape { --r: 50px; --p: 40%; clip-path: shape( from 0 0, hline to calc(var(--p) - var(--r)), arc by calc(2 * var(--r)) 0 of 1px, hline to 100%, vline to 100%, hline to 0 ); } CodePen Embed Fallback How would you adjust the above to have the cut-out at the bottom, left, or right? That’s your first homework assignment! Try to do it before moving to the next part. I will give my implementation so that you can compare with yours, but don’t cheat! If you can do this without referring to my work, you will be able to do more complex shapes more easily. CodePen Embed Fallback Rounded Tab Enough cut-out, let’s try to create a rounded tab: Can you see the puzzle of this one? Similar to the previous shape, it’s a bunch of arc and line commands. Here is the code: .shape { --r: 26px; clip-path: shape( /* left part */ from 0 100%, arc by var(--r) calc(-1 * var(--r)) of var(--r), vline to var(--r), arc by var(--r) calc(-1 * var(--r)) of var(--r) cw, /* right part */ hline to calc(100% - 2 * var(--r)), arc by var(--r) var(--r) of var(--r) cw, vline to calc(100% - var(--r)), arc by var(--r) var(--r) of var(--r) ); } It looks a bit scary, but if you follow it command by command, it becomes a lot clearer to see what’s happening. Here is a figure to help you visualize the left part of it. All the arc commands are using the by directive because, in all the cases, I always need to move by an offset equal to R, meaning I don’t have to calculate the coordinates of the points. And don’t try to replace the radius by 1% because it won’t work since we are drawing a quarter of a circle rather than half of a circle. CodePen Embed Fallback From this, we can easily achieve the left and right variations: CodePen Embed Fallback Notice how I am only using two arc commands instead of three. One rounded corner can be done with a classic border radius, so this can help us simplify the shape. Inverted Radius One last shape, the classic inner curve at the corner also called an inverted radius. How many arc commands do we need for this one? Check the figure below and think about it. If your answer is six, you have chosen the difficult way to do it. It’s logical to think about six arcs since we have six curves, but three of them can be done with a simple border radius, so only three arcs are needed. Always take the time to analyze the shape you are creating. Sometimes, basic CSS properties can help with creating the shape. What are you waiting for? This is your next homework and I won’t help you with a figure this time. You have all that you need to easily create it. If you are struggling, give the article another read and try to study the previous shapes more in depth. Here is my implementation of the four variations: CodePen Embed Fallback Conclusion That’s all for this first part. You should have a good overview of the shape() function. We focused on the line and arc commands which are enough to create most of the common shapes. Don’t forget to bookmark the SVG to CSS converter and keep an eye on my CSS Shape collection where you can find the code of all the shapes I create. And here is a last shape to end this article. CodePen Embed Fallback Better CSS Shapes Using shape() — Part 1: Lines and Arcs originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.
  19. by: Geoff Graham Thu, 22 May 2025 14:43:09 +0000 Clever, clever that Andy Bell. He shares a technique for displaying image alt text when the image fails to load. Well, more precisely, it’s a technique to apply styles to the alt when the image doesn’t load, offering a nice UI fallback for what would otherwise be a busted-looking error. The recipe? First, make sure you’re using alt in the HTML. Then, a little JavaScript snippet that detects when an image fails to load: const images = document.querySelectorAll("img"); if (images) { images.forEach((image) => { image.onerror = () => { image.setAttribute("data-img-loading-error", ""); }; }); } That slaps an attribute on the image — data-img-loading-error — that is selected in CSS: img[data-img-loading-error] { --img-border-style: 0.25em solid color-mix(in srgb, currentColor, transparent 75%); --img-border-space: 1em; border-inline-start: var(--img-border-style); border-block-end: var(--img-border-style); padding-inline-start: var(--img-border-space); padding-block: var(--img-border-space); max-width: 42ch; margin-inline: auto; } And what you get is a lovely little presentation of the alt that looks a bit like a blockquote and is is only displayed when needed. CodePen Embed Fallback Andy does note, however, that Safari does not render alt text if it goes beyond a single line, which 🤷‍♂️. You can style alt text like any other text originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.
  20. Blogger posted a blog entry in Linux Tips
    by: Adnan Shabbir Thu, 22 May 2025 08:59:25 +0000 The awk command is not just a command; it’s a scripting language, just like bash. The awk command is used for advanced pattern scanning, data extraction, and text manipulation. Because of its scripting support, it is useful for Linux power users, whether an administrator, a developer, or a Linux enthusiast. For instance, a system administrator can swiftly examine, i.e., log processing/analysis, tracking network IPs, generating reports, and monitoring system tasks. If you are looking to have a strong grip on awk technically, this guide provides a brief tutorial on the awk command, including its use cases with examples. awk Linux Command The awk command contains programming language features. Because of its diverse use cases, awk has left behind its command-line competitors, i.e., grep, cut, etc. So, before diving further into the awk command examples, let’s first discuss the following: How is the awk command better than grep, cut, and other competitors? Syntax of the awk Command For what Operations can you use the awk command How is the awk command better than grep, cut, and other competitors? Let’s quickly have a look at why awk beats grep, cut, and other competitors. The awk command has built-in variables that are used silently by default. For instance, the “FS” allows you to split the field with some character, and you can access and perform operations on them. The awk supports loops, variables, conditions, arrays, and functions, which are not supported by any of the awk’s competitors. The data can be presented beautifully using the built-in variables that other commands do not have. Syntax of the awk Command awk 'pattern {action}' file The quotes on this command are optional. When using multiple patterns, actions, you need to put the quotes; otherwise, they are not necessary to be used every time. Here’s the further breakdown of the awk: The “file” is the name of the file on which the “awk” is being applied. The ‘pattern {action}’ is the core part of awk: “pattern”: represents a condition, i.e., can be a regex, usually left blank to match all the lines. “action”: The operation to be executed after a successful pattern match. For What Operations can you use the awk Command The awk scripting language is broadly used in text processing. Let’s discuss what text processing operations can be performed using awk: Pattern scanning and processing. Text filtration, transformation, Editing/Modifying. Extracting data from fields or fields as a whole. File processing, i.e., single, multiple, supports different types of file processing Formatted output, i.e., getting output in another file, and print support Mathematical calculations, i.e., using conditions, looping support Controlled operation on the data, i.e., BEGIN, END System monitoring, i.e., using awk with other Linux commands to get the filtered results. That’s all from understanding the basics of the awk command. Now, let’s dig into the examples to learn practically. awk Command Examples The awk examples provided here were experimented on two files, “students.txt” and “class.txt”. Content of the “students.txt”: Content of the “class.txt”: Let’s start with the basic use cases. Print with awk Print is the primary operation of awk command. It can be done anytime and in any form to print the data. Example 1: Print All (in a single or multiple file) Use the print in the “{action}” part to print the content of the file: awk '{print}' file Example 2: Print Specific Columns Write the column number in place of the “n” to show the data of that column only: awk '{print $n}' file Example 3: Print a Specific Range of Data from the File You can specify the column range to retrieve only that specific data: awk 'NR==4, NR==8' file Example 4: Update any Field’s Value and Print it You need to specify the field that you want to update and its value. Then, you can print it or store the output in some other file. Here’s a demonstration: awk '{$3 = "New Value"; print}' file Just updates on the terminal, the original content remains the same. Example 5: Printing From Multiple Files The awk command can be applied to multiple files. Here’s how it works: awk '{print $1}' file1 file2 The command will print the first column/field of two different files: Matching a Specific Expression | awk With Regular Expressions Expressions are used with the “awk” command to match a specific pattern or a word in the file and perform any operation on it. Example 6: Matching the Exact Word The command below matches the expression and performs the operation based on that match. Here’s a simple example: awk '/Software/ {print}' file The command checks for the “Software” word and prints all the data records that contain the “Software” word. Example 7: Match the Start of the Character The “carrot” symbol is used to match the character with the start of the files in the file and then further operations can be performed. Here’s the practical: awk '/^110/ {print}' file Printing the lines that start with “110”: Example 8: Match the Endpoint Character Likewise, the end character can also be specified to match and print (or perform any other operation): awk '/Year$/ {print}' file The above command matches the “Year” and prints all the records that contain the word “year”. Bonus: Other Regex Characters The following are the rest of the Regex operators that can be used with awk to get more refined output: Regex Characters Description [ax] Picks only a and x characters [a-x] Picks all the characters that are in the range of a-x. \w Selects a word \s Blank Space character \d Selects a digit. Formatting the Data With awk | awk Variables ( NR, NF, FS, FNR, OFS, ORS) The awk variables are the built-in variables to process and manipulate the data. Each variable has its own purpose and refers to a record or a field. Let me first introduce all these variables to you: NR (Number of Records): The number of records being processed, i.e., if a file has 10 records (rows), then the NR’s value will range from 1 to 10. Example 9: Print the Number of Records Printing the record number of the data in a file: awk '{print NR, $2}' filename Example 10: Getting the Disk Usage Report Based on NR, the administrator can analyze the disk usage report: df -h | awk 'NR>1 { print $1, $5 }' The command gets the input from the df -h command and then pipes it with awk to get the filesystem name ($1) and the percentage ($5) used by each filesystem. Similarly, other resources’ performance and progress can also be checked using the NR in awk. NF (Number of Fields): Denotes the number of fields in each record. Example 11: Getting Number of Fields in a File Let’s see it through the following: awk '{print NF}' file The command prints the “NF” number of fields in each record of the target file: FS (Field Separator): This is the character used to separate the fields. It is a white space by default and a comma for an Excel file: Example 12: Printing the field separator awk ‘{print FS, $4}’ file This command prints the field separator: FNR (File Number of Record): Counting the number of records for each file when multiple files are being processed. For instance, when a single file is being processed, the NR value always starts from 1 and continues this number when multiple files are being processed, whereas the FNR value starts from 1 (for the new files) instead of continuing as NR. Example 13: Printing the Field Number Record with a Field awk '{print FNR, $4}' file The command prints the field number and the 4th field: OFS (Output Field Separator): This is the Output field separator, i.e. the character separating the output fields. The default output field separator is a space ( “ ” ). However, you can change or set a new field separator with the help of the OFS keyword: Example 14: Changing the Output Field Separator Let’s understand it practically: awk 'BEGIN {OFS=" - "} {print $3, $4}' file The command will print the 3rd and 4th columns from the specified file and will set the “–” as the new OFS: ORS (Output Record Separator): Likewise, OFS, this ORS represents the Output Record Separator. It is the space by default, however, you can change it as we are going to show you here practically. Example 15: Changing the Output Record Separator The following command will change the record separator to “|”: awk '{ORS =" | "} {print}' filename The record separator is now set to “ | ” for this specific output only. Advanced awk Examples Until now, we have gone through some basic and intermediate use cases of the awk example. Since awk also incorporates programming language features, so, here we’ll also discuss awk’s functionality with some advanced use cases: Example 16: Find the Largest Field in a File The following command uses the if-else statement to give you the length of the longest line in the file. Here’s an example to do so: awk '{if (length($0) > max) max = length($0)} END {print max}' file The “awk” is the command keyword, and the “file” on which the operation is being performed. The rest of the details are in quotes. The length($0) expression gets the length of the current line and checks if it is greater than “max”. If the condition is true, the “length($0)” is stored in “max” and the “max” is printed at the end. Similarly, if you want to check/get the minimum length of a line, then it would be: awk '{if (length($1) > min) min = length($1) } END {print min}' file Example 17: Get the Sum of the Field Values With awk, you can calculate the sum of any field. Here’s the practical demonstration: awk '{sum += $1} END {print "Total:", sum}' file A sum variable initially stores the first value from the first field ($1) The $1 (first field) values are being added to the already stored values in the sum. Example 18: Finding a Max Value in a Column Here, m is the variable that stores the maximum value: awk 'BEGIN{m=0} {if($2 > m) m=$1} END {print "Maximum Value:", m}' file Here’s the breakdown of the command: A variable “m” is initialized, then, if the value of the “2nd column” is greater than m, the “2nd column” value is stored in m. This continues until the condition “$2 > m” becomes false. Example 19: Count Specific Occurrences of a Word s is the looping variable, f shows the frequency, and “Year” word to be searched for the number of entries: awk '{for(s=1;s<=NF;s++) f[$s]++} END {for(Year in f) print Year, f[Year]}' file The “for loop” loops through all in each record using (NF). The “f[$s]++” expression stores each word in an associative array “f” and counts how many times it appears. In the END block, the for loop prints each unique word and its frequency (as a value) from an array. Example 20: Monitoring the Log Files To monitor the Apache access log file: awk '{print $n}' /var/log/apache2/access.log Similarly, you can keep track of the iptables.log files to track the IPs triggering the firewall logs. You can check out / print the iptables.log for that purpose, i.e., available at the location /var/log/iptables.log. Example 21: Search and Analyze | AWK with grep The grep is known for its data filtering and searching, and the awk extracts and manipulates data. Let’s see the practical to check how these utilities work together: grep "Software" file | awk "{print $3}" Here’s the breakdown of the above command: grep “Software” will only filter and select the records containing the “Software” keyword. The awk command prints the columns containing the “Software” word. Similarly, grep and awk can be applied to other log files or system files to filter and analyze the specific log-related information. Example 22: Substituting | AWK with sed The “sed” command edits and manipulates the text. So, the output of the awk command can be piped with the sed to perform specific operations on the output, or individually: Let’ see the practical, using the following simple command: awk '{print $3, $4}' file | sed 's/ /,/g' The awk command prints the 3rd and 4th columns of the file, and the sed command substitutes the “,” in place of the white spaces in the document file globally. Functions in awk Since awk is a scripting language, it has a long list of functions that are used to perform various functions. Some of these are used in the above examples, i.e., length(n). Here, we will elaborate on a few functions and their use cases. Substituting in awk with Functions The awk has “sub” and “gsub” as two substitution functions; let’s understand these through examples: Note: The file on which the “sub” and “gsub” functions will be experimented with. Example 23: Substitute the First Occurrence (in each record) Only | awk with sub The “sub” function substitutes the first occurrence of the matching word/expression in each record. Here is an example command to understand: awk '{sub("Year", "Y"); print}' file The first occurrence of the word “Year” will be replaced with the “Y”: Example 24: Substitute all the instances of a word/Expression | awk with gsub The “gsub” globally substitutes the matching keyword, i.e., all the occurrences of the matching keyword. Here’s an example: awk '{ gsub("Year", "Y"); print }' file Now, all the occurrences will be replaced: Example 25: Get the UNIX Timestamp | awk with systime() The awk command has the systime() function to get the UNIX timestamp of the fields or for the whole system. Let’s practice it: awk 'BEGIN {print systime()}' file The command will print the UNIX timestamp for each of the records (when modified last time) of the file: Similarly, you can get the overall UNIX time using the command: awk 'BEGIN {print systime()}' Other awk Functions: Because of its scripting support, the awk has a long list of supported functions. The following table lists some of these and also describes their purpose with syntax: awk Function Description/Purpose Syntax length() Length of the current line awk ‘{print length()}’ file substr(a, b, c) Extracting a substring from string a, the length starts at b, and the overall length is c. awk ‘{print substr($a, b, c)}’ file split(a,b,c) Split string a into array b using a separator c. awk ‘{split($a, arr, “:”); print arr[a] }’ file tolower(a) Converts the a to lowercase awk ‘{print tolower($a)}’ file toupper(a) Converts the a to uppercase awk ‘{print tolower($a)}’ file int(a) Converts the $a into an integer awk ‘{print int($a)} file’ sqrt(a) Square root of $a. awk ‘{print sqrt($a)}’ file srand() Seeding a random generator awk ‘BEGIN { srand(); print rand() }’ rand() Random generator That’s all from this tutorial. Conclusion The awk utility is an effective command-line tool that serves as a scripting language, too. From a basic search and find to running it for advanced scripting, the awk is a full package. This post has a brief overview and explanation of the awk command in Linux, with advanced examples. FAQs Q 1: What does awk stand for? The awk is named after its inventors, i.e., Aho, Weinberger, and Kernighan. They designed awk at AT&T Bell Laboratories in 1977. Q 2: What is awk in Linux? Ans: The awk is a powerful command-line utility and a scripting language. The awk is used to: read the data, search and scan for patterns, print, format, calculate, analyze, and more. For these use cases, awk sometimes has to be used with grep, sed, and normal regular expressions. Q 3: What does awk ‘{print $2}’ mean? The awk ‘{print $2}’ will print the 2nd (second) field of the file on the terminal. If used with multiple files, then the 2nd (second field of multiple files will be printed. Q 4: What is the difference between awk and grep? The grep performs the searching and filtering up to some extent, while the awk utility extracts, manipulates, and analyzes the data. The awk and grep are used together for search and analysis purposes, i.e., grep provides the searching/filtering support, where the awk performs the analysis. Q 5: What is the difference between awk and bash? Bash is recommended for professional scripting. However, where scripting and basic operations on the terminal are required, then awk is good. Both awk and bash are scripting languages. However, the simpler tasks are performed swiftly using awk as compared to bash. Q6: How do I substitute using awk? The awk supports two functions for substituting, i.e., sub and gsub. The sub is used to substitute the first occurrence of the matching word, whereas the gsub is used for global substitution of the matching word.  
  21. by: Abhishek Kumar Thu, 22 May 2025 07:40:49 GMT It took me way longer than I’d like to admit to wrap my head around MCP servers. At first glance, they sound like just another protocol in the never-ending parade of tech buzzwords decorated alongside AI. But trust me, once you understand what they are, you start to see why people are obsessed with them. This post isn’t meant to be the ultimate deep dive (I’ll link to some great resources for that at the end). Instead, consider it just a lil introduction or a starter on MCP servers. And no, I’m not going to explain MCP using USB-C as a metaphor, if you get that joke, congrats, you’ve clearly been Googling around like the rest of us. If not… well, give it time. 😛 Source: Norah Sakal's BlogWhat even is an MCP Server?MCP stands for Model Context Protocol, an open standard introduced by Anthropic in November 2024. Its purpose is to improve how AI models interact with external systems, not by modifying the models themselves, but by providing them structured, secure access to real-world data, tools, and services. An MCP server is a standalone service that exposes specific capabilities such as reading files, querying databases, invoking APIs, or offering reusable prompts, in a standardized format that AI models can understand. Rather than building custom integrations for every individual data source or tool, developers can implement MCP servers that conform to a shared protocol. This eliminates the need for repetitive boilerplate and reduces complexity in AI applications. What can an MCP Server actually do?Source: XQuite a bit. Depending on how they’re set up, MCP servers can expose: Resources – Stuff like files, documents, or database queries that an AI can read.Tools – Actions like sending an email, creating a GitHub issue, or checking the weather.Prompts – Predefined instructions or templates that guide AI behavior in repeatable ways.Each of these is exposed through a JSON-RPC 2.0 interface, meaning AI clients can query what's available, call the appropriate function, and get clean, structured responses.https://www.anthropic.com/ So... how does an MCP server actually work?MCP servers follow a well-defined architecture intended to standardize how AI models access external tools, data, and services. MCP client-server architecture | Source: modelcontextprotocol.ioEach part of the system has a clear role, contributing to a modular and scalable environment for AI integration. Host Applications These are the environments where AI agents operate, such as coding assistants, desktop apps, or conversational UIs. They don’t interact with external systems directly, but instead rely on MCP clients to broker those connections.MCP Clients The client is responsible for managing the connection between the AI agent and the MCP server. It handles protocol-level tasks like capability discovery, permissions, and communication state. Clients maintain direct, persistent connections to the server, ensuring requests and responses are handled correctly.MCP Servers The server exposes defined capabilities such as reading files, executing functions, or retrieving documents using the Model Context Protocol. Each server is configured to present these capabilities in a standardized format that AI models can interpret without needing custom integration logic.Underlying Data or Tooling This includes everything the server is connected to: file systems, databases, external APIs, or internal services. The server mediates access, applying permission controls, formatting responses, and exposing only what the client is authorized to use.This separation of roles between the model host, client, server, and data source, allows AI applications to scale and interoperate cleanly. Developers can focus on defining useful capabilities inside a server, knowing that any MCP-compatible client can access them predictably and securely. Wait, so how are MCP Servers different from APIs?Fair question. It might sound like MCP is just a fancy wrapper around regular APIs, but there are key differences: FeatureTraditional APIMCP ServerPurposeGeneral software communicationFeed AI models with data, tools, or promptsInteractionRequires manual integration and parsingPresents info in model-friendly formatStandardizationVaries wildly per serviceUnified protocol (MCP)SecurityMust be implemented case-by-caseBuilt-in controls and isolationUse CaseBackend services, apps, etc.Enhancing AI agents like Claude or Copilot or Cursor Basically, APIs were made for apps. MCP servers were made for AI. Want to spin up your own self-hosted MCP Server?While building a custom MCP server from scratch is entirely possible, you don’t have to start there. There’s already a growing list of open-source MCP servers you can clone, deploy, and start testing with your preferred AI assistant like Claude, Cursor, or others. mcpservers.org is an amazing website to find open-source MCP ServersIf you're interested in writing your own server or extending an existing one, stay tuned. We’re covering that in a dedicated upcoming post, we'll walk through the process step by step in an upcoming post, using the official Python SDK. Make sure you’re following or better yet, subscribe, so you don’t miss it. Want to learn more on MCP?Here are a few great places to start: I personally found this a good introduction to MCP Servers How I Finally Understood MCP — and Got It Working in Real Life - towards data scienceWhat are MCP Servers And Why It Changes Everything - HuggingfaceConclusionAnd there you have it, a foundational understanding of what MCP servers are, what they can do, and why they’re quickly becoming a cornerstone in the evolving landscape of AI. We’ve only just scratched the surface, but hopefully, this introduction has demystified some of the initial complexities and highlighted the immense potential these servers hold for building more robust, secure, and integrated AI applications. Stay tuned for our next deep dive, where we’ll try and build an MCP server and a client from scratch with the Python SDK. Because really, the best way to learn is to get your hands dirty. Until then, happy hacking. 🧛
  22. by: Abhishek Prakash Thu, 22 May 2025 04:36:31 GMT I have an interesting story to share. You are probably already aware that many products and services offer a trial version for a limited time. And some people try to take advantage of the trial period by creating new accounts with new email addresses. But imagine if a multi-million dollar enterprise does the same. And it does so for an open source software that they could have managed on their own. Free as in Fraud? A $130M Aerospace Company Caught Exploiting Open Source TrialAn unnamed $130M company has been exploiting Xen Orchestra’s free trial for over a decade.It's FOSS NewsSourav Rudra💬 Let's see what else you get in this edition More new default apps in Ubuntu 25.10.Fedora's Wayland decision.Systemd free distros.Making Bash beautiful.And other Linux news, tips, and, of course, memes!This edition of FOSS Weekly is supported by ANY RUN.💖 Grab your ANY.RUN's 9th Birthday special offersAnalyze, investigate, and detect cyber threats with unmatched speed and depth. Interactive Sandbox licenses for your team: Subscription Plans - ANY.RUNInteractive malware hunting service. Live testing of most type of threats in any environments. No installation and no waiting necessary.ANY.RUNSpeed up alert triage and response in your SOC. The offers are active until May 31. 📰 Linux and Open Source NewsFFmpeg has taken a swipe at rust.VS Code is gearing up for an AI-first makeover.WSL is now open source under the MIT license.Microsoft has fixed a dual-boot issue that broke Linux.Warp terminal (non-FOSS) now has experimental support for MCP.2025 looks like a great year for open source, with a few corporate donations.Ubuntu 25.10 will feature new terminal and image viewer apps. Ubuntu 25.10 will Have a Brand New Terminal (and Image Viewer)Ubuntu 25.10 replaces its default terminal and image viewer with modern apps.It's FOSS NewsSourav Rudra🧠 What We’re Thinking AboutAre we finally entering the Xorg-less era? Fedora has taken the bold move to go for Wayland-only desktop offering in the upcoming version 43. No More Xorg! Fedora 43 Will Be Wayland-onlyA bold move by Fedora. Will everyone be onboard?It's FOSS NewsSourav Rudra🧮 Linux Tips, Tutorials and MoreImagine Oh My Zsh but for Bash. The Bash-it framework lets you enjoy a beautiful bash shell experience. I am just surprised that it is not called Oh My Bash 😜Not trying to re-ignite the systemd vs sysvinit debate. Just sharing a list of systemd-free distros in the age where most distros are systemd-first.Take advantage of multi-cursor editing in VS Code to simplify repetitive actions.Try Sausage, and enjoy the classic Bookworm game like experience in the terminal. Play With Words in Linux Terminal With With Bookworm Style GameRemember the classic Bookworm game? You can have similar fun in the terminal with Sausage.It's FOSSAbhishek Prakash Remember your favorite tech websites like Anand Tech or magazines like Linux Voice? They don't exist anymore. In the age of AI Overview in search engines, more and more people are not even reaching the websites from where AI is 'copying' the text. As a result, your favorite websites continue to shut down. More than ever, now is the most crucial time to save your favorite websites from AI onslaught. If you like what we do and would love to support our work, please become It's FOSS Plus member. It costs $24 a year, i.e. $2 a month. Even a burger costs more than $2. For skipping a burger a month, you get an ad-free reading experience with the satisfaction of helping the desktop Linux community. Join It's FOSS Plus 👷 Homelab and Maker's CornerTroubleshooting your Pi? Don’t ignore those blinking LEDs! They are a powerful diagnostic tool that are super handy in headless setup. Red and Green LED Lights on Raspberry Pi and Their MeaningRaspberry Pi’s status LEDs are a surprisingly powerful diagnostic tool, especially for headless setups.It's FOSSAbhishek Kumar✨ Apps HighlightDoodle lets you pixelify your Android smartphone with its cool wallpaper collection. Pixelify Your Android Smartphone with This Wallpaper AppTransform your Android smartphone’s home screen with battery-friendly live wallpapers.It's FOSS NewsSourav RudraHow about an open source, decentralized alternative to the likes of Discord and Slack? Peersuite is a self-hostable peer-to-peer workspace that isn't user data hungry. 📽️ Videos I am Creating for YouMan pages are good but not easy to follow, specially for new Linux users. Here are some alternatives to the man pages in Linux. See them in action. Subscribe to It's FOSS YouTube Channel🧩 Quiz TimeCan you beat the Essential Ubuntu Shortcuts puzzle? Essential Ubuntu Shortcuts: PuzzleDo you know all the handy Ubuntu shortcuts? Solve this puzzle to find out!It's FOSSAnkush Das💡 Quick Handy TipIn file managers like Nemo, Nautilus, etc., you can easily create file duplicates by pressing the CTRL key and dragging the file to a blank space in the window. If you drop a file while pressing the CTRL key when in another folder, the file will be copied to that directory. Use CTRL+Z to undo the file duplication. During this, your file manager will ask you whether you want to delete the copied file. 🤣 Meme of the WeekThe man's got a Debian-flavored beard. 😆 🗓️ Tech TriviaOn May 18, 1998, the U.S. Department of Justice sued Microsoft, alleging that the company was illegally monopolizing the web browser market by integrating its Internet Explorer browser into its Windows operating system. 🧑‍🤝‍🧑 FOSSverse CornerPro FOSSer Neville has compiled a table of Linux distros for beginners that is really well-made. I am so proud of our active community members 🙏 Table of Linux Distros by Difficulty for BeginnersThe outcome of discussion in the forum topic was a table representing collective experience of forum members regarding Linux distros which are easy or difficult for beginners. @Tech_JA suggested that we place the final table in a fresh topic where it is not buried among 130 replies. Thanks Jorge. In future our table will be updated here. Last revision 17/5/25 Difficulty Systemd distros Non-systemd distros Beginner Mint LMDE MX/Systemd MX/sysVinit Peppermint/Debian Pepp…It's FOSS Communitynevj❤️ With loveShare it with your Linux-using friends and encourage them to subscribe (hint: it's here). Share the articles in Linux Subreddits and community forums. Follow us on Google News and stay updated in your News feed. Opt for It's FOSS Plus membership and support us 🙏 Enjoy FOSS 😄
  23. by: Geoff Graham Wed, 21 May 2025 15:09:29 +0000 Shape master Temani Afif has what might be the largest collection of CSS shapes on the planet with all the tools to generate them on the fly. There’s a mix of clever techniques he’s typically used to make those shapes, many of which he’s covered here at CSS-Tricks over the years. Some of the more complex shapes were commonly clipped with the path() function. That makes a lot of sense because it literally accepts SVG path coordinates that you can draw in an app like Figma and export. But Temani has gone all-in on the newly-released shape() function which recently rolled out in both Chromium browsers and Safari. That includes a brand-new generator that converts path() shapes in shape() commands instead. So, if we had a shape that was originally created with an SVG path, like this: .shape { clip-path: path( M199.6, 18.9c-4.3-8.9-12.5-16.4-22.3-17.8c-11.9-1.7-23.1, 5.4-32.2, 13.2c-9.1, 7.8-17.8, 16.8-29.3, 20.3c-20.5, 6.2-41.7-7.4-63.1-7.5c38.7, 27, 24.8, 33, 15.2, 43.3c-35.5, 38.2-0.1, 99.4, 40.6, 116.2c32.8, 13.6, 72.1, 5.9, 100.9-15c27.4-19.9, 44.3-54.9, 47.4-88.6c0.2-2.7, 0.4-5.3, 0.5-7.9c204.8, 38, 203.9, 27.8, 199.6, 18.9z ); } …the generator will spit this out: .shape { clip-path: shape( from 97.54% 10.91%, curve by -10.93% -10.76% with -2.11% -5.38%/-6.13% -9.91%, curve by -15.78% 7.98% with -5.83% -1.03%/-11.32% 3.26%, curve by -14.36% 12.27% with -4.46% 4.71%/-8.72% 10.15%, curve by -30.93% -4.53% with -10.05% 3.75%/-20.44% -4.47%, curve to 7.15% 25.66% with 18.67% 15.81%/11.86% 19.43%, curve by 19.9% 70.23% with -17.4% 23.09%/-0.05% 60.08%, curve by 49.46% -9.07% with 16.08% 8.22%/35.34% 3.57%, curve by 23.23% -53.55% with 13.43% -12.03%/21.71% -33.18%, curve by 0.25% -4.77% with 0.1% -1.63%/0.2% -3.2%, curve to 97.54% 10.91% with 100.09% 22.46%/99.64% 16.29%, close ); } Pretty cool! CodePen Embed Fallback Honestly, I’m not sure how often I’ll need to convert path() to shape(). Seems like a stopgap sorta thing where the need for it dwindles over time as shape() is used more often — and it’s not like the existing path() function is broken or deprecated… it’s just different. But still, I’m using the generator a LOT as I try to wrap my head around shape() commands. Seeing the commands in context is invaluable which makes it an excellent learning tool. SVG to CSS Shape Converter originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.
  24. by: Abhishek Prakash Wed, 21 May 2025 16:16:09 +0530 Have you ever watched a bearded sysadmin navigate their editor with lightning speed, jumping between multiple panes with the flick of a few keystrokes? That's the magic of Vim's split window feature! Think of it as having multiple monitors inside a single screen. And you don't even need screen command or tmux tools for this purpose. Vim does it on its own. Split Windows in Vim EditorYou can split the screen horizontally as well as vertically. And all this is done with a few keystrokes, of course. Vim split window keyboard shortcuts Action Keyboard Shortcut Description Horizontal split :split or :sp Splits window horizontally Vertical split :vsplit or :vs Splits window vertically Close current window :q or :close Closes the active window Close all except current :only or :on Closes all windows except active one Navigate between windows Ctrl-w + h/j/k/l Move to left/down/up/right window Navigate between windows Ctrl-w + Ctrl-w Cycle through all windows Resize horizontally Ctrl-w + < or > Decrease/increase width Resize vertically Ctrl-w + - or + Decrease/increase height Equal size windows Ctrl-w + = Make all windows equal size Maximize height Ctrl-w + _ Maximize current window height Maximize width Ctrl-w + | Maximize current window width Move window Ctrl-w + r Rotate windows Swap with next window Ctrl-w + x Exchange with next window You can also use the mouse for resizing and some other features if you have mouse enabled in Vim. Creating Split windowsLet's see in details about how those magical keys work and look like in the editor. Horizontal splitsCreating a horizontal split in Vim is like adding a floor to your house - you're stacking views on top of each other. When you're deep in code and need to reference something above or below your current focus, horizontal splits come to the rescue. :split filename (or :sp filename) 0:00 /0:11 1× Horizontal split in action Filename is optional here. If you don't specify a filename, Vim will split the window and show the current file in both panes. 💡Use :set splitbelow to open the new windows below the current one.Vertical splitsVertical splits open windows side-by-side. It's good for viewing documentation, or keeping an eye on multiple parts of your project. You can also use it for quickly comparing two files if you do not want to use the dedicated vimdiff. :vsplit filename (or :vs filename) 0:00 /0:12 1× Vertical split in action 💡By default, the new windows are opened on the left of the current window. Use :set splitright to open the new windows on the right.Moving between split windowsOnce you've created splits, hopping between them is where the real productivity starts. Think of Ctrl-w as your magic wand - when followed by a direction key, it teleports your cursor to that window. Ctrl-w followed by w will switch to the below/right window.Ctrl-w followed by W (uppercase W or Shift-w key) will switch to the above/left window.I prefer the direction keys, though. It is easier to navigate this way in my opinion. Ctrl-w h # Move to the window on the left Ctrl-w j # Move to the window below Ctrl-w k # Move to the window above Ctrl-w l # Move to the window on the right 0:00 /0:15 1× Move between splits You can also use the arrow keys instead of the typical hjkl Vim movement keys. 💡If remembering directions feels like a mental gymnastics routine, just cycle through all the windows by pressing Ctrl-w Ctrl-w. Pressing them multiple times in pair and you'll move from one split window to the next.I'll be honest - when I first started using Vim, I kept forgetting these window navigation commands. So, I thought of Ctrl-w as "window" followed by the direction I wanted to go. After a few days of practice, my fingers remembered even when my brain forgot! Resizing split windowsNot all windows are created equal. Some need more space than others, based on your need. Vim lets you adjust your viewing space with a few keystrokes. Ctrl-w + # Increase height by one line Ctrl-w - # Decrease height by one line Ctrl-w > # Increase width by one column Ctrl-w < # Decrease width by one column 0:00 /0:21 1× Resize split windows For faster resizing, prefix these commands with a number: 10 Ctrl-w + # Increase height by 10 lines When things get too chaotic, there's always the great equalizer: Ctrl-w = # Make all windows equal size Just so that you know, you can also create splits with specific dimensions by adding a number before the command. For example, :10split creates a horizontal split with 10 lines of height, while :30vsplit creates a vertical split that's 30 characters wide. 💡Need maximum space ASAP? Try these power moves: Ctrl-w _ maximizes the current window's height Ctrl-w | maximizes the current window's width Ctrl-w = equalizes all windows when you're ready to share again I call this the "focus mode toggle" - perfect for when you need to temporarily zoom in on one particular section of a file!Moving and rearranging WindowsSometimes you create the perfect splits but realize they're in the wrong order. Rather than closing and recreating them, you can rearrange your windows like furniture: Ctrl-w r # Rotate windows downward/rightward Ctrl-w R # Rotate windows upward/leftward Ctrl-w x # Exchange current window with the next one 0:00 /0:28 1× Rearrange split windows You can also completely move a window to a new position: Ctrl-w H # Move current window to far left Ctrl-w J # Move current window to very bottom Ctrl-w K # Move current window to very top Ctrl-w L # Move current window to far right It's like playing Tetris with your editor layout. While I am a fan of the classic Tetris game, I am not a fan of moving and rearranging the windows unless it is really needed. 💡 Few random but useful tipsLet me share a few more tips that will help your workflow when you are dealing with split windows in Vim. Add terminal in the mixIf you are in a situation where you want to look at your code and run it at the same time, like an IDE, you can add a terminal in your split. No more alt-tabbing between terminal and editor! :sp | terminal opens a horizontal split with a terminal :vs | terminal opens a vertical split with a terminalTerminal is split window in VimStart split with VimWant to start Vim with splits already configured? You can do that from your command line: # Open two files in horizontal splits vim -o file1 file2 # Open two files in vertical splits vim -O file1 file2 # Open three files in horizontal splits vim -o3 file1 file2 file3 File explorer in split windowsOne of my favorite tricks is opening Vim's built-in file explorer (netrw) in a split: :Sexplore # Open file explorer in horizontal split :Vexplore # Open file explorer in vertical split Vim file explorer in split windowIt's like having a mini file manager right next to your code - perfect for quickly navigating project files without losing your place in the current file. Close all the split windows and exit VimWhen you are done with your tasks on a project, instead of closing individual split windows, you can close all of them together and exit Vim :qa Save your work before, of course. Wrapping upSplits aren't just a cool feature - they're a strategic tool. You can use it to edit files with reference doc open on the side or to watch log output in the terminal while debugging. It's up to you how you use this amazing feature. It might seem like keyboard gymnastics at first, but quickly becomes second nature. Like learning to touch type or ride a bike, the initial awkwardness gives way to fluid motions that you'll hardly think about. Start small - maybe just two vertical splits - and gradually incorporate more commands as you get comfortable. Before long, you'll be that expert terminal dweller others watch in amazement as you effortlessly dance between multiple files without ever touching your mouse. Happy splitting! 🚀
  25. by: Abhishek Kumar Wed, 21 May 2025 02:40:20 GMT Working with code often involves repetition, changing variable names, updating values, tweaking class names, or adding the same prefix across several lines. If you find yourself making the same changes again and again, line by line, then multi-cursor editing in Visual Studio Code can help simplify that process. In this part of our ongoing VS Code series, we’ll take a closer look at this feature and how it can make everyday tasks quicker and more manageable. Why use multiple cursors?Multi-cursor editing lets you place more than one cursor in your file so you can edit several lines at once. Instead of jumping between lines or writing the same change repeatedly, you can type once and apply that change across multiple places. Here are a few common situations where it comes in handy: Renaming a variable or function in multiple places.Adding or removing the same snippet of code across several lines.Editing repeated structures (like object keys, class names, or attribute values).Commenting out a bunch of lines quickly.Once you start using it, you’ll notice it helps reduce small repetitive tasks and keeps your focus on the code itself. Placing multiple cursors: mouse and keyboardThere are two main ways to place multiple cursors in VS Code using the mouse or keyboard shortcuts. Let’s start with the mouse-based approach, which is more visual and straightforward for beginners. Then, we’ll move on to keyboard shortcuts, which are faster and more efficient once you’re comfortable. Method 1: Using the mouseTo place cursors manually using your mouse: Hold down Alt (Windows/Linux) or Option (Mac), then click anywhere you want to insert a new cursor. Each click places a new blinking cursor. You can now type, delete, or paste, and the change will reflect at all cursor positions simultaneously. To cancel all active cursors and return to a single one, press Esc. This method is handy for quick edits where the lines aren’t aligned or when you want more control over cursor placement. Method 2: Using keyboard shortcutsThe mouse method is a good starting point, but learning keyboard shortcuts can save more time in the long run. Below are a few keyboard-driven techniques to add and manage multiple cursors efficiently. Add Cursors Vertically in a ColumnWhen you want to add cursors above or below the current line to edit a block of similar lines (like inserting or deleting the same code at the beginning of each line), use this shortcut: Ctrl+ Alt + Up/Down arrow keys. This aligns cursors in a vertical column, making it easier to apply the same action to adjacent lines. Select the next occurrence of the current wordTo select and edit repeated words one by one such as variable names or function calls, place your cursor on the word and use: Ctrl + D Each press selects the next matching word and adds a cursor to it. You can press it repeatedly to continue selecting further matches. Select all occurrences of a word in the fileIf you want to update every instance of a word across the file at once, for example, replacing a class name or a repeated property, use: Ctrl + Shift + L This selects all matching words and places a cursor at each one. It’s powerful, but use with care in large files to avoid unintentional edits. Editing with multiple cursorsOnce your cursors are in place, editing works just like usual: Type to insert text across all cursors.Use Backspace or Delete to remove characters.Paste snippets — they get applied to each cursor position.Standard commands like cut, copy, undo, and redo all function as expected.Just keep an eye on alignment. If cursors are placed unevenly across lines, your edits might not be consistent. Since you seem to be interested, check out some of the other VS Code keyboard shortcuts. 15 Best VS Code Keyboard Shortcuts to Increase ProductivityDo you want to be highly productive? Get familiar and memorize these VS Code keyboard shortcuts for Linux, Windows, and macOS.It's FOSSCommunityWrapping UpMulti-cursor editing is one of those small but effective features in VS Code that can make repetitive tasks less of a chore. You don’t need to learn all the shortcuts right away. Start simple, try placing cursors with Ctrl + D or selecting multiple lines vertically and build from there. As you become more comfortable, these techniques will become second nature and help you focus more on writing logic and less on repeating edits.
  26. by: Abhishek Kumar Tue, 20 May 2025 03:07:08 GMT While setting up a Raspberry Pi 5 for a new project, I decided to go with a headless setup - no display, keyboard, or mouse. I flashed the SD card, connected power, and waited for the Pi to appear on my network. But nothing showed up. I scanned my network, double-checked the router’s client list, still no sign of the Pi. Without access to a display, I had no immediate way to see what was happening under the hood. Then I noticed something: the green status LED was blinking in a repeating pattern. It wasn’t random, it looked deliberate. That small detail led me down a rabbit hole, and what I found was surprisingly useful. The Raspberry Pi’s onboard LEDs aren’t just indicators, they’re diagnostic tools. When the Pi fails to boot, it can signal the cause through specific blink patterns. If you know how to read them, you can identify problems like missing boot files, SD card issues, or hardware faults without plugging in a monitor. In this guide, we’ll decode what those LED signals mean and how to use them effectively in your troubleshooting process. 📋The placement, colors, and behavior of the status LEDs vary slightly across different Raspberry Pi models. In this guide, we'll go through the most popular models and explain exactly what each LED pattern means.Raspberry Pi 5The Raspberry Pi 5 is a major step up in terms of power and architecture. It packs a 2.4GHz quad-core ARM Cortex-A76 CPU, supports up to 16GB of LPDDR4X RAM, and includes PCIe, RTC, and power button support. Raspberry Pi 5But when it comes to diagnostics, the big upgrade is in the STAT LED. On the Pi 5: Red LED (PWR): Shows power issues (not always ON by default!)Green LED (STAT): Shows SD card activity and blink codesEthernet LEDs: Show network statusHere’s what the green LED blink codes mean: Long Flash Short Flash Meaning 0 3 Generic failure to boot 0 4 start.elf not found 0 7 kernel.img not found 0 8 SDRAM failure 0 9 Insufficient SDRAM 0 10 In HALT state 2 1 Boot device not FAT formatted 2 2 Failed to read boot partition 2 3 Extended partition not FAT 2 4 File signature/hash mismatch 3 1 SPI EEPROM error 3 2 SPI EEPROM write protected 3 3 I2C error 3 4 Invalid secure boot configuration 4 3 RP1 not found 4 4 Unsupported board type 4 5 Fatal firmware error 4 6 Power failure Type A 4 7 Power failure Type B Thanks to the bootloader residing on the onboard EEPROM (Electrically Erasable Programmable Read-Only Memory), the Raspberry Pi 5 can perform much more detailed self-checks right from the start. Raspberry Pi 4 & 400The Raspberry Pi 4 and the keyboard-integrated Raspberry Pi 400 also feature sophisticated LED diagnostics, similar in many ways to the Pi 5. Raspberry Pi 4BThe Raspberry Pi’s onboard LEDs aren’t just indicators, they’re diagnostic tools. They typically have: Red LED (PWR): Indicates power status. On the Pi 4/400, this LED is solid ON when the board is receiving sufficient power. If it's off or flickering, suspect a power issue.Green LED (ACT): The activity LED. While showing SD card activity, like the Pi 5, it also flashes specific patterns to indicate boot issues.Ethernet LEDs: Found on the Ethernet port (Pi 4 only), showing network link and activity.Like the Pi 5, the Raspberry Pi 4 and 400 boot from onboard EEPROM, enabling them to run more detailed diagnostics than older models. The flash codes for the green ACT LED on the Raspberry Pi 4 and 400 are identical to the Pi 5 codes listed above. Long Flash Short Flash Meaning 0 3 Generic failure to boot 0 4 start.elf not found 0 7 kernel.img not found 0 8 SDRAM failure 0 9 Insufficient SDRAM 0 10 In HALT state 2 1 Boot device not FAT formatted 2 2 Failed to read boot partition 2 3 Extended partition not FAT 2 4 File signature/hash mismatch 3 1 SPI EEPROM error 3 2 SPI EEPROM write protected 3 3 I2C error 3 4 Invalid secure boot configuration 4 3 RP1 not found 4 4 Unsupported board type 4 5 Fatal firmware error 4 6 Power failure Type A 4 7 Power failure Type B Raspberry Pi 3 Model B, B+, and A+Moving back a generation, the Raspberry Pi 3 models were popular for their performance and features. Raspberry Pi 3B+These boards typically have: Red LED (PWR): Solid ON when receiving adequate power. Off or flickering suggests a power problem.Green LED (ACT): Indicates SD card activity. It also flashes error codes if the boot process fails.Ethernet LEDs: Found on the Ethernet port (Model B and B+), showing network link and activity. The slimline Model A+ lacks the Ethernet port and thus these LEDs.Unlike the Pi 4 and 5, the Raspberry Pi 3 boards rely entirely on the SD card for the initial boot process (there's no onboard EEPROM bootloader). This means the diagnostic capabilities are slightly less extensive, but the green ACT LED still provides valuable clues about common boot problems. Here's what the green ACT LED flashes mean on the Raspberry Pi 3 models: Flashes Meaning 3 start.elf not found 4 start.elf corrupt 7 kernel.img not found 8 SDRAM not recognized (bad image or damaged RAM) Irregular Normal read/write activity Raspberry Pi 2 and Pi 1 (Model B, B+, A, A+)This group covers some of the earlier but still widely used Raspberry Pi boards, including the Raspberry Pi 2 Model B, and the various iterations of the original Raspberry Pi 1 (Model B, Model B+, Model A, Model A+). Raspberry Pi 1B+Their LED setups are similar to the Pi 3: Red LED (PWR): Solid ON for sufficient power. Off or flickering indicates a power problem.Green LED (ACT): Shows SD card activity and signals boot errors.Ethernet LEDs: Present on models with an Ethernet port (Pi 2 B, Pi 1 B, Pi 1 B+).They lack advanced diagnostics and rely on the same basic LED flash codes as the Pi 3 series: Flashes Meaning 3 start.elf not found 4 start.elf corrupt 7 kernel.img not found 8 SDRAM not recognized Irregular Normal SD card activity Raspberry Pi Zero and Zero WThe incredibly compact Raspberry Pi Zero and Zero W models are known for their minimalist design, and this extends to their LEDs as well. Raspberry Pi Zero WThe most significant difference here is the absence of the Red (PWR) LED. The Pi Zero series only features: Green LED (ACT): This is the only status LED. It indicates SD card activity and, importantly, signals boot errors. Flashes Meaning 3 start.elf not found 4 start.elf corrupt 7 kernel.img not found 8 SDRAM not recognized Irregular Normal SD activity Since there's no PWR LED, diagnosing power issues can be slightly trickier initially. If the green ACT LED doesn't light up at all, it could mean no power, an improperly inserted SD card, or a corrupted image preventing any activity. Pironman 5 Case With Tower Cooler and Fan This dope Raspberry Pi 5 case has a tower cooler and dual RGB fans to keep the device cool. It also extends your Pi 5 with M.2 SSD slot and 2 standard HDMI ports. Explore Pironman 5 ConclusionIn conclusion, Raspberry Pi’s status LEDs are a surprisingly powerful diagnostic tool, especially for headless setups. They allow you to troubleshoot and pinpoint issues without needing a screen or direct access to the Pi. It’s an intriguing feature that makes the Pi even more versatile for remote projects, as long as you know what the blink codes mean. After all, knowing the code is half the battle, without it, those flashing lights might as well be a mystery show. You can take your debugging to the next step by adding a UART to your Pi and fetch the debugging data in your computer. Using a USB Serial Adapter (UART) to Help Debug Raspberry PiA UART attached to your Raspberry Pi can help you troubleshoot issues with your Raspberry Pi. Here’s what you need to know.It's FOSSPratham PatelIn the same context, knowing the Raspberry Pi pinout is always helpful. Understanding the Raspberry Pi 5 Pin OutLet’s take a closer look at each pin in Raspberry Pi 5 and its specific function to ensure you’re well-prepared for your project.It's FOSSAbhishek KumarWhat do you think? Have you ever used the Pi’s LEDs to diagnose an issue? Drop a comment below and share your experiences.
  27. by: Chris Coyier Mon, 19 May 2025 16:36:15 +0000 I admit I’m a sucker for “do this; don’t do that” (can’t you read the sign) blog posts when it comes to design. Screw nuance, gimme answers. Anthony Hobday has a pretty good one in Visual design rules you can safely follow every time. Makes sense to me; ship it. Erik Kennedy does a pretty good job with posts in this vein, and I just read one about designing sidebars in his email newsletter. But he didn’t blog it so I can’t link to it. Instead I’ll link to his 15 Tips for Better Signup / Login UX which is the same kinda “do this” advice. I perish each time I have to hunt manually for the @ Jon Yablonski’s Laws of UX site is a pretty good example of this too, except the “do this” advice is more like “think about this principle”. They are pretty straightforward though, like: Welp now that we’ve linked up a bunch of design related stuff I’d better keep going. My pockets are always hot with links. I’m like and old man except instead of Wether’s Originals I have great URLs. If I had to design some shirts and hoodies and coats and stuff, I’d definitely want some clean templates to use, so I think these 45 fully editable apparel templates from atipo is pretty sweet. (€30.00 with a bunch of fonts too) Not Boring software rules. They have some really nice apps that feel very designed. I use their Habits app every day. They’ve got a nice blog post on the role of sound in software design. It’s common to think that software that makes any sound is a mistake as it’s just obnoxious or superfluous. I like this one: Is “good” and “bad” web design subjective (like just our opinions) or objective (provable with data)? I mean, that’s subjective, lol. Remy Sharp was thinking about it recently and has developed his own set of criteria. A simple one: Seems simple, but… not always. I was reviewing a site recently and the homepage had just a zillion things it was trying to say. It was a store, so there were locations, an invite to search, an invite to call, and invite to chat, discounts available, a current promotion, financing available, categories for browsing, upcoming events, etc, etc. The thing is, it’s easy to point at it and say Mess! — all that stuff is there because it’s important to somebody in the organization. Deciding on what even “the content” is can be tricky. I always think the homepage probably isn’t the best place to start a big debate like this. Clean up the more focused pages first. Let’s end with something beautiful, like these flowing WebGL gradients by Alex Harri. I loved the mathematical intro on doing all this pixel by pixel work manually, then how to shift the responsibility of that work: Shaders are a real journey, but I bet if you read every word of this post closely you’d be well on your way.
  28. function check_updates() { local server="$1" local environment="$2" # Define environment-to-tag mapping declare -A env_tags=( [prod]="AMPROD EMPROD MONPA MONPE MONPO OCPROD OGGPA OGGPE OGGPO ORMsPA ORMsPE ORMsPO" [dev]="AMDEV EMDEV MONDA MONDE MONDO OCDEV OGGDA OGGDE OGGDO ORMsDA ORMsDE ORMsDO" [uat]="AMUAT EMUAT MONUA MONUE MONUO OCUAT OGGUA OGGUE OGGUO ORMsUA ORMsUE ORMsUO" ) # Define environment-to-tag mapping declare -A env_tags=( [prod]="AMPROD OCPROD EMPROD OGGPA MONAP MONEP MONOP" [dev]="OCDEV AMDEV EMDEV" [uat]="AMUAT OCUAT EMUAT MONOCU MONAMU MONEMU" ) case "$environment" in prod|PROD|Prod|production|Production) env="prod" ;; dev|DEV|Dev|development|Development) env="dev" ;; uat|UAT|Uat|test|Test) env="uat" ;; *) env="" ;; esac # Get the tags for the specified environment local tags="${env_tags[$env]}" if [ -z "$tags" ]; then echo -e "${light_red}Error:${default} Invalid or unspecified environment." return 1 fi # Fetch the server tag local server_tag=$(getJPTags "$server" "$env") # Get the tags for the specified environment local tags="${env_tags[$env]}" if [ -z "$tags" ]; then echo -e "${light_red}Error:${default} Invalid or unspecified environment." return 1 fi # Fetch the server tag local server_tag=$(getJPTags "$server" "$env") echo -en "${light_cyan}Checking ${white}$server (${dark_gray}${server_tag}${white})...${default} " # Get OS type OS_TYPE=$(ssh -o BatchMode=yes -o ConnectTimeout=${SSH_TIMEOUT} "$server" "awk -F= '/^ID=/{print \$2}' /etc/os-release" 2>/dev/null | tr -d '\"' | tr -d '[:space:]') SSH_EXIT_CODE=$? if [[ -z "$OS_TYPE" ]] || [[ $SSH_EXIT_CODE -ne 0 ]]; then note_color=${light_red} count_color=${light_red} COUNT="Error" OPERATING_SYS="Error: Unknown" count_note="Connection failed (or unexpected output) on ${white}$server${note_color}" log_note="Connection failed (or unexpected output)" echo -en "${count_color}Patches Needed: ${COUNT}${default} " echo -e "${light_yellow}[${default}NOTE${light_yellow}] ${light_blue}OS: ${light_cyan}${OPERATING_SYS} ${note_color}${count_note}${default}" echo "${SYS_DATE_TIME},${server},${OPERATING_SYS},${COUNT},${log_note}" >> "$LOGFILE" return fi case "$OS_TYPE" in rhel) OPERATING_SYS="RedHat Linux" ;; centos) OPERATING_SYS="CentOS Linux" ;; almalinux) OPERATING_SYS="Alma Linux" ;; rocky) OPERATING_SYS="Rocky Linux" ;; amazon) OPERATING_SYS="Amazon Linux" ;; oracle) OPERATING_SYS="Oracle Linux" ;; fedora) OPERATING_SYS="Fedora Linux" ;; ubuntu) OPERATING_SYS="Ubuntu" ;; kali) OPERATING_SYS="Kali Linux" ;; debian) OPERATING_SYS="Debian Linux" ;; arch) OPERATING_SYS="Arch Linux" ;; manjaro) OPERATING_SYS="Manjaro Linux" ;; opensuse) OPERATING_SYS="openSUSE Linux" ;; suse) OPERATING_SYS="SUSE Linux" ;; gentoo) OPERATING_SYS="Gentoo Linux" ;; slackware) OPERATING_SYS="Slackware" ;; alpine) OPERATING_SYS="Alpine Linux" ;; *) OPERATING_SYS="Unknown ${OS_TYPE} Linux Distro" ;; esac if [[ "$OS_TYPE" == "rhel" || "$OS_TYPE" == "centos" || "$OS_TYPE" == "fedora" || "$OS_TYPE" == "rocky" || "$OS_TYPE" == "almalinux" || "$OS_TYPE" == "oracle" ]]; then CMD_UPDATE_INFO="sudo yum -q --security updateinfo list | grep -v '^Update ID' | awk '{print \$1}' | sort -u | wc -l" CMD_UPDATE_SIZE="yes N | sudo yum update | awk -F\": \" '/^Total download size/{print $2}'" CMD_DISK_CHECK="df --output=avail /var | tail -n1 | awk '{print int(\$1/1024)}'" CMD_DISK_ROOT_CHECK="df --output=avail / | tail -n1 | awk '{print int(\$1/1024)}'" CLEAN_CMD="sudo yum clean all && sudo rm -rf /var/cache/dnf/*" elif [[ "$OS_TYPE" == "ubuntu" || "$OS_TYPE" == "debian" || "$OS_TYPE" == "kali" ]]; then CMD_UPDATE_INFO="sudo apt list --upgradable 2>/dev/null | grep -c 'security'" CMD_UPDATE_SIZE="sudo apt list --upgradeable 2>/dev/null | awk -F'[][]' '/security/ {sum+=$2} END {print int(sum/1024)}'" CMD_DISK_CHECK="df --output=avail /var | tail -n1 | awk '{print int(\$1/1024)}'" CMD_DISK_ROOT_CHECK="df --output=avail / | tail -n1 | awk '{print int(\$1/1024)}'" CLEAN_CMD="sudo apt clean" else return fi # Fetch update count COUNT=$(ssh -o LogLevel=Error -o BatchMode=yes -o ConnectTimeout=${SSH_TIMEOUT} "$server" "$CMD_UPDATE_INFO" 2>/dev/null | grep -E '^[0-9]+$' | head -n1) # Estimate update size UPDATE_SIZE_MB=$(ssh -o LogLevel=Error -o BatchMode=yes -o ConnectTimeout=${SSH_TIMEOUT} "$server" "$CMD_UPDATE_SIZE" 2>/dev/null | grep -E '^[0-9]+$' | head -n1) [[ -z "$UPDATE_SIZE_MB" ]] && UPDATE_SIZE_MB=1000 # Default to 1GB if unable to estimate # Check available disk space AVAILABLE_MB=$(ssh -o LogLevel=Error -o BatchMode=yes -o ConnectTimeout=${SSH_TIMEOUT} "$server" "$CMD_DISK_CHECK" 2>/dev/null | grep -E '^[0-9]+$' | head -n1) AVAILABLE_ROOT_MB=$(ssh -o LogLevel=Error -o BatchMode=yes -o ConnectTimeout=${SSH_TIMEOUT} "$server" "$CMD_DISK_ROOT_CHECK" 2>/dev/null | grep -E '^[0-9]+$' | head -n1) # Set required space (update size + safety buffer) REQUIRED_SPACE_MB=$((UPDATE_SIZE_MB + SAFETY_BUFFER_MB)) # Determine compliance SSH_EXIT_CODE=$? if [[ -z "$COUNT" ]] || [[ $SSH_EXIT_CODE -ne 0 ]]; then note_color=${light_red} count_color=${light_red} COUNT="Error" count_note="Connection failed (or unexpected output) on ${white}$server${note_color}" log_note="Connection failed (or unexpected output)" echo return elif [[ "$COUNT" -gt 5 ]]; then note_color=${light_red} count_color=${light_red} count_note="${white}$server${note_color} is out of Compliance" log_note="$server is out of Compliance" NON_COMPLIANT_SERVERS+=("$server") elif [[ "$COUNT" -gt 0 ]]; then note_color=${green} count_color=${light_yellow} count_note="${white}$server${note_color} is within Standard Compliance" log_note="$server is within Standard Compliance" elif [[ "$COUNT" -eq 0 ]]; then note_color=${light_green} count_color=${light_green} count_note="${white}$server${note_color} is Compliant" log_note="$server is Compliant" fi if [[ "$AVAILABLE_ROOT_MB" -lt "$REQUIRED_SPACE_MB" ]]; then note_color=${light_red} count="Error" count_note="Root folder did not meet space requirements, there is insufficient disk space on ${white}$server${note_color}. Space needed ${white}$(( REQUIRED_SPACE_MB - AVAILABLE_ROOT_MB ))${dark_gray}mb" log_note="Root folder did not meet space requirements: there is insufficient disk space on $server. Space needed $(( REQUIRED_SPACE_MB - AVAILABLE_ROOT_MB ))mb" else if [[ "$AVAILABLE_MB" -lt "$REQUIRED_SPACE_MB" ]]; then CLEAN_ATTEMPT=$(ssh -o LogLevel=Error -o BatchMode=yes -o ConnectTimeout=${SSH_TIMEOUT} "$server" "$CLEAN_CMD" 2>/dev/null) AVAILABLE_MB=$(ssh -o LogLevel=Error -o BatchMode=yes -o ConnectTimeout=${SSH_TIMEOUT} "$server" "$CMD_DISK_CHECK" 2>/dev/null | grep -E '^[0-9]+$' | head -n1) if [[ "$AVAILABLE_MB" -lt "$REQUIRED_SPACE_MB" ]]; then note_color=${light_red} count="Error" count_note="Clean up attempts did not meet space requirements, there is insufficient disk space on ${white}$server${note_color}. Space needed ${white}$(( REQUIRED_SPACE_MB - AVAILABLE_MB ))${dark_gray}mb" log_note="Clean up attempts did not meet space requirements: there is insufficient disk space on $server. Space needed $(( REQUIRED_SPACE_MB - AVAILABLE_MB ))mb" else note_color=${light_green} count_note="After clean up attempt, disk space was recovered on ${white}$server${note_color}. Space available $(( AVAILABLE_MB - REQUIRED_SPACE_MB + 1000 ))${dark_gray}mb" log_note="After clean up attempt: disk space was recovered on $server. Space available $(( AVAILABLE_MB - REQUIRED_SPACE_MB + 1000 ))mb" fi fi fi # Get system Date and Time: SYS_DATE_TIME="$(date +"%b %d %Y %I:%M%p")" echo -en "${count_color}Patches Needed: ${COUNT}${default} " echo -e "${light_yellow}[${default}NOTE${light_yellow}] ${light_blue}OS: ${light_cyan}${OPERATING_SYS} ${note_color}${count_note}${default}" echo "${SYS_DATE_TIME},${server},${server_tag},${OPERATING_SYS},${COUNT},${log_note},${AVAILABLE_ROOT_MB},${AVAILABLE_MB},${REQUIRED_SPACE_MB}" >> "$LOGFILE" }
  29. by: Juan Diego Rodríguez Mon, 19 May 2025 12:32:22 +0000 A couple of days back, among the tens of crypto-scams that flood our contact inbox, we found an interesting question on nested lists from one of our readers. Styling lists? Enough to catch my attention. After all, I just completed an entire guide about CSS counters. The message continues: Fair enough! So, what we are looking to achieve is a nested list, where each sublist marker/counter is of a different kind. The example linked in the message is the following: 8 The strata corporation must repair and maintain all of the following: (a) common assets of the strata corporation; (b) common property that has not been designated as limited common property; (c) limited common property, but the duty to repair and maintain it is restricted to (i) repair and maintenance that in the ordinary course of events occurs less often than once a year, and (ii) the following, no matter how often the repair or maintenance ordinarily occurs: (A) the structure of a building; (B) the exterior of a building; (C) chimneys, stairs, balconies and other things attached to the exterior of a building; (D) doors, windows and skylights on the exterior of a building or that front on the common property; While simple at first glance, it still has some nuance, so let’s try to come up with the most maintainable solution here. The ugly way My first approach to this problem was no approach at all; I just opened CodePen, wrote up the HTML, and tried to get my CSS to work towards the final result. After translating the Markdown into ol and li elements, and with no special styling on each list, the base list would look like the following: CodePen Embed Fallback Once there, my first instinct was to select each ol element and then change its list-style-type to the desired one. To target each level, I selected each ol depending on its number of ol ancestors, then let the specificity handle the rest: ol { list-style-type: decimal; /* Unnecessary; just for demo */ } ol ol { list-style-type: lower-alpha; } ol ol ol { list-style-type: lower-roman; } ol ol ol ol { list-style-type: upper-alpha; } And as you can see, this works… But we can agree it’s an ugly way to go about it. CodePen Embed Fallback Nesting to the rescue Luckily, CSS nesting has been baseline for a couple of years now, so we could save ourselves a lot of ol selectors by just nesting each element inside the next one. ol { list-style-type: decimal; ol { list-style-type: lower-alpha; ol { list-style-type: lower-roman; ol { list-style-type: upper-alpha; } } } } While too much nesting is usually frowned upon, I think that, for this case in particular, it makes the CSS clearer on what it intends to do — especially since the CSS structure matches the HTML itself, and it also keeps all the list styles in one place. All to the same result: CodePen Embed Fallback It’s legal I don’t know anything about legal documents, nor do I intend to learn about them. However, I do know the law, and by extension, lawyers are finicky about how they are formatted because of legal technicalities and whatnot. The point is that for a legal document, those parentheses surrounding each list marker — like (A) or (ii) — are more than mere decoration and have to be included in our lists, which our current solution doesn’t. A couple of years back, we would have needed to set a counter for each list and then include the parentheses along the counter() output; repetitive and ugly. Nowadays, we can use the @counter-style at rule, which as its name implies, allows us to create custom counter styles that can be used (among other places) in the list-style-type property. In case you’re unfamiliar with the @counter-style syntax, what we need to know is that it can be used to extend predefined counter styles (like decimal or upper-alpha), and attach to them a different suffix or prefix. For example, the following counter style extends the common decimal style and adds a dash (-) as a prefix and a colon (:) as a suffix. @counter-style my-counter-style { system: extends decimal; prefix: "- "; suffix: ": "; } ol { list-style-type: my-counter-style; } CodePen Embed Fallback In our case, we’ll need four counter styles: A decimal marker, without the ending dot. The initial submission doesn’t make it clear if it’s with or without the dot, but let’s assume it’s without. A lower alpha marker, enclosed in parentheses. A lower Roman marker, also enclosed in parentheses. An upper alpha marker, enclosed in parentheses as well. All these would translate to the following @counter-style rules: @counter-style trimmed-decimal { system: extends decimal; suffix: " "; } @counter-style enclosed-lower-alpha { system: extends lower-alpha; prefix: "("; suffix: ") "; } @counter-style enclosed-lower-roman { system: extends lower-roman; prefix: "("; suffix: ") "; } @counter-style enclosed-upper-alpha { system: extends upper-alpha; prefix: "("; suffix: ") "; } And then, we just gotta replace each with its equivalent in our initial ol declarations: ol { list-style-type: trimmed-decimal; ol { list-style-type: enclosed-lower-alpha; ol { list-style-type: enclosed-lower-roman; ol { list-style-type: enclosed-upper-alpha; } } } } CodePen Embed Fallback It should work without CSS! Remember, though, it’s a legal document, so what happens if the internet is weak enough so that only the HTML loads correctly, or if someone checks the page from an old browser that doesn’t support nesting or @counter-style? Thinking only about the list, in most websites, it would be a mild annoyance where the markers go back to decimal, and you have to go by padding to know where each sublist starts. However, in a legal document, it can be a big deal. How big? I am no lawyer, so it beats me, but we still can make sure the list keeps its original numbering even without CSS. For the task, we can use the HTML type attribute. It’s similar to CSS list-style-type but with its own limited uses. First, its use with ul elements is deprecated, while it can be used in ol elements to keep the lists correctly numbered even without CSS, like in legal or technical documents such as ours. It has the following values: "1" for decimal numbers (default) "a" for lowercase alphabetic "A" for uppercase alphabetic "i" for lowercase Roman numbers "I" for uppercase Roman numbers Inside our HTML list, we would assign the correct numbering for each ol level: CodePen Embed Fallback Depending on how long the document is, it may be more the hassle than the benefit, but it is still good to know. Although this kind of document doesn’t change constantly, so it wouldn’t hurt to add this extra safety net. Welp, that was kinda too much for a list! But that’s something intrinsic to legal documents. Still, I think it’s the simplest way to achieve the initial reader’s goal. Let me know in the comments if you think this is overengineered or if there is an easier way. More on lists! Almanac on Apr 23, 2021 list-style ul { list-style: square outside none; } lists Sara Cope Almanac on Jan 28, 2025 @counter-style @counter-style apple-counter { ... } lists Juan Diego Rodríguez Article on May 7, 2025 Styling Counters in CSS lists Juan Diego Rodríguez A Reader’s Question on Nested Lists originally published on CSS-Tricks, which is part of the DigitalOcean family. You should get the newsletter.

Important Information

Terms of Use Privacy Policy Guidelines We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.