// Editorial Agency Profile.
// Full-width ledger → contained 4:5 hero → bio → contact rail → stats sheet →
// justified portfolio gallery (click to enlarge, video plays) → footer.

if (typeof document !== "undefined" && !document.getElementById("profile-polish-css")) {
  const s = document.createElement("style");
  s.id = "profile-polish-css";
  s.textContent = `
      .cl-profile {
        overflow-x: clip;
        text-wrap: pretty;
      }
      .cl-contact-rail,
      .cl-stats-triad {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
      }
      .cl-contact-link {
        min-width: 0;
      }
    .cl-clickable:focus-visible,
    .cl-footer a:focus-visible {
      outline: 1px solid var(--fg);
      outline-offset: 5px;
    }
    .cl-empty {
      min-height: 240px;
      display: grid;
      place-items: center;
      border: 1px solid var(--rule);
      background: linear-gradient(135deg, rgba(243,239,233,0.055), rgba(243,239,233,0.018));
    }
    @media (max-width: 860px) {
      .cl-ledger,
      .cl-stats-grid,
      .cl-footer-grid {
        grid-template-columns: 1fr !important;
      }
      .cl-stats-triad {
        grid-template-columns: 1fr;
      }
      .cl-ledger-cell,
      .cl-footer-grid {
        justify-content: flex-start !important;
      }
      .cl-split-hero {
        grid-template-columns: 1fr !important;
        min-height: 0 !important;
      }
      .cl-split-copy {
        border-right: 0 !important;
        border-bottom: 1px solid var(--rule) !important;
      }
      .cl-stat-row {
        grid-template-columns: minmax(92px, 34%) 1fr !important;
        gap: 12px !important;
      }
      .cl-stat-row > span:last-child {
        grid-column: 2;
      }
      .cl-contact-rail {
        grid-template-columns: 1fr;
      }
      .cl-section-head {
        align-items: flex-start !important;
        flex-direction: column !important;
      }
      .cl-gallery-row {
        flex-direction: column !important;
      }
      .cl-gallery-row figure {
        width: 100% !important;
        height: auto !important;
        flex-basis: auto !important;
      }
      .cl-gallery-row .mi {
        height: auto !important;
      }
      .cl-grid-strict {
        grid-template-columns: 1fr 1fr !important;
      }
    }
    @media (max-width: 560px) {
      .cl-name-lockup {
        font-size: clamp(48px, 17vw, 82px) !important;
      }
      .cl-hero-vitals {
        display: grid !important;
        grid-template-columns: 1fr !important;
        gap: 8px !important;
        text-align: center !important;
      }
    }
  `;
  document.head.appendChild(s);
}

function splitProse(value) {
  return String(value || "")
    .replace(/\r\n?/g, "\n")
    .split(/\n{2,}|(?<=\.)\s+(?=[A-Z])/)
    .map((paragraph) => paragraph.replace(/\s+/g, " ").trim())
    .filter(Boolean);
}

function ClProse({ text, italic = false, quote = false }) {
  const paragraphs = splitProse(text);
  if (!paragraphs.length) return null;

  return (
    <>
      {paragraphs.map((paragraph, index) => (
        <p key={index} style={{ margin: index === 0 ? 0 : "0.82em 0 0" }}>
          {quote && index === 0 ? "“" : ""}{paragraph}{quote && index === paragraphs.length - 1 ? "”" : ""}
        </p>
      ))}
    </>
  );
}

