Skip to content
Skip article header Engineering

What We Kept on the Contrast Exception List

Dated contrast findings stayed visible through a redesign, separating accepted exceptions from passing pairs and keeping unresolved decisions traceable

5 min read 18 views

Reviewed by Dmytro Nasyrov on October 22, 2026.

Our design extraction recorded muted text at contrast ratios of 3.18:1 on the light canvas and 3.55:1 on a surface. A later Ask design recorded the send arrow at 1.78:1 in light mode and 2.31:1 in dark mode. We retained these findings as named exceptions instead of describing the redesigned interface as compliant.

Preserving evidence of unresolved decisions was part of the frontend work. A token can match the design source exactly while remaining unsuitable for a particular text or control. A successful token test must not erase that distinction.

One alias affected many existing labels

At the extraction point, we identified 142 existing uses of the component library's muted-foreground class. Those call sites were not all decorative hints. They included common secondary text that still needed to be read. We mapped that existing semantic role to the source palette's secondary-text token. The lighter muted source color remained available for the narrower situations the design intended. This avoided treating every inherited class name as a literal instruction to choose the faintest text.

That count describes the code inventory at that extraction point. It is not a count of users affected or proof that every call site was individually audited for every background. It explained why one alias decision had a broad migration surface.

Test the pair, then record the exception

A color value alone has no contrast ratio. The foreground and its actual background form the relevant pair. Our recorded token checks computed those pairs and maintained an explicit known-below-threshold list for accepted design values.

Recorded example Date and result Interpretation
Muted text on light canvas October 4: 3.18:1 Known contrast concern
Muted text on light surface October 4: 3.55:1 Background changes the result
Send arrow, light / dark October 6: 1.78:1 / 2.31:1 Named unresolved exception

Recording an exception kept a test suite from making an accidental claim. An exception means the team knows about a failing pair and has not resolved it. It does not convert the failing pair into a passing result.

We could therefore review a palette update without losing the older decision trail. If a pair improved, its measurement could change deliberately. If a new component reused the problematic token on another background, it needed a fresh entry or correction rather than borrowing the old exception blindly.

The exception entry needed its background and use

The extraction contained more than the two muted-text examples. On the subtle light background, the same muted foreground measured 3.37:1. In dark mode, the subtle-background pair measured 4.10:1. A note saying that muted text failed in light mode would therefore have lost an important dark-mode exception. The disconnected-source badge supplied another pair: 2.78:1 in light and 4.37:1 in dark, used for 11-pixel uppercase text. Neither the component name nor its color family explained its readability.

We can reconstruct the useful ledger fields from that record without reproducing a screenshot or implying a new audit. The pair identifies the calculation. The usage identifies the consequence. The date identifies which palette the calculation belongs to. A decision field preserves the remaining owner question.

Historical item Recorded detail Decision still exposed
Muted foreground on subtle background 3.37:1 light, 4.10:1 dark A dark theme did not remove every exception
Disconnected-source foreground on its fill 2.78:1 light, 4.37:1 dark Small badge text needed its own assessment
Default and strong borders on surface 1.27:1 and 1.67:1 The extraction asked whether input boundaries should become darker
Muted semantic alias 142 existing secondary-text call sites Map the semantic role to secondary text while retaining the source muted token

The border entry also shows why a single global text threshold would have been a poor test design. The source discussed component boundaries separately from text, and the later send-arrow check used the icon's control role. An inventory of token names cannot decide whether an element is informative text, an interactive boundary or decoration. The component's rendered use supplies that missing context.

A palette change had to update both sides of the test

The later Ask record pinned new hover and status colors while retaining separate pair calculations. Its destructive-hover check recomputed a color mixture from the new error colors rather than continuing to test a copied older value. Otherwise the assertion could remain green while measuring a color the button no longer used.

That gives a reviewer two independent questions at a token change: does the source-value assertion match the intended palette, and does the contrast calculation consume the value the component now renders? Moving a known failure into a named exception answers neither question by itself. It only makes the remaining decision visible.

The palette changed during the work

The October 6 design superseded several values from the October 4 extraction. We keep dates attached to the examples because combining measurements from different palettes would create a fictional current-state report. This also affected the boundary with design review. The frontend could faithfully apply the chosen source colors and identify the failing pairs. Accepting a visual exception or revising the source palette required an explicit product and design decision. Quietly substituting unrelated colors would have hidden that decision from the shared system.

What we could inspect beyond the formula

Computed contrast checks gave us repeatable evidence about selected pairs. Browser inspection established which background and state the component actually rendered. A pair calculated for the canvas would not describe a label displayed over a raised surface or hover state. The implementation record includes token assertions and visual checking of the integrated interface. It does not provide a complete assistive-technology audit, independent certification or a measured reduction in user errors. Contrast was one dimension of the redesign, not a substitute for keyboard and focus checks.

