// J Renee Studios — Journal page (blog index) sections + posts data

// ---------- GO HIGH LEVEL (GHL) NEWSLETTER CONNECTION ----------
// Paste your GoHighLevel Inbound Webhook URL between the quotes below.
// How to get it in GHL:
//   1. Automation → Workflows → Create Workflow (blank).
//   2. Add Trigger → "Inbound Webhook" → copy the webhook URL it generates.
//   3. Add Action → "Create/Update Contact" (map the {{email}} field), then add
//      the contact to your newsletter list / tag (e.g. "Journal Subscriber").
//   4. Publish the workflow, then paste the copied URL here.
// The subscribe form below will POST { email, source } to this URL. The URL is
// not a secret, so it's safe to keep here in the static site.
const J_GHL_WEBHOOK_URL = "";

// ---------- POSTS DATA ----------
// Each post: slug, title, excerpt, category, city ("Las Vegas" | "Boise" | "General"),
// date, image, featured (boolean — exactly one).
const J_POSTS = [
  {
    slug: "what-to-wear-las-vegas-boudoir-shoot",
    title: "What to Wear to a Las Vegas Boudoir Shoot",
    excerpt: "Bring five to eight fitted pieces you love — and let the studio closet and the posing do the rest. The fitted-not-flowy rule, the bring-three plan, and what's already waiting on the rack.",
    category: "Prep Guides",
    city: "Las Vegas",
    date: "June 5, 2026",
    image: "/images/what-to-wear-boudoir-hero.jpg",
    href: "/las-vegas/boudoir/",
    featured: true,
  },
  {
    slug: "boise-maternity-session-prep",
    title: "How to Prepare for a Boise Modern Maternity Session",
    excerpt: "From skincare in the final weeks to the pieces in your closet that will actually photograph beautifully — a quiet, considered prep guide.",
    category: "Prep Guides",
    city: "Boise",
    date: "April 9, 2026",
    image: "/images/vm-gallery-10.jpg",
    href: "/boise/maternity/",
  },
  {
    slug: "iconic-experience-women-over-40-las-vegas",
    title: "Why I Built The Iconic Experience for Women Over 40",
    excerpt: "Most women over 40 have almost no beautiful photos of themselves. Here's why I built The Iconic Experience in Las Vegas — and what volume one looks like.",
    category: "ICONIC Experience 40+",
    city: "Las Vegas",
    date: "June 5, 2026",
    image: "/images/ic-gallery-05.jpg",
    href: "/las-vegas/iconic/",
  },
  {
    slug: "modern-headshots-vegas-what-to-bring",
    title: "Modern Headshots in Las Vegas: What to Bring on the Day.",
    excerpt: "Three looks, two pairs of shoes, one consistent palette — the short list that gets you a finished gallery you'll actually use.",
    category: "Modern Headshots & Branding",
    city: "Las Vegas",
    date: "March 14, 2026",
    image: "/images/vh-gallery-02.jpg",
    href: "/las-vegas/headshots/",
  },
  {
    slug: "boise-portraits-quiet-confidence",
    title: "Quiet Confidence: A Boise Modern Portraits Session.",
    excerpt: "A walk-through of one recent Modern Portraits session — what we shot, why we kept it tight, and the single image she chose to print.",
    category: "Modern Portraits",
    city: "Boise",
    date: "February 28, 2026",
    image: "/images/boise-portraits.jpg",
    href: "/boise/portraits/",
  },
  {
    slug: "boudoir-session-cost-las-vegas",
    title: "How Much Does a Boudoir Session Cost in Las Vegas?",
    excerpt: "A real answer to what a boudoir session costs in Las Vegas — the $490 session fee, what it covers, the range most women invest, and why it's built that way.",
    category: "Modern Boudoir",
    city: "Las Vegas",
    date: "June 5, 2026",
    image: "/images/vb-gallery-01.jpg",
    href: "/las-vegas/boudoir/",
  },
  {
    slug: "iconic-collection-decision",
    title: "Choosing Your ICONIC Heirloom Album.",
    excerpt: "Linen folio, leather album, or framed wall portrait — how clients decide between the heirloom collections, and why most choose the album.",
    category: "ICONIC Experience 40+",
    city: "Las Vegas",
    date: "January 24, 2026",
    image: "/images/ic-heirloom-02.jpg",
    href: "/las-vegas/iconic/",
  },
  {
    slug: "behind-the-camera-jennifer",
    title: "Behind the Camera: Twenty Years, One Subject.",
    excerpt: "A founder's note on what's changed, what hasn't, and why the studio still photographs only women — across both Boise and Las Vegas.",
    category: "Behind the Brand",
    city: "General",
    date: "January 8, 2026",
    image: "/images/about-jenn-hero.jpg",
    href: "/about/",
  },
  {
    slug: "modern-headshots-boise",
    title: "Where to Use Modern Headshots in Boise (Beyond LinkedIn)",
    excerpt: "Modern headshots aren't just for LinkedIn — your website, real estate signage, podcast spots, speaker bios, and press. Plus why they're a write-off and what a session really looks like.",
    category: "Modern Headshots & Branding",
    city: "Boise",
    date: "June 5, 2026",
    image: "/images/boise-headshots.jpg",
    href: "/specials/boise-headshot-day/",
  },
  {
    slug: "vegas-maternity-couples",
    title: "Why Partners Belong in the Maternity Frame.",
    excerpt: "Editorial maternity isn't only solo. A short note on the family-moment portraits the Las Vegas studio quietly builds in.",
    category: "Modern Maternity",
    city: "Las Vegas",
    date: "December 4, 2025",
    image: "/images/vegas-maternity.jpg",
    href: "/las-vegas/maternity/",
  },
  {
    slug: "what-to-bring-portrait",
    title: "Three Things to Bring to a Modern Portraits Session.",
    excerpt: "A short, honest packing list — including the one item nearly every client forgets — for both Boise and Las Vegas studio sessions.",
    category: "Prep Guides",
    city: "General",
    date: "November 17, 2025",
    image: "/images/portraits.jpg",
    href: "/boise/portraits/",
  },
  {
    slug: "iconic-day-of",
    title: "The Day of an ICONIC Experience, Hour by Hour.",
    excerpt: "Hair and makeup at ten, three editorial looks by two, the full reveal before you leave — a walk through the day.",
    category: "ICONIC Experience 40+",
    city: "Las Vegas",
    date: "October 30, 2025",
    image: "/images/ic-celebration.jpg",
    href: "/las-vegas/iconic/",
  },
  {
    slug: "first-boudoir-session-boise",
    title: "What to Expect at Your First Boudoir Session in Boise",
    excerpt: "Nervous about your first session? Here's exactly what the day feels like — from the makeup chair to the moment you see yourself and say \"that's me?\"",
    category: "Modern Boudoir",
    city: "Boise",
    date: "June 5, 2026",
    image: "/images/boudoir-12.jpg",
    href: "/boise/boudoir/",
  },
  {
    slug: "studio-tour-vegas",
    title: "A Quiet Tour of the Las Vegas Studio.",
    excerpt: "Natural light from the south windows, three painted walls, one ten-foot cyc — a short tour of the room the work is made in.",
    category: "Behind the Brand",
    city: "Las Vegas",
    date: "September 28, 2025",
    image: "/images/vegas-studio.jpg",
    href: "/las-vegas/",
  },
  {
    slug: "modern-portraits-vegas-essay",
    title: "Modern Portraits in Las Vegas: A Different Brief.",
    excerpt: "Not a glam session, not a branding shoot — what Modern Portraits actually is, and the women it's built for.",
    category: "Modern Portraits",
    city: "Las Vegas",
    date: "September 9, 2025",
    image: "/images/vegas-portraits.jpg",
    href: "/las-vegas/portraits/",
  },
];

