fixed page - 85% ready if you asked me

This commit is contained in:
2026-10-05 22:56:34 -04:00
parent e90ebde399
commit 4341adc147
104 changed files with 647 additions and 76 deletions
+14 -7
View File
@@ -2,7 +2,15 @@ import { developments } from "../data";
import { Action, SectionHeading } from "./Primitives";
import "./Gallery.css";
const textures = ["fine", "natural", "structured"];
const textures = [
"/images/refined/gallery/Gemini_Generated_Image_gwchf4gwchf4gwch.jpeg",
"/images/refined/gallery/Gemini_Generated_Image_n36uden36uden36u.jpeg",
"/images/refined/gallery/Gemini_Generated_Image_v9lfrwv9lfrwv9lf.jpeg",
"/images/library/gallery-01.jpeg",
"/images/library/gallery-02.jpeg",
"/images/library/gallery-03.jpeg",
"/images/library/gallery-04.jpeg",
];
export default function Gallery({ preview = false }) {
const items = preview ? developments.slice(0, 3) : developments;
@@ -22,7 +30,7 @@ export default function Gallery({ preview = false }) {
</>
) : (
<>
From greige
From grey
<br />
<em>to possibility.</em>
</>
@@ -32,7 +40,7 @@ export default function Gallery({ preview = false }) {
<p className="gallery__intro">
{preview
? "A selection of knitted structures showing how yarn, composition and machine setup shape the final fabric character."
: "Selected developments are processed separately as reference samples to explore how a construction can translate after dyeing and finishing. RRS commercially manufactures greige fabric only."}
: "Selected developments are processed separately as reference samples to explore how a construction can translate after dyeing and finishing. RRS commercially manufactures grey fabric only."}
</p>
{preview && (
<Action to="/fabrics#developments" variant="outline">
@@ -46,13 +54,12 @@ export default function Gallery({ preview = false }) {
<div className="sample__visual">
<img
className="sample__image"
src={`/images/knit-${textures[index % textures.length]}.jpg`}
alt={`Illustrative placeholder for ${name}; RRS sample photograph not yet supplied`}
src={textures[index]}
alt={`${name} fabric sample`}
width="1600"
height="1200"
loading="lazy"
/>
<span className="sample__badge">Image placeholder</span>
</div>
<div className="sample__heading">
<h3 className="sample__name">{name}</h3>
@@ -75,7 +82,7 @@ export default function Gallery({ preview = false }) {
When supplied, processed images will be labelled{" "}
<strong>Processed Development Reference</strong>. Processed samples
are for visual reference; RRS commercially manufactures and supplies
greige fabric only. Finished appearance may vary depending on the
grey fabric only. Finished appearance may vary depending on the
buyer’s processing and finishing method.
</p>
</div>
+78
View File
@@ -0,0 +1,78 @@
.image-carousel {
position: absolute;
inset: 0;
overflow: hidden;
background: var(--wash);
/* Each image owns a 5s slot; the cycle must span every image or the last
one collides with the first and paints over it. */
--carousel-count: 3;
}
.image-carousel--n2 {
--carousel-count: 2;
}
.image-carousel--n3 {
--carousel-count: 3;
}
.image-carousel--n4 {
--carousel-count: 4;
}
.image-carousel--n5 {
--carousel-count: 5;
}
.image-carousel--n6 {
--carousel-count: 6;
}
.image-carousel__image {
position: absolute;
inset: 0;
display: block;
width: 100%;
height: 100%;
object-fit: cover;
opacity: 0;
animation: carousel-fade calc(var(--carousel-count) * 5s) infinite;
}
.image-carousel__image:nth-child(2) {
animation-delay: 5s;
}
.image-carousel__image:nth-child(3) {
animation-delay: 10s;
}
.image-carousel__image:nth-child(4) {
animation-delay: 15s;
}
.image-carousel__image:nth-child(5) {
animation-delay: 20s;
}
.image-carousel__image:nth-child(6) {
animation-delay: 25s;
}
/* Each slide fades IN over the previous one (which stays opaque beneath it),
so there is never a moment with no image on screen — works for any count. */
@keyframes carousel-fade {
0% {
opacity: 0;
transform: scale(1);
}
4%,
96% {
opacity: 1;
}
96% {
transform: scale(1.015);
}
100% {
opacity: 0;
transform: scale(1.015);
}
}
@media (prefers-reduced-motion: reduce) {
.image-carousel__image {
animation: none;
opacity: 0;
transform: none;
}
.image-carousel__image:first-child {
opacity: 1;
}
}
+31
View File
@@ -0,0 +1,31 @@
import "./ImageCarousel.css";
const defaultImages = [
"/images/refined/hero/Gemini_Generated_Image_41gc6n41gc6n41gc.jpeg",
"/images/refined/hero/Gemini_Generated_Image_al58e4al58e4al58.jpeg",
"/images/refined/hero/Gemini_Generated_Image_jqdm25jqdm25jqdm.jpeg",
"/images/refined/hero/Gemini_Generated_Image_my47hhmy47hhmy47.jpeg",
];
export default function ImageCarousel({
images = defaultImages,
className = "",
}) {
return (
<div
className={`image-carousel image-carousel--n${images.length} ${className}`.trim()}
aria-hidden="true"
>
{images.map((src) => (
<img
className="image-carousel__image"
src={src}
alt=""
width="1600"
height="1200"
key={src}
/>
))}
</div>
);
}
+53 -6
View File
@@ -31,10 +31,31 @@
top: 10px;
}
.site-header {
border-top: 4px solid var(--industrial);
border-bottom: 1px solid var(--line);
background: #faf9f5;
}
.contact-strip {
display: flex;
justify-content: space-between;
gap: 24px;
padding: 9px var(--page-gutter);
background: #111;
color: #fff;
font-size: 10px;
letter-spacing: 0.04em;
}
.contact-strip__details {
display: flex;
gap: 12px;
}
.contact-strip a {
color: inherit;
text-decoration: none;
}
.contact-strip a:hover {
text-decoration: underline;
text-underline-offset: 3px;
}
.site-header__inner {
display: flex;
justify-content: space-between;
@@ -46,16 +67,26 @@
.brand {
display: inline-flex;
align-items: center;
gap: 16px;
color: var(--ink);
text-decoration: none;
}
.brand__logo {
display: block;
width: 92px;
width: 76px;
height: auto;
}
.brand__name {
padding-left: 16px;
border-left: 1px solid var(--line);
font-size: 13px;
font-weight: 600;
white-space: nowrap;
}
.site-nav {
display: flex;
align-items: center;
gap: 34px;
gap: 25px;
}
.site-nav__link {
position: relative;
@@ -84,7 +115,7 @@
display: flex;
align-items: center;
gap: 30px;
margin-left: 45px;
margin-left: 18px;
padding: 12px 20px;
border: 1px solid var(--industrial-deep);
border-radius: 30px;
@@ -262,14 +293,30 @@
gap: 30px;
}
}
@media (max-width: 760px) {
@media (max-width: 900px) {
.site-header__inner {
min-height: 80px;
flex-wrap: wrap;
gap: 0;
}
.brand__logo {
width: 78px;
width: 62px;
}
.brand__name {
padding-left: 10px;
font-size: 11px;
}
.contact-strip {
align-items: center;
padding-block: 8px;
}
.contact-strip > span {
display: none;
}
.contact-strip__details {
width: 100%;
justify-content: center;
gap: 8px;
}
.site-header__toggle {
display: flex;
+20 -3
View File
@@ -14,6 +14,7 @@ function Brand() {
width="1024"
height="809"
/>
<span className="brand__name">{company.shortName}</span>
</Link>
);
}
@@ -31,6 +32,22 @@ function Header() {
}
}}
>
<div className="contact-strip">
<span>Contact RRS</span>
<div className="contact-strip__details">
{company.email ? (
<a href={`mailto:${company.email}`}>{company.email}</a>
) : (
<span>Email to be supplied</span>
)}
<span aria-hidden="true">·</span>
{company.phone ? (
<a href={`tel:${company.phone}`}>{company.phone}</a>
) : (
<span>Phone to be supplied</span>
)}
</div>
</div>
<div className="site-header__inner">
<Brand />
<button
@@ -67,7 +84,7 @@ function Header() {
to="/contact#whatsapp"
onClick={closeMenu}
>
Request a quote <Arrow diagonal />
Talk to us <Arrow diagonal />
</Link>
</nav>
</div>
@@ -118,7 +135,7 @@ function Footer() {
<span>
© {new Date().getFullYear()} Radhe Radhe Synthetics Pvt. Ltd.
</span>
<span>Commercial supply: greige fabric only.</span>
<span>Commercial supply: grey fabric only.</span>
<a className="site-footer__top-link" href="#top">
Back to top ↑
</a>
@@ -135,7 +152,7 @@ export function ContactBanner({
<em>next construction?</em>
</>
),
text = "Talk to RRS about fabric structure, yarn combinations, bulk requirements or new developments.",
text = "Talk to us about fabric structure, yarn combinations, bulk requirements or new developments.",
}) {
return (
<section className="contact-banner">
+9 -9
View File
@@ -33,7 +33,7 @@ export function Action({ children, to, variant = "dark" }) {
}
export function WhatsAppAction({
children = "Talk to us on WhatsApp",
children = "Talk to us",
variant = "dark",
direct = false,
}) {
@@ -84,31 +84,31 @@ export function SectionHeading({ label, title, children, centered = false }) {
}
export function Textile({
kind = "natural",
src,
className = "",
caption = true,
eager = false,
}) {
return (
<figure className={`textile textile--${kind} ${className}`}>
<figure className={`textile ${className}`}>
<img
className="textile__image"
src={`/images/knit-${kind}.jpg`}
alt="Illustrative knitted texture — not an RRS product photograph"
src={src}
alt="Reference fabric photograph — production photography to follow"
width="1600"
height="1200"
loading={eager ? "eager" : "lazy"}
/>
{caption && (
<figcaption className="textile__caption">
Illustrative texture · RRS photography to follow
Reference fabric · Production photography to follow
</figcaption>
)}
</figure>
);
}
export function PageHero({ label, title, children, texture = "natural" }) {
export function PageHero({ label, title, children, src }) {
return (
<section className="page-hero">
<div className="page-hero__copy">
@@ -116,10 +116,10 @@ export function PageHero({ label, title, children, texture = "natural" }) {
<h1 className="page-hero__title">{title}</h1>
<div className="page-hero__description">{children}</div>
<span className="page-hero__footnote">
Radhe Radhe Synthetics · Greige knitted fabrics
RadheRadhe Pvt. Ltd. · Grey knitted fabrics
</span>
</div>
<Textile kind={texture} eager />
<Textile src={src} eager />
</section>
);
}
+1 -1
View File
@@ -10,7 +10,7 @@ const facts = [
},
{
label: "Our specialisation",
value: "Greige",
value: "Grey",
unit: "Knitted fabrics only",
text: "The starting point for a world of possibilities.",
},
+53 -7
View File
@@ -1,7 +1,8 @@
export const company = Object.freeze({
name: "Radhe Radhe Synthetics Pvt. Ltd.",
shortName: "RadheRadhe Pvt. Ltd.",
description:
"Greige knitted fabrics engineered for diverse apparel applications.",
"Grey knitted fabrics engineered for diverse apparel applications.",
whatsapp: "", // Supply the business number in international digits, without + or spaces.
phone: "",
email: "",
@@ -12,28 +13,29 @@ export const company = Object.freeze({
export const navigation = [
{ to: "/", label: "Home" },
{ to: "/fabrics", label: "Fabrics" },
{ to: "/products", label: "Products" },
{ to: "/about", label: "Manufacturing" },
{ to: "/contact", label: "Contact" },
];
export const capabilities = [
{
title: "01 · Develop",
title: "Develop",
subtitle: "Define the construction",
text: "The requirement begins with the intended application, yarn, blend, structure and fabric character.",
},
{
title: "02 · Configure",
title: "Configure",
subtitle: "Match yarn to machine",
text: "Machine configuration and yarn selection are aligned to the construction being developed.",
},
{
title: "03 · Manufacture",
title: "Manufacture",
subtitle: "Circular knitting at scale",
text: "The approved construction moves into greige production across the appropriate circular-knitting setup.",
text: "The approved construction moves into grey production across the appropriate circular-knitting setup.",
},
{
title: "04 · Repeat",
title: "Repeat",
subtitle: "Maintain bulk consistency",
text: "Successful developments are reproduced with repeatability across commercial manufacturing quantities.",
},
@@ -42,7 +44,7 @@ export const capabilities = [
export const applications = [
{
title: "Shirting constructions",
text: "Greige knitted fabrics developed for shirt and apparel applications.",
text: "Grey knitted fabrics developed for shirt and apparel applications.",
},
{
title: "Textured knits",
@@ -58,6 +60,50 @@ export const applications = [
},
];
export const products = [
{
title: "Polyester",
text: "Versatile knitted constructions developed for everyday apparel and repeat production.",
categories: ["Daily-wear T-shirts", "Joggers", "Innerwear"],
images: [
"/images/refined/products/polyester/Gemini_Generated_Image_cl17jacl17jacl17.jpeg",
"/images/refined/products/polyester/Gemini_Generated_Image_dsdddmdsdddmdsdd.jpeg",
"/images/refined/products/polyester/Gemini_Generated_Image_v0zjkuv0zjkuv0zj.jpeg",
],
},
{
title: "Active Wear",
text: "Performance-led constructions for movement, stretch and active applications.",
categories: ["Sports fabrics", "Yoga", "Pilates"],
images: [
"/images/refined/products/active-wear/Gemini_Generated_Image_6iim9q6iim9q6iim.jpeg",
"/images/refined/products/active-wear/Gemini_Generated_Image_w9uvs8w9uvs8w9uv.jpeg",
"/images/refined/products/active-wear/Gemini_Generated_Image_xc9waxc9waxc9wax.jpeg",
"/images/refined/products/active-wear/Gemini_Generated_Image_ysg0d0ysg0d0ysg0.jpeg",
],
},
{
title: "Imported / Exclusive Fabrics",
text: "Selected distinctive constructions for requirements beyond standard fabric programmes.",
categories: [],
images: [
"/images/refined/products/imported-exclusive/exclusive-01-alpine-fleece.jpeg",
"/images/refined/products/imported-exclusive/exclusive-02-bamboo.jpeg",
"/images/refined/products/imported-exclusive/exclusive-03-blue-construction.jpeg",
],
},
{
title: "Cotton & Viscose",
text: "Soft, breathable constructions for varied garment and womenswear applications.",
categories: ["Garments", "Women’s wear"],
images: [
"/images/refined/products/cotton-viscose/cotton-viscose-02-viscose.jpeg",
"/images/refined/products/cotton-viscose/cotton-viscose-03-tencel-cotton.jpeg",
"/images/refined/products/cotton-viscose/cotton-viscose-04-blue-blend.jpeg",
],
},
];
export const yarns = [
"Polyester",
"Cotton",
+2
View File
@@ -8,6 +8,7 @@ import Home from "./pages/Home";
import Fabrics from "./pages/Fabrics";
import About from "./pages/About";
import Contact from "./pages/Contact";
import Products from "./pages/Products";
import "./base.css";
function NotFound() {
@@ -31,6 +32,7 @@ createRoot(document.getElementById("root")).render(
<Route element={<Layout />}>
<Route index element={<Home />} />
<Route path="fabrics" element={<Fabrics />} />
<Route path="products" element={<Products />} />
<Route path="about" element={<About />} />
<Route path="contact" element={<Contact />} />
<Route path="*" element={<NotFound />} />
+3 -2
View File
@@ -24,7 +24,7 @@ const process = [
},
{
title: "Repeat.",
text: "Successful developments are reproduced consistently in commercial greige production.",
text: "Successful developments are reproduced consistently in commercial grey production.",
},
];
@@ -82,6 +82,7 @@ export default function About() {
<>
<PageHero
label="Manufacturing at RRS"
src="/images/library/hero-01-viscose.jpeg"
title={
<>
Built around
@@ -92,7 +93,7 @@ export default function About() {
>
{" "}
<p>
Radhe Radhe Synthetics is a specialist manufacturer of greige knitted
Radhe Radhe Synthetics is a specialist manufacturer of grey knitted
fabrics with a focus on consistent bulk production and continuous
fabric development.
</p>
+1 -1
View File
@@ -60,7 +60,7 @@ export default function Contact() {
<em>fabric requirement.</em>
</>
}
texture="structured"
src="/images/library/hero-02-tencel-cotton.jpeg"
>
<p>
Share an existing requirement, bulk quantity or new construction with
+3 -2
View File
@@ -10,6 +10,7 @@ export default function Fabrics() {
<>
<PageHero
label="Fabrics & capabilities"
src="/images/library/hero-03-blue-texture.jpeg"
title={
<>
Different yarns.
@@ -19,8 +20,8 @@ export default function Fabrics() {
}
>
<p>
RRS manufactures greige knitted fabrics across diverse yarns, fibres
and blends, with constructions developed according to the required
RRS manufactures grey knitted fabrics across diverse yarns, fibres and
blends, with constructions developed according to the required
texture, appearance and apparel application.
</p>
</PageHero>
+16 -18
View File
@@ -6,27 +6,24 @@
overflow: hidden;
min-height: 768px;
margin-inline: calc(0px - var(--page-gutter));
color: var(--paper);
background: var(--ink);
}
.home-hero__image {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
object-position: center 65%;
color: var(--ink);
background: var(--wash);
}
.home-hero__shade {
position: absolute;
inset: 0;
background:
linear-gradient(90deg, #132630e8 0%, #1f3239a8 54%, #17262f73 100%),
linear-gradient(0deg, #111b22b5 0%, transparent 45%);
z-index: 1;
background: linear-gradient(
90deg,
#f5f3eef5 0%,
#f5f3eed1 42%,
#f5f3ee5c 70%,
transparent 100%
);
}
.home-hero__content {
position: relative;
z-index: 1;
z-index: 2;
max-width: 900px;
padding: 65px 62px 90px;
}
@@ -41,7 +38,7 @@
.home-hero__description {
max-width: 400px;
margin: 0 0 30px;
color: #eeece5;
color: var(--muted);
font-size: 15px;
line-height: 1.8;
}
@@ -52,6 +49,7 @@
}
.home-hero__bottom {
position: absolute;
z-index: 2;
bottom: 0;
left: var(--page-gutter);
right: var(--page-gutter);
@@ -59,18 +57,18 @@
justify-content: space-between;
gap: 20px;
padding: 20px 0;
border-top: 1px solid #ffffff35;
border-top: 1px solid #282a2330;
font-size: 11px;
line-height: 1.6;
}
.home-hero__tagline {
font-size: clamp(14px, 1.2vw, 16px);
font-weight: 500;
color: #ffffff;
color: var(--ink);
letter-spacing: 0.01em;
}
.home-hero__image-note {
color: #e2e2dc;
color: var(--muted);
}
.home-intro {
display: grid;
+15 -16
View File
@@ -9,12 +9,18 @@ import {
} from "../components/Primitives";
import { ContactBanner } from "../components/Layout";
import Gallery from "../components/Gallery";
import ImageCarousel from "../components/ImageCarousel";
import Stats from "../components/Stats";
import "./Home.css";
const processItems = capabilities.map((capability, index) => ({
...capability,
image: ["fine", "natural", "structured", "fine"][index],
image: [
"/images/library/polyester-04.jpeg",
"/images/library/polyester-05.jpeg",
"/images/library/exclusive-04-madagascar.jpeg",
"/images/library/exclusive-05-premium-structure.jpeg",
][index],
href: index < 2 ? "/fabrics#applications" : "/fabrics#production",
}));
@@ -22,14 +28,7 @@ export default function Home() {
return (
<>
<section className="home-hero">
<img
className="home-hero__image"
src="/images/knit-natural.jpg"
alt="Original illustrative macro knit texture, pending RRS photography"
width="1600"
height="1200"
fetchPriority="high"
/>
<ImageCarousel className="home-hero__carousel" />
<div className="home-hero__shade" />
<div className="home-hero__content">
<Eyebrow>Specialist circular-knitting manufacturer · RRS</Eyebrow>
@@ -39,15 +38,15 @@ export default function Home() {
<em>Built to repeat.</em>
</h1>
<p className="home-hero__description">
Greige knitted fabrics developed around yarn, structure and
Grey knitted fabrics developed around yarn, structure and
application—then manufactured for consistent commercial supply.
</p>
<div className="home-hero__actions">
<Action to="/fabrics" variant="light">
<Action to="/fabrics" variant="dark">
Explore our fabrics
</Action>
<Action to="/contact#whatsapp" variant="ghost">
Request a quote
<Action to="/contact#whatsapp" variant="outline">
Talk to us
</Action>
</div>
</div>
@@ -66,14 +65,14 @@ export default function Home() {
<div className="home-intro__heading">
<Eyebrow>Our fabrics</Eyebrow>
<h2 className="home-intro__title">
Greige is where
Grey is where
<br />
<em>it begins.</em>
</h2>
</div>
<div className="home-intro__body">
<p className="home-intro__lead">
RRS specialises in circular-knitted greige fabrics developed for
RRS specialises in circular-knitted grey fabrics developed for
varied apparel applications.
</p>
<p className="home-intro__text">
@@ -118,7 +117,7 @@ export default function Home() {
See our capability <Arrow diagonal />
</Link>
</div>
<Textile className="process__visual" kind={image} />
<Textile className="process__visual" src={image} />
</article>
))}
</div>
+156
View File
@@ -0,0 +1,156 @@
.products-hero {
position: relative;
display: flex;
align-items: center;
min-height: 680px;
margin-inline: calc(0px - var(--page-gutter));
overflow: hidden;
color: var(--ink);
}
.products-hero__shade {
position: absolute;
inset: 0;
z-index: 1;
background: linear-gradient(
90deg,
#f5f3eef5 0%,
#f5f3eed1 42%,
#f5f3ee5c 70%,
transparent 100%
);
}
.products-hero__content {
position: relative;
z-index: 2;
width: min(650px, 65%);
padding: 80px var(--page-gutter) 110px;
}
.products-hero__title {
margin: 28px 0 24px;
font-family: var(--serif);
font-size: clamp(54px, 6.5vw, 92px);
font-weight: 400;
line-height: 0.98;
letter-spacing: -0.045em;
}
.products-hero__text {
max-width: 460px;
margin: 0;
font-size: 15px;
line-height: 1.8;
}
.products-hero__note {
position: absolute;
z-index: 2;
right: var(--page-gutter);
bottom: 24px;
margin: 0;
font-size: 10px;
color: var(--muted);
}
.products-list {
padding-top: 95px;
}
.products-list__grid {
border-top: 1px solid var(--line);
}
.product {
display: grid;
grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
align-items: center;
gap: clamp(36px, 7vw, 110px);
padding: 58px 0;
border-bottom: 1px solid var(--line);
}
.product:nth-child(even) .product__visual {
order: 2;
}
.product__visual {
position: relative;
min-height: 0;
aspect-ratio: 16 / 10;
overflow: hidden;
background: var(--wash);
}
.product__visual img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.product__visual span {
position: absolute;
left: 14px;
bottom: 14px;
padding: 7px 10px;
background: #f5f3eedb;
font-size: 10px;
}
.product__copy {
max-width: 520px;
}
.product__title {
margin: 0 0 20px;
font-family: var(--serif);
font-size: clamp(38px, 4.5vw, 64px);
font-weight: 500;
line-height: 1;
letter-spacing: -0.035em;
}
.product__text {
max-width: 440px;
margin: 0;
color: var(--muted);
font-size: 14px;
line-height: 1.9;
}
.product__categories {
display: flex;
flex-wrap: wrap;
gap: 10px 0;
margin: 26px 0 0;
padding: 0;
list-style: none;
}
.product__categories li {
font-size: 12px;
}
.product__categories li + li::before {
content: "/";
margin: 0 12px;
color: var(--muted);
}
@media (max-width: 700px) {
.products-hero {
min-height: 560px;
}
.products-hero__shade {
background: linear-gradient(90deg, #f5f3eef2, #f5f3ee8a);
}
.products-hero__content {
width: 100%;
padding-bottom: 100px;
}
.products-hero__title {
font-size: clamp(46px, 13vw, 72px);
}
.products-hero__note {
left: var(--page-gutter);
right: var(--page-gutter);
}
.products-list {
padding-top: 60px;
}
.product {
grid-template-columns: 1fr;
gap: 28px;
padding: 42px 0;
}
.product:nth-child(even) .product__visual {
order: 0;
}
.product__visual {
min-height: 0;
aspect-ratio: 4 / 3;
}
}
+69
View File
@@ -0,0 +1,69 @@
import { products } from "../data";
import ImageCarousel from "../components/ImageCarousel";
import { ContactBanner } from "../components/Layout";
import { Eyebrow, SectionHeading } from "../components/Primitives";
import "./Products.css";
export default function Products() {
return (
<>
<section className="products-hero">
<ImageCarousel className="products-hero__carousel" />
<div className="products-hero__shade" />
<div className="products-hero__content">
<Eyebrow>Products</Eyebrow>
<h1 className="products-hero__title">
Knitted for
<br />
<em>everyday performance.</em>
</h1>
<p className="products-hero__text">
Explore the product families RRS manufactures across everyday,
active, exclusive and natural-fibre applications.
</p>
</div>
<p className="products-hero__note">
Illustrative product imagery · RRS photography to follow
</p>
</section>
<section className="products-list">
<SectionHeading
label="Product range"
title={
<>
Built around
<br />
<em>the application.</em>
</>
}
>
<p>
Each family can be developed around the required structure, yarn,
handle and commercial quantity.
</p>
</SectionHeading>
<div className="products-list__grid">
{products.map(({ title, text, categories, images }) => (
<article className="product" key={title}>
<div className="product__visual">
<ImageCarousel images={images} />
</div>
<div className="product__copy">
<h2 className="product__title">{title}</h2>
<p className="product__text">{text}</p>
{categories.length > 0 && (
<ul className="product__categories">
{categories.map((category) => (
<li key={category}>{category}</li>
))}
</ul>
)}
</div>
</article>
))}
</div>
</section>
<ContactBanner />
</>
);
}