<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jane Ori</title>
    <description>The latest articles on DEV Community by Jane Ori (@janeori).</description>
    <link>https://dev.to/janeori</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F790708%2Fe61d3abe-e086-407e-8424-21249ea063ad.png</url>
      <title>DEV Community: Jane Ori</title>
      <link>https://dev.to/janeori</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/janeori"/>
    <language>en</language>
    <item>
      <title>Violence at my boundary.</title>
      <dc:creator>Jane Ori</dc:creator>
      <pubDate>Fri, 05 Jun 2026 12:36:47 +0000</pubDate>
      <link>https://dev.to/janeori/violence-at-my-boundary-3hoi</link>
      <guid>https://dev.to/janeori/violence-at-my-boundary-3hoi</guid>
      <description>&lt;p&gt;My childhood was a constant state of fear and severe physical and mental abuse.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trigger warning, that ^ ad nauseam.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My mother made no apparent effort to end the cycles of abuse she suffered.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I see her face in my mind as a wide-eyed absent minded look of pure hatred and immediate intent to harm.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I was 33 years old the last time she hit me in the face and chest repeatedly until I could get my arms around her tight enough to repeat "I'm sorry I forgive you."&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I hear her voice with the vile glee of schadenfreude when she attempts to manipulate someone against me, humiliate me, or give herself room to breathe from the avalanches of imagined bullshit she seemingly drowns in.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I think it's partially because I looked like my father but I have no idea what trauma causes a mother to express almost exclusively hatred to her oldest child their entire life.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;She hasn't used my name once without first deadnaming me and pretending to correct it quickly.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;She spilled hatred and contempt onto every question, hope, and dream I dared to speak my whole life.&lt;/p&gt;

&lt;p&gt;The moment someone else paid attention and began to notice is the rare glimpse of kindness towards me I'd experience so she could save face.&lt;/p&gt;

&lt;p&gt;But I knew better than to take advantage of something she'd hold over me because she already made me feel awful for thinking about it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj6t31wiwwsdp348m4ass.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj6t31wiwwsdp348m4ass.png" alt="A photo of me as a very young child holding a yellow stuffed animal chicken" width="800" height="545"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Did you hear that, they said it's okay for you to do ballet with your sister!"&lt;/p&gt;

&lt;p&gt;"No, I don't want to."&lt;/p&gt;

&lt;p&gt;"I don't know why he's always like this! I guess he doesn't want to! Oh well!"&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;I have done my absolute best&lt;/strong&gt; trying to heal from this trail of violence and hatred and especially try to not let anyone experience it from me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I still have one single trigger, I know what it is, and I think I know what I need to do to end it.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Some of my earliest memories&lt;/strong&gt; are witnessing my mother yelling and fighting with my birth father.&lt;/p&gt;

&lt;p&gt;One night she made sure I knew what cheating meant after he had no choice but to borrow his friend's car to drive home one night during the final split.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I wasn't even in 1st grade yet.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;She stormed inside screaming after he kept her from damaging the car and she locked the front door. He begged me through the window to unlock it, I looked towards mom and she was staring at me with pure hatred&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"don't you fucking dare touch that door."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I looked back to my father and cried helpless. I have absolutely no memory of my little sister or baby brother during that.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;It felt like a week later&lt;/strong&gt;, a new guy showed up.&lt;/p&gt;

&lt;p&gt;She continuously shared reasons to hate my father and in contrast reasons to like the new guy.&lt;/p&gt;

&lt;p&gt;She explained she met the him at her half sister's funeral several states away just prior to the fight with my father -- where she made sure I knew what cheating was. 🙄&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The new guy became dad&lt;/strong&gt; shortly after and then brought 2 new siblings with him.&lt;/p&gt;

&lt;p&gt;A brother a couple months younger than me, and a sister a little younger than my full blood sister.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Technically they're my half cousins because dad was my mom's deceased half-sister's husband who she "met" at the funeral.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It took one quiet moment in my room to understand who &lt;em&gt;actually&lt;/em&gt; cheated &lt;em&gt;and when&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I learned to be extremely vigilant in understanding timing and taking in information without ascribing truth to it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I learned to feel the mood of a person without words and to test uncertainty by enthusiastically saying "I love you!" and digesting the reality behind the nuance of the surface response from mom and dad.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;He beat all of us with his belt. And later the boys, the oldest of which was me, got "&lt;strong&gt;the tearjerker&lt;/strong&gt;" - a piece of wood that used to hold up the box spring on an old wooden bedframe and now used to beat us.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;Somehow she was even more cruel to them than to me.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My brother from dad's side told her "I love you mom!" right after I did, using the same tone of child-like happiness without knowing it was &lt;em&gt;just part of my test&lt;/em&gt; to be over the top so she wouldn't call out the truth of it if she knew.&lt;/p&gt;

&lt;p&gt;We were all in the car out in the middle of nowhere in a wooded swamp after they went fishing off a broken bridge.&lt;/p&gt;

&lt;p&gt;I felt like something was scary and tense. She was normal/reserved tone when replying to my "I love you mom!" but my heart broke for my brother when she turned to dad instead of him and said "oh I'm going to like this one, he loves me even when I'm mad at him."&lt;/p&gt;

&lt;p&gt;&lt;em&gt;He didn't fucking do anything.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I never heard him happy again.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We stopped, my parents got out, went to the trunk, dad opened the big paper map so we couldn't see through the trunk-hood gap from inside into the trunk.&lt;/p&gt;

&lt;p&gt;They whispered and I felt tension rise. It felt like an hour before they came back in. By then mom was irritated at dad, dad was silent.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;My mind sat with a feeling that the five of us kids just survived.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;I told on my brother-cousin in 3rd grade&lt;/strong&gt; for something stupid I don't remember.&lt;/p&gt;

&lt;p&gt;Hours later, while in the bath upstairs, I hear the usual screams and "I didn't do that" from a child as mom screamed with insanity and beat the shit out of my someone. It didn't even cross my mind that I told on him earlier because it was something petty and minor &lt;em&gt;and couldn't be relevant&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;She stomped upstairs burst through my bathroom door and started beating the shit out of me.&lt;/p&gt;

&lt;p&gt;I screamed over and over "&lt;strong&gt;what did I do?! what did I do?!&lt;/strong&gt;"&lt;/p&gt;

&lt;p&gt;She bloodied my nose and &lt;em&gt;repeatedly held my head under the water&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;She finally yelled and said&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"you said your brother blah blah blah!"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;My mind exploded into bewilderment&lt;/strong&gt; at the horrible distortion of what I actually said.&lt;/p&gt;

&lt;p&gt;I yelled through blood, snot, and tears&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"No I didn't! I said (minor nonsense)."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I became really really good at repeating things I heard or said verbatim over the years.&lt;/p&gt;

&lt;p&gt;She stood straight up, her entire energy dropped into deadpan nothing, she looked towards the window and said a neutral volume "Oh." then walked out and back downstairs without another signal of awareness.&lt;/p&gt;

&lt;p&gt;The neighbor two doors down on the opposite side of the house &lt;strong&gt;called child protective services&lt;/strong&gt; for the first time.&lt;/p&gt;

&lt;p&gt;The second time was while my dad beat me with his open hand in my face &lt;em&gt;and&lt;/em&gt; with the tear jerker on my butt &amp;amp; thighs for several minutes because I was too scared to walk up to him and allow him to do it just once.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It was part of the punishment to have to willingly come into beating range so he didn't have to reach for us.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;That was the first time I wore makeup.&lt;/strong&gt; Mom put it on my face to cover the old bruises and fresh marks. &lt;em&gt;CPS has (had?) to call to inform the parents they're coming.&lt;/em&gt; FUCKING STUPID.&lt;/p&gt;




&lt;p&gt;Mom told me in a panic while putting the makeup on&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"that's it, that's enough to do it, we're going to jail. They're going to take you away. You'll never see your siblings again."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;She noticed that last one struck so she repeated it over and over until they got there.&lt;/p&gt;

&lt;p&gt;They started by interviewing us individually but my little brother was too young and they asked me to go with him.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;He answered every question point blank with the truth&lt;/strong&gt;, I interrupted every time and downplayed it and made it seem like he was exaggerating. I lied. &lt;em&gt;I didn't want to lose him.&lt;/em&gt; I didn't know what else to do.&lt;/p&gt;




&lt;p&gt;After my 18th birthday my dad changed completely. It was gradual for only a short time then so much more reserved and kind, soft, seemingly all at once. It was the first time in my life I saw someone actually change. His growth continued and is the only reason we still sometimes talk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I was so fucking hateful by that time though.&lt;/strong&gt; I did everything I could to learn. I studied Buddhism, I felt the love of Ram Dass and Thich Nhat Hanh, and I held onto the sage advice from the few good teachers I encountered.&lt;/p&gt;




&lt;p&gt;My first relationship lasted &lt;strong&gt;3 and a half awful years&lt;/strong&gt;, into sophomore year of college. I told her I'd kill her if she ever cheated, she cheated, she never admitted it but I tasted the condom then the guy told me along with our manager from work where we met.&lt;/p&gt;

&lt;p&gt;It turned me on more than ever.&lt;/p&gt;

&lt;p&gt;But I wasn't allowed to like that let alone admit it, so I put on the pressure with name-calling and constant lack of trust. She cheated again in college more than once.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How do I taste?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;She didn't use a condom that time - still never admitted it but the buried trans girl inside of me was living vicariously through her.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Fine, like normal, the back of my throat is drying out a little though."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;She cancelled my phone her parents were paying for and that's how things officially ended between us.&lt;/p&gt;

&lt;p&gt;I had no way to contact anyone so &lt;strong&gt;I spoke to God and begged him&lt;/strong&gt; to not let me go through that again. To not let me ever do that to someone else again.&lt;/p&gt;

&lt;p&gt;I had 2 non-committed, unlabeled, very short relationships in college after that.&lt;/p&gt;




&lt;p&gt;In the last days of college my friend put her wig on me and I saw myself in the mirror. She noticed me transfixed and quietly took this photo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcxyk66x5dbvxf4mqpb72.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcxyk66x5dbvxf4mqpb72.jpg" alt="photo of me looking in the mirror in college while wearing her wig and seeing a glimpse of me" width="800" height="1161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Playfully and with curiosity in her tone, she looked at me&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"You seem to be enjoying this a little too much. 😏"&lt;/p&gt;

&lt;p&gt;"I've kinda always wanted to."&lt;/p&gt;

&lt;p&gt;"You know you can, right?"&lt;/p&gt;

&lt;p&gt;"Yeah, but, you know, I have to get a job so... No."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For the next 12 years I stayed single, male expressing, not one kiss or hand held. I just worked on figuring myself out.&lt;/p&gt;

&lt;p&gt;Every time I'd get close to a new relationship, it would fall apart and my life path would bend.&lt;/p&gt;




&lt;p&gt;I was 430lbs, jobless, and alone with my cat the day I accepted the label, &lt;strong&gt;I am transgender&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I watched lilly Jo Hanson's coming out video and &lt;em&gt;it clicked a giant vault door lock in my energy bigger than my body.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/cGgVoqr78gk"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I watched it again and I bawled.&lt;/p&gt;

&lt;p&gt;I watched it over and over and &lt;strong&gt;I bawled for weeks straight&lt;/strong&gt; with bursts of laughter and self love pouring into every crack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I had an epiphany that unlocked it all.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Being transgender isn't something you do, it's something you are.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I knew well when something was &lt;em&gt;my bullshit&lt;/em&gt; or &lt;em&gt;someone else's&lt;/em&gt; in every conflict. If I was logically sound and in harmony with my beliefs and perspective when I took an action, I don't give half a bit what you think about it. I can feel when my actions come from misalignment and &lt;strong&gt;I do the shadow work to heal&lt;/strong&gt; it and I apologize when I realize it.&lt;/p&gt;

&lt;p&gt;So in my mind, if transgender was something you do, I couldn't stand living as the woman in my heart in the world we're in. I would feel like I needed to justify it in the face of spite and I hated attention so there's no way I'd even buy the kilts or tunic that had been on my Amazon wishlists for years.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The moment I realized it's something you &lt;em&gt;are&lt;/em&gt;&lt;/strong&gt;, something I obviously am, there wasn't a God that could stop me from transitioning. No justification needed, it just is.&lt;/p&gt;

&lt;p&gt;No attention wanted, I'm just plain Jane.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I've gradually lost 200lbs (90kg) since that day. Not from effort, from the natural unfolding of a happier life.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I had an incredibly fun 6 month relationship since then and I was so damn proud of the person I was. She unlocked so much for me, I was suddenly straight up promiscuous. 11 weeks, 30 people, mostly men, PrEP and DoxyPep, and a whole new confidence. I love myself and I finally felt free to explore this side of me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7a2lj48lgkdidpd7vwfv.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7a2lj48lgkdidpd7vwfv.gif" alt="Animated selfie gif of me sweating and sighing with a smirk then sticking my tongue out and laughing, a caption says 18 &amp;amp; 4" width="480" height="856"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;One big karmic cycle kept coming up over and over though.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The moment I detect someone acting without integrity, I give them a single chance to course correct before I show my teeth.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;If you double down on a lack of integrity, I get vicious and see my mother's hatred living through me.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I do not want to live with this cycle repeating.&lt;/p&gt;

&lt;p&gt;I've come to the brute force awareness that the moment I detect a double down on a lack of integrity, I am on a metaphysical boundary on my life path.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;That relationship is over and cannot be recovered through any actions on my part.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I have one singular option - to walk away.&lt;/p&gt;

&lt;p&gt;Nothing gives me the right to impose my perspective on anyone else's life path. They made their choice, twice. They are living their version of their truth and it is simply incompatible with mine.&lt;/p&gt;

&lt;p&gt;Walk away and stand tall, argue and make myself small, or bend to their nonsense and make myself even smaller.&lt;/p&gt;

&lt;p&gt;I'm done showing my teeth though. If you saw them, I guarantee it's because you violated that one single boundary that I still carry OR I did something I needed to learn from and fix &lt;em&gt;and you received an apology.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I am not perfect but&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I am proud of who I am.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;I just walked away from a six figure Staff Engineer offer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They approached me, they appreciated my tech writing and my extensive list of open source work. (&lt;a href="https://propjockey.io/" rel="noopener noreferrer"&gt;some of which are listed here&lt;/a&gt;) We made plans to talk.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Five great interviews went by.&lt;/li&gt;
&lt;li&gt;I signed the offer letter.&lt;/li&gt;
&lt;li&gt;I was genuinely excited for the role.&lt;/li&gt;
&lt;li&gt;Then they took a couple days "for the lawyers to draft their standard employment agreement." 🚩&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Their employment agreement contained two awful clauses that made my stomach drop when seen together.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;/p&gt;
  These are the 2 clauses
  &lt;p&gt;First, this one which doubts the employee's integrity to the point they feel it necessary to add "Best effort" to the AT WILL employment agreement.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;5 &lt;u&gt;Best Efforts&lt;/u&gt;. During Employee’s employment with Company, Employee will serve Company faithfully and to the best of Employee’s ability and will devote Employee’s full business and professional time, energy, and diligence to the performance of Employee’s job duties. Employee will comply with Company’s policies and practices as they exist from time to time. Employee will promptly communicate to Company all business, commercial and investment opportunities or offers presented to Employee, or of which Employee becomes aware, that relate to Company’s business. During Employee’s employment with Company, Employee will not, directly or indirectly, compete with Company, be employed by or provide services to any other person or entity, or engage in any other business activity, without prior written approval from Company. Employee may, however, engage in passive personal investment activities, so long as the activities do not compete with Company, violate Company policies or interfere with Employee’s job duties.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;🚩 unless they approve it in writing first:&lt;br&gt;
🚩 It blocks my ability to get paid for writing.&lt;br&gt;
🚩 It blocks my ability to get paid for speaking.&lt;br&gt;
🚩 It blocks my ability to continue development on my open source work.&lt;br&gt;
🚩 It blocks my ability to develop new things or even use any new features that excite me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;All of this is specifically outside of work and on my own equipment.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Literally trying to micromanage everything I do, everything that attracted them to me.&lt;/p&gt;

&lt;p&gt;And it's web dev - everything is indirectly related to everything.&lt;/p&gt;

&lt;p&gt;And my OS work is directly related to some of their work.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I have seen barely similar clauses and I always get them removed or neutralized with amendments because of the nature of my OS efforts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is by far the most overreaching variant I have ever witnessed though.&lt;/p&gt;

&lt;p&gt;The next one is INFURIATING to me and I didn't even bring it up in my first response.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;11 &lt;u&gt;Remedies&lt;/u&gt;. Employee acknowledges that violation of this Agreement would have a materially detrimental effect upon Company, the monetary loss from which would be difficult, if not impossible, to measure. If Employee breaches &lt;strong&gt;or threatens to breach&lt;/strong&gt; any term of this Agreement, Company will be entitled as a matter of right to injunctive relief and reasonable attorneys’ fees, costs, and expenses associated with enforcing this Agreement, in addition to any other remedies available at law or equity. Employee waives any right Employee may have to a jury trial to determine Company’s right to recover attorneys’ fees and costs under this Agreement, or to determine the reasonableness of those attorneys’ fees and costs. Nothing in this Agreement will limit Company’s remedies under any applicable Uniform Trade Secrets Act or elsewhere.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(&lt;strong&gt;emphasis&lt;/strong&gt; mine)&lt;/p&gt;

&lt;p&gt;This clause is so one-sided and revolting it makes my skin crawl.&lt;/p&gt;

&lt;p&gt;🚩 No verbiage of the prevailing party - even if they lose, they can legally assign all of their "reasonable" costs to me.&lt;/p&gt;



&lt;p&gt;&lt;/p&gt;




&lt;p&gt;I've done my reflection and I'm confident it was unnecessary to grasp, argue, plead, or show my teeth at all.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I offered if they agreed to 3 interlinked amendments, it would mostly neutralize both and I wouldn't have to point out how awful they were.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They agreed to two. ☣️&lt;/p&gt;




&lt;p&gt;I should have just walked away when they rejected the 3rd amendment.&lt;/p&gt;

&lt;p&gt;But this was my response, the violence at my boundary.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[Redacted],&lt;/p&gt;

&lt;p&gt;I had excellent conversations with everyone on the team and I am excited by the potential of the company in full and individually by each of the members I talked to.&lt;br&gt;
I trust that we are already fully working together, shoulder to shoulder, looking at this employment agreement and working to fix it together.&lt;br&gt;
Not just for me, not just for the image of your company, but for all future employees you attempt to hire.&lt;/p&gt;

&lt;p&gt;Here is section 5 in full to continue discussion:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;5 Best Efforts. [...]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This clause directly implies that your legal team doesn't have trust in my integrity to give my best effort - even though the agreement is at-will and you are free to terminate employment any moment you felt like I wasn't giving my best effort. Your legal team's mistrust and now insistence to micromanage what I do outside of work on my own equipment and restrict my multiple streams of income is wholly unacceptable. &lt;/p&gt;

&lt;p&gt;I apologize for any perceived harshness but I will no longer move forward with the employment agreement unless it is removed in full.&lt;/p&gt;

&lt;p&gt;Further, since your legal team's intentions have been magnified here, it forces a closer look at their egregious, one-sided, fear based, power hungry lack of integrity in section 11. Here it is in full for reference:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;11 Remedies. [...]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Your perception of how I've labeled it is a direct reflection of the energy your legal team has inserted into your employment agreement.&lt;/p&gt;

&lt;p&gt;Either remove this entirely as well or introduce some integrity by replacing the sentence beginnig with "If Employee breaches or threatens to breach..." with the following:&lt;/p&gt;

&lt;p&gt;In any legal action or arbitration arising out of or related to this Agreement, the prevailing party shall be entitled to recover its reasonable attorneys' fees, costs, and expenses from the non-prevailing party, in addition to any other relief to which it may be entitled.&lt;/p&gt;

&lt;p&gt;Additionally, the next sentence should be similarly bi-directional to the benefit of the prevailing party and not one-sided.&lt;/p&gt;

&lt;p&gt;Happy to continue once these issues are fixed.&lt;/p&gt;

&lt;p&gt;You want leaders, not captured pokemon.&lt;/p&gt;

&lt;p&gt;// Jane&lt;/p&gt;


&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;If you want to work with &lt;em&gt;ME&lt;/em&gt; - I'd love to chat.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you want me afraid of punishment, unable to live as myself, unable to follow my excitement outside of work without a zero trust leash around my neck, unable to play with new tech without permission, &lt;em&gt;you can't have me&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I refuse to be anyone less than I've grown to be.&lt;/p&gt;

&lt;p&gt;I love myself. I love the work I do. I love each of my open source contributions. I love my grind and drive. I love my passion. I love my integrity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrlpd2j27gz3mf7o3s7j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdrlpd2j27gz3mf7o3s7j.png" alt="A recent photo of me, smiling, happy, with pink hair and bangs" width="800" height="1338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm available and eager to be part of a team again. :)&lt;/p&gt;

&lt;p&gt;Happy pride month 🏳️‍⚧️&lt;/p&gt;




&lt;h2&gt;
  
  
  Open Contact 👽
&lt;/h2&gt;

&lt;p&gt;Please keep the comments on-topic and reach out with anything else through my socials! Happy to help, love to see what you've created using my OS contributions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;small&gt;PropJockey&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;CodePen&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;DEV Blog&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;GitHub&lt;/small&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://propjockey.io" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/propjockey-lines.svg" alt="PropJockey.io"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://codepen.io/propjockey" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/codepen.svg" alt="CodePen"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/janeori"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/dev.svg" alt="DEV Blog"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/propjockey" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/github.svg" alt="GitHub"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;small&gt;Mastodon&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;LinkedIn&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;X&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;Bluesky&lt;/small&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://front-end.social/@JaneOri" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/mastodon.svg" alt="Mastodon"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.linkedin.com/in/janeori/" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/linkedin.svg" alt="LinkedIn"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://x.com/jane0ri" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/x.svg" alt="X"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bsky.app/profile/janeori.propjockey.io" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/bluesky.svg" alt="Bluesky"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  My heart is open to receive abundance in all forms,&lt;br&gt;flowing to me in many expected and unexpected ways.
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PayPal&lt;/th&gt;
&lt;th&gt;Ko-fi&lt;/th&gt;
&lt;th&gt;Venmo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.paypal.com/donate/?cmd=_s-xclick&amp;amp;hosted_button_id=9Z925L3SJJ8BS&amp;amp;source=qr&amp;amp;ssrt=1772865628068" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/paypal.svg" alt="PayPal"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://ko-fi.com/janeori" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/ko-fi.svg" alt="Ko-fi"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://account.venmo.com/u/JaneOri" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/venmo.svg" alt="Venmo"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;BTC&lt;/th&gt;
&lt;th&gt;XRP&lt;/th&gt;
&lt;th&gt;ETH&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://app.ens.domains/janeori.eth" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/btc.svg" alt="BTC bc1qe2ss8hvmskcxpmk046msrjpmy9qults2yusgn9"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bithomp.com/en/account/X7zmKiqEhMznSXgj9cirEnD5sWo3iZPqbNPChdEKV9sM9WF" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/xrp.svg" alt="XRP rw2ciyaNshpHe7bCHo4bRWq6pqqynnWKQg : 459777128"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://app.ens.domains/janeori.eth" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/eth.svg" alt="ETH 0x674D4191dEBf9793e743D21a4B8c4cf1cC3beF54"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bc1qe...usgn9&lt;/td&gt;
&lt;td&gt;rw2ci...nWKQg&lt;br&gt;: 459777128&lt;/td&gt;
&lt;td&gt;0x674...beF54&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>trans</category>
      <category>opensource</category>
      <category>employeeexperience</category>
      <category>help</category>
    </item>
    <item>
      <title>Abhorrent Employment Agreements.</title>
      <dc:creator>Jane Ori</dc:creator>
      <pubDate>Thu, 04 Jun 2026 22:53:57 +0000</pubDate>
      <link>https://dev.to/janeori/abhorrent-employment-agreements-j88</link>
      <guid>https://dev.to/janeori/abhorrent-employment-agreements-j88</guid>
      <description>&lt;p&gt;I recently received (and later rejected) a six figure &lt;strong&gt;Staff Engineer&lt;/strong&gt; position.&lt;/p&gt;

&lt;p&gt;They approached me, they appreciated my tech writing and my extensive list of open source work. (&lt;a href="https://propjockey.io/packages/" rel="noopener noreferrer"&gt;some of which are listed here&lt;/a&gt;) We made plans to talk.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Five great interviews went by.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I signed the offer letter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I was genuinely excited for the role.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then they took a couple days "for the lawyers to draft their standard employment agreement." 🚩&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Their employment agreement contained two awful clauses that made my stomach drop when seen together.&lt;/p&gt;

&lt;p&gt;However, if they agreed to 3 interlinked amendments I proposed, it would mostly neutralize both and I wouldn't have to point out how it made me feel.&lt;/p&gt;

&lt;p&gt;They agreed to two. ☣️&lt;/p&gt;




&lt;h2&gt;
  
  
  My biggest flaw is showing my teeth when I witness someone double down on a lack of integrity.
&lt;/h2&gt;

&lt;p&gt;Or maybe it's that I got mad at all. I don't know.&lt;/p&gt;

&lt;p&gt;I make no apologies because my life experience has made me &lt;em&gt;feel&lt;/em&gt; like it's necessary, but I &lt;em&gt;know&lt;/em&gt; it's not. I forgive myself because I always deliberately grow when I see a pattern. BUT THIS ONE IS PERSISTENT.&lt;/p&gt;




&lt;p&gt;I need to end this karmic cycle in my life.&lt;/p&gt;




&lt;p&gt;In order to do that, &lt;strong&gt;I need to ask for your help&lt;/strong&gt;. &lt;em&gt;For your perspective that my life has not provided.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I need to open myself up to be seen authentically for who I am, in this direction, at moments like this in my life.&lt;/p&gt;

&lt;p&gt;I ask: &lt;strong&gt;How do you navigate something like this without wanting to rip their heads off?!&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It's extremely rare for someone to double down on a lack of integrity so most of you will be surprised to hear this about me if you've witnessed me anywhere normally.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Unless of course, some sh*tbag quietly spread rumors when I got mad at them instead of using the opportunity to look in the mirror - and then you heard it from them.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Just kidding. &lt;em&gt;kind of&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;That sentiment is part of the structure I need to dismantle here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I want to think of myself as kind, I &lt;em&gt;feel&lt;/em&gt; like that is the sentiment most people have of me.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;But I know I am a c-unit if you trip this perceived-lack-of-integrity that's trying to take advantage of me, "boundary" that I'm carrying around.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It is code I need help debugging.&lt;/p&gt;

&lt;p&gt;In the words of Paul Selig, &lt;a href="https://www.youtube.com/shorts/DurYKRxF2-4" rel="noopener noreferrer"&gt;"what you damn, damns you back"&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You don't have to align to Paul's beliefs, but I know it to be &lt;em&gt;true in my life&lt;/em&gt;, so it is the experience &lt;em&gt;I&lt;/em&gt; have lived. &lt;em&gt;Because I also believe that my beliefs create my experience of my life.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The abhorrent* combination of clauses.
&lt;/h2&gt;

&lt;p&gt;*- in my opinion, with a degree of acknowledged anger behind it&lt;/p&gt;

&lt;p&gt;First, this one which doubts the employee's integrity to the point they feel it necessary to add "Best effort" to the AT WILL employment agreement.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;5 &lt;u&gt;Best Efforts&lt;/u&gt;. During Employee’s employment with Company, Employee will serve Company faithfully and to the best of Employee’s ability and will devote Employee’s full business and professional time, energy, and diligence to the performance of Employee’s job duties. Employee will comply with Company’s policies and practices as they exist from time to time. Employee will promptly communicate to Company all business, commercial and investment opportunities or offers presented to Employee, or of which Employee becomes aware, that relate to Company’s business. During Employee’s employment with Company, Employee will not, directly or indirectly, compete with Company, be employed by or provide services to any other person or entity, or engage in any other business activity, without prior written approval from Company. Employee may, however, engage in passive personal investment activities, so long as the activities do not compete with Company, violate Company policies or interfere with Employee’s job duties.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;🚩 &lt;em&gt;unless they approve it in writing first&lt;/em&gt;:&lt;br&gt;
🚩 It blocks my ability to get paid for writing.&lt;br&gt;
🚩 It blocks my ability to get paid for speaking.&lt;br&gt;
🚩 It blocks my ability to continue development on my open source work.&lt;br&gt;
🚩 It blocks my ability to develop new things &lt;em&gt;or even use any new features&lt;/em&gt; that excite me.&lt;/p&gt;

&lt;p&gt;All of this is specifically outside of work and on my own equipment.&lt;/p&gt;

&lt;p&gt;Literally trying to micromanage everything I do, everything that attracted them to me.&lt;/p&gt;

&lt;p&gt;And it's web dev - everything is indirectly related to everything.&lt;/p&gt;

&lt;p&gt;And my OS work is directly related to some of their work.&lt;/p&gt;

&lt;p&gt;I have seen barely similar clauses and I &lt;em&gt;always&lt;/em&gt; get them removed or neutralized with amendments because of the nature of my OS efforts.&lt;/p&gt;

&lt;p&gt;This is by far the most overreaching variant I have ever witnessed though.&lt;/p&gt;