const J_CATEGORIES = [
  "All",
  "Modern Boudoir",
  "Modern Headshots & Branding",
  "Modern Portraits",
  "Modern Maternity",
  "ICONIC Experience 40+",
  "Behind the Brand",
  "Prep Guides",
];
const J_CITIES = ["All", "Las Vegas", "Boise"];

// A post links to its real article page (/journal/<slug>/) once it has been
// written (i.e. content exists in window.J_POST_CONTENT). Until then it keeps
// linking to its related service page so no card ever lands on an empty page.
function jPostHref(post) {
  const written = (typeof window !== "undefined" && window.J_POST_CONTENT) || {};
  return written[post.slug] ? `/journal/${post.slug}/` : post.href;
}

// ---------- 1. HERO ----------
function JHero() {
  return (
    <section data-screen-label="01 Journal Hero" style={{
      background: J_WHITE, padding: "140px 48px 120px",
      borderBottom: `1px solid ${J_BEIGE}`,
    }}>
      <div style={{ maxWidth: 1100, margin: "0 auto", textAlign: "center" }}>
        <div style={{ display: "inline-flex", alignItems: "center", gap: 16, marginBottom: 36 }}>
          <JGoldRule width={48} />
          <JEyebrow>Journal</JEyebrow>
          <JGoldRule width={48} />
        </div>
        <h1 style={{
          fontFamily: "Gloock, serif", fontWeight: 400, color: J_INK,
          fontSize: "clamp(56px, 9vw, 148px)", lineHeight: 0.98,
          letterSpacing: "-0.01em", margin: "0 0 44px 0", textWrap: "balance",
        }}>
          The <em style={{ fontStyle: "italic", color: J_GOLD }}>Journal</em>.
        </h1>
        <p style={{
          fontFamily: "Poppins, sans-serif", fontWeight: 300,
          fontSize: "clamp(17px, 1.4vw, 19px)", lineHeight: 1.7,
          color: "#3a3530", maxWidth: 680, margin: "0 auto", textWrap: "pretty",
        }}>
          Thoughts on women's portraiture, prep guides for sessions, and stories from behind the camera — written from the studios in Boise and Las Vegas.
        </p>
      </div>
    </section>
  );
}

