<?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: Demir Ajvazi</title>
    <description>The latest articles on DEV Community by Demir Ajvazi (@demirajvazi10max).</description>
    <link>https://dev.to/demirajvazi10max</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%2F3958449%2F456ec139-37ca-4bbe-8743-92c4743fb791.png</url>
      <title>DEV Community: Demir Ajvazi</title>
      <link>https://dev.to/demirajvazi10max</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/demirajvazi10max"/>
    <language>en</language>
    <item>
      <title>20 Years with a Screen Reader: What Developers Still Get Wrong</title>
      <dc:creator>Demir Ajvazi</dc:creator>
      <pubDate>Mon, 05 Oct 2026 20:57:15 +0000</pubDate>
      <link>https://dev.to/demirajvazi10max/20-years-with-a-screen-reader-what-developers-still-get-wrong-328e</link>
      <guid>https://dev.to/demirajvazi10max/20-years-with-a-screen-reader-what-developers-still-get-wrong-328e</guid>
      <description>&lt;p&gt;I am blind, and I have used the JAWS screen reader every day for about twenty years. I fix phones and computers, and I build accessible software: the Ultra suite, a set of creative tools like a video editor and an audio editor that blind and sighted people can both use.&lt;/p&gt;

&lt;p&gt;Blind people talk about accessibility problems all the time. We talk about them on mailing lists, in forums, in private groups. The people who could actually fix them almost never read those places. So this time I am writing in public, for every developer, designer and product team who will ever build a button.&lt;/p&gt;

&lt;p&gt;None of what follows is rare. I hit these problems almost every week.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Buttons and fields with no name
&lt;/h2&gt;

&lt;p&gt;This is the most common problem, and the easiest to fix. A sighted person sees a magnifying glass and knows it means search. My screen reader sees an image with no text and says "button". Or "button, button, button", ten times in a row. Which one sends the form? Which one deletes my account? I have to guess.&lt;/p&gt;

&lt;p&gt;Text fields are the same. I land in an edit box and JAWS says "edit". Is it my name, my email, my phone number? If the label is just grey text placed near the field, a screen reader does not know they belong together.&lt;/p&gt;

&lt;p&gt;The fix takes seconds:&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="c"&gt;&amp;lt;!-- Bad: a screen reader says only "button" --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&amp;gt;&amp;lt;svg&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Good: a screen reader says "Search, button" --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;aria-label=&lt;/span&gt;&lt;span class="s"&gt;"Search"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;aria-hidden=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Bad: placeholder is not a label --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Good: the label is tied to the field --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Email&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same rule applies in mobile apps: &lt;code&gt;contentDescription&lt;/code&gt; on Android, &lt;code&gt;accessibilityLabel&lt;/code&gt; on iOS. Every control a person can touch needs a name a person can understand. Not "btn_submit_2". Not nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The CAPTCHA wall
&lt;/h2&gt;

&lt;p&gt;A CAPTCHA asks me to prove I am human by doing the one thing I cannot do: look at a picture. Pick all the traffic lights. Type the blurry letters. The audio version, when it exists, is often so distorted that it fails too.&lt;/p&gt;

&lt;p&gt;So the test meant to stop robots stops me. And when it sits in front of registration, login or payment, it locks me out of the whole service.&lt;/p&gt;

&lt;p&gt;There are better options. Rate limiting, email or SMS verification, invisible risk checks, and passkeys all stop bots without asking anyone to see. If you must use a challenge, test it with a screen reader before you ship it, and give people another way through.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Sites I simply cannot use
&lt;/h2&gt;

&lt;p&gt;Recently I wanted to subscribe to a water dispenser from Knjaz Natura, a water delivery service here in Serbia. A simple task: open the site, register, choose a plan. I could not do it. Unlabeled fields, controls my screen reader could not reach, a page that did not behave like a page. In the end I had to call someone who can see to finish the registration for me.&lt;/p&gt;

