> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bfl.ml/llms.txt
> Use this file to discover all available pages before exploring further.

# Fashion

> Change outfits, add accessories, and recolor garments on existing photos with FLUX.2, using hex color codes for precise control.

export const MultiRefMasonry = ({inputs = [], result = {}, prompt = ""}) => {
  const [hoveredInput, setHoveredInput] = useState(-1);
  const colors = [{
    bg: "rgba(99,182,137,0.22)",
    border: "#63b689",
    text: "#63b689"
  }, {
    bg: "rgba(130,170,255,0.22)",
    border: "#82aaff",
    text: "#82aaff"
  }, {
    bg: "rgba(255,180,107,0.22)",
    border: "#ffb46b",
    text: "#ffb46b"
  }, {
    bg: "rgba(199,140,230,0.22)",
    border: "#c78ce6",
    text: "#c78ce6"
  }, {
    bg: "rgba(255,130,130,0.22)",
    border: "#ff8282",
    text: "#ff8282"
  }, {
    bg: "rgba(130,220,220,0.22)",
    border: "#82dcdc",
    text: "#82dcdc"
  }, {
    bg: "rgba(220,200,120,0.22)",
    border: "#dcc878",
    text: "#dcc878"
  }, {
    bg: "rgba(200,160,180,0.22)",
    border: "#c8a0b4",
    text: "#c8a0b4"
  }];
  const renderPrompt = () => {
    if (!prompt) return null;
    const parts = [];
    let lastIndex = 0;
    const re = /\b(image\s+(\d))\b/gi;
    let m;
    while ((m = re.exec(prompt)) !== null) {
      if (m.index > lastIndex) parts.push({
        text: prompt.slice(lastIndex, m.index),
        idx: -1
      });
      parts.push({
        text: m[1],
        idx: parseInt(m[2], 10) - 1
      });
      lastIndex = m.index + m[0].length;
    }
    if (lastIndex < prompt.length) parts.push({
      text: prompt.slice(lastIndex),
      idx: -1
    });
    return parts.map((p, i) => {
      if (p.idx >= 0 && p.idx < colors.length) {
        const c = colors[p.idx];
        return <span key={i} style={{
          color: c.text,
          fontWeight: 700,
          padding: "1px 5px",
          borderRadius: "3px",
          background: hoveredInput === p.idx ? c.bg : "transparent",
          transition: "background 200ms"
        }}>
            {p.text}
          </span>;
      }
      return <span key={i}>{p.text}</span>;
    });
  };
  const n = inputs.length;
  const useLeftRight = n <= 4;
  const inputItem = (img, idx) => {
    const c = colors[idx % colors.length];
    const isHovered = hoveredInput === idx;
    return <div key={idx} onMouseEnter={() => setHoveredInput(idx)} onMouseLeave={() => setHoveredInput(-1)} style={{
      position: "relative",
      overflow: "hidden",
      borderRadius: "4px",
      cursor: "default",
      outline: isHovered ? "2px solid " + c.border : "2px solid transparent",
      outlineOffset: "-2px",
      transition: "outline-color 150ms ease"
    }}>
        <img src={img.src} alt={img.label || "Input " + (idx + 1)} style={{
      display: "block",
      width: "100%",
      height: "auto",
      pointerEvents: "none"
    }} />
        <div style={{
      position: "absolute",
      top: "4px",
      left: "4px",
      width: "22px",
      height: "22px",
      borderRadius: "50%",
      background: c.border,
      color: "#000",
      display: "flex",
      alignItems: "center",
      justifyContent: "center",
      fontSize: "0.65rem",
      fontWeight: 800,
      boxShadow: "0 1px 4px rgba(0,0,0,0.5)"
    }}>
          {idx + 1}
        </div>
      </div>;
  };
  const resultItem = <div style={{
    position: "relative",
    overflow: "hidden",
    borderRadius: "4px"
  }}>
      <img src={result.src} alt={result.label || "Result"} style={{
    display: "block",
    width: "100%",
    height: "auto",
    pointerEvents: "none"
  }} />
      <div style={{
    position: "absolute",
    top: "6px",
    right: "6px",
    padding: "3px 10px",
    borderRadius: "5px",
    background: "rgba(0,0,0,0.6)",
    backdropFilter: "blur(4px)",
    color: "#fff",
    fontSize: "0.65rem",
    fontWeight: 600
  }}>
        Result
      </div>
    </div>;
  const inputRows = n <= 2 ? n : n <= 4 ? 2 : n;
  const inputColsInner = n <= 3 ? 1 : 2;
  return <div className="not-prose" style={{
    borderRadius: "0.75rem",
    border: "1px solid rgba(255,255,255,0.08)",
    background: "#000000"
  }}>

      {useLeftRight ? <div style={{
    display: "grid",
    gridTemplateColumns: "1fr 2fr",
    gap: "3px",
    padding: "3px",
    alignItems: "start"
  }}>
          {}
          <div style={{
    display: "grid",
    gridTemplateColumns: "repeat(" + inputColsInner + ", 1fr)",
    gridTemplateRows: "repeat(" + inputRows + ", auto)",
    gap: "3px"
  }}>
            {inputs.map((img, idx) => inputItem(img, idx))}
          </div>
          {}
          {resultItem}
        </div> : <div style={{
    display: "flex",
    flexDirection: "column",
    gap: "3px",
    padding: "3px"
  }}>
          <div style={{
    display: "grid",
    gridTemplateColumns: "repeat(" + Math.min(n, 6) + ", 1fr)",
    gap: "3px"
  }}>
            {inputs.map((img, idx) => inputItem(img, idx))}
          </div>
          {resultItem}
        </div>}

      {}
      {prompt && <div style={{
    padding: "0.5rem 0.5rem 0.6rem"
  }}>
          <div style={{
    padding: "0.6rem 0.75rem",
    borderRadius: "6px",
    background: "rgba(255,255,255,0.06)",
    border: "1px solid rgba(255,255,255,0.10)",
    fontFamily: "monospace",
    fontSize: "0.72rem",
    lineHeight: 1.6,
    color: "rgba(255,255,255,0.7)"
  }}>
            <span style={{
    color: "rgba(255,255,255,0.35)",
    fontSize: "0.6rem",
    marginRight: "5px"
  }}>prompt:</span>
            {renderPrompt()}
          </div>
        </div>}
    </div>;
};