&lt;p&gt;The next one is INFURIATING to me &lt;em&gt;and I didn't even bring it up in my first response&lt;/em&gt;.&lt;/p&gt;



&lt;blockquote&gt;
&lt;p&gt;11 &lt;u&gt;Remedies&lt;/u&gt;. Employee acknowledges that violation of this Agreement would have a materially detrimental effect upon Company, the monetary loss from which would be difficult, if not impossible, to measure. If Employee breaches &lt;strong&gt;or threatens to breach&lt;/strong&gt; any term of this Agreement, Company will be entitled as a matter of right to injunctive relief and reasonable attorneys’ fees, costs, and expenses associated with enforcing this Agreement, in addition to any other remedies available at law or equity. Employee waives any right Employee may have to a jury trial to determine Company’s right to recover attorneys’ fees and costs under this Agreement, or to determine the reasonableness of those attorneys’ fees and costs. Nothing in this Agreement will limit Company’s remedies under any applicable Uniform Trade Secrets Act or elsewhere.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(&lt;strong&gt;emphasis&lt;/strong&gt; mine)&lt;/p&gt;



&lt;p&gt;This clause is so one-sided and revolting it makes my skin crawl.&lt;/p&gt;

&lt;p&gt;🚩 No verbiage of the prevailing party - &lt;strong&gt;even if they lose&lt;/strong&gt;, they can legally assign all of their "reasonable" costs to me.&lt;/p&gt;


&lt;h2&gt;
  
  
  My first response.
&lt;/h2&gt;

&lt;p&gt;I did my absolute best to give them a chance to agree to amendments that neutralize them enough to the point where I'm not worried about the rest becoming a problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I suspect I have already made mistakes here and I need genuine feedback on how you would handle this differently than me so I can learn how to fix my anger that comes later.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: The final page I reference here was where I listed my prior inventions, it had a single line available for entry.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The email:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hello [redacted]!&lt;/p&gt;

&lt;p&gt;I had a great weekend! I watched "I Swear" in a local theater which was incredibly touching and eye opening.&lt;/p&gt;

&lt;p&gt;The document is agreeable. Since I have an extensive set of prior inventions, I need the final page of the document to be replaced with the 3 pages I've attached here.&lt;/p&gt;

&lt;p&gt;In addition to the prior inventions list, I have also included the requested "prior written consent" for section 5 Best Effort that allows me to continue my current engagements outside of Company time/equipment without interference.&lt;/p&gt;

&lt;p&gt;Please include your signature and date on the final lines of that written prior consent form before sending me the revision so I may sign the complete document that includes your approved written consent.&lt;/p&gt;

&lt;p&gt;I am very excited to onboard and work with you all as well! :D&lt;/p&gt;

&lt;p&gt;Thank you!&lt;br&gt;
// Jane&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The three pages of prior inventions was necessary to safeguard most of my work from "invention assignment" clauses I won't even talk about here.&lt;/p&gt;

&lt;p&gt;Obviously I shouldn't have said it was agreeable when it's clearly not... It's literally dishonest which is itself a lack of integrity and authenticity, so I'm not totally blind to my faults here...&lt;/p&gt;

&lt;p&gt;Whatever my karma is though, it's deeper, and I need someone's insight who has some perspective that I'm totally missing here.&lt;/p&gt;

&lt;p&gt;My mindset is &lt;strong&gt;"if they agree to these 3 amendments, I don't need to talk about the problems, and we can move forward peacefully, together."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The 3 amendments:&lt;/p&gt;



&lt;blockquote&gt;
&lt;p&gt;Prior Written Consent for section 5, Best Effort:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Independent Speaking and Writing:&lt;/strong&gt;&lt;br&gt;
Employee may, utilizing their own time and personal equipment, engage in paid or unpaid writing, publishing, and speaking engagements. Permitted topics include web development&lt;br&gt;
methodologies, cascading style sheets (CSS) architecture, advanced programming techniques, data encoding (including steganography and related concepts), information security, and any subjects related to the Intellectual Property disclosed as Prior Inventions in Attachment 1.&lt;br&gt;
&amp;nbsp;&lt;br&gt;
Individual prior written consent from the Company is only required for writing or speaking engagements that would directly disclose or utilize Company Confidential Information or specific Company Work Product.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Continuation of Prior Inventions:&lt;/strong&gt;&lt;br&gt;
Employee retains the sole right, title, and interest to continue the development, commercialization, and sale of the software, games, physics simulations, and systems disclosed in Attachment 1. Such continued development shall be conducted on Employee's own time and&lt;br&gt;
utilizing personal equipment, and all resulting income shall remain the sole property of Employee.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Future Independent Development:&lt;/strong&gt;&lt;br&gt;
Furthermore, Employee may author, conceive, and commercialize new independent software, games, and applications during the term of employment without prior written consent, provided such development: (a) is conducted entirely on Employee's own time, (b) utilizes only personal equipment, and (c) does not directly relate to, or compete with, the Company's current business or specific Work Product.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;



&lt;p&gt;They rejected amendment 3, which cripples #1 and makes #2 rocky enough that they might pull the hairpin trigger on their "Remedies" clause if I made something clever or added a new feature.&lt;/p&gt;

&lt;p&gt;I did my best responding to them rejecting the 3rd amendment but it took more than a full day for them to respond and in that time the "Remedies" clause really ate at my mind.&lt;/p&gt;


&lt;h2&gt;
  
  
  My second response.
&lt;/h2&gt;

&lt;p&gt;This is where my teeth show after they doubled down, &lt;em&gt;which is probably too late into my karmic cycle to address it&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I had the presence of mind to direct it at their "legal team" instead of at the CEO I was talking to.&lt;/p&gt;



&lt;p&gt;While I suspect &lt;em&gt;some of you&lt;/em&gt; will think I've done okay, and it would be comforting to my ego to hear, &lt;strong&gt;I most need to hear from the people who get mad at me for what I do and say here&lt;/strong&gt;. Please. Tell me your perspective. Tell me what you would have done. Tell me what you would have been &lt;em&gt;feeling&lt;/em&gt; because what I feel is as close to rage as I get.&lt;/p&gt;



&lt;p&gt;I am sick of this happening to me. And I know it's because something in me doesn't see what is probably obvious to someone reading this.&lt;/p&gt;

&lt;p&gt;If you are watching this show and yelling at the screen, THIS IS YOUR CHANCE FOR THE SCREEN TO ACTUALLY LISTEN.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: This is incredibly uncomfortable for me to share so please do allow me some grace while you point out what's obvious to you.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I am not proud of it, I was holding back anger, it's obvious in the tone, it feels bad, and I don't know how to fix it.&lt;/p&gt;



&lt;blockquote&gt;
&lt;p&gt;[Redacted],&lt;/p&gt;

&lt;p&gt;I had excellent conversations with everyone on the team and I am excited by the potential of the company in full and individually by each of the members I talked to.&lt;br&gt;
I trust that we are already fully working together, shoulder to shoulder, looking at this employment agreement and working to fix it&amp;nbsp;together.&lt;br&gt;
Not just for me, not just for the image of your company, but for all future employees you attempt to hire.&lt;/p&gt;

&lt;p&gt;Here is section 5 in full to continue discussion:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;5 &lt;u&gt;Best Efforts&lt;/u&gt;. [...]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This clause&amp;nbsp;directly implies that your legal team doesn't have trust in my integrity to give my best effort - even though the agreement is at-will and you are free to terminate employment any moment you felt like I wasn't giving my best effort.&amp;nbsp;Your legal team's mistrust and now &lt;strong&gt;insistence to&amp;nbsp;micromanage what I do outside of work&lt;/strong&gt; on my own equipment and restrict my multiple streams of income &lt;strong&gt;is wholly unacceptable&lt;/strong&gt;.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;I apologize for any perceived harshness but I will no longer move forward with the employment agreement unless it is removed in full.&lt;/p&gt;

&lt;p&gt;Further, since your legal team's intentions have been magnified here, it forces a closer look at their egregious, one-sided, fear based, power hungry lack of integrity in section 11. Here it is in full for reference:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;11 &lt;u&gt;Remedies&lt;/u&gt;. [...]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Your perception of how I've labeled it is a direct reflection of the energy your legal team has inserted into your employment agreement.&lt;/p&gt;

&lt;p&gt;Either remove this entirely as well or introduce some integrity by replacing the sentence beginnig with "If Employee breaches or threatens to breach..." with the following:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In any legal action or arbitration arising out of or related to this Agreement, the prevailing party shall be entitled to recover its reasonable attorneys' fees, costs, and expenses from the non-prevailing party, in addition to any other relief to which it may be entitled.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Additionally, the next sentence should be similarly bi-directional to the benefit of the prevailing party and not one-sided.&lt;/p&gt;

&lt;p&gt;Happy to continue once these issues are fixed.&lt;/p&gt;

&lt;p&gt;You want leaders, not captured pokemon.&lt;/p&gt;

&lt;p&gt;// Jane&lt;/p&gt;
&lt;/blockquote&gt;



&lt;p&gt;&lt;/p&gt;
  Their final response more than a day later.
  &lt;br&gt;
  Jane,

&lt;p&gt;Thanks for the note, and for the time you spent speaking with the team. Appreciate your candor.&lt;/p&gt;

&lt;p&gt;Want to briefly clarify that the agreement was not intended to suggest mistrust or micromanagement; it was our counsel’s effort to account for circumstances we do not expect, but still need to protect against in a standard employment context.&lt;/p&gt;

&lt;p&gt;That said, I hear your concerns and respect your decision. Given where we are, it's best that we not move forward with the employment relationship.&lt;/p&gt;

&lt;p&gt;I'm sorry we weren't able to get this across the line. I appreciated getting to know you and wish you the very best.&lt;/p&gt;

&lt;p&gt;Best,&lt;br&gt;
  [Redacted]&lt;br&gt;
&lt;/p&gt;

&lt;br&gt;
&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
  My final response.
  &lt;br&gt;
  [Redacted],

&lt;p&gt;No worries at all! I wish you all the best on your journey.&amp;nbsp;What you're planning to build&amp;nbsp;([Redacted])&amp;nbsp;was really exciting to learn about - not just as a potential participant, but also as a guaranteed user&amp;nbsp;eager to have access to such a tool!&lt;/p&gt;

&lt;p&gt;Looking forward to seeing it!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkci0drxrx2tomswq8i4k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkci0drxrx2tomswq8i4k.png" alt="An image of Krishna playing the flute with text reading Krishna Says: What is meant for you will not confuse your heart, rush your soul, or demand fear." width="800" height="1513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Farewell! 👋&amp;nbsp;💚&lt;br&gt;
  // Jane&lt;br&gt;
&lt;/p&gt;

&lt;br&gt;
&lt;p&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  I need your perspective.
&lt;/h2&gt;

&lt;p&gt;Especially the ones who think you see something obvious and feel like I'm daft for not realizing it.&lt;/p&gt;

&lt;p&gt;THIS SUCKS but I cannot have this exact same nonsense happening to me over and over and over again.&lt;/p&gt;

&lt;p&gt;Reality is a mirror, the answer is inward, but I have searched for years to fix this poison in me and cannot find it without whichever repressed, hidden part of me is represented in you. I know it's just a defense mechanism trying to protect me from &lt;em&gt;something&lt;/em&gt; but I feel like a dog barking at its shadow oblivious to wtf it is.&lt;/p&gt;




&lt;h2&gt;
  
  
  I invite Open Contact 💚👽
&lt;/h2&gt;

&lt;p&gt;Please keep the comments on-topic and reach out with anything else through my socials! Happy to help, love to see what you've created using my OS contributions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;small&gt;PropJockey&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;CodePen&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;DEV Blog&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;GitHub&lt;/small&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://propjockey.io" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/propjockey-lines.svg" alt="PropJockey.io"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://codepen.io/propjockey" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/codepen.svg" alt="CodePen"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/janeori"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/dev.svg" alt="DEV Blog"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/propjockey" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/github.svg" alt="GitHub"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;small&gt;Mastodon&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;LinkedIn&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;X&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;Bluesky&lt;/small&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://front-end.social/@JaneOri" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/mastodon.svg" alt="Mastodon"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.linkedin.com/in/janeori/" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/linkedin.svg" alt="LinkedIn"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://x.com/jane0ri" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/x.svg" alt="X"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bsky.app/profile/janeori.propjockey.io" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/bluesky.svg" alt="Bluesky"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  My heart is open to receive abundance in all forms,&lt;br&gt;flowing to me in many expected and unexpected ways.
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PayPal&lt;/th&gt;
&lt;th&gt;Ko-fi&lt;/th&gt;
&lt;th&gt;Venmo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.paypal.com/donate/?cmd=_s-xclick&amp;amp;hosted_button_id=9Z925L3SJJ8BS&amp;amp;source=qr&amp;amp;ssrt=1772865628068" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/paypal.svg" alt="PayPal"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://ko-fi.com/janeori" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/ko-fi.svg" alt="Ko-fi"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://account.venmo.com/u/JaneOri" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/venmo.svg" alt="Venmo"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;BTC&lt;/th&gt;
&lt;th&gt;XRP&lt;/th&gt;
&lt;th&gt;ETH&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://app.ens.domains/janeori.eth" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/btc.svg" alt="BTC bc1qe2ss8hvmskcxpmk046msrjpmy9qults2yusgn9"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bithomp.com/en/account/X7zmKiqEhMznSXgj9cirEnD5sWo3iZPqbNPChdEKV9sM9WF" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/xrp.svg" alt="XRP rw2ciyaNshpHe7bCHo4bRWq6pqqynnWKQg : 459777128"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://app.ens.domains/janeori.eth" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/eth.svg" alt="ETH 0x674D4191dEBf9793e743D21a4B8c4cf1cC3beF54"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bc1qe...usgn9&lt;/td&gt;
&lt;td&gt;rw2ci...nWKQg&lt;br&gt;: 459777128&lt;/td&gt;
&lt;td&gt;0x674...beF54&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>opensource</category>
      <category>employeeexperience</category>
      <category>help</category>
    </item>
    <item>
      <title>CSS - The single coolest API technique you can imagine.</title>
      <dc:creator>Jane Ori</dc:creator>
      <pubDate>Thu, 07 May 2026 23:15:51 +0000</pubDate>
      <link>https://dev.to/janeori/css-the-single-coolest-api-technique-you-can-imagine-4ma8</link>
      <guid>https://dev.to/janeori/css-the-single-coolest-api-technique-you-can-imagine-4ma8</guid>
      <description>&lt;p&gt;To simply call Kizu's &lt;a href="https://kizu.dev/cyclic-toggles/" rel="noopener noreferrer"&gt;Cyclic Space Toggles&lt;/a&gt; an upgrade to my &lt;a href="https://github.com/propjockey/css-sweeper#css-is-a-programming-language-thanks-to-the-space-toggle-trick" rel="noopener noreferrer"&gt;Space Toggle&lt;/a&gt; technique is like calling &lt;code&gt;apple computers&lt;/code&gt; an upgrade to &lt;code&gt;apples&lt;/code&gt;. I'll prove it, slowly.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;my Space Toggles are a checkbox&lt;/strong&gt;&lt;br&gt;
no matter how complex the downstream implications are, or how many properties the space toggle toggles, your input is a single binary on and off so there are only ever &lt;em&gt;two states&lt;/em&gt; produced by a single toggle. (two space toggles is 4 states, three toggles is 8, 4 is 16, it's binary so it does get cooler fast! But... you're adding multiple input toggles to reach that, which means the API you expose tells your dev users to set multiple properties. &lt;em&gt;And it's hard enough to tell a dev to set even a single CSS property without hiding it behind a class name.&lt;/em&gt; lol)&lt;/p&gt;

&lt;p&gt;Kizu's invention, &lt;strong&gt;Cyclic Space Toggles, are much more.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of a one-bit checkbox, you get an &lt;em&gt;N-bit&lt;/em&gt; radio-button set, or a &lt;em&gt;dropdown select&lt;/em&gt;. The dev user's single input option is now determining any number of alternative states internally, and each one of those is itself a traditional (&lt;em&gt;inverted&lt;/em&gt;) Space Toggle.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To get an intuitive perspective on what that means, think of any dropdown - a language selector - and imagine the implications of replacing it with a single checkbox.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On the surface alone, that's a good measure of the difference I'll demonstrate.&lt;/p&gt;



&lt;p&gt;Keep in mind for this read, for both of our toggles &lt;strong&gt;Global User Reach is ~95-97%&lt;/strong&gt;. Cyclic Space Toggles are only &lt;em&gt;slightly&lt;/em&gt; less reach because of a spec-"bug" I hit with early Space Toggle research and in July 2020 &lt;a href="https://github.com/w3c/csswg-drafts/issues/5370" rel="noopener noreferrer"&gt;managed to convince them to address it&lt;/a&gt;, shipping the fix cross-browser shortly after.&lt;/p&gt;

&lt;p&gt;That means nearly everyone can benefit from and use what is shown here today.&lt;/p&gt;
&lt;h2&gt;
  
  
  Inverted? Space Toggle? CSS APIs? Catch-me-up!
&lt;/h2&gt;

&lt;p&gt;First, a standard space toggle is two states, &lt;code&gt;initial&lt;/code&gt; and a space &lt;code&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  initial
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;initial&lt;/code&gt; is effectively an &lt;code&gt;undefined&lt;/code&gt;, falsey state that on the surface allows the fallback of a &lt;code&gt;var()&lt;/code&gt; to be used. &lt;code&gt;--x: var(--falsey, fallback)&lt;/code&gt;. When it's used in the value of another property, without a fallback, the property using it &lt;em&gt;also becomes entirely falsey&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--falsey-too: var(--falsey);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is one of several falsey-state triggers the spec calls IACVT (invalid at computed value time).&lt;/p&gt;

&lt;p&gt;A var(--reference) that was never defined is &lt;code&gt;initial&lt;/code&gt; by default. A variable set to or including the keyword &lt;code&gt;initial&lt;/code&gt; is also, equally, falsey.&lt;/p&gt;
&lt;h3&gt;
  
  
  (space)
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt; (space) is effectively an inert truthy state that blocks the fallback without changing the rest of the value it's used in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;--space&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--just-blue&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--space&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;blue&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In spec terms today, it's known as &lt;code&gt;&amp;lt;empty&amp;gt;&lt;/code&gt; and setting a var with no value at all (not even a space) became valid, whereas it used to be invalid without the space. You should always include a space for best browser compatibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  Space Toggle
&lt;/h3&gt;

&lt;p&gt;Now, combine them into a toggle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;--space-toggle&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--blue-or-falsey&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--space-toggle&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;blue&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="c"&gt;/* blue */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;--space-toggle&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;initial&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--blue-or-falsey&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--space-toggle&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;blue&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="c"&gt;/* falsey */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can conditionally set any number of other properties with it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;border&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="nt"&gt;solid&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--blue-or-falsey&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;red&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--blue-or-falsey&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;black&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;cyan&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and even build more half-toggled references&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;--rem-or-falsey&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--space-toggle&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;rem&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--white-or-falsey&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--space-toggle&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;white&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;font-size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--rem-or-falsey&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;10&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--white-or-falsey&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;red&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can add multiple space toggles into a single property and if any of them are falsey, the whole thing is falsey, giving you the binary permutations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inverted?
&lt;/h3&gt;

&lt;p&gt;The standard space toggle is &lt;em&gt;perfect&lt;/em&gt; for &lt;a href="https://propjockey.github.io/bcd7sdd/" rel="noopener noreferrer"&gt;logic gates&lt;/a&gt; and going as far as a full fledged actually-programatic, not hardcoded at all beyond saying where the turds are located, &lt;a href="https://propjockey.github.io/css-sweeper/" rel="noopener noreferrer"&gt;100% CSS implementation of minesweeper&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When you expose a space toggle as an &lt;em&gt;CSS API endpoint&lt;/em&gt;, however, the library/component/etc will typically have implemented their CSS with the space toggle defined as a space (truthy), making their developer users set it to &lt;code&gt;initial&lt;/code&gt; as the API endpoint to flip it.&lt;/p&gt;

&lt;p&gt;CSS implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;--use-my-feature&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--currently-disabled&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--use-my-feature&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;none&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;border-style&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--currently-disabled&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;solid&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--currently-disabled&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;"/img/cat.gif"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CSS API docs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set `--use-my-feature` to `initial` for a great time.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The API tells them to &lt;em&gt;turn off&lt;/em&gt; a space toggle to &lt;em&gt;turn on&lt;/em&gt; a feature. Hence, inverted.&lt;/p&gt;

&lt;p&gt;For a long time, the only way "flip" a space toggle programmatically was with an animation, so if a library implemented it as &lt;code&gt;initial&lt;/code&gt; by default without that animation layer, they didn't have great ways to define a default state. For example:&lt;/p&gt;

&lt;p&gt;Wonky CSS implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;--use-my-feature&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;initial&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--currently-disabled&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--use-my-feature&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;none&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nt"&gt;border-style&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--currently-disabled&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="c"&gt;/* ^ technically works because `solid` is the default property value when ` ` is attempted. */&lt;/span&gt;

&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--currently-disabled&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;"/img/cat.gif"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="c"&gt;/* ^ technically works because it's invalid as "none cat" until flipped to the valid (space) cat `  cat` */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CSS API docs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Set `--use-my-feature` to ` ` for a great time with a wonky backstory.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Inversion history
&lt;/h4&gt;

&lt;p&gt;When I first invented the space toggle, it was an intentional prayer for &lt;a href="https://augmented-ui.com/" rel="noopener noreferrer"&gt;augmented-ui&lt;/a&gt; v2's CSS-based API (rather than HTML/class/attr based API) that got answered by some external divine ping telling me to read the specification over and over. Once I tuned into what God was trying to show me, a fire was lit and I ran with it.&lt;/p&gt;

&lt;p&gt;Tangent, demo, showcase, tangent, demo showcase, spreading all over CSS world on social media and gaining a much wider audience than I was accustom to. So much fun. :)&lt;/p&gt;

