/* global React */
// Sidebar-CONTAINED deep-hierarchy navigation (nothing opens to the right).
// Focus: how to stay oriented at 10 levels without running out of vertical room.

const { useState } = React;

const T = {
  paper: "#f3eee2", paper2: "#e6dfc9", 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 = 1180;
const ART_H = 780;
const SIDEBAR = 300;

// 10-level archival lineage
const LINEAGE = [
  { level: "Fonds",      name: "Adesanya Coastal Archive" },
  { level: "Series",     name: "Field Studies" },
  { level: "Subseries",  name: "Europe" },
  { level: "Group",      name: "Netherlands" },
  { level: "Subgroup",   name: "Rotterdam" },
  { level: "File",       name: "Maeslantkering" },
  { level: "Subfile",    name: "1998 Commissioning" },
  { level: "Item group", name: "Roll 14 — stress test" },
  { level: "Item",       name: "Frame 22 — gate closing" },
  { level: "Component",  name: "Verso — annotation" },
];

const CHILDREN = ["Recto — image", "Verso — annotation", "Conservation note", "Rights statement"];

/* ── atoms ── */
const SmallCaps = ({ children, style }) => (
  <span style={{ fontFamily: T.sans, fontSize: 9.5, letterSpacing: "0.14em",
    textTransform: "uppercase", fontWeight: 600, color: T.muted, ...style }}>{children}</span>
);
const Folder = ({ size = 12 }) => (
  <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke="currentColor" strokeWidth="1.4">
    <path d="M3 7h6l2 2h10v10H3z" /></svg>
);
const Doc = ({ size = 12 }) => (
  <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke="currentColor" strokeWidth="1.4">
    <path d="M6 3h9l4 4v14H6z" /><path d="M14 3v5h5" /></svg>
);
const Chev = ({ size = 11, dir = "r" }) => (
  <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke="currentColor" strokeWidth="2"
    style={{ transform: dir === "d" ? "rotate(90deg)" : dir === "l" ? "rotate(180deg)" : dir === "u" ? "rotate(-90deg)" : "none" }}>
    <path d="M9 6l6 6-6 6" /></svg>
);

function Frame({ children }) {
  return (
    <div style={{ width: ART_W, height: ART_H, background: T.paper2,
      position: "relative", overflow: "hidden", fontFamily: T.sans }}>{children}</div>
  );
}
function Bar() {
  return (
    <div style={{ height: 48, background: T.paper, borderBottom: `1px solid ${T.hairline}`,
      display: "flex", alignItems: "center", padding: "0 24px", gap: 10 }}>
      <span style={{ width: 24, height: 24, background: T.ink, color: T.paper,
        display: "grid", placeItems: "center", fontFamily: T.serif, fontWeight: 600, fontSize: 12 }}>E</span>
      <span style={{ fontFamily: T.serif, fontWeight: 600, fontSize: 14 }}>Eastbrook Libraries</span>
      <span style={{ marginLeft: 8, color: T.muted, fontSize: 12 }}>· Collection Discovery</span>
    </div>
  );
}
function Annot({ verdict, strategy, tone = "good" }) {
  const bg = tone === "good" ? T.good : tone === "warn" ? T.warn : T.ink;
  return (
    <div style={{ position: "absolute", left: 0, right: 0, bottom: 0, background: bg, color: T.surface,
      padding: "9px 24px", display: "flex", gap: 14, alignItems: "center", fontFamily: T.sans, fontSize: 11.5 }}>
      <span style={{ fontFamily: T.mono, fontSize: 9.5, letterSpacing: "0.08em", textTransform: "uppercase", opacity: 0.7 }}>At 10 levels</span>
      <strong style={{ fontWeight: 600 }}>{verdict}</strong>
      <span style={{ opacity: 0.5 }}>·</span>
      <span style={{ opacity: 0.85 }}>{strategy}</span>
    </div>
  );
}
function Stage({ sidebar }) {
  return (
    <div style={{ position: "absolute", top: 48, left: 0, right: 0, bottom: 34,
      display: "grid", gridTemplateColumns: `${SIDEBAR}px 1fr`, background: T.paper }}>
      <aside style={{ borderRight: `1px solid ${T.hairline}`, background: T.surface,
        display: "flex", flexDirection: "column", overflow: "hidden" }}>
        {sidebar}
      </aside>
      <main style={{ background: T.paper2, display: "flex", flexDirection: "column",
        alignItems: "center", justifyContent: "center", gap: 10 }}>
        <div style={{ width: 170, height: 128, background: "linear-gradient(135deg,#1f3a2e,#406b51)" }} />
        <div style={{ fontFamily: T.serif, fontSize: 15, fontWeight: 500 }}>Verso — annotation</div>
        <div style={{ fontFamily: T.mono, fontSize: 10, color: T.muted }}>Depth: level 10 of 10</div>
      </main>
    </div>
  );
}

/* ═══════════ A · Ancestry spine + children (two-zone) ═══════════ */
function SpineChildren() {
  return (
    <Frame>
      <Bar />
      <Stage sidebar={
        <>
          {/* zone 1: ancestry spine — compact, every level one thin row */}
          <div style={{ padding: "10px 12px 6px", borderBottom: `1px solid ${T.hairline}` }}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 4 }}>
              <SmallCaps>Path · 10 levels</SmallCaps>
              <span style={{ fontSize: 10, color: T.muted, textDecoration: "underline" }}>Collapse</span>
            </div>
            {LINEAGE.map((n, i) => {
              const last = i === LINEAGE.length - 1;
              return (
                <div key={i} style={{ display: "flex", alignItems: "center", gap: 6,
                  padding: "2px 0", paddingLeft: i * 9,
                  color: last ? T.accent : T.ink2, fontWeight: last ? 600 : 400 }}>
                  <span style={{ width: 5, height: 5, borderRadius: 9, flexShrink: 0,
                    background: last ? T.accent : T.hairline2 }} />
                  <span style={{ fontSize: 11.5, whiteSpace: "nowrap", overflow: "hidden",
                    textOverflow: "ellipsis" }}>{n.name}</span>
                </div>
              );
            })}
          </div>
          {/* zone 2: children of current node */}
          <div style={{ padding: "8px 12px 4px" }}>
            <SmallCaps>Inside this item</SmallCaps>
          </div>
          <div style={{ overflow: "auto", padding: "0 0 8px" }}>
            {CHILDREN.map((c) => {
              const cur = c === "Verso — annotation";
              return (
                <div key={c} style={{ display: "grid", gridTemplateColumns: "16px 1fr", gap: 8,
                  alignItems: "center", padding: "7px 14px", fontSize: 12.5,
                  background: cur ? T.accentSoft : "transparent", color: cur ? T.accent : T.ink,
                  fontWeight: cur ? 600 : 400,
                  borderLeft: cur ? `2px solid ${T.accent}` : "2px solid transparent" }}>
                  <span style={{ color: cur ? T.accent : T.muted }}><Doc /></span>
                  <span>{c}</span>
                </div>
              );
            })}
          </div>
        </>
      } />
      <Annot verdict="Full ancestry as a thin vertical spine + children below"
        strategy="10 rows of lineage fit easily vertically · children scroll independently" />
    </Frame>
  );
}