// ---------- 2. FEATURED POST ----------
function JFeatured({ post }) {
  if (!post) return null;
  return (
    <section data-screen-label="02 Featured Post" style={{ background: J_WHITE, padding: "140px 48px" }}>
      <div style={{ maxWidth: 1320, margin: "0 auto" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 16, marginBottom: 56 }}>
          <JEyebrow>Featured</JEyebrow>
          <JGoldRule width={56} />
        </div>
        <a href={jPostHref(post)} className="j-featured-card" style={{
          display: "grid", gridTemplateColumns: "1.15fr 1fr",
          gap: 80, alignItems: "center", textDecoration: "none", color: "inherit",
        }}>
          <div style={{
            aspectRatio: "5 / 6",
            border: `1px solid ${J_GOLD}`,
            background: J_BEIGE, overflow: "hidden",
          }}>
            <img
              src={post.image}
              alt={`${post.category} — ${post.title} | J. Renée Studios ${post.city !== "General" ? post.city : ""}`}
              style={{ display: "block", width: "100%", height: "100%", objectFit: "cover" }}
            />
          </div>
          <div>
            <div style={{ display: "flex", alignItems: "center", gap: 22, marginBottom: 28, flexWrap: "wrap" }}>
              <span style={{
                fontFamily: "Poppins, sans-serif", fontWeight: 300, fontSize: 10.5,
                letterSpacing: "0.32em", textTransform: "uppercase", color: J_GOLD,
              }}>{post.category}</span>
              <span style={{ width: 4, height: 4, background: J_GREY_SOFT, borderRadius: "50%" }} />
              <span style={{
                fontFamily: "Poppins, sans-serif", fontWeight: 300, fontSize: 10.5,
                letterSpacing: "0.32em", textTransform: "uppercase", color: J_GREY,
              }}>{post.city}</span>
            </div>
            <h2 style={{
              fontFamily: "Gloock, serif", fontWeight: 400, color: J_INK,
              fontSize: "clamp(32px, 3.6vw, 52px)", lineHeight: 1.1,
              letterSpacing: "-0.005em", margin: "0 0 28px 0", textWrap: "balance",
            }}>{post.title}</h2>
            <p style={{
              fontFamily: "Poppins, sans-serif", fontWeight: 300, fontSize: 17,
              lineHeight: 1.7, color: "#3a3530", margin: "0 0 40px 0", maxWidth: 520, textWrap: "pretty",
            }}>{post.excerpt}</p>
            <div style={{
              fontFamily: "Poppins, sans-serif", fontWeight: 300, fontSize: 11,
              fontStyle: "italic", color: J_GREY, marginBottom: 36,
            }}>{post.date}</div>
            <span style={{
              display: "inline-flex", alignItems: "center", gap: 14,
              fontFamily: "Poppins, sans-serif", fontWeight: 300, fontSize: 11,
              letterSpacing: "0.36em", textTransform: "uppercase",
              color: J_GOLD, paddingBottom: 6, borderBottom: `1px solid ${J_GOLD}`,
            }}>Read the post <span aria-hidden>→</span></span>
          </div>
        </a>
      </div>
    </section>
  );
}