&lt;p&gt;Then I got pulled into another thrilling tangent and in July 2020, I created and released &lt;a href="https://github.com/propjockey/css-media-vars" rel="noopener noreferrer"&gt;css-media-vars&lt;/a&gt; before finishing &lt;code&gt;augmented-ui&lt;/code&gt; v2 because the combination of space-toggles and media queries was so good that I've used &lt;code&gt;css-media-vars&lt;/code&gt; in every website I've done since then. (until its successor, &lt;a href="https://dev.to/janeori/css-breakpoint-units-design-with-pixels-and-get-fluid-ux-for-free-while-automatically-solving-two-4mdj"&gt;breakpoint-system&lt;/a&gt;) The standard space-toggle was perfect for that use case because the user was defining both of the states and I was only &lt;a href="https://github.com/propjockey/css-media-vars/blob/master/css-media-vars.css" rel="noopener noreferrer"&gt;shipping the toggles&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So for &lt;strong&gt;augmented-ui&lt;/strong&gt;, when it came time to finalize the API in August 2020, (after realizing that it was much cleaner in my code if we start with it "on" to define our "off" state by default) I had to decide either stick with the messy code and tell my users to write an empty space to turn on the feature (to which they'd surely raise an eyebrow), or tell them to ...initialize it with "initial" which seemed legit. Easy choice except... there's another trade-off that's been resolved in the spec (as previously mentioned) but it was actually &lt;em&gt;very&lt;/em&gt; problematic at the time to default it to &lt;code&gt;initial&lt;/code&gt; in a library that's intended to be nested, so it required an entire separate "reset" layer in between nestings to avoid. A problem &lt;a href="https://propjockey.github.io/css-media-vars/" rel="noopener noreferrer"&gt;&lt;code&gt;css-media-vars&lt;/code&gt;&lt;/a&gt; didn't directly have because it was on &lt;code&gt;:root&lt;/code&gt;. I was hesitant to make that trade off, but decided to move forward with it and add a huge annoying Caveat Sand Storm section to the docs to explain it.&lt;/p&gt;

&lt;p&gt;After all that time, when &lt;a href="https://lea.verou.me/blog/2020/10/the-var-space-hack-to-toggle-multiple-values-with-one-custom-property/" rel="noopener noreferrer"&gt;Lea Verou wrote about the space toggle&lt;/a&gt; in October 2020, she proposed them as inverted by default (without warning about the spec nesting problem D:). So... there may not be a consensus in the wider CSS loving audience on which variant is "inverted" because she had orders of magnitude more reach than I did at the time... buuut I maintain my perspective on which is which, and I've digressed!&lt;/p&gt;

&lt;h2&gt;
  
  
  Cyclic Space Toggles
&lt;/h2&gt;

&lt;p&gt;Imagining cyclic space toggles as a dropdown is a great mental entry.&lt;/p&gt;

&lt;p&gt;You can programmatically respond to each option individually in your CSS code, knowing if it's selected or not.&lt;/p&gt;

&lt;p&gt;This is a Super Saiyan space toggle to our Saiyan space toggle, for several reasons.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvlxdwv9exbgxac7pwlx9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvlxdwv9exbgxac7pwlx9.png" alt="an image showing CSS vars, one named --select and 5 named --option-1 to 5. Select is set to option 1. All 5 options are set to select with an empty space fallback. option 1 and select are red indicating invalid cyclic. The other 4 options are green indicating valid because they're using the space fallback. The 4 options not selected reference select but because select isn't referencing them, select is treated as initial but they are still allowed to use the fallback because they aren't cyclic." width="768" height="768"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All of these API &lt;code&gt;--option&lt;/code&gt; vars are inverted space toggles (the kind we prefer in making APIs - our users make them initial while we use space to set defaults internally!), and they're all interlinked, only one option resolves to &lt;code&gt;initial&lt;/code&gt;, the rest are &lt;code&gt;space&lt;/code&gt;. You can add any number of --options you want, and they can all have completely different effects on the broader library internals.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A key difference here is that with the standard space toggle, the toggle itself is what the library/component author uses to control their internal state AND that same var is what our user modifies by setting it to &lt;code&gt;initial&lt;/code&gt; (or to a space).&lt;/p&gt;

&lt;p&gt;With cyclic vars, the API is our dev user setting the &lt;code&gt;--select&lt;/code&gt; to one of our &lt;code&gt;--option&lt;/code&gt; vars, internally we only use each of the &lt;code&gt;--option&lt;/code&gt; vars because &lt;code&gt;--select&lt;/code&gt; is &lt;em&gt;always initial&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The dropdown analogy... is a veil.
&lt;/h3&gt;

&lt;p&gt;One of the most heavily desired features CSS library authors have wanted since variables were introduced is the ability to make shorthand properties so our users can specify multiple related states in a single declaration.&lt;/p&gt;

&lt;p&gt;WE WERE &lt;a href="https://issues.chromium.org/issues/390205875#comment4" rel="noopener noreferrer"&gt;SO CLOSE&lt;/a&gt; TO GETTING THAT WITH CUSTOM FUNCTIONS, but in a gutting last moment change &lt;a href="https://github.com/w3c/csswg-drafts/issues/11190#issuecomment-2596276757" rel="noopener noreferrer"&gt;that was originally expected and planned to happen&lt;/a&gt; comma-separated var() values passed as arguments no longer spread by default like they do in standard functions &lt;code&gt;rgb(var(--rgb))&lt;/code&gt;. So there's still no way implemented in any browser to dissect a custom property set to multiple values.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I'm not exaggerating even slightly, there are an enormous number of benefits to csvargument spreading in custom functions, removal of that, aside from being &lt;a href="https://front-end.social/@JaneOri/116265070044655944" rel="noopener noreferrer"&gt;another irritating inconsistency&lt;/a&gt; in CSS, is the single biggest nerf I've ever witnessed to an incredible potential. Custom shorthands is a footnote on the tip of the iceberg of the potential in csvargument spreading. DEPRESSING.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;BUT! &lt;strong&gt;We have a surprise here.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If space toggles were new-born Saiyans, cyclic space toggles are Super Saiyan God (Blue) Super Saiyans. The abilities ARE THAT MUCH MORE POWERFUL; I'M NOT KIDDING EVEN A LITTLE!&lt;/p&gt;

&lt;p&gt;I don't even know if Kizu realizes all of this yet, but just wait for the details here. 🥵🤤&lt;/p&gt;

&lt;p&gt;The dropdown... is actually a multi-select. &lt;strong&gt;The implications of this in CSS API development are awesome!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your dev user sets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;--select&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--option-1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--option-2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then &lt;em&gt;both&lt;/em&gt; options are &lt;code&gt;initial&lt;/code&gt; and the rest are still space.&lt;/p&gt;

&lt;p&gt;This is a custom &lt;em&gt;boolean only&lt;/em&gt; shorthand API. It's a far cry from actual shorthands I'm begging for, but man it is AWESOME for now!&lt;/p&gt;

&lt;p&gt;CSS library/component authors can specify any number of related boolean (space toggle) options and their dev users can flip all of them on in a single declaration.&lt;/p&gt;

&lt;h4&gt;
  
  
  Real world use case
&lt;/h4&gt;

&lt;p&gt;I've already shipped a CSS library using this!&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://propjockey.breakpoint-system.com/#docs-fluidity" rel="noopener noreferrer"&gt;breakpoint-system's fluidity option&lt;/a&gt; I allow users to opt-in to a subset of their globally defined breakpoints.&lt;/p&gt;

&lt;p&gt;This causes the internals to skip the missing breakpoints as if they weren't part of the set for a specific design. Among other effects, the built in fluid design vars &lt;a href="https://propjockey.breakpoint-system.com/#bpu-breakpoint-accessibility-tutorial" rel="noopener noreferrer"&gt;"breakpoint units"&lt;/a&gt; will now scale seamlessly from the lower breakpoint up to the next one included without resetting on the skipped one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.promotion-page-layout&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--bp-fluidity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--fluid-xxs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--fluid-sm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--fluid-lg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes the whole system behave as if there were only those 3 breakpoints defined, while their global set remains untouched on other pages/layouts.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I've even used this multi-select idea in other features within the library that are currently undocumented!&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Where else would we use it?
&lt;/h4&gt;

&lt;p&gt;If a theming library had variants, you could provide an API like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;--use-theme&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--blue-theme&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--button-states&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--text-emphasis&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--override-preference-to-dark-mode&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And internally, because space toggles can be combined logically, the library would know how to emphasize the text in the blue theme on a button, which could be different from in a paragraph or in the yellow theme.&lt;/p&gt;




&lt;p&gt;An &lt;a href="https://css-peeps.com/" rel="noopener noreferrer"&gt;avatar-building CSS library like CSS-Peeps&lt;/a&gt; could take its current &lt;a href="https://www.bitovi.com/blog/css-only-type-grinding-casting-tokens-into-useful-values" rel="noopener noreferrer"&gt;CSS type-grinding&lt;/a&gt; API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;  &lt;span class="nt"&gt;--peep-head&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;long-straight&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;--peep-face&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;rage&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;--peep-body&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;striped-tee&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and instead do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;--peep&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--head-long-straight&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
 &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--face-rage&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
 &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--body-striped-tee&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Tailwind could go from awful dom pollution repeated a thousand times&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-blue-600 hover:bg-blue-700 text-white font-bold rounded-lg transition px-4 py-2 text-sm md:px-8 md:py-4 md:text-lg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Click Me
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-blue-600 hover:bg-blue-700 text-white font-bold rounded-lg transition px-4 py-2 text-sm md:px-8 md:py-4 md:text-lg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Click Me Too
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to a reusable CSS-based API&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tailwind my-tw-button"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Click Me
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"tailwind my-tw-button"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Click Me Too
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.my-tw-button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--tailwind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--bg-blue-600&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--hover&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;bg-blue-700&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--text-white&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--font-bold&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--rounded-lg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--transition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--px-4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--py-2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--text-sm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;px-8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;py-4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;text-lg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which is such a great idea, I might even implement it myself. Internally, inside the media queries where those responsive classes are defined, it instead would check if those specific space toggles were flipped.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I could probably port all of the base tailwind classes to this cyclic space toggle version in a single day.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Open Contact 👽
&lt;/h2&gt;

&lt;p&gt;Please do reach out - I'd LOVE to hear what you think!&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;small&gt;PropJockey&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;CodePen&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;DEV Blog&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;GitHub&lt;/small&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://propjockey.io" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/propjockey-lines.svg" alt="PropJockey.io"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://codepen.io/propjockey" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/codepen.svg" alt="CodePen"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/janeori"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/dev.svg" alt="DEV Blog"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/propjockey" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/github.svg" alt="GitHub"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;small&gt;Mastodon&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;LinkedIn&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;X&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;Bluesky&lt;/small&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://front-end.social/@JaneOri" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/mastodon.svg" alt="Mastodon"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.linkedin.com/in/janeori/" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/linkedin.svg" alt="LinkedIn"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://x.com/jane0ri" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/x.svg" alt="X"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bsky.app/profile/janeori.propjockey.io" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/bluesky.svg" alt="Bluesky"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  My heart is open to receive abundance in all forms,&lt;br&gt;flowing to me in many expected and unexpected ways.
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PayPal&lt;/th&gt;
&lt;th&gt;Ko-fi&lt;/th&gt;
&lt;th&gt;Venmo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.paypal.com/donate/?cmd=_s-xclick&amp;amp;hosted_button_id=9Z925L3SJJ8BS&amp;amp;source=qr&amp;amp;ssrt=1772865628068" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/paypal.svg" alt="PayPal"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://ko-fi.com/janeori" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/ko-fi.svg" alt="Ko-fi"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://account.venmo.com/u/JaneOri" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/venmo.svg" alt="Venmo"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;BTC&lt;/th&gt;
&lt;th&gt;XRP&lt;/th&gt;
&lt;th&gt;ETH&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://app.ens.domains/janeori.eth" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/btc.svg" alt="BTC bc1qe2ss8hvmskcxpmk046msrjpmy9qults2yusgn9"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bithomp.com/en/account/X7zmKiqEhMznSXgj9cirEnD5sWo3iZPqbNPChdEKV9sM9WF" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/xrp.svg" alt="XRP rw2ciyaNshpHe7bCHo4bRWq6pqqynnWKQg : 459777128"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://app.ens.domains/janeori.eth" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/eth.svg" alt="ETH 0x674D4191dEBf9793e743D21a4B8c4cf1cC3beF54"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bc1qe...usgn9&lt;/td&gt;
&lt;td&gt;rw2ci...nWKQg&lt;br&gt;: 459777128&lt;/td&gt;
&lt;td&gt;0x674...beF54&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>css</category>
      <category>api</category>
      <category>webdev</category>
    </item>
    <item>
      <title>100% CSS: repeat(--n, anything)</title>
      <dc:creator>Jane Ori</dc:creator>
      <pubDate>Sat, 02 May 2026 19:33:36 +0000</pubDate>
      <link>https://dev.to/janeori/100-css-repeat-n-anything-59ni</link>
      <guid>https://dev.to/janeori/100-css-repeat-n-anything-59ni</guid>
      <description>&lt;p&gt;Ages ago when CSS grids came with a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/repeat" rel="noopener noreferrer"&gt;repeat() function&lt;/a&gt; to simplify defining repetitive columns and rows, I was not alone in wishing for this function to be made generic and work in any context.&lt;/p&gt;

&lt;p&gt;After seeing &lt;a href="https://bsky.app/profile/wesbos.com/post/3mknlplcdrs2v" rel="noopener noreferrer"&gt;Wes Bos on BlueSky wishing for this exact concept&lt;/a&gt;, specifically for repeating segments in a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/basic-shape/shape" rel="noopener noreferrer"&gt;shape()&lt;/a&gt; definition, I chimed in with my +1's on making &lt;code&gt;repeat()&lt;/code&gt; generic across CSS&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flo53288ikimra748oonj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flo53288ikimra748oonj.png" alt="Screenshot of my responses reading " width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Without delay, &lt;a href="https://github.com/w3c/csswg-drafts/issues/13862" rel="noopener noreferrer"&gt;@noamr opened an issue for the w3c csswg&lt;/a&gt; to get that ball rolling.&lt;/p&gt;

&lt;p&gt;Moments later I was struck by that inspiration that seems to come from God/heaven/the universe/source, full of the excitement of "I can do that &lt;em&gt;now&lt;/em&gt;!" and I began banging out a custom function in codepen, on my phone, to bring our hopes into the &lt;em&gt;present&lt;/em&gt; instead of waiting for an official implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Here is CSS --repeat() in full
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@function&lt;/span&gt; &lt;span class="n"&gt;--repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;--x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--bit7&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;down&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="py"&gt;--val6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--bit7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;128&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="py"&gt;--bit6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;down&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--val6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;64&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="py"&gt;--val5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--val6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--bit6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="py"&gt;--bit5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;down&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--val5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;32&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="py"&gt;--val4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--val5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--bit5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="py"&gt;--bit4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;down&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--val4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;16&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="py"&gt;--val3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--val4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--bit4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;16&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="py"&gt;--bit3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;down&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--val3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="py"&gt;--val2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--val3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--bit3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="py"&gt;--bit2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;down&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--val2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="py"&gt;--val1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--val2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--bit2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="py"&gt;--bit1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;down&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--val1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="py"&gt;--bit0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--val1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--bit1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="py"&gt;--pow0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;--pow1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--pow0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--pow0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;--pow2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--pow1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--pow1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;--pow3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--pow2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--pow2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;--pow4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--pow3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--pow3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;--pow5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--pow4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--pow4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;--pow6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--pow5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--pow5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;--pow7&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--pow6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--pow6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="py"&gt;result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--bit0&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--pow0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="py"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;
    &lt;span class="err"&gt;if(style(--bit1&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;1):&lt;/span&gt; &lt;span class="err"&gt;var(--pow1);&lt;/span&gt; &lt;span class="py"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;
    &lt;span class="err"&gt;if(style(--bit2&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;1):&lt;/span&gt; &lt;span class="err"&gt;var(--pow2);&lt;/span&gt; &lt;span class="py"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;
    &lt;span class="err"&gt;if(style(--bit3&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;1):&lt;/span&gt; &lt;span class="err"&gt;var(--pow3);&lt;/span&gt; &lt;span class="py"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;
    &lt;span class="err"&gt;if(style(--bit4&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;1):&lt;/span&gt; &lt;span class="err"&gt;var(--pow4);&lt;/span&gt; &lt;span class="py"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;
    &lt;span class="err"&gt;if(style(--bit5&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;1):&lt;/span&gt; &lt;span class="err"&gt;var(--pow5);&lt;/span&gt; &lt;span class="py"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;
    &lt;span class="err"&gt;if(style(--bit6&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;1):&lt;/span&gt; &lt;span class="err"&gt;var(--pow6);&lt;/span&gt; &lt;span class="py"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;
    &lt;span class="err"&gt;if(style(--bit7&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;1):&lt;/span&gt; &lt;span class="err"&gt;var(--pow7);&lt;/span&gt; &lt;span class="py"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="err"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And hands on:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/XJNWYqQ?height=600&amp;amp;default-tab=css,result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Ultimately what any non-iterative &lt;code&gt;repeat()&lt;/code&gt; function actually is just casting the number-of-times-to-repeat parameter into the &lt;a href="https://en.wikipedia.org/wiki/Unary_numeral_system" rel="noopener noreferrer"&gt;unary number base&lt;/a&gt; using the 2nd parameter as the symbol representing "1".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;--repeat(4,1);&lt;/span&gt;
&lt;span class="cm"&gt;/* 1111 */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The easiest way to convert to unary in CSS is to first convert it to binary because ...the most apt way to describe what it means to read a binary number in the context of a &lt;code&gt;--repeat()&lt;/code&gt; function is to say:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;For each bit:

if it's 1,
  add the corresponding power of two to the total value.

If it's 0,
  add 0 (or just do nothing) to the total value.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, what is &lt;code&gt;0b10111&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  1 x 2^4 (1 x 16)
+ 0 x 2^3 (0 x 8)
+ 1 x 2^2 (1 x 4)
+ 1 x 2^1 (1 x 2)
+ 1 x 2^0 (1 x 1)
------------------
23
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So converting to unary from there becomes a sequence of known concatenations (additions) rather than an arbitrary length from a direct conversion. Ultimately, the corresponding binary bit represents a boolean flag - do we include this specific known set in the final concatenation or not?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(1 yes) 1111 1111 1111 1111
(0 nah) 1111 1111
(1 yes) 1111
(1 yes) 11
(1 yes) 1
---------------------------
(0b10111) 1111 1111 1111 1111  1111  11  1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(the spaces are for human readability and not actually part of unary)&lt;/p&gt;

&lt;h3&gt;
  
  
  Converting decimal to binary in CSS
&lt;/h3&gt;

&lt;p&gt;Long long ago when Ana Tudor pointed out &lt;a href="https://x.com/anatudor/status/1399849494628425734" rel="noopener noreferrer"&gt;how she simulates mod()&lt;/a&gt; on twitter (which had been known to her &lt;em&gt;even longer&lt;/em&gt;), I hadn't even begun playing with custom properties of the Houdini spec yet, but I realized how much potential was in that idea to do something impossible CSS - to add binary operators to the language. I released &lt;a href="https://propjockey.github.io/css-bin-bits/" rel="noopener noreferrer"&gt;css-bin-bits&lt;/a&gt; a month later - it works exactly like the start of this repeat function:&lt;/p&gt;

&lt;p&gt;We use rounded integer casting (which is the same as &lt;code&gt;floor(n)&lt;/code&gt; or &lt;code&gt;round(down, n, 1)&lt;/code&gt;, after division of powers of two, in sequence, to bite off the most significant bit of an input number:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# 0b10111
&lt;/span&gt;
&lt;span class="n"&gt;dec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# 1.3125
&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;or1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;round&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;down&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 1
&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;or1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="c1"&gt;# 0b00101
&lt;/span&gt;
&lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;just do that until the last bit and you've converted your input from decimal into binary, with each bit in its own var.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You do have to assume a maximum value. The &lt;code&gt;--repeat()&lt;/code&gt; function I provided supports 8 bits, 255 total repeats.&lt;br&gt;
(css-bin-bits supports multiple 16 bit values)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In modern CSS, you implement this sequence exactly like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;  &lt;span class="nt"&gt;--bit7&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;round&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;down&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--n&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="err"&gt;128&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="nt"&gt;--val6&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--n&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--bit7&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="err"&gt;128&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nt"&gt;--bit6&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;round&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;down&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--val6&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="err"&gt;64&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="nt"&gt;--val5&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--val6&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--bit6&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="err"&gt;64&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nt"&gt;--bit5&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;round&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;down&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--val5&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="err"&gt;32&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="nt"&gt;--val4&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--val5&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--bit5&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="err"&gt;32&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nt"&gt;--bit4&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;round&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;down&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--val4&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="err"&gt;16&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="nt"&gt;--val3&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--val4&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--bit4&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="err"&gt;16&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nt"&gt;--bit3&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;round&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;down&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--val3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="err"&gt;8&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="nt"&gt;--val2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--val3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--bit3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="err"&gt;8&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nt"&gt;--bit2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;round&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;down&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--val2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="err"&gt;4&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="nt"&gt;--val1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--val2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--bit2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="err"&gt;4&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="nt"&gt;--bit1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;round&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;down&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--val1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
  &lt;span class="nt"&gt;--bit0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--val1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--bit1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start with the most significant bit supported, divide by that corresponding power of two, round that result down, if it's 1, subtract that power of two from &lt;code&gt;--n&lt;/code&gt; and use that value for the next step... continue until the last bit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Converting binary to unary in CSS
&lt;/h3&gt;

&lt;p&gt;We mentioned earlier that it's concatenating known sets of the symbol back-to-back, based on powers of two.&lt;/p&gt;

&lt;p&gt;So we must generate the list of known sets up to our maximum.&lt;/p&gt;

&lt;p&gt;First, to repeat any CSS variable is straight forward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;  &lt;span class="nt"&gt;--x&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;👽&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;--pow0&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--x&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;--pow1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="c"&gt;/* --pow1 = 👽 👽 */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's 2^0 and 2^1 taken care of.&lt;/p&gt;

&lt;p&gt;Since each power of 2 is double the previous, we just complete the set by doubling the previous until max:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;  &lt;span class="nt"&gt;--pow2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;--pow3&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;--pow4&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;--pow5&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow4&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow4&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;--pow6&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow5&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;--pow7&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow6&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow6&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and we inch towards &lt;a href="https://en.wikipedia.org/wiki/Billion_laughs_attack" rel="noopener noreferrer"&gt;the billion laughs attack&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;CSS has protections for the billion laughs attack built in! During development of &lt;a href="https://augmented-ui.com/" rel="noopener noreferrer"&gt;augmented-ui v2&lt;/a&gt; in early 2020 after I &lt;a href="https://github.com/propjockey/css-sweeper#css-is-a-programming-language-thanks-to-the-space-toggle-trick" rel="noopener noreferrer"&gt;invented the Space Toggle&lt;/a&gt;, I actually &lt;a href="https://x.com/Jane0ri/status/1283474925139959808" rel="noopener noreferrer"&gt;triggered Chrome's new protection limit&lt;/a&gt; and Anders (who is very often the one responsible for implementing incredibly awesome CSS features in Chrome) bumped up their low-ish limit to something very comfortable for all of CSS since we had legitimate use cases!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now that we have our sets built out, we just need to check each of our bits with the new &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/if" rel="noopener noreferrer"&gt;if(style())&lt;/a&gt;, output the corresponding &lt;code&gt;--powX&lt;/code&gt; variable if it's 1, else an empty "space" in a concatenation block, and we're done!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;  &lt;span class="nt"&gt;result&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--bit0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="nt"&gt;else&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;;)&lt;/span&gt;
    &lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--bit1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="nt"&gt;else&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;;)&lt;/span&gt;
    &lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--bit2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow2&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="nt"&gt;else&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;;)&lt;/span&gt;
    &lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--bit3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="nt"&gt;else&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;;)&lt;/span&gt;
    &lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--bit4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow4&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="nt"&gt;else&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;;)&lt;/span&gt;
    &lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--bit5&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="nt"&gt;else&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;;)&lt;/span&gt;
    &lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--bit6&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow6&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="nt"&gt;else&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;;)&lt;/span&gt;
    &lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--bit7&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--pow7&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="nt"&gt;else&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;if(style())&lt;/code&gt; is such incredible work, once it's baseline, it makes the Space Toggle completely obsolete and already does far more and far cooler things than Space Toggle alone can do.&lt;/p&gt;

&lt;p&gt;It's even properly short-circuited - so those &lt;code&gt;--powX&lt;/code&gt; variables &lt;em&gt;are not computed&lt;/em&gt; unless they are used. (Only the dependency tree for them is calculated, which is a simple straight line from &lt;code&gt;--pow7&lt;/code&gt; ... to &lt;code&gt;--pow0&lt;/code&gt; to &lt;code&gt;--x&lt;/code&gt;)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Like always, my work feels inspired/guided, and comes with amazing synchronicities leading up to it. I had absolutely no idea this &lt;code&gt;if(style( = ))&lt;/code&gt; syntax existed, and it doesn't work with &lt;code&gt;if(style( : ))&lt;/code&gt; syntax. But the day prior, in a completely unrelated thread, I saw &lt;a href="https://bsky.app/profile/css-only.dev/post/3mkl4hb3u3c26" rel="noopener noreferrer"&gt;T. Afif post&lt;/a&gt; a link to &lt;a href="https://css-tip.com/if-trick/" rel="noopener noreferrer"&gt;an article teaching about it&lt;/a&gt;. When my assumed implementation didn't work using &lt;code&gt;:&lt;/code&gt;, I got a tap on my brain, swapped the syntax to what I just learned about, and suddenly it worked! Thank you my friend!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  --repeat() use cases and demos!
&lt;/h2&gt;

&lt;p&gt;I've packaged it up for easy use anywhere just by importing it into your CSS file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="sx"&gt;url("https://unpkg.com/@propjockey/doubledash.css@0.0.2/functions/repeat.css")&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use it in content
&lt;/h3&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/GgNgbVG?height=600&amp;amp;default-tab=css,result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Use it with text-shadow
&lt;/h3&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/raWaXNe?height=600&amp;amp;default-tab=css,result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;em&gt;--repeat-join(--n, --join, --x)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The minimum value for --n is 1, we can pass a comma as a parameter by wrapping it in the do-not-spread curly braces operator as shown in the codepen.&lt;/p&gt;

&lt;p&gt;We modify the original repeat function by subtracting 1 from --n before turning it into binary. We add --join to --x for --pow0, which then duplicates join everywhere before --x --n minus 1 times.&lt;/p&gt;

&lt;p&gt;Then on the output we use --x directly once first, then conditionally concatenate all the --powX values like before.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/propjockey/doubledash.css/blob/e8c11de3d93cdade5cbc88613d316ef093996fdf/functions/repeat-join.css" rel="noopener noreferrer"&gt;Code on github here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Leave a star while you're there!&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Use it with drop-shadow() in a filter
&lt;/h3&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/wBoBVgb?height=600&amp;amp;default-tab=css,result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Use it to repeat line segments in shape()
&lt;/h3&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/EaNaqXX?height=600&amp;amp;default-tab=css,result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Use it for any part of any property!
&lt;/h3&gt;

&lt;p&gt;Need to repeat subsets your animation-* property list without using the default looping of the full list?&lt;br&gt;
This solves it!&lt;/p&gt;

&lt;p&gt;Need to repeat &lt;em&gt;any subset&lt;/em&gt; of any parallel-array CSS properties?&lt;br&gt;
This solves it!&lt;/p&gt;

&lt;p&gt;Need to repeat steps in your conic-gradient() only a few times?&lt;br&gt;
This solves it!&lt;/p&gt;

&lt;p&gt;Need to repeat something not listed? Leave a comment!&lt;/p&gt;




&lt;h2&gt;
  
  
  Open Contact 👽
&lt;/h2&gt;

&lt;p&gt;Please do reach out if you need help with any of this, have feature requests, or want to share what you've created!&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;small&gt;PropJockey&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;CodePen&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;DEV Blog&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;GitHub&lt;/small&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://propjockey.io" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/propjockey-lines.svg" alt="PropJockey.io"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://codepen.io/propjockey" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/codepen.svg" alt="CodePen"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/janeori"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/dev.svg" alt="DEV Blog"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/propjockey" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/github.svg" alt="GitHub"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;small&gt;Mastodon&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;LinkedIn&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;X&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;Bluesky&lt;/small&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://front-end.social/@JaneOri" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/mastodon.svg" alt="Mastodon"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.linkedin.com/in/janeori/" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/linkedin.svg" alt="LinkedIn"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://x.com/jane0ri" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/x.svg" alt="X"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bsky.app/profile/janeori.propjockey.io" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/bluesky.svg" alt="Bluesky"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  My heart is open to receive abundance in all forms,&lt;br&gt;flowing to me in many expected and unexpected ways.
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PayPal&lt;/th&gt;
&lt;th&gt;Ko-fi&lt;/th&gt;
&lt;th&gt;Venmo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.paypal.com/donate/?cmd=_s-xclick&amp;amp;hosted_button_id=9Z925L3SJJ8BS&amp;amp;source=qr&amp;amp;ssrt=1772865628068" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/paypal.svg" alt="PayPal"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://ko-fi.com/janeori" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/ko-fi.svg" alt="Ko-fi"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://account.venmo.com/u/JaneOri" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/venmo.svg" alt="Venmo"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;BTC&lt;/th&gt;
&lt;th&gt;XRP&lt;/th&gt;
&lt;th&gt;ETH&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://app.ens.domains/janeori.eth" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/btc.svg" alt="BTC bc1qe2ss8hvmskcxpmk046msrjpmy9qults2yusgn9"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bithomp.com/en/account/X7zmKiqEhMznSXgj9cirEnD5sWo3iZPqbNPChdEKV9sM9WF" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/xrp.svg" alt="XRP rw2ciyaNshpHe7bCHo4bRWq6pqqynnWKQg : 459777128"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://app.ens.domains/janeori.eth" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/eth.svg" alt="ETH 0x674D4191dEBf9793e743D21a4B8c4cf1cC3beF54"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bc1qe...usgn9&lt;/td&gt;
&lt;td&gt;rw2ci...nWKQg&lt;br&gt;: 459777128&lt;/td&gt;
&lt;td&gt;0x674...beF54&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>css</category>
      <category>customcssfunctions</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>CSS Breakpoint Units - design with pixels and get fluid UX for free while automatically solving two of the oldest accessibility problems.</title>
      <dc:creator>Jane Ori</dc:creator>
      <pubDate>Sat, 18 Apr 2026 20:16:19 +0000</pubDate>
      <link>https://dev.to/janeori/css-breakpoint-units-design-with-pixels-and-get-fluid-ux-for-free-while-automatically-solving-two-4mdj</link>
      <guid>https://dev.to/janeori/css-breakpoint-units-design-with-pixels-and-get-fluid-ux-for-free-while-automatically-solving-two-4mdj</guid>
      <description>&lt;p&gt;I've created many NPM packages and invented many hacks focused on helping us all &lt;em&gt;easily&lt;/em&gt; create beyond what's typically considered possible. It drives me.&lt;/p&gt;

&lt;p&gt;This idea, I swear was given to me by higher powers and backed with so much excitement and perfectly sequenced synchronicities... Nobody would believe the details.&lt;/p&gt;

&lt;h2&gt;
  
  
  A new breakpoint-system
&lt;/h2&gt;

&lt;p&gt;Using my &lt;a href="https://dev.to/janeori/css-type-casting-to-numeric-tanatan2-scalars-582j"&gt;tan(atan2()) scalar&lt;/a&gt; idea, I take a &lt;code&gt;&amp;lt;length&amp;gt;&lt;/code&gt; like &lt;code&gt;100cqw&lt;/code&gt; and turn it into its pixel equivalent as a &lt;code&gt;&amp;lt;number&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, &lt;code&gt;1rem&lt;/code&gt; length becomes the number &lt;code&gt;16&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Writing up to 10 user-configurable &lt;code&gt;&amp;lt;number&amp;gt;&lt;/code&gt; vars as pixel-based breakpoint locations, (maybe called &lt;code&gt;sm&lt;/code&gt;, &lt;code&gt;md&lt;/code&gt;, &lt;code&gt;lg&lt;/code&gt;, etc)&lt;/p&gt;

&lt;p&gt;I &lt;a href="https://codepen.io/propjockey/pen/MYjEZYp?editors=1100" rel="noopener noreferrer"&gt;combine it all with abs(), clamp(), min(), max(), and calc() into registered &lt;code&gt;&amp;lt;integer&amp;gt;&lt;/code&gt; results&lt;/a&gt; to create bit flags. &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Each flag represents the results of comparing those breakpoints to &lt;code&gt;100cqw as a number&lt;/code&gt;. Is the number less than the breakpoint? Greater than or equal to? In between two of them?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;100cqw&lt;/code&gt; becomes the width to query against, &lt;em&gt;the bit flag comparisons are the results of each query&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  This opens up 3 API paths
&lt;/h3&gt;

&lt;p&gt;calc() switches, @container style() queries, and if(style()) queries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;aspect-ratio&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--qlt-md&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;5&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="err"&gt;7&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
  &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--qin-md&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;4&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="err"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
  &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--qgte-lg&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;16&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="err"&gt;9&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.biggest-heading&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;@container&lt;/span&gt; &lt;span class="err"&gt;style(&lt;/span&gt;&lt;span class="py"&gt;--qlt-md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;@container&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--qin-md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;@container&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--qgte-lg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;28px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;grid-template-areas&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
  &lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--qlt-md&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="s1"&gt;"a"&lt;/span&gt; &lt;span class="s1"&gt;"b"&lt;/span&gt; &lt;span class="s1"&gt;"c"&lt;/span&gt; &lt;span class="s1"&gt;"d"&lt;/span&gt; &lt;span class="s1"&gt;"e"&lt;/span&gt; &lt;span class="s1"&gt;"f"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--qin-md&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="s1"&gt;"a a"&lt;/span&gt; &lt;span class="s1"&gt;"b c"&lt;/span&gt; &lt;span class="s1"&gt;"b d"&lt;/span&gt; &lt;span class="s1"&gt;"b e"&lt;/span&gt; &lt;span class="s1"&gt;"f e"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--qgte-lg&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;):&lt;/span&gt; &lt;span class="s1"&gt;"a a a a"&lt;/span&gt; &lt;span class="s1"&gt;"b b c d"&lt;/span&gt; &lt;span class="s1"&gt;"b b f e"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;calc()&lt;/code&gt; can do all of these at the same time &lt;a href="https://codepen.io/propjockey/pen/azmVpvd" rel="noopener noreferrer"&gt;using keyframes of an always-paused animation&lt;/a&gt;, setting all 3 properties in each keyframe.&lt;/p&gt;

&lt;p&gt;You choose your API to choose your user reach. The library reach is 91% as of April 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  This is the solution to web development.
&lt;/h2&gt;

&lt;p&gt;Designers win. Developers win. Accessibility wins. Your users win.&lt;/p&gt;

&lt;p&gt;Even the consciousness of the idea itself wins because it becomes a source of ease for everyone involved.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Everything we've come to accept goes away&lt;/em&gt; as everything we've hoped for takes its place. With &lt;strong&gt;&lt;em&gt;less&lt;/em&gt;&lt;/strong&gt; effort.&lt;/p&gt;




&lt;h3&gt;
  
  
  Automatic accessibility win #1
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;100cqw&lt;/code&gt; &lt;em&gt;does not include the scrollbars&lt;/em&gt;, media queries &lt;em&gt;do&lt;/em&gt;. If a user's system accessibility is configured for scrollbars to always be on and maybe even set to a bigger size, historically you deliver your 1024 breakpoint design in an unknowable smaller available space.&lt;/p&gt;

&lt;p&gt;For years engineers have been left to work around it without even reliably being able to detect it in CSS, let alone measure it or have the skill to adjust a designer's vision appropriately for every potential scenario.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;breakpoint-system&lt;/code&gt;, scrollbar gutters biting into a 1024 viewport just won't trip the 1024 breakpoint yet so there's plenty of room for the smaller design still.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;and it gets so much better later because of &lt;strong&gt;Breakpoint Units&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Designer and developer wins that are such a relief, your first response may be to doubt it.
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;We use rem and its decimal fractions everywhere because it is the best solution to support our user's system font size increases for accessibility.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Just use pixels anyway.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;We're supposed to use &lt;code&gt;em&lt;/code&gt; for breakpoints for the same reason, but it's extremely rare to see it in practice.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No guilt. Keep using pixels.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Designers, devs, and project managers know the max length of our content, especially titles, and we already plan for that as a team.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Keep doing that.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Which of us is responsible for making designs not look terrible, squished, janky, cut-off, overflowing, or just broken when the user's system font size is 20px - a full 25% bigger?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pixels don't do that, so let's all just use pixels.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;We want a fluid design that scales with the view width, respects rem, is aware of the starting size, surrounding breakpoints, and ending size, and isn't a nightmare to re-calc() if designs change later.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Only the breakpoints you choose to include for designs of this specific layout/component exist as screen sizes.&lt;/p&gt;

&lt;p&gt;Like designing physical playing cards. It's finally safe to ignore all other scenarios and in-between screen sizes.&lt;/p&gt;

&lt;p&gt;So pixels are the best choice here too.&lt;/p&gt;

&lt;p&gt;Pixels. :)&lt;/p&gt;




&lt;p&gt;You never need to use rem again.&lt;/p&gt;

&lt;p&gt;Breakpoint Units take care of all of this automatically in the background and they map 1:1 with your pixels.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automatic accessibility win #2
&lt;/h3&gt;

&lt;p&gt;For over a decade authors like Zell Liew have &lt;a href="https://zellwk.com/blog/media-query-units/" rel="noopener noreferrer"&gt;written about the importance of using em in your media query breakpoints&lt;/a&gt; yet we have largely collectively avoided it. There are two main reasons for this: pixels are easier to work with, and you need to make adjustments to every breakpoint design and every block of css inside every media query to allow the intended effect without causing weird max caps in the wrong scenarios, etc. Effectively it doubles the effort to be mindful in both design and dev.&lt;/p&gt;




&lt;p&gt;Taking a step back for a moment.&lt;/p&gt;

&lt;p&gt;When we &lt;a href="https://dev.to/janeori/css-type-casting-to-numeric-tanatan2-scalars-582j"&gt;tan(atan2())&lt;/a&gt; &lt;code&gt;1rem&lt;/code&gt; into a number, and divide it by the expected &lt;code&gt;16&lt;/code&gt;, we get a scalar telling us how much the user has adjusted their system font size for accessibility.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;20 / 16 = 1.25
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We shift your pixel based breakpoints for this user by that amount.&lt;/p&gt;

&lt;p&gt;This is equivalent to what using &lt;code&gt;em&lt;/code&gt; in media query breakpoints does.&lt;/p&gt;

&lt;p&gt;HOWEVER, when combined with this pixel philosophy of my breakpoint-system and &lt;strong&gt;Breakpoint Units&lt;/strong&gt;, your user will never see text smaller than their preference, your designs won't break, they don't have to pinch-pan-zoom, nothing overflows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Breakpoint Units&lt;/strong&gt; automatically show the previous design, magnified beyond where it would have changed to a bigger design and flawlessly meets the requirement.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Their experience of your designs is exactly the same as any other user's experience, just bigger as if the website thought their tablet was a phone and scaled up to fill their screen.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Neither designers nor devs need to plan for this or make extra effort. It happens in the background automatica11y.&lt;/p&gt;

&lt;h4&gt;
  
  
  The smallest breakpoint has no smaller design to show.
&lt;/h4&gt;

&lt;p&gt;Technically this is a caveat - &lt;em&gt;but it requires no new effort&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The status quo for your smallest designs remains important:&lt;br&gt;
Nearly everything is just stacked in a single column, nothing is vertically constrained, and break word is expected. In your smallest defined breakpoint range only, our typography breakpoint units directly express the user's magnification.&lt;/p&gt;

&lt;p&gt;(Breakpoint Units never actually expand for the system font size outside of that smallest range. The math and UX just makes it seem like that's the reason they've grown to meet the requirement!)&lt;/p&gt;
&lt;h2&gt;
  
  
  Hands-on learning
&lt;/h2&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/53aab6691d362761057a73133579fc65?height=600&amp;amp;default-tab=result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  @propjockey/breakpoint-system
&lt;/h2&gt;

&lt;p&gt;You will never build a personal site or app again without using breakpoint-system as the foundation once you've experienced it. Neither will I.&lt;/p&gt;

&lt;p&gt;It has solved so many problems, some over a decade old, for so many different groups of people at once, and packaged the API so well, that any full-feature design system built in the future will either use &lt;code&gt;@propjockey/breakpoint-system&lt;/code&gt; directly as a foundation or it must ...&lt;a href="https://www.youtube.com/watch?v=ag3L1fBPo54" rel="noopener noreferrer"&gt;replicate it&lt;/a&gt; to keep up.&lt;/p&gt;

&lt;p&gt;Once your team has begun experiencing the zero friction handoffs in addition to all of the relief it delivers on the surface, you will agree with what I already know is true&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I have created the new baseline expectation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://propjockey.breakpoint-system.com" rel="noopener noreferrer"&gt;https://propjockey.breakpoint-system.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/propjockey/breakpoint-system" rel="noopener noreferrer"&gt;https://github.com/propjockey/breakpoint-system&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmjs.com/package/@propjockey/breakpoint-system" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@propjockey/breakpoint-system&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Open Contact 👽
&lt;/h2&gt;

&lt;p&gt;Please do reach out if you need help with any of this, have feature requests, or want to share what you've created!&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;small&gt;PropJockey&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;CodePen&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;DEV Blog&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;GitHub&lt;/small&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://propjockey.io" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/propjockey-lines.svg" alt="PropJockey.io"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://codepen.io/propjockey" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/codepen.svg" alt="CodePen"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/janeori"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/dev.svg" alt="DEV Blog"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/propjockey" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/github.svg" alt="GitHub"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;small&gt;Mastodon&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;LinkedIn&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;X&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;Bluesky&lt;/small&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://front-end.social/@JaneOri" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/mastodon.svg" alt="Mastodon"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.linkedin.com/in/janeori/" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/linkedin.svg" alt="LinkedIn"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://x.com/jane0ri" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/x.svg" alt="X"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bsky.app/profile/janeori.propjockey.io" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/bluesky.svg" alt="Bluesky"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  My heart is open to receive abundance in all forms,&lt;br&gt;flowing to me in many expected and unexpected ways.
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PayPal&lt;/th&gt;
&lt;th&gt;Ko-fi&lt;/th&gt;
&lt;th&gt;Venmo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.paypal.com/donate/?cmd=_s-xclick&amp;amp;hosted_button_id=9Z925L3SJJ8BS&amp;amp;source=qr&amp;amp;ssrt=1772865628068" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/paypal.svg" alt="PayPal"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://ko-fi.com/janeori" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/ko-fi.svg" alt="Ko-fi"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://account.venmo.com/u/JaneOri" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/venmo.svg" alt="Venmo"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;BTC&lt;/th&gt;
&lt;th&gt;XRP&lt;/th&gt;
&lt;th&gt;ETH&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://app.ens.domains/janeori.eth" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/btc.svg" alt="BTC bc1qe2ss8hvmskcxpmk046msrjpmy9qults2yusgn9"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bithomp.com/en/account/X7zmKiqEhMznSXgj9cirEnD5sWo3iZPqbNPChdEKV9sM9WF" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/xrp.svg" alt="XRP rw2ciyaNshpHe7bCHo4bRWq6pqqynnWKQg : 459777128"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://app.ens.domains/janeori.eth" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/eth.svg" alt="ETH 0x674D4191dEBf9793e743D21a4B8c4cf1cC3beF54"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bc1qe...usgn9&lt;/td&gt;
&lt;td&gt;rw2ci...nWKQg&lt;br&gt;: 459777128&lt;/td&gt;
&lt;td&gt;0x674...beF54&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>css</category>
      <category>design</category>
      <category>designsystem</category>
      <category>a11y</category>
    </item>
    <item>
      <title>Customizing the MacOS Terminal with help from AI</title>
      <dc:creator>Jane Ori</dc:creator>
      <pubDate>Fri, 06 Mar 2026 14:36:27 +0000</pubDate>
      <link>https://dev.to/janeori/customizing-the-macos-terminal-with-help-from-ai-3f91</link>
      <guid>https://dev.to/janeori/customizing-the-macos-terminal-with-help-from-ai-3f91</guid>
      <description>&lt;p&gt;After spending a year traveling the world, I've acquired a new Macbook Air and had to set up my terminal interface again.&lt;/p&gt;

&lt;p&gt;I do not normally enjoy this process but I loved it this time.&lt;br&gt;
A continuous conversation with AI (Gemini specifically) lead to every random idea I had becoming realized in my &lt;code&gt;.zshrc&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;There are some goodies in here I suspect you'll enjoy too.&lt;/p&gt;
&lt;h2&gt;
  
  
  Basic settings and imports
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# # # # # # # # # # # # #&lt;/span&gt;
&lt;span class="c"&gt;# import things we need #&lt;/span&gt;
&lt;span class="c"&gt;# # # # # # # # # # # # #&lt;/span&gt;

&lt;span class="c"&gt;# load 'live' hooks to execute things every call,&lt;/span&gt;
&lt;span class="c"&gt;# load TAB completion&lt;/span&gt;
autoload &lt;span class="nt"&gt;-Uz&lt;/span&gt; add-zsh-hook compinit

&lt;span class="c"&gt;# # # # # # # # # # # # #&lt;/span&gt;
&lt;span class="c"&gt;# Enable Tab Completion #&lt;/span&gt;
&lt;span class="c"&gt;# # # # # # # # # # # # #&lt;/span&gt;

&lt;span class="c"&gt;# 1. Prevent duplicate entries in paths&lt;/span&gt;
&lt;span class="nb"&gt;typeset&lt;/span&gt; &lt;span class="nt"&gt;-U&lt;/span&gt; FPATH PATH
&lt;span class="c"&gt;# 2. Add Homebrew to FPATH for even better tab completion (if it's not present already)&lt;/span&gt;
&lt;span class="nv"&gt;FPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/opt/homebrew/share/zsh/site-functions:&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;FPATH&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="c"&gt;# 3. Enable TAB completion&lt;/span&gt;
compinit

&lt;span class="c"&gt;# # # # # # # # # # # # #&lt;/span&gt;
&lt;span class="c"&gt;# Toggling Misc options #&lt;/span&gt;
&lt;span class="c"&gt;# # # # # # # # # # # # #&lt;/span&gt;

&lt;span class="c"&gt;# make ls pretty&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;CLICOLOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Basic aliases
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# make the current terminal tab aware of things just installed or changed&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;reload&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'source ~/.zshrc'&lt;/span&gt;

&lt;span class="c"&gt;# shortcut to go to my main projects folder&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;pj&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"cd ~/Desktop/PropJockey"&lt;/span&gt;

&lt;span class="c"&gt;# Launch Gemini in a frameless chrome window&lt;/span&gt;
&lt;span class="nb"&gt;alias &lt;/span&gt;&lt;span class="nv"&gt;gemini&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/Applications/Google&lt;/span&gt;&lt;span class="se"&gt;\ &lt;/span&gt;&lt;span class="s2"&gt;Chrome.app/Contents/MacOS/Google&lt;/span&gt;&lt;span class="se"&gt;\ &lt;/span&gt;&lt;span class="s2"&gt;Chrome --app=https://gemini.google.com/app"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Whenever you modify the .zshrc file, which I did about a hundred times during this, you either have to open a new tab or run the command I've aliased with a simple "reload".&lt;/p&gt;

&lt;p&gt;I wound up installing Gemini using Chrome's built in "Install as App" feature which had the added benefit of getting Gemini in my dock. 🤙 Sweet.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa0gaxoryrpyff60bj3qx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa0gaxoryrpyff60bj3qx.png" alt="Chrome menu → " width="800" height="1253"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Lock Function
&lt;/h2&gt;

&lt;p&gt;One of the first things I do when setting up a mac is turn sleep into hibernate. When I close the lid, I'm done for the night, no reason to sleep.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo pmset -a hibernatemode 25&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately, no matter how you've configured your lock screen settings, after only a minute idle on the lock screen, the mac gets bored and falls asleep, which in my case hibernates it and I have to sit through memory reloading from the harddrive to log back in.&lt;/p&gt;

&lt;p&gt;The fix:&lt;/p&gt;

&lt;p&gt;First create a shortcut using the Shortcuts app that ships with mac. It's &lt;em&gt;great&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Add a new shortcut, search for the lock screen action, add it, name it "LockMac", and you're ready for the script&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsvm4jk0mj35b4mjb4rqc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsvm4jk0mj35b4mjb4rqc.png" alt="Shortcuts app screenshot of the lock mac shortcut" width="800" height="338"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Lock the screen without sleeping the system and keep it awake until ctrl + c to quit&lt;/span&gt;
&lt;span class="c"&gt;# alias lock='shortcuts run "LockMac" &amp;amp;&amp;amp; caffeinate -i -d -t 3600'&lt;/span&gt;
&lt;span class="c"&gt;# ^ great but this is better because I don't have to ctrl + c!&lt;/span&gt;
lock&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;# Start caffeinate in the background, disown it, hide its output, and save its Process ID (PID)&lt;/span&gt;
  caffeinate &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; 3600 &amp;amp;&amp;gt;/dev/null &amp;amp;!
  &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;caff_pid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$!&lt;/span&gt;

  shortcuts run &lt;span class="s2"&gt;"LockMac"&lt;/span&gt;

  &lt;span class="c"&gt;# Give macOS a bit to register the locked state&lt;/span&gt;
  &lt;span class="nb"&gt;sleep &lt;/span&gt;3

  &lt;span class="c"&gt;# The Magic Loop: Poll the Mac's hardware registry. &lt;/span&gt;
  &lt;span class="c"&gt;# This specific string ONLY exists while the screen is actively locked.&lt;/span&gt;
  &lt;span class="k"&gt;while &lt;/span&gt;ioreg &lt;span class="nt"&gt;-n&lt;/span&gt; Root &lt;span class="nt"&gt;-d1&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"CGSSessionScreenIsLocked"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nb"&gt;sleep &lt;/span&gt;2
  &lt;span class="k"&gt;done&lt;/span&gt;

  &lt;span class="c"&gt;# You're back! Kill the caffeinate process silently&lt;/span&gt;
  &lt;span class="nb"&gt;kill&lt;/span&gt; &lt;span class="nv"&gt;$caff_pid&lt;/span&gt; 2&amp;gt;/dev/null

  &lt;span class="c"&gt;# Print a Bifrost-styled welcome back message&lt;/span&gt;
  &lt;span class="c"&gt;# print -P "%F{cyan}🛸 Welcome back. Sleep prevention disabled.%f"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I always have at least one terminal open so I just type &lt;code&gt;lock&lt;/code&gt; and I'm off to the bathroom in my hostel. The mac stays wide awake the whole time so I can simply type my password and continue.&lt;/p&gt;

&lt;p&gt;I use this &lt;em&gt;often&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhdgmkey7xska9rzrrsp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhdgmkey7xska9rzrrsp.png" alt="screenshot of a terminal tab with the lock command ran many times" width="800" height="583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Automatic Node &amp;amp; NPM version mismatch warning
&lt;/h2&gt;

&lt;p&gt;One of the things any seasoned node developer has done time and time again is accidentally run their project with the wrong version, or worse, installed packages.&lt;/p&gt;

&lt;p&gt;I wanted to prevent that as best as I could so I requested a function that alerts the node version and the version specified in &lt;code&gt;.nvmrc&lt;/code&gt; or &lt;code&gt;package.json&lt;/code&gt; with pass/fail indicators based on a comparison of the values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Checks current versions against .nvmrc or package.json requirements&lt;/span&gt;
nvi&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;# 1. Ensure Node is actually installed&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; node &amp;amp;&amp;gt; /dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;print &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="s2"&gt;"%F{red}✘ Node.js is not installed or not in PATH.%f"&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;1
  &lt;span class="k"&gt;fi

  &lt;/span&gt;&lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;current_node&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;node &lt;span class="nt"&gt;-v&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;current_npm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;npm &lt;span class="nt"&gt;-v&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;req_node&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;req_npm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;

  &lt;span class="c"&gt;# 2. Look for project requirements (.nvmrc takes priority for node)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;".nvmrc"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;req_node&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; .nvmrc | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'\n'&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'\r'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;fi&lt;/span&gt;

  &lt;span class="c"&gt;# Fallback to package.json engines if it exists&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"package.json"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$req_node&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
      &lt;span class="c"&gt;# Safely extract engines.node using Node itself&lt;/span&gt;
      &lt;span class="nv"&gt;req_node&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;node &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"try { console.log(require('./package.json').engines.node || '') } catch(e) {}"&lt;/span&gt; 2&amp;gt;/dev/null&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;fi&lt;/span&gt;
    &lt;span class="c"&gt;# Extract engines.npm&lt;/span&gt;
    &lt;span class="nv"&gt;req_npm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;node &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"try { console.log(require('./package.json').engines.npm || '') } catch(e) {}"&lt;/span&gt; 2&amp;gt;/dev/null&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;fi&lt;/span&gt;

  &lt;span class="c"&gt;# 3. Print Current Versions&lt;/span&gt;
  print &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="s2"&gt;"%F{magenta}Current Node:%f %F{cyan}&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;current_node&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%f"&lt;/span&gt;
  print &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="s2"&gt;"%F{magenta}Current NPM:%f  %F{cyan}v&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;current_npm&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%f"&lt;/span&gt;

  &lt;span class="c"&gt;# 4. Evaluate and Print Requirements (if they exist)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$req_node&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$req_npm&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
    print &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="s2"&gt;"%F{242}Project Requirements:%f"&lt;/span&gt;

    &lt;span class="c"&gt;# Node Requirement Check&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$req_node&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
      &lt;span class="c"&gt;# Extract just the major version number for a reliable comparison&lt;/span&gt;
      &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;clean_current&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$current_node&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oE&lt;/span&gt; &lt;span class="s1"&gt;'[0-9]+'&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
      &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;clean_req&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$req_node&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oE&lt;/span&gt; &lt;span class="s1"&gt;'[0-9]+'&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$clean_current&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$clean_req&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$current_node&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$req_node&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;print &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="s2"&gt;"%F{green}✔ Node:%f &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;req_node&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
      &lt;span class="k"&gt;else
        &lt;/span&gt;print &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="s2"&gt;"%F{red}✘ Node:%f &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;req_node&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (Mismatch detected)"&lt;/span&gt;
      &lt;span class="k"&gt;fi
    fi&lt;/span&gt;

    &lt;span class="c"&gt;# NPM Requirement Check&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$req_npm&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
      &lt;/span&gt;&lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;clean_current_npm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$current_npm&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oE&lt;/span&gt; &lt;span class="s1"&gt;'[0-9]+'&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
      &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;clean_req_npm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$req_npm&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oE&lt;/span&gt; &lt;span class="s1"&gt;'[0-9]+'&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$clean_current_npm&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$clean_req_npm&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$current_npm&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$req_npm&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;print &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="s2"&gt;"%F{green}✔ NPM:%f  &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;req_npm&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
      &lt;span class="k"&gt;else
        &lt;/span&gt;print &lt;span class="nt"&gt;-P&lt;/span&gt; &lt;span class="s2"&gt;"%F{red}✘ NPM:%f  &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;req_npm&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (Mismatch detected)"&lt;/span&gt;
      &lt;span class="k"&gt;fi
    fi
  fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just run &lt;code&gt;nvi&lt;/code&gt; (Node Version Information) and we're golden...&lt;/p&gt;

&lt;p&gt;...but we could be platinum if we called this &lt;strong&gt;automatically&lt;/strong&gt; when you change directory into one with node expected!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# # # # # # # # # # # # #&lt;/span&gt;
&lt;span class="c"&gt;# Run nvi automatically #&lt;/span&gt;
&lt;span class="c"&gt;# # # # # # # # # # # # #&lt;/span&gt;

auto_check_node_env&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;# Check if we are in a folder with Node files&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"package.json"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;".nvmrc"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="c"&gt;# Add a blank line for visual breathing room&lt;/span&gt;
    nvi
  &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;# Attach it to the 'Change Directory' hook&lt;/span&gt;
add-zsh-hook chpwd auto_check_node_env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🤌 Great success.&lt;/p&gt;

&lt;p&gt;Now every time I cd into the root of one of my node projects, it runs this command so I'll be shown without needing to remember to check. I stopped short of letting it &lt;code&gt;nvm&lt;/code&gt; into the "right" version automatically hah&lt;/p&gt;

&lt;h2&gt;
  
  
  The Beautifully Colorful Path Highlighting and Git Info
&lt;/h2&gt;

&lt;p&gt;First, I installed this color theme called Bifrost:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/lysyi3m/macos-terminal-themes?tab=readme-ov-file#bifrost-download" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9a7zg6xyxqg6ruffq8zf.png" alt="A terminal color theme pallet display with corresponding color codes" width="640" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, for the current directory path, I wanted to grey out the roots of the path, highlight the project name by detecting if it's in a git repository, then highlight everything after the project name in a different color.&lt;/p&gt;

&lt;p&gt;The end result is the most significant parts being easy to distinguish and effortlessly identified at a glance. I. Love. It.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F42dqg1axfaofi6wl8qfe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F42dqg1axfaofi6wl8qfe.png" alt="Screenshot of my terminal showing the current path dissected into colors" width="800" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There's all kinds of other stuff in here like basic git status indicators, the branch, separate counts of staged and unstaged files, etc.&lt;/p&gt;

&lt;p&gt;The first part of the prompt is something that is slightly redundant indicating complete vs a failed reason, followed by a completion timestamp of the previous command AND the number of seconds the previous command took (if it was more than one).&lt;/p&gt;

&lt;p&gt;A couple line breaks after that and the typical PROMPT shows up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# # # # # # # # # # # # #&lt;/span&gt;
&lt;span class="c"&gt;# Meta info of last cmd #&lt;/span&gt;
&lt;span class="c"&gt;# # # # # # # # # # # # #&lt;/span&gt;

&lt;span class="c"&gt;# 1. Capture the start time of a command&lt;/span&gt;
preexec&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;timer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;timer&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;$SECONDS&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;# 2. Calculate the difference and format it&lt;/span&gt;
calculate_timer&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$timer&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nv"&gt;timer_show&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;&lt;span class="nv"&gt;$SECONDS&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;$timer&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nv"&gt;$timer_show&lt;/span&gt; &lt;span class="nt"&gt;-ge&lt;/span&gt; 1 &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ELAPSED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%F{yellow}&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;timer_show&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;s %f"&lt;/span&gt;
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ELAPSED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
    &lt;span class="k"&gt;fi
    &lt;/span&gt;&lt;span class="nb"&gt;unset &lt;/span&gt;timer
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="c"&gt;# THE FIX: If no command was run, clear the old time!&lt;/span&gt;
    &lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ELAPSED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
  &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
add-zsh-hook precmd calculate_timer


&lt;span class="c"&gt;# # # # # # # # # # # # #&lt;/span&gt;
&lt;span class="c"&gt;# Best git aware prompt #&lt;/span&gt;
&lt;span class="c"&gt;# # # # # # # # # # # # #&lt;/span&gt;

&lt;span class="c"&gt;# look inside the variables every time the PROMPT is printed&lt;/span&gt;
setopt PROMPT_SUBST

&lt;span class="c"&gt;# Fetch the Mac Display Name&lt;/span&gt;
&lt;span class="nv"&gt;DISPLAY_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Define the raw escape codes for Dim and Reset&lt;/span&gt;
&lt;span class="nv"&gt;DIM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\e&lt;/span&gt;&lt;span class="s1"&gt;[2m'&lt;/span&gt;
&lt;span class="nv"&gt;RESET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\e&lt;/span&gt;&lt;span class="s1"&gt;[22m'&lt;/span&gt;
&lt;span class="c"&gt;# %{${DIM}%}%F{yellow}%~%f%{${RESET}%}&lt;/span&gt;

set_surgical_path&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;exit_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$?&lt;/span&gt; &lt;span class="c"&gt;# capture exit code of previous command&lt;/span&gt;

  &lt;span class="nb"&gt;local &lt;/span&gt;repo_root
  &lt;span class="c"&gt;# Get the absolute path to the repo root&lt;/span&gt;
  &lt;span class="nv"&gt;repo_root&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git rev-parse &lt;span class="nt"&gt;--show-toplevel&lt;/span&gt; 2&amp;gt;/dev/null&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;GIT_INFO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="c"&gt;# Start with a blank slate&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$repo_root&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;full_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;# 1. Everything BEFORE the repo root&lt;/span&gt;
    &lt;span class="c"&gt;# We take the directory of the repo_root (its parent)&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;parent_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;dirname&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$repo_root&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;parent_dir&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt;
    &lt;span class="nv"&gt;prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;/#&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="p"&gt;/~&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="c"&gt;# Clean up Home path&lt;/span&gt;

    &lt;span class="c"&gt;# 2. The Repo folder itself&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;repo_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;basename&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$repo_root&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;# 3. Everything AFTER the repo root&lt;/span&gt;
    &lt;span class="c"&gt;# We remove the repo_root path from the full_path&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;suffix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;full_path&lt;/span&gt;&lt;span class="p"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;$repo_root&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="c"&gt;# Assemble: Dim Prefix + Bright Repo + Dim Suffix&lt;/span&gt;
    &lt;span class="nv"&gt;DYNAMIC_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%{&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DIM&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%}%F{white}&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;prefix&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%f%{&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RESET&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%}"&lt;/span&gt;
    DYNAMIC_PATH+&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%F{magenta}&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;repo_name&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%f"&lt;/span&gt;
    DYNAMIC_PATH+&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%F{blue}&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;suffix&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%f"&lt;/span&gt;
    &lt;span class="c"&gt;# Get the branch name, fallback to short hash if in detached HEAD&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;git_branch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git branch &lt;span class="nt"&gt;--show-current&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; git rev-parse &lt;span class="nt"&gt;--short&lt;/span&gt; HEAD 2&amp;gt;/dev/null&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;# Check for Action States (Merging / Rebasing)&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;git_action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$repo_root&lt;/span&gt;&lt;span class="s2"&gt;/.git/MERGE_HEAD"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
      &lt;/span&gt;&lt;span class="nv"&gt;git_action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%F{yellow}(merge)%f "&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$repo_root&lt;/span&gt;&lt;span class="s2"&gt;/.git/rebase-merge"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$repo_root&lt;/span&gt;&lt;span class="s2"&gt;/.git/rebase-apply"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
      &lt;/span&gt;&lt;span class="nv"&gt;git_action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%F{yellow}(rebase)%f "&lt;/span&gt;
    &lt;span class="k"&gt;fi&lt;/span&gt;

    &lt;span class="c"&gt;# Check Clean/Dirty Status&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;git_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;git_status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git status &lt;span class="nt"&gt;--porcelain&lt;/span&gt; 2&amp;gt;/dev/null&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$git_status&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
      &lt;/span&gt;&lt;span class="nv"&gt;git_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%F{green}✔%f"&lt;/span&gt; &lt;span class="c"&gt;# Perfectly clean&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="c"&gt;# Check for staged changes (+) and unstaged/untracked files (*)# Count lines matching staged (column 1) and unstaged/untracked (column 2)&lt;/span&gt;
      &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;staged_count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$git_status&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'^[AMRCD]'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
      &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;unstaged_count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$git_status&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'^.[MD?]'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

      &lt;span class="c"&gt;# If there are staged files, add the yellow count&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$staged_count&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 0 &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;git_state+&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%F{yellow}+&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;staged_count&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%f"&lt;/span&gt;
      &lt;span class="k"&gt;fi&lt;/span&gt;

      &lt;span class="c"&gt;# If there are unstaged/untracked files, add the red count&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$unstaged_count&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; 0 &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="c"&gt;# Add a space for readability if we also have staged files (e.g., +2 *3)&lt;/span&gt;
        &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$git_state&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git_state+&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;" "&lt;/span&gt;
        git_state+&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%F{red}*&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;unstaged_count&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%f"&lt;/span&gt;
      &lt;span class="k"&gt;fi
    fi&lt;/span&gt;

    &lt;span class="c"&gt;# Assemble the final Git string&lt;/span&gt;
    &lt;span class="nv"&gt;GIT_INFO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;" on %F{cyan}&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;git_branch&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%f &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;git_action&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;git_state&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="c"&gt;# Not in a repo: Show the whole path dimmed&lt;/span&gt;
    &lt;span class="nv"&gt;DYNAMIC_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%{&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DIM&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%}%F{magenta}%~%f%{&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RESET&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%}"&lt;/span&gt;
  &lt;span class="k"&gt;fi&lt;/span&gt;

  &lt;span class="c"&gt;# Define the Prompt&lt;/span&gt;
  &lt;span class="c"&gt;# %D{%H:%M:%S} = Hour:Minute:Second&lt;/span&gt;
  &lt;span class="c"&gt;# %n = username&lt;/span&gt;
  &lt;span class="c"&gt;# %~ = current directory (shortened)&lt;/span&gt;
  &lt;span class="c"&gt;# %# = % for users, # for root (I replaced this with: %(!.#.$))&lt;/span&gt;
  &lt;span class="c"&gt;# %(!.#.$) = # for root, $ for users&lt;/span&gt;
  &lt;span class="c"&gt;# The %(?.X.Y) syntax means: If last exit code was 0, show X, else show Y ## %(?.%F{green}Completed.%F{red}Stopped)%f&lt;/span&gt;

  &lt;span class="nb"&gt;local nl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt; &lt;span class="c"&gt;# ${nl}&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;status_line&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nv"&gt;$HISTCMD&lt;/span&gt; &lt;span class="nt"&gt;-ne&lt;/span&gt; &lt;span class="nv"&gt;$LAST_HISTCMD&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;status_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;

    &lt;span class="c"&gt;# 2. The Exit Code Skyscraper&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nv"&gt;$exit_code&lt;/span&gt; &lt;span class="k"&gt;in
      &lt;/span&gt;0&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;status_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%F{green}Completed"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;

      &lt;span class="c"&gt;# The "Oh, I meant to do that" code&lt;/span&gt;
      130&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;status_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%F{yellow}Stopped"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt; &lt;span class="c"&gt;# SIGINT (Ctrl+C)&lt;/span&gt;

      &lt;span class="c"&gt;# The "Wait, what just happened?" codes&lt;/span&gt;
      126&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;status_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%F{magenta}Denied (126)"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt; &lt;span class="c"&gt;# Permission denied / Not executable&lt;/span&gt;
      127&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;status_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%F{magenta}Not Found (127)"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt; &lt;span class="c"&gt;# Typo in command name&lt;/span&gt;

      &lt;span class="c"&gt;# The "Violent Crash" codes&lt;/span&gt;
      137&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;status_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%F{red}Killed / Out of Memory (137)"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt; &lt;span class="c"&gt;# SIGKILL (Often the Out-Of-Memory killer)&lt;/span&gt;
      139&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;status_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%F{red}Segfault (139)"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt; &lt;span class="c"&gt;# SIGSEGV (Memory access violation)&lt;/span&gt;
      143&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;status_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%F{yellow}Terminated (143)"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt; &lt;span class="c"&gt;# SIGTERM (Graceful kill command)&lt;/span&gt;

      &lt;span class="c"&gt;# The Catch-All for standard script errors&lt;/span&gt;
      &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;status_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%F{red}Exit code: &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;exit_code&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    &lt;span class="k"&gt;esac&lt;/span&gt;

    &lt;span class="nv"&gt;status_line&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;nl&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%{&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DIM&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%}&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;status_text&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%f%{&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RESET&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%} %F{242}at %D{%H:%M:%S}%f &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ELAPSED&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;nl&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;nl&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;fi
  &lt;/span&gt;&lt;span class="nv"&gt;LAST_HISTCMD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$HISTCMD&lt;/span&gt;

  &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;name_path_git&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"%F{magenta}&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DISPLAY_NAME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%f in &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DYNAMIC_PATH&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;GIT_INFO&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;input_indicator&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;nl&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%{&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;DIM&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%}%F{yellow}%(!.#.&lt;/span&gt;&lt;span class="nv"&gt;$)&lt;/span&gt;&lt;span class="s2"&gt;%f%{&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RESET&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;%}"&lt;/span&gt;

  &lt;span class="nv"&gt;PROMPT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;status_line&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;name_path_git&lt;/span&gt;&lt;span class="k"&gt;}${&lt;/span&gt;&lt;span class="nv"&gt;input_indicator&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; "&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# 4. Tell the surgical path function to run before every prompt&lt;/span&gt;
add-zsh-hook precmd set_surgical_path
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The final touch
&lt;/h2&gt;

&lt;p&gt;Place a little 👽 Extra Terrestrial emoji in right prompt so I can scroll up the wall of text and find my inputs a little more easily.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# # # # # # # # # # # # #&lt;/span&gt;
&lt;span class="c"&gt;# A little splash of me #&lt;/span&gt;
&lt;span class="c"&gt;# # # # # # # # # # # # #&lt;/span&gt;

&lt;span class="nv"&gt;RPROMPT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'👽'&lt;/span&gt;


&lt;span class="c"&gt;# # # # # # # # # # # # #&lt;/span&gt;
&lt;span class="c"&gt;# This was a triumph. ♫ #&lt;/span&gt;
&lt;span class="c"&gt;# # # # # # # # # # # # #&lt;/span&gt;

&lt;span class="c"&gt;# I'm making a note here: Huge success.&lt;/span&gt;


&lt;span class="c"&gt;# # # # # # # # # # # # #&lt;/span&gt;
&lt;span class="c"&gt;# Things added by tools #&lt;/span&gt;
&lt;span class="c"&gt;# # # # # # # # # # # # #&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;NVM_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.nvm"&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NVM_DIR&lt;/span&gt;&lt;span class="s2"&gt;/nvm.sh"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\.&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NVM_DIR&lt;/span&gt;&lt;span class="s2"&gt;/nvm.sh"&lt;/span&gt;  &lt;span class="c"&gt;# This loads nvm&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NVM_DIR&lt;/span&gt;&lt;span class="s2"&gt;/bash_completion"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\.&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NVM_DIR&lt;/span&gt;&lt;span class="s2"&gt;/bash_completion"&lt;/span&gt;  &lt;span class="c"&gt;# This loads nvm bash_completion&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Open Contact 👽
&lt;/h2&gt;

&lt;p&gt;Please do reach out if you need help with any of this, have feature requests, or want to share what you've created!&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;small&gt;PropJockey&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;CodePen&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;DEV Blog&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;GitHub&lt;/small&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://propjockey.io" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/propjockey-lines.svg" alt="PropJockey.io"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://codepen.io/propjockey" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/codepen.svg" alt="CodePen"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/janeori"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/dev.svg" alt="DEV Blog"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/propjockey" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/github.svg" alt="GitHub"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;small&gt;Mastodon&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;LinkedIn&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;X&lt;/small&gt;&lt;/th&gt;
&lt;th&gt;&lt;small&gt;Bluesky&lt;/small&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://front-end.social/@JaneOri" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/mastodon.svg" alt="Mastodon"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.linkedin.com/in/janeori/" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/linkedin.svg" alt="LinkedIn"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://x.com/jane0ri" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/x.svg" alt="X"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bsky.app/profile/janeori.propjockey.io" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/external-social/100px/bluesky.svg" alt="Bluesky"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  My heart is open to receive abundance in all forms, flowing to me in many expected and unexpected ways.
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PayPal&lt;/th&gt;
&lt;th&gt;Ko-Fi&lt;/th&gt;
&lt;th&gt;Venmo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.paypal.com/donate/?cmd=_s-xclick&amp;amp;hosted_button_id=9Z925L3SJJ8BS&amp;amp;source=qr&amp;amp;ssrt=1772865628068" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/paypal.svg" alt="PayPal"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://ko-fi.com/janeori" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/ko-fi.svg" alt="Ko-fi"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://account.venmo.com/u/JaneOri" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/venmo.svg" alt="Venmo"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;BTC&lt;/th&gt;
&lt;th&gt;XRP&lt;/th&gt;
&lt;th&gt;ETH&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://app.ens.domains/janeori.eth" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/btc.svg" alt="BTC bc1qe2ss8hvmskcxpmk046msrjpmy9qults2yusgn9"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/xrp.svg" alt="XRP rw2ciyaNshpHe7bCHo4bRWq6pqqynnWKQg : 459777128"&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://app.ens.domains/janeori.eth" rel="noopener noreferrer"&gt;&lt;img src="//raw.githubusercontent.com/propjockey/propjockey-brand/main/QR-Codes/svg/200px/eth.svg" alt="ETH 0x674D4191dEBf9793e743D21a4B8c4cf1cC3beF54"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bc1qe...usgn9&lt;/td&gt;
&lt;td&gt;rw2ci...nWKQg&lt;br&gt;: 459777128&lt;/td&gt;
&lt;td&gt;0x674...beF54&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>cli</category>
      <category>zshrc</category>
      <category>shell</category>
    </item>
    <item>
      <title>100% CSS: Fetch and Exfiltrate 512 bits of Server-Generated Data Embedded in an Animated SVG</title>
      <dc:creator>Jane Ori</dc:creator>
      <pubDate>Fri, 17 Jan 2025 21:41:08 +0000</pubDate>
      <link>https://dev.to/janeori/100-css-fetch-and-exfiltrate-512-bits-of-server-generated-data-embedded-in-an-animated-svg-5aad</link>
      <guid>https://dev.to/janeori/100-css-fetch-and-exfiltrate-512-bits-of-server-generated-data-embedded-in-an-animated-svg-5aad</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This is a direct followup to to &lt;a href="https://dev.to/janeori/getting-your-ip-address-with-css-and-other-32-bit-api-responses-without-javascript-402h"&gt;Getting 32 bit API Response Data in CSS&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In CSS, &lt;code&gt;16 bits&lt;/code&gt; of response data, placed both in the intrinsic width and in the intrinsic height, was a huge improvement from not being able to get API response data at all (without JavaScript)...&lt;/p&gt;

&lt;p&gt;However, in the days after I figured it out, my mind leaned in one direction:&lt;br&gt;
&lt;strong&gt;It would be way more fun if it was &lt;code&gt;16 bits&lt;/code&gt; &lt;em&gt;32 times&lt;/em&gt; instead of just twice.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feogate0l0up6img1r2ze.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feogate0l0up6img1r2ze.gif" alt="Gif recording of a harsh terminal app setting several integer values to an array of variables one at a time" width="726" height="341"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Packing 512 bits into an SVG for Exfiltration
&lt;/h2&gt;

&lt;p&gt;I was meditating before bed and got struck with another inspired thought -&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What if it was possible for the image document &lt;em&gt;itself&lt;/em&gt; to animate its &lt;em&gt;own&lt;/em&gt; intrinsic size?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The usual chain of realizations after an inspired thought each flashed with understanding on how it could be accomplished... I just needed to figure out if such an image type existed.&lt;/p&gt;

&lt;p&gt;I grabbed my phone and and searched across all the animated image formats I knew of, seeing if any of them were capable of it. &lt;strong&gt;svg&lt;/strong&gt;, &lt;strong&gt;webp&lt;/strong&gt;, &lt;strong&gt;apng&lt;/strong&gt;, &lt;strong&gt;gif&lt;/strong&gt;, &lt;em&gt;maybe weird video formats&lt;/em&gt;? I couldn't find any.&lt;/p&gt;

&lt;p&gt;In the morning, something in me said to &lt;em&gt;keep digging at SVG&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I tried embedded CSS, &lt;a href="https://www.sitepoint.com/using-svg-with-media-queries/" rel="noopener noreferrer"&gt;media queries&lt;/a&gt;, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs#example" rel="noopener noreferrer"&gt;use'd defs&lt;/a&gt;, more &lt;a href="https://css-tricks.com/guide-svg-animations-smil/#specifying-the-target-of-the-animation-with-xlinkhref" rel="noopener noreferrer"&gt;use'd defs&lt;/a&gt;, diving into the numerous &lt;a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Element/animate" rel="noopener noreferrer"&gt;SVG animate docs&lt;/a&gt;, &lt;a href="https://stackoverflow.com/questions/78736461/is-it-possible-to-disable-svgs-animate-element-for-prefers-reduced-motion-media#:~:text=Disable%20animations%20via" rel="noopener noreferrer"&gt;trying to trick them&lt;/a&gt;, and read up on &lt;a href="https://github.com/w3c/fxtf-drafts/issues/7" rel="noopener noreferrer"&gt;other ideas&lt;/a&gt; and animation related properties - nothing could let me set height or width.&lt;/p&gt;

&lt;p&gt;But that last link made me think...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;...what about &lt;code&gt;viewBox&lt;/code&gt;? I'd have some other hurdles to tackle but... Is &lt;em&gt;that&lt;/em&gt; possible to animate?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;vvv&lt;br&gt;
&lt;a href="https://stackoverflow.com/a/33821641" rel="noopener noreferrer"&gt;IT IS!!&lt;/a&gt;&lt;br&gt;
^^^&lt;/p&gt;
&lt;h3&gt;
  
  
  Sorting out the solution space
&lt;/h3&gt;

&lt;p&gt;Now the problem is, if you don't set &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; attributes on the root &lt;code&gt;svg&lt;/code&gt; element then try to use the svg as &lt;code&gt;content&lt;/code&gt; on a &lt;code&gt;pseudo&lt;/code&gt;, it renders &lt;code&gt;0px&lt;/code&gt; x &lt;code&gt;0px&lt;/code&gt; because it's a vector document and no longer has an &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Intrinsic_Size" rel="noopener noreferrer"&gt;intrinsic size&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So I searched and added &lt;a href="https://unmatchedstyle.com/news/svg-and-the-preserveaspectratio-property.php#:~:text=preserveAspectRatio-,Example%205,-is%20an%20interactive" rel="noopener noreferrer"&gt;preserveAspectRatio&lt;/a&gt; to it... Still &lt;code&gt;0x0&lt;/code&gt;... but then in my CSS, I pinned the width to &lt;code&gt;10px&lt;/code&gt; and let the preserved aspect ratio of the &lt;code&gt;viewBox&lt;/code&gt; determine the height (which I can change with an animation embedded in the SVG) aaand... the html element containing it grew to the expected height.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;:3&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If there was only one frame, this took my original 32 bits and cut it in half; since only one dimension can be exfiltrated while the other is static.&lt;/p&gt;

&lt;p&gt;BUT! Now, my 2nd dimension was &lt;strong&gt;time&lt;/strong&gt; and the first is at the mercy of time, so there's more than enough data to be had.&lt;/p&gt;

&lt;p&gt;How exciting!&lt;/p&gt;

&lt;p&gt;I learned all I could about how to &lt;a href="https://oak.is/thinking/animated-svgs/" rel="noopener noreferrer"&gt;control the animation in SVGs&lt;/a&gt; and whipped up a server side script to generate my first animated SVG:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
  &lt;span class="nb"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Content-type: image/svg+xml'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nv"&gt;$data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;450&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;175&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nv"&gt;$datalen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nv"&gt;$viewBoxXYWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'0 0 10 '&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nv"&gt;$frames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$viewBoxXYWidth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$viewBoxXYWidth&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$val&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$datalen&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="nv"&gt;$dur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$datalen&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.33&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// total seconds&lt;/span&gt;

  &lt;span class="nv"&gt;$keytimeStep&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$datalen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// uniform portion per frame&lt;/span&gt;

  &lt;span class="nv"&gt;$keytimes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;implode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"; "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;array_map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$keytimeStep&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$index&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nv"&gt;$keytimeStep&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$datalen&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;

  &lt;span class="nv"&gt;$values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;implode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"; "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$frames&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

  &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg"&amp;gt;
    &amp;lt;animate
      attributeName="viewBox"
      dur="'&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$dur&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'s"
      fill="freeze"
      begin="0.1s;"
      values="'&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$values&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'" 
      keytimes="'&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$keytimes&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'"
      repeatCount="indefinite"
      calcMode="discrete"
    /&amp;gt;
  &amp;lt;/svg&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;(why php?! - because I already had a server I've been paying for for years, set up to run php out the gate.... And even though I've earned a wonderful living knowing JavaScript and node really well, sometimes &lt;em&gt;it's fun&lt;/em&gt; to look up every single function, operator, and syntax to progress through something you know you &lt;em&gt;can&lt;/em&gt; do without knowing specifics. lol)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now let's fork my first CodePen from the &lt;a href="https://dev.to/janeori/getting-your-ip-address-with-css-and-other-32-bit-api-responses-without-javascript-402h"&gt;previous article&lt;/a&gt; to see CSS responding to and changing size --vars as the SVG ticks along:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/9e6d471ea957785ac3d2157bd7a52549?height=600&amp;amp;default-tab=css,result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Confirmed! We &lt;em&gt;can&lt;/em&gt; read the size change. Like in the previous article, in the end, it'll be using the &lt;code&gt;view-timeline&lt;/code&gt; measurement technique instead this &lt;a href="https://dev.to/janeori/css-type-casting-to-numeric-tanatan2-scalars-582j"&gt;tan(atan2())&lt;/a&gt; technique.&lt;/p&gt;

&lt;p&gt;It cooks my cpu so we'll want to remove it from &lt;code&gt;content&lt;/code&gt; when the exfiltration completes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conceptually, how to procedurally exfiltrate 1D + time
&lt;/h3&gt;

&lt;p&gt;The demo above isn't very useful on its own. It reports a copy of the height whenever it's there but we need to save it... and what good is a bunch of 16 bit values if you don't know and can't trust the order?&lt;/p&gt;

&lt;p&gt;I know I can accumulate values in CSS with &lt;a href="https://dev.to/janeori/expert-css-the-cpu-hack-4ddj"&gt;the CPU Hack&lt;/a&gt; and mathematically determine which --var gets incoming values updated instead of just holding its previous value, so I won't worry about CSS specifically. How, in general, could we exfiltrate 1D over time?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Sentinel_value" rel="noopener noreferrer"&gt;Sentinel values&lt;/a&gt; to the rescue!&lt;/p&gt;

&lt;p&gt;The size of the measuring area we use doesn't HAVE to be limited to 16 bits even if I want to limit the data packets themselves to 16 bits. So we can pack some sentinels in there too. &lt;a href="https://www.npmjs.com/package/css-api-fetch" rel="noopener noreferrer"&gt;css-api-fetch&lt;/a&gt; ships with the ability to handle values up to &lt;code&gt;99999&lt;/code&gt;, which is well above &lt;code&gt;65535&lt;/code&gt; (the 16 bit ceiling).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So what do we need to know?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What problems might we run into?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If &lt;strong&gt;two values in our data are the same back-to-back&lt;/strong&gt;, we need an interruption to know it's two distinct packets. I already decided we'll be aiming for 512 bits, so we need the SVG's animation to have a maximum of 32 16-bit data frames, with sentinel frames in between...&lt;/p&gt;

&lt;p&gt;If the CPU is feeling heavy, &lt;strong&gt;the SVG animation may appear to skip discrete steps entirely&lt;/strong&gt;. That means we need some way of always knowing what step we're on. So rather than a single "between data frames" sentinel, let's use the data index (1 based like CSS nth-* selectors) as the sentinel value, making it its own discrete step before the discrete step showing the data for that index.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Sentinel index -&amp;gt; data -&amp;gt; sentinel index -&amp;gt; data ...&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That lets us know when it loops too, potentially when we hit sentinel &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But how do we know that it didn't skip to a different data frame and &lt;strong&gt;accidentally have us record it in the wrong slot&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;We need to let it loop and &lt;em&gt;keep going until it's right&lt;/em&gt;, and the best way to know if data is correct is &lt;a href="https://en.wikipedia.org/wiki/Checksum" rel="noopener noreferrer"&gt;a checksum&lt;/a&gt;! So we need another data frame, and a sentinel for that value.&lt;/p&gt;

&lt;h4&gt;
  
  
  Creating the Checksum Algorithm
&lt;/h4&gt;

&lt;p&gt;I could use &lt;a href="https://propjockey.github.io/css-bin-bits/#logic-docs" rel="noopener noreferrer"&gt;&lt;code&gt;css-bin-bits&lt;/code&gt; to XOR&lt;/a&gt; all the data, but it's quite heavy and isn't needed anywhere else - let's settle on an alternative that's simple to do in CSS.&lt;/p&gt;

&lt;p&gt;Mathematically, if you take a 16 bit value, divide it by 256 (floor to integer), and take the 16 bit value again modulo by 256, you get the high and low bytes. Add those 8 bit values together and you're at 9 bits. This feels like a reasonable checksum approach, let's circle back to this though.&lt;/p&gt;

&lt;p&gt;We don't have to stay in 16 bit range to &lt;em&gt;compute&lt;/em&gt; the checksum as long as the &lt;em&gt;final checksum is 16 bits&lt;/em&gt;, so let's just sum all (up-to) 32 values.&lt;/p&gt;

&lt;p&gt;We've got to be careful about incorrect storage writes due to skipped frames though, so let's add the even index values &lt;em&gt;twice&lt;/em&gt; so there's &lt;em&gt;some semblance of order&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That sum, &lt;code&gt;16 bit values&lt;/code&gt;, &lt;code&gt;32 times&lt;/code&gt;, plus an additional &lt;code&gt;16 times&lt;/code&gt;, is about &lt;code&gt;22 bits&lt;/code&gt;. Divide and module &lt;code&gt;11 bits&lt;/code&gt; on each side circling back to the earlier thought, then add those together, giving &lt;code&gt;12 bits&lt;/code&gt; as our checksum response.&lt;/p&gt;

&lt;p&gt;Seems reasonable... It's not completely error proof but the SVG would have to be skipping several steps to mess it up in a way to MAYBE generate the same checksum now... In any case, let's also send back the &lt;code&gt;data length&lt;/code&gt; and &lt;em&gt;include that in the checksum as well&lt;/em&gt;, just by adding it as the last step of our checksum. The max data length (number of 16 bit values we want to handle) is only &lt;code&gt;32&lt;/code&gt;, so adding the length value to the 12 bits doesn't come anywhere near pushing us over 16 bits. Yay!&lt;/p&gt;

&lt;p&gt;spoiler: this &lt;em&gt;is&lt;/em&gt; what I did but CSS became lossy somewhere around 21 bits so I split it up and effectively did the same algorithm but in smaller chunks at a time. Server side uses the alg exactly as described.&lt;/p&gt;

&lt;p&gt;Technically with the setup we've described, it doesn't matter what the order is in the &lt;em&gt;animation&lt;/em&gt; as long as each sentinel tells you what index the next frame is supposed to be in the &lt;em&gt;data&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;One more thing, let's put the &lt;code&gt;data length value&lt;/code&gt; first in the response and add a sentinel for that too (sentinel in the SVG animation before the value, as with the rest of the data).&lt;/p&gt;

&lt;p&gt;That's &lt;em&gt;34 sentinels&lt;/em&gt;. The SVG &lt;code&gt;viewBox&lt;/code&gt; height can't be &lt;code&gt;0&lt;/code&gt; and CSS will benefit from allowing &lt;code&gt;0&lt;/code&gt; to represent no data internally, so let's say we have &lt;strong&gt;35 sentinels&lt;/strong&gt; with &lt;code&gt;0&lt;/code&gt; deliberately unused.&lt;/p&gt;

&lt;p&gt;All data frames now get embedded in the SVG with &lt;code&gt;35&lt;/code&gt; &lt;strong&gt;added to their value&lt;/strong&gt;. &lt;code&gt;Length&lt;/code&gt; and &lt;code&gt;checksum&lt;/code&gt; data values ALSO get &lt;code&gt;35&lt;/code&gt; added to the viewbox value. &lt;code&gt;viewBox&lt;/code&gt; heights in the SVG Animation representing the sentinels will have values &lt;em&gt;0 to 34&lt;/em&gt; (skipping 0) and each tell us exactly what the next frame in the SVG Animation represents.&lt;/p&gt;

&lt;p&gt;CSS side, we just check if &lt;em&gt;the raw measurement&lt;/em&gt; is greater than 34, it's &lt;code&gt;data&lt;/code&gt; so subtract &lt;code&gt;35&lt;/code&gt; from it, if it's less than &lt;code&gt;35&lt;/code&gt;, it's a &lt;code&gt;sentinel&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvffqw4huzstc7c0at6by.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvffqw4huzstc7c0at6by.png" alt="A meme picture of Charlie Day from It's Always Sunny in Philadelphia with a crazed look standing in front of a board covered in paper with red lines connecting them hectically" width="600" height="243"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Beginning to Exfiltrate the 512 bits with CSS
&lt;/h2&gt;

&lt;p&gt;After I finished the PHP side to generate the SVG animation as detailed, I thought on specific ways to begin the CSS for this exfiltration process.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
  Here's the PHP code!
  &lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
  &lt;span class="nb"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Content-type: image/svg+xml'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nv"&gt;$data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;450&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;175&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nv"&gt;$datalen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nv"&gt;$viewBoxXYWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'0 0 10 '&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// add 35 to all the values so we can use 0 to 34 for sentinels. 0 = CSS-side sentinel, 1-32 = data frames, 33 = length, 34 = checksum&lt;/span&gt;
  &lt;span class="nv"&gt;$frames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$viewBoxXYWidth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$viewBoxXYWidth&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'; '&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$viewBoxXYWidth&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$val&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$datalen&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// 1 up to 32 = indicator that next frame is the value(+35) for that index(1-based)&lt;/span&gt;

  &lt;span class="c1"&gt;// no matter how many are in the array, '33' indicates the next frame is data length, which is used in the checksum too&lt;/span&gt;
  &lt;span class="nb"&gt;array_unshift&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$frames&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$viewBoxXYWidth&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'33; '&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$viewBoxXYWidth&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$datalen&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt; &lt;span class="c1"&gt;// + 35 b/c data&lt;/span&gt;
  &lt;span class="c1"&gt;// unshift so the length is (hopefully) the first value read and a sense of progress can be reported&lt;/span&gt;

  &lt;span class="nv"&gt;$fullsum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$datalen&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nv"&gt;$x&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// double the odd ones so there's some semblance of order accounted for&lt;/span&gt;
    &lt;span class="c1"&gt;// the odd ones with 0 based index is the even ones on the CSS side&lt;/span&gt;
    &lt;span class="nv"&gt;$fullsum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$x&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;$x&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$x&lt;/span&gt;&lt;span class="p"&gt;]));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nv"&gt;$checksum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$fullsum&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$fullsum&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$datalen&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// + 35 because it's data&lt;/span&gt;

  &lt;span class="c1"&gt;// no matter how many are in the array, '34' indicates the next frame is checksum&lt;/span&gt;
  &lt;span class="nb"&gt;array_push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$frames&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$viewBoxXYWidth&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'34; '&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$viewBoxXYWidth&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$checksum&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nv"&gt;$actualNumItems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$frames&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nv"&gt;$dur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$actualNumItems&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.33&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// total seconds&lt;/span&gt;

  &lt;span class="nv"&gt;$keytimeStep&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$actualNumItems&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// uniform portion per frame&lt;/span&gt;

  &lt;span class="nv"&gt;$keytimes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;implode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"; "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;array_map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$keytimeStep&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$index&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nv"&gt;$keytimeStep&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$actualNumItems&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;

  &lt;span class="nv"&gt;$values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;implode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"; "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$frames&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

  &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;svg viewBox="0 0 10 100" preserveAspectRatio="xMinYMin meet" xmlns="http://www.w3.org/2000/svg"&amp;gt;
    &amp;lt;animate
      attributeName="viewBox"
      dur="'&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$dur&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'s"
      fill="freeze"
      begin="0.1s;"
      values="'&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$values&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'" 
      keytimes="'&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$keytimes&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'"
      repeatCount="indefinite"
      calcMode="discrete"
    /&amp;gt;
  &amp;lt;/svg&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;&lt;/p&gt;

&lt;p&gt;There are a few ways to accomplish this in CSS and potentially many more coming with &lt;a href="https://www.bram.us/2024/12/18/the-future-of-css-construct-custom-idents-and-dashed-idents-with-ident/" rel="noopener noreferrer"&gt;recent spec additions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;My first approach is the easiest conceptually - using a view-timeline for every piece of data and doing the same thing over and over. It was working but I groaned through my progress in displeasure with how gross it was. That'll be nearly 40 animations on &lt;code&gt;:root&lt;/code&gt; if I continued.&lt;/p&gt;

&lt;p&gt;So I went to sleep.&lt;/p&gt;

&lt;p&gt;When I woke up, I laid there several moments looking out the window smiling with that just-woke-up-or-meditated buzzy feeling, then a firehose of thoughts rushed into my head. I rolled over, grabbed my notebook and the closest pen, sat up in bed, and started writing down the algorithm to exfiltrate it with just 6 CSS animations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwafy0ni6wwzmf3qzn6r0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwafy0ni6wwzmf3qzn6r0.png" alt="my chicken scratch handwriting on a single piece of lined notebook paper with arrows pointing to a couple of nested boxes detailing the method described below" width="525" height="934"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Literally solved on paper; This is &lt;em&gt;EXACTLY&lt;/em&gt; how it's implemented.&lt;/p&gt;

&lt;p&gt;I got up, got on my computer, ignored my previous work, and opened a new CodePen.&lt;/p&gt;

&lt;p&gt;I set up the 4 html elements indicated among the chicken scratch there, then flooded the CSS panel with notes around 4 empty class selectors corresponding to them. It won't be on &lt;code&gt;:root&lt;/code&gt; now but we can place anything that relies on it inside.&lt;/p&gt;

&lt;p&gt;Not a single piece of functionality was added until the notes were copied from the paper and written in more specific detail in CodePen.&lt;/p&gt;

&lt;p&gt;When I was done, I just read the notes and started implementing what they said, all the way to the final working result.&lt;/p&gt;

&lt;p&gt;(I wrote "20" instead of "35" because I was going to test with 256 bits)&lt;/p&gt;

&lt;p&gt;I'll dive into how it works. Because of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/view-timeline" rel="noopener noreferrer"&gt;view-timeline&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/timeline-scope" rel="noopener noreferrer"&gt;timeline-scope&lt;/a&gt;, you can set data up to flow in in kind of a Klein Bottle shape if you can picture the surface animating and getting sucked into the "hole", back up to the narrow top to poor down over the surface again, gaining size and complexity through dom layers, and then loop back up through the blackhole into the higher consciousness (:root).&lt;/p&gt;

&lt;p&gt;It's mostly vertically cyclic (rather than &lt;a href="https://dev.to/janeori/expert-css-the-cpu-hack-4ddj"&gt;mostly horizontally cyclic&lt;/a&gt; or &lt;a href="https://kizu.dev/indirect-cyclic-conditions/" rel="noopener noreferrer"&gt;statically cyclic&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/MYgEexp?height=600&amp;amp;default-tab=css,result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Exfiltrating the 512 bits with CSS
&lt;/h2&gt;

&lt;p&gt;The notes we slightly tweaked and made more clear:&lt;/p&gt;

&lt;p&gt;256 test -&amp;gt; 512 final&lt;/p&gt;

&lt;p&gt;and I added a presentation node inside which is great because I can show the internals too as the algorithm executes.&lt;/p&gt;

&lt;p&gt;but here is the final notes without all the implementation and presentation noise. This exactly describes how it all works.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/d7f701e4bd136e2264e9264913d73808?height=600&amp;amp;default-tab=css&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;It may not be in good form for an article to have this many details embedded externally but I will be breaking down each chunk to show &lt;em&gt;how&lt;/em&gt; it's implemented.&lt;/p&gt;

&lt;h3&gt;
  
  
  Main Controller
&lt;/h3&gt;

&lt;p&gt;At the top of this structure is 4 timeline values and their animations. So let's just plop those in.&lt;/p&gt;

&lt;p&gt;The key piece of data flow that this enables, is it gives us the ability to lift data nested deep in the DOM back up to a host (timeline scope). It's not efficient, so we want to limit how often we do this. Each registered property and it's animation can vertically host a single piece of data. The data's value is determined by the &lt;code&gt;inline&lt;/code&gt; or &lt;code&gt;block&lt;/code&gt; &lt;code&gt;view&lt;/code&gt; position of an element somewhere deep in the structure - we'll get to that part later.&lt;/p&gt;

&lt;p&gt;(see the looping example previously embedded above for a clearer picture of the data flow)&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/b6845b2d74877f3da004611b46da9655?height=600&amp;amp;default-tab=css&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The four pieces of data we're lifting here are:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--xfl-cpu-phase&lt;/code&gt; - this is a numeric value 0 to 4 that signals what phase of the CPU Hack is currently being executed. (a single 'frame' of the CPU Hack is 4 to 5 CSS render frames, one loop of the phases 'ticks' the CPU Hack) I will demonstrate this more specifically later in this article.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--xfl-raw-data&lt;/code&gt; - this hosts the height of the SVG wherever the SVG is in its animation cycle. Our raw data. As said before, if this value is less than 35, this discrete step of the SVG animation is a sentinel value. If it's greater than 34, this discrete step of the SVG animation is our 16 bit value &lt;code&gt;+ 35&lt;/code&gt;, which corresponds to what the previous sentinel indicated.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--xfl-data-type&lt;/code&gt; - this is the most recent sentinel value. This value does not change until the next sentinel is encountered. There is a 1 CSS frame delay from setting &lt;code&gt;--xfl-raw-data&lt;/code&gt; to setting this value.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--xfl-data-value&lt;/code&gt; - this is the current data value after &lt;code&gt;35&lt;/code&gt; was subtracted from the raw value, or &lt;code&gt;0&lt;/code&gt; if we haven't reached this step of the sequence yet. There is a 1 CSS frame delay from setting &lt;code&gt;--xfl-data-type&lt;/code&gt; to setting this value.&lt;/p&gt;

&lt;p&gt;I've also preemptively wrapped &lt;code&gt;svg-animation-current-state-reporter&lt;/code&gt; in a condition that only has functionality and only loads the animated SVG while the process is incomplete. (so all the internals are removed from memory and the heavy animated svg is removed from rendering when we finish)&lt;/p&gt;

&lt;p&gt;The keyframe values go from a &lt;code&gt;max&lt;/code&gt; value for that piece of data to 0. I'll explain later why these are backwards - look for the image of Uno Reverse cards.&lt;/p&gt;

&lt;h3&gt;
  
  
  CPU Exfiltrator
&lt;/h3&gt;

&lt;p&gt;Next we set up the basic boilerplate for a &lt;a href="https://dev.to/janeori/expert-css-the-cpu-hack-4ddj"&gt;CPU Hack&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The CPU Hack boilerplate is just following a variable name pattern to set up &lt;code&gt;capture&lt;/code&gt; and &lt;code&gt;hoist&lt;/code&gt; animations.&lt;/p&gt;

&lt;p&gt;If we have 1 integer &lt;code&gt;--xfl\\1&lt;/code&gt; that we want to cycle horizontally (over time), we register it and we set up capture and hoist animations like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;capture&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;--xfl\\1&lt;/span&gt;&lt;span class="py"&gt;-captured&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--xfl&lt;/span&gt;&lt;span class="err"&gt;\\&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;hoist&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;--xfl\\1&lt;/span&gt;&lt;span class="py"&gt;-hoist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--xfl&lt;/span&gt;&lt;span class="err"&gt;\\&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;-captured&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then complete the cyclic assignment on the &lt;code&gt;.cpu-exfiltrator&lt;/code&gt; element where the two CPU animations are hosted. I'll do it for just one of the values for now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;  &lt;span class="nt"&gt;--xfl&lt;/span&gt;&lt;span class="err"&gt;\\1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--xfl&lt;/span&gt;&lt;span class="err"&gt;\\1&lt;/span&gt;&lt;span class="nt"&gt;-hoist&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;
  &lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Chrome, they won't statically cycle (become the &lt;code&gt;initial&lt;/code&gt; value) unless both animations are &lt;code&gt;running&lt;/code&gt; at the same time. Which is a FANTASTIC side effect of what's likely an optimization of paused animations setting numeric properties.&lt;/p&gt;

&lt;p&gt;Finally, since we're using a new automatic version of the CPU Hack (you don't have to :hover to cycle the phases like in the original hack), we wire in the &lt;code&gt;--xfl-cpu-phase&lt;/code&gt; var from previous (hosted on the parent element here, so we can use style queries to respond to it) and control the play state of our animations.&lt;/p&gt;

&lt;p&gt;We also output &lt;code&gt;--cpu-next-phase&lt;/code&gt; which will later be lifted back to the top and set the next value for &lt;code&gt;--xfl-cpu-phase&lt;/code&gt; using its view position and timeline scope.&lt;/p&gt;

&lt;p&gt;I've added an additional phase to keep the CPU Hack paused until the SVG Animation measurement has successfully locked in the next &lt;code&gt;--xfl-data-type&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;  &lt;span class="k"&gt;@container&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--xfl-cpu-phase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;animation-play-state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;paused&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;paused&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;--cpu-next-phase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--xfl-data-type&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(as it is now, data-type is still always 0 so once next phase is wired in, this will already be looping the CPU Hack. Once we have a data-type sentinel it won't loop until we've cleared it deliberately with the &lt;code&gt;0&lt;/code&gt; sentinel)&lt;/p&gt;

&lt;p&gt;Later, we'll also add the noted condition to prevent CPU phase 1 from starting until data is all in place. That will ensure that between data type (sentinel) being locked in and data value (raw - 35) being locked in, we want to leave the CPU Hack in its capture phase. So it's "ready to be ready" as Abraham Hicks might say.&lt;/p&gt;

&lt;p&gt;I'll go ahead and register all the 32 values plus checksum and length that we expect the SVG Animation to report.&lt;/p&gt;

&lt;p&gt;Since registration of &lt;code&gt;--xfl\\1&lt;/code&gt; to &lt;code&gt;--xfl\\32&lt;/code&gt; is a big block and the CPU animations are just boilerplate too, I'll move all those to the bottom of the hack setup to be ignored moving forward.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/3f8a2de1185abe7ac4852d65b0a3e805?height=600&amp;amp;default-tab=css&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Automatic CPU Hack
&lt;/h3&gt;

&lt;p&gt;This wires the next cpu phase up to the &lt;code&gt;--xfl-cpu-phase&lt;/code&gt; value&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.cpu-phase-cycle-request0r&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;hotpink&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="err"&gt;&amp;amp;::before&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;25px&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--cpu-next-phase&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;lime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;view-timeline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;--xfl-cpu-phase&lt;/span&gt; &lt;span class="nb"&gt;inline&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's some CSS boilerplate here to make the element be a scroll container and put it off screen. The important part is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;view-timeline: --xfl-cpu-phase inline;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;which says where the right edge of this pseudo element falls in its 100px wide parent, wire it up as a "progress" from the left to our animation that moves from 0 to 4... So 25px is 25% complete, which maps to 1 when 25% is between 0 and 4.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrdeyocs40lpilceihqg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrdeyocs40lpilceihqg.png" alt="picture of two 'reverse' cards from Uno" width="800" height="450"&gt;&lt;/a&gt; image sourced from a google search leading to &lt;a href="https://x.com/HawksRunning/status/1580160214426603520" rel="noopener noreferrer"&gt;twitter&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;TECHNICALLY the animation is 4 to 0 and TECHNICALLY it's measuring from the right edge of the pseudo as view progress towards the right. So 25px wide pseudo is 75% from the right of its 100px wide scroll parent and maps to a value of 1 when 75% is between 4 and 0.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's easier to understand if you don't cognitively process the reverse reverse math and just accept the end result is a simple progress 0 to 4 because the max value in the animation is 4 (again ignoring that the animation &lt;em&gt;starts&lt;/em&gt; at 4).&lt;/p&gt;

&lt;p&gt;Let's also write the ready state that holds the CPU in phase 0 until the data is ready. The note is on line 64 of our demos:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Data ready = data-type &amp;gt; 0 &amp;amp;&amp;amp; raw-frame-data - 35 === data-value&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;  &lt;span class="nt"&gt;--xfl-data-is-ready&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="nt"&gt;min&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--xfl-data-type&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
    &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt; &lt;span class="nt"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;min&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;max&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--xfl-raw-data&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-&lt;/span&gt; &lt;span class="err"&gt;35&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--xfl-data-value&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--xfl-data-value&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--xfl-raw-data&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-&lt;/span&gt; &lt;span class="err"&gt;35&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;)))&lt;/span&gt;
  &lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;@container&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--xfl-cpu-phase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;animation-play-state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;paused&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;--cpu-next-phase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--xfl-data-is-ready&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Wait, === in CSS?