export const PromptDisplay = ({prompt}) => {
  const [copied, setCopied] = useState(false);
  const copy = () => {
    navigator.clipboard.writeText(prompt);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };
  return <div className="not-prose" style={{
    marginTop: "1rem"
  }}>
      <div style={{
    backgroundColor: "#1a1a1a",
    borderRadius: "1rem",
    padding: "1.25rem 1.5rem",
    display: "flex",
    flexDirection: "column",
    gap: "1rem"
  }}>
        <p style={{
    color: "#e5e5e5",
    fontSize: "1rem",
    lineHeight: 1.6,
    margin: 0,
    fontFamily: "inherit"
  }}>
          {prompt}
        </p>
        <div style={{
    display: "flex",
    justifyContent: "flex-end"
  }}>
          <button onClick={copy} style={{
    backgroundColor: copied ? "#3d8a5b" : "var(--aspen-evergreen, #486A58)",
    color: "#fff",
    border: "none",
    borderRadius: "0.375rem",
    padding: "0.25rem 0.6rem",
    fontSize: "0.7rem",
    fontWeight: 600,
    cursor: "pointer",
    transition: "background-color 0.2s"
  }}>
            {copied ? "Copied!" : "Copy prompt"}
          </button>
        </div>
      </div>
    </div>;
};

