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
+40
View File
@@ -0,0 +1,40 @@
category,refined_filename,original_source
hero,hero-01-viscose.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.40.jpeg
hero,hero-02-tencel-cotton.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.41.jpeg
hero,hero-03-blue-texture.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.55 (3).jpeg
hero,hero-04-polyester-tencel.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.10.51 (1).jpeg
hero,hero-05-cotton-viscose-comparison.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.10.49.jpeg
products/polyester,polyester-01.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.10.51 (1).jpeg
products/polyester,polyester-02.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.52.jpeg
products/polyester,polyester-03.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.55 (1).jpeg
products/polyester,polyester-04.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.00.jpeg
products/polyester,polyester-05.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.02.jpeg
products/active-wear,active-wear-01-football.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.00 (3).jpeg
products/active-wear,active-wear-02-osaka-rib.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.04 (1).jpeg
products/active-wear,active-wear-03-cotton-lycra.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.05 (1).jpeg
products/active-wear,active-wear-04-technical-mesh.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.06 (3).jpeg
products/active-wear,active-wear-05-structured.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.11.jpeg
products/imported-exclusive,exclusive-01-alpine-fleece.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.50.jpeg
products/imported-exclusive,exclusive-02-bamboo.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.49 (2).jpeg
products/imported-exclusive,exclusive-03-blue-construction.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.50 (1).jpeg
products/imported-exclusive,exclusive-04-madagascar.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.11 (2).jpeg
products/imported-exclusive,exclusive-05-premium-structure.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.14 (1).jpeg
products/cotton-viscose,cotton-viscose-01-comparison.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.10.49.jpeg
products/cotton-viscose,cotton-viscose-02-viscose.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.40.jpeg
products/cotton-viscose,cotton-viscose-03-tencel-cotton.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.41.jpeg
products/cotton-viscose,cotton-viscose-04-blue-blend.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.55 (3).jpeg
products/cotton-viscose,cotton-viscose-05-open-structure.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.07 (2).jpeg
gallery,gallery-01.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.10.53.jpeg
gallery,gallery-02.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.10.54.jpeg
gallery,gallery-03.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.53 (2).jpeg
gallery,gallery-04.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.56.jpeg
gallery,gallery-05.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.58 (1).jpeg
gallery,gallery-06.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.59.jpeg
gallery,gallery-07.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.00 (1).jpeg
gallery,gallery-08.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.02 (1).jpeg
gallery,gallery-09.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.06 (2).jpeg
gallery,gallery-10.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.07 (2).jpeg
gallery,gallery-11.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.08.jpeg
gallery,gallery-12.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.11 (2).jpeg
gallery,gallery-13.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.13.jpeg
gallery,gallery-14.jpeg,/mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.14 (1).jpeg
1 category refined_filename original_source
2 hero hero-01-viscose.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.40.jpeg
3 hero hero-02-tencel-cotton.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.41.jpeg
4 hero hero-03-blue-texture.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.55 (3).jpeg
5 hero hero-04-polyester-tencel.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.10.51 (1).jpeg
6 hero hero-05-cotton-viscose-comparison.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.10.49.jpeg
7 products/polyester polyester-01.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.10.51 (1).jpeg
8 products/polyester polyester-02.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.52.jpeg
9 products/polyester polyester-03.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.55 (1).jpeg
10 products/polyester polyester-04.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.00.jpeg
11 products/polyester polyester-05.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.02.jpeg
12 products/active-wear active-wear-01-football.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.00 (3).jpeg
13 products/active-wear active-wear-02-osaka-rib.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.04 (1).jpeg
14 products/active-wear active-wear-03-cotton-lycra.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.05 (1).jpeg
15 products/active-wear active-wear-04-technical-mesh.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.06 (3).jpeg
16 products/active-wear active-wear-05-structured.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.11.jpeg
17 products/imported-exclusive exclusive-01-alpine-fleece.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.50.jpeg
18 products/imported-exclusive exclusive-02-bamboo.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.49 (2).jpeg
19 products/imported-exclusive exclusive-03-blue-construction.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.50 (1).jpeg
20 products/imported-exclusive exclusive-04-madagascar.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.11 (2).jpeg
21 products/imported-exclusive exclusive-05-premium-structure.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.14 (1).jpeg
22 products/cotton-viscose cotton-viscose-01-comparison.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.10.49.jpeg
23 products/cotton-viscose cotton-viscose-02-viscose.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.40.jpeg
24 products/cotton-viscose cotton-viscose-03-tencel-cotton.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.41.jpeg
25 products/cotton-viscose cotton-viscose-04-blue-blend.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.55 (3).jpeg
26 products/cotton-viscose cotton-viscose-05-open-structure.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.07 (2).jpeg
27 gallery gallery-01.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.10.53.jpeg
28 gallery gallery-02.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.10.54.jpeg
29 gallery gallery-03.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.53 (2).jpeg
30 gallery gallery-04.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.56.jpeg
31 gallery gallery-05.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.58 (1).jpeg
32 gallery gallery-06.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.11.59.jpeg
33 gallery gallery-07.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.00 (1).jpeg
34 gallery gallery-08.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.02 (1).jpeg
35 gallery gallery-09.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.06 (2).jpeg
36 gallery gallery-10.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.07 (2).jpeg
37 gallery gallery-11.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.08.jpeg
38 gallery gallery-12.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.11 (2).jpeg
39 gallery gallery-13.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.13.jpeg
40 gallery gallery-14.jpeg /mnt/1TB-HDD/WhatsApp Image 2026-09-25 at 12.12.14 (1).jpeg
+12
View File
@@ -0,0 +1,12 @@
# General AI refinement prompt
Refine this photographed textile sample into a clean, premium product image for a professional textile-manufacturing website. Preserve the exact knit structure, weave geometry, fibre texture, pattern scale, colour relationships, and all visible material characteristics of the original sample. Remove stickers, handwriting, printed labels, plastic wrapping, glare, harsh shadows, dust, background clutter, and camera distortion. Correct white balance and exposure, improve edge definition, and apply restrained photographic sharpening without inventing fibres or changing the construction. Place the fabric on a clean warm-neutral studio background (#F5F3EE) with soft, realistic, diffuse lighting. Extend the existing fabric naturally beyond the original frame where needed for the requested composition. Do not add garments, machinery, logos, text, labels, decorative props, new patterns, seams, folds, or surface details that are not present in the source. Do not make the fabric look synthetic, illustrated, plastic, overly smooth, or AI-generated. The result must remain an accurate commercial representation of the supplied fabric.
Output variants:
1. Hero: 16:9 landscape, fabric filling the frame, quiet negative space on the left for website copy.
2. Product card: 4:3 landscape, evenly framed texture, no text.
3. Gallery: 1:1 square macro crop showing the construction clearly, no text.
Quality: photorealistic, natural textile detail, high resolution, consistent colour, web-ready.
Important: compare the result against the original before approval. Reject any output that alters the knit pattern, hole spacing, rib direction, yarn thickness, fibre content appearance, or colour.
Binary file not shown.

After

Width:  |  Height:  |  Size: 832 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 686 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 874 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 826 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 941 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1024 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 604 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 750 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 832 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 686 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 759 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 920 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 683 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 480 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 KiB

+42
View File
@@ -0,0 +1,42 @@
"""Pre-scale the carousel imagery so browsers never upscale it.
The refined fabric shots top out at 1024-1376px, but the full-bleed hero paints
them across up to ~1920 CSS px (3840 device px on retina). Browsers enlarge them
at render time and the knit stitches smear. Resampling once with Lanczos plus a
light unsharp pass keeps the texture readable and, at these sizes, costs about
the same bytes as the originals. Requires Pillow. Generated assets are committed;
runtime needs nothing.
"""
from pathlib import Path
import sys
from PIL import Image, ImageFilter
ROOT = Path(__file__).resolve().parents[1]
TARGETS = [ROOT / "public" / "images" / "refined" / "hero",
ROOT / "public" / "images" / "refined" / "products"]
LONG_EDGE = 2048
QUALITY = 82
def optimize(path):
with Image.open(path) as source:
image = source.convert("RGB")
scale = LONG_EDGE / max(image.size)
if scale > 1:
image = image.resize(
(round(image.width * scale), round(image.height * scale)),
Image.Resampling.LANCZOS,
)
image = image.filter(ImageFilter.UnsharpMask(radius=1.0, percent=60, threshold=3))
before = path.stat().st_size
image.save(path, quality=QUALITY, optimize=True, progressive=True)
after = path.stat().st_size
print(f"{path.relative_to(ROOT)} {image.size} {before // 1024}KB -> {after // 1024}KB")
if __name__ == "__main__":
files = sorted(p for target in TARGETS for p in target.rglob("*.jpeg"))
if not files:
sys.exit("no carousel images found")
for file in files:
optimize(file)
+14 -7
View File
@@ -2,7 +2,15 @@ import { developments } from "../data";
import { Action, SectionHeading } from "./Primitives"; import { Action, SectionHeading } from "./Primitives";
import "./Gallery.css"; 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 }) { export default function Gallery({ preview = false }) {
const items = preview ? developments.slice(0, 3) : developments; const items = preview ? developments.slice(0, 3) : developments;
@@ -22,7 +30,7 @@ export default function Gallery({ preview = false }) {
</> </>
) : ( ) : (
<> <>
From greige From grey
<br /> <br />
<em>to possibility.</em> <em>to possibility.</em>
</> </>
@@ -32,7 +40,7 @@ export default function Gallery({ preview = false }) {
<p className="gallery__intro"> <p className="gallery__intro">
{preview {preview
? "A selection of knitted structures showing how yarn, composition and machine setup shape the final fabric character." ? "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> </p>
{preview && ( {preview && (
<Action to="/fabrics#developments" variant="outline"> <Action to="/fabrics#developments" variant="outline">
@@ -46,13 +54,12 @@ export default function Gallery({ preview = false }) {
<div className="sample__visual"> <div className="sample__visual">
<img <img
className="sample__image" className="sample__image"
src={`/images/knit-${textures[index % textures.length]}.jpg`} src={textures[index]}
alt={`Illustrative placeholder for ${name}; RRS sample photograph not yet supplied`} alt={`${name} fabric sample`}
width="1600" width="1600"
height="1200" height="1200"
loading="lazy" loading="lazy"
/> />
<span className="sample__badge">Image placeholder</span>
</div> </div>
<div className="sample__heading"> <div className="sample__heading">
<h3 className="sample__name">{name}</h3> <h3 className="sample__name">{name}</h3>
@@ -75,7 +82,7 @@ export default function Gallery({ preview = false }) {
When supplied, processed images will be labelled{" "} When supplied, processed images will be labelled{" "}
<strong>Processed Development Reference</strong>. Processed samples <strong>Processed Development Reference</strong>. Processed samples
are for visual reference; RRS commercially manufactures and supplies 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. buyer’s processing and finishing method.
</p> </p>
</div> </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; top: 10px;
} }
.site-header { .site-header {
border-top: 4px solid var(--industrial);
border-bottom: 1px solid var(--line); border-bottom: 1px solid var(--line);
background: #faf9f5; 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 { .site-header__inner {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@@ -46,16 +67,26 @@
.brand { .brand {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
gap: 16px;
color: var(--ink);
text-decoration: none;
} }
.brand__logo { .brand__logo {
display: block; display: block;
width: 92px; width: 76px;
height: auto; height: auto;
} }
.brand__name {
padding-left: 16px;
border-left: 1px solid var(--line);
font-size: 13px;
font-weight: 600;
white-space: nowrap;
}
.site-nav { .site-nav {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 34px; gap: 25px;
} }
.site-nav__link { .site-nav__link {
position: relative; position: relative;
@@ -84,7 +115,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
gap: 30px; gap: 30px;
margin-left: 45px; margin-left: 18px;
padding: 12px 20px; padding: 12px 20px;
border: 1px solid var(--industrial-deep); border: 1px solid var(--industrial-deep);
border-radius: 30px; border-radius: 30px;
@@ -262,14 +293,30 @@
gap: 30px; gap: 30px;
} }
} }
@media (max-width: 760px) { @media (max-width: 900px) {
.site-header__inner { .site-header__inner {
min-height: 80px; min-height: 80px;
flex-wrap: wrap; flex-wrap: wrap;
gap: 0; gap: 0;
} }
.brand__logo { .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 { .site-header__toggle {
display: flex; display: flex;
+20 -3
View File
@@ -14,6 +14,7 @@ function Brand() {
width="1024" width="1024"
height="809" height="809"
/> />
<span className="brand__name">{company.shortName}</span>
</Link> </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"> <div className="site-header__inner">
<Brand /> <Brand />
<button <button
@@ -67,7 +84,7 @@ function Header() {
to="/contact#whatsapp" to="/contact#whatsapp"
onClick={closeMenu} onClick={closeMenu}
> >
Request a quote <Arrow diagonal /> Talk to us <Arrow diagonal />
</Link> </Link>
</nav> </nav>
</div> </div>
@@ -118,7 +135,7 @@ function Footer() {
<span> <span>
© {new Date().getFullYear()} Radhe Radhe Synthetics Pvt. Ltd. © {new Date().getFullYear()} Radhe Radhe Synthetics Pvt. Ltd.
</span> </span>
<span>Commercial supply: greige fabric only.</span> <span>Commercial supply: grey fabric only.</span>
<a className="site-footer__top-link" href="#top"> <a className="site-footer__top-link" href="#top">
Back to top ↑ Back to top ↑
</a> </a>
@@ -135,7 +152,7 @@ export function ContactBanner({
<em>next construction?</em> <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 ( return (
<section className="contact-banner"> <section className="contact-banner">
+9 -9
View File
@@ -33,7 +33,7 @@ export function Action({ children, to, variant = "dark" }) {
} }
export function WhatsAppAction({ export function WhatsAppAction({
children = "Talk to us on WhatsApp", children = "Talk to us",
variant = "dark", variant = "dark",
direct = false, direct = false,
}) { }) {
@@ -84,31 +84,31 @@ export function SectionHeading({ label, title, children, centered = false }) {
} }
export function Textile({ export function Textile({
kind = "natural", src,
className = "", className = "",
caption = true, caption = true,
eager = false, eager = false,
}) { }) {
return ( return (
<figure className={`textile textile--${kind} ${className}`}> <figure className={`textile ${className}`}>
<img <img
className="textile__image" className="textile__image"
src={`/images/knit-${kind}.jpg`} src={src}
alt="Illustrative knitted texture — not an RRS product photograph" alt="Reference fabric photograph — production photography to follow"
width="1600" width="1600"
height="1200" height="1200"
loading={eager ? "eager" : "lazy"} loading={eager ? "eager" : "lazy"}
/> />
{caption && ( {caption && (
<figcaption className="textile__caption"> <figcaption className="textile__caption">
Illustrative texture · RRS photography to follow Reference fabric · Production photography to follow
</figcaption> </figcaption>
)} )}
</figure> </figure>
); );
} }
export function PageHero({ label, title, children, texture = "natural" }) { export function PageHero({ label, title, children, src }) {
return ( return (
<section className="page-hero"> <section className="page-hero">
<div className="page-hero__copy"> <div className="page-hero__copy">
@@ -116,10 +116,10 @@ export function PageHero({ label, title, children, texture = "natural" }) {
<h1 className="page-hero__title">{title}</h1> <h1 className="page-hero__title">{title}</h1>
<div className="page-hero__description">{children}</div> <div className="page-hero__description">{children}</div>
<span className="page-hero__footnote"> <span className="page-hero__footnote">
Radhe Radhe Synthetics · Greige knitted fabrics RadheRadhe Pvt. Ltd. · Grey knitted fabrics
</span> </span>
</div> </div>
<Textile kind={texture} eager /> <Textile src={src} eager />
</section> </section>
); );
} }
+1 -1
View File
@@ -10,7 +10,7 @@ const facts = [
}, },
{ {
label: "Our specialisation", label: "Our specialisation",
value: "Greige", value: "Grey",
unit: "Knitted fabrics only", unit: "Knitted fabrics only",
text: "The starting point for a world of possibilities.", text: "The starting point for a world of possibilities.",
}, },
+53 -7
View File
@@ -1,7 +1,8 @@
export const company = Object.freeze({ export const company = Object.freeze({
name: "Radhe Radhe Synthetics Pvt. Ltd.", name: "Radhe Radhe Synthetics Pvt. Ltd.",
shortName: "RadheRadhe Pvt. Ltd.",
description: 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. whatsapp: "", // Supply the business number in international digits, without + or spaces.
phone: "", phone: "",
email: "", email: "",
@@ -12,28 +13,29 @@ export const company = Object.freeze({
export const navigation = [ export const navigation = [
{ to: "/", label: "Home" }, { to: "/", label: "Home" },
{ to: "/fabrics", label: "Fabrics" }, { to: "/fabrics", label: "Fabrics" },
{ to: "/products", label: "Products" },
{ to: "/about", label: "Manufacturing" }, { to: "/about", label: "Manufacturing" },
{ to: "/contact", label: "Contact" }, { to: "/contact", label: "Contact" },
]; ];
export const capabilities = [ export const capabilities = [
{ {
title: "01 · Develop", title: "Develop",
subtitle: "Define the construction", subtitle: "Define the construction",
text: "The requirement begins with the intended application, yarn, blend, structure and fabric character.", text: "The requirement begins with the intended application, yarn, blend, structure and fabric character.",
}, },
{ {
title: "02 · Configure", title: "Configure",
subtitle: "Match yarn to machine", subtitle: "Match yarn to machine",
text: "Machine configuration and yarn selection are aligned to the construction being developed.", text: "Machine configuration and yarn selection are aligned to the construction being developed.",
}, },
{ {
title: "03 · Manufacture", title: "Manufacture",
subtitle: "Circular knitting at scale", 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", subtitle: "Maintain bulk consistency",
text: "Successful developments are reproduced with repeatability across commercial manufacturing quantities.", text: "Successful developments are reproduced with repeatability across commercial manufacturing quantities.",
}, },
@@ -42,7 +44,7 @@ export const capabilities = [
export const applications = [ export const applications = [
{ {
title: "Shirting constructions", 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", 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 = [ export const yarns = [
"Polyester", "Polyester",
"Cotton", "Cotton",
+2
View File
@@ -8,6 +8,7 @@ import Home from "./pages/Home";
import Fabrics from "./pages/Fabrics"; import Fabrics from "./pages/Fabrics";
import About from "./pages/About"; import About from "./pages/About";
import Contact from "./pages/Contact"; import Contact from "./pages/Contact";
import Products from "./pages/Products";
import "./base.css"; import "./base.css";
function NotFound() { function NotFound() {
@@ -31,6 +32,7 @@ createRoot(document.getElementById("root")).render(
<Route element={<Layout />}> <Route element={<Layout />}>
<Route index element={<Home />} /> <Route index element={<Home />} />
<Route path="fabrics" element={<Fabrics />} /> <Route path="fabrics" element={<Fabrics />} />
<Route path="products" element={<Products />} />
<Route path="about" element={<About />} /> <Route path="about" element={<About />} />
<Route path="contact" element={<Contact />} /> <Route path="contact" element={<Contact />} />
<Route path="*" element={<NotFound />} /> <Route path="*" element={<NotFound />} />
+3 -2
View File
@@ -24,7 +24,7 @@ const process = [
}, },
{ {
title: "Repeat.", 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 <PageHero
label="Manufacturing at RRS" label="Manufacturing at RRS"
src="/images/library/hero-01-viscose.jpeg"
title={ title={
<> <>
Built around Built around
@@ -92,7 +93,7 @@ export default function About() {
> >
{" "} {" "}
<p> <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 fabrics with a focus on consistent bulk production and continuous
fabric development. fabric development.
</p> </p>
+1 -1
View File
@@ -60,7 +60,7 @@ export default function Contact() {
<em>fabric requirement.</em> <em>fabric requirement.</em>
</> </>
} }
texture="structured" src="/images/library/hero-02-tencel-cotton.jpeg"
> >
<p> <p>
Share an existing requirement, bulk quantity or new construction with Share an existing requirement, bulk quantity or new construction with
+3 -2
View File
@@ -10,6 +10,7 @@ export default function Fabrics() {
<> <>
<PageHero <PageHero
label="Fabrics & capabilities" label="Fabrics & capabilities"
src="/images/library/hero-03-blue-texture.jpeg"
title={ title={
<> <>
Different yarns. Different yarns.
@@ -19,8 +20,8 @@ export default function Fabrics() {
} }
> >
<p> <p>
RRS manufactures greige knitted fabrics across diverse yarns, fibres RRS manufactures grey knitted fabrics across diverse yarns, fibres and
and blends, with constructions developed according to the required blends, with constructions developed according to the required
texture, appearance and apparel application. texture, appearance and apparel application.
</p> </p>
</PageHero> </PageHero>
+16 -18
View File
@@ -6,27 +6,24 @@
overflow: hidden; overflow: hidden;
min-height: 768px; min-height: 768px;
margin-inline: calc(0px - var(--page-gutter)); margin-inline: calc(0px - var(--page-gutter));
color: var(--paper); color: var(--ink);
background: var(--ink); background: var(--wash);
}
.home-hero__image {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
object-position: center 65%;
} }
.home-hero__shade { .home-hero__shade {
position: absolute; position: absolute;
inset: 0; inset: 0;
background: z-index: 1;
linear-gradient(90deg, #132630e8 0%, #1f3239a8 54%, #17262f73 100%), background: linear-gradient(
linear-gradient(0deg, #111b22b5 0%, transparent 45%); 90deg,
#f5f3eef5 0%,
#f5f3eed1 42%,
#f5f3ee5c 70%,
transparent 100%
);
} }
.home-hero__content { .home-hero__content {
position: relative; position: relative;
z-index: 1; z-index: 2;
max-width: 900px; max-width: 900px;
padding: 65px 62px 90px; padding: 65px 62px 90px;
} }
@@ -41,7 +38,7 @@
.home-hero__description { .home-hero__description {
max-width: 400px; max-width: 400px;
margin: 0 0 30px; margin: 0 0 30px;
color: #eeece5; color: var(--muted);
font-size: 15px; font-size: 15px;
line-height: 1.8; line-height: 1.8;
} }
@@ -52,6 +49,7 @@
} }
.home-hero__bottom { .home-hero__bottom {
position: absolute; position: absolute;
z-index: 2;
bottom: 0; bottom: 0;
left: var(--page-gutter); left: var(--page-gutter);
right: var(--page-gutter); right: var(--page-gutter);
@@ -59,18 +57,18 @@
justify-content: space-between; justify-content: space-between;
gap: 20px; gap: 20px;
padding: 20px 0; padding: 20px 0;
border-top: 1px solid #ffffff35; border-top: 1px solid #282a2330;
font-size: 11px; font-size: 11px;
line-height: 1.6; line-height: 1.6;
} }
.home-hero__tagline { .home-hero__tagline {
font-size: clamp(14px, 1.2vw, 16px); font-size: clamp(14px, 1.2vw, 16px);
font-weight: 500; font-weight: 500;
color: #ffffff; color: var(--ink);
letter-spacing: 0.01em; letter-spacing: 0.01em;
} }
.home-hero__image-note { .home-hero__image-note {
color: #e2e2dc; color: var(--muted);
} }
.home-intro { .home-intro {
display: grid; display: grid;

Some files were not shown because too many files have changed in this diff Show More