function ProfileClinical({ model, tweaks }) {
  const rootRef = React.useRef(null);
  React.useEffect(() => { applyTheme(rootRef.current, tweaks); }, [tweaks]);

  const { hero, gallery, statsDensity, mediaCount } = tweaks;
  const allMedia  = Array.isArray(model.media) ? model.media : [];
  const media     = allMedia.slice(0, mediaCount);
  const heroItem  = media[0];
  const rest      = media.slice(1);
  const allStats   = Array.isArray(model.stats) ? model.stats : [];
  const stats     = statsDensity === "minimal"
    ? allStats.filter((s) =>
        ["Age", "Height", "Cup size", "Dress", "Shoe", "Hair", "Eyes",
         "Based in", "Availability", "Travel"]
          .includes(s.k))
    : allStats;

  // ── Lightbox state — keyed off the FULL media list (incl. hero) so
  // clicking the hero also opens it as item 0. ──
  const lb = useLightbox(media);

  return (
    <div ref={rootRef} style={{
      width:"100%", minHeight:"100%",
      fontFamily:"var(--font-body)",
      "--col-pad":"clamp(28px, 4vw, 64px)",
      "--max-w":"1480px",
      "--mono":'"freight-sans-pro", system-ui, -apple-system, Helvetica, Arial, sans-serif',
    }} className="cl-profile">
      {tweaks?.showLedger !== false && <ClHeaderLedger model={model}/>}

      {hero === "masthead" ? (
        <ClHeroMasthead model={model} item={heroItem} onOpen={() => lb.open(0)}/>
      ) : hero === "split" ? (
        <ClHeroSplit    model={model} item={heroItem} stats={stats} onOpen={() => lb.open(0)}/>
      ) : (
        <ClHeroOverlay  model={model} item={heroItem} onOpen={() => lb.open(0)}/>
      )}

      <ClBio model={model}/>
      <ClContactRail model={model}/>
      <ClStatsSheet stats={stats} model={model}/>
      <ClPersonality model={model}/>
      <ClGallery
        items={rest}
        layout={gallery}
        onOpen={(restIdx) => lb.open(restIdx + 1)}
      />
      <ClFooter model={model}/>

      <Lightbox
        items={media}
        idx={lb.idx}
        onClose={lb.close}
        onPrev={lb.prev}
        onNext={lb.next}
      />
    </div>
  );
}

// ─── Top ledger ────────────────────────────────────────────────────────
function ClHeaderLedger({ model }) {
  return (
    <div style={{
      display:"grid", gridTemplateColumns:"1.2fr 1fr 1fr",
      borderBottom:"1px solid var(--rule-strong)",
      fontFamily:"var(--mono)",
      fontSize: 10.5, letterSpacing:".14em", textTransform:"uppercase",
    }} className="cl-ledger">
      <ClLedgerCell>
        <ClLK>Talent</ClLK>
        <ClLV>{model.firstName} {model.lastName}</ClLV>
      </ClLedgerCell>
      <ClLedgerCell>
        <ClLK>Index</ClLK>
        <ClLV>042 / 300</ClLV>
      </ClLedgerCell>
      <ClLedgerCell right>
        <ClLK>File</ClLK>
        <ClLV>EV-42 · R 26.05</ClLV>
      </ClLedgerCell>
    </div>
  );
}
function ClLedgerCell({ children, right }) {
  return (
    <div style={{
      padding:"16px clamp(20px, 2.5vw, 32px)",
      borderLeft:"1px solid var(--rule)",
      display:"flex", alignItems:"center", gap: 12,
      justifyContent: right ? "flex-end" : "flex-start",
    }} className="cl-ledger-cell">{children}</div>
  );
}
function ClLK({ children }) { return <span style={{ color:"var(--fg-faint)" }}>{children}</span>; }
function ClLV({ children }) { return <span style={{ color:"var(--fg)", fontWeight:500 }}>{children}</span>; }