&lt;p&gt;Think about what that means. I am a developer. I have used screen readers for twenty years. And I still needed help to sign up for water. Every person who gets stuck like this is a customer you lose, and most of them will never write to tell you why.&lt;/p&gt;

&lt;p&gt;Before you launch, try this: turn off your monitor, start NVDA (it is free) or VoiceOver, and complete your own main task using only the keyboard. If you cannot finish it, neither can we.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Redesigns that take it all away
&lt;/h2&gt;

&lt;p&gt;KupujemProdajem is the biggest classifieds site in Serbia. For years it was fantastic with a screen reader. I could search, read listings and message sellers with no problems at all.&lt;/p&gt;

&lt;p&gt;Then came the redesign. Since then, neither the website nor the app works for me. Content my screen reader cannot read, pages I cannot navigate, the same problems everywhere.&lt;/p&gt;

&lt;p&gt;This hurts more than a site that was never accessible, because it shows the work had already been done, and then it was thrown away. A new design is a chance to improve accessibility, not a reason to lose it. Put screen reader testing in your redesign checklist, next to performance and browser testing. And keep the users who relied on the old version in the loop.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. It can be done: Microsoft
&lt;/h2&gt;

&lt;p&gt;I do not want this to be only complaints, because some companies get it right. Microsoft is the best example I know. Office is fully accessible to me: I write, edit and work in it every day with JAWS. Windows is solid too.&lt;/p&gt;

&lt;p&gt;That did not happen by accident. It happens when accessibility is part of how a company builds, not a fix added after launch. If a company as big as Microsoft can do it across products used by hundreds of millions of people, a registration form can do it too.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I ask of every developer
&lt;/h2&gt;

&lt;p&gt;Whatever you build, a website, an app, a small internal tool, check it with someone who uses a screen reader. If you cannot find that person, at least ask an AI assistant to review your interface for accessibility. Either one will catch most of what I described here.&lt;/p&gt;

&lt;p&gt;The checklist is short:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Every button has a clear name a screen reader can say.&lt;/li&gt;
&lt;li&gt;Every field has a real label tied to it, not just a placeholder.&lt;/li&gt;
&lt;li&gt;Everything works with the keyboard alone.&lt;/li&gt;
&lt;li&gt;No CAPTCHA that depends only on sight.&lt;/li&gt;
&lt;li&gt;Every redesign is tested with a screen reader before release.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of this is hard. It costs minutes when you build it, and hours, or customers, when you do not. And if you want to know what it is really like, ask us. We have been waiting a long time for someone to ask.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I am Demir Ajvazi, a blind developer from Serbia building the accessible Ultra suite. You can find my work on &lt;a href="https://github.com/demirajvazi10-max" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Ultra Bridge: Translating JAWS Keyboard Commands to NVDA with Sanity Context</title>
      <dc:creator>Demir Ajvazi</dc:creator>
      <pubDate>Sat, 26 Sep 2026 01:09:54 +0000</pubDate>
      <link>https://dev.to/demirajvazi10max/ultra-bridge-translating-jaws-keyboard-commands-to-nvda-with-sanity-context-3ii</link>
      <guid>https://dev.to/demirajvazi10max/ultra-bridge-translating-jaws-keyboard-commands-to-nvda-with-sanity-context-3ii</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/sanity-2026-09-16"&gt;Sanity Challenge, Path One: Ship an Agent That Queries Real Content&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Ultra Bridge is an agent for screen reader users. You ask it things like "What is the NVDA equivalent of JAWS Insert+F7?" or "Which keys do different jobs in JAWS and NVDA?", and it answers from a Sanity dataset through Sanity Context MCP. Every answer says how well the underlying command is verified, so you know whether to trust it or check it yourself first.&lt;/p&gt;

