1 звезда на GitHub = 1 новый компонент.

Поставить звезду
Команда и авторы

Team Grid Section

Секция представления команды с карточками участников, ролями и социальными сетями.

teampeopleleadershiphiringsocial
Живое превью
Our Team

Built by Engineers, Designers & Open Source Believers

Meet the passionate team behind the Astro Components Kit, crafting tools to elevate modern web interfaces.

AM

Alexandre Moreau

Lead Architect & Founder

Passionate about zero-runtime systems and developer experience.

ER

Elena Rostova

Head of Design & UI/UX

Design systems veteran specializing in dark-mode glassmorphism and WCAG compliance.

LC

Liam Chen

Senior 3D & Graphics Engineer

Creator of the WebGL and Three.js shader particle background engines.

SM

Sophia Martinez

Core Maintainer & DX Lead

Obsessed with strict TypeScript typings, automated testing, and bundling performance.

WE ARE HIRING

Want to help shape the future of React components?

We are looking for frontend wizards, designers, and open-source contributors.

View Open Roles →

Использование

Скопируйте и вставьте этот код в ваш React-компонент:

tsx
import { TeamGridSection } from 'react-component-kit-ui/sections';

<TeamGridSection />

Ручная установка

Если вы не используете пакет npm, создайте файл и вставьте следующий код: src/components/sections/TeamGridSection.tsx + TeamGridSection.css:

TeamGridSection.tsx
'use client';

import type { CSSProperties } from 'react';
import './TeamGridSection.css';

/** "a: b; --c: d" → style object */
function st(css: string | undefined): CSSProperties {
  const o: Record<string, string> = {};
  for (const decl of String(css ?? '').split(';')) {
    const i = decl.indexOf(':');
    if (i < 0) continue;
    const k = decl.slice(0, i).trim();
    if (k) o[k.startsWith('--') ? k : k.replace(/-([a-z])/g, (_, c) => c.toUpperCase())] = decl.slice(i + 1).trim();
  }
  return o as CSSProperties;
}

/**
 * TeamGridSection — Full-page team & leadership section with glass profile cards, social links, and open positions banner.
 * 
 * @param {string} badge - Eyebrow badge text.
 * @param {string} title - Section main heading.
 * @param {string} subtitle - Description text.
 */
export interface TeamGridSectionProps {
  badge?: string;
  title?: string;
  subtitle?: string;
  className?: string;
}