FLUX.2 can change outfits, add accessories, recolor garments, and adapt clothing styles on existing photos. Use hex color codes for precise color control and describe fabric details to preserve realism.

## Examples

### Virtual try-on from product image

<Columns cols={2}>
  <img src="https://cdn.sanity.io/images/2gpum2i6/production/f41f929d85560abe026eb5693ba0be102258e1a3-1800x2592.png" alt="Black hooded jacket product shot" />

  <img src="https://cdn.sanity.io/images/2gpum2i6/production/6dd39900da3912fd414536acf46581c75e354bf9-992x1440.png" alt="Man wearing black hooded jacket on beach" />
</Columns>

<PromptDisplay prompt="The man is wearing the hooded jacket from image 1, walking on a beach at golden hour" />

### Full outfit change

<Columns cols={2}>
  <img src="https://cdn.sanity.io/images/2gpum2i6/production/6579b7ebe92a74bd1751a3a1cc326ae22913b32b-1033x1549.jpg" alt="Woman in original outfit" />

  <img src="https://cdn.sanity.io/images/2gpum2i6/production/c7290aa10cf6fefde30483bb4c94244042a63165-960x1440.png" alt="Woman in fuchsia dress" />
</Columns>

<PromptDisplay prompt="Change the woman's outfit to a bold fuchsia pink dress against a green studio gradient background." />

### Precise dress recoloring

<Columns cols={2}>
  <img src="https://cdn.sanity.io/images/2gpum2i6/production/bb82e82e1bdc520dbe56f745d7747ddc60a26760-3456x5184.jpg" alt="White lace wedding dress" />

  <img src="https://cdn.sanity.io/images/2gpum2i6/production/29a25e49a0f1f5d563c5cc0e6721b763351f6452-960x1440.png" alt="Sky blue lace wedding dress" />
</Columns>

<PromptDisplay prompt="Change the color of the woman's lace wedding dress to sky blue (light blue, #87CEEB), while keeping all lace embroidery details white and fully visible. Preserve the original fabric texture, transparency, patterns, highlights, and natural folds." />

### Add accessories with hex colors

<Columns cols={2}>
  <img src="https://cdn.sanity.io/images/2gpum2i6/production/ba0d03ae17f20399af993b40eeb84f698b11a180-1287x1929.png" alt="Woman without jacket" />

  <img src="https://cdn.sanity.io/images/2gpum2i6/production/5a24563bf7ac4b3bc8b90e7d8bb7f363fbeba3b1-960x1440.png" alt="Woman with fluffy jacket and hat" />
</Columns>

<PromptDisplay prompt="Add a short fluffy jacket on her colored #778899, and a hat in the same fluffy style, colored #98AFC7. Keep her pose" />

### Seasonal outfit + scene change

<Columns cols={2}>
  <img src="https://cdn.sanity.io/images/2gpum2i6/production/f1593a684df0df252e1d03c64d4000b21d5948a9-960x1440.png" alt="Woman in original scene" />

  <img src="https://cdn.sanity.io/images/2gpum2i6/production/067391e56a9159ed51e81c11a6776ca5ac420f80-960x1440.png" alt="Woman in winter outfit with snow" />
</Columns>

<PromptDisplay prompt="Keep the woman's pose unchanged. It is now heavily snowing, the background is white and the trees are bare. Snowflakes are visible falling in the frame. The woman is wearing a black coat, and the umbrella is a yellowish-green color" />

### Fashion editorial — volcanic landscape

