A tool for skeleton + marks Arabic font workflows — would love your feedback

Hi everyone,

My name is Aziz Mohseny. I've built a personal tool called FFB (Font Feature Builder), and I've now reached a stage where technical feedback from this community would be really valuable to me.

The idea:
Instead of drawing a separate glyph for every dotted Arabic letter, we decompose the font into dotless skeletons and separate mark glyphs (dots and diacritics). At runtime, GSUB composes the skeleton and marks, and GPOS positions the marks from anchors.

The goal is to keep glyph counts manageable, let the designer focus only on skeletons, marks, and anchors, and allow them to develop the font without needing a font engineer.

What FFB currently does:

  • Generates GSUB for isol / init / medi / fina

  • Generates GPOS for mark and mkmk

  • Generates curs from Ex / _Ex anchors

  • Includes a browser-based tool (no install) for syncing anchor coordinates from a UFO

I've just published v0.1.0. The code is MIT-licensed, but the sample font glyphs are proprietary and for demonstration only.

In the next stage, I plan to add alternate glyph handling (features like calt and rclt), and also a tool for adjusting kerning of glyphs, dots, and marks. Ideally, I want the dots and marks to be fluid — all emerging from a single, shared fixed origin, while taking their best position relative to neighboring glyphs (contextual GPOS).

What I'm looking for:

  • General feedback on the approach and the generated feature code

  • Reports on any technical issues when compiling or testing

  • Thoughts on whether this method aligns with how you actually build Arabic-script fonts

You can try the tool here:
https://ffb-flame.vercel.app

Repository and release notes:
https://github.com/AzizMohseny/FFB/releases/tag/v0.1.0

I know this is an early version and I'm not claiming it's production-ready. My goal is to understand where this approach breaks down and what you actually need.

Thanks for your time.
— Aziz Mohseny

Note: AI was used to translate and edit this post. All technical content, project details, and design decisions are my own.

