Skip to content

feat(partners): tiered partner display (gold/silver/bronze)#867

Merged
tannerlinsley merged 7 commits intomainfrom
taren/quizzical-babbage-07d1ad
Apr 30, 2026
Merged

feat(partners): tiered partner display (gold/silver/bronze)#867
tannerlinsley merged 7 commits intomainfrom
taren/quizzical-babbage-07d1ad

Conversation

@tannerlinsley
Copy link
Copy Markdown
Member

@tannerlinsley tannerlinsley commented Apr 28, 2026

Summary

  • Replaces score-based dynamic sizing in the partner grid and right rail with a clear three-tier system (Gold / Silver / Bronze), retaining score for in-tier ordering
  • Each tier gets distinct sizing, color flares (gradient bars + pill labels + metal-tone icons), and corner radii to give the partner display a polished, deliberate hierarchy on every page that renders partners
  • Marks Convex / Fireship / Nozzle / Vercel / Speakeasy as inactive (no current partnership)
  • Also adds the "Become a Partner" link to the rail header on every page (previously docs-only), restructures the blog index so the rail meets the page edge, and fixes a GamVrec1 width bug that overflowed the docs sidebar

Files

  • src/utils/partners.tsx — adds PartnerTier, partnerTierLabels/Order/Flares (shared icons + gradients), assigns tiers, drops the standalone application-builder tier map (now derived from partner.tier)
  • src/components/PartnersGrid.tsx — three-card layout, gradient L-shape with rounded TL/BR + sharp TR/BL, centered pill tier labels, mobile-responsive cascade with no breakpoint where two tiers share column count
  • src/components/RightRail.tsx — tier grouping with per-tier max widths and a colored top bar per section, centered pill labels, desaturate + brightness-90 logos with hover restoration, hidden scrollbar, [&>*]:shrink-0 so the rail no longer clips its content
  • src/components/DocsLayout.tsx — drops the manual "Become a Partner" overlay (now lives in PartnersRail)
  • src/routes/blog.index.tsx — restructured so the rail extends flush to the right edge and the content panel keeps its own padding
  • src/routes/blog.$.tsx — drops redundant Nozzle/Fireship name filters (covered by status)
  • src/components/Gam.tsxw-full max-w-[300px] so the sidebar promo widget no longer horizontal-overflows the 280px docs rail

Test plan

  • Homepage / landing pages: partner grid renders three tier cards with clear size jumps and colored ribbons
  • Docs pages: right rail renders tier groups (Gold full-width / Silver 2-up / Bronze 3-up), no horizontal overflow, scrolls when total content exceeds viewport, no visible scrollbar
  • Blog index: right rail flush to the page right edge, content panel still has padding
  • Blog post pages: rail content not clipped, "Become a Partner" link visible in the header
  • Application builder: partner suggestions still group correctly into the existing 1/2/3 tier UI (derived from partner.tier)
  • Mobile (<sm), sm (640–767), md, lg, xl: no two tiers share the same column count in the grid
  • Light & dark mode: tier gradients (gold = warm yellow → orange, silver = slate, bronze = amber → stone-brown) read correctly
  • Hovering a rail logo restores its color/brightness

Summary by CodeRabbit

  • New Features

    • Partners are grouped by tier (Gold/Silver/Bronze) with visual headers and tiered layouts.
    • A "Become a Partner" link appears in the partners rail header.
  • Improvements

    • All active partners are now shown (previous exclusions removed).
    • Partner cards and right-rail sizing use tier-driven layouts for consistency.
    • Ad component made responsive; blog and partners page spacing/layout refined.
  • Bug Fixes

    • Removed overlay-style partner link in docs right rail.

Replace score-based dynamic sizing in PartnersGrid and PartnersRail with
a tiered system. Each active partner is assigned a tier (gold, silver,
or bronze) that drives sizing, layout, and accent styling. Score is
retained for in-tier ordering.

- Add `PartnerTier` type, `partnerTierLabels`, `partnerTierOrder`, and
  `partnerTierFlares` (gradients, icons, label colors) shared between
  PartnersGrid and PartnersRail
- PartnersGrid: render each tier as its own Card with a gradient L-shape,
  rounded TL/BR + sharp TR/BL corners, and a centered pill tier label.
  Different per-tier sizing with clear visual jumps between tiers.
  Mobile-responsive (gold 1-col, silver 1-col, bronze 2-col on small)
- PartnersRail: group by tier with per-tier max widths, gradient top
  bars, and centered pill tier labels. Desaturate + brightness-90 logos
  with hover restoration. Hide scrollbars and prevent flex shrink so
  the rail no longer clips its content
