// witness-primitives.jsx — reusable parts for The Witness UI
const { useState, useEffect, useRef, useMemo } = React;

// ─────────────────────────────────────────────────────────────
// Panel — base raised metal surface
function WPanel({
  children,
  style = {},
  base = W.iron,
  density = 1,
  intensity = 0.6,
  angle = 87,
  ...rest
}) {
  return (
    <div
      style={{
        background: hairlineMetal({ base, density, intensity, angle }),
        ...embossed,
        borderRadius: 2,
        position: "relative",
        ...style,
      }}
      {...rest}
    >
      {children}
    </div>
  );
}

// Sunken inset — for fields, value wells
function WInset({ children, style = {}, ...rest }) {
  return (
    <div
      style={{
        background: `linear-gradient(180deg, #050608, #0d0e10)`,
        ...sunk,
        borderRadius: 2,
        ...style,
      }}
      {...rest}
    >
      {children}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// IdentityAxis — the core visual.
// `progress` 0..1; as it climbs, the bar transitions from faint translucent
// hairline to thick deeply embossed gold etched bar.
function IdentityAxis({
  progress = 0,
  hours = 0,
  cap = 1000,
  label = "IDENTITY",
  subtitle = "",
  orientation = "h",
  height = 14,
  showHours = true,
  flashTick = 0,
}) {
  const p = Math.max(0, Math.min(1, progress));
  // The "etch depth" grows with progress.
  const fillIntensity = 0.5 + p * 0.9;
  const fillDensity = 0.6 + p * 1.2;
  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        gap: 6,
        position: "relative",
      }}
    >
      {label && (
        <div
          style={{
            display: "flex",
            justifyContent: "space-between",
            alignItems: "baseline",
          }}
        >
          <div
            style={{
              fontFamily: W.mono,
              fontSize: 9.5,
              letterSpacing: "0.22em",
              color: W.textLo,
              textTransform: "uppercase",
              fontWeight: 500,
            }}
          >
            {label}
          </div>
          {showHours && (
            <div
              style={{
                fontFamily: W.mono,
                fontSize: 10,
                color: W.text,
                letterSpacing: "0.08em",
              }}
            >
              <span style={{ color: W.goldHi }}>{hours.toFixed(1)}</span>
              <span style={{ color: W.textXLo }}> / {cap.toFixed(0)} h</span>
            </div>
          )}
        </div>
      )}
      {/* The bar */}
      <div
        style={{
          position: "relative",
          height,
          width: "100%",
          background: "#06070a",
          boxShadow:
            "inset 0 1px 2px rgba(0,0,0,0.85), inset 0 -1px 0 rgba(255,255,255,0.025)",
          overflow: "hidden",
          borderRadius: 1,
        }}
      >
        {/* Empty track tick marks */}
        <div
          style={{
            position: "absolute",
            inset: 0,
            background:
              "repeating-linear-gradient(90deg, transparent 0 23px, rgba(255,255,255,0.03) 23px 24px)",
          }}
        />
        {/* Filled mass */}
        <div
          style={{
            position: "absolute",
            top: 0,
            bottom: 0,
            left: 0,
            width: `${p * 100}%`,
            background: brushedGold({ intensity: fillIntensity, angle: 87 }),
            boxShadow: [
              `inset 0 1px 0 rgba(${W.hiRGB},0.5)`,
              "inset 0 -1px 1px rgba(0,0,0,0.65)",
              `inset -1px 0 0 rgba(0,0,0,0.55)`,
              `0 0 ${4 + p * 6}px rgba(${W.midRGB},${0.06 + p * 0.1})`,
            ].join(","),
            transition: "width 0.6s cubic-bezier(.2,.7,.25,1)",
          }}
        >
          {/* Brushed hairlines on top */}
          <div
            style={{
              position: "absolute",
              inset: 0,
              background: `repeating-linear-gradient(87deg, rgba(${W.hiRGB},0.08) 0 .5px, rgba(0,0,0,0.25) .5px ${(1.2 / fillDensity).toFixed(2)}px)`,
              mixBlendMode: "overlay",
            }}
          />
        </div>
        {/* Etched edge of the fill — the "engraving" line */}
        {p > 0 && p < 1 && (
          <div
            style={{
              position: "absolute",
              top: 0,
              bottom: 0,
              left: `calc(${p * 100}% - 1px)`,
              width: 2,
              background:
                "linear-gradient(180deg, rgba(0,0,0,0.9), rgba(0,0,0,0.4))",
              boxShadow: `1px 0 0 rgba(${W.hiRGB},0.25)`,
              transition: "left 0.6s cubic-bezier(.2,.7,.25,1)",
            }}
          />
        )}
        {/* Flash on increment */}
        {flashTick > 0 && (
          <div
            key={flashTick}
            style={{
              position: "absolute",
              inset: 0,
              pointerEvents: "none",
              animation: "witness-flash 0.9s ease-out forwards",
              background: `linear-gradient(90deg, transparent, rgba(${W.hiRGB},0.18), transparent)`,
            }}
          />
        )}
      </div>
      {subtitle && (
        <div
          style={{
            fontFamily: W.mono,
            fontSize: 9,
            letterSpacing: "0.12em",
            color: W.textXLo,
          }}
        >
          {subtitle}
        </div>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// MonoStat — high-precision data block
function MonoStat({
  label,
  value,
  unit,
  accent = false,
  size = "md",
  align = "left",
}) {
  const sz = { sm: 18, md: 26, lg: 38, xl: 56 }[size] || 26;
  return (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
        gap: 4,
        alignItems: align === "right" ? "flex-end" : "flex-start",
      }}
    >
      {label && (
        <div
          style={{
            fontFamily: W.mono,
            fontSize: 9,
            letterSpacing: "0.24em",
            color: W.textLo,
            textTransform: "uppercase",
          }}
        >
          {label}
        </div>
      )}
      <div
        style={{
          fontFamily: W.mono,
          fontWeight: 300,
          fontSize: sz,
          lineHeight: 1,
          letterSpacing: "-0.02em",
          color: accent ? W.goldHi : W.textHi,
          fontVariantNumeric: "tabular-nums",
          ...etched(),
        }}
      >
        {value}
        {unit && (
          <span
            style={{
              fontSize: sz * 0.45,
              marginLeft: 4,
              color: accent ? W.gold : W.textLo,
              letterSpacing: "0.1em",
            }}
          >
            {unit}
          </span>
        )}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// SerialNum — small label like "№ 0241" or "SN-A-014"
function SerialNum({ children, style = {} }) {
  return (
    <span
      style={{
        fontFamily: W.mono,
        fontSize: 9.5,
        letterSpacing: "0.22em",
        color: W.textLo,
        textTransform: "uppercase",
        ...style,
      }}
    >
      {children}
    </span>
  );
}

// ─────────────────────────────────────────────────────────────
// PrioTag — A/B/C priority. A = gold, B = brushed steel, C = engraved void.
function PrioTag({ p = "A" }) {
  const isA = p === "A",
    isB = p === "B";
  const bg = isA
    ? brushedGold({ intensity: 1 })
    : isB
      ? "linear-gradient(180deg, #4a4c52, #2a2b30)"
      : "linear-gradient(180deg, #0d0e10, #06070a)";
  const fg = isA ? W.onAccent : isB ? "#dcdad3" : W.textLo;
  return (
    <div
      style={{
        width: 22,
        height: 22,
        display: "inline-flex",
        alignItems: "center",
        justifyContent: "center",
        background: bg,
        boxShadow: isA
          ? `inset 0 1px 0 rgba(${W.hiRGB},0.5), inset 0 -1px 1px rgba(0,0,0,0.55), 0 0 0 1px rgba(0,0,0,0.5)`
          : "inset 0 1px 0 rgba(255,255,255,0.06), inset 0 -1px 0 rgba(0,0,0,0.6), 0 0 0 1px rgba(0,0,0,0.5)",
        fontFamily: W.mono,
        fontSize: 11,
        fontWeight: 600,
        color: fg,
        letterSpacing: "0",
      }}
    >
      {p}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// Checkbox — engraved square with gold etched check
function WCheck({ checked = false, onChange, size = 22 }) {
  return (
    <button
      onClick={onChange}
      style={{
        width: size,
        height: size,
        padding: 0,
        border: 0,
        cursor: "pointer",
        background: checked
          ? brushedGold({ intensity: 1 })
          : "linear-gradient(180deg, #06070a, #0e0f12)",
        boxShadow: checked
          ? `inset 0 1px 0 rgba(${W.hiRGB},0.5), inset 0 -1px 1px rgba(0,0,0,0.6), 0 0 0 1px rgba(0,0,0,0.7)`
          : "inset 0 1px 2px rgba(0,0,0,0.85), inset 0 -1px 0 rgba(255,255,255,0.04), 0 0 0 1px rgba(0,0,0,0.6)",
        position: "relative",
      }}
    >
      {checked && (
        <svg
          width={size * 0.55}
          height={size * 0.55}
          viewBox="0 0 12 12"
          style={{
            position: "absolute",
            left: "50%",
            top: "50%",
            transform: "translate(-50%,-50%)",
          }}
        >
          <path
            d="M2 6.5L4.8 9.2 10 3.5"
            stroke={W.onAccent}
            strokeWidth="2"
            fill="none"
            strokeLinecap="square"
            strokeLinejoin="miter"
          />
        </svg>
      )}
    </button>
  );
}

// ─────────────────────────────────────────────────────────────
// WToggle — chunky engraved toggle (heavier than iOS default)
function WToggle({ on, onChange }) {
  return (
    <button
      onClick={onChange}
      style={{
        width: 44,
        height: 24,
        padding: 2,
        border: 0,
        cursor: "pointer",
        background: on
          ? `linear-gradient(180deg, ${W.accentDk}, ${W.onAccent})`
          : "linear-gradient(180deg, #06070a, #101013)",
        boxShadow:
          "inset 0 1px 2px rgba(0,0,0,0.8), 0 0 0 1px rgba(0,0,0,0.7), inset 0 -1px 0 rgba(255,255,255,0.04)",
        position: "relative",
        display: "flex",
        alignItems: "center",
      }}
    >
      <div
        style={{
          width: 18,
          height: 18,
          background: on
            ? brushedGold({ intensity: 1 })
            : "linear-gradient(180deg, #4a4c52, #2a2b30)",
          transform: `translateX(${on ? 20 : 0}px)`,
          transition:
            "transform 0.2s cubic-bezier(.4,1.4,.4,1), background 0.2s",
          boxShadow:
            "inset 0 1px 0 rgba(255,255,255,0.2), inset 0 -1px 1px rgba(0,0,0,0.5), 0 1px 2px rgba(0,0,0,0.5)",
        }}
      />
    </button>
  );
}

// ─────────────────────────────────────────────────────────────
// WCapsule — frosted graphite pill button.
// Three variants — primary (slightly lighter, white text), default (subdued),
// ghost (outline only). Pair with an optional `label` above for the IOST-style
// meta caption (e.g. "ENTER STRICT MODE" → button "LOCK & FOCUS").
function WCapsule({
  children,
  onClick,
  label,
  hint,
  variant = "default",
  size = "md",
  leading,
  trailing,
  style = {},
  fullWidth = false,
}) {
  const dims = {
    sm: { padY: 7, padX: 16, font: 10, gap: 8 },
    md: { padY: 10, padX: 22, font: 11, gap: 9 },
    lg: { padY: 13, padX: 30, font: 12, gap: 11 },
  }[size];

  const fills = {
    primary: {
      background: `linear-gradient(180deg, rgba(${W.midRGB},0.04) 0%, rgba(0,0,0,0.45) 100%)`,
      border: `0.5px solid rgba(${W.midRGB},0.7)`,
      boxShadow: `inset 0 0 14px rgba(${W.midRGB},0.07)`,
      color: W.accentHi,
    },
    default: {
      background: "transparent",
      border: "0.5px solid rgba(255,255,255,0.16)",
      boxShadow: "none",
      color: W.text,
    },
    ghost: {
      background: "transparent",
      border: "0.5px solid rgba(255,255,255,0.10)",
      boxShadow: "none",
      color: "rgba(232,230,224,0.55)",
    },
  }[variant];

  const wrap = {
    display: fullWidth ? "flex" : "inline-flex",
    flexDirection: "column",
    alignItems: "center",
    gap: 10,
    width: fullWidth ? "100%" : undefined,
  };

  return (
    <div style={wrap}>
      {label && (
        <div
          style={{
            fontFamily: W.mono,
            fontSize: 9,
            letterSpacing: "0.24em",
            color: W.textLo,
            textTransform: "uppercase",
            fontWeight: 400,
          }}
        >
          {label}
        </div>
      )}
      <button
        onClick={onClick}
        style={{
          padding: `${dims.padY}px ${dims.padX}px`,
          borderRadius: 9999,
          cursor: "pointer",
          fontFamily: W.mono,
          fontSize: dims.font,
          fontWeight: 500,
          letterSpacing: "0.22em",
          textTransform: "uppercase",
          display: "inline-flex",
          alignItems: "center",
          justifyContent: "center",
          gap: dims.gap,
          width: fullWidth ? "100%" : undefined,
          transition: "color .2s, border-color .2s, background .2s",
          ...fills,
          ...style,
        }}
        onMouseEnter={(e) => {
          e.currentTarget.style.filter = "brightness(1.15)";
        }}
        onMouseLeave={(e) => {
          e.currentTarget.style.filter = "none";
        }}
      >
        {leading}
        <span>{children}</span>
        {trailing}
      </button>
      {hint && (
        <div
          style={{
            fontFamily: W.mono,
            fontSize: 9,
            letterSpacing: "0.18em",
            color: W.textXLo,
            textTransform: "uppercase",
          }}
        >
          {hint}
        </div>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// TomatoGlyph — tomato icon using currentColor so the tab bar controls
// inactive (grey) → active (amber) exactly like the other tab icons.
function TomatoGlyph({ size = 22 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none">
      {/* stem */}
      <path d="M12 8C12 5.5 14.5 4 16 3.5" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" opacity="0.6"/>
      {/* leaf */}
      <path d="M12 8C10.5 5.5 8 5 7 6.5C8.5 7.2 10.5 8 12 8Z" fill="currentColor" opacity="0.6"/>
      {/* body */}
      <circle cx="12" cy="15.5" r="7.5" fill="currentColor"/>
      {/* inner highlight */}
      <path d="M8.5 12C7.5 13 7 14.5 7.5 16.5" stroke="rgba(0,0,0,0.18)" strokeWidth="1.2" strokeLinecap="round"/>
    </svg>
  );
}

// ─────────────────────────────────────────────────────────────
// WModeToggle — 3-icon tab bar in a dark rounded container.
// Active tab = solid flat accent fill. No metallic brushing.
function WModeToggle({ mode = "list", onChange, onSettings }) {
  const tabs = [
    {
      id: "list",
      icon: (
        <svg width="22" height="22" viewBox="0 0 22 22">
          <rect x="1" y="1" width="20" height="20" rx="5" fill="currentColor" />
          <path
            d="M5.5 11.5L9 15L16.5 7.5"
            stroke={W.void}
            strokeWidth="2.2"
            strokeLinecap="round"
            strokeLinejoin="round"
            fill="none"
          />
        </svg>
      ),
    },
    {
      id: "goals",
      icon: (
        <svg width="22" height="22" viewBox="0 0 22 22">
          <circle cx="11" cy="11" r="10" fill="currentColor" />
          <circle cx="11" cy="11" r="6.5" fill="rgba(0,0,0,0.55)" />
          <circle cx="11" cy="11" r="3" fill="currentColor" />
        </svg>
      ),
    },
    {
      id: "pomodoro",
      icon: <TomatoGlyph size={22} />,
    },
  ];

  return (
    <div
      style={{
        display: "flex",
        justifyContent: "center",
        padding: "12px 0 30px",
        background:
          "linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.6) 60%, rgba(0,0,0,0.92) 100%)",
        position: "relative",
        zIndex: 5,
      }}
    >
      <div
        style={{
          display: "inline-flex",
          gap: 4,
          background: "rgba(10,10,12,0.97)",
          borderRadius: 9999,
          padding: "5px",
          border: "0.5px solid rgba(255,255,255,0.09)",
          boxShadow: "0 4px 24px rgba(0,0,0,0.6)",
        }}
      >
        {tabs.map((tab) => {
          const on = mode === tab.id;
          return (
            <button
              key={tab.id}
              onClick={() => onChange && onChange(tab.id)}
              style={{
                width: 66,
                height: 46,
                borderRadius: 9999,
                border: 0,
                background: "transparent",
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
                cursor: "pointer",
              }}
            >
              <div
                style={{
                  width: 505,
                  height: 55,
                  borderRadius: 9999,
                  background: on ? "rgba(0,0,0,0.28)" : "transparent",
                  display: "flex",
                  alignItems: "center",
                  justifyContent: "center",
                  color: on ? W.accentHi : "rgba(255,255,255,0.22)",
                  transition: "background .2s, color .2s",
                }}
              >
                {tab.icon}
              </div>
            </button>
          );
        })}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// WCategoryHeader — top header showing the current filter, with a
// chevron-down. Tapping (or pulling down on the screen) opens the sheet.
function WCategoryHeader({ title, count, onOpen, sheetOpen }) {
  return (
    <button
      onClick={onOpen}
      style={{
        width: "100%",
        padding: "8px 24px 6px",
        border: 0,
        background: "transparent",
        cursor: "pointer",
        display: "flex",
        alignItems: "center",
        justifyContent: "space-between",
        fontFamily: W.mono,
      }}
    >
      <div style={{ display: "flex", alignItems: "baseline", gap: 8 }}>
        <span
          style={{
            fontFamily: W.display,
            fontSize: 17,
            fontWeight: 600,
            color: W.textHi,
            letterSpacing: "-0.005em",
          }}
        >
          {title}
        </span>
        <svg
          width="11"
          height="7"
          viewBox="0 0 11 7"
          style={{
            transform: sheetOpen ? "rotate(180deg)" : "none",
            transition: "transform .25s",
          }}
        >
          <path
            d="M1 1L5.5 5.5 10 1"
            stroke={W.textLo}
            strokeWidth="1.4"
            fill="none"
            strokeLinecap="round"
            strokeLinejoin="round"
          />
        </svg>
      </div>
      {count !== undefined && (
        <span
          style={{
            fontFamily: W.mono,
            fontSize: 11,
            color: W.textLo,
            letterSpacing: "0.12em",
            fontVariantNumeric: "tabular-nums",
          }}
        >
          {String(count).padStart(2, "0")}
        </span>
      )}
    </button>
  );
}

// ─────────────────────────────────────────────────────────────
// WCategorySheet — pull-down drawer with category list. The host owns
// open/close state; this just renders the visual. Drag handle is the bar
// across the top — also clickable to dismiss. The whole sheet is
// translucent and sits over a scrim that darkens the underlying content.
function WCategorySheet({
  open,
  onClose,
  sectionLabel,
  items = [],
  activeId,
  onPick,
  hint,
  addLabel,
  onAdd,
}) {
  return (
    <div
      style={{
        position: "absolute",
        inset: 0,
        zIndex: 30,
        pointerEvents: open ? "auto" : "none",
      }}
    >
      {/* Scrim */}
      <div
        onClick={onClose}
        style={{
          position: "absolute",
          inset: 0,
          background: "rgba(0,0,0,0.55)",
          backdropFilter: "blur(2px)",
          WebkitBackdropFilter: "blur(2px)",
          opacity: open ? 1 : 0,
          transition: "opacity .25s",
        }}
      />
      {/* Sheet */}
      <div
        style={{
          position: "absolute",
          top: 0,
          left: 0,
          right: 0,
          background:
            "linear-gradient(180deg, rgba(20,21,26,0.96) 0%, rgba(8,9,12,0.96) 100%)",
          borderBottomLeftRadius: 24,
          borderBottomRightRadius: 24,
          boxShadow:
            "0 24px 60px rgba(0,0,0,0.7), inset 0 -1px 0 rgba(255,255,255,0.05)",
          WebkitBackdropFilter: "blur(20px) saturate(140%)",
          backdropFilter: "blur(20px) saturate(140%)",
          transform: open ? "translateY(0)" : "translateY(-100%)",
          transition: "transform .35s cubic-bezier(.25,.85,.3,1)",
          paddingTop: 50,
          paddingBottom: 18,
        }}
      >
        {/* drag handle */}
        <div
          onClick={onClose}
          style={{
            position: "absolute",
            top: 56,
            left: "50%",
            transform: "translateX(-50%)",
            width: 40,
            height: 4,
            borderRadius: 4,
            background: "rgba(255,255,255,0.18)",
            cursor: "pointer",
          }}
        />
        <div style={{ padding: "22px 24px 12px" }}>
          <SerialNum>{sectionLabel}</SerialNum>
        </div>
        <div
          style={{
            padding: "0 12px",
            display: "flex",
            flexDirection: "column",
          }}
        >
          {items.map((it) => {
            const on = activeId === it.id;
            return (
              <button
                key={it.id}
                onClick={() => {
                  onPick && onPick(it.id);
                  onClose && onClose();
                }}
                style={{
                  display: "flex",
                  alignItems: "center",
                  gap: 14,
                  padding: "14px 14px",
                  border: 0,
                  background: on ? "rgba(255,255,255,0.04)" : "transparent",
                  cursor: "pointer",
                  textAlign: "left",
                  borderRadius: 6,
                  transition: "background .15s",
                }}
              >
                {/* Glyph */}
                <div
                  style={{
                    width: 28,
                    height: 28,
                    flexShrink: 0,
                    display: "flex",
                    alignItems: "center",
                    justifyContent: "center",
                    background: on
                      ? brushedAccent({ intensity: 0.85 })
                      : "rgba(255,255,255,0.04)",
                    boxShadow: on
                      ? `inset 0 1px 0 rgba(${W.hiRGB},0.4), 0 0 0 1px rgba(0,0,0,0.6)`
                      : "inset 0 1px 0 rgba(255,255,255,0.04), 0 0 0 1px rgba(0,0,0,0.5)",
                    color: on ? W.onAccent : W.textLo,
                  }}
                >
                  {it.glyph}
                </div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div
                    style={{
                      fontFamily: W.display,
                      fontSize: 16,
                      fontWeight: 500,
                      color: on ? W.textHi : W.text,
                      letterSpacing: "-0.005em",
                    }}
                  >
                    {it.label}
                  </div>
                  {it.subtitle && (
                    <div
                      style={{
                        fontFamily: W.mono,
                        fontSize: 9.5,
                        color: W.textLo,
                        marginTop: 2,
                        letterSpacing: "0.16em",
                      }}
                    >
                      {it.subtitle.toUpperCase()}
                    </div>
                  )}
                </div>
                {it.count !== undefined && (
                  <span
                    style={{
                      fontFamily: W.mono,
                      fontSize: 13,
                      color: on ? W.accentHi : W.textLo,
                      fontVariantNumeric: "tabular-nums",
                      letterSpacing: "0.05em",
                    }}
                  >
                    {String(it.count).padStart(2, "0")}
                  </span>
                )}
              </button>
            );
          })}
        </div>
        {addLabel && (
          <div style={{ padding: "6px 12px 0" }}>
            <button
              onClick={onAdd}
              style={{
                width: "100%",
                padding: "14px",
                border: "0.5px dashed rgba(255,255,255,0.18)",
                background: "transparent",
                borderRadius: 6,
                fontFamily: W.mono,
                fontSize: 11,
                color: W.textLo,
                letterSpacing: "0.18em",
                cursor: "pointer",
                textTransform: "uppercase",
              }}
            >
              {addLabel}
            </button>
          </div>
        )}
        {hint && (
          <div style={{ padding: "14px 24px 4px" }}>
            <SerialNum style={{ color: W.textXLo, fontSize: 9 }}>
              {hint}
            </SerialNum>
          </div>
        )}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// WSegmentBar — horizontal swipeable pill bar at top of the screen.
// List mode: fixed segments (已過期/今天/未來七天/蒐集箱).
// Goals mode: user-defined categories + an "add" tail pill.
function WSegmentBar({ items, activeId, onPick, onAdd, addLabel }) {
  const scrollRef = React.useRef(null);
  return (
    <div
      ref={scrollRef}
      style={{
        overflowX: "auto",
        overflowY: "hidden",
        WebkitOverflowScrolling: "touch",
        scrollbarWidth: "none",
        msOverflowStyle: "none",
        padding: "6px 0 10px",
      }}
    >
      <style>{`[data-segbar]::-webkit-scrollbar{display:none}`}</style>
      <div
        data-segbar
        style={{
          display: "inline-flex",
          gap: 22,
          padding: "0 22px",
          whiteSpace: "nowrap",
          alignItems: "baseline",
        }}
      >
        {items.map((it) => {
          const on = activeId === it.id;
          return (
            <button
              key={it.id}
              onClick={() => onPick && onPick(it.id)}
              style={{
                padding: on ? "5px 14px" : "5px 4px",
                border: 0,
                cursor: "pointer",
                background: on ? W.accentHi : "transparent",
                borderRadius: 9999,
                fontFamily: W.display,
                fontSize: 14,
                fontWeight: on ? 600 : 400,
                letterSpacing: "0.01em",
                color: on ? W.onAccent : "rgba(232,230,224,0.45)",
                transition: "color .2s, background .2s, padding .2s",
                display: "inline-flex",
                alignItems: "center",
                gap: 5,
                boxShadow: on ? "0 2px 6px rgba(0,0,0,0.3)" : "none",
              }}
            >
              <span>{it.label}</span>
              {it.count !== undefined && it.count > 0 && (
                <span
                  style={{
                    fontFamily: W.mono,
                    fontSize: 9.5,
                    color: on ? "rgba(26,19,5,0.65)" : "rgba(232,230,224,0.28)",
                    fontVariantNumeric: "tabular-nums",
                    letterSpacing: "0.04em",
                  }}
                >
                  {it.count}
                </span>
              )}
            </button>
          );
        })}
        {addLabel && (
          <button
            onClick={onAdd}
            style={{
              padding: "4px 0 6px",
              border: 0,
              cursor: "pointer",
              background: "transparent",
              fontFamily: W.display,
              fontSize: 14,
              fontWeight: 400,
              color: "rgba(232,230,224,0.3)",
            }}
          >
            ＋
          </button>
        )}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// WDivider — hairline rule
function WDivider({ style = {} }) {
  return (
    <div
      style={{
        height: 1,
        background:
          "linear-gradient(90deg, transparent, rgba(255,255,255,0.08) 20%, rgba(255,255,255,0.08) 80%, transparent)",
        boxShadow: "0 1px 0 rgba(0,0,0,0.6)",
        ...style,
      }}
    />
  );
}

// Status bar replacement for our dark frames — wrapper that sets time + style
function WStatusBar({ time = "04:41" }) {
  return (
    <div
      style={{
        display: "flex",
        alignItems: "center",
        justifyContent: "space-between",
        padding: "17px 30px 0",
        height: 50,
        position: "relative",
        zIndex: 20,
        fontFamily: W.mono,
        fontSize: 13,
        fontWeight: 500,
        color: W.textHi,
        letterSpacing: "0.04em",
        fontVariantNumeric: "tabular-nums",
      }}
    >
      <span>{time}</span>
      <span style={{ width: 110 }} />
      {/* island clearance */}
      <div style={{ display: "flex", gap: 5, alignItems: "center" }}>
        {/* signal */}
        <svg width="17" height="11" viewBox="0 0 17 11">
          {[2.5, 5, 7.5, 10].map((h, i) => (
            <rect
              key={i}
              x={i * 4}
              y={11 - h}
              width="3"
              height={h}
              rx="0.5"
              fill={W.text}
            />
          ))}
        </svg>
        {/* battery */}
        <div style={{ width: 24, height: 11, position: "relative" }}>
          <div
            style={{
              position: "absolute",
              inset: 0,
              border: `1px solid ${W.textLo}`,
              borderRadius: 2.5,
            }}
          />
          <div
            style={{
              position: "absolute",
              left: 1.5,
              top: 1.5,
              bottom: 1.5,
              width: 16,
              background: W.text,
              borderRadius: 1,
            }}
          />
          <div
            style={{
              position: "absolute",
              right: -3,
              top: 3,
              width: 2,
              height: 5,
              background: W.textLo,
              borderRadius: 1,
            }}
          />
        </div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// WBottomNav — bottom navigation, engraved tabs
function WBottomNav({ active = "list", onChange }) {
  const items = [
    {
      id: "list",
      label: "LEDGER",
      glyph: (
        <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
          <rect
            x="3"
            y="3"
            width="14"
            height="14"
            stroke="currentColor"
            strokeWidth="1.2"
          />
          <line
            x1="3"
            y1="8"
            x2="17"
            y2="8"
            stroke="currentColor"
            strokeWidth="1.2"
          />
          <line
            x1="3"
            y1="13"
            x2="17"
            y2="13"
            stroke="currentColor"
            strokeWidth="1.2"
          />
        </svg>
      ),
    },
    {
      id: "goals",
      label: "AXES",
      glyph: (
        <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
          <line
            x1="3"
            y1="17"
            x2="17"
            y2="17"
            stroke="currentColor"
            strokeWidth="1.2"
          />
          <rect x="4.5" y="11" width="3" height="6" fill="currentColor" />
          <rect x="8.5" y="7" width="3" height="10" fill="currentColor" />
          <rect x="12.5" y="3" width="3" height="14" fill="currentColor" />
        </svg>
      ),
    },
    {
      id: "identity",
      label: "WITNESS",
      glyph: (
        <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
          <circle
            cx="10"
            cy="10"
            r="7"
            stroke="currentColor"
            strokeWidth="1.2"
          />
          <circle cx="10" cy="10" r="2.5" fill="currentColor" />
        </svg>
      ),
    },
    {
      id: "settings",
      label: "RECORD",
      glyph: (
        <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
          <line
            x1="4"
            y1="5"
            x2="16"
            y2="5"
            stroke="currentColor"
            strokeWidth="1.2"
          />
          <line
            x1="4"
            y1="10"
            x2="16"
            y2="10"
            stroke="currentColor"
            strokeWidth="1.2"
          />
          <line
            x1="4"
            y1="15"
            x2="12"
            y2="15"
            stroke="currentColor"
            strokeWidth="1.2"
          />
        </svg>
      ),
    },
  ];
  return (
    <div
      style={{
        display: "flex",
        background: hairlineMetal({
          base: "#0d0e11",
          density: 1,
          intensity: 0.5,
        }),
        borderTop: "1px solid rgba(0,0,0,0.8)",
        boxShadow:
          "inset 0 1px 0 rgba(255,255,255,0.05), 0 -2px 8px rgba(0,0,0,0.5)",
        paddingBottom: 22,
        position: "relative",
        zIndex: 5,
      }}
    >
      {items.map((it) => {
        const on = active === it.id;
        return (
          <button
            key={it.id}
            onClick={() => onChange && onChange(it.id)}
            style={{
              flex: 1,
              border: 0,
              background: "transparent",
              cursor: "pointer",
              padding: "12px 0 8px",
              display: "flex",
              flexDirection: "column",
              alignItems: "center",
              gap: 5,
              color: on ? W.goldHi : W.textLo,
              position: "relative",
            }}
          >
            {on && (
              <div
                style={{
                  position: "absolute",
                  top: 0,
                  left: "30%",
                  right: "30%",
                  height: 1.5,
                  background: brushedGold({ intensity: 1 }),
                  boxShadow: `0 0 6px rgba(${W.midRGB},0.4)`,
                }}
              />
            )}
            {it.glyph}
            <span
              style={{
                fontFamily: W.mono,
                fontSize: 8.5,
                letterSpacing: "0.22em",
                fontWeight: 500,
              }}
            >
              {it.label}
            </span>
          </button>
        );
      })}
    </div>
  );
}

// Frame keyframes for flash
if (
  typeof document !== "undefined" &&
  !document.getElementById("witness-anim")
) {
  const s = document.createElement("style");
  s.id = "witness-anim";
  s.textContent = `
    @keyframes witness-flash { 0%{opacity:0}20%{opacity:1}100%{opacity:0;transform:translateX(40%)} }
    @keyframes witness-pulse { 0%,100%{opacity:0.6}50%{opacity:1} }
    @keyframes witness-breathe { 0%,100%{transform:scale(1);opacity:0.55} 50%{transform:scale(1.04);opacity:0.85} }
    @keyframes witness-engrave { from{opacity:0;transform:translateY(2px)} to{opacity:1;transform:none} }
    @keyframes witness-tick { 0%,100%{opacity:0.5}50%{opacity:1} }
    @keyframes sugg-in { from{opacity:0;transform:translateY(-6px) scale(0.97)} to{opacity:1;transform:translateY(0) scale(1)} }
  `;
  document.head.appendChild(s);
}

Object.assign(window, {
  WPanel,
  WInset,
  IdentityAxis,
  MonoStat,
  SerialNum,
  PrioTag,
  WCheck,
  WToggle,
  WCapsule,
  TomatoGlyph,
  WModeToggle,
  WCategoryHeader,
  WCategorySheet,
  WSegmentBar,
  WDivider,
  WStatusBar,
  WBottomNav,
});
