// SiteChrome — top navigation (with DE/EN/CS switcher) + dark footer.
//
// Kantorszugang: der eine benannte Weg für Roy. Ohne Anmeldung führt er ins
// Portal; ist er angemeldet, schaltet derselbe Platz das Bearbeiten der Texte
// ein. Bewusst SICHTBAR und benannt — ein versteckter Zugang (früher die
// Jahreszahl » 2026 «) war ein Fehler: der Screenreader las » Verwaltung «,
// das Auge sah 2026. Und bewusst im Haus-Ton der Fußzeile: Messing-Haarlinie
// auf dunklem Grund, dieselbe Schrift, dieselbe Zeilenhöhe wie die
// Rechtslinks daneben — ein Knopf, der nicht wie ein Fremdkörper sitzt.
// Reads design-system components from the global namespace.
const NS = window.RoyHeyneDesignSystem_df1161;

// Shared responsive hook — every screen may read it. Mobile = ≤768px.
function useIsMobile(bp) {
  const q = bp || 768;
  const [m, setM] = React.useState(typeof window !== 'undefined' && window.innerWidth <= q);
  React.useEffect(() => {
    const on = () => setM(window.innerWidth <= q);
    on(); window.addEventListener('resize', on);
    return () => window.removeEventListener('resize', on);
  }, [q]);
  return m;
}
window.useIsMobile = useIsMobile;