<MultiRefMasonry
  inputs={[
{ src: "https://cdn.sanity.io/images/2gpum2i6/production/37e4806e60f200a6d1e91c293e5d692cb959eba5-1801x2600.webp", label: "Shoes" },
{ src: "https://cdn.sanity.io/images/2gpum2i6/production/7feabf6fe8b13ad66b99aaa85389365ff9f762b4-1347x1941.webp", label: "Jacket" },
{ src: "https://cdn.sanity.io/images/2gpum2i6/production/002aeb1a553d9b665b716005aec984383cdcba1a-1800x2592.webp", label: "Jeans" },
{ src: "https://cdn.sanity.io/images/2gpum2i6/production/2c440ffd03bdb8282414b8ad1155d2e37bab96c3-1801x2600.webp", label: "Shirt" },
{ src: "https://cdn.sanity.io/images/2gpum2i6/production/e2a93a31ba4a4c0562bd615881f1987419adab46-1801x2600.webp", label: "Cap" },
{ src: "https://cdn.sanity.io/images/2gpum2i6/production/393af3a74a9faebd93e2827bc91bfe39241198d5-800x1156.webp", label: "Tie" },
]}
  result={{ src: "https://cdn.sanity.io/images/2gpum2i6/production/73311a39cf82bcb121d8fb2997ecc1dead9fac7f-992x1440.png" }}
  prompt="A dramatic geological photograph captured on expired Agfachrome 100 slide film cross-processed from 1990 with a 35mm spherical lens at f/8, featuring model standing on black lava rock field. The model wears the outfit, positioned on jagged basalt formations, red jersey creating stark color contrast against black rock. Background shows otherworldly volcanic landscape - sharp lava rocks, steam vents releasing white smoke, distant active lava glow, ash-covered ground, no vegetation, alien barren terrain. Overcast grey sky with volcanic ash haze at 1/250. Cross-processed Agfachrome showing extreme contrast, desaturated landscape with punchy red jersey, cyan-magenta split, crushed blacks in rocks, blown highlights in steam, heavy grain. Composition emphasizes post-apocalyptic fashion editorial. Hiroshi Sugimoto seascapes minimalism, Andreas Gursky epic landscapes, sci-fi fashion photography aesthetic."
/>

### Fashion editorial — gas station night

<MultiRefMasonry
  inputs={[
{ src: "https://cdn.sanity.io/images/2gpum2i6/production/8b8f915bc81406d7c7d9bd29d17fa5c57482b5a4-1801x2600.webp", label: "Sunglasses" },
{ src: "https://cdn.sanity.io/images/2gpum2i6/production/cc74b82bad2d75dbc938f1d1de6f98fecb1d162a-762x1100.webp", label: "Beanie" },
{ src: "https://cdn.sanity.io/images/2gpum2i6/production/a0a82ecc5bc1d9000480ee2f0fe5c00deb72cf2b-1801x2600.webp", label: "Trousers" },
{ src: "https://cdn.sanity.io/images/2gpum2i6/production/27fc7456c2f9522a70ce0f60185fb20e2b0571a6-1801x2600.webp", label: "Jersey" },
{ src: "https://cdn.sanity.io/images/2gpum2i6/production/37e4806e60f200a6d1e91c293e5d692cb959eba5-1801x2600.webp", label: "Shoes" },
]}
  result={{ src: "https://cdn.sanity.io/images/2gpum2i6/production/c3e34d8be20888999ec0baa9d91b3da2dcec06aa-1440x2048.png" }}
  prompt="A medium-wide fashion photograph captured on expired Kodak Portra 800 film pushed one stop from 1990 with a 50mm spherical lens at f/2, featuring male model at abandoned gas station at night. The model wears the outfit, leaning casually against vintage fuel pump with hands in trouser pockets, head slightly tilted in confident pose. Background shows derelict gas station - peeling paint on pump, cracked concrete, flickering neon sign casting magenta-green glow, distant highway lights. Deep blue night sky. Single sodium vapor streetlight creating harsh orange-yellow illumination from above at 1/60 second. Expired pushed Portra showing heavy grain structure, warm orange cast, cyan-magenta split, soft contrast, glowing highlights around neon, elevated saturation. Composition emphasizes urban decay meets sportswear luxury. 1990s hip-hop fashion editorial aesthetic meets Juergen Teller snapshot style."
/>