/* ═══════════ B · Collapsed spine (ellipsis for very deep) ═══════════ */
function CollapsedSpine() {
  // show first 2 + ellipsis + last 3
  const head = LINEAGE.slice(0, 2);
  const tail = LINEAGE.slice(-3);
  const hidden = LINEAGE.length - head.length - tail.length;
  return (
    <Frame>
      <Bar />
      <Stage sidebar={
        <>
          <div style={{ padding: "10px 12px 8px", borderBottom: `1px solid ${T.hairline}` }}>
            <SmallCaps style={{ marginBottom: 6, display: "block" }}>Path · level 10 of 10</SmallCaps>
            {head.map((n, i) => <SpineRow key={i} n={n} depth={i} />)}
            {/* collapsed middle */}
            <div style={{ display: "flex", alignItems: "center", gap: 6, padding: "4px 0", paddingLeft: 18,
              color: T.muted, cursor: "default" }}>
              <span style={{ width: 16, height: 16, border: `1px dashed ${T.hairline2}`,
                display: "grid", placeItems: "center", fontSize: 9, fontFamily: T.mono }}>+{hidden}</span>
              <span style={{ fontSize: 11, fontStyle: "italic", fontFamily: T.serif }}>show {hidden} hidden levels</span>
            </div>
            {tail.map((n, i) => <SpineRow key={i} n={n} depth={3 + i} last={i === tail.length - 1} />)}
          </div>
          <div style={{ padding: "8px 12px 4px" }}><SmallCaps>Inside this item</SmallCaps></div>
          <div style={{ overflow: "auto" }}>
            {CHILDREN.map((c) => {
              const cur = c === "Verso — annotation";
              return (
                <div key={c} style={{ display: "grid", gridTemplateColumns: "16px 1fr", gap: 8,
                  alignItems: "center", padding: "7px 14px", fontSize: 12.5,
                  background: cur ? T.accentSoft : "transparent", color: cur ? T.accent : T.ink,
                  fontWeight: cur ? 600 : 400,
                  borderLeft: cur ? `2px solid ${T.accent}` : "2px solid transparent" }}>
                  <span style={{ color: cur ? T.accent : T.muted }}><Doc /></span><span>{c}</span>
                </div>
              );
            })}
          </div>
        </>
      } />
      <Annot verdict="Even the spine collapses — head + “+N hidden” + tail"
        strategy="When 10 rows is too many: keep the ends, fold the middle behind a chip" />
    </Frame>
  );
}
function SpineRow({ n, depth, last }) {
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 6, padding: "2px 0", paddingLeft: depth * 9,
      color: last ? T.accent : T.ink2, fontWeight: last ? 600 : 400 }}>
      <span style={{ width: 5, height: 5, borderRadius: 9, flexShrink: 0, background: last ? T.accent : T.hairline2 }} />
      <span style={{ fontSize: 11.5, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{n.name}</span>
    </div>
  );
}