export function TeamGridSection({
  badge = "Our Team",
  title = "Built by Engineers, Designers & Open Source Believers",
  subtitle = "Meet the passionate team behind the Astro Components Kit, crafting tools to elevate modern web interfaces.",
  className = ""
}: TeamGridSectionProps) {
  const members = [
    {
      name: "Alexandre Moreau",
      role: "Lead Architect & Founder",
      bio: "Passionate about zero-runtime systems and developer experience.",
      initials: "AM",
      avatarColor: "linear-gradient(135deg, #6366f1, #a855f7)",
      github: "https://github.com",
      twitter: "https://x.com"
    },
    {
      name: "Elena Rostova",
      role: "Head of Design & UI/UX",
      bio: "Design systems veteran specializing in dark-mode glassmorphism and WCAG compliance.",
      initials: "ER",
      avatarColor: "linear-gradient(135deg, #eab308, #d97706)",
      github: "https://github.com",
      twitter: "https://x.com"
    },
    {
      name: "Liam Chen",
      role: "Senior 3D & Graphics Engineer",
      bio: "Creator of the WebGL and Three.js shader particle background engines.",
      initials: "LC",
      avatarColor: "linear-gradient(135deg, #06b6d4, #3b82f6)",
      github: "https://github.com",
      twitter: "https://x.com"
    },
    {
      name: "Sophia Martinez",
      role: "Core Maintainer & DX Lead",
      bio: "Obsessed with strict TypeScript typings, automated testing, and bundling performance.",
      initials: "SM",
      avatarColor: "linear-gradient(135deg, #10b981, #059669)",
      github: "https://github.com",
      twitter: "https://x.com"
    }
  ];
  return (
    <>
      <div className="cq-team-grid-section-cq" data-rk-e56c49="">
      <section className={`team-section ${className}`} aria-labelledby="team-title" data-rk-e56c49="">
        <div className="team-bg" aria-hidden="true" data-rk-e56c49="">
          <div className="team-glow" data-rk-e56c49=""></div>
        </div>
      
        <div className="container" data-rk-e56c49="">
          {/* Header */}
          <div className="section-header" data-rk-e56c49="">
            {badge && <span className="section-badge" data-rk-e56c49="">{badge}</span>}
            <h2 id="team-title" className="section-title" data-rk-e56c49="">{title}</h2>
            <p className="section-subtitle" data-rk-e56c49="">{subtitle}</p>
          </div>
      
          {/* Team Grid */}
          <div className="team-grid" data-rk-e56c49="">
            {members.map((member, __i: number) => (
              <article key={__i} className="member-card" data-rk-e56c49="">
                <div className="member-avatar" style={st(`background: ${member.avatarColor};`)} data-rk-e56c49="">
                  <span data-rk-e56c49="">{member.initials}</span>
                </div>
                <h3 className="member-name" data-rk-e56c49="">{member.name}</h3>
                <span className="member-role" data-rk-e56c49="">{member.role}</span>
                <p className="member-bio" data-rk-e56c49="">{member.bio}</p>
                <div className="member-socials" data-rk-e56c49="">
                  <a href={member.github} target="_blank" rel="noopener" aria-label={`${member.name} on GitHub`} className="social-icon" data-rk-e56c49="">
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" data-rk-e56c49=""><path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4" data-rk-e56c49="" /><path d="M9 18c-4.51 2-5-2-7-2" data-rk-e56c49="" /></svg>
                  </a>
                  <a href={member.twitter} target="_blank" rel="noopener" aria-label={`${member.name} on Twitter`} className="social-icon" data-rk-e56c49="">
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" data-rk-e56c49=""><path d="M22 4s-.7 2.1-2 3.4c1.6 10-9.4 17.3-18 11.6 2.2.1 4.4-.6 6-2C3 15.5.5 9.6 3 5c2.2 2.6 5.6 4.1 9 4-.9-4.2 4-6.6 7-3.8 1.1 0 3-1.2 3-1.2z" data-rk-e56c49="" /></svg>
                  </a>
                </div>
              </article>
            ))}
          </div>
      
          {/* Hiring Banner */}
          <div className="hiring-banner" data-rk-e56c49="">
            <div className="hiring-info" data-rk-e56c49="">
              <span className="hiring-tag" data-rk-e56c49="">WE ARE HIRING</span>
              <h4 data-rk-e56c49="">Want to help shape the future of React components?</h4>
              <p data-rk-e56c49="">We are looking for frontend wizards, designers, and open-source contributors.</p>
            </div>
            <a href="#careers" className="hiring-btn" data-rk-e56c49="">View Open Roles →</a>
          </div>
        </div>
      </section>
      </div>
    </>
  );
}

export default TeamGridSection;
TeamGridSection.css
/* TeamGridSection — ported from astro-component-kit (sections/TeamGridSection.astro) */

.cq-team-grid-section-cq:where([data-rk-e56c49]) { container-type: inline-size; }
.team-section:where([data-rk-e56c49]) {
  position: relative;
  padding: var(--sp-20, 5rem) var(--sp-6, 1.5rem);
  background: var(--c-bg-primary, #030712);
  overflow: hidden;
}

.team-bg:where([data-rk-e56c49]) {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}

.team-glow:where([data-rk-e56c49]) {
  position: absolute;
  top: 40%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 650px;
  height: 450px;
  background: radial-gradient(circle, rgba(168, 85, 247, 0.08), transparent 70%);
  filter: blur(120px);
}

.container:where([data-rk-e56c49]) {
  position: relative;
  z-index: 1;
  max-width: 1200px;
  margin: 0 auto;
}

.section-header:where([data-rk-e56c49]) {
  text-align: center;
  max-width: 780px;
  margin: 0 auto 3.5rem;
}

.section-badge:where([data-rk-e56c49]) {
  display: inline-flex;
  padding: 0.35rem 0.9rem;
  border-radius: 9999px;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: rgba(168, 85, 247, 0.12);
  color: #c084fc;
  border: 1px solid rgba(168, 85, 247, 0.25);
  margin-bottom: var(--sp-4, 1rem);
}

.section-title:where([data-rk-e56c49]) {
  font-size: clamp(2rem, 4vw, 3rem);
  font-weight: 900;
  color: #fff;
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin: 0 0 var(--sp-4, 1rem);
}

.section-subtitle:where([data-rk-e56c49]) {
  font-size: 1.1rem;
  color: #94a3b8;
  line-height: 1.6;
  margin: 0;
}

.team-grid:where([data-rk-e56c49]) {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1.5rem;
  margin-bottom: 3.5rem;
}

.member-card:where([data-rk-e56c49]) {
  background: rgba(15, 23, 42, 0.55);
  backdrop-filter: blur(20px);
  border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.08);
  border-radius: var(--r-xl, 20px);
  padding: 2rem 1.5rem;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  transition: transform 0.3s ease, border-color 0.3s ease;
}