&lt;p&gt;I built it because I rely on a screen reader myself, and moving between JAWS and NVDA means relearning keys that look the same but are not. That gap costs real time and real confidence, and it is exactly the kind of problem structured content is good at closing. Ultra Bridge is part of the Ultra suite of accessible software I am building.&lt;/p&gt;

&lt;p&gt;The reason it needs structured content: a keyword search can find a page that mentions both screen readers, but it cannot tell you which keys collide, which ones translate cleanly, or which ones simply do not exist yet on the other side. In Ultra Bridge an &lt;strong&gt;action&lt;/strong&gt; ("show a list of all links") is separate from a &lt;strong&gt;command&lt;/strong&gt; (the keys one screen reader uses for that action). Equivalents are found through the shared action, so a relationship question becomes one query instead of a guess.&lt;/p&gt;

&lt;p&gt;This query lists every single letter key that exists in both screen readers but does a different job:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*[_type=="command" &amp;amp;&amp;amp; screenReader-&amp;gt;slug.current=="jaws" &amp;amp;&amp;amp; context=="browse-mode"]{
  keys,
  "jawsAction": action-&amp;gt;title,
  "nvdaMeansSomethingElse": *[_type=="command" &amp;amp;&amp;amp; screenReader-&amp;gt;slug.current=="nvda" &amp;amp;&amp;amp; keys==^.keys &amp;amp;&amp;amp; action._ref != ^.action._ref]{"action": action-&amp;gt;title}
}[count(nvdaMeansSomethingElse)&amp;gt;0]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Against the seed data it returns six keys. R is "region" in JAWS and "radio button" in NVDA. Q is "main content" in JAWS and "block quote" in NVDA. A, O, S and D collide too. That is exactly the kind of thing that costs a person time when they switch, and exactly the kind of question a keyword search cannot answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://ultra-bridge-xm71.vercel.app/" rel="noopener noreferrer"&gt;https://ultra-bridge-xm71.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The page has example questions you can press. Open "How this was found" under any answer to see the exact GROQ query the agent ran to get there — nothing is hidden between the question and the data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/demirajvazi10-max/Ultra-Bridge" rel="noopener noreferrer"&gt;https://github.com/demirajvazi10-max/Ultra-Bridge&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Sanity
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Schema.&lt;/strong&gt; Seven document types: &lt;code&gt;screenReader&lt;/code&gt;, &lt;code&gt;source&lt;/code&gt;, &lt;code&gt;action&lt;/code&gt;, &lt;code&gt;command&lt;/code&gt;, &lt;code&gt;concept&lt;/code&gt;, &lt;code&gt;difference&lt;/code&gt; and &lt;code&gt;guide&lt;/code&gt;. The dataset currently has 229 documents: 60 actions, 127 commands, 13 concepts, 12 differences, 7 guides and 8 sources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trust as data, not as an afterthought.&lt;/strong&gt; Every command has a &lt;code&gt;verification&lt;/code&gt; field (&lt;code&gt;tested-by-author&lt;/code&gt;, &lt;code&gt;cross-checked&lt;/code&gt;, &lt;code&gt;first-party&lt;/code&gt;, &lt;code&gt;third-party&lt;/code&gt;, &lt;code&gt;recalled&lt;/code&gt;) and references to &lt;code&gt;source&lt;/code&gt; documents. The system prompt tells the agent to say the verification level out loud whenever it uses a command, and to point to input help (Insert+1 in JAWS, NVDA+1 in NVDA) whenever a command is not yet confirmed. When two sources disagree, the disagreement is written on the command instead of hidden. Right now 11 commands are tested-by-author, 58 cross-checked, 44 first-party and 14 third-party — zero are still sitting at the weakest "recalled" level, because I keep a running checklist of what still needs a hands-on pass on a real screen reader.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sanity Context, two modes.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GROQ mode serves the structured dataset. The agent fetches &lt;code&gt;/initial-context&lt;/code&gt; over HTTP, puts it in its system prompt, and uses &lt;code&gt;groq_query&lt;/code&gt; and &lt;code&gt;schema_explorer&lt;/code&gt; for anything that names a specific command, key or action.&lt;/li&gt;
&lt;li&gt;Knowledge Base mode serves seven guides written in prose, reserved for open-ended questions like "what should I learn first" or "how are the two screen readers different overall," where a single structured query would not be the right shape of answer. The Knowledge Base is created and built from the CLI (&lt;code&gt;sanity context create&lt;/code&gt;, &lt;code&gt;imports create&lt;/code&gt;, &lt;code&gt;build --watch&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The two &lt;code&gt;initial_context&lt;/code&gt; tools have the same name, so the agent drops both and inlines their content directly into the system prompt instead. If the Knowledge Base endpoint is unavailable, the agent falls back to the structured dataset only rather than failing the whole request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Engineering for free-tier reality.&lt;/strong&gt; The public demo runs on free model tiers, which cap tokens per minute hard enough that a naive integration falls over under real traffic. So the agent only exposes the two tools it actually needs (&lt;code&gt;groq_query&lt;/code&gt;, &lt;code&gt;knowledge_base_read&lt;/code&gt;), compacts every tool result before it goes back to the model (stripping fields the model does not need and hard-capping length), and chains four model providers (Google, Groq, Cerebras, Anthropic) so a rate limit on one provider fails over to the next instead of failing the request. The public page also rate-limits per visitor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I learned.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One endpoint serves one source type, so the structured data and the Knowledge Base need separate access paths.&lt;/li&gt;
&lt;li&gt;GROQ &lt;code&gt;match&lt;/code&gt; is tokenised text matching, so I use equality (&lt;code&gt;==&lt;/code&gt;) for keys that contain &lt;code&gt;+&lt;/code&gt;, or the match would silently split "Insert+F7" into pieces.&lt;/li&gt;
&lt;li&gt;The Sanity CLI covers almost everything I needed: project, schema deploy, dataset import, tokens and the Knowledge Base. That mattered because I work from the command line.&lt;/li&gt;
&lt;li&gt;Because Sanity's API was not reachable from where I built the first version, I wrote a small local server that speaks the Context MCP tool names and evaluates real GROQ with &lt;code&gt;groq-js&lt;/code&gt;. It let me test the agent, the prompt queries and the whole interface offline, and it ships in the repo so anyone can try the project without accounts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Accessibility.&lt;/strong&gt; I am blind and use JAWS day to day, and I tested this myself before anyone else touched it. The interface has a skip link, real headings for every question and answer, one polite live region that announces the full answer once when it is complete, a "read last answer again" button, and stable focus in the question box. An end-to-end test drives it in Chromium and runs axe-core in light and dark colour schemes, so accessibility is checked automatically, not just by hand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sanity Project Details
&lt;/h2&gt;

&lt;p&gt;Project ID: u2f7mbu5&lt;br&gt;
Dataset: production (public)&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>sanitychallenge</category>
      <category>sanity</category>
      <category>ai</category>
    </item>
    <item>
      <title>AI Camera — Fan Edition: it hypes up your jersey like a stadium commentator 🏆</title>
      <dc:creator>Demir Ajvazi</dc:creator>
      <pubDate>Sun, 12 Jul 2026 00:24:13 +0000</pubDate>
      <link>https://dev.to/demirajvazi10max/ai-camera-fan-edition-it-hypes-up-your-jersey-like-a-stadium-commentator-5cb2</link>
      <guid>https://dev.to/demirajvazi10max/ai-camera-fan-edition-it-hypes-up-your-jersey-like-a-stadium-commentator-5cb2</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/weekend-2026-07-09"&gt;Weekend Challenge: Passion Edition&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  AI Camera — Fan Edition 🏆📷
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AI Camera&lt;/strong&gt; is a phone-camera app that describes what it sees, out loud, in real time — powered by Google's Gemini vision model. It started as an assistive tool for blind and low-vision users (general scene description, reading text aloud, describing an item for a marketplace listing, describing a person's appearance). For this challenge, I added a fifth mode built specifically around &lt;strong&gt;passion&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;🏆 &lt;strong&gt;Fan Mode&lt;/strong&gt; — point your phone at a jersey, scarf, flag, or any fan gear, and the app turns into a hyped-up stadium commentator, calling out colors, team details, and team spirit with real enthusiasm. With the World Cup happening right now, it felt like the right moment to build it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📱 &lt;strong&gt;Important: this is a mobile-first app.&lt;/strong&gt; It's built around your phone's rear camera and needs to be held up and pointed at real things — please try it on a phone, not a desktop, for the intended experience.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;🔗 &lt;strong&gt;Live app (open on your phone):&lt;/strong&gt; &lt;a href="https://demirajvazi10-max.github.io/ai-camera-fan-edition/" rel="noopener noreferrer"&gt;https://demirajvazi10-max.github.io/ai-camera-fan-edition/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll need a free Gemini API key from &lt;a href="https://aistudio.google.com/app/apikey" rel="noopener noreferrer"&gt;aistudio.google.com/app/apikey&lt;/a&gt; — paste it in when the app asks. It's stored only in your browser and never leaves your device except to call Google's API directly.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(I wasn't able to put together a screen recording for this submission — camera-based apps are a bit awkward to record on a phone! Since the whole thing runs client-side with no backend, the live link above lets you try Fan Mode yourself on your own phone in about 30 seconds.)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/demirajvazi10-max/ai-camera-fan-edition" rel="noopener noreferrer"&gt;https://github.com/demirajvazi10-max/ai-camera-fan-edition&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;Passion shows up in different ways. Sometimes it's the quiet kind — building something so a person who can't see can still "see" the world around them. Sometimes it's the loud kind — losing your mind over your team's jersey during a World Cup year. I already had the first one built. Adding Fan Mode let the same engine carry both.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vanilla HTML/CSS/JS — no framework, no build step, no backend&lt;/li&gt;
&lt;li&gt;Camera access via &lt;code&gt;getUserMedia&lt;/code&gt;, photo captured to a canvas and sent as base64 to the &lt;strong&gt;Gemini API&lt;/strong&gt; (&lt;code&gt;gemini-flash-latest&lt;/code&gt;) with a mode-specific prompt&lt;/li&gt;
&lt;li&gt;Each mode is just a different prompt string — Fan Mode's prompt asks Gemini to respond "like a hyped-up sports commentator hyping up the crowd"&lt;/li&gt;
&lt;li&gt;Responses are read aloud via the browser's Web Speech API (free, works offline once the page is loaded)&lt;/li&gt;
&lt;li&gt;The whole thing is one static &lt;code&gt;index.html&lt;/code&gt;, so it deploys straight to GitHub Pages with HTTPS — which matters, because phones require a secure context for camera access&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Best Use of Google AI&lt;/strong&gt; — Gemini's vision model is the core of the app; every one of the five modes depends on it to analyze the photo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notes for judges:&lt;/strong&gt; please test on a phone if possible — that's the intended experience (rear camera + held up to real objects). Fan Mode is the new addition for this challenge; the other four modes existed before as an accessibility tool.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
    </item>
    <item>
      <title>Reviving Ultra Creative Suite: The First Fully Accessible Video Editor for Blind Users</title>
      <dc:creator>Demir Ajvazi</dc:creator>
      <pubDate>Sat, 30 May 2026 00:13:16 +0000</pubDate>
      <link>https://dev.to/demirajvazi10max/reviving-ultra-creative-suite-the-first-fully-accessible-video-editor-for-blind-users-286l</link>
      <guid>https://dev.to/demirajvazi10max/reviving-ultra-creative-suite-the-first-fully-accessible-video-editor-for-blind-users-286l</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-05-21"&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Ultra Creative Suite is a professional video and audio editor for Windows, built from the ground up for blind and low-vision users. Every feature works equally for sighted and non-sighted users — no compromises, no stripped-down accessible mode.&lt;/p&gt;