/* ═══════════ C · In-sidebar drill (push, stays in sidebar) ═══════════ */
function InSidebarDrill() {
  return (
    <Frame>
      <Bar />
      <Stage sidebar={
        <>
          {/* compact back header showing parent */}
          <div style={{ padding: "10px 12px", borderBottom: `1px solid ${T.hairline}`,
            display: "flex", alignItems: "center", gap: 8 }}>
            <button style={{ background: T.ink, color: T.paper, border: 0, width: 24, height: 24,
              display: "grid", placeItems: "center", cursor: "default", flexShrink: 0 }}>
              <Chev dir="l" size={12} />
            </button>
            <div style={{ minWidth: 0 }}>
              <SmallCaps style={{ fontSize: 8 }}>Item · level 9 of 10</SmallCaps>
              <div style={{ fontFamily: T.serif, fontSize: 13.5, fontWeight: 500, whiteSpace: "nowrap",
                overflow: "hidden", textOverflow: "ellipsis" }}>Frame 22 — gate closing</div>
            </div>
          </div>
          {/* mini breadcrumb strip (compact, scrolls horizontally if needed) */}
          <div style={{ padding: "6px 12px", borderBottom: `1px solid ${T.hairline}`,
            display: "flex", alignItems: "center", gap: 3, overflow: "hidden",
            fontSize: 10.5, color: T.muted }}>
            <span>Fonds</span><Chev size={8} /><span style={{ opacity: 0.5 }}>⋯</span>
            <Chev size={8} /><span>Roll 14</span><Chev size={8} />
            <span style={{ color: T.ink2 }}>Frame 22</span>
          </div>
          {/* current level's children fill the sidebar */}
          <div style={{ overflow: "auto" }}>
            {CHILDREN.map((c) => {
              const cur = c === "Verso — annotation";
              return (
                <div key={c} style={{ display: "grid", gridTemplateColumns: "16px 1fr 14px", gap: 8,
                  alignItems: "center", padding: "10px 14px", fontSize: 12.5,
                  borderBottom: `1px solid ${T.hairline}`,
                  background: cur ? T.accentSoft : "transparent", color: cur ? T.accent : T.ink,
                  fontWeight: cur ? 600 : 400 }}>
                  <span style={{ color: cur ? T.accent : T.muted }}><Doc /></span>
                  <span>{c}</span>
                  <span style={{ color: T.hairline2 }}><Chev size={11} /></span>
                </div>
              );
            })}
            <div style={{ padding: "10px 14px", color: T.muted, fontSize: 11 }}>
              Tap a row → it replaces this list (drills deeper, still in the sidebar)
            </div>
          </div>
        </>
      } />
      <Annot tone="warn" verdict="One level fills the sidebar; ‹ back ascends — never opens right"
        strategy="Infinite depth, zero overflow · trade: siblings of other levels hidden" />
    </Frame>
  );
}