- Move `Become a Partner` link into PartnersRail itself so it shows up
  on blog pages too (previously docs-only via overlay)
- Mark Convex, Fireship, Nozzle, Vercel, Speakeasy inactive
- Restructure blog index layout so the rail meets the page edge while
  keeping content padding intact
- Fix GamVrec1 to use `w-full max-w-[300px]` (was hardcoded `w-[300px]`,
  causing horizontal overflow inside the 280px docs rail)
- Tune per-partner image scale on Clerk, Netlify, OpenRouter, PowerSync
  for visual balance within their tier
At the sm breakpoint range (640-767px), both gold and silver were
rendering as 2-col, making them visually identical in column count.
Skip the 2-col phase for silver (jumps from 1-col to 3-col at sm) and
likewise bump bronze from 3-col to 4-col so silver and bronze stay
distinct too.

Final cascade:
- Gold:   1 / 2 / 2 / 2 / 2  (xs / sm / md / lg / xl)
- Silver: 1 / 3 / 3 / 4 / 4
- Bronze: 2 / 4 / 4 / 5 / 6
@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 28, 2026

Deploy Preview for tanstack ready!

Name Link
🔨 Latest commit 674708e
🔍 Latest deploy log https://app.netlify.com/projects/tanstack/deploys/69f0e6a7bfeb4e00080aba41
😎 Deploy Preview https://deploy-preview-867--tanstack.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 30
Accessibility: 90
Best Practices: 83
SEO: 97
PWA: 70
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

📝 Walkthrough

Walkthrough

Partner rendering switched from score-based sizing to a tier system (gold/silver/bronze); partners are grouped and sorted by tier/score. Active partner filtering now includes all status === 'active'. DocsLayout overlay and its click tracking removed. Ad container made responsive.

Changes