// ---------- 3. FILTER BAR ----------
function JFilterBar({ category, city, setCategory, setCity }) {
  const Row = ({ label, options, active, onPick }) => (
    <div style={{ display: "flex", alignItems: "baseline", gap: 28, flexWrap: "wrap" }}>
      <span style={{
        fontFamily: "Poppins, sans-serif", fontWeight: 300, fontSize: 10,
        letterSpacing: "0.36em", textTransform: "uppercase", color: J_GREY,
        minWidth: 80,
      }}>{label}</span>
      <div style={{ display: "flex", gap: 6, flexWrap: "wrap", rowGap: 14 }}>
        {options.map(opt => {
          const isActive = active === opt;
          return (
            <button
              key={opt}
              onClick={() => onPick(opt)}
              style={{
                appearance: "none", background: "transparent",
                border: "none", padding: "8px 14px", cursor: "pointer",
                fontFamily: "Poppins, sans-serif", fontWeight: 300, fontSize: 11,
                letterSpacing: "0.32em", textTransform: "uppercase",
                color: isActive ? J_INK : "#5a5550",
                borderBottom: `1px solid ${isActive ? J_GOLD : "transparent"}`,
                transition: "color 200ms ease, border-color 200ms ease",
              }}
              onMouseEnter={(e) => { if (!isActive) e.currentTarget.style.color = J_INK; }}
              onMouseLeave={(e) => { if (!isActive) e.currentTarget.style.color = "#5a5550"; }}
            >{opt}</button>
          );
        })}
      </div>
    </div>
  );
  return (
    <section data-screen-label="03 Filter Bar" style={{
      background: J_BEIGE, padding: "56px 48px",
      borderTop: `1px solid rgba(26,26,26,0.06)`,
      borderBottom: `1px solid rgba(26,26,26,0.06)`,
    }}>
      <div style={{ maxWidth: 1320, margin: "0 auto", display: "grid", gap: 24 }}>
        <Row label="Category" options={J_CATEGORIES} active={category} onPick={setCategory} />
        <Row label="City"     options={J_CITIES}      active={city}     onPick={setCity} />
      </div>
    </section>
  );
}

// ---------- 4. POST GRID ----------
function JPostCard({ post }) {
  const [hover, setHover] = jUseState(false);
  return (
    <a
      href={jPostHref(post)}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{ textDecoration: "none", color: "inherit", display: "block" }}
    >
      <div style={{
        aspectRatio: "4 / 5",
        border: `1px solid ${J_GOLD}`,
        background: J_BEIGE, overflow: "hidden", marginBottom: 26,
      }}>
        <img
          src={post.image}
          alt={`${post.category} — ${post.title} | J. Renée Studios${post.city !== "General" ? " " + post.city : ""}`}
          style={{
            display: "block", width: "100%", height: "100%",
            objectFit: "cover",
            transform: hover ? "scale(1.04)" : "scale(1)",
            transition: "transform 700ms cubic-bezier(.2,.8,.2,1)",
          }}
        />
      </div>
      <div style={{ display: "flex", alignItems: "center", gap: 14, marginBottom: 16, flexWrap: "wrap" }}>
        <span style={{
          fontFamily: "Poppins, sans-serif", fontWeight: 300, fontSize: 9.5,
          letterSpacing: "0.32em", textTransform: "uppercase", color: J_GOLD,
        }}>{post.category}</span>
        <span style={{ width: 3, height: 3, background: J_GREY_SOFT, borderRadius: "50%" }} />
        <span style={{
          fontFamily: "Poppins, sans-serif", fontWeight: 300, fontSize: 9.5,
          letterSpacing: "0.32em", textTransform: "uppercase", color: J_GREY,
        }}>{post.city}</span>
      </div>
      <h3 style={{
        fontFamily: "Gloock, serif", fontWeight: 400, color: J_INK,
        fontSize: "clamp(22px, 1.7vw, 26px)", lineHeight: 1.18,
        letterSpacing: "-0.005em", margin: "0 0 14px 0", textWrap: "balance",
      }}>{post.title}</h3>
      <p style={{
        fontFamily: "Poppins, sans-serif", fontWeight: 300, fontSize: 14,
        lineHeight: 1.65, color: "#3a3530", margin: "0 0 20px 0", textWrap: "pretty",
      }}>{post.excerpt}</p>
      <div style={{
        fontFamily: "Poppins, sans-serif", fontWeight: 300, fontSize: 11,
        fontStyle: "italic", color: J_GREY,
      }}>{post.date}</div>
    </a>
  );
}