// ─── Hero: contained 4:5 portrait, name overlay (DEFAULT) ──────────────
//
// The frame is width-bounded by the viewport height, so the actual rendered
// card stays 4:5 instead of stretching wide when the page shell is short.
function ClHeroOverlay({ model, item, onOpen }) {
  // Pull a handful of vitals from the stats array so the bottom strip
  // shows real values from the registration form (no labels — the values
  // alone read as model vitals in context).
  const valueOf = (k) => model.stats.find((s) => s.k === k)?.v;
  const age     = valueOf("Age");
  const basedIn = valueOf("Based in");
  const height  = valueOf("Height");
  return (
    <section style={{
      padding:"clamp(28px, 4vw, 56px) var(--col-pad)",
      display:"flex", justifyContent:"center",
    }}>
      <div style={{ width:"100%", display:"flex", justifyContent:"center" }}>
        <div
          onClick={onOpen}
          onKeyDown={(event) => {
            if (event.key === "Enter" || event.key === " ") {
              event.preventDefault();
              onOpen();
            }
          }}
          role="button"
          tabIndex={0}
          aria-label={`Open ${model.firstName} ${model.lastName || ""} hero image`}
          className="cl-clickable cl-front-hero-card"
          style={{
            position:"relative",
            width:"min(100%, 70vh, 900px)",
            aspectRatio:"4 / 5",
            margin:"0 auto",
            overflow:"hidden",
            background:"#1a1816",
            cursor:"zoom-in",
          }}
        >
          <MediaItem item={item} crop={true} priority style={{ width:"100%", height:"100%" }}/>

          {/* Subtle bottom vignette so name + meta stay legible */}
          <div style={{
            position:"absolute", inset:0,
            background:
              "linear-gradient(180deg, rgba(0,0,0,0.16) 0%, rgba(0,0,0,0) 22%, " +
              "rgba(0,0,0,0) 48%, rgba(0,0,0,0.5) 100%)",
            pointerEvents:"none",
          }}/>

          {/* Name — lower-centre */}
          <div style={{
            position:"absolute", top:"56%", left:0, right:0,
            display:"flex", flexDirection:"column", alignItems:"center",
            color:"#f6f0e2", textAlign:"center",
            padding:"0 8%", pointerEvents:"none",
          }}>
            <div style={{
              fontFamily:"var(--font-display)",
              fontWeight:700,
              letterSpacing:"var(--name-tracking)",
              lineHeight:"var(--display-leading)",
              fontSize:"clamp(64px, 9vw, 156px)",
              textShadow:"0 2px 28px rgba(0,0,0,0.28)",
            }} className="cl-name-lockup">
              <div>{model.firstName.toUpperCase()}</div>
              <div style={{ marginTop:"-0.08em" }}>{model.lastName.toUpperCase()}</div>
            </div>
          </div>

          {/* Bottom vitals strip — age · based in · height */}
          <div style={{
            position:"absolute", bottom:0, left:0, right:0,
            padding:"22px 6%",
            display:"flex", justifyContent:"space-between", alignItems:"center",
            color:"rgba(246,240,226,0.92)",
            fontFamily:"var(--mono)",
            fontWeight:700,
            fontSize: "clamp(11px, 0.95vw, 14px)",
            letterSpacing:".18em", textTransform:"uppercase",
            textShadow:"0 2px 18px rgba(0,0,0,0.38)",
            pointerEvents:"none",
          }} className="cl-hero-vitals">
            <span>{age}</span>
            <span>{basedIn}</span>
            <span>{height}</span>
          </div>
        </div>
      </div>
    </section>
  );
}

// ─── Hero: Masthead (name big above contained image) ───────────────────
function ClHeroMasthead({ model, item, onOpen }) {
  return (
    <section style={{ padding:"clamp(48px, 6vw, 80px) var(--col-pad) 0" }}>
      <div style={{
        maxWidth:"var(--max-w)", margin:"0 auto",
        fontFamily:"var(--font-display)",
        fontWeight:"var(--display-weight)",
        letterSpacing:"var(--name-tracking)",
        lineHeight:"var(--display-leading)",
        fontSize:"clamp(96px, 14vw, 220px)",
        textAlign:"center",
      }} className="cl-name-lockup">
        <div>{model.firstName.toUpperCase()}</div>
        <div>{model.lastName.toUpperCase()}</div>
      </div>
      <div style={{
        maxWidth:"min(880px, 100%)", margin:"40px auto",
      }}>
        <div
          onClick={onOpen}
          onKeyDown={(event) => {
            if (event.key === "Enter" || event.key === " ") {
              event.preventDefault();
              onOpen();
            }
          }}
          role="button"
          tabIndex={0}
          aria-label={`Open ${model.firstName} ${model.lastName || ""} hero image`}
          className="cl-clickable"
          style={{
          aspectRatio:"4 / 5", maxHeight:"calc(100vh - 200px)",
          margin:"0 auto", overflow:"hidden", background:"#1a1816",
          cursor:"zoom-in",
        }}>
          <MediaItem item={item} crop={true} priority style={{ width:"100%", height:"100%" }}/>
        </div>
      </div>
    </section>
  );
}