&lt;/h4&gt;

&lt;p&gt;These are quite outdated now and I'd do them differently today, written before &lt;code&gt;clamp()&lt;/code&gt; was baseline, but I always open this old codepen to mindlessly copy paste numeric comparators when I need them. It'd be a good article to update these and explain them but here you go in the meantime: &lt;a href="https://codepen.io/propjockey/pen/YzZMNaz" rel="noopener noreferrer"&gt;https://codepen.io/propjockey/pen/YzZMNaz&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Reading the SVG Animation
&lt;/h3&gt;

&lt;p&gt;This is initially &lt;em&gt;VERY&lt;/em&gt; similar to the &lt;code&gt;CPU Exfiltrator&lt;/code&gt; section because it's the same technique, measuring and moving data from here up the DOM to where it's hosted (scope).&lt;/p&gt;

&lt;p&gt;We'll be measuring and reporting the last 3 values for the base element we set up initially.&lt;/p&gt;

&lt;p&gt;On &lt;code&gt;::before&lt;/code&gt; we'll render the SVG and set &lt;code&gt;--xfl-raw-data&lt;/code&gt; using &lt;code&gt;block&lt;/code&gt; view position which is the measurement of the animated SVG's height. (remember, we'll pin the width to &lt;code&gt;10px&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;On &lt;code&gt;::after&lt;/code&gt; we'll set &lt;code&gt;--xfl-data-type&lt;/code&gt; inline (sentinel values 0 to 34) and &lt;code&gt;--xfl-data-value&lt;/code&gt; block (16 bit values).&lt;/p&gt;

&lt;p&gt;The parent will need to be wide enough to render the SVG (at least 10px) and accurately provide measurements for the sentinel values (0 to 34).&lt;/p&gt;

&lt;p&gt;The parent will also need to be tall enough to measure 16 bit values (+ 35). Since we set a max value in the first step of 100k, we'll just use that even though it's about 30% bigger than we need.&lt;/p&gt;

&lt;p&gt;And move it off screen to the top and left so it doesn't cause scrollbars.&lt;/p&gt;

&lt;p&gt;Therefore,&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.svg-animation-current-state-reporter&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;gets&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;  &lt;span class="nt"&gt;position&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;absolute&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;rgba&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;255&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;34&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="c"&gt;/* --xfl-data-type keyframes are 34 to 0 b/c max data-type = 34 */&lt;/span&gt;
  &lt;span class="nt"&gt;height&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--xfl-max&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;bottom&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--xfl-max&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="nt"&gt;vh&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;left&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;-100vw&lt;/span&gt; &lt;span class="nt"&gt;-&lt;/span&gt; &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;overflow&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;hidden&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;font-size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nt"&gt;important&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;line-height&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nt"&gt;important&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;margin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and before becomes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;::before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url('http://css-api.propjockey.io/api.svg.php?')&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;lime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="py"&gt;--height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2135px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="py"&gt;view-timeline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;--xfl-raw-data&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and &lt;code&gt;::after&lt;/code&gt; gets&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;  &lt;span class="nt"&gt;position&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;absolute&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;height&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;left&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--TODO_SENTINEL_VALUE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="nt"&gt;-&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;
  &lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;top&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--TODO_DATA_VALUE&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="nt"&gt;-&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt;
  &lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;black&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;view-timeline&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;--xfl-data-type&lt;/span&gt; &lt;span class="nt"&gt;inline&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;--xfl-data-value&lt;/span&gt; &lt;span class="nt"&gt;block&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essentially the storage medium here for these after values is the view position of a 1px square pseudo against its parent scroll container. We subtract 1px in the left and top calcs because the pseudo itself is 1x1 and we want it to report 0 when the corresponding value is 0.&lt;/p&gt;

&lt;p&gt;This is all very similar to what was done previously.&lt;/p&gt;

&lt;p&gt;There are several complexities to how we calculate what these values should be, as the note indicates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* there's 4 stages here
// 1) cpu tells us to reset to 0s
// 2) cpu is in phase 0 (capture running) and stays until these stages finish
//   a. if svg animation frame (based on raw) is type, set type else use prev
//   3. if svg animation frame (based on raw) is data, set data else use prev
// 4) CPU is executing, our job is to hold prev values and ignore the SVG ani
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key to understanding how to solve this is that any comparator value is set to either 0 or 1. 1 if it's true, 0 if it's false. Then multiply it by some value. If it's false, the result stays 0, otherwise it becomes whatever the value is.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://css-tricks.com/dry-switching-with-css-variables-the-difference-of-one-declaration/" rel="noopener noreferrer"&gt;Ana Tudor goes into great depth of how this idea works here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, if we do that comparison twice, with a different or opposite comparison for the second value, and add them together (Ensuring at most one of the comparators is 1) then the addition of two of them is just saying "else if".&lt;/p&gt;

&lt;p&gt;&lt;code&gt;if not ready&lt;/code&gt; * &lt;code&gt;use the old value&lt;/code&gt; + &lt;code&gt;else&lt;/code&gt;&lt;br&gt;
&lt;code&gt;if is ready&lt;/code&gt; * &lt;code&gt;use this new value&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is how we hold onto the sentinel value through the duration of the SVG Animation's discrete step for the value after the type has already been reported.&lt;/p&gt;

&lt;p&gt;The CSS code implementing it begins on line 191 here, just above the big block of &lt;code&gt;--xfl\\...&lt;/code&gt; property registrations we put towards the bottom&lt;br&gt;
&lt;code&gt;@property --xfl\\1 { syntax: "&amp;lt;integer&amp;gt;"; initial-value: 0; inherits: true; }&lt;/code&gt;&lt;br&gt;
...&lt;br&gt;
and it contains additional notes:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/a99afb3c6e4d4d6397e62ce24528bc7c?height=600&amp;amp;default-tab=css&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting specific CSS --var values (addressed assignments)
&lt;/h3&gt;

&lt;p&gt;The logic we just touched on is exactly the same concept we use for all of the &lt;code&gt;--xfl\\1&lt;/code&gt;, 2, 32 values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;  &lt;span class="nt"&gt;--xfl-set&lt;/span&gt;&lt;span class="err"&gt;\\1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt; &lt;span class="nt"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;min&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;max&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
      &lt;span class="err"&gt;1&lt;/span&gt; &lt;span class="nt"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--xfl-data-type&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
      &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--xfl-data-type&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;-&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;
    &lt;span class="o"&gt;)))&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--xfl-data-is-ready&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="nt"&gt;--xfl&lt;/span&gt;&lt;span class="err"&gt;\\1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;calc&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--xfl-set&lt;/span&gt;&lt;span class="err"&gt;\\1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--xfl-data-value&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt; &lt;span class="nt"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--xfl-set&lt;/span&gt;&lt;span class="err"&gt;\\1&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--xfl&lt;/span&gt;&lt;span class="err"&gt;\\1&lt;/span&gt;&lt;span class="nt"&gt;-hoist&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You read &lt;code&gt;--xfl-set\\1&lt;/code&gt; as &lt;code&gt;if --xfl-data-type gte 1&lt;/code&gt; &lt;code&gt;use --xfl-data-is-ready&lt;/code&gt; with an implied &lt;code&gt;else 0&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;--xfl-data-is-ready&lt;/code&gt; was established earlier as a flag holding us in phase 0 until it's time to flip to phase 1.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That means our condition is &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; logic. Both flags must be 1 to pass.&lt;/p&gt;