Comments

  • Simon Cozens
    Simon Cozens Posts: 886
    edited October 9
    The approach is right. I don't know why anyone wouldn't do that. (Actually, I do: they open a font editor like Glyphs, select "Arabic" and it gives them a big grid of glyphs that they "need" to fill. They don't.) Khaled seems to have removed his classic "just take the dots off" blog post, but it's been the obvious way to make Arabic fonts for years.

    However, the idea behind the tool seems odd:
    • Generates GSUB for isol/init/medi/fina - any font editor which doesn't do that for you is broken and should be fixed.
    • Generates GPOS for mark/mkmk / generates curs from entry and exit anchors - any font compiler which doesn't do that for you is broken and should be fixed.
    • Syncs anchors into the feature file - again unnecessary because the font compiler already does this.
    So I'm not sure what problem you're actually solving.
  • Thanks Simon, this is a really useful point, and I think you're right that I didn't explain the "why" well enough.

    You're absolutely right that any competent font editor or compiler handles isol/init/medi/fina, mark/mkmk, and curs automatically. And for a conventional font — where each encoded letter has its own glyph — that's exactly the right thing to do, and FFB would be pointless.

    But the workflow FFB is built for is different: decomposed fonts. In this model, the encoded letters stay empty, and at runtime GSUB replaces them with a dotless skeleton plus separate mark glyphs. The point is to avoid the glyph explosion you get when every dotted letter, every positional form, and every diacritic combination needs its own glyph.

    The problem is that the moment you go decomposed, the font editor's automatic features stop working — because there's nothing to attach init/medi/fina to. The editor sees an empty glyph and has no idea that this glyph should actually decompose into skeleton + marks. So the feature code has to be generated from somewhere else, and that somewhere is the decomposition table.

    I work in FontLab 8, and I should say upfront that I have no experience with Glyphs — maybe the story is different there. Here's what I've found:

    • FontLab's component feature lets you define a glyph's parts and their anchors, and then it composes a single composite glyph from those anchors. So it's doing essentially what FFB does — but it produces one glyph, not a feature rule. FFB does the same thing, but instead of building a glyph, it builds a feature rule. That's the opposite of decomposition, where what you need at the end is a substitution rule, not a merged glyph. Is there a way for FontLab — or any other font editor — to do this instead?

    • I have never been able to get mark/mkmk to work correctly for Arabic fonts in FontLab. Whatever it generates, it doesn't work.

    • FontLab generates isol/init/medi/fina using Lookup Type 1 (single substitution), but for decomposed fonts you need Lookup Type 2 (multiple substitution) — because the output is not one glyph, it's a sequence of glyphs.

    • Many Arabic type designers I've spoken to do their glyph shapes in FontLab but write the features manually and painfully in VOLT instead. That's the workflow I'm trying to replace.

    I haven't found any documentation showing how to make FontLab produce the correct lookup type for a decomposed Arabic font — or how to set up Arabic kerning in FontLab, or how GPOS features are supposed to be built there. There are checkboxes for the last one, but the result isn't what you'd expect, and what gets generated doesn't actually work. Maybe I'm missing something. Do you know of a way to make FontLab do this — to add a feature rule instead of building a glyph? Maybe there's a path I don't know about. If you know of a way, or a document that explains it, I'd be genuinely grateful.

    That's what FFB does: it reads a decomposition table and writes the fea code that the editor would have written if the font weren't decomposed. It's not replacing the compiler — it's feeding it.

    You're also right that anchor syncing is redundant in a normal workflow. But in the decomposed workflow, the anchors live on the skeleton glyphs, and the generated feature code needs to reference those anchors by name. When the designer moves an anchor in the UFO, that change has to propagate into the .fea before compiling. Without that, the two drift apart. It also lets us use kerning to make dots and diacritics fluid — so they pick the best position relative to their neighboring glyphs.

    Thanks again for taking the time. I'd genuinely love to hear your thoughts on whether this is a real problem worth solving, or whether I'm mistaken and just reinventing the wheel.

  • Simon Cozens
    Simon Cozens Posts: 886
    But the workflow FFB is built for is different: decomposed fonts. In this model, the encoded letters stay empty, and at runtime GSUB replaces them with a dotless skeleton plus separate mark glyphs. The point is to avoid the glyph explosion you get when every dotted letter, every positional form, and every diacritic combination needs its own glyph.
    This is not something that you need to explain to me. :) By the way, having empty encoded letters sometimes mess up "glyph picker" palette windows. It's better to use components in those cases. I do it for some of the minority letters in Noto Nastaliq Urdu, but I should probably use components for those as well. (Especially for those, come to think of it, because they're often hard to keyboard.)
    • I have never been able to get mark/mkmk to work correctly for Arabic fonts in FontLab. Whatever it generates, it doesn't work.

    • FontLab generates isol/init/medi/fina using Lookup Type 1 (single substitution), but for decomposed fonts you need Lookup Type 2 (multiple substitution) — because the output is not one glyph, it's a sequence of glyphs.

    I think this may be the crux of the problem. For the first point, if you can't get mark/mkmk working properly, then... get it working properly! The anchors should just work. If they don't, I think you're probably not driving FontLab properly, but I don't have enough FontLab experience to confirm. I would be amazed if FontLab was unable to attach marks to arbitrary glyphs. I feel pretty sure that something else is wrong.

    The usual way to do it is to take the dots off in ccmp, then fix up the forms in the init/medi/fina (no need for isolation) features. But because you have things like jeem/noon/dad/etc. you do still need to have some multiple substitution rules in there. I agree that a font editor script to help generate those rules would be useful. But it can't be entirely data-driven. For example, in some fonts I prefer to also decompose the gaf sarkash and just deal with gaf as though it were kaf; but in others, I don't do that. Designer preference comes into it.

    But in the decomposed workflow, the anchors live on the skeleton glyphs, and the generated feature code needs to reference those anchors by name.

    I can see this is necessary if you need to write a separate feature file. But you shouldn't need to be doing that. The editor should be handling it. If it isn't, that's the problem that you need to fix.

  • John Hudson
    John Hudson Posts: 3,856
    edited October 9
    I always assume that the feature automation offered by font tools is, at best, a starting place whose results I am going to need to edit, and at worst is completely useless for my purposes because they presuppose that I am building a font in a particular way. So what I understand you to be doing is creating an alternative automation model to build Arabic fonts in a different but still particular way. That’s obviously useful for you and likely useful to some other people.
    Regarding decomposition, for a very long time I have advocated for a new cmap table format that supports one-to-many character to glyph mapping. This would mean that a font wouldn’t need to include any precomposed glyphs or empty glyphs representing encoded characters.

  • This is not something that you need to explain to me. :) By the way, having empty encoded letters sometimes mess up "glyph picker" palette windows. It's better to use components in those cases....

    Thanks Simon. A quick apology first: sorry for over-explaining the bit about empty glyph boxes. I'm in Iran, where I constantly have to spell everything out, and sometimes I forget that I'm talking to professionals here. :)

    1. mark/mkmk — You're right, I'm probably not driving FontLab properly. My experience is incomplete and I need to dig into it more. If it turns out this can actually be done in FontLab, FFB may not even be needed for this part. Do you know of a guide or resource that explains how?

    2. Not being entirely data-driven — I completely agree. You can't automate designer preference. That's why I'm currently developing a part of FFB where the designer can define alternates and the system writes the rules for them, helping the designer place those alternates in the right lookup. It allows changing three related glyphs at once, so the designer can define each glyph individually and FFB will generate the rules. You have far more experience than I do — if a better approach comes to mind, I'd welcome it.

    3. The editor should be handling it — This is a really important point, and I think you're right. If editors could natively support the decomposed workflow, tools like FFB wouldn't be needed at all. But do you think there's any chance the editors (FontLab, Glyphs) will add this? Or does their structure — being glyph-centric rather than data-centric — make that unlikely?

    One last question: in Noto Nastaliq Urdu, as you mentioned, you use components. Could that approach be applied to decomposed fonts too? I mean, instead of empty glyphs, use components and let the editor figure out that it should decompose into skeleton + marks?


  • Azizmohseny
    Azizmohseny Posts: 21
    edited October 10
    I always assume that the feature automation offered by font tools is, at best, a starting place whose results  ...

    Thank you, John. What an interesting idea — I'll be waiting impatiently for that change to cmap. For Arabic fonts, it would be a godsend.

    And what you said about the tables editors provide being a starting point for later editing is exactly right. That's precisely how I designed FFB: to make it easier for the designer to then edit them.


  • John Hudson
    John Hudson Posts: 3,856
    I'll be waiting impatiently for that change to cmap.
    When I first suggested the idea many, many years ago, I was told it is unlikely to be adopted, due to the major changes to core text processing that would be required to support it in apps and operating systems.

    [In the meantime, things like the format 14 cmap for Unicode variation sequences have already been added to OpenType and supported widely.]

  • Simon Cozens
    Simon Cozens Posts: 886
    edited October 10
    Azizmohseny said:
    If editors could natively support the decomposed workflow, tools like FFB wouldn't be needed at all. But do you think there's any chance the editors (FontLab, Glyphs) will add this?

    In answer to this question, I will just note that I have produced several decomposed Arabic fonts in Glyphs without either writing manual mark feature code, or using FFB...  :)


  • In answer to this question, I will just note that I have produced several decomposed Arabic fonts in Glyphs without either writing manual mark feature code, or using FFB...  :)

    Thank you, Simon. I appreciate the smile — and it is a fair point.

    But let me explain why Glyphs is not an option for many of us.

    I am from Iran. Apple has never had an official presence in my country, and its products are not supported here. We have lived under sanctions for years. Even if Glyphs were available, its price would be far beyond the reach of most designers here.

    And this is not just about Iran. Most countries that use the Arabic script are poor countries. Many type designers in these regions earn almost nothing from type design. We are expected to design one of the most complex scripts in the world — and receive almost nothing for it. In my country, the market for selling fonts is less than 10 years old. We have no wealthy type designers. Most of them do type design alongside another job.

    So we depend on free platforms. That is why I started FFB: to create a workflow that does not depend on a specific piece of software, and that helps designers produce fonts faster and more accurately — regardless of where they live or what they can afford.

    I am not trying to compete with Glyphs. I am trying to build something that works for those who cannot use Glyphs at all.

    Thank you again for your time.

    (Note: I used AI assistance for translation and drafting.)
  • I think a decomposed model would work well in Fontra and would certainly work in Counterpunch; one of the fonts that Yanone uses to test Counterpunch (Fustat) is designed in a decomposed way.
  • Thomas Phinney
    Thomas Phinney Posts: 3,210

    This is not something that you need to explain to me. :) By the way, having empty encoded letters sometimes mess up "glyph picker" palette windows. It's better to use components in those cases....

    Thanks Simon. A quick apology first: sorry for over-explaining the bit about empty glyph boxes. I'm in Iran, where I constantly have to spell everything out, and sometimes I forget that I'm talking to professionals here. :)


    It is hard to strike the right balance between the discussion you are having, and the fact that it is in a thread that is going to be read by outside folks who bring less prior knowledge to the topic, but are still interested!

    I sometimes end up prefacing portions of my reply with something like “As you doubtless know, but just for other readers…” (and maybe even put it in parentheses).
     :) 
  • I think a decomposed model would work well in Fontra and would certainly work in Counterpunch; one of the fonts that Yanone uses to test Counterpunch (Fustat) is designed in a decomposed way.
    Thank you, Simon. I will look into both Fontra and Counterpunch.
    The fact that Counterpunch is built around a decomposed model — and that Fustat is designed that way — is very encouraging. I am currently working on a decomposed Arabic font myself, and the question of how to handle kashida at the font layer is central to what I am trying to solve.
    I will report back once I have something to share.
    Thank you again for your time.

    (Note: I used AI assistance for translation and drafting.)
  • It is hard to strike the right balance between the discussion you are having, and the fact that it is in a thread that is going to be read by outside folks who bring less prior knowledge to the topic, but are still interested!
    Thank you, Thomas. That is a very useful reminder — and I appreciate the practical suggestion.

    You are right that there is a tension between the depth of the discussion and the fact that it is read by people with less prior knowledge. I will try to adopt your approach: "As you doubtless know, but just for other readers..."

    Thank you for taking the time to offer this advice.

    (Note: I used AI assistance for translation and drafting.)
  • I think a decomposed model would work well in Fontra and would certainly work in Counterpunch; one of the fonts that Yanone uses to test Counterpunch (Fustat) is designed in a decomposed way.
    Thank you again, Simon, for pointing me to these tools.
    I was already familiar with Fontra. In my view it is still under development and not yet stable enough — and I am not sure it will remain free once it matures.
    Counterpunch, on the other hand, is a wonderful piece of software. It is very well designed. But it still does not fit our situation.
    Let me try to explain the context in the Arabic-script region, so you can understand why.
    As I mentioned before, in most countries of this region, there is no profession called "type designer." Or if there is, it does not offer enough security for anyone to rely on it as their main source of income. In most of these countries, copyright does not exist — or if there is a law, the cost of litigation is so high, and the income from fonts so low, that suing infringers is not worth it. Most people who have designed fonts in this region have learned on an open-source platform. Because there are no structured educational resources for these tools, they have learned them with great difficulty and managed to produce a font.
    On top of this, in most of these countries, the internet is extremely unstable — and you cannot rely on online applications. For example, last year, because of the war, we were without internet for more than five months.
    And now we are told: abandon that, learn a new tool, because it is better — and in a few years, another better tool will come along, and the cycle will repeat.
    What I have built with FFB is aligned with the conditions of this region. I believe it is the right path — because I live here, and I have a deep understanding of the situation. By building a tool that is not tied to a specific platform, I am trying to speed up the font production process.
    Perhaps for you, living in the West, producing one font a year is enough to cover your expenses, and your profession offers high security. But in my country, even if we produced one font per month, it would still not cover the cost of living. The average price of a font here is barely $5. So speed of production matters enormously. Learning a new application and mastering all its aspects takes 6 to 12 months.
    And that is not the only thing I have to do. We still have no legal body to defend our rights. There is no union, no informal association, not even a desk within another organization such as a graphic designers' guild. We have to build these things too — things that you in the West have had two centuries to build.
    There is also no meaningful connection between Arabic type designers in different countries. We do not know each other. We are unaware of each other's experiences. This has been left to the wealthy countries of the region, which occasionally hold festivals. But unfortunately, those who have money lack motivation, and those who have motivation lack money.
    Add to all of this the pride of a multi-thousand-year-old civilization — a pride that does not allow us to place our burden on others. We are eternally grateful to Microsoft and Adobe for enabling us to build fonts like Iran Nastaliq. But the time has come for us to solve our own problems ourselves.
    In this context, the advice and guidance of professional friends like you is the greatest help — and we are always grateful for the time you devote to it.

    (Note: I used AI assistance for translation and drafting.)
  • Simon Cozens
    Simon Cozens Posts: 886
    edited October 11
    Thank you for the additional context. I don't want to discourage you from making your own tools - I think it's very important to dig into font engineering, and if you have come up with a tool which works for you and your own community, and allows you to more easily make fonts, that is the most important thing. I am just concerned that you are spending time solving a "problem" which is caused by not correctly using the tools you already have. I am convinced that both Glyphs and Fontlab will be able to emit mark/mkmk code and cursive positioning anchors in a decomposed Arabic workflow if things are set up correctly. The Noto fonts are an example of how to do this, so you can try them out. But again, the "best" tool is always the one which works best for you.
  • Azizmohseny
    Azizmohseny Posts: 21
    edited October 11
    do this automatically, in a way that you never need to edit it?Simon Cozens said:
     The Noto fonts are an example of how to do this, so you can try them out. But again, the "best" tool is always the one which works best for you.
    Thank you, Simon.
    I am as concerned about the technical aspects of Arabic fonts as you are — perhaps even more so, given my background in calligraphy and my study of 1,000-year-old Arabic scripts, especially Nastaliq.
    The Noto fonts are excellent fonts, especially for display. Legible, simple, with solid geometry. But their design combines decomposed and ligature approaches — and I am strongly opposed to ligatures in fonts. I believe they weaken the font. Every character should retain its independence.
    In my own fonts, I do not even ligate words like "Allah." Of course, combinations like "shadda + fatha" or a symbol like the Riyal sign are fine. But the "Allah" ligature has caused us endless trouble. In Persian, we have the word "lale" (meaning nanny), and nearly every font renders it as "Allah" — elevating our nannies to divinity.
    I once worked on a project for teaching Persian to beginners. The method was to create a story for each letter of the alphabet, and that letter had to appear in a different color in the story. I used Calibri — and you can imagine the trouble I had with ligatures.
    Ligatures were an intelligent trick for metal type, and they worked well in their time. But in the computer age, with a solid infrastructure like OpenType, I cannot accept the use of ligatures. It simply does not make sense to me.
    So in my view, the ligatures in Noto are a weakness in an otherwise beautiful font.
    I am also not sure that Glyphs writes the mark and mkmk features automatically. Since you have experience building Arabic fonts — does Glyphs 
  • Simon Cozens
    Simon Cozens Posts: 886
    edited October 11

    Since you have experience building Arabic fonts — does Glyphs do this automatically, in a way that you never need to edit it?
    Yes. This is the third time I have told you that it does, and that I am sure Fontlab does too, and that you can examine the way that Noto fonts are built, and build them for yourself, if you do not believe me. You can even open the Glyphs file in Fontlab, export it there and test it. Decomposed workflows with automatic anchoring work absolutely fine.
  • FontLab 8 had no built-in cursive attachment automation. FontLab 9 that we announced on Friday will have one. Combined with the auto layers (automatic live glyph composition), it'll be finally very easy to fill the encoded dotted glyph slots. This will also make further decomposition (DecoType-style) easier. 

  • Yes. This is the third time I have told you that it does, and that I am sure Fontlab does too, and that you can examine the way that Noto fonts are built, and build them for yourself, if you do not believe me. You can even open the Glyphs file in Fontlab, export it there and test it. Decomposed workflows with automatic anchoring work absolutely fine.
    Thank you, Simon.

    I never doubted that Glyphs can do this — as I said at the beginning of the discussion, I have no experience with Glyphs. My question was whether the features it generates need editing, or whether they are complete and reliable out of the box. Now I understand that they are.

    I wish FontForge had something similar.

    Thank you for your patience.

    (Note: I used AI assistance for translation and drafting.)
  • Azizmohseny
    Azizmohseny Posts: 21
    edited October 12
    FontLab 8 had no built-in cursive attachment automation. FontLab 9 that we announced on Friday will have one. Combined with the auto layers (automatic live glyph composition), it'll be finally very easy to fill the encoded dotted glyph slots. This will also make further decomposition (DecoType-style) easier. 
    Thank you, Adam.
    This is very good news. I have always wondered why an application as capable and complete as FontLab did not do this simple thing.
    Does FontLab 9 support kerning for Arabic as well?
    I hope we see FontLab 9 very soon.

    (Note: I used AI assistance for translation and drafting.)
  • Dave Crossland
    Dave Crossland Posts: 1,584
    I am not sure it will remain free once it matures.

    Fontra is GPLv3 so it will remain libre ;) 

  • Fontra is GPLv3 so it will remain libre ;) 

    Thanks Dave. Based on my research, Fontra currently uses features only for its own preview — meaning the features must be written beforehand, and Fontra does not generate them itself. But the application is under development, and this capability will likely be added soon.

    In FFB, we are working on an open standard for Arabic script that can prevent glyph explosion using a decomposed method, and in the next stage, provide facilities for easier and more accurate line justification.

    Maybe we can collaborate with Fontra on this.

    Thanks also for pointing out GPLv3

  • Dave Crossland
    Dave Crossland Posts: 1,584
    That sounds more like https://counterpunch.space
  • @yanone  recently said this:

    I created a basic Arabic ccmp sample font based on Fustat's ccmp rules and outlines, and the glyph composer infers the composition recipes from it, complete with anchors, so you get a readily engineered font and can start typing immediately... You can add the characters either as ccmp or as materialized components. Either way you get a complete functioning Arabic font from the beginning and can start typing and designing it immediately, and convert between ccmp and materialized components like I showed for Latin earlier...
    • Counterpunch encourages users to start a ccmp font instead of materialized components, or allows to convert if possible
    • App as controlled environment always supports ccmp
    • Font is edited entirely as ccmp throughout, optionally based on readily engineered glyph setup from Language Packs
    • Source format converts cleanly between a) simple kerning for materialized and b) contextual positioning for ccmp
    • Font source defines a storage format for contextual positioning (doesn't need to wait for other people's source format updates)
    • If needed, a Babelfont filter would export the font as legacy materialized
    • Actually removes the engineering overhead of keeping the components in check for beginners. ccmp will be the recommended method.
  • yanone
    yanone Posts: 148
    edited October 16
    Yes, this sounds familiar. Counterpunch will ship with ccmp-based recipes for Latin and Arabic from the beginning. Not yet implemented is a UI for contextual positioning (the equivalent of kerning in flat fonts) and the conversion between the two positioning concepts, but it will before the 1.0 release. Otherwise, Counterpunch already supports glyph composition conversion between ccmp and materialized component glyphs and vice versa.

    The goal is to re-engineer all scripts from a ccmp-first approach and provide recipes in specific Language Packs. Users will be able to choose a specific Language Pack for each script that their font shall support if they are not satisfied with the default option or more specific functionality is needed.

    For example, the default Arabic language pack will support common Arabic styles such as Naskh and Kufi, while Nastaliq and Ruqaa will require features such as the cursive attachment as part of the glyph recipes that don't need to be included in the basic set and will only confuse designers of basic Arabic.

    Counterpunch is uniquely positioned for this approach as its renderer doesn’t attempt to emulate OpenType shaping, but instead ships with a full bidirectional text processing and OpenType shaping. It outsources correct OpenType shaping to compiling an actual OpenType font live while editing which is rendered with Harfbuzz, so the correct function of the font is guaranteed rather than leaving it to guesswork and external proofing. That was the core design principle that kicked off the project.

    The Language Packs will provide glyph recipes, sample outlines, and OpenType feature code generators such that non-technical users can make any pre-defined calligraphic features happen with just a few mouse clicks without ever concerning themselves with OpenType feature code or glyph naming schemes.

    This is not yet public code, but the ccmp approach and Language Packs will be the biggest announcement I’ll make as part of my presentation at ATypI Sharjah in two weeks.

    Counterpunch will provide the technical infrastructure, but won’t automatically ship with the actual Language Packs needed for each script. Encoding the world’s calligraphy into these definitions is a separate effort and the Language Pack library will only grow over time.
  • @yanone  recently said this:

    Thank you, Simon. I truly appreciate the time you take to share these insights—it is invaluable to me
    yanone said:
    Yes, this sounds familiar. Counterpunch will ship with ccmp-based recipes for Latin and Arabic from the beginning. 

    And thank you, dear Yanone, for the remarkable work you are doing.

    Your initiative with Language Packs is brilliant. As someone with years of experience in calligraphy and deep research into Arabic calligraphy, I fully understand the immense value of this approach.

    I wish I could meet you in Sharjah, but as you know, we are currently caught in a war. I wish you the greatest success with your ATypI presentation and I am eagerly looking forward to the 1.0 release of Counterpunch!

  • yanone
    yanone Posts: 148
    Thank you so much 🙏