function TopNav({ current, onNav, lang, onLang, overDark, t }) {
  // Apple-schlanke Kopfzeile: DESKTOP zeigt sieben Kernziele — inkl. Mediathek
  //   (trägt den Klang-Moment). Edition lebt im Mobil-Menü und im Footer; nichts
  //   geht verloren. „Meine Claviere“ steht auf ausdrücklichen Wunsch in der Leiste.
  const all = [
    ['start', t('nav.start')],
    ['konzerte', t('nav.konzerte')],
    ['orgel', t('nav.orgel')],
    ['instrumente', t('teaser.instr_label')],
    ['vita', t('nav.vita')],
    ['edition', t('nav.edition')],
    ['media', t('nav.media')],
    ['kontakt', t('nav.kontakt')],
  ];
  const primaryKeys = ['start', 'konzerte', 'orgel', 'instrumente', 'vita', 'kontakt'];
  const primary = all.filter(([k]) => primaryKeys.indexOf(k) !== -1);
  const langs = ['de', 'en', 'cs'];
  const langName = { de: 'Deutsch', en: 'English', cs: 'Čeština' };
  const [scrolled, setScrolled] = React.useState(false);
  const isMobile = useIsMobile(1000);  // sieben schlanke Desktop-Punkte passen ab ~1000 px; darunter Drawer (volle Liste)
  const [open, setOpen] = React.useState(false);
  const [hidden, setHidden] = React.useState(false);
  React.useEffect(() => {
    let lastY = window.scrollY;
    const onScroll = () => {
      const y = window.scrollY;
      setScrolled(y > 64);
      // Header fährt beim Runterscrollen weg, beim Hochscrollen (oder oben) zurück
      //   — so verdeckt er den großen Konzert-Titel beim Lesen nie (Apple-Muster).
      if (y < 80) setHidden(false);
      else if (y > lastY + 6) setHidden(true);
      else if (y < lastY - 6) setHidden(false);
      lastY = y;
    };
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  React.useEffect(() => { document.body.style.overflow = open ? 'hidden' : ''; return () => { document.body.style.overflow = ''; }; }, [open]);
  React.useEffect(() => { setOpen(false); }, [current]);

  const solid = scrolled || !overDark || (isMobile && open);
  const linkColor = solid ? 'var(--schiefer)' : 'rgba(236,230,216,0.92)';
  const linkActive = solid ? 'var(--tinte)' : 'var(--pergament-text)';
  const logoColor = solid ? 'var(--tinte)' : 'var(--pergament-text)';
  const go = (key) => { setOpen(false); onNav(key); };

  return (
    <React.Fragment>
    <header style={{
      position: 'fixed', top: 0, left: 0, right: 0, zIndex: 30,
      background: solid ? 'rgba(242,238,228,0.86)' : 'transparent',
      backdropFilter: solid ? 'saturate(1.1) blur(10px)' : 'none',
      WebkitBackdropFilter: solid ? 'saturate(1.1) blur(10px)' : 'none',
      borderBottom: solid ? '1px solid var(--border-hairline)' : '1px solid transparent',
      transform: (isMobile && hidden && !open) ? 'translateY(-100%)' : 'translateY(0)',
      transition: 'transform var(--dur-base) var(--ease-standard), background var(--dur-base) var(--ease-standard), border-color var(--dur-base) var(--ease-standard)',
    }}>
      <div style={{
        maxWidth: 'var(--container-wide)', margin: '0 auto', padding: '0 var(--gutter)',
        height: isMobile ? 60 : (solid ? 64 : 76), display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 28,
        transition: 'height var(--dur-base) var(--ease-standard)',
      }}>
        <a href="#" onClick={(e) => { e.preventDefault(); go('start'); }}
          style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: isMobile ? 21 : 24, letterSpacing: '0.01em', whiteSpace: 'nowrap', flex: 'none', color: logoColor, textDecoration: 'none', transition: 'color var(--dur-base) var(--ease-standard)', padding: '10px 0', margin: '-10px 0' }}>
          Roy Heyne
        </a>
        {isMobile ? (
          <button aria-label={open ? 'Menü schließen' : 'Menü öffnen'} aria-expanded={open} onClick={() => setOpen((o) => !o)}
            style={{ width: 44, height: 44, display: 'grid', placeItems: 'center', background: 'none', border: 'none', cursor: 'pointer', color: logoColor, margin: '0 -10px 0 0' }}>
            <svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" aria-hidden="true">
              {open
                ? <React.Fragment><line x1="5" y1="5" x2="19" y2="19" /><line x1="19" y1="5" x2="5" y2="19" /></React.Fragment>
                : <React.Fragment><line x1="3" y1="7" x2="21" y2="7" /><line x1="3" y1="12" x2="21" y2="12" /><line x1="3" y1="17" x2="21" y2="17" /></React.Fragment>}
            </svg>
          </button>
        ) : (
          <nav style={{ display: 'flex', alignItems: 'center', gap: 24, flexWrap: 'nowrap' }}>
            {primary.map(([key, label]) => (
              <a key={key} href="#" className="rh-navlink" onClick={(e) => { e.preventDefault(); onNav(key); }}
                style={{
                  fontFamily: 'var(--font-ui)', fontSize: 'var(--fs-15)', fontWeight: 500, whiteSpace: 'nowrap',
                  color: current === key ? linkActive : linkColor,
                  ['--nav-hover']: linkActive,
                  textDecoration: 'none', paddingBottom: 3,
                  borderBottom: current === key ? '1px solid var(--messing)' : '1px solid transparent',
                  transition: 'color var(--dur-base) var(--ease-standard)',
                }}>
                {label}
              </a>
            ))}
            <span style={{ display: 'flex', alignItems: 'center', gap: 2, marginLeft: 8, paddingLeft: 18, borderLeft: `1px solid ${solid ? 'var(--border-hairline)' : 'rgba(236,230,216,0.25)'}` }}>
              {langs.map((l) => (
                <button key={l} onClick={() => onLang(l)} aria-label={`Sprache: ${langName[l]}`} className="rh-navlink"
                  style={{
                    background: 'none', border: 'none', cursor: 'pointer', padding: '4px 6px',
                    fontFamily: 'var(--font-ui)', fontSize: 'var(--fs-12)', letterSpacing: '0.1em', fontWeight: 600,
                    color: lang === l ? (solid ? 'var(--messing-dunkel)' : 'var(--messing)') : (solid ? 'var(--zinn)' : 'rgba(236,230,216,0.78)'),
                    ['--nav-hover']: solid ? 'var(--messing-dunkel)' : 'var(--messing)',
                  }}>
                  {({ de: 'DE', en: 'EN', cs: 'CZ' })[l]}
                </button>
              ))}
            </span>
          </nav>
        )}
      </div>
      </header>
      {isMobile && open && (
        <div style={{ position: 'fixed', top: 60, left: 0, right: 0, bottom: 0, height: 'calc(100dvh - 60px)', background: 'var(--surface-page)', zIndex: 29, overflowY: 'auto', WebkitOverflowScrolling: 'touch', padding: '8px var(--gutter) 40px', borderTop: '1px solid var(--border-hairline)' }}>
          <nav style={{ display: 'flex', flexDirection: 'column' }}>
            {all.map(([key, label]) => (
              <a key={key} href="#" onClick={(e) => { e.preventDefault(); go(key); }}
                style={{ fontFamily: 'var(--font-display)', fontSize: 'var(--fs-24)', fontWeight: 500, color: current === key ? 'var(--messing-dunkel)' : 'var(--text-strong)', textDecoration: 'none', padding: '16px 2px', borderBottom: '1px solid var(--border-hairline)' }}>
                {label}
              </a>
            ))}
          </nav>
          <div style={{ display: 'flex', gap: 8, marginTop: 24 }}>
            {langs.map((l) => (
              <button key={l} onClick={() => { onLang(l); }}
                style={{ flex: 1, padding: '13px 0', borderRadius: 'var(--radius-sm)', border: '1px solid var(--border-hairline)', cursor: 'pointer', fontFamily: 'var(--font-ui)', fontSize: 'var(--fs-14)', fontWeight: 600, letterSpacing: '0.06em', color: lang === l ? 'var(--pergament-text)' : 'var(--schiefer)', background: lang === l ? 'var(--tinte)' : 'transparent' }}>
                {langName[l]}
              </button>
            ))}
          </div>
        </div>
      )}
    </React.Fragment>
  );
}