&lt;p&gt;I am blind. I use JAWS for Windows daily. I built this because no professional video editor on the market — Adobe Premiere, DaVinci Resolve, Final Cut — is actually usable with a screen reader.&lt;/p&gt;

&lt;p&gt;The project includes an AI video generator that takes a single audio file and produces a complete 4K video: lyric analysis, automatic stock footage download, mood-based color grading, ambient sound mixing, and GPU-accelerated rendering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/demirajvazi10-max/Ultra-Creative-suite" rel="noopener noreferrer"&gt;https://github.com/demirajvazi10-max/Ultra-Creative-suite&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The demo video in the repository was created entirely by me — blind, using JAWS only. AI analyzed the lyrics, selected stock footage, applied color grading, mixed ambient sounds, and rendered to 4K. Zero sighted assistance.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Comeback Story
&lt;/h2&gt;

&lt;p&gt;The project existed and worked, but had several critical issues that made real-world use unreliable:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Audio fade timing was broken — &lt;code&gt;afade&lt;/code&gt; filter used absolute timestamps instead of stream-relative timing, causing ambient sounds to fade incorrectly&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;totalDuration&lt;/code&gt; was not adjusted for &lt;code&gt;AudioStartSeconds&lt;/code&gt;, so videos were consistently shorter than expected (2:57 audio rendered as 2:49)&lt;/li&gt;
&lt;li&gt;SmartOutroPool had no cap on clip repetition, causing the same outro clip to repeat endlessly&lt;/li&gt;
&lt;li&gt;Temp files were written directly to &lt;code&gt;D:\&lt;/code&gt; drive instead of system temp folder, cluttering the disk&lt;/li&gt;
&lt;li&gt;IskraSync used incorrect timing references, causing beat-locked edits to drift&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;After (with GitHub Copilot):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;afade&lt;/code&gt; now uses &lt;code&gt;st=0&lt;/code&gt; relative to stream start — ambient sounds fade correctly&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;totalDuration&lt;/code&gt; is now corrected immediately after beat detection: &lt;code&gt;rawDuration - AudioStartSeconds&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;SmartOutroPool has repetition cap, recycle pool, and ultra-safe fallback queries&lt;/li&gt;
&lt;li&gt;All temp audio batches now go to &lt;code&gt;%TEMP%\UVE_MixAudio_*&lt;/code&gt; with automatic cleanup after render&lt;/li&gt;
&lt;li&gt;IskraSync rebuilt to use &lt;code&gt;timelineSpan&lt;/code&gt; as primary measure with proper beat-lock offset&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GitHub Copilot helped me understand the scope of changes across three files simultaneously and generated a precise commit description that captured every fix — something that would have taken me much longer to write manually while navigating with a screen reader.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Experience with GitHub Copilot
&lt;/h2&gt;