function JPostGrid({ posts, visible, onLoadMore }) {
  const shown = posts.slice(0, visible);
  const hasMore = visible < posts.length;
  return (
    <section data-screen-label="04 Post Grid" style={{ background: J_WHITE, padding: "120px 48px" }}>
      <div style={{ maxWidth: 1320, margin: "0 auto" }}>
        {shown.length === 0 ? (
          <div style={{
            padding: "80px 0", textAlign: "center",
            fontFamily: "Poppins, sans-serif", fontWeight: 300, fontSize: 15, fontStyle: "italic",
            color: J_GREY,
          }}>
            No posts match this filter — try a different category or city.
          </div>
        ) : (
          <div className="j-grid-3" style={{
            display: "grid", gridTemplateColumns: "repeat(3, 1fr)",
            gap: "72px 48px",
          }}>
            {shown.map(p => <JPostCard key={p.slug} post={p} />)}
          </div>
        )}

        {/* 5. LOAD MORE */}
        {hasMore && (
          <div style={{ textAlign: "center", marginTop: 96 }}>
            <JBtn variant="outline-ink" onClick={onLoadMore}>
              Load more posts <span aria-hidden>↓</span>
            </JBtn>
            <div style={{
              marginTop: 22,
              fontFamily: "Poppins, sans-serif", fontWeight: 300, fontSize: 11,
              fontStyle: "italic", color: J_GREY,
            }}>
              Showing {shown.length} of {posts.length}
            </div>
          </div>
        )}
      </div>
    </section>
  );
}