/* ═══════════ D · Sticky ancestry + scrolling subtree ═══════════ */
function StickyAncestry() {
  // ancestry pinned (compact), current node + its children + grandchildren scroll
  return (
    <Frame>
      <Bar />
      <Stage sidebar={
        <>
          {/* pinned ancestry — single compact wrapping line */}
          <div style={{ padding: "9px 12px", borderBottom: `1px solid ${T.hairline}`,
            background: T.paper2, position: "sticky", top: 0 }}>
            <SmallCaps style={{ fontSize: 8.5, display: "block", marginBottom: 4 }}>You are here</SmallCaps>
            <div style={{ display: "flex", flexWrap: "wrap", alignItems: "center", gap: "2px 4px",
              fontSize: 10.5, color: T.muted, lineHeight: 1.3 }}>
              {LINEAGE.slice(0, 8).map((n, i) => (
                <span key={i} style={{ display: "inline-flex", alignItems: "center", gap: 3 }}>
                  <span>{n.name.length > 14 ? n.name.slice(0, 12) + "…" : n.name}</span>
                  <Chev size={7} />
                </span>
              ))}
              <span style={{ color: T.accent, fontWeight: 600 }}>Frame 22</span>
            </div>
          </div>
          {/* scrolling: current node expanded with children + one level of grandchildren */}
          <div style={{ overflow: "auto", padding: "6px 0" }}>
            <TreeRow depth={0} label="Frame 22 — gate closing" lv="Item" open root />
            {CHILDREN.map((c) => {
              const cur = c === "Verso — annotation";
              return <TreeRow key={c} depth={1} label={c} lv="Component" current={cur} leaf
                open={cur} />;
            })}
            {/* grandchildren under current */}
            <TreeRow depth={2} label="Transcription" lv="Text" leaf />
            <TreeRow depth={2} label="Translation (EN)" lv="Text" leaf />
          </div>
        </>
      } />
      <Annot verdict="Ancestry pinned compact at top; only current branch scrolls below"
        strategy="Re-rooting feel · header never scrolls away so you keep orientation" />
    </Frame>
  );
}
function TreeRow({ depth, label, lv, open, current, root, leaf }) {
  return (
    <div style={{ display: "grid", gridTemplateColumns: "14px 14px 1fr auto", alignItems: "center", gap: 6,
      padding: "6px 12px", paddingLeft: 10 + depth * 16,
      background: current ? T.accentSoft : "transparent",
      color: current ? T.accent : T.ink, fontWeight: current || root ? 600 : 400,
      borderLeft: current ? `2px solid ${T.accent}` : "2px solid transparent" }}>
      <span style={{ color: T.muted }}>{!leaf ? <Chev dir={open ? "d" : "r"} size={10} /> : <span />}</span>
      <span style={{ color: current ? T.accent : T.muted }}>{leaf ? <Doc /> : <Folder />}</span>
      <span style={{ fontSize: 12.5, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{label}</span>
      <span style={{ fontSize: 7.5, letterSpacing: "0.06em", textTransform: "uppercase", color: T.muted, fontWeight: 600 }}>{lv}</span>
    </div>
  );
}

function App() {
  return (
    <DesignCanvas>
      <DCSection
        id="sidebar-deep"
        title="Deep hierarchy, sidebar-contained (nothing opens right)"
        subtitle="10-level lineage. The trick at depth: split the sidebar into ancestry (where you are) + children (where you can go)."
      >
        <DCArtboard id="a" label="A · Ancestry spine + children" width={ART_W} height={ART_H}>
          <SpineChildren />
        </DCArtboard>
        <DCArtboard id="b" label="B · Collapsed spine (ellipsis)" width={ART_W} height={ART_H}>
          <CollapsedSpine />
        </DCArtboard>
        <DCArtboard id="c" label="C · In-sidebar drill (push)" width={ART_W} height={ART_H}>
          <InSidebarDrill />
        </DCArtboard>
        <DCArtboard id="d" label="D · Sticky ancestry + scrolling subtree" width={ART_W} height={ART_H}>
          <StickyAncestry />
        </DCArtboard>
      </DCSection>
    </DesignCanvas>
  );
}

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