function Kantorszugang({ t }) {
  const [an, setAn] = React.useState(false);
  React.useEffect(() => {
    // Die Textpflege-Schicht sagt, ob Roy angemeldet ist; sie lädt asynchron
    // (im Netz fragt sie den Server), darum kurz nachfassen statt raten.
    let tot = 0, laeuft = true;
    const pruefen = () => {
      if (!laeuft) return;
      const T = window.RH_TEXT;
      const da = !!(T && T.angemeldet && T.angemeldet() && T.bereit && T.bereit());
      setAn(da);
      if (!da && tot++ < 12) setTimeout(pruefen, 400);
    };
    pruefen();
    return () => { laeuft = false; };
  }, []);
  // Ein Wort in der Zeile — dieselbe Farbe und Größe wie das Copyright, kein
  // Rahmen, keine Füllung. Die Trefferfläche bleibt 44 px hoch (Innenabstand,
  // durch negativen Außenabstand ohne Einfluss auf die Zeilenhöhe).
  const wort = { color: 'inherit', textDecoration: 'none', cursor: 'pointer', display: 'inline-block', padding: '12px 0', margin: '-12px 0', background: 'none', border: 'none', font: 'inherit', ['--nav-hover']: 'var(--nav-hover-on-dark)' };
  if (!an) {
    return (
      <span style={{ display: 'inline-flex', alignItems: 'baseline', gap: 6 }}>
        <span aria-hidden="true">·</span>
        <a href="/verwaltung/index.html" className="rh-navlink" style={wort}>{t.f({ de: 'Anmelden', en: 'Sign in', cs: 'Přihlásit se' })}</a>
      </span>
    );
  }
  return (
    <span style={{ display: 'inline-flex', alignItems: 'baseline', gap: 6, flexWrap: 'wrap' }}>
      <span aria-hidden="true">·</span>
      <button type="button" className="rh-navlink" style={Object.assign({}, wort, { color: 'var(--messing)' })}
        onClick={() => window.RH_TEXT && window.RH_TEXT.einschalten()}>
        {t.f({ de: '✎ Texte bearbeiten', en: '✎ Edit texts', cs: '✎ Upravit texty' })}
      </button>
      <span aria-hidden="true">·</span>
      <a href="#" className="rh-navlink" style={wort}
        onClick={(e) => { e.preventDefault(); window.RH_TEXT && window.RH_TEXT.abmelden(); }}>
        {t.f({ de: 'Abmelden', en: 'Sign out', cs: 'Odhlásit se' })}
      </a>
    </span>
  );
}