// ─── Hero: Split ───────────────────────────────────────────────────────
function ClHeroSplit({ model, item, stats, onOpen }) {
  return (
    <section style={{
      display:"grid", gridTemplateColumns:"1fr 1fr",
      borderBottom:"1px solid var(--rule-strong)",
      minHeight:"min(820px, 84vh)",
    }} className="cl-split-hero">
      <div style={{
        padding:"clamp(36px, 5vw, 64px) var(--col-pad)",
        display:"flex", flexDirection:"column", justifyContent:"space-between",
        borderRight:"1px solid var(--rule)",
      }} className="cl-split-copy">
        <div>
          <div style={{
            fontFamily:"var(--mono)", fontSize:10.5, letterSpacing:".18em",
            textTransform:"uppercase", color:"var(--fg-faint)", marginBottom: 22,
          }} className="cl-name-lockup">
            File R-26.05 · 042 · {model.city}
          </div>
          <div style={{
            fontFamily:"var(--font-display)",
            fontWeight:"var(--display-weight)",
            letterSpacing:"var(--name-tracking)",
            lineHeight: 0.88,
            fontSize:"clamp(72px, 8vw, 140px)",
          }}>
            <div>{model.firstName.toUpperCase()}</div>
            <div>{model.lastName.toUpperCase()}</div>
          </div>
        </div>
        <div style={{
          marginTop: 60,
          fontFamily:"var(--mono)", fontSize:11, lineHeight:1.95, letterSpacing:".04em",
          textTransform:"uppercase",
          borderTop:"1px solid var(--rule)", paddingTop:18,
          maxWidth: 460,
        }}>
          {stats.slice(0, 8).map((s) => (
            <div key={s.k} style={{ display:"flex", justifyContent:"space-between", gap:24 }}>
              <span style={{color:"var(--fg-faint)"}}>{s.k}</span>
              <span style={{color:"var(--fg)"}}>{s.v}</span>
            </div>
          ))}
        </div>
      </div>
      <div
        onClick={onOpen}
        onKeyDown={(event) => {
          if (event.key === "Enter" || event.key === " ") {
            event.preventDefault();
            onOpen();
          }
        }}
        role="button"
        tabIndex={0}
        aria-label={`Open ${model.firstName} ${model.lastName || ""} hero image`}
        className="cl-clickable"
        style={{ height:"100%", overflow:"hidden", cursor:"zoom-in" }}
      >
        <MediaItem item={item} crop={true} priority style={{ height:"100%" }}/>
      </div>
    </section>
  );
}

// ─── Stats sheet ───────────────────────────────────────────────────────
const PHYSICAL_STATS = ["Age", "Height", "Hair", "Eyes", "Breasts", "Cup size", "Dress", "Shoe", "Marks"];
const BACKGROUND_STATS = ["Nationality", "Based in", "Languages", "Travel", "Availability"];

function statByKey(stats, key) {
  const found = stats.find((item) => String(item.k || "").toLowerCase() === key.toLowerCase());
  return found || { k: key, v: "N/A", sub: "" };
}

function ClStatsSheet({ stats, model }) {
  return (
    <section style={{
      padding:"clamp(42px, 5vw, 76px) var(--col-pad) clamp(56px, 6vw, 88px)",
      maxWidth:"var(--max-w)", margin:"0 auto",
      width:"100%",
    }}>
      <ClSectionHead num="01" label="Statistics" right="Submitted data"/>
      <div style={{
        marginTop: 28,
        gap:"clamp(20px, 3vw, 36px)",
        alignItems:"start",
      }} className="cl-stats-triad">
        <ClStatsGroup title="Physical">
          {PHYSICAL_STATS.map((key) => {
            const s = statByKey(stats, key);
            return <ClStatRow key={key} k={s.k} v={s.v} sub={s.sub}/>;
          })}
        </ClStatsGroup>
        <ClStatsGroup title="Background">
          {BACKGROUND_STATS.map((key) => {
            const s = statByKey(stats, key);
            return <ClStatRow key={key} k={s.k} v={s.v} sub={s.sub}/>;
          })}
        </ClStatsGroup>
        <ClStatsGroup title="Services & Rates">
          <ClPriceTable rows={model.prices || []} from={model.priceFrom}/>
          <ClServicesList services={model.services || []}/>
        </ClStatsGroup>
      </div>
    </section>
  );
}