&lt;p&gt;Then you continue to read &lt;code&gt;--xfl\\1&lt;/code&gt; as &lt;code&gt;if --xfl-set\\1&lt;/code&gt; &lt;code&gt;use --xfl-data-value&lt;/code&gt; (the current SVG Animation value) else &lt;code&gt;if NOT --xfl-set\\1&lt;/code&gt; &lt;code&gt;use --xfl\\1-hoist&lt;/code&gt; (the previous value the CPU hack was holding for --xfl\1)&lt;/p&gt;

&lt;p&gt;This is highly repetitive, and describes almost the entirety of the rest of this exfiltration.&lt;/p&gt;

&lt;p&gt;The final steps are running basic &lt;code&gt;calc()&lt;/code&gt; and &lt;code&gt;mod()&lt;/code&gt; math to build the checksum as described earlier, then adding if the computed checksum === the checksum embedded in the SVG Animation to the CPU Hack so we know when it's complete. All more of the same.&lt;/p&gt;

&lt;p&gt;So now it's time. :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Presenting: The CSS Animated SVG Exfiltration Hack
&lt;/h2&gt;

&lt;p&gt;Because I wanted to show each and every piece of this hack one value per element, the presentation for this is obnoxiously heavy. Over 2000 lines of HTML and over 400 lines of CSS. Plus I'm using &lt;a href="https://propjockey.github.io/css-bin-bits/" rel="noopener noreferrer"&gt;css-bin-bits&lt;/a&gt; to convert each register to binary, etc.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/ee2e273bc44529cefa21f7e97dd82a6c?height=600&amp;amp;default-tab=result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;(Click rerun in the bottom right of the codepen frame to see it happen in real time!)&lt;/p&gt;