&lt;p&gt;As a blind developer, navigating code with a screen reader is significantly slower than visual inspection. GitHub Copilot changed my workflow in a concrete way.&lt;/p&gt;

&lt;p&gt;When I modified three files — &lt;code&gt;AIVideoCreator.xaml.cs&lt;/code&gt;, &lt;code&gt;RenderEngine.cs&lt;/code&gt;, and &lt;code&gt;SkiaAnimationEngine.cs&lt;/code&gt; — Copilot generated this commit description automatically:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Multiple fixes across AIVideoCreator, RenderEngine and SkiaAnimationEngine: correct audio fade timing (afade) relative to asetpts/stream start; adjust totalDuration by subtracting AudioStartSeconds so -ss trimming doesn't shorten output unexpectedly; implement SmartOutroPool with max clip duration, recycle pool, ultra-safe fallback queries and fade-out tagging..."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That level of detail would have required me to re-navigate every changed file manually. Copilot gave me that summary instantly, which I could then use directly as a commit message.&lt;/p&gt;

&lt;p&gt;For accessibility, this is not a convenience — it is a genuine productivity multiplier.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>a11y</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I'm Blind. I Built a Professional Video Editor. Here's Why.</title>
      <dc:creator>Demir Ajvazi</dc:creator>
      <pubDate>Fri, 29 May 2026 12:41:14 +0000</pubDate>
      <link>https://dev.to/demirajvazi10max/im-blind-i-built-a-professional-video-editor-heres-why-3681</link>
      <guid>https://dev.to/demirajvazi10max/im-blind-i-built-a-professional-video-editor-heres-why-3681</guid>
      <description>&lt;p&gt;Every time I opened Adobe Premiere, DaVinci Resolve, or any other professional video editor, I hit the same wall. Buttons without labels. Timelines that exist only as visual elements. Drag-and-drop workflows that assume you can see where you're dragging. For a sighted user, these tools are industry standard. For me — a blind developer using JAWS for Windows — they are practically unusable.&lt;br&gt;