function ClStatsGroup({ title, children }) {
  return (
    <article style={{
      minWidth: 0,
      borderTop:"1px solid var(--rule)",
    }}>
      <h3 style={{
        margin:"0",
        padding:"18px 0 8px",
        fontFamily:"var(--font-body)",
        fontSize:"clamp(18px, 1.35vw, 22px)",
        lineHeight:1.1,
        color:"var(--fg)",
      }}>{title}</h3>
      {children}
    </article>
  );
}

function ClStatRow({ k, v, sub }) {
  return (
    <div style={{
      display:"grid", gridTemplateColumns:"minmax(92px, 36%) 1fr",
      alignItems:"baseline",
      padding:"12px 0",
      borderBottom:"1px solid var(--rule)",
      fontFamily:"var(--mono)",
      fontSize:11, letterSpacing:".08em", textTransform:"uppercase",
      columnGap: 16,
    }} className="cl-stat-row">
      <span style={{ color:"var(--fg-faint)" }}>{k}</span>
      <span style={{ color:"var(--fg)", fontWeight:500 }}>
        {v || "N/A"}
        {sub ? <small style={{ display:"block", marginTop: 5, color:"var(--fg-soft)", fontSize:10, letterSpacing:".08em" }}>{sub}</small> : null}
      </span>
    </div>
  );
}

function ClPriceTable({ rows, from }) {
  const cleanRows = Array.isArray(rows) ? rows.filter((row) => row && (row.incall || row.outcall)) : [];
  return (
    <div style={{ marginTop: 8 }}>
      <div style={{
        display:"flex", justifyContent:"space-between", gap: 14,
        padding:"12px 0",
        borderBottom:"1px solid var(--rule)",
        fontFamily:"var(--mono)", fontSize:11, letterSpacing:".08em",
        textTransform:"uppercase", color:"var(--fg-faint)",
      }}>
        <span>Pricing Table</span>
        <span>{from || ""}</span>
      </div>
      {cleanRows.length ? (
        <table style={{
          width:"100%", borderCollapse:"collapse",
          fontFamily:"var(--mono)", fontSize:10.5, letterSpacing:".06em",
          textTransform:"uppercase",
        }}>
          <thead>
            <tr>
              <th style={{ textAlign:"left", padding:"12px 0 8px", color:"var(--fg-faint)", fontWeight:400 }}></th>
              <th style={{ textAlign:"right", padding:"12px 0 8px", color:"var(--fg-faint)", fontWeight:400 }}>Incall</th>
              <th style={{ textAlign:"right", padding:"12px 0 8px", color:"var(--fg-faint)", fontWeight:400 }}>Outcall</th>
            </tr>
          </thead>
          <tbody>
            {cleanRows.map((row) => (
              <tr key={row.key || row.label}>
                <td style={{ padding:"10px 0", borderTop:"1px solid var(--rule)", color:"var(--fg-faint)" }}>{row.label}</td>
                <td style={{ padding:"10px 0", borderTop:"1px solid var(--rule)", textAlign:"right", color:"var(--fg)" }}>{row.incall || "N/A"}</td>
                <td style={{ padding:"10px 0", borderTop:"1px solid var(--rule)", textAlign:"right", color:"var(--fg)" }}>{row.outcall || "N/A"}</td>
              </tr>
            ))}
          </tbody>
        </table>
      ) : (
        <ClStatRow k="Pricing Table" v="N/A"/>
      )}
    </div>
  );
}

