// graphics.jsx — decorative editorial elements.
// All low-key, type-and-line based. No stock illustrations.

/* -------------------- MARQUEE -------------------- */

function Marquee({ items, speed = 60, separator = '✦' }) {
  // items: array of strings; rendered twice for seamless loop
  const seq = [...items, ...items];
  return (
    <div style={{
      width: '100%',
      overflow: 'hidden',
      borderTop: '1px solid var(--rule)',
      borderBottom: '1px solid var(--rule)',
      padding: '18px 0',
      background: 'transparent',
    }}>
      <div style={{
        display: 'flex',
        gap: 40,
        whiteSpace: 'nowrap',
        animation: `mq-scroll ${speed}s linear infinite`,
        width: 'max-content',
      }}>
        {seq.map((it, i) => (
          <span key={i} style={{
            display: 'inline-flex', alignItems: 'center', gap: 40,
            fontFamily: 'var(--serif)',
            fontSize: 'clamp(28px, 4vw, 44px)',
            fontWeight: 400,
            letterSpacing: '-0.01em',
            color: 'var(--accent)',
          }}>
            <span style={{ fontStyle: i % 2 ? 'italic' : 'normal', fontWeight: i % 2 ? 300 : 400 }}>{it}</span>
            <span style={{
              fontSize: 16, color: 'var(--accent)', opacity: 0.55,
              transform: 'translateY(-2px)',
            }}>{separator}</span>
          </span>
        ))}
      </div>
      <style>{`
        @keyframes mq-scroll {
          from { transform: translateX(0); }
          to { transform: translateX(-50%); }
        }
        @media (prefers-reduced-motion: reduce) {
          [style*="mq-scroll"] { animation: none !important; }
        }
      `}</style>
    </div>
  );
}

/* -------------------- BIG SECTION NUMERAL -------------------- */

function BigNumeral({ children, side = 'right', top = 0 }) {
  // Huge faded numeral behind section heading.
  return (
    <div aria-hidden="true" style={{
      position: 'absolute',
      [side]: 0,
      top,
      fontFamily: 'var(--serif)',
      fontSize: 'clamp(180px, 26vw, 360px)',
      lineHeight: 0.85,
      fontWeight: 400,
      fontStyle: 'italic',
      color: 'var(--ink)',
      opacity: 0.05,
      pointerEvents: 'none',
      letterSpacing: '-0.04em',
      userSelect: 'none',
    }}>{children}</div>
  );
}

/* -------------------- STAMP / SEAL -------------------- */

/* -------------------- TICK RULER -------------------- */

function TickRuler({ count = 24, labels = [] }) {
  return (
    <div style={{
      display: 'flex',
      alignItems: 'flex-end',
      width: '100%',
      height: 24,
      gap: 0,
    }}>
      {Array.from({ length: count }, (_, i) => {
        const big = i % 4 === 0;
        return (
          <div key={i} style={{
            flex: 1,
            height: big ? 12 : 6,
            borderRight: '1px solid var(--rule)',
            position: 'relative',
          }}>
            {big && labels[i / 4] && (
              <span style={{
                position: 'absolute',
                bottom: -14, left: 0,
                fontFamily: 'var(--mono)', fontSize: 9, letterSpacing: '0.08em',
                color: 'var(--ink-faint)',
                transform: 'translateX(-2px)',
              }}>{labels[i / 4]}</span>
            )}
          </div>
        );
      })}
    </div>
  );
}

/* -------------------- CROSSHAIR -------------------- */

function Crosshair({ size = 14 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 14 14" style={{ display: 'block' }}>
      <line x1="7" y1="0" x2="7" y2="14" stroke="var(--ink-faint)" strokeWidth="0.5" />
      <line x1="0" y1="7" x2="14" y2="7" stroke="var(--ink-faint)" strokeWidth="0.5" />
      <circle cx="7" cy="7" r="3" stroke="var(--ink-faint)" strokeWidth="0.5" fill="none" />
    </svg>
  );
}

/* -------------------- BIG QUOTE -------------------- */

function BigQuote({ children, attribution }) {
  return (
    <figure style={{ margin: 0, position: 'relative' }}>
      <div aria-hidden="true" style={{
        position: 'absolute',
        left: -8, top: -42,
        fontFamily: 'var(--serif)',
        fontSize: 'clamp(120px, 16vw, 220px)',
        lineHeight: 1,
        color: 'var(--ink)',
        opacity: 0.1,
        pointerEvents: 'none',
        userSelect: 'none',
        fontStyle: 'italic',
      }}>“</div>
      <blockquote style={{
        margin: 0,
        position: 'relative',
        fontFamily: 'var(--serif)',
        fontStyle: 'italic',
        fontWeight: 300,
        fontSize: 'clamp(22px, 3vw, 32px)',
        lineHeight: 1.35,
        letterSpacing: '-0.01em',
        color: 'var(--ink)',
        textWrap: 'pretty',
      }}>{children}</blockquote>
      {attribution && (
        <figcaption style={{
          marginTop: 22,
          fontFamily: 'var(--mono)', fontSize: 11, letterSpacing: '0.12em',
          textTransform: 'uppercase', color: 'var(--ink-faint)',
        }}>— {attribution}</figcaption>
      )}
    </figure>
  );
}

/* -------------------- ITEM GLYPHS -------------------- */

