Menu

Change language

GitHub repo

Logo Clouds

blockmarketing

Logo-cloud section set: a static trusted-by grid, single- and tri-row infinite marquees, a categorized filter grid with testimonial modal, a grayscale-hover wall, and a ticker with sector filters and telemetry hover cards.

Installation

$npx shadcn@latest add https://uipkge.dev/r/lit/logos.json
Manifest:https://uipkge.dev/r/lit/logos.jsonInstalls to:src/uip/blocks/logos/

Variants

Loading interactive previews…

Props

NameType / ValuesDefaultRequired
variantLogosVariantgridoptional

Schema

Type aliases exported from this item's source. Use these to shape the data you pass in.

Logo
type Logo { label: string; d: string }

const ROW_2: Logo[] = [
  {
    label: 'React',
    d: 'M14.23 12.004a2.236 2.236 0 0 1-2.235 2.236 2.236 2.236 0 0 1-2.236-2.236 2.236 2.236 0 0 1 2.235-2.236 2.236 2.236 0 0 1 2.236 2.236zm2.648-10.69c-1.346 0-3.107.96-4.888 2.622-1.78-1.653-3.542-2.602-4.887-2.602-.41 0-.783.093-1.106.278-1.375.793-1.683 3.264-.973 6.365C1.98 8.917 0 10.42 0 12.004c0 1.59 1.99 3.097 5.043 4.03-.704 3.113-.39 5.588.988 6.38.32.187.69.275 1.102.275 1.345 0 3.107-.96 4.888-2.624 1.78 1.654 3.542 2.603 4.887 2.603.41 0 .783-.09 1.106-.275 1.374-.792 1.683-3.263.973-6.365C22.02 15.096 24 13.59 24 12.004c0-1.59-1.99-3.097-5.043-4.032.704-3.11.39-5.587-.988-6.38-.318-.184-.688-.277-1.092-.278zm-.005 1.09v.006c.225 0 .406.044.558.127.666.382.955 1.835.73 3.704-.054.46-.142.945-.25 1.44-.96-.236-2.006-.417-3.107-.534-.66-.905-1.345-1.727-2.035-2.447 1.592-1.48 3.087-2.292 4.105-2.295zm-9.77.02c1.012 0 2.514.808 4.11 2.28-.686.72-1.37 1.537-2.02 2.442-1.107.117-2.154.298-3.113.538-.112-.49-.195-.964-.254-1.42-.23-1.868.054-3.32.714-3.707.19-.09.4-.127.563-.132zm4.882 3.05c.455.468.91.992 1.36 1.564-.44-.02-.89-.034-1.345-.034-.46 0-.915.01-1.36.034.44-.572.895-1.096 1.345-1.565zM12 8.1c.74 0 1.477.034 2.202.093.406.582.802 1.203 1.183 1.86.372.64.71 1.29 1.018 1.946-.308.655-.646 1.31-1.013 1.95-.38.66-.773 1.288-1.18 1.87-.728.063-1.466.098-2.21.098-.74 0-1.477-.035-2.202-.093-.406-.582-.802-1.204-1.183-1.86-.372-.64-.71-1.29-1.018-1.946.303-.657.646-1.313 1.013-1.954.38-.66.773-1.286 1.18-1.868.728-.064 1.466-.098 2.21-.098zm-3.635.254c-.24.377-.48.763-.704 1.16-.225.39-.435.782-.635 1.174-.265-.656-.49-1.31-.676-1.947.64-.15 1.315-.283 2.015-.386zm7.26 0c.695.103 1.365.23 2.006.387-.18.632-.405 1.282-.66 1.933-.2-.39-.41-.783-.64-1.174-.225-.392-.465-.774-.705-1.146zm3.063.675c.484.15.944.317 1.375.498 1.732.74 2.852 1.708 2.852 2.476-.005.768-1.125 1.74-2.857 2.475-.42.18-.88.342-1.355.493-.28-.958-.646-1.956-1.1-2.98.45-1.017.81-2.01 1.085-2.964zm-13.395.004c.278.96.645 1.957 1.1 2.98-.45 1.017-.812 2.01-1.086 2.964-.484-.15-.944-.317-1.375-.498-1.732-.74-2.852-1.708-2.852-2.476.005-.768 1.125-1.74 2.857-2.475.42-.18.88-.342 1.355-.493.28.958.646 1.956 1.1 2.98-.45 1.017-.81 2.01-1.085 2.964zM7.08 13.45c.26.65.48 1.3.66 1.93-.64.15-1.31.28-2.01.39.24-.38.48-.76.7-1.15.23-.4.44-.78.65-1.17zm9.84 0c.21.39.42.77.65 1.17.22.39.46.77.7 1.15-.7-.11-1.37-.24-2.01-.39.18-.63.4-1.28.66-1.93zm-7.26.575c.64.15 1.31.28 2.01.39-.24.38-.48.76-.7 1.15-.23.4-.44.78-.65 1.17-.26-.65-.48-1.3-.66-1.93.64-.15 1.31-.28 0 0zm4.68 0c.26.65.48 1.3.66 1.93-.64.15-1.31.28-2.01.39.24-.38.48-.76.7-1.15.23-.4.44-.78.65-1.17zM12 15.9c.74 0 1.477-.034 2.202-.093.406-.582.802-1.203 1.183-1.86.372-.64.71-1.29 1.018-1.946-.308-.655-.646-1.31-1.013-1.95-.38-.66-.773-1.288-1.18-1.87-.728-.063-1.466-.098-2.21-.098-.74 0-1.477.035-2.202.093-.406.582-.802 1.204-1.183 1.86-.372.64-.71 1.29-1.018 1.946.303.657.646 1.313 1.013 1.954.38.66.773 1.286 1.18 1.868.728.064 1.466.098 2.21.098zm-3.635-.254c-.24-.377-.48-.763-.704-1.16-.225-.39-.435-.782-.635-1.174-.265.656-.49 1.31-.676 1.947.64.15 1.315.283 2.015.386zm7.26 0c.695-.103 1.365-.23 2.006-.387-.18-.632-.405-1.282-.66-1.933-.2.39-.41.783-.64 1.174-.225.392-.465.774-.705 1.146zm-9.697-.672c-.484-.15-.944-.317-1.375-.498-1.732-.74-2.852-1.708-2.852-2.476.005-.768 1.125-1.74 2.857-2.475.42-.18.88-.342 1.355-.493.28.958.646 1.956 1.1 2.98-.45 1.017-.81 2.01-1.085 2.964zm13.395-.004c-.278-.96-.645-1.957-1.1-2.98.45-1.017.812-2.01 1.086-2.964.484.15.944.317 1.375.498 1.732.74 2.852 1.708 2.852 2.476-.005.768-1.125 1.74-2.857 2.475-.42.18-.88.342-1.355.493-.28-.958-.646-1.956-1.1-2.98.45-1.017.81-2.01 1.085-2.964zM7.08 10.55c-.26-.65-.48-1.3-.66-1.93.64-.15 1.31-.28 2.01-.39-.24.38-.48.76-.7 1.15-.23.4-.44.78-.65 1.17zm9.84 0c-.21-.39-.42-.77-.65-1.17-.22-.39-.46-.77-.7-1.15.7.11 1.37.24 2.01.39-.18.63-.4 1.28-.66 1.93zm-7.26-.575c-.64-.15-1.31-.28-2.01-.39.24-.38.48-.76.7-1.15.23-.4.44-.78.65-1.17.26.65.48 1.3.66 1.93-.64.15-1.31.28 0 0zm4.68 0c-.26-.65-.48-1.3-.66-1.93.64-.15 1.31-.28 2.01-.39-.24.38-.48.76-.7 1.15-.23.4-.44.78-.65 1.17zM9.348 3.05c-.225 0-.406.044-.558.127-.666.382-.955 1.835-.73 3.704.054.46.142.945.25 1.44.96-.236 2.006-.417 3.107-.534.66-.905 1.345-1.727 2.035-2.447-1.592-1.48-3.087-2.292-4.105-2.295zm9.77.02c-1.012 0-2.514.808-4.11 2.28.686.72 1.37 1.537 2.02 2.442 1.107.117 2.154.298 3.113.538.112.49.195.964.254 1.42.23 1.868-.054 3.32-.714 3.707-.19.09-.4.127-.563.132z',
  },
  {
    label: 'Next.js',
    d: 'M18.665 21.978C16.758 23.255 14.465 24 12 24 5.377 24 0 18.623 0 12S5.377 0 12 0s12 5.377 12 12c0 3.583-1.574 6.801-4.067 9.001L9.219 7.2H7.2v9.596h1.615V9.251l9.85 12.727Zm-3.332-8.533 1.6 2.061V7.2h-1.6v6.245Z',
  },
  {
    label: 'Vue.js',
    d: 'M24,1.61H14.06L12,5.16,9.94,1.61H0L12,22.39ZM12,14.08,5.16,2.23H9.59L12,6.41l2.41-4.18h4.43Z',
  },
  {
    label: 'Tailwind',
    d: 'M12.001,4.8c-3.2,0-5.2,1.6-6,4.8c1.2-1.6,2.6-2.2,4.2-1.8c0.913,0.228,1.565,0.89,2.288,1.624 C13.666,10.618,15.027,12,18.001,12c3.2,0,5.2-1.6,6-4.8c-1.2,1.6-2.6,2.2-4.2,1.8c-0.913-0.228-1.565-0.89-2.288-1.624 C16.337,6.182,14.976,4.8,12.001,4.8z M6.001,12c-3.2,0-5.2,1.6-6,4.8c1.2-1.6,2.6-2.2,4.2-1.8c0.913,0.228,1.565,0.89,2.288,1.624 c1.177,1.194,2.538,2.576,5.512,2.576c3.2,0,5.2-1.6,6-4.8c-1.2,1.6-2.6,2.2-4.2,1.8c-0.913-0.228-1.565-0.89-2.288-1.624 C10.337,13.382,8.976,12,6.001,12z',
  },
  {
    label: 'Supabase',
    d: 'M11.9 1.036c-.015-.986-1.26-1.41-1.874-.637L.764 12.05C-.33 13.427.65 15.455 2.409 15.455h9.579l.113 7.51c.014.985 1.259 1.408 1.873.636l9.262-11.653c1.093-1.375.113-3.403-1.645-3.403h-9.642z',
  },
  {
    label: 'GitHub',
    d: 'M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12',
  },
]