I got tired of waiting for someone else to fix this.&lt;br&gt;
So I built Ultra Creative Suite.&lt;br&gt;
What it is&lt;br&gt;
Ultra Creative Suite is a professional video and audio editor for Windows, built from the ground up with one rule: every single feature must work equally for blind, low-vision, and sighted users. No "accessible mode" that hides features. No stripped-down alternative workflow. The same full editor, for everyone.&lt;br&gt;
What it can do&lt;br&gt;
Give it an audio file — a song, a narration, anything — and it will:&lt;/p&gt;

&lt;p&gt;Analyze lyrics using a local AI model (Ollama / Qwen 2.5 14B)&lt;br&gt;
Detect mood, season, and energy per lyric line&lt;br&gt;
Automatically download matching stock footage from Pixabay&lt;br&gt;
Apply per-lyric color grading via FFmpeg curves&lt;br&gt;
Mix ambient sounds from a library of 1,279+ categorized clips&lt;br&gt;
Render the finished video to 4K&lt;/p&gt;

&lt;p&gt;All of this is controllable entirely through the keyboard. Every action is announced by the screen reader. No mouse required for any core workflow.&lt;br&gt;
The technical decisions that made accessibility possible&lt;br&gt;
The most important decision was the timeline. Most video editors use custom-drawn UI elements for their timelines — visually rich, but completely invisible to screen readers. I used a Win32 native ListView control instead. The same Windows control used in File Explorer. JAWS and NVDA read every clip natively, without plugins or workarounds: clip name, type, duration, position, and AI-generated audio description.&lt;br&gt;
Every dialog has proper focus management. Every action produces a live region announcement. The entire application is navigable with standard keyboard shortcuts.&lt;br&gt;
The demo&lt;br&gt;
The demo video linked in the repository was created entirely by me — blind, using JAWS only. No sighted assistance at any point. AI analyzed the lyrics, selected the footage, applied the effects, mixed the audio, and rendered to 4K. I controlled every step through the keyboard.&lt;br&gt;
Why open source&lt;br&gt;
Because I'm not the only blind developer who has hit this wall. And I'm not the only blind person who wants to create. Ultra Creative Suite is GPL-3, fully open source, and designed to be a reusable foundation for accessible creative software.&lt;br&gt;
If you've ever thought "why isn't there accessible software for X" — maybe this is the starting point.&lt;br&gt;
Links&lt;br&gt;
GitHub: github.com/demirajvazi10-max/Ultra-Creative-suite&lt;br&gt;
If you want to support the project: ko-fi.com/ultra-creativesuite or paypal.me/demirajvazi10&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>opensource</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