.member-card:hover:where([data-rk-e56c49]) {
  transform: translateY(-4px);
  border-color: rgb(var(--ink-rgb, 255 255 255) / 0.2);
}

.member-avatar:where([data-rk-e56c49]) {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 1.3rem;
  font-weight: 800;
  color: #fff;
  margin-bottom: 1.25rem;
  border: 2px solid rgb(var(--ink-rgb, 255 255 255) / 0.2);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
}

.member-name:where([data-rk-e56c49]) {
  font-size: 1.15rem;
  font-weight: 800;
  color: #fff;
  margin: 0 0 0.25rem;
}

.member-role:where([data-rk-e56c49]) {
  font-size: 0.8rem;
  font-weight: 600;
  color: #eab308;
  margin-bottom: 0.85rem;
}

.member-bio:where([data-rk-e56c49]) {
  font-size: 0.85rem;
  color: #94a3b8;
  line-height: 1.5;
  margin: 0 0 1.25rem;
  flex: 1;
}

.member-socials:where([data-rk-e56c49]) {
  display: flex;
  gap: 0.75rem;
}

.social-icon:where([data-rk-e56c49]) {
  width: 34px;
  height: 34px;
  border-radius: 8px;
  background: rgb(var(--ink-rgb, 255 255 255) / 0.05);
  border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #94a3b8;
  text-decoration: none;
  transition: all 0.2s ease;
}

.social-icon:hover:where([data-rk-e56c49]) {
  color: #fff;
  background: rgb(var(--ink-rgb, 255 255 255) / 0.12);
  border-color: rgb(var(--ink-rgb, 255 255 255) / 0.2);
}

/* Hiring Banner */
.hiring-banner:where([data-rk-e56c49]) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  padding: 2rem 2.5rem;
  background: linear-gradient(135deg, rgba(25, 30, 60, 0.8), rgba(15, 20, 40, 0.9));
  border: 1px solid rgba(168, 85, 247, 0.3);
  border-radius: 20px;
  flex-wrap: wrap;
}

.hiring-tag:where([data-rk-e56c49]) {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  color: #c084fc;
  margin-bottom: 0.25rem;
}

.hiring-info:where([data-rk-e56c49]) h4:where([data-rk-e56c49]) {
  font-size: 1.25rem;
  font-weight: 800;
  color: #fff;
  margin: 0 0 0.25rem;
}

.hiring-info:where([data-rk-e56c49]) p:where([data-rk-e56c49]) {
  font-size: 0.9rem;
  color: #94a3b8;
  margin: 0;
}

.hiring-btn:where([data-rk-e56c49]) {
  padding: 0.8rem 1.6rem;
  background: #a855f7;
  border-radius: 10px;
  color: #fff;
  font-size: 0.92rem;
  font-weight: 700;
  text-decoration: none;
  transition: all 0.25s ease;
  box-shadow: 0 4px 15px rgba(168, 85, 247, 0.3);
}

.hiring-btn:hover:where([data-rk-e56c49]) {
  background: #9333ea;
  box-shadow: 0 6px 20px rgba(168, 85, 247, 0.45);
}

@container (max-width: 1024px) {
  .team-grid:where([data-rk-e56c49]) {
    grid-template-columns: repeat(2, 1fr);
  }
}

@container (max-width: 640px) {
  .team-grid:where([data-rk-e56c49]) {
    grid-template-columns: 1fr;
  }
  .hiring-banner:where([data-rk-e56c49]) {
    flex-direction: column;
    align-items: flex-start;
    gap: 1.25rem;
  }
}