function ClServicesList({ services }) {
  const items = Array.isArray(services) ? services.filter(Boolean) : [];
  const preview = items.slice(0, 9);
  const remaining = Math.max(0, items.length - preview.length);
  return (
    <div style={{ marginTop: 10 }}>
      <ClStatRow k="Extra Services" v={items.length ? `${items.length} options` : "N/A"}/>
      {items.length ? (
        <div
          aria-label="Extra services"
          style={{
            display:"grid",
            gridTemplateColumns:"repeat(2, minmax(0, 1fr))",
            gap: 6,
            paddingTop: 10,
          }}
        >
          {preview.map((service) => (
            <span
              key={service}
              title={service}
              style={{
                minWidth: 0,
                overflow: "hidden",
                textOverflow: "ellipsis",
                whiteSpace: "nowrap",
                border:"1px solid var(--rule)",
                padding:"8px 9px",
                color:"var(--fg-soft)",
                fontFamily:"var(--mono)",
                fontSize:10,
                letterSpacing:".08em",
                textTransform:"uppercase",
              }}
            >
              {service}
            </span>
          ))}
          {remaining ? (
            <span style={{
              border:"1px solid var(--rule)",
              padding:"8px 9px",
              color:"var(--fg-faint)",
              fontFamily:"var(--mono)",
              fontSize:10,
              letterSpacing:".08em",
              textTransform:"uppercase",
            }}>+ {remaining} more</span>
          ) : null}
        </div>
      ) : null}
    </div>
  );
}

// ─── Section head ──────────────────────────────────────────────────────
function ClSectionHead({ num, label, right }) {
  return (
    <div style={{
      display:"flex", alignItems:"baseline", justifyContent:"space-between",
      borderTop:"1px solid var(--rule-strong)", paddingTop: 20, gap: 24,
    }} className="cl-section-head">
      <div style={{ display:"flex", alignItems:"baseline", gap: 18 }}>
        <span style={{
          fontFamily:"var(--mono)", fontSize:10.5, letterSpacing:".18em",
          color:"var(--fg-faint)", textTransform:"uppercase",
        }}>— {num}</span>
        <span style={{
          fontFamily:"var(--font-display)", fontWeight:"var(--display-weight)",
          fontSize:"clamp(28px, 3vw, 40px)", letterSpacing:"-0.02em", lineHeight:1,
        }}>{label}</span>
      </div>
      {right && (
        <span style={{
          fontFamily:"var(--mono)", fontSize:10.5, letterSpacing:".18em",
          color:"var(--fg-faint)", textTransform:"uppercase", textAlign:"right",
        }}>{right}</span>
      )}
    </div>
  );
}

// ─── Bio ──────────────────────────────────────────────────────────────
function ClBio({ model }) {
  return (
    <section style={{
      padding:"clamp(28px, 4vw, 52px) var(--col-pad) 0",
      maxWidth:"var(--max-w)", margin:"0 auto", width:"100%",
    }}>
      <div style={{
        maxWidth: 840, marginInline:"auto",
        borderTop:"1px solid var(--rule-strong)",
        borderBottom:"1px solid var(--rule)",
        padding:"clamp(24px, 4vw, 46px) 0",
      }}>
        <div style={{
          marginBottom: 18,
          fontFamily:"var(--mono)", fontSize:10.5, letterSpacing:".18em",
          textTransform:"uppercase", color:"var(--fg-faint)", textAlign:"center",
        }}>Biography</div>
        <div style={{
        fontFamily:"var(--font-display)",
        fontSize:"clamp(20px, 2vw, 27px)",
        lineHeight: 1.42,
        letterSpacing:"0",
        textWrap:"pretty",
        textAlign:"center",
        color:"var(--fg)",
      }}>
        <ClProse text={model.bio}/>
      </div>
      <div style={{
          marginTop: 22, textAlign:"center",
          fontFamily:"var(--mono)", fontSize:10, letterSpacing:".18em",
        textTransform:"uppercase", color:"var(--fg-faint)",
      }}>
        — {model.firstName} {model.lastName}
      </div>
      </div>
    </section>
  );
}