const ROW_3: Logo[] = [
  {
    label: 'Anthropic',
    d: 'M17.3041 3.541h-3.6718l6.696 16.918H24Zm-10.6082 0L0 20.459h3.7442l1.3693-3.5527h7.0052l1.3693 3.5528h3.7442L10.5363 3.5409Zm-.3712 10.2232 2.2914-5.9456 2.2914 5.9456Z',
  },
  {
    label: 'Sentry',
    d: 'M13.91 2.505c-.873-1.448-2.972-1.448-3.844 0L6.904 7.92a15.478 15.478 0 0 1 8.53 12.811h-2.221A13.301 13.301 0 0 0 5.784 9.814l-2.926 5.06a7.65 7.65 0 0 1 4.435 5.848H2.194a.365.365 0 0 1-.298-.534l1.413-2.402a5.16 5.16 0 0 0-1.614-.913L.296 19.275a2.182 2.182 0 0 0 .812 2.999 2.24 2.24 0 0 0 1.086.288h6.983a9.322 9.322 0 0 0-3.845-8.318l1.11-1.922a11.47 11.47 0 0 1 4.95 10.24h5.915a17.242 17.242 0 0 0-7.885-15.28l2.244-3.845a.37.37 0 0 1 .504-.13c.255.14 9.75 16.708 9.928 16.9a.365.365 0 0 1-.327.543h-2.287c.029.612.029 1.223 0 1.831h2.297a2.206 2.206 0 0 0 1.922-3.31z',
  },
  {
    label: 'PlanetScale',
    d: 'M0 12C0 5.373 5.373 0 12 0c4.873 0 9.067 2.904 10.947 7.077l-15.87 15.87a11.981 11.981 0 0 1-1.935-1.099L14.99 12H12l-8.485 8.485A11.962 11.962 0 0 1 0 12Zm12.004 12L24 12.004C23.998 18.628 18.628 23.998 12.004 24Z',
  },
  {
    label: 'Render',
    d: 'M18.263.007c-3.121-.147-5.744 2.109-6.192 5.082-.018.138-.045.272-.067.405-.696 3.703-3.936 6.507-7.827 6.507-1.388 0-2.691-.356-3.825-.979a.2024.2024 0 0 0-.302.178V24H12v-8.999c0-1.656 1.338-3 2.987-3h2.988c3.382 0 6.103-2.817 5.97-6.244-.12-3.084-2.61-5.603-5.682-5.75',
  },
  {
    label: 'Railway',
    d: 'M.113 10.27A13.026 13.026 0 000 11.48h18.23c-.064-.125-.15-.237-.235-.347-3.117-4.027-4.793-3.677-7.19-3.78-.8-.034-1.34-.048-4.524-.048-1.704 0-3.555.005-5.358.01-.234.63-.459 1.24-.567 1.737h9.342v1.216H.113v.002zm18.26 2.426H.009c.02.326.05.645.094.961h16.955c.754 0 1.179-.429 1.315-.96zm-17.318 4.28s2.81 6.902 10.93 7.024c4.855 0 9.027-2.883 10.92-7.024H1.056zM11.988 0C7.5 0 3.593 2.466 1.531 6.108l4.75-.005v-.002c3.71 0 3.849.016 4.573.047l.448.016c1.563.052 3.485.22 4.996 1.364.82.621 2.007 1.99 2.712 2.965.654.902.842 1.94.396 2.934-.408.914-1.289 1.458-2.353 1.458H.391s.099.42.249.886h22.748A12.026 12.026 0 0024 12.005C24 5.377 18.621 0 11.988 0z',
  },
  {
    label: 'Stripe',
    d: 'M13.976 9.15c-2.172-.806-3.356-1.426-3.356-2.409 0-.831.683-1.305 1.901-1.305 2.227 0 4.515.858 6.09 1.631l.89-5.494C18.252.975 15.697 0 12.165 0 9.667 0 7.589.654 6.104 1.872 4.56 3.147 3.757 4.992 3.757 7.218c0 4.039 2.467 5.76 6.476 7.219 2.585.92 3.445 1.574 3.445 2.583 0 .98-.84 1.545-2.354 1.545-1.875 0-4.965-.921-6.99-2.109l-.9 5.555C5.175 22.99 8.385 24 11.714 24c2.641 0 4.843-.624 6.328-1.813 1.664-1.305 2.525-3.236 2.525-5.732 0-4.128-2.524-5.851-6.594-7.305h.003z',
  },
]

const grayscaleCustomers = [
  'Northwind',
  'Halden',
  'Verity',
  'Calder',
  'Ridgeway',
  'Ashford',
  'Brightmoor',
  'Kesteven',
  'Marlowe',
  'Thornbury',
  'Wexley',
  'Alderton',
]

interface CustomerEntity {
  id: string
  name: string
  category: 'cloud' | 'devtools' | 'fintech' | 'ai'
  tier: string
  scale: string
  quote: string
  author: string
  title: string
}
BrandPartner
interface BrandPartner {
  id: string
  name: string
  category: 'devtools' | 'fintech' | 'enterprise'
  role: string
  metric: string
  region: string
}
HTMLElementTagNameMap
interface HTMLElementTagNameMap {
    'uip-logos': UipLogos
  }
}