&lt;p&gt;No JavaScript!&lt;/p&gt;




&lt;h2&gt;
  
  
  Open Contact 👽
&lt;/h2&gt;

&lt;p&gt;Please do reach out if you think this is neat and wish to learn more! Always happy to answer questions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PropJockey.io&lt;/th&gt;
&lt;th&gt;CodePen&lt;/th&gt;
&lt;th&gt;DEV Blog&lt;/th&gt;
&lt;th&gt;GitHub&lt;/th&gt;
&lt;th&gt;Mastodon&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://propjockey.io" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fpropjockey-lines.svg" alt="PropJockey.io" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://codepen.io/propjockey" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fcodepen.svg" alt="CodePen" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/janeori"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fdev.svg" alt="DEV Blog" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/propjockey" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fgithub.svg" alt="GitHub" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://front-end.social/@JaneOri" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fmastodon.svg" alt="Mastodon" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://bsky.app/profile/janeori.propjockey.io" rel="noopener noreferrer"&gt;🦋@JaneOri.PropJockey.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://x.com/jane0ri" rel="noopener noreferrer"&gt;𝕏@Jane0ri&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>hacking</category>
      <category>svg</category>
    </item>
    <item>
      <title>100% CSS: &lt;fieldset&gt;'s border &lt;legend&gt; knockout behavior for any element !</title>
      <dc:creator>Jane Ori</dc:creator>
      <pubDate>Wed, 08 Jan 2025 06:31:03 +0000</pubDate>
      <link>https://dev.to/janeori/100-css-s-border-knockout-behavior-for-any-element--4b7b</link>
      <guid>https://dev.to/janeori/100-css-s-border-knockout-behavior-for-any-element--4b7b</guid>
      <description>&lt;p&gt;Legend has it, there will come a day when the beautiful fieldset border knockout effect will be possible with any html element.&lt;/p&gt;

&lt;p&gt;And I have great news: In Chrome, that day is today!&lt;/p&gt;

&lt;h2&gt;
  
  
  Fieldset? Legend?
&lt;/h2&gt;

&lt;p&gt;If you're unfamiliar, here's the border knockout effect on a fieldset with a legend:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv85906qevz3g7uh9wtxz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv85906qevz3g7uh9wtxz.png" alt="a picture of two simple fieldset elements with their legend (titles) leaving a gap the width of their text in the fieldset's border" width="800" height="380"&gt;&lt;/a&gt;fieldset legend examples in a slightly modified screenshot from &lt;a href="https://vanillahtml.fandeytech.com/" rel="noopener noreferrer"&gt;VanillaHTML&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The width of the &lt;code&gt;legend&lt;/code&gt; (title) is clipping a hole in the border of the &lt;code&gt;fieldset&lt;/code&gt; automatically.&lt;/p&gt;

&lt;p&gt;While technically possible to just use &lt;code&gt;&amp;lt;fieldset&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;legend&amp;gt;&lt;/code&gt; anywhere, it's generally not recommended to use a &lt;code&gt;&amp;lt;fieldset&amp;gt;&lt;/code&gt; outside of a &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; and without any &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; elements inside of it, as the primary purpose of a fieldset is to &lt;em&gt;semantically group related form inputs&lt;/em&gt;. Using it in unrelated contexts goes against its intended meaning and can negatively impact accessibility for screen readers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fieldset border legend knockout behavior anywhere
&lt;/h2&gt;

&lt;p&gt;This is not trivial to accomplish so I hid every bit of the complexity that I could to make it as close to trivial to replicate:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/9d6539d75d50c4f9e60e142641c78c3a?height=600&amp;amp;default-tab=result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;@import&lt;/code&gt; the &lt;a href="https://www.npmjs.com/package/fieldset-legend" rel="noopener noreferrer"&gt;fieldset-legend&lt;/a&gt; utility in your css.&lt;/li&gt;
&lt;li&gt;Add the &lt;code&gt;fieldset-legend&lt;/code&gt; class to the wrapper&lt;/li&gt;
&lt;li&gt;Set the &lt;code&gt;--fl-left&lt;/code&gt; property to any &lt;code&gt;&amp;lt;length-percentage&amp;gt;&lt;/code&gt; value (even negative values if you wish)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And the library will position the &lt;code&gt;:first-child&lt;/code&gt; so it's vertically centered with the top of the element and knock out the stuff behind it!&lt;/p&gt;

&lt;p&gt;To create a gap around the title, add padding to the &lt;code&gt;:first-child&lt;/code&gt; however you want to.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The biggest gotcha here is you can't put plain text nodes directly in the &lt;code&gt;fieldset-legend&lt;/code&gt; wrapper, text has to be nested inside of their own elements.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also, &lt;em&gt;technically&lt;/em&gt; &lt;code&gt;fieldset&lt;/code&gt;'s border knockout doesn't &lt;em&gt;sink&lt;/em&gt; to the bottom of the &lt;code&gt;legend&lt;/code&gt; element and clip the background too, like it does above.&lt;/p&gt;

&lt;p&gt;If you prefer the knockout to only &lt;em&gt;sink&lt;/em&gt; through the border, you can provide an additional &lt;code&gt;&amp;lt;length&amp;gt;&lt;/code&gt; property, &lt;code&gt;--fl-sink&lt;/code&gt; and set it equal to your border width:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/fe26154ad3d7a12af48d301ecf357f54?height=600&amp;amp;default-tab=css,result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Does it do anything else?
&lt;/h2&gt;

&lt;p&gt;It does!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;--fl-left&lt;/code&gt; alternatives
&lt;/h3&gt;

&lt;p&gt;Instead of &lt;code&gt;--fl-left&lt;/code&gt;, you could instead use &lt;code&gt;--fl-center&lt;/code&gt;.&lt;br&gt;
If you set &lt;code&gt;--fl-center&lt;/code&gt; to &lt;code&gt;0px&lt;/code&gt;, the title will be centered horizontally along the top edge.&lt;br&gt;
If you set it to &lt;code&gt;-10px&lt;/code&gt;, it will be offset to the left of center by &lt;code&gt;10px&lt;/code&gt;.&lt;br&gt;
Set it to &lt;code&gt;15px&lt;/code&gt; and it will shift right of center by &lt;code&gt;15px&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Instead of &lt;code&gt;--fl-left&lt;/code&gt; or &lt;code&gt;--fl-center&lt;/code&gt;, you could also use &lt;code&gt;--fl-right&lt;/code&gt; with the expected behavior.&lt;/p&gt;

&lt;p&gt;All 3 of these are &lt;code&gt;&amp;lt;length-percentage&amp;gt;&lt;/code&gt; and can be positive, 0px, or negative.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;--fl-top&lt;/code&gt; option
&lt;/h3&gt;

&lt;p&gt;By default, the title element is vertically centered with the top edge of the outer element. Setting &lt;code&gt;--fl-top&lt;/code&gt; to a negative &lt;code&gt;&amp;lt;length&amp;gt;&lt;/code&gt; lifts it, and to a positive length drops it.&lt;/p&gt;

&lt;p&gt;By default, the bottom edge of the title is how far down the knockout sinks into the element, so remember you can control that as well with &lt;code&gt;--fl-sink&lt;/code&gt; described previously!&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/ByBYjEy?height=600&amp;amp;default-tab=result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;fieldset-legend&lt;/code&gt; container also automatically applies a &lt;code&gt;margin-top&lt;/code&gt; to cover the height of the title poking above the element. The rule setting this has 0 specificity so it can easily be overwritten if you prefer another value.&lt;/p&gt;

&lt;h3&gt;
  
  
  Title as &lt;code&gt;:first-child&lt;/code&gt; alternatives
&lt;/h3&gt;

&lt;p&gt;It may be important for you to place other elements, such as screenreader-only page jumps, prior to the title inside the &lt;code&gt;fieldset-legend&lt;/code&gt; container.&lt;/p&gt;

&lt;p&gt;Place a class &lt;code&gt;fieldset-legend-title&lt;/code&gt; on any ONE of the direct descendants of your &lt;code&gt;fieldset-legend&lt;/code&gt; element and the library will lift that element to the same desired position at the top, leaving &lt;code&gt;:first-child&lt;/code&gt; alone.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;fieldset-legend&lt;/code&gt; uses the &lt;code&gt;::before&lt;/code&gt; pseudo
&lt;/h3&gt;

&lt;p&gt;You can make it use the &lt;code&gt;::after&lt;/code&gt; pseudo instead, just change the class name from &lt;code&gt;fieldset-legend&lt;/code&gt; to &lt;code&gt;fieldset-legend-after&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;fieldset-legend&lt;/code&gt; no pseudo?
&lt;/h3&gt;

&lt;p&gt;This is advanced usage but...&lt;/p&gt;

&lt;p&gt;You can &lt;code&gt;inset: 0px;&lt;/code&gt; an element inside the wrapper, customize it however you want, and use &lt;code&gt;fieldset-legend-custom&lt;/code&gt; instead of &lt;code&gt;fieldset-legend&lt;/code&gt; or &lt;code&gt;fieldset-legend-after&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This drops all of the library's clipping and gives you a custom &lt;code&gt;mask&lt;/code&gt; to use anywhere inside of the &lt;code&gt;fieldset-legend-custom&lt;/code&gt; element.&lt;/p&gt;

&lt;p&gt;For example, if you wanted to use this with your favorite sci-fi shaping library, &lt;a href="https://augmented-ui.com/" rel="noopener noreferrer"&gt;augmented-ui&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/6c7c6383c874218951fa4870411f7585?height=600&amp;amp;default-tab=css,result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Fallback behavior
&lt;/h2&gt;

&lt;p&gt;The limiting feature support required to use this utility is &lt;a href="https://caniuse.com/mdn-css_properties_timeline-scope" rel="noopener noreferrer"&gt;&lt;code&gt;timeline-scope&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Container &lt;a href="https://caniuse.com/css-container-queries-style" rel="noopener noreferrer"&gt;style queries&lt;/a&gt; are also required.&lt;/p&gt;