Cohort / File(s) Summary
Partner Tier System
src/utils/partners.tsx
Adds PartnerTier (`'gold'
Tiered Partner UI & Layout
src/components/PartnersGrid.tsx, src/components/RightRail.tsx, src/routes/partners.index.tsx
Replaces score-derived sizing with tier-driven sizing/layout; partitions partners into gold/silver/bronze, sorts within tiers by score, renders tier headers (flare + label), applies per-tier sizing classes, preserves cumulative slotIndex for analytics, and updates rail scroll styling. RightRail adds an external “Become a Partner” header link with click tracking.
Docs & Blog Integration
src/components/DocsLayout.tsx, src/routes/blog.index.tsx, src/routes/blog.$.tsx
activePartners filter simplified to include all partners with status === 'active' (removed explicit exclusions); DocsLayout removed the overlay “Become a Partner” link and its associated tracking; blog index layout container sizes and RightRail positioning adjusted.
Ad Unit Responsiveness
src/components/Gam.tsx
GamVrec1 container changed from fixed w-[300px] to responsive w-full max-w-[300px], retaining twMerge class merging and props.className.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐇 I hopped through tiers of gold and bronze tonight,
Rows rearranged into tidy light.
Partners shimmer in ordered bands,
Rails and ads dance by gentle hands.
A carrot-cheer for layouts done just right. 🥕✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: introducing a three-tier (gold/silver/bronze) system for displaying partners, which is the core objective across all modified files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch taren/quizzical-babbage-07d1ad

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/utils/partners.tsx (1)

62-63: Use partnerTiers as the single source of truth.

This export is now the canonical tier list, but src/components/PartnersGrid.tsx and src/components/RightRail.tsx still hardcode the same tuple. Importing partnerTiers there avoids silently dropping a future tier.

♻️ Suggested follow-up
-const tiers: Array<PartnerTier> = ['gold', 'silver', 'bronze']
+const tiers = partnerTiers
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utils/partners.tsx` around lines 62 - 63, The components currently
hardcode the tier tuple instead of using the canonical exported list; update
both PartnersGrid and RightRail to import partnerTiers (and PartnerTier if a
type is needed) from the utils module and replace the hardcoded array/tuple with
partnerTiers so new tiers are honored automatically; ensure any type annotations
that referenced the literal tuple use the exported PartnerTier type or derive
from partnerTiers to keep a single source of truth.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/utils/partners.tsx`:
- Around line 62-63: The components currently hardcode the tier tuple instead of
using the canonical exported list; update both PartnersGrid and RightRail to
import partnerTiers (and PartnerTier if a type is needed) from the utils module
and replace the hardcoded array/tuple with partnerTiers so new tiers are honored
automatically; ensure any type annotations that referenced the literal tuple use
the exported PartnerTier type or derive from partnerTiers to keep a single
source of truth.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bd590352-0e3b-4c9d-9d11-2bc57a03479b

📥 Commits

Reviewing files that changed from the base of the PR and between e117e0e and aba97fb.

📒 Files selected for processing (7)
  • src/components/DocsLayout.tsx
  • src/components/Gam.tsx
  • src/components/PartnersGrid.tsx
  • src/components/RightRail.tsx
  • src/routes/blog.$.tsx
  • src/routes/blog.index.tsx
  • src/utils/partners.tsx

Switch from per-cell `group-hover` to a named `group/rail` on the
PartnersRail outer container. Hovering anywhere within the rail now
restores all logos to full color and brightness in one motion, rather
than only the cell directly under the cursor.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/components/RightRail.tsx (1)

103-113: Derive the rendered tier list from partnerTierOrder.

This block hard-codes ['gold', 'silver', 'bronze'] and then separately sorts with partnerTierOrder. That creates drift risk: adding or reordering a tier in ~/utils/partners can leave this component rendering stale tiers. Prefer deriving the list from partnerTierOrder directly.

♻️ Proposed refactor
-  const tiers: Array<PartnerTier> = ['gold', 'silver', 'bronze']
+  const tiers = (Object.entries(partnerTierOrder) as Array<[PartnerTier, number]>)
+    .sort((a, b) => a[1] - b[1])
+    .map(([tier]) => tier)

   const rowsByTier = tiers
     .map((tier) => ({
       tier,
       partners: partners
         .filter((partner) => (partner.tier ?? 'bronze') === tier)
         .sort((a, b) => b.score - a.score),
     }))
     .filter((row) => row.partners.length > 0)
-    .sort((a, b) => partnerTierOrder[a.tier] - partnerTierOrder[b.tier])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/RightRail.tsx` around lines 103 - 113, The tiers array is
hard-coded; replace it by deriving the tier list from partnerTierOrder so the
component follows the canonical ordering: compute tiers as
Object.keys(partnerTierOrder) cast to Array<PartnerTier> (or equivalent) and
then keep the existing rowsByTier logic (filtering partners, sorting by score)
but map over that derived tiers list instead of ['gold','silver','bronze'];
update references to the tiers variable used when building rowsByTier (and
ensure PartnerTier typing remains correct).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/RightRail.tsx`:
- Around line 126-139: The Become a Partner CTA inside the RightRail component
is hidden on small screens because RightRail uses the rail’s responsive classes
(hidden sm:block / hidden md:block); move or duplicate the anchor so it always
renders on phone viewports by either extracting the <a> block (the anchor that
calls trackEvent with analyticsPlacement and analyticsProperties) into a
top-level container that has no hidden sm:block classes or add a small-screen
fallback outside RightRail (e.g., render the same anchor conditionally when
viewport is < sm); ensure the same onClick handler
(trackEvent('become_partner_clicked', { placement: analyticsPlacement,
...analyticsProperties })) and classes are preserved so analytics and styling
remain consistent.
- Around line 225-228: The grayscale-to-color transition is only applied on
hover via the "group-hover/rail:grayscale-0 group-hover/rail:brightness-100"
classes; update the class list used in the JSX (the className passed into
twMerge for the element that includes layout.logoMaxWidth) to also include the
equivalent keyboard focus variant "group-focus-within/rail:grayscale-0
group-focus-within/rail:brightness-100" so that focus via keyboard receives the
same affordance as hover while keeping the existing transition classes intact.

---

Nitpick comments:
In `@src/components/RightRail.tsx`:
- Around line 103-113: The tiers array is hard-coded; replace it by deriving the
tier list from partnerTierOrder so the component follows the canonical ordering:
compute tiers as Object.keys(partnerTierOrder) cast to Array<PartnerTier> (or
equivalent) and then keep the existing rowsByTier logic (filtering partners,
sorting by score) but map over that derived tiers list instead of
['gold','silver','bronze']; update references to the tiers variable used when
building rowsByTier (and ensure PartnerTier typing remains correct).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 377a9006-1cce-4bc7-9b2a-322995bc5e32

📥 Commits

Reviewing files that changed from the base of the PR and between aba97fb and 654dfc4.

📒 Files selected for processing (1)
  • src/components/RightRail.tsx

Comment on lines +126 to +139
<a
href="https://docs.google.com/document/d/1Hg2MzY2TU6U3hFEZ3MLe2oEOM3JS4-eByti3kdJU3I8"
target="_blank"
rel="noopener noreferrer"
className="font-medium opacity-60 hover:opacity-100 text-xs hover:underline"
onClick={() => {
trackEvent('become_partner_clicked', {
placement: analyticsPlacement,
...analyticsProperties,
})
}}
>
Become a Partner
</a>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

The new CTA is still unavailable on mobile.

Because this link now lives inside RightRail, it inherits the rail’s hidden sm:block / hidden md:block behavior and disappears below the breakpoint. That undercuts the “site-wide” rollout for phone-sized viewports. Please add a small-screen fallback outside the rail or move the CTA to a container that always renders.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/RightRail.tsx` around lines 126 - 139, The Become a Partner
CTA inside the RightRail component is hidden on small screens because RightRail
uses the rail’s responsive classes (hidden sm:block / hidden md:block); move or
duplicate the anchor so it always renders on phone viewports by either
extracting the <a> block (the anchor that calls trackEvent with
analyticsPlacement and analyticsProperties) into a top-level container that has
no hidden sm:block classes or add a small-screen fallback outside RightRail
(e.g., render the same anchor conditionally when viewport is < sm); ensure the
same onClick handler (trackEvent('become_partner_clicked', { placement:
analyticsPlacement, ...analyticsProperties })) and classes are preserved so
analytics and styling remain consistent.

Comment on lines +225 to +228
className={twMerge(
'w-full flex items-center justify-center mx-auto grayscale brightness-90 group-hover/rail:grayscale-0 group-hover/rail:brightness-100 transition-[filter] duration-500 ease-out',
layout.logoMaxWidth,
)}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Mirror the rail-level hover state for keyboard focus.

The new full-color treatment is hover-only right now. When users tab through the links, the logos stay grayscale because there’s no group-focus-within/rail equivalent. Please add a focus path so keyboard navigation gets the same affordance.

⌨️ Proposed fix
       <div
         className={twMerge(
-          'w-full flex items-center justify-center mx-auto grayscale brightness-90 group-hover/rail:grayscale-0 group-hover/rail:brightness-100 transition-[filter] duration-500 ease-out',
+          'w-full flex items-center justify-center mx-auto grayscale brightness-90 group-hover/rail:grayscale-0 group-hover/rail:brightness-100 group-focus-within/rail:grayscale-0 group-focus-within/rail:brightness-100 transition-[filter] duration-500 ease-out',
           layout.logoMaxWidth,
         )}
       >
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
className={twMerge(
'w-full flex items-center justify-center mx-auto grayscale brightness-90 group-hover/rail:grayscale-0 group-hover/rail:brightness-100 transition-[filter] duration-500 ease-out',
layout.logoMaxWidth,
)}
className={twMerge(
'w-full flex items-center justify-center mx-auto grayscale brightness-90 group-hover/rail:grayscale-0 group-hover/rail:brightness-100 group-focus-within/rail:grayscale-0 group-focus-within/rail:brightness-100 transition-[filter] duration-500 ease-out',
layout.logoMaxWidth,
)}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/RightRail.tsx` around lines 225 - 228, The grayscale-to-color
transition is only applied on hover via the "group-hover/rail:grayscale-0
group-hover/rail:brightness-100" classes; update the class list used in the JSX
(the className passed into twMerge for the element that includes
layout.logoMaxWidth) to also include the equivalent keyboard focus variant
"group-focus-within/rail:grayscale-0 group-focus-within/rail:brightness-100" so
that focus via keyboard receives the same affordance as hover while keeping the
existing transition classes intact.

tannerlinsley and others added 2 commits April 28, 2026 10:54
Active partners on /partners now render as three sections (Gold,
Silver, Bronze) with section dividers and a centered tier-color pill
header. Each tier uses its own card sizing tailored for the dedicated
partners page (Gold = 2-up large cards with full description, Silver =
3-up medium with description, Bronze = 4-up compact, name + tagline).

When a library filter or the previous-partners view is active, the
flat 3-col grid is preserved since tier grouping doesn't apply.

Also:
- Drop the Lifetime Support Share section and its NetlifyImage import
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
src/routes/partners.index.tsx (2)

460-479: Give each tier section an actual heading.

These new groups are rendered as semantic sections, but the label is only a styled div. That leaves the sections effectively unnamed for heading/landmark navigation. Making the pill an h2 and connecting it with aria-labelledby would preserve the design and improve accessibility.

♿ Suggested adjustment
-function TierSectionHeader({ tier }: { tier: PartnerTier }) {
+function TierSectionHeader({
+  tier,
+  headingId,
+}: {
+  tier: PartnerTier
+  headingId: string
+}) {
   const flare = partnerTierFlares[tier]
   return (
     <div className="flex items-center gap-4 mb-8">
       <div
         className={`h-px flex-1 bg-gradient-to-r from-transparent ${flare.gradientStops}`}
       />
-      <div
+      <h2
+        id={headingId}
         className={`flex items-center gap-2 px-3 py-1 rounded-full ${flare.labelColor}`}
       >
         <span className={flare.iconColor}>{flare.icon}</span>
         <span className="text-xs uppercase tracking-[0.2em] font-bold">
           {partnerTierLabels[tier]}
         </span>
-      </div>
+      </h2>
       <div
         className={`h-px flex-1 bg-gradient-to-l from-transparent ${flare.gradientStops}`}
       />
     </div>
   )
 }
@@
-        <section key={section.tier}>
-          <TierSectionHeader tier={section.tier} />
+        <section
+          key={section.tier}
+          aria-labelledby={`partner-tier-${section.tier}`}
+        >
+          <TierSectionHeader
+            tier={section.tier}
+            headingId={`partner-tier-${section.tier}`}
+          />

Also applies to: 503-524

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/partners.index.tsx` around lines 460 - 479, The TierSectionHeader
currently renders the tier label as a styled div, leaving semantic sections
unnamed; update TierSectionHeader to render the pill as a real heading element
(e.g., an h2) using the existing flare styling (partnerTierFlares,
partnerTierLabels, flare.icon, flare.* classes) and give the parent semantic
section an aria-labelledby that points to the heading's id so screen readers can
identify the section; ensure each generated heading has a unique id (e.g.,
derived from the tier value) and keep the visual styling identical to preserve
design.

310-350: Derive tier literals from the shared partner config.

CardSize and tiers both re-state the gold/silver/bronze set that already exists in src/utils/partners.tsx. The hardcoded tiers array is the risky part: if a new PartnerTier is added later, this page will silently stop rendering that tier because Array<PartnerTier> is not exhaustive. Prefer type CardSize = PartnerTier | 'flat' and iterate partnerTiers directly.

♻️ Suggested cleanup
 import {
   partners,
   PartnerImage,
+  partnerTiers,
   partnerTierFlares,
   partnerTierLabels,
   partnerTierOrder,
   type PartnerTier,
 } from '~/utils/partners'
@@
-type CardSize = 'gold' | 'silver' | 'bronze' | 'flat'
+type CardSize = PartnerTier | 'flat'
@@
-  const tiers: Array<PartnerTier> = ['gold', 'silver', 'bronze']
+  const tiers = partnerTiers

Also applies to: 489-499

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/partners.index.tsx` around lines 310 - 350, Replace the hardcoded
CardSize union and tier list with the shared PartnerTier definitions: change the
CardSize type to "PartnerTier | 'flat'" (referencing PartnerTier) and rebuild
cardSizeLayout so its keys are derived from partnerTiers plus the 'flat' entry
(ensure 'flat' retains its layout). Update any other duplicated tier arrays (the
similar block later around the other card layout) to iterate partnerTiers
instead of a hardcoded ['gold','silver','bronze'] so adding a new PartnerTier
will automatically be included; keep existing layout values mapped to each
PartnerTier name and preserve the special 'flat' mapping.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/routes/partners.index.tsx`:
- Around line 460-479: The TierSectionHeader currently renders the tier label as
a styled div, leaving semantic sections unnamed; update TierSectionHeader to
render the pill as a real heading element (e.g., an h2) using the existing flare
styling (partnerTierFlares, partnerTierLabels, flare.icon, flare.* classes) and
give the parent semantic section an aria-labelledby that points to the heading's
id so screen readers can identify the section; ensure each generated heading has
a unique id (e.g., derived from the tier value) and keep the visual styling
identical to preserve design.
- Around line 310-350: Replace the hardcoded CardSize union and tier list with
the shared PartnerTier definitions: change the CardSize type to "PartnerTier |
'flat'" (referencing PartnerTier) and rebuild cardSizeLayout so its keys are
derived from partnerTiers plus the 'flat' entry (ensure 'flat' retains its
layout). Update any other duplicated tier arrays (the similar block later around
the other card layout) to iterate partnerTiers instead of a hardcoded
['gold','silver','bronze'] so adding a new PartnerTier will automatically be
included; keep existing layout values mapped to each PartnerTier name and
preserve the special 'flat' mapping.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4f14f691-9086-4e2f-9c20-7e70c0ff413f

📥 Commits

Reviewing files that changed from the base of the PR and between 654dfc4 and 674708e.

📒 Files selected for processing (1)
  • src/routes/partners.index.tsx

@tannerlinsley tannerlinsley merged commit 098eda8 into main Apr 30, 2026
8 checks passed
@tannerlinsley tannerlinsley deleted the taren/quizzical-babbage-07d1ad branch April 30, 2026 18:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant