/* global React */
// Five approaches to the collection-hierarchy navigation problem.
// Same archive — "Coastal Adaptation Photographs / Field Studies / Rotterdam" —
// shown in a SEARCH-RESULTS state where facets must also be reachable.
// The question being answered in each artboard: "where do facets live when
// the tree is also on screen?"

const { useState } = React;

/* ── shared tokens ── */
const T = {
  paper: "#f3eee2",
  paper2: "#e6dfc9",   // outer / gutter
  surface: "#fbf8ef",
  ink: "#1c1814",
  ink2: "#3a342c",
  muted: "#6c655a",
  hairline: "#d8cfba",
  hairline2: "#c5b99c",
  accent: "#6a1f23",
  accentInk: "#fbf8ef",
  accentSoft: "#f0d8d4",
  good: "#2f5a3a",
  warn: "#8a4a1f",
  serif: '"Newsreader", Georgia, serif',
  sans: '"Geist", ui-sans-serif, system-ui, sans-serif',
  mono: '"Geist Mono", ui-monospace, Menlo, monospace',
};

const ART_W = 1440;
const ART_H = 900;
const GUTTER = 96;       // whitespace each side
const CARD_W = ART_W - GUTTER * 2;  // = 1248

/* ── atoms ── */
const SmallCaps = ({ children, style }) => (
  <span style={{
    fontFamily: T.sans, fontSize: 10, letterSpacing: "0.14em",
    textTransform: "uppercase", fontWeight: 600, color: T.muted, ...style,
  }}>{children}</span>
);

const Chevron = ({ open, size = 11 }) => (
  <svg viewBox="0 0 24 24" width={size} height={size} fill="none"
    stroke="currentColor" strokeWidth="2"
    style={{ transform: open ? "rotate(0)" : "rotate(-90deg)", transition: "transform .15s" }}>
    <path d="M6 9l6 6 6-6" />
  </svg>
);

const Folder = ({ size = 13 }) => (
  <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke="currentColor" strokeWidth="1.4">
    <path d="M3 7h6l2 2h10v10H3z" />
  </svg>
);

const FilterIcon = ({ size = 14 }) => (
  <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke="currentColor" strokeWidth="1.4">
    <path d="M4 5h16l-6 8v6l-4 1v-7L4 5z" />
  </svg>
);

const TreeIcon = ({ size = 14 }) => (
  <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke="currentColor" strokeWidth="1.4">
    <path d="M5 4h6M5 12h6M5 20h6" />
    <path d="M11 4h4v16h-4" />
  </svg>
);

/* ── brand bar (full-bleed app shell) ── */
function BrandBar() {
  return (
    <div style={{
      height: 56, background: T.paper, borderBottom: `1px solid ${T.hairline}`,
      display: "flex", alignItems: "center",
      padding: `0 ${GUTTER}px`, gap: 28,
      fontFamily: T.sans, fontSize: 13, color: T.ink2,
    }}>
      <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
        <span style={{
          width: 26, height: 26, background: T.ink, color: T.paper,
          display: "grid", placeItems: "center", fontFamily: T.serif, fontWeight: 600, fontSize: 13,
        }}>E</span>
        <span style={{ fontFamily: T.serif, fontWeight: 600, fontSize: 14 }}>Eastbrook Libraries</span>
      </div>
      <div style={{ display: "flex", gap: 20, color: T.muted, fontSize: 12.5 }}>
        <span>Library Search</span>
        <span>Research Assistant</span>
        <span>Journals</span>
        <span style={{ color: T.ink, fontWeight: 500, borderBottom: `1.5px solid ${T.ink}`, paddingBottom: 16 }}>
          Collection Discovery
        </span>
      </div>
    </div>
  );
}

/* ── hero ── */
function Hero({ breadcrumb, title, height = 150 }) {
  return (
    <div style={{
      position: "relative", height, overflow: "hidden",
      background: "linear-gradient(110deg, #1f3a2e 0%, #2c5544 45%, #406b51 100%)",
    }}>
      <svg viewBox="0 0 1200 200" preserveAspectRatio="none"
        style={{ position: "absolute", inset: 0, width: "100%", height: "100%", opacity: 0.16 }}>
        <defs>
          <pattern id="dot" width="14" height="14" patternUnits="userSpaceOnUse">
            <circle cx="2" cy="2" r="1" fill="#fbf8ef" />
          </pattern>
        </defs>
        <rect width="100%" height="100%" fill="url(#dot)" />
        <path d="M0 130 Q300 90 600 130 T1200 110 L1200 200 L0 200 Z" fill="#fbf8ef" opacity="0.12" />
        <path d="M0 160 Q300 130 600 160 T1200 150 L1200 200 L0 200 Z" fill="#fbf8ef" opacity="0.18" />
      </svg>
      <div style={{
        position: "absolute", inset: 0, padding: "14px 24px 16px",
        display: "flex", flexDirection: "column", justifyContent: "space-between",
        color: T.surface,
      }}>
        {breadcrumb}
        <div>
          <h1 style={{
            fontFamily: T.serif, margin: 0,
            fontSize: 24, fontWeight: 500, letterSpacing: "-0.01em",
            lineHeight: 1.1, textWrap: "balance",
          }}>{title}</h1>
          <div style={{ marginTop: 6, fontSize: 11.5, opacity: 0.85, fontFamily: T.sans }}>
            Mira K. Adesanya · 2000–2024 · <span style={{ letterSpacing: "0.12em", textTransform: "uppercase", fontSize: 9.5 }}>Archival material</span>
          </div>
        </div>
      </div>
    </div>
  );
}

const Sep = () => (
  <span style={{ margin: "0 7px", color: "rgba(251,248,239,0.55)", fontFamily: T.sans, fontSize: 11.5 }}>/</span>
);

function BC({ children, current, after }) {
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
      <span style={{
        fontFamily: T.sans, fontSize: 11.5,
        color: current ? T.surface : "rgba(251,248,239,0.75)",
        textDecoration: current ? "none" : "underline", textUnderlineOffset: 3,
        fontWeight: current ? 500 : 400,
      }}>{children}</span>
      {after}
    </span>
  );
}

/* ── tree data ── */
const TREE_NODES = [
  {
    id: "root", name: "Coastal Adaptation Photographs", open: true,
    children: [
      {
        id: "field", name: "Field Studies", count: 24, open: true,
        children: [
          { id: "rotterdam", name: "Rotterdam", count: 8, current: true },
          { id: "miami", name: "Miami", count: 12 },
          { id: "lagos", name: "Lagos", count: 4 },
        ],
      },
      { id: "press", name: "Press & Media", count: 18 },
      { id: "maps", name: "Maps & Plans", count: 36 },
      { id: "oral", name: "Oral Histories", count: 14 },
      { id: "site", name: "Site Reports", count: 22 },
    ],
  },
];

function TreeBranch({ node, depth = 0 }) {
  const [open, setOpen] = useState(node.open ?? false);
  const has = node.children?.length;
  const indent = depth * 14;
  return (
    <>
      <div style={{
        display: "grid", gridTemplateColumns: "14px 1fr auto",
        alignItems: "center", gap: 6,
        padding: "5px 8px", paddingLeft: 8 + indent,
        background: node.current ? T.accentSoft : "transparent",
        color: node.current ? T.accent : T.ink,
        borderLeft: node.current ? `2px solid ${T.accent}` : "2px solid transparent",
        fontFamily: T.sans, fontSize: 12, fontWeight: node.current ? 600 : 400,
      }}>
        <span onClick={() => setOpen(!open)} style={{ display: "inline-flex", color: T.muted }}>
          {has ? <Chevron open={open} size={10} /> : <span style={{ width: 10 }} />}
        </span>
        <span style={{ display: "inline-flex", alignItems: "center", gap: 6, minWidth: 0 }}>
          <Folder size={12} />
          <span style={{ whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{node.name}</span>
        </span>
        {node.count != null && (
          <span style={{ fontFamily: T.mono, fontSize: 10.5, color: node.current ? T.accent : T.muted }}>
            {node.count}
          </span>
        )}
      </div>
      {has && open && node.children.map((c) => <TreeBranch key={c.id} node={c} depth={depth + 1} />)}
    </>
  );
}

/* ── facets panel ── */
function FacetsPanel({ width = "100%", title = "Refine" }) {
  const groups = [
    { title: "Format", items: [
      { l: "Photograph", c: 412, on: true },
      { l: "Contact sheet", c: 22 },
      { l: "Negative", c: 88 },
      { l: "Oversized", c: 11 },
    ]},
    { title: "Date", items: [
      { l: "2020 – 2024", c: 198, on: true },
      { l: "2010 – 2019", c: 287 },
      { l: "2000 – 2009", c: 47 },
    ]},
    { title: "Photographer", items: [
      { l: "M. Adesanya", c: 218 },
      { l: "L. Holmberg", c: 142 },
      { l: "C. Park", c: 96 },
    ]},
  ];
  return (
    <div style={{ width, fontFamily: T.sans, color: T.ink }}>
      <div style={{
        padding: "12px 14px 8px", display: "flex", justifyContent: "space-between", alignItems: "baseline",
      }}>
        <SmallCaps style={{ color: T.ink }}>{title}</SmallCaps>
        <span style={{ fontSize: 10.5, color: T.muted, textDecoration: "underline" }}>Clear</span>
      </div>
      {groups.map((g) => (
        <div key={g.title} style={{ padding: "10px 14px", borderTop: `1px solid ${T.hairline}` }}>
          <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", paddingBottom: 6 }}>
            <SmallCaps style={{ color: T.ink2, fontSize: 9.5 }}>{g.title}</SmallCaps>
            <Chevron open size={9} />
          </div>
          {g.items.map((it) => (
            <div key={it.l} style={{
              display: "grid", gridTemplateColumns: "14px 1fr auto", alignItems: "center", gap: 8,
              padding: "3px 0", fontSize: 12,
            }}>
              <span style={{
                width: 12, height: 12, border: `1.5px solid ${it.on ? T.accent : T.hairline2}`,
                background: it.on ? T.accent : "transparent", color: T.accentInk,
                display: "grid", placeItems: "center", fontSize: 9,
              }}>{it.on ? "✓" : ""}</span>
              <span>{it.l}</span>
              <span style={{ fontFamily: T.mono, fontSize: 10.5, color: T.muted }}>{it.c}</span>
            </div>
          ))}
        </div>
      ))}
    </div>
  );
}

/* ── results body — toolbar + item grid ── */
function ResultsBody({ showFilterButton = false }) {
  return (
    <div style={{ background: T.paper, padding: "16px 22px 22px", fontFamily: T.sans }}>
      {/* toolbar */}
      <div style={{
        display: "flex", justifyContent: "space-between", alignItems: "center",
        gap: 12, flexWrap: "wrap",
      }}>
        <div style={{ display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap" }}>
          {showFilterButton && (
            <button style={{
              display: "inline-flex", alignItems: "center", gap: 6,
              background: T.ink, color: T.paper, border: 0, padding: "6px 11px",
              fontFamily: T.sans, fontSize: 12, fontWeight: 500,
            }}>
              <FilterIcon size={12} /> Filters · 2
            </button>
          )}
          <Chip on>Photograph</Chip>
          <Chip on>2020 – 2024</Chip>
          <Chip>+ Add filter</Chip>
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 10, fontSize: 11.5, color: T.muted }}>
          <span>Sort by</span>
          <span style={{ color: T.ink, fontWeight: 500 }}>Newest ▾</span>
          <span style={{ color: T.hairline2 }}>|</span>
          <span style={{ color: T.ink }}>▦</span>
          <span>≡</span>
        </div>
      </div>
      <div style={{ marginTop: 10, fontSize: 11.5, color: T.muted }}>
        Showing <span style={{ fontFamily: T.mono, color: T.ink }}>1–8</span> of <span style={{ fontFamily: T.mono, color: T.ink }}>198</span> in Rotterdam
      </div>

      {/* grid */}
      <div style={{
        marginTop: 14, display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 12,
      }}>
        {[
          ["Photograph", "Maeslantkering stress test, 2014"],
          ["Contact sheet", "Boompjes, 2017 (rolls 1–3)"],
          ["Photograph", "Hoboken seawall, 2018"],
          ["Photograph", "Rijnhaven dock, 2019"],
          ["Negative", "Erasmusbrug, 2021"],
          ["Photograph", "Katendrecht walkway, 2022"],
          ["Photograph", "Noordereiland flood line"],
          ["Photograph", "Wilhelminapier, 2024"],
        ].map(([type, title], i) => {
          const palettes = [
            ["#1f3a2e", "#a8c2b0"],
            ["#3b465e", "#9aa6c0"],
            ["#6a1f23", "#e6b4ad"],
            ["#8a4a1f", "#d9b58c"],
          ];
          const [fg, bg] = palettes[i % palettes.length];
          return (
            <div key={i} style={{ border: `1px solid ${T.hairline}`, background: T.surface }}>
              <div style={{ height: 86, background: `linear-gradient(135deg, ${fg}, ${bg})`, position: "relative" }}>
                <span style={{
                  position: "absolute", top: 6, left: 8,
                  fontFamily: T.sans, fontSize: 8.5, letterSpacing: "0.12em",
                  textTransform: "uppercase", color: "#fbf8ef", opacity: 0.95,
                }}>{type}</span>
              </div>
              <div style={{ padding: "8px 10px" }}>
                <div style={{ fontFamily: T.serif, fontSize: 13, fontWeight: 500, lineHeight: 1.2 }}>{title}</div>
                <div style={{ marginTop: 4, fontFamily: T.mono, fontSize: 10, color: T.muted }}>
                  MS-2078 · Box 14 · F.{2 + i}
                </div>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function Chip({ children, on }) {
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 5,
      padding: "4px 9px", fontSize: 11.5, fontFamily: T.sans,
      background: on ? T.ink : "transparent",
      color: on ? T.paper : T.ink2,
      border: on ? "0" : `1px solid ${T.hairline2}`,
      borderStyle: on ? "solid" : (typeof children === "string" && children.startsWith("+") ? "dashed" : "solid"),
    }}>{children}</span>
  );
}

/* ═════════════ VARIANT 1 — Three columns (Tree | Facets | Content) ═════════════ */
function Variant1() {
  return (
    <Frame>
      <BrandBar />
      <Card>
        <div style={{ display: "grid", gridTemplateColumns: "224px 224px 1fr", flex: 1, minHeight: 0 }}>
          <aside style={{ borderRight: `1px solid ${T.hairline}`, background: T.surface, overflow: "auto" }}>
            <div style={{
              padding: "12px 14px 8px", display: "flex", justifyContent: "space-between", alignItems: "center",
              borderBottom: `1px solid ${T.hairline}`,
            }}>
              <SmallCaps style={{ color: T.ink }}>Hierarchy</SmallCaps>
              <span style={iconBtn}>‹</span>
            </div>
            <div style={{ padding: "6px 0" }}>{TREE_NODES.map((n) => <TreeBranch key={n.id} node={n} />)}</div>
          </aside>
          <aside style={{ borderRight: `1px solid ${T.hairline}`, background: T.paper2, overflow: "auto" }}>
            <FacetsPanel />
          </aside>
          <main style={{ overflow: "auto" }}>
            <Hero
              breadcrumb={<div><BC>Discovery</BC><Sep /><BC>Coastal Adaptation</BC><Sep /><BC>Field Studies</BC><Sep /><BC current>Rotterdam</BC></div>}
              title="Rotterdam Field Studies"
            />
            <ResultsBody />
          </main>
        </div>
      </Card>
      <Annot
        tone="warn"
        verdict="Heavy — 448px gone before content even starts"
        strategy="Both panels persistent · two adjacent left rails inside the card"
      />
    </Frame>
  );
}

/* ═════════════ VARIANT 2 — Slim rail toggles WHAT the second column shows ═════════════ */
function Variant2() {
  const [mode, setMode] = useState("tree"); // tree | filter
  return (
    <Frame>
      <BrandBar />
      <Card>
        <div style={{ display: "grid", gridTemplateColumns: "52px 248px 1fr", flex: 1, minHeight: 0 }}>
          {/* rail */}
          <aside style={{
            background: T.ink, color: T.surface,
            display: "flex", flexDirection: "column", alignItems: "center", padding: "12px 0", gap: 4,
          }}>
            <RailBtn icon={<TreeIcon size={15} />} active={mode === "tree"} onClick={() => setMode("tree")} label="Tree" />
            <RailBtn icon={<FilterIcon size={15} />} active={mode === "filter"} onClick={() => setMode("filter")} label="Filters" badge="2" />
            <RailBtn icon={<Folder size={15} />} label="Saved" />
            <div style={{ flex: 1 }} />
            <div style={{
              writingMode: "vertical-rl", transform: "rotate(180deg)",
              fontFamily: T.sans, fontSize: 9.5, letterSpacing: "0.18em",
              textTransform: "uppercase", color: "rgba(251,248,239,0.45)", padding: "8px 0",
            }}>Field Studies › Rotterdam</div>
          </aside>
          <aside style={{
            borderRight: `1px solid ${T.hairline}`, background: T.surface, overflow: "auto",
          }}>
            {mode === "tree" ? (
              <>
                <div style={{
                  padding: "12px 14px 8px", borderBottom: `1px solid ${T.hairline}`,
                  display: "flex", justifyContent: "space-between", alignItems: "center",
                }}>
                  <SmallCaps style={{ color: T.ink }}>Hierarchy</SmallCaps>
                  <span style={{ fontFamily: T.mono, fontSize: 10, color: T.muted }}>MS-2078</span>
                </div>
                <div style={{ padding: "6px 0" }}>{TREE_NODES.map((n) => <TreeBranch key={n.id} node={n} />)}</div>
              </>
            ) : (
              <FacetsPanel />
            )}
          </aside>
          <main style={{ overflow: "auto" }}>
            <Hero
              breadcrumb={<div><BC>Discovery</BC><Sep /><BC>Coastal Adaptation</BC><Sep /><BC>Field Studies</BC><Sep /><BC current>Rotterdam</BC></div>}
              title="Rotterdam Field Studies"
            />
            <ResultsBody />
          </main>
        </div>
      </Card>
      <Annot
        tone="good"
        verdict="One rail · one panel · either mode = same footprint"
        strategy="Rail icons toggle the second column between Hierarchy & Filters"
      />
    </Frame>
  );
}

function RailBtn({ icon, active, label, badge, onClick }) {
  return (
    <div onClick={onClick} title={label} style={{
      width: 40, height: 40, display: "grid", placeItems: "center", position: "relative",
      background: active ? T.accent : "transparent",
      color: active ? T.accentInk : T.surface,
    }}>
      {icon}
      {badge && (
        <span style={{
          position: "absolute", top: 4, right: 4, minWidth: 14, height: 14,
          background: T.accent, color: T.accentInk, fontFamily: T.mono, fontSize: 9,
          display: "grid", placeItems: "center", borderRadius: 999,
        }}>{badge}</span>
      )}
    </div>
  );
}

/* ═════════════ VARIANT 3 — Breadcrumb dropdowns + facets get the rail ═════════════ */
function Variant3() {
  const [open, setOpen] = useState("field");
  return (
    <Frame>
      <BrandBar />
      <Card>
        <div style={{ display: "grid", gridTemplateColumns: "232px 1fr", flex: 1, minHeight: 0 }}>
          <aside style={{ borderRight: `1px solid ${T.hairline}`, background: T.surface, overflow: "auto" }}>
            <FacetsPanel />
          </aside>
          <main style={{ overflow: "auto", position: "relative" }}>
            <Hero
              height={170}
              breadcrumb={
                <div style={{ position: "relative" }}>
                  <BC after={<DropChev onClick={() => setOpen("root")} />}>Discovery</BC><Sep />
                  <BC after={<DropChev onClick={() => setOpen("coll")} />}>Coastal Adaptation</BC><Sep />
                  <BC after={<DropChev open={open === "field"} onClick={() => setOpen(open === "field" ? null : "field")} />}>
                    Field Studies
                  </BC><Sep />
                  <BC current>Rotterdam</BC>

                  {open === "field" && (
                    <SiblingMenu
                      title="Field Studies"
                      items={[
                        { l: "Rotterdam", c: 8, cur: true },
                        { l: "Miami", c: 12 },
                        { l: "Lagos", c: 4 },
                        { l: "Jakarta", c: 6 },
                        { l: "New Orleans", c: 9 },
                      ]}
                      style={{ left: 260, top: 30 }}
                    />
                  )}
                </div>
              }
              title="Rotterdam Field Studies"
            />
            <ResultsBody />
          </main>
        </div>
      </Card>
      <Annot
        tone="good"
        verdict="Facets get the full rail — no fight"
        strategy="Tree lives in the breadcrumb chevrons · zero permanent tree UI"
      />
    </Frame>
  );
}

function DropChev({ open, onClick }) {
  return (
    <span onClick={onClick} style={{
      background: open ? "rgba(251,248,239,0.18)" : "rgba(251,248,239,0.06)",
      border: "1px solid rgba(251,248,239,0.25)", color: T.surface,
      width: 16, height: 16, padding: 0, display: "inline-grid", placeItems: "center",
      marginLeft: 1,
    }}>
      <Chevron open size={8} />
    </span>
  );
}

function SiblingMenu({ title, items, style }) {
  return (
    <div style={{
      position: "absolute", background: T.surface, color: T.ink,
      border: `1px solid ${T.hairline2}`, width: 230, padding: "6px 0",
      boxShadow: "0 18px 40px -12px rgba(28,24,20,0.30)", zIndex: 5,
      ...style,
    }}>
      <div style={{
        padding: "4px 14px 6px", borderBottom: `1px solid ${T.hairline}`,
        display: "flex", justifyContent: "space-between",
      }}>
        <SmallCaps>{title}</SmallCaps>
        <span style={{ fontFamily: T.mono, fontSize: 10, color: T.muted }}>{items.length}</span>
      </div>
      {items.map((it) => (
        <div key={it.l} style={{
          padding: "5px 14px", display: "flex", justifyContent: "space-between", alignItems: "center",
          background: it.cur ? T.accentSoft : "transparent",
          color: it.cur ? T.accent : T.ink,
          fontFamily: T.sans, fontSize: 12, fontWeight: it.cur ? 600 : 400,
        }}>
          <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}><Folder size={11} /> {it.l}</span>
          <span style={{ fontFamily: T.mono, fontSize: 10.5, color: it.cur ? T.accent : T.muted }}>{it.c}</span>
        </div>
      ))}
    </div>
  );
}

/* ═════════════ VARIANT 4 — One left column, tabbed (Hierarchy | Filters) ═════════════ */
function Variant4() {
  const [tab, setTab] = useState("tree");
  return (
    <Frame>
      <BrandBar />
      <Card>
        <div style={{ display: "grid", gridTemplateColumns: "280px 1fr", flex: 1, minHeight: 0 }}>
          <aside style={{
            borderRight: `1px solid ${T.hairline2}`, background: T.paper2, overflow: "hidden",
            display: "flex", flexDirection: "column",
          }}>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", borderBottom: `1px solid ${T.hairline2}` }}>
              <Tab active={tab === "tree"} onClick={() => setTab("tree")}>
                <TreeIcon size={12} /> Hierarchy
              </Tab>
              <Tab active={tab === "filter"} onClick={() => setTab("filter")}>
                <FilterIcon size={12} /> Filters
                <span style={{
                  marginLeft: 4, fontFamily: T.mono, fontSize: 10,
                  background: T.accent, color: T.accentInk, padding: "0 5px",
                }}>2</span>
              </Tab>
            </div>
            <div style={{
              padding: "12px 14px 10px", borderBottom: `1px solid ${T.hairline2}`, background: T.paper2,
            }}>
              <SmallCaps style={{ color: T.ink2 }}>Finding aid</SmallCaps>
              <div style={{ fontFamily: T.serif, fontSize: 15, fontWeight: 500, marginTop: 2, letterSpacing: "-0.005em" }}>
                Coastal Adaptation Photographs
              </div>
              <div style={{ fontFamily: T.mono, fontSize: 10, color: T.muted, marginTop: 3 }}>
                MS-2078 · 2000–2024 · 8.4 lin. ft.
              </div>
            </div>
            {tab === "tree" ? (
              <div style={{ padding: "8px 0", flex: 1, overflow: "auto" }}>
                {TREE_NODES.map((n) => <TreeBranch key={n.id} node={n} />)}
              </div>
            ) : (
              <div style={{ flex: 1, overflow: "auto", background: T.surface }}>
                <FacetsPanel title="Filters" />
              </div>
            )}
          </aside>
          <main style={{ overflow: "auto" }}>
            <Hero
              breadcrumb={<div><BC>Discovery</BC><Sep /><BC>Coastal Adaptation</BC><Sep /><BC>Field Studies</BC><Sep /><BC current>Rotterdam</BC></div>}
              title="Rotterdam Field Studies"
            />
            <ResultsBody />
          </main>
        </div>
      </Card>
      <Annot
        tone="good"
        verdict="One column · same width · both modes available"
        strategy="Single left rail with [Hierarchy | Filters] tabs — modal mutex"
      />
    </Frame>
  );
}

function Tab({ children, active, onClick }) {
  return (
    <button onClick={onClick} style={{
      display: "inline-flex", alignItems: "center", gap: 6, justifyContent: "center",
      padding: "10px 8px", background: active ? T.surface : "transparent", border: 0,
      borderBottom: active ? `2px solid ${T.accent}` : `2px solid transparent`,
      color: active ? T.ink : T.muted, fontFamily: T.sans, fontSize: 12, fontWeight: 500,
      cursor: "default",
    }}>
      {children}
    </button>
  );
}

/* ═════════════ VARIANT 5 — Facets get the rail, tree via peek widget ═════════════ */
function Variant5() {
  const [peek, setPeek] = useState(true);
  return (
    <Frame>
      <BrandBar />
      <Card>
        <div style={{ display: "grid", gridTemplateColumns: "232px 1fr", flex: 1, minHeight: 0 }}>
          <aside style={{ borderRight: `1px solid ${T.hairline}`, background: T.surface, overflow: "auto" }}>
            <FacetsPanel />
          </aside>
          <main style={{ overflow: "auto", position: "relative" }}>
            <Hero
              height={170}
              breadcrumb={
                <div style={{ position: "relative" }}>
                  <BC>Discovery</BC><Sep /><BC>Coastal Adaptation</BC><Sep /><BC>Field Studies</BC><Sep /><BC current>Rotterdam</BC>
                  <span onClick={() => setPeek(!peek)} style={{
                    marginLeft: 10, display: "inline-flex", alignItems: "center", gap: 5,
                    padding: "3px 7px", background: "rgba(251,248,239,0.14)",
                    border: "1px solid rgba(251,248,239,0.28)",
                    fontFamily: T.sans, fontSize: 10.5, color: T.surface,
                  }}>
                    <TreeIcon size={10} /> 8 siblings <Chevron open={peek} size={8} />
                  </span>
                  {peek && <PeekMap style={{ top: 32, left: 410 }} />}
                </div>
              }
              title="Rotterdam Field Studies"
            />
            <ResultsBody />
          </main>
        </div>
      </Card>
      <Annot
        tone="good"
        verdict="Same as #3 visually · tree access is on-demand"
        strategy="Facets own the rail · small chip → compact 3-level peek"
      />
    </Frame>
  );
}

function PeekMap({ style }) {
  return (
    <div style={{
      position: "absolute", background: T.surface, color: T.ink,
      border: `1px solid ${T.hairline2}`, width: 340, padding: "10px 12px",
      boxShadow: "0 18px 40px -12px rgba(28,24,20,0.30)", zIndex: 5,
      ...style,
    }}>
      <SmallCaps>You are here</SmallCaps>
      <div style={{ marginTop: 6, fontFamily: T.sans, fontSize: 12 }}>
        <div style={{ color: T.muted, display: "flex", justifyContent: "space-between", padding: "3px 0" }}>
          <span style={{ display: "inline-flex", gap: 5, alignItems: "center" }}>↑ <Folder size={11} /> Field Studies</span>
          <span style={{ fontFamily: T.mono, fontSize: 10.5 }}>24</span>
        </div>
        <div style={{ paddingLeft: 10, borderLeft: `1px dashed ${T.hairline2}`, marginTop: 3 }}>
          {[
            { l: "Rotterdam", c: 8, cur: true },
            { l: "Miami", c: 12 },
            { l: "Lagos", c: 4 },
            { l: "Jakarta", c: 6 },
            { l: "New Orleans", c: 9 },
          ].map((s) => (
            <div key={s.l} style={{
              display: "flex", justifyContent: "space-between", padding: "3px 8px",
              background: s.cur ? T.accentSoft : "transparent",
              color: s.cur ? T.accent : T.ink,
              fontWeight: s.cur ? 600 : 400,
              borderLeft: s.cur ? `2px solid ${T.accent}` : "2px solid transparent",
            }}>
              <span style={{ display: "inline-flex", gap: 5, alignItems: "center" }}><Folder size={11} /> {s.l}</span>
              <span style={{ fontFamily: T.mono, fontSize: 10.5, color: s.cur ? T.accent : T.muted }}>{s.c}</span>
            </div>
          ))}
        </div>
        <div style={{ marginTop: 6, color: T.muted }}>↓ Inside Rotterdam</div>
        <div style={{ paddingLeft: 10, marginTop: 2 }}>
          {[{ l: "Maeslantkering tests", c: 3 }, { l: "Neighborhood walks", c: 5 }].map((s) => (
            <div key={s.l} style={{ display: "flex", justifyContent: "space-between", padding: "2px 0" }}>
              <span>· {s.l}</span>
              <span style={{ fontFamily: T.mono, fontSize: 10.5, color: T.muted }}>{s.c}</span>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

/* ── chrome ── */
const iconBtn = {
  width: 20, height: 20, display: "grid", placeItems: "center",
  border: `1px solid ${T.hairline2}`, background: "transparent",
  color: T.muted, fontFamily: T.sans, fontSize: 11,
};

function Frame({ children }) {
  // Outer = page gutter colour. Children render the brand bar (full bleed)
  // and then a centred content card via <Card>.
  return (
    <div style={{
      width: ART_W, height: ART_H, background: T.paper2,
      position: "relative", overflow: "hidden", fontFamily: T.sans,
    }}>
      {children}
    </div>
  );
}

function Card({ children }) {
  return (
    <div style={{
      width: CARD_W, margin: "0 auto", marginTop: 0,
      background: T.paper,
      borderLeft: `1px solid ${T.hairline}`,
      borderRight: `1px solid ${T.hairline}`,
      height: ART_H - 56 - 56,   // brand bar 56 + annot 56
      overflow: "hidden",
      display: "flex", flexDirection: "column",
    }}>
      {children}
    </div>
  );
}

function Annot({ verdict, strategy, tone }) {
  const bg = tone === "good" ? T.good : tone === "warn" ? T.warn : T.ink;
  return (
    <div style={{
      position: "absolute", left: GUTTER, bottom: 20, right: GUTTER,
      background: bg, color: T.surface,
      padding: "10px 14px",
      display: "flex", gap: 16, alignItems: "center",
      fontFamily: T.sans, fontSize: 11.5,
    }}>
      <span style={{
        fontFamily: T.mono, fontSize: 10, letterSpacing: "0.08em",
        textTransform: "uppercase", opacity: 0.7, whiteSpace: "nowrap",
      }}>Verdict</span>
      <strong style={{ fontWeight: 600 }}>{verdict}</strong>
      <span style={{ opacity: 0.5 }}>·</span>
      <span style={{ opacity: 0.85 }}>{strategy}</span>
    </div>
  );
}

/* ── app ── */
function App() {
  return (
    <DesignCanvas>
      <DCSection
        id="with-facets"
        title="Hierarchy + Facets — five co-existence strategies"
        subtitle="Search-results state inside an archive. Both the tree AND the filter panel need to be reachable. The question for each variant: where do facets live?"
      >
        <DCArtboard id="v1" label="1 · Three columns (both persistent)" width={ART_W} height={ART_H}>
          <Variant1 />
        </DCArtboard>
        <DCArtboard id="v2" label="2 · Slim rail toggles panel mode" width={ART_W} height={ART_H}>
          <Variant2 />
        </DCArtboard>
        <DCArtboard id="v3" label="3 · Breadcrumb dropdowns · facets own rail" width={ART_W} height={ART_H}>
          <Variant3 />
        </DCArtboard>
        <DCArtboard id="v4" label="4 · One tabbed column [Hierarchy | Filters]" width={ART_W} height={ART_H}>
          <Variant4 />
        </DCArtboard>
        <DCArtboard id="v5" label="5 · Peek widget · facets own rail" width={ART_W} height={ART_H}>
          <Variant5 />
        </DCArtboard>
      </DCSection>
    </DesignCanvas>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