&lt;p&gt;This is what the first demo in this article looks like in non-Chrome browsers:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsxliyd2qhvvvknolrjbi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsxliyd2qhvvvknolrjbi.png" alt="picture of the fallback behavior as described below" width="800" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It applies the same mechanical styling to minimize differences, such as a non-static position and &lt;code&gt;isolation: isolate;&lt;/code&gt; but most notably, it moves the title back inline and does two &lt;code&gt;!important&lt;/code&gt; things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The title &lt;code&gt;color&lt;/code&gt; becomes &lt;code&gt;currentColor&lt;/code&gt; - the content behind the title switches from the body to the inside of your &lt;code&gt;fieldset-legend&lt;/code&gt; container, which may have a very different background. Using &lt;code&gt;currentColor&lt;/code&gt; ensures the content is readable because the rest of the content in your not-a-fieldset is likely already set appropriately.&lt;/li&gt;
&lt;li&gt;Along the same lines, I can't know if your title element already had its own background (though if it did, you don't need this utility to position it over the border) so the background is forced to &lt;code&gt;transparent&lt;/code&gt;, ensuring &lt;code&gt;currentColor&lt;/code&gt; on the &lt;code&gt;fieldset-legend&lt;/code&gt;'s background, which in most cases will already be readable.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To determine specific fallback behavior, you can set&lt;br&gt;
&lt;code&gt;--fl-fallback-title-color&lt;/code&gt; and &lt;code&gt;--fl-fallback-title-background&lt;/code&gt; which will be used in place of &lt;code&gt;currentColor&lt;/code&gt; or &lt;code&gt;transparent&lt;/code&gt; in the event it is rendered somewhere without support.&lt;/p&gt;

&lt;p&gt;And this is what the custom demo above looks like in browsers that don't support &lt;code&gt;fieldset-legend&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmsuu8ule5m9xzw2biiii.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmsuu8ule5m9xzw2biiii.png" alt="picture of the fallback behaviors as described above" width="800" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Further fallback support
&lt;/h3&gt;

&lt;p&gt;If you know how to use my old &lt;a href="https://github.com/propjockey/css-sweeper?tab=readme-ov-file#css-is-a-programming-language-thanks-to-the-space-toggle-trick" rel="noopener noreferrer"&gt;Space Toggle&lt;/a&gt; technique, the library also provides:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--fl-supported&lt;/code&gt;, which will be a space when supported and &lt;code&gt;initial&lt;/code&gt; when not supported&lt;/p&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--fl-not-supported&lt;/code&gt;, which is the opposite.&lt;/p&gt;




&lt;h2&gt;
  
  
  Open Contact 👽
&lt;/h2&gt;

&lt;p&gt;Please do reach out if you need help with any of this, have feature requests, or want to share what you've created!&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PropJockey.io&lt;/th&gt;
&lt;th&gt;CodePen&lt;/th&gt;
&lt;th&gt;DEV Blog&lt;/th&gt;
&lt;th&gt;GitHub&lt;/th&gt;
&lt;th&gt;Mastodon&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://propjockey.io" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fpropjockey-lines.svg" alt="PropJockey.io" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://codepen.io/propjockey" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fcodepen.svg" alt="CodePen" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/janeori"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fdev.svg" alt="DEV Blog" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/propjockey" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fgithub.svg" alt="GitHub" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://front-end.social/@JaneOri" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fmastodon.svg" alt="Mastodon" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://bsky.app/profile/janeori.propjockey.io" rel="noopener noreferrer"&gt;🦋@JaneOri.PropJockey.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://x.com/jane0ri" rel="noopener noreferrer"&gt;𝕏@Jane0ri&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>GETting your IP Address with CSS - and other 32 bit API responses - without JavaScript!</title>
      <dc:creator>Jane Ori</dc:creator>
      <pubDate>Mon, 06 Jan 2025 18:30:13 +0000</pubDate>
      <link>https://dev.to/janeori/getting-your-ip-address-with-css-and-other-32-bit-api-responses-without-javascript-402h</link>
      <guid>https://dev.to/janeori/getting-your-ip-address-with-css-and-other-32-bit-api-responses-without-javascript-402h</guid>
      <description>&lt;p&gt;Just over a week ago while scrolling YouTube shorts after work on a Friday, looking for something to want, this 35 second video stopped me and took 100% of my attention&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/WzlTtn8NCZI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;After one and a half playthroughs, I paused it, tilted my head back and stared off into space as ideas rushed into my mind.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I could make Chess in CSS with the CPU Hack."&lt;/p&gt;

&lt;p&gt;"Could I connect it to that tablebase without JS?"&lt;/p&gt;

&lt;p&gt;"The only way CSS can reach out to a server is with background ima---!!!&lt;/p&gt;

&lt;p&gt;It can also use &lt;code&gt;url()&lt;/code&gt; as &lt;code&gt;content&lt;/code&gt; on a pseudo element, which can resize the parent, then &lt;code&gt;inset: 0px&lt;/code&gt; an absolute position &lt;code&gt;container&lt;/code&gt; inside of it and I can measure that with &lt;a href="https://dev.to/janeori/css-type-casting-to-numeric-tanatan2-scalars-582j"&gt;tan(atan2())&lt;/a&gt; aaand that's my GET request's response data...&lt;/p&gt;

&lt;p&gt;If the element resizes based on that content, it would be useful to have it off screen to avoid causing scrollbars - plus better DX for anyone using would if it didn't need a weird one-off setup that you had to build &lt;em&gt;inside&lt;/em&gt; of... So how do I get the data out --&lt;/p&gt;

&lt;p&gt;I've known how to lift data to &lt;code&gt;:root&lt;/code&gt; since the &lt;a href="https://dev.to/janeori/expert-css-the-cpu-hack-4ddj"&gt;CPU Hack&lt;/a&gt; since it already does that on a much smaller scale but never had a reason to try..."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then I paused as my eyes darted around without any awareness of my physical surroundings, looking for edge cases among the components I've assembled - "What can't be done here?"&lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I'd have to &lt;code&gt;@container style(--x: N)&lt;/code&gt; wrap my urls so gamestate can choose what ones to use but I'd only have a hardcoded list of possible endpoints until we get &lt;code&gt;url()&lt;/code&gt; &lt;a href="https://drafts.csswg.org/css-link-params/" rel="noopener noreferrer"&gt;param()&lt;/a&gt;...&lt;br&gt;
AH WAIT! I could also generate the necessary request url and prompt the player to &lt;a href="https://dev.to/janeori/the-css-smear-hack-4fd1"&gt;SMEAR&lt;/a&gt; it into the page, shrouded as the UI to confirm their move..."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I leaned back and splayed my fingers and palms, panning my eyes across the room slowly as excitement built inside me.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"16 bits on the width and 16 bits on the height is huge but well within possible..."&lt;/p&gt;

&lt;p&gt;"I think that's it! I can do it!"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;/p&gt;
  The rest of this plot exposition isn't directly relevant, but I'm enjoying the moment so I'll leave the writing here for anyone reading along
  &lt;p&gt;So I started building my chess board in &lt;a href="https://codepen.io/propjockey" rel="noopener noreferrer"&gt;CodePen, where all my ideas start their journey into realization&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I guess it's time to learn Chess so I know how to build the API request and to determine if ~32 bits was enough response data for it to communicate the CPU move..."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;I played Chess briefly back in my teenage IRC-loving, game hacking days and quit at the end of a losing streak with hysterical laughter when I devised a way to cheat every move of a match and still lost. (I made my friend go first then used the move he wrote in IRC against the "expert" computer player in the chess game I downloaded, then communicated to him what the CPU did as my move.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I was COMPLETELY oblivious to how much of Chess I knew absolutely nothing about.&lt;/p&gt;

&lt;p&gt;I searched for existing APIs I could just wrap, assuming I'll generate an image on my server use the height/width as the response data. I quickly found &lt;a href="https://chess-api.com/" rel="noopener noreferrer"&gt;chess-api.com&lt;/a&gt; which can respond with a next move given "FEN" as input.&lt;/p&gt;

&lt;p&gt;I &lt;a href="https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation" rel="noopener noreferrer"&gt;learned FEN&lt;/a&gt;, which lead to even more discovery of how much I didn't know about Chess. I knew I could generate the SMEAR Hack to build the gamestate in FEN format, and most importantly, I measured that I could indeed bitpack the important response data &lt;code&gt;move: "b7b8q"&lt;/code&gt; into 32 bits. (It's an 8x8 board and I know where everything is, not much fundamentally has to be provided in the response.)&lt;/p&gt;

&lt;p&gt;Now, I know with more certainty I can program Chess against a CPU Player in 100% CSS.&lt;/p&gt;

&lt;p&gt;I also knew at that moment, I should definitely rewatch The Queen's Gambit because I absolutely loved it and can't wait to pick up on new details.&lt;/p&gt;



&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The universe is talking to me and I'm putting the excitement into action to keep the loop flowing.&lt;/p&gt;

&lt;p&gt;Time to test the CSS API URL GET ALL CAPS TRAIN idea and see if it works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demoing the basics
&lt;/h2&gt;

&lt;p&gt;First, establish appropriate background noise for this endeavor, &lt;a href="https://www.netflix.com/title/80234304" rel="noopener noreferrer"&gt;The Queen's Gambit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next, confirm measuring an image.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/ab9685602b2041007a7f85177a1bc635?height=600&amp;amp;default-tab=css,result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Easy enough! Just make sure all the content inside stays absolute so it doesn't change the size of the container holding the image.&lt;/p&gt;

&lt;p&gt;Throw in a test for changing what URL we GET...&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/19e9ede4136dbb7310e6b0b0119c35f7?height=600&amp;amp;default-tab=css,result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Proof of concept confirmed, next leg of this journey was lifting the response data to &lt;code&gt;:root&lt;/code&gt; so I can make all the setup invisible and at least 65535px off screen to the top and left.&lt;/p&gt;

&lt;p&gt;I knew this was going to be heavy, esoteric CSS+HTML and &lt;a href="https://github.com/propjockey/propjockey.io/blame/main/src/components/Jane.astro#L76" rel="noopener noreferrer"&gt;I make things that help people make things&lt;/a&gt;, so right from the start, I built this with the intention of making it an easy-to-use library.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://github.com/propjockey/css-api-fetch/tree/52abadea53c09048ccabe082ec3384b7e271aa8e" rel="noopener noreferrer"&gt;version 1&lt;/a&gt;, &lt;a href="https://github.com/propjockey/css-api-fetch/blob/52abadea53c09048ccabe082ec3384b7e271aa8e/html-templates-root.md" rel="noopener noreferrer"&gt;Copy plop some specific (bulky) HTML&lt;/a&gt; in your page with a handful of options built in to make the requests and do the &lt;code&gt;:root&lt;/code&gt; lift for you.&lt;/p&gt;

&lt;p&gt;Import the library and specify the API endpoint from your CSS,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="sx"&gt;url(https://unpkg.com/css-api-fetch@1/api-fetch.css)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@container&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--api-id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.api-fetch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;--api-fetch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url(https://css-api.propjockey.io/ip-address.php)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the data will be on &lt;code&gt;:root&lt;/code&gt; for the rest of your app once it's ready.&lt;/p&gt;

&lt;p&gt;But it gets better, fast!&lt;/p&gt;

&lt;h2&gt;
  
  
  First Public Demonstration, Chrome Only, :root
&lt;/h2&gt;

&lt;p&gt;GETting a user's IP Address with CSS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codepen.io/propjockey/pen/pvzrWyG" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flk2jqiwuo4pfbzlr0rnk.png" alt="Screenshot of the initial state of the codepen linked" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm not going to go into super specific implementation details in this post of how exactly that CSS+HTML lifts the data to &lt;code&gt;:root&lt;/code&gt; in that original public demo because a couple of CSS loving friends pointed me in a much easier direction I hadn't learned about!&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
  but I will put this quick summary here for anyone interested
  &lt;p&gt;&lt;code&gt;:root:has(.specific-element:hover) { ..state... }&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If the specific-element descendant knows it's &lt;code&gt;:hover&lt;/code&gt;, it can change to put a different element on top of where it currently is which causes the next element to be hovered, then &lt;code&gt;:root:has(...:hover)&lt;/code&gt; changes its state based on that element too, in a loop.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/janeori/expert-css-the-cpu-hack-4ddj"&gt;The CPU Hack&lt;/a&gt; lets us accumulate the state as different elements are &lt;code&gt;:hover&lt;/code&gt;'d.&lt;/p&gt;

&lt;p&gt;So if the data we want to lift is '512', we can sequence 'thousands', 'hundreds', 'tens', and 'ones', telling the child to present an element 0 to 9 representing the value it's holding in that position.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;.api-transfer-value-0:hover&lt;/code&gt;, &lt;code&gt;...5:hover&lt;/code&gt;, &lt;code&gt;1&lt;/code&gt;, &lt;code&gt;2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Child knows what numeric position we're asking for because state cascades, &lt;code&gt;:has()&lt;/code&gt; lifts the value because the child presented the corresponding digit for us to &lt;code&gt;:hover&lt;/code&gt; and read at &lt;code&gt;:root&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The CPU Hack accumulates it into one value then tells the child to stop reporting after the ones position is saved.&lt;/p&gt;

&lt;p&gt;The HTML in the demo linked above reveals a bit of what setup is required for that. The CSS code for it is here in &lt;a href="https://unpkg.com/css-api-fetch@1/api-fetch.css" rel="noopener noreferrer"&gt;v1 of css-api-fetch&lt;/a&gt;.&lt;/p&gt;



&lt;p&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Second Public Demonstration - Cross Browser, no :root
&lt;/h2&gt;

&lt;p&gt;The only difference here is that I don't lift it to :root and instead leave it in the container, DX requires you to wrap all of your content that needs access to the data in an absolutely positioned element inside of the hack's context.&lt;/p&gt;

&lt;p&gt;In my original exposition I mentioned that I wanted to avoid this scenario, but it's cross browser and it has its uses too. Plus, it's not like you &lt;em&gt;can't&lt;/em&gt; build your whole app inside the specific html setup.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codepen.io/propjockey/pen/EaYvdey" rel="noopener noreferrer"&gt;You can see in the HTML tab&lt;/a&gt; just how much less effort is involved in there.&lt;/p&gt;

&lt;p&gt;Just &lt;a href="https://github.com/propjockey/css-api-fetch/blob/0289b936fd583b71234728d30393a89f9c6abe25/html-templates-compat.md" rel="noopener noreferrer"&gt;4 specific nested html elements&lt;/a&gt; are required in the cross-browser version, then you build anything you want using your response data inside of that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Third Public Demonstration - Chrome Only, :root, trivial
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://front-end.social/@kizu/113732033335417449" rel="noopener noreferrer"&gt;Kizu mentioned it might be possible to simplify&lt;/a&gt; so I went digging, then after not quite putting the dots together, &lt;a href="https://front-end.social/@css/113732421808915352" rel="noopener noreferrer"&gt;T. Afif showed a possible way in that direction&lt;/a&gt;, I learned a ton from that article but was unsatisfied with the division and precision loss so I dove into the articles and &lt;a href="https://scroll-driven-animations.style/tools/view-timeline/ranges/" rel="noopener noreferrer"&gt;amazing tools&lt;/a&gt; &lt;a href="https://front-end.social/@bramus" rel="noopener noreferrer"&gt;Bramus&lt;/a&gt; made and came up with a variation that satisfied my use cases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codepen.io/propjockey/pen/JoPyxrK" rel="noopener noreferrer"&gt;As you can see in the CodePen's HTML&lt;/a&gt; the setup is so simple it's literally &lt;a href="https://github.com/propjockey/css-api-fetch/tree/0289b936fd583b71234728d30393a89f9c6abe25?tab=readme-ov-file#adding-the-html" rel="noopener noreferrer"&gt;one line of HTML&lt;/a&gt; to fetch and your response data is on &lt;code&gt;:root&lt;/code&gt;. In this case I used a second element to present the data too. AMAZING!&lt;/p&gt;

&lt;p&gt;I &lt;a href="https://www.npmjs.com/package/css-api-fetch" rel="noopener noreferrer"&gt;packaged it up for a v3 release&lt;/a&gt; making all the handoff mindless, putting the measuring stuff off screen already set up since it's not important.&lt;/p&gt;

&lt;p&gt;I posted about the release, then &lt;a href="https://front-end.social/@css/113736016084195154" rel="noopener noreferrer"&gt;T. Afif linked a different article demonstrating a similar view-timeline configuration for measuring&lt;/a&gt; that I worked out for this - without the division! :)&lt;/p&gt;

&lt;p&gt;I highly recommend reading all the work I've linked above, there's some exciting, talented CSS people sharing their ideas -- and knowing something is possible opens entire worlds of cool ideas!&lt;/p&gt;

&lt;h2&gt;
  
  
  What is &lt;code&gt;css-api-fetch&lt;/code&gt; doing?
&lt;/h2&gt;

&lt;p&gt;Importing &lt;a href="https://www.npmjs.com/package/css-api-fetch" rel="noopener noreferrer"&gt;css-api-fetch&lt;/a&gt; and adding a single line of html, you can fairly easily do API requests in your CSS and not have to consider the complexity of view-timeline yourself. I made it so you don't have to think about it, but for the curious, here's the concept and setup the library uses internally:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Two animations setting a --ints &lt;code&gt;from&lt;/code&gt; the max values your API will respond with &lt;code&gt;to&lt;/code&gt; 0&lt;/li&gt;
&lt;li&gt;host (scope) the animations and their timelines on &lt;code&gt;:root&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;create a measuring element sized to the max values your API will respond with, with non-static position, overflow hidden, etc to make it suitable for reading view/scroll positions.&lt;/li&gt;
&lt;li&gt;Throw it absolute offscreen to the top left so it doesn't cause scrollbars on your app.&lt;/li&gt;
&lt;li&gt;load the image &lt;code&gt;url()&lt;/code&gt; inside of a nested &lt;code&gt;size&lt;/code&gt; &lt;code&gt;container&lt;/code&gt;'s pseudo element's &lt;code&gt;content&lt;/code&gt; and set &lt;code&gt;view-timeline&lt;/code&gt;s for both &lt;code&gt;inline&lt;/code&gt; and &lt;code&gt;block&lt;/code&gt; corresponding to the animations in step 1&amp;amp;2.&lt;/li&gt;
&lt;li&gt;The animations now report the size of the image to the whole document&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's a demonstration of all 6 of the steps above, step 4 is commented out so you can see it. We'll use &lt;a href="https://picsum.photos/" rel="noopener noreferrer"&gt;Lorem Picsum&lt;/a&gt; to emulate specific height &amp;amp; width api responses easily.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/a2f529ef98795bf645ce489bc2e8ffef?height=600&amp;amp;default-tab=css,result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;That's the fundamentals but the library sets up &lt;a href="https://github.com/propjockey/css-api-fetch/tree/main?tab=readme-ov-file#customize-api-endpoints-in-the-css-root-version" rel="noopener noreferrer"&gt;4 separate API request/responses&lt;/a&gt; that you can use simultaneously without knowing how it works.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's &lt;code&gt;css-bin-bits&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;All 3 of the public releases have demonstrations that use a library I made ages ago, &lt;a href="https://propjockey.github.io/css-bin-bits/" rel="noopener noreferrer"&gt;css-bin-bits&lt;/a&gt; that makes it super easy to do bitwise operations on 16 bit integers in 100% CSS and you don't usually have to write any calc() yourself - the library takes care of it all. For the 32 bit IP Address, using &lt;code&gt;css-bin-bits&lt;/code&gt; I was able to limit the size of the image to exactly 16 bits on a single dimension.&lt;/p&gt;

&lt;p&gt;Without bitpacking the 32 bit IP Address into two 16 bit values, &lt;a href="https://front-end.social/@css/113736545957058158" rel="noopener noreferrer"&gt;T. Afif demonstrates&lt;/a&gt; you could use a &lt;code&gt;255255px by 255255px&lt;/code&gt; measuring container and split the response data out with decimal math - skipping &lt;code&gt;css-bin-bits&lt;/code&gt;. &lt;code&gt;css-api-fetch&lt;/code&gt; supports you setting any maximum, shipping with &lt;code&gt;99999&lt;/code&gt; as the default maximum, much more than 16 bits (65535), but not quite &lt;code&gt;255255&lt;/code&gt; lol.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you set up an API to respond with data in the image?
&lt;/h2&gt;

&lt;p&gt;The lightest and most trivial way to pack data into the width and height of an image is to make the server respond with a bare-minimum SVG.&lt;/p&gt;

&lt;p&gt;Here's how the IP address is packed and served in PHP, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
  &lt;span class="nb"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Content-type: image/svg+xml'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nv"&gt;$adr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$_SERVER&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'REMOTE_ADDR'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="s1"&gt;'255.255.255.255'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;$hex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str_pad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;implode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;array_map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'dechex'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;explode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;preg_replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/[^\d\.]/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$adr&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))),&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;STR_PAD_LEFT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="cm"&gt;/* rx returns first 4 hex chars, removing up to 3 leading 0's */&lt;/span&gt;
  &lt;span class="nv"&gt;$width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;hexdec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;preg_replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/(^0{0,3})|(.{4}$)/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$hex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="s1"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="cm"&gt;/* rx returns the last 4 hex chars, removing up to 3 leading 0's */&lt;/span&gt;
  &lt;span class="nv"&gt;$height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;hexdec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;preg_replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/^.{4}0{0,3}/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$hex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="s1"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;svg xmlns="http://www.w3.org/2000/svg" width="'&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$width&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'px" height="'&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$height&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'px"&amp;gt;&amp;lt;/svg&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The API requests you set up could easily accomplish a handful of low hanging fruit that CSS can't otherwise do without JavaScript&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RNG &lt;/li&gt;
&lt;li&gt;Current Time&lt;/li&gt;
&lt;li&gt;TimeZone &lt;/li&gt;
&lt;li&gt;Country Code&lt;/li&gt;
&lt;li&gt;Operating System&lt;/li&gt;
&lt;li&gt;or connection to any other api if you wrap it - such as &lt;a href="https://chess-api.com/" rel="noopener noreferrer"&gt;chess-api&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What comes next?
&lt;/h2&gt;

&lt;p&gt;Chess?!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5n35loivqlijw3anuk27.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5n35loivqlijw3anuk27.png" alt="Screenshot of an early build of an unreleased Chess game with a bit of code on the left indicating specific openings such as king's pawn and queen's pawn. The board shows an opening move has been played by white, it's the Reti Opening, Nf3" width="800" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not yet! Plus, Lilian has already made Chess in CSS!&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1838643820428165565-495" src="https://platform.twitter.com/embed/Tweet.html?id=1838643820428165565"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1838643820428165565-495');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1838643820428165565&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;I'm not sure how it works or if there's a publicly available demo, but I'm sure she'd answer any questions! :)&lt;/p&gt;




&lt;p&gt;For now, my excitement is focused elsewhere......&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I want more than 32 bits per request.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I want 512 bits per request.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flyvict2cu9jb742mui6b.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flyvict2cu9jb742mui6b.gif" alt="Gif showing a bunch of integer data being set one at a time in a harsh terminal appearance" width="726" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No JavaScript.&lt;/p&gt;




&lt;h2&gt;
  
  
  Open Contact 👽
&lt;/h2&gt;

&lt;p&gt;Please do reach out if you need help with any of this, have feature requests, want to share what you've created, or wish to learn more.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PropJockey.io&lt;/th&gt;
&lt;th&gt;CodePen&lt;/th&gt;
&lt;th&gt;DEV Blog&lt;/th&gt;
&lt;th&gt;GitHub&lt;/th&gt;
&lt;th&gt;Mastodon&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://propjockey.io" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fpropjockey-lines.svg" alt="PropJockey.io" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://codepen.io/propjockey" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fcodepen.svg" alt="CodePen" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/janeori"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fdev.svg" alt="DEV Blog" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/propjockey" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fgithub.svg" alt="GitHub" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://front-end.social/@JaneOri" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fmastodon.svg" alt="Mastodon" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://bsky.app/profile/janeori.propjockey.io" rel="noopener noreferrer"&gt;🦋@JaneOri.PropJockey.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://x.com/jane0ri" rel="noopener noreferrer"&gt;𝕏@Jane0ri&lt;/a&gt;&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>hacking</category>
      <category>api</category>
    </item>
    <item>
      <title>CSS Type Casting to Numeric: tan(atan2()) Scalars</title>
      <dc:creator>Jane Ori</dc:creator>
      <pubDate>Mon, 09 Oct 2023 05:48:34 +0000</pubDate>
      <link>https://dev.to/janeori/css-type-casting-to-numeric-tanatan2-scalars-582j</link>
      <guid>https://dev.to/janeori/css-type-casting-to-numeric-tanatan2-scalars-582j</guid>
      <description>&lt;p&gt;In current browser implementations of CSS, you cannot divide by length types; &lt;code&gt;calc(100vw / 5px)&lt;/code&gt; does not work. It will eventually because &lt;a href="https://www.w3.org/TR/css-values-4/#calc-type-checking" rel="noopener noreferrer"&gt;it's in the spec&lt;/a&gt;, and &lt;a href="https://github.com/web-platform-tests/interop/issues/513" rel="noopener noreferrer"&gt;with enough support it may happen soon&lt;/a&gt;. But for now, no way to produce scalars based on size.&lt;/p&gt;

&lt;p&gt;With, technically, one up-and-coming exception, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/atan2" rel="noopener noreferrer"&gt;&lt;code&gt;atan2()&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://caniuse.com/mdn-css_types_atan2" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F417b276cdr1mkrvyvq21.png" alt="screenshot of caniuse data for atan2 showing 87.25% support" width="800" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;atan2()&lt;/code&gt; accepts 2 params, effectively the slope, rise over run, y divided by x, &lt;code&gt;atan2(height, width)&lt;/code&gt; and returns the angle from the bottom of the slope looking to the top.&lt;/p&gt;

&lt;p&gt;Then, did you know? &lt;code&gt;tan(atan2(height, width))&lt;/code&gt; is the scalar &lt;code&gt;&amp;lt;number&amp;gt;&lt;/code&gt; between the two dimensions.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;No, I did not know that; is that true?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's right... One could scale all kinds of dimensions, using simple trigonometry functions.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Really...?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If one were so &lt;em&gt;inclined&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  tan(atan2()) is just a scalar
&lt;/h2&gt;

&lt;p&gt;No need to dive into normal trig things; pretty graphs, maps, and geometric art, etc.&lt;/p&gt;

&lt;p&gt;Fundamentally, &lt;code&gt;tan(atan2())&lt;/code&gt; is just a scalar between two dimensions.&lt;/p&gt;

&lt;p&gt;For this article I'll focus on identity scaling as a means to typecast into a numeric value but there are many ways to use this and compare any two dimensions now.&lt;/p&gt;




&lt;h3&gt;
  
  
  Screensize
&lt;/h3&gt;

&lt;p&gt;One thing many people want is the ability to have the numeric pixel width (or height) of the viewport to find the aspect-ratio or do other calcs down the line.&lt;/p&gt;

&lt;p&gt;I solved screensize in 100% CSS previously with a binary search using &lt;a href="https://dev.to/janeori/expert-css-the-cpu-hack-4ddj"&gt;The CPU Hack&lt;/a&gt; but I realized today it's so much easier and faster with &lt;code&gt;tan(atan2())&lt;/code&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What is the numeric pixel value of 100vw?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;should be as easy as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--px-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;tan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;atan2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100vw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but atan2 is super buggy in browsers right now. (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/atan2#parameters" rel="noopener noreferrer"&gt;mixing vw and px was intended to work&lt;/a&gt;)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Chrome returns &lt;code&gt;100&lt;/code&gt; in this case, &lt;a href="https://bugs.chromium.org/p/chromium/issues/detail?id=1491662" rel="noopener noreferrer"&gt;which is strange/undesirable&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Firefox returns &lt;code&gt;0&lt;/code&gt; in this case because of the mixed units failing. If both are &lt;code&gt;vw&lt;/code&gt; or both are &lt;code&gt;px&lt;/code&gt;, Firefox correctly returns &lt;code&gt;100&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Safari seems to &lt;em&gt;always&lt;/em&gt; return &lt;code&gt;0&lt;/code&gt; from &lt;code&gt;tan(atan2(Y, X))&lt;/code&gt;  for &lt;em&gt;any&lt;/em&gt; &lt;code&gt;Y&lt;/code&gt; and &lt;em&gt;any&lt;/em&gt; &lt;code&gt;X&lt;/code&gt;. With or without units, mixed or matching. (edit: &lt;a href="https://bugs.webkit.org/show_bug.cgi?id=263000" rel="noopener noreferrer"&gt;Unless you wrap it in calc()&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So for now we first need &lt;code&gt;100vw&lt;/code&gt; as &lt;code&gt;NNNpx&lt;/code&gt;, which is easy in CSS because that's what happens automatically if you register a var as &lt;code&gt;&amp;lt;length&amp;gt;&lt;/code&gt; then set it to a value like &lt;code&gt;--100vw: 100vw&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@property&lt;/span&gt; &lt;span class="n"&gt;--100vw&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;syntax&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"&amp;lt;length&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;initial-value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;inherits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now this works in Chrome exactly as hoped:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--100vw&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--px-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;tan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;atan2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--100vw&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;--px-width&lt;/code&gt; is the width of the screen as a, usually integer, number&lt;/p&gt;

&lt;p&gt;here it is live including one for &lt;code&gt;100vh&lt;/code&gt; too:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/6a0d83e6c3dd0eacdfa35cd736a26d83?height=600&amp;amp;default-tab=css,result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h3&gt;
  
  
  get font-size and more
&lt;/h3&gt;