const ItemGlyph = ({ name, size = 36 }) => {
  // Clean rounded icon set (route / audio / chapters / cafes / phone / music).
  // Self-contained palette: sage badge, deep-green stroke, accent fills.
  const box = size * 1.5;
  const bodies = {
    route: (
      <>
        <path d="M48 72 C48 72 29 53 29 38 C29 26.4 37.6 18 48 18 C58.4 18 67 26.4 67 38 C67 53 48 72 48 72 Z" fill="none" stroke="#12382D" strokeWidth="4.6" strokeLinecap="round" strokeLinejoin="round" />
        <circle cx="48" cy="38" r="8.2" fill="#23A66B" />
      </>
    ),
    story: (
      <>
        <path d="M26 52 V45 C26 31.5 35.5 22 48 22 C60.5 22 70 31.5 70 45 V52" fill="none" stroke="#12382D" strokeWidth="4.6" strokeLinecap="round" strokeLinejoin="round" />
        <rect x="22" y="49" width="12" height="24" rx="4.4" fill="#23A66B" stroke="#12382D" strokeWidth="4.2" />
        <rect x="62" y="49" width="12" height="24" rx="4.4" fill="#23A66B" stroke="#12382D" strokeWidth="4.2" />
      </>
    ),
    chapter: (
      <>
        <path d="M22 31 C30 27 39 27.5 48 34 V70 C39.5 64.8 30 63.7 22 68 V31 Z" fill="#DDE8D5" />
        <path d="M74 31 C66 27 57 27.5 48 34 V70 C56.5 64.8 66 63.7 74 68 V31 Z" fill="#DDE8D5" />
        <path d="M22 31 C30 27 39 27.5 48 34 V70 C39.5 64.8 30 63.7 22 68 V31 Z" fill="none" stroke="#12382D" strokeWidth="4.4" strokeLinecap="round" strokeLinejoin="round" />
        <path d="M74 31 C66 27 57 27.5 48 34 V70 C56.5 64.8 66 63.7 74 68 V31 Z" fill="none" stroke="#12382D" strokeWidth="4.4" strokeLinecap="round" strokeLinejoin="round" />
        <path d="M48 34 V70" fill="none" stroke="#12382D" strokeWidth="4" strokeLinecap="round" />
      </>
    ),
    cafe: (
      <>
        <path d="M28 40 H62 V58 C62 67.5 55 73 45 73 H41 C33.5 73 28 67.5 28 60 V40 Z" fill="#23A66B" stroke="#12382D" strokeWidth="4.5" strokeLinecap="round" strokeLinejoin="round" />
        <path d="M62 47 H66 C72 47 76 51 76 57 C76 63 72 67 66 67 H62" fill="none" stroke="#12382D" strokeWidth="4.5" strokeLinecap="round" strokeLinejoin="round" />
        <path d="M40 28 C36.5 32 43.5 34 40 38" fill="none" stroke="#12382D" strokeWidth="4" strokeLinecap="round" />
        <path d="M53 28 C49.5 32 56.5 34 53 38" fill="none" stroke="#12382D" strokeWidth="4" strokeLinecap="round" />
      </>
    ),
    phone: (
      <>
        <rect x="34" y="18" width="28" height="60" rx="9" fill="none" stroke="#12382D" strokeWidth="4.6" strokeLinecap="round" strokeLinejoin="round" />
        <rect x="40" y="29" width="16" height="10" rx="3" fill="#23A66B" />
        <circle cx="48" cy="68" r="2.5" fill="#12382D" />
      </>
    ),
    music: (
      <>
        <path d="M35 56 V31 L67 26 V52" fill="none" stroke="#12382D" strokeWidth="4.6" strokeLinecap="round" strokeLinejoin="round" />
        <circle cx="30" cy="62" r="9" fill="#23A66B" stroke="#12382D" strokeWidth="4.6" />
        <circle cx="62" cy="57" r="9" fill="#23A66B" stroke="#12382D" strokeWidth="4.6" />
      </>
    ),
    forever: (
      <>
        <path d="M38 48 C38 41 33 36 27 36 C21 36 18 41 18 48 C18 55 21 60 27 60 C33 60 36 55 40 48 C44 41 47 36 53 36 C59 36 62 41 62 48 C62 55 59 60 53 60 C47 60 42 55 38 48 Z" fill="none" stroke="#12382D" strokeWidth="4.6" strokeLinecap="round" strokeLinejoin="round" transform="translate(8,0)" />
        <circle cx="48" cy="48" r="5.5" fill="#23A66B" />
      </>
    ),
  };
  return (
    <svg width={box} height={box} viewBox="0 0 96 96" fill="none" style={{ display: 'block' }}>
      <rect x="12" y="12" width="72" height="72" rx="24" fill="#E8EDE0" />
      {bodies[name] || null}
    </svg>
  );
};

/* -------------------- PAPER GRAIN OVERLAY -------------------- */

function PaperGrain() {
  // Subtle fixed grain overlay using SVG turbulence.
  const svg = `
    <svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'>
      <filter id='n'>
        <feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' seed='3' />
        <feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.55 0' />
      </filter>
      <rect width='100%' height='100%' filter='url(#n)' />
    </svg>
  `;
  const url = `url("data:image/svg+xml;utf8,${encodeURIComponent(svg)}")`;
  return (
    <div aria-hidden="true" style={{
      position: 'fixed',
      inset: 0,
      backgroundImage: url,
      opacity: 0.08,
      pointerEvents: 'none',
      mixBlendMode: 'multiply',
      zIndex: 1,
    }} />
  );
}

/* -------------------- ROUTE LINE (timeline) -------------------- */

function RouteDot({ active }) {
  return (
    <div style={{
      width: 12, height: 12, borderRadius: 999,
      background: active ? 'var(--ink)' : 'transparent',
      border: `1px solid var(--ink)`,
      flexShrink: 0,
    }} />
  );
}

Object.assign(window, {
  Marquee, BigNumeral, TickRuler, Crosshair,
  BigQuote, ItemGlyph, PaperGrain, RouteDot,
});