Files installed (1)

  • src/uip/blocks/logos/logos.ts40.6 kB
    import { LitElement, css, html, nothing } from 'lit'
    import {
      ArrowRight,
      Brain,
      Building2,
      Cloud,
      Globe,
      Pause,
      Play,
      Quote,
      ShieldCheck,
      Terminal,
      X,
      type IconNode,
    } from 'lucide'
    import { cn } from '../../lib/utils'
    import { tailwind } from '../../lib/styles'
    import { ThemeController } from '../../lib/theme'
    import { icon } from '../../lib/icon'
    // Side-effect imports: register the composed elements for standalone use
    // (consumers who install only this block still get working primitives).
    import '../../components/badge/badge'
    import '../../components/button/button'
    import '../../components/card/card'
    import '../../components/separator/separator'
    
    export type LogosVariant = 'grid' | 'marquee' | 'marquee-rows' | 'categorized' | 'ticker' | 'grayscale'
    
    // Sample logo set sourced from simpleicons.org (MIT). Swap these paths and
    // labels for your own customer logos before shipping.
    const LOGOS = [
      {
        label: 'Vercel',
        d: 'm12 1.608 12 20.784H0Z',
      },
      {
        label: 'Stripe',
        d: 'M13.976 9.15c-2.172-.806-3.356-1.426-3.356-2.409 0-.831.683-1.305 1.901-1.305 2.227 0 4.515.858 6.09 1.631l.89-5.494C18.252.975 15.697 0 12.165 0 9.667 0 7.589.654 6.104 1.872 4.56 3.147 3.757 4.992 3.757 7.218c0 4.039 2.467 5.76 6.476 7.219 2.585.92 3.445 1.574 3.445 2.583 0 .98-.84 1.545-2.354 1.545-1.875 0-4.965-.921-6.99-2.109l-.9 5.555C5.175 22.99 8.385 24 11.714 24c2.641 0 4.843-.624 6.328-1.813 1.664-1.305 2.525-3.236 2.525-5.732 0-4.128-2.524-5.851-6.594-7.305h.003z',
      },
      {
        label: 'Linear',
        d: 'M2.886 4.18A11.982 11.982 0 0 1 11.99 0C18.624 0 24 5.376 24 12.009c0 3.64-1.62 6.903-4.18 9.105L2.887 4.18ZM1.817 5.626l16.556 16.556c-.524.33-1.075.62-1.65.866L.951 7.277c.247-.575.537-1.126.866-1.65ZM.322 9.163l14.515 14.515c-.71.172-1.443.282-2.195.322L0 11.358a12 12 0 0 1 .322-2.195Zm-.17 4.862 9.823 9.824a12.02 12.02 0 0 1-9.824-9.824Z',
      },
      {
        label: 'Notion',
        d: 'M4.459 4.208c.746.606 1.026.56 2.428.466l13.215-.793c.28 0 .047-.28-.046-.326L17.86 1.968c-.42-.326-.981-.7-2.055-.607L3.01 2.295c-.466.046-.56.28-.374.466zm.793 3.08v13.904c0 .747.373 1.027 1.214.98l14.523-.84c.841-.046.935-.56.935-1.167V6.354c0-.606-.233-.933-.748-.887l-15.177.887c-.56.047-.747.327-.747.933zm14.337.745c.093.42 0 .84-.42.888l-.7.14v10.264c-.608.327-1.168.514-1.635.514-.748 0-.935-.234-1.495-.933l-4.577-7.186v6.952L12.21 19s0 .84-1.168.84l-3.222.186c-.093-.186 0-.653.327-.746l.84-.233V9.854L7.822 9.76c-.094-.42.14-1.026.793-1.073l3.456-.233 4.764 7.279v-6.44l-1.215-.139c-.093-.514.28-.887.747-.933zM1.936 1.035l13.31-.98c1.634-.14 2.055-.047 3.082.7l4.249 2.986c.7.513.934.653.934 1.213v16.378c0 1.026-.373 1.634-1.68 1.726l-15.458.934c-.98.047-1.448-.093-1.962-.747l-3.129-4.06c-.56-.747-.793-1.306-.793-1.96V2.667c0-.839.374-1.54 1.447-1.632z',
      },
      {
        label: 'Figma',
        d: 'M15.852 8.981h-4.588V0h4.588c2.476 0 4.49 2.014 4.49 4.49s-2.014 4.491-4.49 4.491zM12.735 7.51h3.117c1.665 0 3.019-1.355 3.019-3.019s-1.355-3.019-3.019-3.019h-3.117V7.51zm0 1.471H8.148c-2.476 0-4.49-2.014-4.49-4.49S5.672 0 8.148 0h4.588v8.981zm-4.587-7.51c-1.665 0-3.019 1.355-3.019 3.019s1.354 3.02 3.019 3.02h3.117V1.471H8.148zm4.587 15.019H8.148c-2.476 0-4.49-2.014-4.49-4.49s2.014-4.49 4.49-4.49h4.588v8.98zM8.148 8.981c-1.665 0-3.019 1.355-3.019 3.019s1.355 3.019 3.019 3.019h3.117V8.981H8.148zM8.172 24c-2.489 0-4.515-2.014-4.515-4.49s2.014-4.49 4.49-4.49h4.588v4.441c0 2.503-2.047 4.539-4.563 4.539zm-.024-7.51a3.023 3.023 0 0 0-3.019 3.019c0 1.665 1.365 3.019 3.044 3.019 1.705 0 3.093-1.376 3.093-3.068v-2.97H8.148zm7.704 0h-.098c-2.476 0-4.49-2.014-4.49-4.49s2.014-4.49 4.49-4.49h.098c2.476 0 4.49 2.014 4.49 4.49s-2.014 4.49-4.49 4.49zm-.097-7.509c-1.665 0-3.019 1.355-3.019 3.019s1.355 3.019 3.019 3.019h.098c1.665 0 3.019-1.355 3.019-3.019s-1.355-3.019-3.019-3.019h-.098z',
      },
      {
        label: 'Loom',
        d: 'M24 10.665h-7.018l6.078-3.509-1.335-2.312-6.078 3.509 3.508-6.077L16.843.94l-3.508 6.077V0h-2.67v7.018L7.156.94 4.844 2.275l3.509 6.077-6.078-3.508L.94 7.156l6.078 3.509H0v2.67h7.017L.94 16.844l1.335 2.313 6.077-3.508-3.509 6.077 2.312 1.335 3.509-6.078V24h2.67v-7.017l3.508 6.077 2.312-1.335-3.509-6.078 6.078 3.509 1.335-2.313-6.077-3.508h7.017v-2.67H24zm-12 4.966a3.645 3.645 0 1 1 0-7.29 3.645 3.645 0 0 1 0 7.29z',
      },
    ]
    
    type Logo = { label: string; d: string }
    
    const ROW_2: Logo[] = [
      {
        label: 'React',
        d: 'M14.23 12.004a2.236 2.236 0 0 1-2.235 2.236 2.236 2.236 0 0 1-2.236-2.236 2.236 2.236 0 0 1 2.235-2.236 2.236 2.236 0 0 1 2.236 2.236zm2.648-10.69c-1.346 0-3.107.96-4.888 2.622-1.78-1.653-3.542-2.602-4.887-2.602-.41 0-.783.093-1.106.278-1.375.793-1.683 3.264-.973 6.365C1.98 8.917 0 10.42 0 12.004c0 1.59 1.99 3.097 5.043 4.03-.704 3.113-.39 5.588.988 6.38.32.187.69.275 1.102.275 1.345 0 3.107-.96 4.888-2.624 1.78 1.654 3.542 2.603 4.887 2.603.41 0 .783-.09 1.106-.275 1.374-.792 1.683-3.263.973-6.365C22.02 15.096 24 13.59 24 12.004c0-1.59-1.99-3.097-5.043-4.032.704-3.11.39-5.587-.988-6.38-.318-.184-.688-.277-1.092-.278zm-.005 1.09v.006c.225 0 .406.044.558.127.666.382.955 1.835.73 3.704-.054.46-.142.945-.25 1.44-.96-.236-2.006-.417-3.107-.534-.66-.905-1.345-1.727-2.035-2.447 1.592-1.48 3.087-2.292 4.105-2.295zm-9.77.02c1.012 0 2.514.808 4.11 2.28-.686.72-1.37 1.537-2.02 2.442-1.107.117-2.154.298-3.113.538-.112-.49-.195-.964-.254-1.42-.23-1.868.054-3.32.714-3.707.19-.09.4-.127.563-.132zm4.882 3.05c.455.468.91.992 1.36 1.564-.44-.02-.89-.034-1.345-.034-.46 0-.915.01-1.36.034.44-.572.895-1.096 1.345-1.565zM12 8.1c.74 0 1.477.034 2.202.093.406.582.802 1.203 1.183 1.86.372.64.71 1.29 1.018 1.946-.308.655-.646 1.31-1.013 1.95-.38.66-.773 1.288-1.18 1.87-.728.063-1.466.098-2.21.098-.74 0-1.477-.035-2.202-.093-.406-.582-.802-1.204-1.183-1.86-.372-.64-.71-1.29-1.018-1.946.303-.657.646-1.313 1.013-1.954.38-.66.773-1.286 1.18-1.868.728-.064 1.466-.098 2.21-.098zm-3.635.254c-.24.377-.48.763-.704 1.16-.225.39-.435.782-.635 1.174-.265-.656-.49-1.31-.676-1.947.64-.15 1.315-.283 2.015-.386zm7.26 0c.695.103 1.365.23 2.006.387-.18.632-.405 1.282-.66 1.933-.2-.39-.41-.783-.64-1.174-.225-.392-.465-.774-.705-1.146zm3.063.675c.484.15.944.317 1.375.498 1.732.74 2.852 1.708 2.852 2.476-.005.768-1.125 1.74-2.857 2.475-.42.18-.88.342-1.355.493-.28-.958-.646-1.956-1.1-2.98.45-1.017.81-2.01 1.085-2.964zm-13.395.004c.278.96.645 1.957 1.1 2.98-.45 1.017-.812 2.01-1.086 2.964-.484-.15-.944-.317-1.375-.498-1.732-.74-2.852-1.708-2.852-2.476.005-.768 1.125-1.74 2.857-2.475.42-.18.88-.342 1.355-.493.28.958.646 1.956 1.1 2.98-.45 1.017-.81 2.01-1.085 2.964zM7.08 13.45c.26.65.48 1.3.66 1.93-.64.15-1.31.28-2.01.39.24-.38.48-.76.7-1.15.23-.4.44-.78.65-1.17zm9.84 0c.21.39.42.77.65 1.17.22.39.46.77.7 1.15-.7-.11-1.37-.24-2.01-.39.18-.63.4-1.28.66-1.93zm-7.26.575c.64.15 1.31.28 2.01.39-.24.38-.48.76-.7 1.15-.23.4-.44.78-.65 1.17-.26-.65-.48-1.3-.66-1.93.64-.15 1.31-.28 0 0zm4.68 0c.26.65.48 1.3.66 1.93-.64.15-1.31.28-2.01.39.24-.38.48-.76.7-1.15.23-.4.44-.78.65-1.17zM12 15.9c.74 0 1.477-.034 2.202-.093.406-.582.802-1.203 1.183-1.86.372-.64.71-1.29 1.018-1.946-.308-.655-.646-1.31-1.013-1.95-.38-.66-.773-1.288-1.18-1.87-.728-.063-1.466-.098-2.21-.098-.74 0-1.477.035-2.202.093-.406.582-.802 1.204-1.183 1.86-.372.64-.71 1.29-1.018 1.946.303.657.646 1.313 1.013 1.954.38.66.773 1.286 1.18 1.868.728.064 1.466.098 2.21.098zm-3.635-.254c-.24-.377-.48-.763-.704-1.16-.225-.39-.435-.782-.635-1.174-.265.656-.49 1.31-.676 1.947.64.15 1.315.283 2.015.386zm7.26 0c.695-.103 1.365-.23 2.006-.387-.18-.632-.405-1.282-.66-1.933-.2.39-.41.783-.64 1.174-.225.392-.465.774-.705 1.146zm-9.697-.672c-.484-.15-.944-.317-1.375-.498-1.732-.74-2.852-1.708-2.852-2.476.005-.768 1.125-1.74 2.857-2.475.42-.18.88-.342 1.355-.493.28.958.646 1.956 1.1 2.98-.45 1.017-.81 2.01-1.085 2.964zm13.395-.004c-.278-.96-.645-1.957-1.1-2.98.45-1.017.812-2.01 1.086-2.964.484.15.944.317 1.375.498 1.732.74 2.852 1.708 2.852 2.476-.005.768-1.125 1.74-2.857 2.475-.42.18-.88.342-1.355.493-.28-.958-.646-1.956-1.1-2.98.45-1.017.81-2.01 1.085-2.964zM7.08 10.55c-.26-.65-.48-1.3-.66-1.93.64-.15 1.31-.28 2.01-.39-.24.38-.48.76-.7 1.15-.23.4-.44.78-.65 1.17zm9.84 0c-.21-.39-.42-.77-.65-1.17-.22-.39-.46-.77-.7-1.15.7.11 1.37.24 2.01.39-.18.63-.4 1.28-.66 1.93zm-7.26-.575c-.64-.15-1.31-.28-2.01-.39.24-.38.48-.76.7-1.15.23-.4.44-.78.65-1.17.26.65.48 1.3.66 1.93-.64.15-1.31.28 0 0zm4.68 0c-.26-.65-.48-1.3-.66-1.93.64-.15 1.31-.28 2.01-.39-.24.38-.48.76-.7 1.15-.23.4-.44.78-.65 1.17zM9.348 3.05c-.225 0-.406.044-.558.127-.666.382-.955 1.835-.73 3.704.054.46.142.945.25 1.44.96-.236 2.006-.417 3.107-.534.66-.905 1.345-1.727 2.035-2.447-1.592-1.48-3.087-2.292-4.105-2.295zm9.77.02c-1.012 0-2.514.808-4.11 2.28.686.72 1.37 1.537 2.02 2.442 1.107.117 2.154.298 3.113.538.112.49.195.964.254 1.42.23 1.868-.054 3.32-.714 3.707-.19.09-.4.127-.563.132z',
      },
      {
        label: 'Next.js',
        d: 'M18.665 21.978C16.758 23.255 14.465 24 12 24 5.377 24 0 18.623 0 12S5.377 0 12 0s12 5.377 12 12c0 3.583-1.574 6.801-4.067 9.001L9.219 7.2H7.2v9.596h1.615V9.251l9.85 12.727Zm-3.332-8.533 1.6 2.061V7.2h-1.6v6.245Z',
      },
      {
        label: 'Vue.js',
        d: 'M24,1.61H14.06L12,5.16,9.94,1.61H0L12,22.39ZM12,14.08,5.16,2.23H9.59L12,6.41l2.41-4.18h4.43Z',
      },
      {
        label: 'Tailwind',
        d: 'M12.001,4.8c-3.2,0-5.2,1.6-6,4.8c1.2-1.6,2.6-2.2,4.2-1.8c0.913,0.228,1.565,0.89,2.288,1.624 C13.666,10.618,15.027,12,18.001,12c3.2,0,5.2-1.6,6-4.8c-1.2,1.6-2.6,2.2-4.2,1.8c-0.913-0.228-1.565-0.89-2.288-1.624 C16.337,6.182,14.976,4.8,12.001,4.8z M6.001,12c-3.2,0-5.2,1.6-6,4.8c1.2-1.6,2.6-2.2,4.2-1.8c0.913,0.228,1.565,0.89,2.288,1.624 c1.177,1.194,2.538,2.576,5.512,2.576c3.2,0,5.2-1.6,6-4.8c-1.2,1.6-2.6,2.2-4.2,1.8c-0.913-0.228-1.565-0.89-2.288-1.624 C10.337,13.382,8.976,12,6.001,12z',
      },
      {
        label: 'Supabase',
        d: 'M11.9 1.036c-.015-.986-1.26-1.41-1.874-.637L.764 12.05C-.33 13.427.65 15.455 2.409 15.455h9.579l.113 7.51c.014.985 1.259 1.408 1.873.636l9.262-11.653c1.093-1.375.113-3.403-1.645-3.403h-9.642z',
      },
      {
        label: 'GitHub',
        d: 'M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12',
      },
    ]
    
    const ROW_3: Logo[] = [
      {
        label: 'Anthropic',
        d: 'M17.3041 3.541h-3.6718l6.696 16.918H24Zm-10.6082 0L0 20.459h3.7442l1.3693-3.5527h7.0052l1.3693 3.5528h3.7442L10.5363 3.5409Zm-.3712 10.2232 2.2914-5.9456 2.2914 5.9456Z',
      },
      {
        label: 'Sentry',
        d: 'M13.91 2.505c-.873-1.448-2.972-1.448-3.844 0L6.904 7.92a15.478 15.478 0 0 1 8.53 12.811h-2.221A13.301 13.301 0 0 0 5.784 9.814l-2.926 5.06a7.65 7.65 0 0 1 4.435 5.848H2.194a.365.365 0 0 1-.298-.534l1.413-2.402a5.16 5.16 0 0 0-1.614-.913L.296 19.275a2.182 2.182 0 0 0 .812 2.999 2.24 2.24 0 0 0 1.086.288h6.983a9.322 9.322 0 0 0-3.845-8.318l1.11-1.922a11.47 11.47 0 0 1 4.95 10.24h5.915a17.242 17.242 0 0 0-7.885-15.28l2.244-3.845a.37.37 0 0 1 .504-.13c.255.14 9.75 16.708 9.928 16.9a.365.365 0 0 1-.327.543h-2.287c.029.612.029 1.223 0 1.831h2.297a2.206 2.206 0 0 0 1.922-3.31z',
      },
      {
        label: 'PlanetScale',
        d: 'M0 12C0 5.373 5.373 0 12 0c4.873 0 9.067 2.904 10.947 7.077l-15.87 15.87a11.981 11.981 0 0 1-1.935-1.099L14.99 12H12l-8.485 8.485A11.962 11.962 0 0 1 0 12Zm12.004 12L24 12.004C23.998 18.628 18.628 23.998 12.004 24Z',
      },
      {
        label: 'Render',
        d: 'M18.263.007c-3.121-.147-5.744 2.109-6.192 5.082-.018.138-.045.272-.067.405-.696 3.703-3.936 6.507-7.827 6.507-1.388 0-2.691-.356-3.825-.979a.2024.2024 0 0 0-.302.178V24H12v-8.999c0-1.656 1.338-3 2.987-3h2.988c3.382 0 6.103-2.817 5.97-6.244-.12-3.084-2.61-5.603-5.682-5.75',
      },
      {
        label: 'Railway',
        d: 'M.113 10.27A13.026 13.026 0 000 11.48h18.23c-.064-.125-.15-.237-.235-.347-3.117-4.027-4.793-3.677-7.19-3.78-.8-.034-1.34-.048-4.524-.048-1.704 0-3.555.005-5.358.01-.234.63-.459 1.24-.567 1.737h9.342v1.216H.113v.002zm18.26 2.426H.009c.02.326.05.645.094.961h16.955c.754 0 1.179-.429 1.315-.96zm-17.318 4.28s2.81 6.902 10.93 7.024c4.855 0 9.027-2.883 10.92-7.024H1.056zM11.988 0C7.5 0 3.593 2.466 1.531 6.108l4.75-.005v-.002c3.71 0 3.849.016 4.573.047l.448.016c1.563.052 3.485.22 4.996 1.364.82.621 2.007 1.99 2.712 2.965.654.902.842 1.94.396 2.934-.408.914-1.289 1.458-2.353 1.458H.391s.099.42.249.886h22.748A12.026 12.026 0 0024 12.005C24 5.377 18.621 0 11.988 0z',
      },
      {
        label: 'Stripe',
        d: 'M13.976 9.15c-2.172-.806-3.356-1.426-3.356-2.409 0-.831.683-1.305 1.901-1.305 2.227 0 4.515.858 6.09 1.631l.89-5.494C18.252.975 15.697 0 12.165 0 9.667 0 7.589.654 6.104 1.872 4.56 3.147 3.757 4.992 3.757 7.218c0 4.039 2.467 5.76 6.476 7.219 2.585.92 3.445 1.574 3.445 2.583 0 .98-.84 1.545-2.354 1.545-1.875 0-4.965-.921-6.99-2.109l-.9 5.555C5.175 22.99 8.385 24 11.714 24c2.641 0 4.843-.624 6.328-1.813 1.664-1.305 2.525-3.236 2.525-5.732 0-4.128-2.524-5.851-6.594-7.305h.003z',
      },
    ]
    
    const grayscaleCustomers = [
      'Northwind',
      'Halden',
      'Verity',
      'Calder',
      'Ridgeway',
      'Ashford',
      'Brightmoor',
      'Kesteven',
      'Marlowe',
      'Thornbury',
      'Wexley',
      'Alderton',
    ]
    
    interface CustomerEntity {
      id: string
      name: string
      category: 'cloud' | 'devtools' | 'fintech' | 'ai'
      tier: string
      scale: string
      quote: string
      author: string
      title: string
    }
    
    const customerList: CustomerEntity[] = [
      {
        id: 'cloudflare',
        name: 'Cloudflare',
        category: 'cloud',
        tier: 'Enterprise Scale',
        scale: '300+ Edge Data Centers',
        quote:
          'UIPKGE allowed us to standardize our internal console UI across 40+ engineering squads with zero bundle overhead.',
        author: 'Alex K.',
        title: 'Principal Architect, Cloudflare Workers',
      },
      {
        id: 'flyio',
        name: 'Fly.io',
        category: 'cloud',
        tier: 'Core Partner',
        scale: '50k+ Compute Machines',
        quote: 'We copy the raw SFC components and style them directly to match our brand — no package upgrades to fight.',
        author: 'Sam T.',
        title: 'Lead Frontend Engineer',
      },
      {
        id: 'railway',
        name: 'Railway',
        category: 'cloud',
        tier: 'Growth Tier',
        scale: '1.5M Deployed Services',
        quote:
          'AST-level source control gives our team complete confidence without ever fearing breaking upstream package releases.',
        author: 'Elena R.',
        title: 'VP of Product Experience',
      },
      {
        id: 'vercel',
        name: 'Vercel',
        category: 'devtools',
        tier: 'Design Pioneer',
        scale: '100M+ Monthly Visitors',
        quote:
          'The level of keyboard ergonomics, focus ring layering, and spring physics in UIPKGE meets the highest craft benchmarks.',
        author: 'Rauno F.',
        title: 'Design Engineering Advisor',
      },
      {
        id: 'supabase',
        name: 'Supabase',
        category: 'devtools',
        tier: 'Ecosystem Partner',
        scale: '1M+ Databases Provisioned',
        quote: 'Dual-framework parity means we can ship both Vue and React examples for our developer docs in minutes.',
        author: 'Ant W.',
        title: 'Co-Founder & CEO',
      },
      {
        id: 'biome',
        name: 'BiomeJS',
        category: 'devtools',
        tier: 'Open Source',
        scale: '20M+ Weekly Downloads',
        quote: 'The cleanest AST code patterns in any modern UI registry. 100% type-safe.',
        author: 'Nico M.',
        title: 'Core Maintainer',
      },
      {
        id: 'stripe',
        name: 'Stripe',
        category: 'fintech',
        tier: 'Global Infrastructure',
        scale: '$1T+ Payment Volume',
        quote:
          'Zero dependency bloat guarantees compliance with strict internal security and dependency auditing requirements.',
        author: 'Marcus H.',
        title: 'Staff Security Engineer',
      },
      {
        id: 'ramp',
        name: 'Ramp',
        category: 'fintech',
        tier: 'Scale Unicorn',
        scale: '$10B+ Managed Spend',
        quote: 'The dense KPI tiles and transaction workbenches are plug-and-play masterpieces.',
        author: 'David P.',
        title: 'Director of Frontend Engineering',
      },
      {
        id: 'snyk',
        name: 'Snyk Security',
        category: 'fintech',
        tier: 'Enterprise SecOps',
        scale: '2.5M+ Repos Scanned',
        quote: 'Owning the source code completely removes transitive dependency CVE vulnerabilities.',
        author: 'Sarah L.',
        title: 'Head of Developer Relations',
      },
      {
        id: 'replicate',
        name: 'Replicate',
        category: 'ai',
        tier: 'AI Infrastructure',
        scale: '500M+ Model Inferences',
        quote: 'We built our interactive prompt tester in an afternoon using UIPKGE terminal and slider primitives.',
        author: 'Ben F.',
        title: 'Co-Founder',
      },
      {
        id: 'modal',
        name: 'Modal Labs',
        category: 'ai',
        tier: 'GPU Cloud',
        scale: '10k+ GPU Clusters',
        quote: 'The tactile feel and speed of the UI blocks matches the lightning speed of our Python container runs.',
        author: 'Erik B.',
        title: 'Co-Founder & CTO',
      },
      {
        id: 'mistral',
        name: 'Mistral AI',
        category: 'ai',
        tier: 'Frontier AI',
        scale: 'Global Deployment',
        quote: 'Phenomenal attention to typographic hierarchy and clean Geist font metrics.',
        author: 'Arthur M.',
        title: 'Co-Founder',
      },
    ]
    
    type VerticalCategory = 'all' | 'cloud' | 'devtools' | 'fintech' | 'ai'
    
    const categoryMeta: Record<VerticalCategory, { label: string; icon: IconNode; iconName: string }> = {
      all: { label: 'All Industries', icon: Globe, iconName: 'globe' },
      cloud: { label: 'Cloud & Infra', icon: Cloud, iconName: 'cloud' },
      devtools: { label: 'DevTools & DX', icon: Terminal, iconName: 'terminal' },
      fintech: { label: 'Fintech & Security', icon: ShieldCheck, iconName: 'shield-check' },
      ai: { label: 'AI & GPU Compute', icon: Brain, iconName: 'brain' },
    }
    
    interface BrandPartner {
      id: string
      name: string
      category: 'devtools' | 'fintech' | 'enterprise'
      role: string
      metric: string
      region: string
    }
    
    const partners: BrandPartner[] = [
      { id: 'vercel', name: 'Vercel Edge', category: 'devtools', role: 'Global Edge Ingestion', metric: '99.95% SLA', region: 'Global' },
      { id: 'supabase', name: 'Supabase Postgres', category: 'devtools', role: 'Real-Time Replication', metric: '1.2M QPS', region: 'US-East' },
      { id: 'linear', name: 'Linear Method', category: 'enterprise', role: 'Issue Sync Engine', metric: '< 20ms Sync', region: 'Global' },
      { id: 'stripe', name: 'Stripe Billing', category: 'fintech', role: 'Usage Metering Gateway', metric: '$120M+ Processed', region: 'Global' },
      { id: 'resend', name: 'Resend SMTP', category: 'devtools', role: 'Transactional Dispatch', metric: '200M msgs/mo', region: 'US-West' },
      { id: 'cloudflare', name: 'Cloudflare Workers', category: 'devtools', role: 'Zero-Trust Isolation', metric: '300+ Cities', region: 'Global' },
      { id: 'planetscale', name: 'PlanetScale DB', category: 'enterprise', role: 'Branching Schema', metric: 'Zero Downtime', region: 'EU-Central' },
      { id: 'brex', name: 'Brex Treasury', category: 'fintech', role: 'Ledger Reconciliation', metric: 'Real-time API', region: 'US-East' },
    ]
    
    type TickerCategory = 'all' | 'devtools' | 'fintech' | 'enterprise'
    
    const logoMark = (logo: Logo) => html`
      <div class="text-foreground/55 hover:text-foreground inline-flex shrink-0 items-center gap-2 transition-colors">
        <svg viewBox="0 0 24 24" class="size-5 shrink-0" fill="currentColor" role="img" aria-label=${logo.label}>
          <title>${logo.label}</title>
          <path d=${logo.d} />
        </svg>
        <span class="text-base font-semibold tracking-tight">${logo.label}</span>
      </div>
    `
    
    /**
     * <uip-logos> — the registry Logos block collection as a web component.
     *
     * One block, one install unit: `variant` selects the section ('grid' |
     * 'marquee' | 'marquee-rows' | 'categorized' | 'ticker' | 'grayscale').
     * Class strings and SVG paths are React's verbatim. React state (useState)
     * becomes @state fields. React's injected <style> keyframes (marquee loops,
     * edge masks, pause-on-hover, reduced-motion) are copied into static styles —
     * the one allowed CSS exception besides the :host one-liner.
     */
    export class UipLogos extends LitElement {
      static shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true }
      static styles = [
        tailwind,
        // React-injected keyframes, copied verbatim (scoped to this shadow root).
        css`
          :host {
            display: block;
          }
          @keyframes logos-marquee {
            from {
              transform: translateX(0);
            }
            to {
              transform: translateX(-50%);
            }
          }
          @keyframes logos-marquee-right {
            from {
              transform: translateX(-50%);
            }
            to {
              transform: translateX(0);
            }
          }
          @keyframes marquee {
            0% {
              transform: translateX(0%);
            }
            100% {
              transform: translateX(-50%);
            }
          }
          .logos02-track {
            animation: logos-marquee 30s linear infinite;
          }
          .group:hover .logos02-track {
            animation-play-state: paused;
          }
          .logos03-left-32 {
            animation: logos-marquee 32s linear infinite;
          }
          .logos03-right-26 {
            animation: logos-marquee-right 26s linear infinite;
          }
          .logos03-left-38 {
            animation: logos-marquee 38s linear infinite;
          }
          .group:hover .logos03-track {
            animation-play-state: paused;
          }
          .animate-marquee {
            animation: marquee 32s linear infinite;
          }
          @media (prefers-reduced-motion: reduce) {
            .logos02-track,
            .logos03-track {
              animation: none !important;
            }
          }
        `,
      ]
    
      static properties = {
        variant: { reflect: true },
        selectedCategory: { state: true },
        activeModalCustomer: { state: true },
        tickerCategory: { state: true },
        isPaused: { state: true },
        isFastSpeed: { state: true },
        hoveredBrand: { state: true },
      }
    
      variant: LogosVariant = 'grid'
      private selectedCategory: VerticalCategory = 'all'
      private activeModalCustomer: CustomerEntity | null = null
      private tickerCategory: TickerCategory = 'all'
      private isPaused = false
      private isFastSpeed = false
      private hoveredBrand: BrandPartner | null = null
    
      constructor() {
        super()
        new ThemeController(this)
      }
    
      connectedCallback() {
        super.connectedCallback()
        this.setAttribute('data-uipkge', '')
        this.setAttribute('data-slot', 'logos')
      }
    
      private get filteredCustomers() {
        if (this.selectedCategory === 'all') return customerList
        return customerList.filter((c) => c.category === this.selectedCategory)
      }
    
      private get filteredPartners() {
        if (this.tickerCategory === 'all') return partners
        return partners.filter((p) => p.category === this.tickerCategory)
      }
    
      render() {
        switch (this.variant) {
          case 'marquee':
            return this.renderMarquee()
          case 'marquee-rows':
            return this.renderMarqueeRows()
          case 'categorized':
            return this.renderCategorized()
          case 'ticker':
            return this.renderTicker()
          case 'grayscale':
            return this.renderGrayscale()
          default:
            return this.renderGrid()
        }
      }
    
      private renderGrid() {
        return html`
          <section data-slot="logos-01" class="bg-muted/30 border-y">
            <div class="mx-auto max-w-6xl px-6 py-14">
              <p class="text-muted-foreground text-center text-xs font-medium tracking-widest uppercase">
                Trusted by teams at
              </p>
              <div class="mt-10 grid grid-cols-2 items-center justify-items-center gap-x-10 gap-y-8 sm:grid-cols-3 lg:grid-cols-6">
                ${LOGOS.map(
                  (logo) => html`
                    <div class="text-foreground/55 hover:text-foreground inline-flex items-center gap-2 transition-colors">
                      <svg
                        viewBox="0 0 24 24"
                        class="size-5 shrink-0"
                        fill="currentColor"
                        role="img"
                        aria-label=${logo.label}
                      >
                        <title>${logo.label}</title>
                        <path d=${logo.d} />
                      </svg>
                      <span class="text-base font-semibold tracking-tight">${logo.label}</span>
                    </div>
                  `,
                )}
              </div>
            </div>
          </section>
        `
      }
    
      private renderMarquee() {
        return html`
          <section data-slot="logos-02" class="bg-muted/30 border-y">
            <div class="mx-auto max-w-6xl px-6 py-14">
              <p class="text-muted-foreground mb-10 text-center text-xs font-medium tracking-widest uppercase">
                Trusted by teams at
              </p>
    
              <div
                class="group relative overflow-hidden"
                style="mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent); -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);"
              >
                <div class="logos02-track flex w-max gap-12 will-change-transform">
                  ${[...LOGOS, ...LOGOS].map((logo) => logoMark(logo))}
                </div>
              </div>
            </div>
          </section>
        `
      }
    
      private renderMarqueeRows() {
        const rows: { logos: Logo[]; trackClass: string }[] = [
          { logos: LOGOS, trackClass: 'logos03-left-32' },
          { logos: ROW_2, trackClass: 'logos03-right-26' },
          { logos: ROW_3, trackClass: 'logos03-left-38' },
        ]
        // NOTE: React's Logos03 root section carries no data-slot — preserved.
        return html`
          <section class="bg-muted/30 border-y">
            <div class="mx-auto max-w-6xl px-6 py-14">
              <p class="text-muted-foreground mb-10 text-center text-xs font-medium tracking-widest uppercase">
                Powering teams everywhere
              </p>
    
              <div
                class="group relative space-y-5 overflow-hidden"
                style="mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent); -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);"
              >
                ${rows.map(
                  (row) => html`
                    <div data-slot="logos-03" class=${`logos03-track ${row.trackClass} flex w-max gap-12 will-change-transform`}>
                      ${[...row.logos, ...row.logos].map((logo) => logoMark(logo))}
                    </div>
                  `,
                )}
              </div>
            </div>
          </section>
        `
      }
    
      private renderGrayscale() {
        return html`
          <section data-slot="logo-cloud-grayscale" class="bg-background">
            <div class="mx-auto max-w-6xl px-6 py-16">
              <div class="text-center">
                <uip-badge variant="secondary">Customers</uip-badge>
                <p class="mt-4 text-lg font-medium">Running the close at 240 companies</p>
                <p class="text-muted-foreground mt-1.5 text-sm">
                  Freight, healthcare, retail, and manufacturing · median 1,100 staff
                </p>
              </div>
    
              <ul class="mt-10 grid grid-cols-2 gap-x-8 gap-y-6 sm:grid-cols-3 lg:grid-cols-6">
                ${grayscaleCustomers.map(
                  (customer) => html`
                    <li class="flex items-center justify-center">
                      <span
                        class="text-muted-foreground/60 hover:text-foreground cursor-default text-sm font-semibold tracking-[0.18em] uppercase transition-colors"
                      >
                        ${customer}
                      </span>
                    </li>
                  `,
                )}
              </ul>
    
              <uip-separator class="[&::part(base)]:my-10"></uip-separator>
    
              <div class="flex flex-wrap items-center justify-center gap-4 text-center">
                <p class="text-muted-foreground text-sm">Six of the ten largest UK freight forwarders.</p>
                <uip-button variant="link" class="h-auto p-0 text-sm">Read their stories</uip-button>
              </div>
            </div>
          </section>
        `
      }
    
      private renderCategorized() {
        return html`
          <section data-slot="logo-cloud-categorized-grid" class="bg-background relative overflow-hidden px-4 py-16 sm:px-6 sm:py-24 lg:px-8">
            <div class="mx-auto max-w-7xl space-y-12">
              <div class="mx-auto max-w-3xl space-y-4 text-center">
                <uip-badge variant="secondary" class="gap-1.5 px-3 py-1 font-mono text-xs shadow-xs">
                  ${icon(Building2, 'building-2', 'text-primary size-3.5')} Industry Benchmark Customers
                </uip-badge>
                <h2 class="text-foreground text-3xl font-bold tracking-tight sm:text-4xl">
                  Powering the world's most rigorous engineering organizations.
                </h2>
                <p class="text-muted-foreground text-base">
                  From frontier AI labs to global payment platforms, see how top tier engineering teams build on UIPKGE.
                </p>
    
                <div class="flex flex-wrap items-center justify-center gap-1 pt-4">
                  ${(Object.keys(categoryMeta) as VerticalCategory[]).map((catKey) => {
                    const meta = categoryMeta[catKey]
                    return html`
                      <button
                        type="button"
                        class=${cn(
                          'flex items-center gap-1.5 rounded-lg border px-3 py-1.5 font-mono text-xs transition-colors',
                          this.selectedCategory === catKey
                            ? 'border-primary bg-primary text-primary-foreground font-semibold shadow-xs'
                            : 'border-border bg-card/60 text-muted-foreground hover:text-foreground hover:bg-muted',
                        )}
                        @click=${() => {
                          this.selectedCategory = catKey
                        }}
                      >
                        ${icon(meta.icon, meta.iconName, 'size-3.5')}
                        <span>${meta.label}</span>
                      </button>
                    `
                  })}
                </div>
              </div>
    
              <div class="grid grid-cols-1 gap-4 sm:grid-cols-2 sm:gap-6 lg:grid-cols-3">
                ${this.filteredCustomers.map(
                  (customer) => html`
                    <uip-card
                      class="border-border bg-card/90 hover:border-primary/40 group flex cursor-pointer flex-col justify-between space-y-4 rounded-2xl p-5 shadow-sm transition-colors hover:shadow-md"
                      @click=${() => {
                        this.activeModalCustomer = customer
                      }}
                    >
                      <div class="flex items-center justify-between">
                        <div class="flex items-center gap-2.5">
                          <div
                            class="bg-primary/10 text-primary flex size-8 items-center justify-center rounded-lg font-mono text-xs font-bold"
                          >
                            ${customer.name.charAt(0)}
                          </div>
                          <div>
                            <h3
                              class="text-foreground group-hover:text-primary font-mono text-sm font-bold transition-colors"
                            >
                              ${customer.name}
                            </h3>
                            <p class="text-muted-foreground text-xs">${customer.scale}</p>
                          </div>
                        </div>
                        <uip-badge variant="outline" class="font-mono text-xs capitalize">${customer.tier}</uip-badge>
                      </div>
    
                      <p class="text-muted-foreground line-clamp-2 text-xs leading-relaxed italic">
                        &ldquo;${customer.quote}&rdquo;
                      </p>
    
                      <div class="border-border/60 flex items-center justify-between border-t pt-2 text-xs">
                        <span class="text-muted-foreground font-mono text-xs">${customer.author}</span>
                        <span class="text-primary flex items-center gap-1 text-xs font-medium group-hover:underline">
                          <span>Read quote</span>
                          ${icon(ArrowRight, 'arrow-right', 'size-3')}
                        </span>
                      </div>
                    </uip-card>
                  `,
                )}
              </div>
    
              ${this.activeModalCustomer
                ? html`
                    <div class="bg-background/80 fixed inset-0 z-50 flex items-center justify-center p-4 backdrop-blur-md sm:p-6">
                      <div
                        class="bg-card border-border relative w-full max-w-xl space-y-6 rounded-2xl border p-6 text-left shadow-sm sm:p-8"
                      >
                        <div class="border-border flex items-center justify-between border-b pb-4">
                          <div class="flex items-center gap-3">
                            <div
                              class="bg-primary/10 text-primary flex size-10 items-center justify-center rounded-xl font-mono text-sm font-bold"
                            >
                              ${this.activeModalCustomer.name.charAt(0)}
                            </div>
                            <div>
                              <h3 class="text-foreground font-mono text-base font-bold">
                                ${this.activeModalCustomer.name}
                              </h3>
                              <p class="text-muted-foreground font-mono text-xs">${this.activeModalCustomer.scale}</p>
                            </div>
                          </div>
                          <button
                            type="button"
                            class="text-muted-foreground hover:text-foreground hover:bg-muted rounded-md p-1 transition-colors"
                            @click=${() => {
                              this.activeModalCustomer = null
                            }}
                          >
                            ${icon(X, 'x', 'size-4')}
                          </button>
                        </div>
    
                        <div class="space-y-4">
                          ${icon(Quote, 'quote', 'text-primary/40 size-6')}
                          <p class="text-foreground text-sm leading-relaxed sm:text-base">
                            &ldquo;${this.activeModalCustomer.quote}&rdquo;
                          </p>
                        </div>
    
                        <div
                          class="border-border bg-muted/20 -mx-6 -mb-6 flex items-center justify-between rounded-b-2xl border-t p-4 px-6 pt-4 sm:-mx-8 sm:-mb-8 sm:px-8"
                        >
                          <div>
                            <p class="text-foreground text-xs font-bold">${this.activeModalCustomer.author}</p>
                            <p class="text-muted-foreground font-mono text-xs">${this.activeModalCustomer.title}</p>
                          </div>
                          <uip-badge variant="outline" class="border-success/20 bg-success/10 text-success font-mono text-xs">
                            Verified Production Customer
                          </uip-badge>
                        </div>
                      </div>
                    </div>
                  `
                : nothing}
            </div>
          </section>
        `
      }
    
      private renderTicker() {
        const filtered = this.filteredPartners
        return html`
          <section data-slot="logo-ticker-infinite" class="border-border/80 bg-muted/20 relative overflow-hidden border-y px-4 py-14 sm:px-6 sm:py-20 lg:px-8">
            <div class="mx-auto max-w-7xl space-y-8 text-center">
              <div class="border-border/60 flex flex-col items-center justify-between gap-4 border-b pb-6 text-left md:flex-row">
                <div class="space-y-1">
                  <div class="flex items-center gap-2">
                    <span class="bg-success size-2 rounded-full"></span>
                    <p class="text-foreground font-mono text-xs font-semibold tracking-wider uppercase">
                      Production Verified Infrastructure
                    </p>
                  </div>
                  <p class="text-muted-foreground text-xs">
                    Trusted by modern engineering teams shipping high-throughput production workloads.
                  </p>
                </div>
    
                <div class="flex flex-wrap items-center gap-2">
                  <div class="bg-background border-border flex items-center gap-1 rounded-lg border p-0.5">
                    ${(['all', 'devtools', 'fintech', 'enterprise'] as TickerCategory[]).map(
                      (cat) => html`
                        <button
                          type="button"
                          class=${cn(
                            'rounded-md px-2.5 py-1 font-mono text-xs capitalize transition-colors',
                            this.tickerCategory === cat
                              ? 'bg-primary text-primary-foreground font-semibold shadow-xs'
                              : 'text-muted-foreground hover:text-foreground',
                          )}
                          @click=${() => {
                            this.tickerCategory = cat
                          }}
                        >
                          ${cat}
                        </button>
                      `,
                    )}
                  </div>
    
                  <div class="flex items-center gap-1">
                    <button
                      type="button"
                      class="border-border bg-background text-muted-foreground hover:text-foreground rounded-lg border p-1.5 transition-colors"
                      title=${this.isPaused ? 'Resume Ticker' : 'Pause Ticker'}
                      @click=${() => {
                        this.isPaused = !this.isPaused
                      }}
                    >
                      ${this.isPaused ? icon(Play, 'play', 'size-3.5 fill-current') : icon(Pause, 'pause', 'size-3.5')}
                    </button>
                    <button
                      type="button"
                      class="border-border bg-background text-muted-foreground hover:text-foreground rounded-lg border px-2 py-1 font-mono text-xs transition-colors"
                      @click=${() => {
                        this.isFastSpeed = !this.isFastSpeed
                      }}
                    >
                      ${this.isFastSpeed ? '2x' : '1x'}
                    </button>
                  </div>
                </div>
              </div>
    
              <div class="group relative overflow-hidden">
                <div
                  class="from-background via-background/80 pointer-events-none absolute inset-y-0 left-0 z-10 w-16 bg-gradient-to-r to-transparent sm:w-28"
                ></div>
                <div
                  class="from-background via-background/80 pointer-events-none absolute inset-y-0 right-0 z-10 w-16 bg-gradient-to-l to-transparent sm:w-28"
                ></div>
    
                <div
                  class=${cn(
                    'flex w-max items-center gap-4 py-3',
                    !this.isPaused ? 'animate-marquee' : '',
                    this.isFastSpeed ? '[animation-duration:15s]' : '[animation-duration:32s]',
                  )}
                  style=${`animation-play-state: ${this.isPaused ? 'paused' : 'running'};`}
                >
                  ${[...filtered, ...filtered].map(
                    (item) => html`
                      <div
                        class="border-border bg-card/80 hover:bg-card hover:border-primary/50 relative flex shrink-0 cursor-pointer items-center gap-3 rounded-xl border px-4 py-2.5 shadow-xs backdrop-blur-md transition-colors duration-200"
                        @mouseenter=${() => {
                          this.hoveredBrand = item
                        }}
                        @mouseleave=${() => {
                          this.hoveredBrand = null
                        }}
                      >
                        <div
                          class="bg-primary/10 text-primary flex size-7 items-center justify-center rounded-lg font-mono text-xs font-bold"
                        >
                          ${item.name.charAt(0)}
                        </div>
    
                        <div class="text-left">
                          <p class="text-foreground font-mono text-xs font-semibold tracking-tight">${item.name}</p>
                          <p class="text-muted-foreground text-xs">${item.role}</p>
                        </div>
    
                        <uip-badge variant="outline" class="border-success/20 bg-success/10 text-success ml-1 font-mono text-xs">
                          ${item.metric}
                        </uip-badge>
                      </div>
                    `,
                  )}
                </div>
              </div>
    
              ${this.hoveredBrand
                ? html`
                    <div
                      class="border-border bg-card animate-in fade-in-0 mx-auto max-w-md rounded-xl border p-3 text-left shadow-lg duration-150"
                    >
                      <div class="flex items-center justify-between font-mono text-xs">
                        <span class="text-foreground font-bold">${this.hoveredBrand.name} Architecture Integration</span>
                        <span class="text-success">${this.hoveredBrand.region}</span>
                      </div>
                      <p class="text-muted-foreground mt-1 text-xs">
                        Connected through ${this.hoveredBrand.role} &bull; Monitored with ${this.hoveredBrand.metric}
                        verified telemetry.
                      </p>
                    </div>
                  `
                : nothing}
            </div>
          </section>
        `
      }
    }
    
    customElements.get('uip-logos') || customElements.define('uip-logos', UipLogos)
    
    declare global {
      interface HTMLElementTagNameMap {
        'uip-logos': UipLogos
      }
    }
    

Raw manifest:https://uipkge.dev/r/lit/logos.json