function SiteFooter({ onNav, t }) {
  return (
    <footer style={{ background: 'var(--nachtschiefer)', color: 'var(--pergament-text)', marginTop: 0 }}>
      <div style={{ maxWidth: 'var(--container-wide)', margin: '0 auto', padding: '72px var(--gutter) 56px',
        display: 'grid', gridTemplateColumns: '1.4fr 1fr 1fr', gap: 48 }}>
        <div>
          <div style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--fs-28)' }}>Roy Heyne</div>
          <p style={{ color: 'var(--text-on-inverse-muted)', fontSize: 'var(--fs-16)', lineHeight: 1.7, maxWidth: '34ch', marginTop: 12 }}>
            {t('footer.blurb')}
          </p>
        </div>
        <div>
          <div className="rh-label" style={{ color: 'var(--messing)', marginBottom: 16 }}>{t('footer.nav_title')}</div>
          {[['konzerte', t('nav.konzerte')], ['orgel', t('nav.orgel')], ['instrumente', t('teaser.instr_label')], ['vita', t('nav.vita')], ['edition', t('nav.edition')], ['media', t('nav.media')], ['kontakt', t('nav.kontakt')]].map(([k, l]) => (
            <a key={k} href="#" onClick={(e) => { e.preventDefault(); onNav(k); }} className="rh-navlink"
              style={{ display: 'block', color: 'rgba(236,230,216,0.82)', ['--nav-hover']: 'var(--nav-hover-on-dark)', fontFamily: 'var(--font-ui)', fontSize: 'var(--fs-15)', padding: '12px 0', margin: '-7px 0', textDecoration: 'none' }}>{l}</a>
          ))}
        </div>
        <div>
          <div className="rh-label" style={{ color: 'var(--messing)', marginBottom: 16 }}>{t('footer.contact_title')}</div>
          <p style={{ color: 'var(--text-on-inverse-muted)', fontFamily: 'var(--font-ui)', fontSize: 'var(--fs-15)', lineHeight: 1.8, margin: 0 }}>
            {window.RH_STAMM.nameGrad}<br />{window.RH_STAMM.strasse}<br />{window.RH_STAMM.ort}
          </p>
          <div style={{ display: 'flex', gap: 10, marginTop: 20 }}>
            {[['Instagram', 'M12 2.2c3.2 0 3.6 0 4.9.07 1.2.05 1.8.25 2.2.42.6.2 1 .47 1.4.9.43.4.7.8.9 1.4.17.4.37 1 .42 2.2.06 1.3.07 1.7.07 4.9s0 3.6-.07 4.9c-.05 1.2-.25 1.8-.42 2.2-.2.6-.47 1-.9 1.4-.4.43-.8.7-1.4.9-.4.17-1 .37-2.2.42-1.3.06-1.7.07-4.9.07s-3.6 0-4.9-.07c-1.2-.05-1.8-.25-2.2-.42-.6-.2-1-.47-1.4-.9-.43-.4-.7-.8-.9-1.4-.17-.4-.37-1-.42-2.2C2.2 15.6 2.2 15.2 2.2 12s0-3.6.07-4.9c.05-1.2.25-1.8.42-2.2.2-.6.47-1 .9-1.4.4-.43.8-.7 1.4-.9.4-.17 1-.37 2.2-.42C8.4 2.2 8.8 2.2 12 2.2zm0 1.8c-3.1 0-3.5 0-4.7.07-.9.04-1.4.2-1.7.32-.43.17-.74.37-1.06.7-.32.31-.52.62-.7 1.05-.12.3-.28.8-.32 1.7C3.73 8.5 3.7 8.9 3.7 12s0 3.5.07 4.7c.04.9.2 1.4.32 1.7.17.43.37.74.7 1.06.31.32.62.52 1.05.7.3.12.8.28 1.7.32 1.2.06 1.6.07 4.7.07s3.5 0 4.7-.07c.9-.04 1.4-.2 1.7-.32.43-.17.74-.37 1.06-.7.32-.31.52-.62.7-1.05.12-.3.28-.8.32-1.7.06-1.2.07-1.6.07-4.7s0-3.5-.07-4.7c-.04-.9-.2-1.4-.32-1.7a2.8 2.8 0 0 0-.7-1.06 2.8 2.8 0 0 0-1.05-.7c-.3-.12-.8-.28-1.7-.32C15.5 4 15.1 4 12 4zm0 3.1a4.9 4.9 0 1 1 0 9.8 4.9 4.9 0 0 1 0-9.8zm0 1.8a3.1 3.1 0 1 0 0 6.2 3.1 3.1 0 0 0 0-6.2zm5.1-.3a1.15 1.15 0 1 1-2.3 0 1.15 1.15 0 0 1 2.3 0z'], ['YouTube', 'M23.5 6.5a3 3 0 0 0-2.1-2.1C19.5 3.9 12 3.9 12 3.9s-7.5 0-9.4.5A3 3 0 0 0 .5 6.5C0 8.4 0 12 0 12s0 3.6.5 5.5a3 3 0 0 0 2.1 2.1c1.9.5 9.4.5 9.4.5s7.5 0 9.4-.5a3 3 0 0 0 2.1-2.1c.5-1.9.5-5.5.5-5.5s0-3.6-.5-5.5zM9.6 15.6V8.4l6.2 3.6-6.2 3.6z'], ['WhatsApp', 'M12 2a10 10 0 0 0-8.6 15L2 22l5.2-1.4A10 10 0 1 0 12 2zm0 18.2c-1.5 0-3-.4-4.3-1.2l-.3-.2-3 .8.8-2.9-.2-.3A8.2 8.2 0 1 1 12 20.2zm4.6-6.1c-.2-.1-1.5-.7-1.7-.8-.2-.1-.4-.1-.6.1-.2.3-.6.8-.8 1-.1.1-.3.2-.5.1a6.7 6.7 0 0 1-2-1.2 7.5 7.5 0 0 1-1.4-1.7c-.1-.3 0-.4.1-.5l.4-.5.3-.5v-.5c0-.1-.6-1.4-.8-1.9-.2-.5-.4-.4-.6-.4h-.5a1 1 0 0 0-.7.3c-.2.3-.9.9-.9 2.2s.9 2.5 1.1 2.7c.1.2 1.8 2.7 4.3 3.8 1.6.7 2.2.7 3 .6.5 0 1.5-.6 1.7-1.2.2-.6.2-1.1.1-1.2l-.4-.3z'], ['Spotify', 'M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20zm4.6 14.4a.6.6 0 0 1-.9.2c-2.3-1.4-5.2-1.7-8.6-.9a.6.6 0 1 1-.3-1.2c3.7-.9 6.9-.5 9.5 1a.6.6 0 0 1 .3.9zm1.2-2.7a.8.8 0 0 1-1 .3c-2.6-1.6-6.6-2.1-9.7-1.1a.8.8 0 1 1-.5-1.5c3.5-1.1 7.9-.6 10.9 1.2.4.2.5.7.3 1.1zm.1-2.8C14.7 9 9.3 8.8 6.3 9.7a.9.9 0 1 1-.5-1.8c3.5-1 9.4-.8 13 1.3a.9.9 0 1 1-.9 1.6z']].filter(([name]) => !!(window.RH_STAMM.social || {})[name]).map(([name, d]) => (
              <a key={name} href={(window.RH_STAMM.social || {})[name]} aria-label={name} title={name}
                target="_blank" rel="me noopener noreferrer"
                style={{ width: 44, height: 44, display: 'grid', placeItems: 'center', margin: '-3px', color: 'var(--pergament-text)' }}>
                <span style={{ width: 38, height: 38, display: 'grid', placeItems: 'center', border: '1px solid var(--hairline-on-inverse)', borderRadius: 'var(--radius-sm)' }}>
                  <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d={d} /></svg>
                </span>
              </a>
            ))}
          </div>
        </div>
      </div>
      <div style={{ borderTop: '1px solid var(--hairline-on-inverse)' }}>
        <div style={{ maxWidth: 'var(--container-wide)', margin: '0 auto', padding: '20px var(--gutter)',
          display: 'flex', justifyContent: 'space-between', flexWrap: 'wrap', gap: 12, fontFamily: 'var(--font-ui)', fontSize: 'var(--fs-13)', color: 'var(--text-on-inverse-muted)' }}>
          {/* Der Zugang für Roy steht in der Zeile mit dem Copyright — als ruhiges
              Wort, nicht als Knopf. Benannt und lesbar (kein versteckter Link),
              aber ohne jede Betonung: gleiche Farbe, gleiche Größe wie die Zeile. */}
          <span style={{ display: 'inline-flex', alignItems: 'baseline', gap: 6, flexWrap: 'wrap' }}>
            <span>© 2026 Roy Heyne · {t('footer.rights')}</span>
            <Kantorszugang t={t} />
          </span>
          <span style={{ display: 'flex', gap: 22, flexWrap: 'wrap' }}>
            {/* Impressum, Datenschutz, Bildnachweise tragen denselben Hover wie die
                Navigation darüber: gleicher Farbton, nur mehr Präsenz.
                Vorher stand hier `color: inherit` — der Ruhezustand hing damit an
                einem Vorfahren, und der Effekt war geerbt statt definiert.
                Jetzt: eigener Ruheton + der benannte Ziel-Ton für dunklen Grund. */}
            {[['impressum', t('footer.imprint')],
              ['datenschutz', t('footer.privacy')],
              ['bildnachweise', t.f({ de: 'Bildnachweise', en: 'Image credits', cs: 'Obrazové zdroje' })]].map(([key, label]) => (
              <a key={key} href="#" className="rh-navlink"
                onClick={(e) => { e.preventDefault(); onNav(key); }}
                style={{ color: 'var(--text-on-inverse-muted)', ['--nav-hover']: 'var(--nav-hover-on-dark)',
                  textDecoration: 'none', padding: '12px 0', margin: '-12px 0', whiteSpace: 'nowrap' }}>
                {label}
              </a>
            ))}
          </span>
        </div>
      </div>
    </footer>
  );
}

Object.assign(window, { TopNav, SiteFooter });