function ClContactRail({ model }) {
  const contact = model.contact || {};
  const phone = contact.phoneCompact || "447919787899";
  const email = contact.email || "info@elara-intl.com";
  const telegram = contact.telegramUrl || "https://t.me/elaralondon";
  const message = `Hello Elara, I would like to ask about ${model.firstName}.`;
  const subject = `Elara enquiry: ${model.firstName}`;
  const links = [
    { label:"WhatsApp", href:`https://wa.me/${phone}?text=${encodeURIComponent(message)}` },
    { label:"Telegram", href:telegram },
    { label:"Email", href:`mailto:${email}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(message)}` },
  ];
  return (
    <nav aria-label={`Contact Elara about ${model.firstName}`} style={{
      padding:"clamp(18px, 3vw, 30px) var(--col-pad) 0",
      maxWidth:"var(--max-w)", margin:"0 auto", width:"100%",
    }}>
      <div className="cl-contact-rail" style={{
        gap: 10,
        maxWidth: 840,
        marginInline:"auto",
      }}>
        {links.map((link) => (
          <a
            key={link.label}
            className="cl-contact-link"
            href={link.href}
            target="_blank"
            rel="noreferrer"
            style={{
              minHeight: 46,
              display:"inline-flex",
              alignItems:"center",
              justifyContent:"center",
              border:"1px solid var(--rule-strong)",
              color:"var(--fg)",
              textDecoration:"none",
              fontFamily:"var(--mono)",
              fontSize:10.5,
              letterSpacing:".16em",
              textTransform:"uppercase",
              background:"rgba(241,236,221,0.025)",
            }}
          >
            {link.label}
          </a>
        ))}
      </div>
    </nav>
  );
}

// ─── Personality (free text from registration form) ────────────────────
// Visually distinct from Bio: italic, narrower column, smaller scale —
// reads as a personal note rather than the professional artist statement.
function ClPersonality({ model }) {
  if (!model.personality) return null;
  return (
    <section style={{
      padding:"0 var(--col-pad) clamp(56px, 6vw, 96px)",
      maxWidth:"var(--max-w)", margin:"0 auto", width:"100%",
    }}>
      <ClSectionHead num="03" label="Personality" right="In her own words"/>
      <div style={{
        marginTop: 48,
        maxWidth: 620, marginInline:"auto",
        fontFamily:"var(--font-display)",
        fontStyle:"italic",
        fontSize:"clamp(18px, 1.7vw, 24px)",
        lineHeight: 1.55,
        letterSpacing:"-0.005em",
        textWrap:"pretty",
        textAlign:"center",
        color:"var(--fg-soft)",
      }}>
        <ClProse text={model.personality} quote/>
      </div>
    </section>
  );
}

// ─── Gallery ───────────────────────────────────────────────────────────
function ClGallery({ items, layout, onOpen }) {
  const videoCount = items.filter((it) => it.kind === "video").length;
  const right = videoCount
    ? `${items.length} works · ${videoCount} ${videoCount === 1 ? "film" : "films"}`
    : `${items.length} works`;

  return (
    <section style={{
      padding:"0 var(--col-pad) clamp(56px, 6vw, 96px)",
      maxWidth:"var(--max-w)", margin:"0 auto", width:"100%",
    }}>
      <ClSectionHead num="04" label="Portfolio" right={right}/>
      <div style={{ marginTop: 36 }}>
        {!items.length ? <ClEmptyPortfolio/> :
         layout === "grid"      ? <ClGridStrict items={items} onOpen={onOpen}/> :
         layout === "cinematic" ? <ClCinematic items={items} onOpen={onOpen}/>  :
                                  <ClJustified items={items} onOpen={onOpen}/>}
      </div>
    </section>
  );
}

function ClEmptyPortfolio() {
  return (
    <div className="cl-empty">
      <span style={{
        fontFamily:"var(--mono)",
        fontSize: 10.5,
        letterSpacing: ".18em",
        textTransform: "uppercase",
        color: "var(--fg-faint)",
      }}>
        Gallery pending review
      </span>
    </div>
  );
}