// ---------- 6. SUBSCRIBE ----------
function JSubscribe() {
  const [email, setEmail] = jUseState("");
  const [submitted, setSubmitted] = jUseState(false);
  const [error, setError] = jUseState("");
  const [sending, setSending] = jUseState(false);
  const onSubmit = async (e) => {
    e.preventDefault();
    if (!email || sending) return;
    setError("");
    // No webhook configured yet — confirm visually so the form still works in preview.
    if (!J_GHL_WEBHOOK_URL) {
      setSubmitted(true);
      return;
    }
    setSending(true);
    try {
      await fetch(J_GHL_WEBHOOK_URL, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email, source: "Journal subscribe form" }),
      });
      setSubmitted(true);
    } catch (err) {
      setError("Something went wrong. Please try again in a moment.");
    } finally {
      setSending(false);
    }
  };
  return (
    <section data-screen-label="06 Subscribe" style={{ background: J_BEIGE, padding: "160px 48px" }}>
      <div style={{ maxWidth: 760, margin: "0 auto", textAlign: "center" }}>
        <div style={{ display: "inline-flex", alignItems: "center", gap: 16, marginBottom: 28 }}>
          <JGoldRule width={36} />
          <JEyebrow>Subscribe</JEyebrow>
          <JGoldRule width={36} />
        </div>
        <h2 style={{
          fontFamily: "Gloock, serif", fontWeight: 400, color: J_INK,
          fontSize: "clamp(34px, 4.4vw, 56px)", lineHeight: 1.1,
          letterSpacing: "-0.005em", margin: "0 0 22px 0", textWrap: "balance",
        }}>
          New posts in your <em style={{ fontStyle: "italic", color: J_GOLD }}>inbox</em>.
        </h2>
        <p style={{
          fontFamily: "Poppins, sans-serif", fontWeight: 300, fontSize: 15,
          lineHeight: 1.75, color: "#3a3530", margin: "0 auto 48px",
          maxWidth: 540, textWrap: "pretty",
        }}>
          Get new journal posts delivered when they're published. No spam — just stories, prep guides, and thoughts on women's portraiture.
        </p>

        {submitted ? (
          <div style={{
            fontFamily: "Poppins, sans-serif", fontWeight: 300, fontSize: 14,
            fontStyle: "italic", color: J_INK, padding: "22px 0",
          }}>
            Thank you — you're on the list. A confirmation is on its way to {email}.
          </div>
        ) : (
          <form onSubmit={onSubmit} className="j-subscribe-form" style={{
            display: "grid", gridTemplateColumns: "1fr auto", gap: 0,
            maxWidth: 560, margin: "0 auto",
            border: `1px solid ${J_INK}`, background: J_WHITE,
          }}>
            <input
              type="email"
              required
              value={email}
              onChange={(e) => setEmail(e.target.value)}
              placeholder="your@email.com"
              aria-label="Email address"
              style={{
                appearance: "none", border: "none", outline: "none",
                background: "transparent", padding: "20px 24px",
                fontFamily: "Poppins, sans-serif", fontWeight: 300, fontSize: 14,
                color: J_INK, letterSpacing: "0.02em",
              }}
            />
            <button type="submit" disabled={sending} style={{
              appearance: "none", border: "none", cursor: sending ? "default" : "pointer",
              background: J_INK, color: J_WHITE,
              padding: "0 36px",
              fontFamily: "Poppins, sans-serif", fontWeight: 300, fontSize: 11,
              letterSpacing: "0.36em", textTransform: "uppercase",
              transition: "background-color 220ms ease", opacity: sending ? 0.7 : 1,
            }}
              onMouseEnter={(e) => { if (!sending) e.currentTarget.style.background = J_GOLD; }}
              onMouseLeave={(e) => e.currentTarget.style.background = J_INK}
            >{sending ? "Sending…" : "Subscribe"}</button>
          </form>
        )}

        {error ? (
          <div style={{
            marginTop: 18, fontFamily: "Poppins, sans-serif", fontWeight: 300,
            fontSize: 13, fontStyle: "italic", color: "#a3402f",
          }}>
            {error}
          </div>
        ) : null}

        <div style={{
          marginTop: 28,
          fontFamily: "Poppins, sans-serif", fontStyle: "italic", fontWeight: 300,
          fontSize: 11, color: J_GREY,
        }}>
          No spam, unsubscribe anytime.
        </div>
      </div>
    </section>
  );
}

// ---------- 7. FINAL CTA ----------
function JFinalCTA() {
  return (
    <section data-screen-label="07 Final CTA" style={{ background: J_WHITE, padding: "180px 48px" }}>
      <div style={{ maxWidth: 760, margin: "0 auto", textAlign: "center" }}>
        <div style={{ display: "inline-flex", alignItems: "center", gap: 16, marginBottom: 36 }}>
          <JGoldRule width={36} />
          <JEyebrow>Inquire</JEyebrow>
          <JGoldRule width={36} />
        </div>
        <h2 style={{
          fontFamily: "Gloock, serif", fontWeight: 400, color: J_INK,
          fontSize: "clamp(32px, 3.8vw, 48px)", lineHeight: 1.15,
          letterSpacing: "-0.005em", margin: "0 0 26px 0", textWrap: "balance",
        }}>
          Have a session question?
        </h2>
        <p style={{
          fontFamily: "Poppins, sans-serif", fontWeight: 300, fontSize: 16,
          lineHeight: 1.7, color: "#3a3530", margin: "0 auto 48px", maxWidth: 520,
        }}>
          Reach out — every inquiry comes to me directly.
        </p>
        <JBtn variant="gold" href="/inquire/">Inquire <span aria-hidden>→</span></JBtn>
      </div>
    </section>
  );
}

Object.assign(window, {
  J_POSTS, J_CATEGORIES, J_CITIES,
  JHero, JFeatured, JFilterBar, JPostCard, JPostGrid, JSubscribe, JFinalCTA,
});