A ledger is useful only while its meaning stays visible

Our review question became concrete: which pair fails, where is it used, what changed since the measurement and who owns the remaining decision? That is more actionable than a general note that accessibility needs improvement.

These measurements remain historical examples. A release-level compliance statement would require fresh measurements of the actual release in its required states.

FAQ

Last updated:

Quick answers to common questions about custom software development, pricing, process and technology.

  • How long have you been in business?

    Pharos Production has been in business since 2013, with over 13 years of experience in custom software development. During this time, we have delivered over 110 applications for 200+ clients across 28 industries, including FinTech, healthcare, crypto and e-commerce. We are rated 5/5 on Clutch based on 107 verified reviews (2026).

  • What services do you provide?

    Pharos Production provides six core service categories: AI Development (LLM applications, AI agents, machine learning and computer vision), Blockchain and Web3 (smart contracts, DeFi, tokenization on Ethereum, Solana, TON and other chains), FinTech Development (payment platforms, digital banking, KYC and AML integration), Software Development (mobile apps, web platforms, database design, UI/UX), Security and QA (code audits, penetration testing, smart contract audits, manual and automated testing) and Consulting (architecture design, MVP validation, startup consulting).

  • Where is Pharos Production located?

    Pharos Production is headquartered in Las Vegas, Nevada, USA (5348 Vegas Dr, Las Vegas, NV 89108), with an engineering office in Kyiv, Ukraine (44-B Eugene Konovalets Str. Suite 201, Kyiv 01133). We work with clients worldwide and provide remote collaboration across all time zones. Visit our contact page for directions and scheduling options.

  • How big is your team?

    Pharos Production has a team of 90+ engineers, including software developers, blockchain specialists, QA engineers, DevOps experts, UI/UX designers, project managers and solution architects. Our founder, Dr. Dmytro Nasyrov, holds a PhD in Artificial Intelligence and leads the technical direction of all projects.

  • What types of customers do you serve?

    We serve a wide range of clients, from startups and product companies to mid-sized enterprises and large institutions. Our clients include crypto exchanges, FinTech providers (like Pleenk), healthcare organizations, sportsbook operators (like Pro Gambling), e-commerce platforms and SaaS companies. Pharos Production has worked with 200+ clients across 28 industries since 2013, adapting engagement models to match each client's stage, whether it is MVP validation for a startup or enterprise-scale development for an established business.

  • How is a custom software development company different from an agency?

    A custom software development company like Pharos Production assigns one dedicated engineering team that owns your product across multiple release cycles, instead of handing it off once a contract ends. Agencies more often rotate staff between clients and optimize for fast delivery over long-term product ownership.

    Pharos Production keeps the same team on your codebase through 2-week sprints, so there is no re-onboarding cost each time you request a new feature.

  • How much does custom software development cost?

    Custom software development costs vary based on project scope and complexity. At Pharos Production, typical project ranges are: MVP development ($10,000-$25,000), suitable for startups validating a product idea; full-fledged production ($25,000-$50,000), for established businesses scaling a proven concept; and full-cycle development ($50,000-$80,000+), for complex enterprise-grade systems. These ranges include architecture design, development, QA testing and deployment. Hourly rates range from $50 to $99 depending on role and seniority. Final pricing depends on technology stack, number of integrations and engagement model (staff augmentation, dedicated team or project outsourcing).

  • How long does it take to develop a custom software application?

    Development timelines depend on scope and complexity. At Pharos Production, a typical MVP takes 2-4 months, a production-ready application takes 4-8 months and a complex enterprise system can take 8-12+ months. We use an agile methodology with 2-week sprints, delivering working increments after each sprint. Every sprint includes a retrospective, progress report and planning session for the next iteration. This approach ensures transparency and allows businesses to launch faster by prioritizing high-impact features first. Get a timeline estimate for your project.

  • What industries does Pharos Production serve?

    Pharos Production serves 28 industries: FinTech, MiCA Compliance, Banking, Insurance, Crypto, Healthcare, Fitness, E-Commerce, Food & Restaurant, On-Demand, Manufacturing, Automotive, Energy, Oil & Gas, Supply Chain, Construction, Real Estate, Gaming, Streaming, Media, Telecom, Education, Aviation, Travel, Logistics, Marketing, Agriculture and Recommender Systems. Our deepest expertise is in FinTech, blockchain and healthcare, where we have delivered compliance-ready platforms (HIPAA, PCI DSS, GDPR) and high-load systems handling thousands of concurrent users. For the latest industry insights, read our guides on FinTech trends in 2026 and the Web3 technology stack.

  • Why hire a software development company instead of building in-house?

    Hiring a software development company offers faster time-to-market, lower upfront costs and access to specialized expertise without long-term employment commitments. According to Deloitte's 2024 Global Outsourcing Survey, 57% of companies outsource software development to access skills they cannot hire internally.

    Factor In-house team Software development company
    Time to assemble 3-6 months (recruiting + onboarding) 1-2 weeks
    Upfront cost High (salaries, benefits, equipment) Lower (project-based pricing)
    Specialized expertise Limited to who you can hire locally Access to 90+ engineers across blockchain, AI, FinTech
    Scalability Slow (each new hire takes months) Fast (scale up or down per sprint)
    Long-term commitment Full-time employment contracts Flexible engagement models
    Risk High if key engineers leave Company ensures continuity and knowledge transfer

    For businesses that need blockchain, AI or high-load architecture expertise, outsourcing to a specialized firm like Pharos Production reduces risk and accelerates delivery.

  • What projects does Pharos Production not take on?

    Pharos Production focuses on mid-to-large custom software projects with budgets starting at $10,000. We do not take on template-based websites, WordPress theme customization or short-term contracts under one month. We also do not provide non-technical staffing (marketing, sales or design-only roles). Our strongest fit is blockchain, FinTech and healthcare projects where security, compliance and high-load architecture are critical. For smaller projects or MVPs under $10,000, we recommend exploring freelance platforms or no-code tools as a more cost-effective starting point.

  • Why does Pharos Production use agile methodology?

    We use agile with 2-week sprints because it reduces the risk of building features that miss the mark. Each sprint ends with a working demo, a retrospective and a plan for the next iteration.

    This means clients see progress every 14 days and can adjust priorities based on real results, not assumptions. We chose this approach after years of experience showing that rigid, fixed-scope contracts lead to scope creep, missed deadlines and products that do not match market needs by launch day.

  • When should you NOT hire a custom software development company?

    Custom development is not the right choice in every situation. You should not hire a custom software company if: your problem is fully solved by an existing SaaS product (e.g. Shopify for e-commerce, Salesforce for CRM); your budget is under $10,000 and timeline is under 4 weeks; you need a simple landing page or marketing website (WordPress or Webflow is faster and cheaper); or you are still validating the idea and have not spoken to potential users yet.

    In these cases, off-the-shelf tools or no-code platforms offer better ROI. Custom development makes sense when you need unique workflows, regulatory compliance, high-load architecture or competitive differentiation that packaged software cannot provide.

  • What kind of projects has Pharos Production delivered?

    Here are three anonymized examples from our recent delivery history:

    FinTech startup - payment platform (MVP)
    Scope: mobile app + backend API with bank-grade encryption. Team: 4 engineers, 1 QA. Timeline: 10 weeks. Budget: $38,000. Result: launched on schedule, processed $2M+ in transactions within the first quarter.

    Healthcare provider - patient portal (Full product)
    Scope: HIPAA-aligned web platform with EHR integration, appointment scheduling and telemedicine. Team: 6 engineers, 1 DevOps, 2 QA. Timeline: 6 months. Budget: $120,000. Result: 15,000+ active patients, zero compliance violations in two annual audits.

    Crypto exchange - trading engine (Complex)
    Scope: high-load matching engine handling 50,000+ orders per second, multi-chain wallet infrastructure on Ethereum and Solana. Team: 8 engineers, 2 QA, 1 security auditor. Timeline: 11 months. Budget: $340,000. Result: 99.97% uptime, passed three independent security audits.

    See more projects: NoMoreBets, Pulse, Sagas, Gambit Stream and Pleenk. For the full portfolio, visit our case studies. Learn more about the technology behind these projects in our guide to stablecoins and crypto infrastructure.

Stas Rysin is the Lead Frontend Developer at Pharos Production. His work covers the design system, reader interfaces and administration workflows of a professional learning platform for aesthetic medicine.

Dmytro Nasyrov, Founder and CTO at Pharos Production
Dmytro Nasyrov Founder & CTO Let's work together!

Your business results matter

Achieve them with minimized risk through our bespoke innovation capabilities

Your contact details
Please enter your name
Please enter a valid email address
Please enter your message

We use your details only to reply to your request. Data Privacy and Legal Notice

We typically reply within 24 hours

What happens next?

  1. Contact us

    Contact us today to discuss your project. We're ready to review your request promptly and guide you on the best next steps for collaboration

    Same day
  2. NDA

    We're committed to keeping your information confidential, so we'll sign a Non-Disclosure Agreement

    1 day
  3. Plan the Goals

    After we chat about your goals and needs, we'll craft a comprehensive proposal detailing the project scope, team, timeline and budget

    3-5 days
  4. Finalize the Details

    Let's connect on Google Meet to go through the proposal and confirm all the details together!

    1-2 days
  5. Sign the Contract

    As soon as the contract is signed, our dedicated team will jump into action on your project!

    Same day