&lt;p&gt;You can use this same idea for any container query units, calc sizes containing mixed units, find out the px size of rem, anything you want. Just register a length, set its value, and convert to numeric px with &lt;code&gt;tan(atan2())&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/58bff61364b7fbdd344bd0ac6a71dd45?height=600&amp;amp;default-tab=css,result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Easy peasy! Potentially super useful.&lt;/p&gt;

&lt;p&gt;Works with &lt;code&gt;&amp;lt;time&amp;gt;&lt;/code&gt; too&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:root::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--ms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;tan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;atan2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;12s&lt;/span&gt; &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1ms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1ms&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="nl"&gt;counter-reset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--ms&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"Numeric ms value of 12s + 1ms is: "&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c"&gt;/* counter prints 12001 */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all numeric typecasting identity scalars, and it's fun to think about all the ways you can mix calcs now, but there's even more cool stuff tan-atan2 can-a-can-do, perhaps for a future article ~&lt;/p&gt;




&lt;h2&gt;
  
  
  The Trig (update)
&lt;/h2&gt;

&lt;p&gt;The trig behind this isn't necessary to know to use it, but I had a couple questions come up in private about it:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tan( angle )&lt;/code&gt; is a &lt;a href="https://en.wikipedia.org/wiki/Trigonometric_functions#Right-angled_triangle_definitions" rel="noopener noreferrer"&gt;function&lt;/a&gt; that takes an angle then produces a result that's equal to "opposite over adjacent" - the height divided by the width of a right triangle:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdoia1yad6ya0wpp4a3c3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdoia1yad6ya0wpp4a3c3.png" alt="a right triangle with a shorter height than width, the hypotenuse bisects the image from the top left to the bottom right, the left side is labeled " width="757" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;atan( ratio )&lt;/code&gt; is a &lt;a href="https://en.wikipedia.org/wiki/Inverse_trigonometric_functions" rel="noopener noreferrer"&gt;function&lt;/a&gt; that takes the value of height divided by width and returns the angle; the inverse of &lt;code&gt;tan()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;atan2( Y, X )&lt;/code&gt; is a &lt;a href="https://en.wikipedia.org/wiki/Atan2" rel="noopener noreferrer"&gt;programming language's adaptation of atan()&lt;/a&gt; that takes the height (Y) and width (X) as separate arguments instead of dividing them before passing, then returns the same thing atan would have.&lt;/p&gt;

&lt;p&gt;So what this trick is doing is kind of silly in most worlds (and probably why nobody pointed it out sooner) because we're using two trig functions instead of division that &lt;code&gt;calc()&lt;/code&gt; implementations can't do yet.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;atan2( Height, Width )&lt;/code&gt; = &lt;code&gt;angle&lt;/code&gt; from the picture above&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tan( angle )&lt;/code&gt; = &lt;code&gt;Height / Width&lt;/code&gt; from the picture above&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tan( atan2( Height, Width ) )&lt;/code&gt; = &lt;code&gt;Height / Width&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@property&lt;/span&gt; &lt;span class="n"&gt;--MyFullInlineSize&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;syntax&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"&amp;lt;length&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;initial-value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;inherits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;@property&lt;/span&gt; &lt;span class="n"&gt;--MyEm&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;syntax&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"&amp;lt;length&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;initial-value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;inherits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="nc"&gt;.in-a-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--MyFullInlineSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="n"&gt;cqi&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--MyEm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--MyNumEmsWide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;tan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;atan2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--MyFullInlineSize&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--MyEm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="py"&gt;--MyNumPxWide&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;tan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;atan2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--MyFullInlineSize&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="m"&gt;1px&lt;/span&gt;
  &lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The End
&lt;/h2&gt;

&lt;p&gt;If you think this is useful, fun, or interesting, it's the kind of thing I do in my free time! So please do consider following me around the web:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PropJockey.io&lt;/th&gt;
&lt;th&gt;CodePen&lt;/th&gt;
&lt;th&gt;DEV Blog&lt;/th&gt;
&lt;th&gt;GitHub&lt;/th&gt;
&lt;th&gt;Mastodon&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://propjockey.io" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fpropjockey-lines.svg" alt="PropJockey.io" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://codepen.io/propjockey" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fcodepen.svg" alt="CodePen" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/janeori"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fdev.svg" alt="DEV Blog" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/propjockey" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fgithub.svg" alt="GitHub" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://front-end.social/@JaneOri" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fmastodon.svg%3F" alt="Mastodon" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;and &lt;a href="https://x.com/jane0ri" rel="noopener noreferrer"&gt;𝕏@Jane0ri&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👽💜&lt;br&gt;
// Jane Ori&lt;/p&gt;




&lt;p&gt;PS: I've been laid off recently and am looking for a job!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://linkedin.com/in/JaneOri" rel="noopener noreferrer"&gt;https://linkedin.com/in/JaneOri&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Over 13 years of full stack (mostly JS) engineering work and consulting, ready for the right opportunity!&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>hacking</category>
      <category>howto</category>
    </item>
    <item>
      <title>[CSS Fix] When justify-content: space-evenly overflows, un-center the content</title>
      <dc:creator>Jane Ori</dc:creator>
      <pubDate>Tue, 26 Sep 2023 14:42:27 +0000</pubDate>
      <link>https://dev.to/janeori/css-fix-when-justify-content-space-evenly-overflows-un-center-the-content-4l50</link>
      <guid>https://dev.to/janeori/css-fix-when-justify-content-space-evenly-overflows-un-center-the-content-4l50</guid>
      <description>&lt;p&gt;Bramus has shown us a clever scroll animation based &lt;a href="https://github.com/propjockey/css-sweeper#basics-of-space-toggle" rel="noopener noreferrer"&gt;Space Toggle&lt;/a&gt; that allows our styles to respond based on weather the element can scroll or not.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.bram.us/2023/09/16/solved-by-css-scroll-driven-animations-detect-if-an-element-can-scroll-or-not/" rel="noopener noreferrer"&gt;https://www.bram.us/2023/09/16/solved-by-css-scroll-driven-animations-detect-if-an-element-can-scroll-or-not/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pop over there to see how it works, continue here to see how I've used it ~&lt;/p&gt;




&lt;h2&gt;
  
  
  When we use space-evenly
&lt;/h2&gt;

&lt;p&gt;When content spans the full width of your page in columns, like itineraries, house banners, etc,&lt;br&gt;
&lt;code&gt;justify-content: space-evenly;&lt;/code&gt; is subjectively the best looking layout for it.&lt;/p&gt;

&lt;p&gt;(that's .&lt;code&gt;justify-evenly&lt;/code&gt; if you tailwind)&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/2efa1cfd97260f464e111f1104ee239d?height=600&amp;amp;default-tab=result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  What space-evenly breaks
&lt;/h2&gt;

&lt;p&gt;If a column section is set to space-evenly but the code allows more columns to be added and scrolled horizontally, you'd probably expect &lt;code&gt;overflow-x: auto;&lt;/code&gt; to do it well.&lt;/p&gt;

&lt;p&gt;Here's 7 columns with &lt;code&gt;overflow-x: auto;&lt;/code&gt; and the same code as shown previously:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/2a57fee9c51d8d2a1711b0a6dadeb1ac?height=600&amp;amp;default-tab=result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;At least 1.7 columns are totally inaccessible, scrolled off to the left in the unreachable negative scroll positions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why space-evenly breaks on overflow
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/67111711/how-not-to-overflow-on-the-left-when-using-justify-content-space-evenly/67115137#67115137" rel="noopener noreferrer"&gt;This answer on stackoverflow does a great job&lt;/a&gt; explaining the 'why':&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I found the &lt;a href="https://www.w3.org/TR/css-align-3/#distribution-values" rel="noopener noreferrer"&gt;CSS specs&lt;/a&gt; describe a "fallback alignment" in case the spacing cannot be applied. For space-between this is start whereas for space-evenly this is center, unfortunately. This explains the observed overlap difference.&lt;/p&gt;

&lt;p&gt;Nevertheless, the spec also mentions&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A future level of this module may allow the fallback alignment to be specified explicitly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;so perhaps with time we may be able to set the fallback to start.&lt;/p&gt;

&lt;p&gt;Until that time I've found a workaround: set min-width on the container. To avoid excessive width, wrap the container in a scrolling parent element. &lt;a href="https://jsfiddle.net/oL7yke6g/" rel="noopener noreferrer"&gt;Demo here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;author: &lt;a href="https://stackoverflow.com/users/2290493/paul" rel="noopener noreferrer"&gt;Paul&lt;/a&gt;&lt;/p&gt;


&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Where is the CSS-Only fix to space-evenly overflows?!
&lt;/h2&gt;

&lt;p&gt;It starts &lt;a href="https://www.bram.us/2023/09/16/solved-by-css-scroll-driven-animations-detect-if-an-element-can-scroll-or-not/" rel="noopener noreferrer"&gt;in this article from Bramus&lt;/a&gt;, then adapting his Space Toggle into our solution, we create a class to replace &lt;code&gt;.justify-evenly&lt;/code&gt; here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;detect-scroll&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;--can-scroll&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.justify-evenly-until-scroll&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--start-if-can-scroll&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--can-scroll&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;--start-if-can-scroll&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;space-evenly&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;detect-scroll&lt;/span&gt; &lt;span class="n"&gt;linear&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;animation-timeline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;scroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt; &lt;span class="nb"&gt;inline&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Making a note here, huge success - and we added &lt;code&gt;inline&lt;/code&gt; to the &lt;code&gt;animation-timeline: scroll(self inline)&lt;/code&gt; to make it respond to horizontal scroll instead.&lt;/p&gt;

&lt;p&gt;Swap &lt;code&gt;.justify-evenly&lt;/code&gt; in the html with our new &lt;code&gt;.justify-evenly-until-scroll&lt;/code&gt; and you get:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/9b20183c3a6daa1c426c568777a50d3a?height=600&amp;amp;default-tab=result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Hooray!&lt;/p&gt;

&lt;h2&gt;
  
  
  Who am I?
&lt;/h2&gt;

&lt;p&gt;If you think this is useful, fun, or interesting, it's the kind of thing I do in my free time! So please do consider following me here, &lt;a href="https://codepen.io/propjockey" rel="noopener noreferrer"&gt;on CodePen&lt;/a&gt;, and &lt;a href="https://twitter.com/Jane0ri" rel="noopener noreferrer"&gt;on X&lt;/a&gt; as well!&lt;/p&gt;

&lt;p&gt;👽💜&lt;br&gt;
// Jane Ori&lt;/p&gt;



&lt;p&gt;PS: I've been laid off recently and am looking for a job!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://linkedin.com/in/JaneOri" rel="noopener noreferrer"&gt;https://linkedin.com/in/JaneOri&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Over 13 years of full stack (mostly JS) engineering work and consulting, ready for the right opportunity!&lt;/p&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;PropJockey.io&lt;/th&gt;
&lt;th&gt;CodePen&lt;/th&gt;
&lt;th&gt;DEV Blog&lt;/th&gt;
&lt;th&gt;GitHub&lt;/th&gt;
&lt;th&gt;X&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://propjockey.io" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fpropjockey-lines.svg" alt="PropJockey.io" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://codepen.io/propjockey" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fcodepen.svg" alt="CodePen" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dev.to/janeori"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fdev.svg" alt="DEV Blog" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/propjockey" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fgithub.svg" alt="GitHub" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://x.com/jane0ri" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fpropjockey%2Fpropjockey-brand%2Fmain%2Fexternal-social%2F100px%2Fx.svg" alt="X" width="100" height="100"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;p&gt;UPDATE:&lt;/p&gt;


&lt;h2&gt;
  
  
  Wait? Nope! Continue, but, heads up:
&lt;/h2&gt;

&lt;p&gt;Bramus (and someone privately) informed me of a new feature with a slight superset of browser support over animation scroll():&lt;/p&gt;

&lt;p&gt;justify-content's &lt;code&gt;safe&lt;/code&gt; keyword&lt;/p&gt;

&lt;p&gt;&lt;a href="https://drafts.csswg.org/css-align-3/#overflow-values" rel="noopener noreferrer"&gt;https://drafts.csswg.org/css-align-3/#overflow-values&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It currently works with &lt;code&gt;justify-content: center safe;&lt;/code&gt; but if you specifically want &lt;code&gt;space-evenly&lt;/code&gt; (I do!), this hack is currently the only working solution.&lt;/p&gt;

&lt;p&gt;All the previous demos use grid, here it is with flex, first using &lt;code&gt;space-evenly safe&lt;/code&gt; which doesn't do anything yet. Then, further down, same hack as used on the grid demos above, also works on flex.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/bGOMgjy?height=600&amp;amp;default-tab=result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

</description>
      <category>css</category>
      <category>howtofix</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Expert CSS: The CPU Hack</title>
      <dc:creator>Jane Ori</dc:creator>
      <pubDate>Sun, 17 Sep 2023 03:33:01 +0000</pubDate>
      <link>https://dev.to/janeori/expert-css-the-cpu-hack-4ddj</link>
      <guid>https://dev.to/janeori/expert-css-the-cpu-hack-4ddj</guid>
      <description>&lt;p&gt;A "CPU Hack" implies unlocking the ability for continuous crunching of data and re-evaluation of state.&lt;/p&gt;

&lt;p&gt;For example, if cyclic vars didn't automatically fail to invalid (&lt;code&gt;initial&lt;/code&gt;) state in CSS, this would continuously increment the value of &lt;code&gt;--frame-count&lt;/code&gt; here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--input-frame&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--frame-count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;--frame-count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--input-frame&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Spoiler alert: You actually &lt;em&gt;can&lt;/em&gt; do this in CSS, without ever touching JS, I'll show you how!&lt;/p&gt;

&lt;h2&gt;
  
  
  The 5 Observables
&lt;/h2&gt;

&lt;p&gt;First, let's establish a handful of observations of advanced CSS animation usage so the final demonstration isn't entirely unexpected.&lt;/p&gt;

&lt;p&gt;Not directly related to "&lt;a href="https://www.youtube.com/watch?v=sstBSuXIW0I" rel="noopener noreferrer"&gt;The 5 Observables&lt;/a&gt;"&lt;/p&gt;




&lt;h3&gt;
  
  
  1. Animation State Rules Over All (almost)
&lt;/h3&gt;

&lt;p&gt;The property assignments set by Animation State trump all Selector State property assignments.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;body background is always &lt;code&gt;hotpink&lt;/code&gt; in this example:&lt;/p&gt;


&lt;pre class="highlight css"&gt;&lt;code&gt;  &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;green&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="nd"&gt;:has&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;hotpink&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;p&gt;This is (partially) why Animation State is not allowed to alter properties that control animations. As in, you cannot&lt;sup&gt;[1]&lt;/sup&gt; animate the value of &lt;code&gt;animation-play-state&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;(otherwise, once started, a self-setting animation could only be stopped by JS removal of the element it lives on since the animation could set its own &lt;code&gt;animation&lt;/code&gt; value and stay alive no matter what other selector states tried to stop it.&lt;sup&gt;[2]&lt;/sup&gt;)&lt;/p&gt;

&lt;p&gt;Paused animations are no exception; whatever the value is when it's paused still trumps other states.&lt;/p&gt;

&lt;p&gt;[1] Technically there's an unrelated hack that allows this, dealing with inheritance and invalid compute states, but the animation-frame timing of that hack is unreliable for CPU ticking.&lt;/p&gt;

&lt;p&gt;[2] This is what went wrong with Ultron.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Property Assignments in a Keyframe Can Use var()
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;green&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="nd"&gt;:has&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the background color is &lt;code&gt;blue&lt;/code&gt; by default, &lt;code&gt;green&lt;/code&gt; if hovering, or &lt;code&gt;red&lt;/code&gt; if hovering specifically within a div. The color changes as the user interacts.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. --var Assignments on Keyframe Results are Cached
&lt;/h3&gt;

&lt;p&gt;We can test this by adding a little indirection to the background color assignment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--bg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;green&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="nd"&gt;:has&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;--bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No matter what, the background is always &lt;code&gt;blue&lt;/code&gt; because it first evaluated as &lt;code&gt;blue&lt;/code&gt; and changes to &lt;code&gt;--color&lt;/code&gt; are not re-computed.&lt;/p&gt;

&lt;p&gt;Even if the animation is &lt;code&gt;paused&lt;/code&gt;, the cached value does not change when states in the background change.&lt;/p&gt;

&lt;p&gt;(paused animations use the cached value)&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Changing An Animation Property Breaks The Cache
&lt;/h3&gt;

&lt;p&gt;By altering the &lt;code&gt;animation-duration&lt;/code&gt; while the user :hovers, the animation cache is recomputed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--bg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;green&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="nd"&gt;:has&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;--bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The end result here is exactly the same as in #2 above; the background color is &lt;code&gt;blue&lt;/code&gt; by default, &lt;code&gt;green&lt;/code&gt; if hovering, or &lt;code&gt;red&lt;/code&gt; if hovering specifically within a div.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Safari has a bug where it does NOT recompute the cache when an animation property changes, so we've entered Chrome-only territory (firefox can't animate --vars yet)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If we "changed" the &lt;code&gt;animation-duration&lt;/code&gt; to &lt;code&gt;1s&lt;/code&gt;, it would not technically change, and the cache does not recompute.&lt;/p&gt;

&lt;p&gt;You begin to get interesting behavior if both :hover states use the same value that's different from the default state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="nd"&gt;:has&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's show this one live:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/6fcc512d52cd936640f44dfbdd17cda1?height=600&amp;amp;default-tab=css,result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;depending on where your mouse enters the screen (from the top vs bottom), you'll get different colors that "lock" to one or the other until you mouse out.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Two Animations
&lt;/h3&gt;

&lt;p&gt;What if instead of pseudo selector state changing the value of &lt;code&gt;--color&lt;/code&gt;, we made another animation that changed it?&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;example&lt;/code&gt; animation still sets &lt;code&gt;--bg&lt;/code&gt; based on &lt;code&gt;--color&lt;/code&gt;, so we can expect it to still have the same caching behavior.&lt;/p&gt;

&lt;p&gt;Changing an animation property of our &lt;code&gt;example&lt;/code&gt; animation should also, still, cause it to recompute its cache.&lt;/p&gt;

&lt;p&gt;So, finally, the &lt;code&gt;example&lt;/code&gt; animation should accept whatever the current &lt;code&gt;--color&lt;/code&gt; value is from another animation and cache it with its state.&lt;/p&gt;

&lt;p&gt;Here's what that would look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="m"&gt;3s&lt;/span&gt; &lt;span class="n"&gt;step-end&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--bg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-play-state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;paused&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"color preview"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="err"&gt;33&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;33&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="err"&gt;67&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;green&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;67&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;--bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note: Even though we're pausing the &lt;code&gt;example&lt;/code&gt; animation on :hover, that still constitutes a change from the default &lt;code&gt;running&lt;/code&gt; state so it re-computes and pauses in the same CSS paint frame.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and here's what it feels like:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/3f8b84767d12d3eea5308864ae6ddab6?height=600&amp;amp;default-tab=result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The bg locks to whatever it was when you entered, then re-computes and re-locks to whatever it is when you leave.&lt;/p&gt;

&lt;p&gt;Persistence! NEAT!&lt;/p&gt;




&lt;h2&gt;
  
  
  The CPU Hack Begins
&lt;/h2&gt;

&lt;p&gt;The previous information implies something extremely interesting; grabbing the cached &lt;em&gt;value&lt;/em&gt; from an animation does not recompute it, so it shouldn't cause an invalid cyclic state if the source of the cached value is one step removed.&lt;/p&gt;

&lt;p&gt;Double capture, compute once, manage the timing... Should be possible.&lt;/p&gt;

&lt;p&gt;We have the &lt;code&gt;example&lt;/code&gt; animation conditionally capturing the value from either normal selector states or from another animation.&lt;/p&gt;

&lt;p&gt;Let's imagine it's capturing a number instead of a color, like the &lt;code&gt;--frame-count&lt;/code&gt; from the opening of this article.&lt;/p&gt;

&lt;p&gt;And we'll rename it from &lt;code&gt;example&lt;/code&gt; to &lt;code&gt;capture&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;capture&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="py"&gt;--input-frame&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--frame-count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--input-frame&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;capture&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;--frame-captured&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--frame-count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wouldn't it be great if we could set &lt;code&gt;--input-frame&lt;/code&gt; to that &lt;code&gt;--frame-captured&lt;/code&gt; value?&lt;/p&gt;

&lt;p&gt;We know that doing it directly would be cyclic because all 3 of these assignments exist in the same frame:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--input-frame&lt;/code&gt; = &lt;code&gt;--frame-captured&lt;/code&gt;&lt;br&gt;
&lt;code&gt;--frame-count&lt;/code&gt; = &lt;code&gt;--input-frame&lt;/code&gt; + 1&lt;br&gt;
&lt;code&gt;--frame-captured&lt;/code&gt; = &lt;code&gt;--frame-count&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If we capture the captured value though and make sure both captures aren't running at the same time, the capture-capture could hoist that value back to &lt;code&gt;--input-frame&lt;/code&gt;...&lt;/p&gt;

&lt;p&gt;Let's try. We'll call the captured capture &lt;code&gt;hoist&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Also, since we don't want them ever running at the same time (because that would definitely be cyclic), let's start them off &lt;code&gt;paused&lt;/code&gt; to be safe.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;hoist&lt;/span&gt; &lt;span class="m"&gt;1ms&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;capture&lt;/span&gt; &lt;span class="m"&gt;1ms&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-play-state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;paused&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;paused&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="py"&gt;--input-frame&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--frame-hoist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;--frame-count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--input-frame&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;counter-reset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--frame-count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"--frame-count: "&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;hoist&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;--frame-hoist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--frame-captured&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;capture&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;--frame-captured&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--frame-count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, in order to test this, we also want to set up some dom that we can hover in a specific order to trigger the &lt;code&gt;animation-play-state&lt;/code&gt; in the right order. No gaps between the elements and we'll give them classes &lt;code&gt;phase-0&lt;/code&gt;, etc&lt;/p&gt;

&lt;p&gt;The first phase is definitely capturing the original output. So we'll keep &lt;code&gt;hoist&lt;/code&gt; paused and let our old friend &lt;code&gt;capture&lt;/code&gt; run first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="nd"&gt;:has&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;.phase-0&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-play-state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;paused&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can stop hovering that element to pause both, which will capture &lt;code&gt;--frame-count&lt;/code&gt;, or we can go ahead and set up another element to explicitly do that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="nd"&gt;:has&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;.phase-1&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-play-state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;paused&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;paused&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, finally? The moment of truth, test if we can run &lt;code&gt;hoist&lt;/code&gt; while &lt;code&gt;capture&lt;/code&gt; is paused, which should give us enough room to avoid the cyclic dependency and plop that output back that the top as input... which should give us our first &lt;code&gt;2&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="nd"&gt;:has&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;.phase-2&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-play-state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;paused&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here it is live, :hover the cursor from top to bottom to complete a loop:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/86fc64e923093e4ce9e865bd0c9b8da7?height=600&amp;amp;default-tab=result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  The CPU Hack
&lt;/h2&gt;

&lt;p&gt;Eureka!&lt;/p&gt;

&lt;p&gt;We could make the user pet the dom with their cursor all day orrrr we could move the dom under the cursor the moment it needs to be to automatically trigger :hover&lt;/p&gt;

&lt;p&gt;Let's figure that out!&lt;/p&gt;

&lt;p&gt;We'll need hovering &lt;code&gt;.phase-0&lt;/code&gt; to automatically "goto" &lt;code&gt;.phase-1&lt;/code&gt;, then hovering that will "goto" &lt;code&gt;.phase-2&lt;/code&gt;...&lt;/p&gt;

&lt;p&gt;And then hovering &lt;code&gt;.phase-2&lt;/code&gt; needs to return to a &lt;code&gt;paused, paused&lt;/code&gt; state to avoid any single frame running a compute for both animations at the same time.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Remember: playing or pausing an animation causes it to re-compute on that frame, so changing from &lt;code&gt;running, paused&lt;/code&gt; straight to &lt;code&gt;paused, running&lt;/code&gt; is actually, for one frame, running both at the same time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So we need to "goto" a state that will then "goto" &lt;code&gt;.phase-0&lt;/code&gt;. Since &lt;code&gt;.phase-1&lt;/code&gt; is &lt;code&gt;paused, paused&lt;/code&gt; and "goto" 2, we'll duplicate it and make the new &lt;code&gt;.phase-3&lt;/code&gt; also pause both but "goto" 0 instead.&lt;/p&gt;

&lt;p&gt;Let's add this CSS to what we had:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="nd"&gt;:has&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;.phase-3&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-play-state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;paused&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;paused&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we'll use this for the HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ol&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"cpu"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"phase-0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"phase-1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"phase-2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"phase-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ol&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;/p&gt;
  Here's a recap of each phase if interested
  &lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;.phase-0&lt;/code&gt; (&lt;code&gt;hoist&lt;/code&gt; paused, &lt;code&gt;capture&lt;/code&gt; running)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hoist Value is Frozen&lt;/li&gt;
&lt;li&gt;Assign Captured = Output Value&lt;/li&gt;
&lt;li&gt;GOTO &lt;code&gt;.phase-1&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;.phase-1&lt;/code&gt; (&lt;code&gt;hoist&lt;/code&gt; paused, &lt;code&gt;capture&lt;/code&gt; paused)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hoist Value is Frozen&lt;/li&gt;
&lt;li&gt;Assign Captured Value = Output Value&lt;/li&gt;
&lt;li&gt;Freeze Captured (at the end of this css paint frame)&lt;/li&gt;
&lt;li&gt;GOTO &lt;code&gt;.phase-2&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;.phase-2&lt;/code&gt; (&lt;code&gt;hoist&lt;/code&gt; running, &lt;code&gt;capture&lt;/code&gt; paused)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Captured Value is Frozen&lt;/li&gt;
&lt;li&gt;Assign Hoist Value = Captured Value&lt;/li&gt;
&lt;li&gt;GOTO &lt;code&gt;.phase-3&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;.phase-3&lt;/code&gt; (&lt;code&gt;hoist&lt;/code&gt; paused, &lt;code&gt;capture&lt;/code&gt; paused)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Captured Value is Frozen&lt;/li&gt;
&lt;li&gt;Assign Hoist Value = Captured Value&lt;/li&gt;
&lt;li&gt;Freeze Hoist (at the end of this css paint frame)&lt;/li&gt;
&lt;li&gt;GOTO &lt;code&gt;.phase-0&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Next, we'll style this &lt;code&gt;.cpu&lt;/code&gt; element so each of its children take up its whole area when their width becomes &lt;code&gt;100%&lt;/code&gt;, z-stacked on top of each other in dom order.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.cpu&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;list-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.cpu&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;inset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.cpu&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;.phase-0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.cpu&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;.phase-0&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;.phase-1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.cpu&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;.phase-1&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;.phase-2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.cpu&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;.phase-2&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;.phase-3&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should be the final piece; each phase triggers the next and they'll only happen for one CSS Paint Frame each. Let's see it live!&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/9fbc3990ce135b77c2af8267dbd14a0c?height=600&amp;amp;default-tab=result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: we also needed to register the output var (&lt;code&gt;--frame-count&lt;/code&gt;) or else it will suddenly stop working at 100 because of &lt;code&gt;calc()&lt;/code&gt; technically becoming nested each iteration. Casting it to integer prevents this and is much more efficient. The demo above has the &lt;code&gt;@property&lt;/code&gt; code included.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also, technically, one small cleanup you could make:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Drop the &lt;code&gt;--input-frame&lt;/code&gt; var, just &lt;code&gt;--frame-hoist&lt;/code&gt; directly, it's cleaner.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Rest of the Owl
&lt;/h2&gt;

&lt;p&gt;So you have a CPU in CSS. What can you do with it?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codepen.io/propjockey/pen/ExGXjaE" rel="noopener noreferrer"&gt;100% CSS Compute Integer --width and --height of the Screen&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codepen.io/propjockey/pen/qBQjYxd" rel="noopener noreferrer"&gt;100% CSS Image-Mouse-Coordinate Zoom on Hover&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codepen.io/propjockey/pen/NWEYdjY" rel="noopener noreferrer"&gt;100% CSS Conway's Game of Life Simulator - Infinite Generations, 42x42&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;100% CSS Breakout, play it here:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/propjockey/embed/preview/dywNyBQ?height=600&amp;amp;default-tab=result&amp;amp;theme-id=40148&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  The End!
&lt;/h2&gt;

&lt;p&gt;If you think this is useful, fun, or interesting, it's the kind of thing I do in my free time! So please do consider following me here, &lt;a href="https://codepen.io/propjockey" rel="noopener noreferrer"&gt;on CodePen&lt;/a&gt;, and &lt;a href="https://twitter.com/Jane0ri" rel="noopener noreferrer"&gt;on X&lt;/a&gt; as well!&lt;/p&gt;

&lt;p&gt;👽💜&lt;br&gt;
// Jane Ori&lt;/p&gt;




&lt;p&gt;PS: I've been laid off recently and am looking for a job!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://linkedin.com/in/JaneOri" rel="noopener noreferrer"&gt;https://linkedin.com/in/JaneOri&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Over 13 years of full stack (mostly JS) engineering work and consulting, ready for the right opportunity!&lt;/p&gt;

</description>
      <category>css</category>
      <category>howto</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