function ClJustified({ items, onOpen }) {
  const ref = React.useRef(null);
  const width = useElementWidth(ref);
  const target = items.length <= 4 ? 620
              :  items.length <= 7 ? 520
              :  items.length <= 11 ? 440 : 380;
  const gap = 8;
  // Tag each item with its index so it survives justifyRows's spread-clones
  // — the lightbox needs the rest-index back when a tile is clicked.
  const tagged = React.useMemo(
    () => items.map((it, idx) => ({ ...it, _idx: idx })),
    [items],
  );
  const rows = width > 0 ? justifyRows(tagged, width, target, gap, 1.4) : [];

  return (
    <div ref={ref} style={{ display:"flex", flexDirection:"column", gap }}>
      {rows.map((row, ri) => (
        <div key={ri} style={{ display:"flex", gap, width:"100%" }} className="cl-gallery-row">
          {row.items.map((it) => (
            <GalleryFig
              key={it.i}
              item={it}
              w={it._w} h={it._h}
              onOpen={() => onOpen(it._idx)}
            />
          ))}
        </div>
      ))}
    </div>
  );
}

function ClGridStrict({ items, onOpen }) {
  return (
    <div style={{ display:"grid", gridTemplateColumns:"repeat(3, 1fr)", gap: 8 }} className="cl-grid-strict">
      {items.map((it, idx) => (
        <GalleryFig
          key={it.i}
          item={it}
          aspect="3 / 4"
          crop
          onOpen={() => onOpen(idx)}
        />
      ))}
    </div>
  );
}

function ClCinematic({ items, onOpen }) {
  return (
    <div style={{ display:"flex", flexDirection:"column", gap: 12 }}>
      {items.map((it, idx) => (
        <GalleryFig
          key={it.i}
          item={it}
          full
          onOpen={() => onOpen(idx)}
        />
      ))}
    </div>
  );
}

// One figure. Either justified ({w, h}), strict grid (aspect + crop), or
// cinematic (full = full width, natural aspect).
function GalleryFig({ item, w, h, aspect, crop, full, onOpen }) {
  const styleProps = full
    ? { width:"100%" }
    : aspect
      ? { aspectRatio: aspect }
      : { width: w, height: h, flex: `0 0 ${w}px` };

  return (
    <figure
      onClick={onOpen}
      onKeyDown={(event) => {
        if (event.key === "Enter" || event.key === " ") {
          event.preventDefault();
          onOpen();
        }
      }}
      role="button"
      tabIndex={0}
      aria-label={`Open portfolio image ${String(item.i).padStart(2, "0")}`}
      className="cl-clickable"
      style={{
        margin:0, position:"relative", overflow:"hidden",
        background:"#1a1816", cursor:"zoom-in",
        ...styleProps,
      }}
    >
      <MediaItem item={item} crop={!!crop} style={{ width:"100%", height: crop || full ? (crop ? "100%" : "auto") : "100%" }}/>
      <ClImageNumber n={item.i}/>
    </figure>
  );
}

// Number-only caption — top-right corner, faint mono pill.
function ClImageNumber({ n }) {
  return (
    <div style={{
      position:"absolute", top:10, right:12,
      color:"rgba(246,240,226,0.86)",
      fontFamily:"var(--mono)",
      fontSize: 10, letterSpacing:".18em", textTransform:"uppercase",
      padding:"3px 8px", borderRadius: 999,
      background:"rgba(10,10,10,0.32)",
      backdropFilter:"blur(4px)",
      WebkitBackdropFilter:"blur(4px)",
      pointerEvents:"none",
    }}>
      {String(n).padStart(2, "0")}
    </div>
  );
}

// ─── Footer — just the credit line ─────────────────────────────────────
function ClFooter({ model }) {
  return (
    <footer style={{
      padding:"clamp(36px, 4vw, 56px) var(--col-pad)",
      background:"var(--bg-deep)",
      borderTop:"1px solid var(--rule-strong)",
    }} className="cl-footer">
      <div style={{
        maxWidth:"var(--max-w)", margin:"0 auto",
        display:"grid", gridTemplateColumns:"repeat(3, auto)", justifyContent:"space-between", alignItems:"center", gap: 18,
        fontFamily:"var(--mono)", fontSize:10.5, letterSpacing:".18em",
        textTransform:"uppercase", color:"var(--fg-faint)",
      }} className="cl-footer-grid">
        <span>© {model.agency} 2026</span>
        <span>File R-26.05</span>
        <span>{model.firstName} {model.lastName}</span>
      </div>
    </footer>
  );
}

Object.assign(window, { ProfileClinical });
