// SimpleViews — News, Talks, Service, Awards, Patents.
const XV = window.WINTELAcademicDesignSystem_045d4f;

function NewsItem({ item }) {
  const [open, setOpen] = React.useState(false);
  const hasEmbed = !!item.embed;
  const hasVideo = !!item.video;
  const expandable = hasEmbed || hasVideo;
  return (
    <li style={{ listStyle: 'none', borderBottom: '1px solid var(--border-default)' }}>
      <div
        onClick={expandable ? () => setOpen((v) => !v) : undefined}
        role={expandable ? 'button' : undefined}
        aria-expanded={expandable ? open : undefined}
        style={{ display: 'flex', alignItems: 'flex-start', gap: '1rem', padding: '1rem 0', cursor: expandable ? 'pointer' : 'default' }}>
        <span style={{ flexShrink: 0, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: '2rem', height: '2rem', borderRadius: '50%', background: 'var(--surface-card)', border: '1px solid var(--border-default)', color: 'var(--accent)', marginTop: '0.1rem' }}>
          <i className={item.icon || 'ri-bookmark-line'} style={{ fontSize: 17 }} />
        </span>
        <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--text-xs)', color: 'var(--text-muted)', whiteSpace: 'nowrap', flexShrink: 0, paddingTop: '0.4rem', minWidth: '5.5rem' }}>{item.date}</span>
        <p style={{ margin: 0, flex: 1, fontSize: 'var(--text-base)', color: 'var(--text-primary)', fontWeight: 'var(--weight-light)', lineHeight: 'var(--leading-snug)', textWrap: 'pretty' }}>{item.title}</p>
        {expandable ? (
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: '0.3rem', flexShrink: 0, color: 'var(--text-muted)', paddingTop: '0.1rem' }}>
            {hasVideo ? (
              <i className="ri-youtube-fill" style={{ fontSize: 18, color: '#ff0000' }} />
            ) : (
              <i className="ri-linkedin-box-fill" style={{ fontSize: 18, color: '#0a66c2' }} />
            )}
            <i className="ri-arrow-down-s-line" style={{ fontSize: 20, transform: open ? 'rotate(180deg)' : 'none', transition: 'transform var(--duration-base) var(--ease-standard)' }} />
          </span>
        ) : null}
      </div>
      {expandable && open ? (
        <div style={{ paddingBottom: '1.25rem', display: 'flex', justifyContent: 'center' }}>
          {hasVideo ? (
            <div style={{ width: '100%', maxWidth: '640px', aspectRatio: '16 / 9', borderRadius: 'var(--radius-md)', overflow: 'hidden', border: '1px solid var(--border-default)', background: '#000' }}>
              <iframe src={item.video} title={item.title} frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen loading="lazy"
                style={{ width: '100%', height: '100%', display: 'block', border: 'none' }} />
            </div>
          ) : (
            <iframe src={item.embed} title={item.title} frameBorder="0" allowFullScreen loading="lazy"
              style={{ width: '100%', maxWidth: '504px', height: (item.height || 480) + 'px', border: '1px solid var(--border-default)', borderRadius: 'var(--radius-md)', background: 'var(--surface-card)' }} />
          )}
        </div>
      ) : null}
    </li>
  );
}

function NewsView({ data }) {
  return (
    <main style={{ display: 'flex', flexDirection: 'column', gap: '1.25rem' }}>
      <XV.SectionHeading title="News" />
      <ul style={{ margin: 0, padding: 0, borderTop: '1px solid var(--border-default)' }}>
        {data.news.map((n, i) => <NewsItem key={i} item={n} />)}
      </ul>
    </main>
  );
}

function TalkItem({ t }) {
  const topics = t.tags
    ? t.tags.map((l) => (window.TOPICS || []).find((x) => x.label === l)).filter(Boolean)
    : (window.topicsFor ? window.topicsFor({ t: t.title, v: t.meta }) : []);
  const flag = window.flagForText ? window.flagForText(t.meta) : null;
  return (
    <li style={{ listStyle: 'none', display: 'flex', gap: '0.85rem', alignItems: 'flex-start' }}>
      <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--text-sm)', color: 'var(--text-muted)', flexShrink: 0, paddingTop: '0.15rem', minWidth: '2.75rem' }}>[{t.id}]</span>
      <div style={{ display: 'flex', flexDirection: 'column', gap: '0.3rem' }}>
        <h3 style={{ margin: 0, fontSize: 'var(--text-base)', fontWeight: 'var(--weight-medium)', color: 'var(--text-primary)', lineHeight: 'var(--leading-snug)', textWrap: 'pretty' }}>{t.title}</h3>
        {t.with ? (
          <p style={{ margin: 0, fontSize: 'var(--text-sm)', fontWeight: 'var(--weight-light)', color: 'var(--text-muted)' }}>
            {t.with.split('A. Celik').map((seg, j, arr) => (
              <React.Fragment key={j}>{seg}{j < arr.length - 1 ? <span style={{ fontWeight: 'var(--weight-semibold)', color: 'var(--text-body)' }}>A. Celik</span> : null}</React.Fragment>
            ))}
          </p>
        ) : null}
        <p style={{ margin: 0, fontSize: 'var(--text-base)', fontWeight: 'var(--weight-light)', color: 'var(--text-body)', textWrap: 'pretty' }}>
          {t.meta}{flag ? <span style={{ marginLeft: '0.4rem', fontSize: '1.05em' }}>{flag}</span> : null}
        </p>
        {topics.length ? (
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.35rem', marginTop: '0.1rem' }}>
            {topics.map((tp) => window.TopicTag ? <window.TopicTag key={tp.label} topic={tp} /> : null)}
          </div>
        ) : null}
      </div>
    </li>
  );
}

function talkYear(meta) {
  const m = (meta || '').match(/(20\d{2})/g);
  return m ? m[m.length - 1] : 'Undated';
}

function groupTalksByYear(items) {
  const g = {};
  items.forEach((it) => { const y = talkYear(it.meta); (g[y] = g[y] || []).push(it); });
  return Object.keys(g)
    .sort((a, b) => (a === 'Undated' ? 1 : b === 'Undated' ? -1 : Number(b) - Number(a)))
    .map((y) => ({ year: y, items: g[y] }));
}

// Geography across ALL dissemination: talks (every group) + conference presentations.
function dissemGeo(data) {
  const R = window.resolveCity;
  if (!R) return { countries: [], cities: [] };
  const counts = {}; const cities = {};
  const add = (c) => {
    if (!c) return;
    counts[c.iso] = counts[c.iso] || { iso: c.iso, name: c.country, n: 0 }; counts[c.iso].n += 1;
    cities[c.key] = cities[c.key] || { key: c.key, lon: c.lon, lat: c.lat, country: c.country, n: 0 }; cities[c.key].n += 1;
  };
  (data.talks || []).forEach((grp) => grp.items.forEach((it) => add(R({ v: it.meta }))));
  const P = window.WINTEL_PUBLICATIONS;
  if (P) (P.proceedings || []).forEach((p) => add(R(p)));
  const geo = { countries: Object.values(counts), cities: Object.values(cities) };
  return window.mergeExtraGeo ? window.mergeExtraGeo(geo) : { countries: geo.countries.sort((a, b) => b.n - a.n), cities: geo.cities };
}

const TYPE_SHORT = { 'Invited Talks & Seminars': 'Seminars' };

function DissemStats({ data }) {
  const SB = window.StatBox;
  const geo = React.useMemo(() => dissemGeo(data), [data]);
  const P = window.WINTEL_PUBLICATIONS;
  const confN = P ? (P.proceedings || []).length : 0;
  const byGroup = {};
  (data.talks || []).forEach((g) => { byGroup[g.group] = g.items.length; });
  const total = (data.talks || []).reduce((s, g) => s + g.items.length, 0) + confN;
  return (
    <div style={{ display: 'flex', gap: '0.6rem', flexWrap: 'wrap' }}>
      {SB ? <SB value={total} label="Engagements" /> : null}
      {SB ? <SB value={byGroup['Keynotes'] || 0} label="Keynotes" /> : null}
      {SB ? <SB value={byGroup['Invited Talks & Seminars'] || 0} label="Seminars" /> : null}
      {SB ? <SB value={byGroup['Tutorials'] || 0} label="Tutorials" /> : null}
      {SB ? <SB value={confN} label="Conf. talks" /> : null}
      {SB ? <SB value={geo.countries.length} label="Countries" /> : null}
    </div>
  );
}

function DissemGraphs({ data }) {
  const HBar = window.HBarChart; const WMap = window.WorldMap; const accent = (window.chartAccent ? window.chartAccent() : '#2563eb');
  const geo = React.useMemo(() => dissemGeo(data), [data]);
  const P = window.WINTEL_PUBLICATIONS;
  const confN = P ? (P.proceedings || []).length : 0;
  const typeRows = [
    ...(data.talks || []).map((g) => ({ key: TYPE_SHORT[g.group] || g.group, n: g.items.length })),
    { key: 'Conferences', n: confN },
  ].sort((a, b) => b.n - a.n);
  const countryRows = geo.countries.map((c) => ({ key: c.name, full: c.name, n: c.n }));
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem', marginTop: '1.25rem' }}>
      {WMap ? <WMap countries={geo.countries} cities={geo.cities} title="Dissemination footprint" hint={"city markers \u00b7 country fill intensity = engagements (talks + conferences) there"} /> : null}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '1rem' }}>
        {HBar ? <HBar title="Dissemination by country" hint={"talks + conference presentations"} rows={countryRows} colorFor={() => accent} /> : null}
        {HBar ? <HBar title="Dissemination by format" hint={"engagements by type"} rows={typeRows} colorFor={() => accent} /> : null}
      </div>
    </div>
  );
}

function TalksView({ data }) {
  const ORDER = ['Keynotes', 'Panels', 'Invited Talks & Seminars', 'Tutorials'];
  const LABELS = { 'Invited Talks & Seminars': 'Invited Talks' };
  const tabs = [...data.talks].sort((a, b) => {
    const ia = ORDER.indexOf(a.group); const ib = ORDER.indexOf(b.group);
    return (ia === -1 ? 99 : ia) - (ib === -1 ? 99 : ib);
  }).map((g) => ({ key: g.group, label: LABELS[g.group] || g.group, items: g.items }));
  const [active, setActive] = React.useState(tabs[0].key);
  const [showStats, setShowStats] = React.useState(false);
  const current = tabs.find((t) => t.key === active) || tabs[0];
  const grouped = groupTalksByYear(current.items);

  return (
    <main style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: '1rem', flexWrap: 'wrap' }}>
        <XV.SectionHeading title="Talks & Tutorials" />
        <button onClick={() => setShowStats((v) => !v)} aria-expanded={showStats} aria-label="Toggle analytics"
          style={{ display: 'inline-flex', alignItems: 'center', gap: '0.4rem', padding: '0.4rem 0.75rem', background: showStats ? 'var(--surface-muted)' : 'var(--accent)', border: '1px solid ' + (showStats ? 'var(--border-default)' : 'var(--accent)'), borderRadius: 'var(--radius-full)', cursor: 'pointer', color: showStats ? 'var(--text-primary)' : 'var(--text-inverse, #fff)', font: 'inherit', fontSize: 'var(--text-sm)', fontWeight: 'var(--weight-medium)', whiteSpace: 'nowrap', transition: 'all var(--duration-base) var(--ease-standard)' }}>
          <i className="ri-bar-chart-2-fill" style={{ fontSize: 15 }} />
          <span>{showStats ? 'Hide analytics' : 'Analytics'}</span>
          <i className="ri-arrow-down-s-line dissem-arrow" style={{ fontSize: 16, transform: showStats ? 'rotate(180deg)' : 'none', transition: 'transform var(--duration-base) var(--ease-standard)', animation: showStats ? 'none' : 'dissemBounce 1.4s ease-in-out infinite' }} />
        </button>
      </div>

      <div style={{ borderBottom: '1px solid var(--border-default)', paddingBottom: '1.25rem' }}>
        <DissemStats data={data} />
        {showStats ? <DissemGraphs data={data} /> : null}
      </div>

      <div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.5rem', borderBottom: '1px solid var(--border-default)', paddingBottom: '1rem' }}>
        {tabs.map((t) => (
          <XV.Button key={t.key} size="sm" variant={active === t.key ? 'default' : 'outline'} onClick={() => setActive(t.key)}>
            {t.label}
            <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--text-xs)', opacity: 0.7, marginLeft: '0.1rem' }}>{t.items.length}</span>
          </XV.Button>
        ))}
      </div>

      <div style={{ display: 'flex', flexDirection: 'column', gap: '2.25rem' }}>
        {grouped.map((g) => (
          <section key={g.year} style={{ display: 'flex', flexDirection: 'column', gap: '1.1rem' }}>
            <div style={{ display: 'flex', alignItems: 'baseline', gap: '0.75rem', borderBottom: '1px solid var(--border-default)', paddingBottom: '0.4rem' }}>
              <h2 style={{ margin: 0, fontFamily: 'var(--font-mono)', fontSize: 'var(--text-lg)', fontWeight: 'var(--weight-semibold)', letterSpacing: 'var(--tracking-tight)', color: 'var(--text-primary)' }}>{g.year}</h2>
              <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--text-xs)', color: 'var(--text-muted)' }}>{g.items.length}</span>
            </div>
            <ol style={{ margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: '1.25rem' }}>
              {g.items.map((t, i) => <TalkItem key={i} t={t} />)}
            </ol>
          </section>
        ))}
      </div>
    </main>
  );
}

function SvcSection({ title, count, children }) {
  return (
    <section style={{ display: 'flex', flexDirection: 'column', gap: '1.1rem' }}>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: '0.75rem', borderBottom: '1px solid var(--border-default)', paddingBottom: '0.4rem' }}>
        <h2 style={{ margin: 0, fontSize: 'var(--text-lg)', fontWeight: 'var(--weight-semibold)', letterSpacing: 'var(--tracking-tight)', color: 'var(--text-primary)' }}>{title}</h2>
        {count != null ? <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--text-xs)', color: 'var(--text-muted)' }}>{count}</span> : null}
      </div>
      {children}
    </section>
  );
}

function SvcSubList({ items }) {
  // one nesting level: each item may have `years` and/or `sub`
  return (
    <ul style={{ margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: '0.55rem' }}>
      {items.map((it, i) => (
        <li key={i} style={{ listStyle: 'none' }}>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: '0.75rem', justifyContent: 'space-between' }}>
            <span style={{ fontSize: 'var(--text-base)', fontWeight: 'var(--weight-light)', color: 'var(--text-body)', textWrap: 'pretty' }}>
              <span style={{ color: 'var(--text-muted)', marginRight: '0.5rem' }}>&middot;</span>{it.label}
            </span>
            {it.years ? <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--text-xs)', color: 'var(--text-muted)', flexShrink: 0, whiteSpace: 'nowrap' }}>{it.years}</span> : null}
          </div>
          {it.sub ? (
            <ul style={{ margin: '0.5rem 0 0', padding: 0, paddingLeft: '1.1rem', display: 'flex', flexDirection: 'column', gap: '0.45rem' }}>
              {it.sub.map((s, j) => (
                <li key={j} style={{ listStyle: 'none', display: 'flex', alignItems: 'baseline', gap: '0.75rem', justifyContent: 'space-between' }}>
                  <span style={{ fontSize: 'var(--text-sm)', fontWeight: 'var(--weight-light)', color: 'var(--text-muted)', textWrap: 'pretty' }}>
                    <span style={{ marginRight: '0.5rem' }}>&ndash;</span>{s.label}
                  </span>
                  {s.years ? <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--text-xs)', color: 'var(--text-muted)', flexShrink: 0, whiteSpace: 'nowrap' }}>{s.years}</span> : null}
                </li>
              ))}
            </ul>
          ) : null}
        </li>
      ))}
    </ul>
  );
}

function SvcConfGroup({ g }) {
  const [open, setOpen] = React.useState(false);
  const hasItems = g.items && g.items.length;
  return (
    <li style={{ listStyle: 'none', borderBottom: '1px solid var(--border-default)' }}>
      <div onClick={hasItems ? () => setOpen((v) => !v) : undefined} role={hasItems ? 'button' : undefined} aria-expanded={hasItems ? open : undefined}
        style={{ display: 'flex', alignItems: 'flex-start', gap: '1rem', padding: '0.85rem 0', cursor: hasItems ? 'pointer' : 'default' }}>
        <h3 style={{ margin: 0, flex: 1, fontSize: 'var(--text-base)', fontWeight: 'var(--weight-medium)', color: 'var(--text-primary)', lineHeight: 'var(--leading-snug)', textWrap: 'pretty' }}>{g.conf}</h3>
        {g.years ? <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--text-xs)', color: 'var(--text-muted)', flexShrink: 0, paddingTop: '0.25rem' }}>{g.years}</span> : null}
        {hasItems ? (
          <span style={{ flexShrink: 0, color: 'var(--text-muted)', display: 'inline-flex', alignItems: 'center', gap: '0.4rem', paddingTop: '0.05rem' }}>
            <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--text-xs)' }}>{g.items.length}</span>
            <i className="ri-arrow-down-s-line" style={{ fontSize: 20, transform: open ? 'rotate(180deg)' : 'none', transition: 'transform var(--duration-base) var(--ease-standard)' }} />
          </span>
        ) : null}
      </div>
      {hasItems && open ? <div style={{ padding: '0 0 1.15rem 0.25rem' }}><SvcSubList items={g.items} /></div> : null}
    </li>
  );
}

function ServiceView({ data }) {
  const s = data.service || {};
  return (
    <main style={{ display: 'flex', flexDirection: 'column', gap: '2.5rem' }}>
      <XV.SectionHeading title="Professional Service" />

      <SvcSection title="Editorial Boards" count={(s.editors || []).length}>
        <ul style={{ margin: 0, padding: 0, borderTop: '1px solid var(--border-default)' }}>
          {(s.editors || []).map((e, i) => (
            <li key={i} style={{ listStyle: 'none', borderBottom: '1px solid var(--border-default)', padding: '0.85rem 0', display: 'flex', justifyContent: 'space-between', gap: '1rem', alignItems: 'baseline' }}>
              <span style={{ fontSize: 'var(--text-base)', color: 'var(--text-primary)' }}>
                <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--text-xs)', color: 'var(--text-muted)', marginRight: '0.6rem' }}>Editor</span>{e.venue}
              </span>
              <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--text-sm)', color: 'var(--text-muted)', flexShrink: 0 }}>{e.years}</span>
            </li>
          ))}
        </ul>
      </SvcSection>

      <SvcSection title="PhD Examiner" count={(s.phdExaminer || []).length}>
        <ol style={{ margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
          {(s.phdExaminer || []).map((p, i) => (
            <li key={i} style={{ listStyle: 'none', display: 'flex', gap: '0.85rem', alignItems: 'flex-start' }}>
              <span style={{ color: 'var(--accent)', flexShrink: 0, paddingTop: '0.15rem' }}><i className="ri-user-star-line" style={{ fontSize: 17 }} /></span>
              <div style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem' }}>
                <h3 style={{ margin: 0, fontSize: 'var(--text-base)', fontWeight: 'var(--weight-medium)', color: 'var(--text-primary)', lineHeight: 'var(--leading-snug)' }}>{p.name}</h3>
                <p style={{ margin: 0, fontSize: 'var(--text-sm)', fontWeight: 'var(--weight-light)', color: 'var(--text-muted)' }}>{p.inst} &middot; {p.date}</p>
                <p style={{ margin: '0.1rem 0 0', fontSize: 'var(--text-base)', fontWeight: 'var(--weight-light)', color: 'var(--text-body)', fontStyle: 'italic', textWrap: 'pretty' }}>{p.title}</p>
                {p.supervisors ? <p style={{ margin: 0, fontSize: 'var(--text-sm)', fontWeight: 'var(--weight-light)', color: 'var(--text-muted)' }}>Supervisor(s): {p.supervisors}</p> : null}
              </div>
            </li>
          ))}
        </ol>
      </SvcSection>

      <SvcSection title="Symposium & Workshop Chairing" count={(s.chairing || []).length}>
        <ol style={{ margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: '1.25rem' }}>
          {(s.chairing || []).map((c, i) => (
            <li key={i} style={{ listStyle: 'none', display: 'flex', gap: '0.85rem', alignItems: 'flex-start' }}>
              <span style={{ color: 'var(--accent)', flexShrink: 0, paddingTop: '0.15rem' }}><i className="ri-mic-line" style={{ fontSize: 17 }} /></span>
              <div style={{ display: 'flex', flexDirection: 'column', gap: '0.2rem' }}>
                <h3 style={{ margin: 0, fontSize: 'var(--text-base)', fontWeight: 'var(--weight-medium)', color: 'var(--text-primary)', lineHeight: 'var(--leading-snug)', textWrap: 'pretty' }}>{c.event}</h3>
                <p style={{ margin: 0, fontSize: 'var(--text-base)', fontWeight: 'var(--weight-light)', color: 'var(--text-body)', textWrap: 'pretty' }}>
                  {c.role}
                  {c.url ? (
                    <a href={c.url} target="_blank" rel="noopener" style={{ marginLeft: '0.45rem', color: 'var(--accent)', textDecoration: 'none', whiteSpace: 'nowrap', fontSize: 'var(--text-xs)', fontFamily: 'var(--font-mono)' }}>
                      <i className="ri-external-link-line" style={{ fontSize: 13, verticalAlign: '-1px' }} /> link
                    </a>
                  ) : null}
                </p>
              </div>
            </li>
          ))}
        </ol>
      </SvcSection>

      <SvcSection title="Technical Program Committee" count={(s.tpc || []).length}>
        <ul style={{ margin: 0, padding: 0, borderTop: '1px solid var(--border-default)' }}>
          {(s.tpc || []).map((g, i) => <SvcConfGroup key={i} g={g} />)}
        </ul>
      </SvcSection>

      <SvcSection title="Conference Session Chairing" count={(s.sessionChairing || []).length}>
        <ul style={{ margin: 0, padding: 0, borderTop: '1px solid var(--border-default)' }}>
          {(s.sessionChairing || []).map((g, i) => <SvcConfGroup key={i} g={g} />)}
        </ul>
      </SvcSection>
    </main>
  );
}

const AWARD_ICONS = {
  trophy: 'ri-trophy-line',
  'medal-1': 'ri-medal-line',
  'medal-2': 'ri-medal-line',
  'medal-3': 'ri-medal-line',
  badge: 'ri-award-line',
  award: 'ri-award-line',
};

function AwardMediaTrigger({ a, open, setOpen }) {
  const hasVideo = !!a.video;
  if (!hasVideo && !a.embed) return null;
  return (
    <button type="button" onClick={() => setOpen((v) => !v)} aria-expanded={open}
      style={{ display: 'inline-flex', alignItems: 'center', gap: '0.4rem', background: 'none', border: '1px solid var(--border-default)', borderRadius: 'var(--radius-md)', padding: '0.2rem 0.55rem', cursor: 'pointer', color: 'var(--text-body)', fontSize: 'var(--text-xs)', fontFamily: 'var(--font-mono)', letterSpacing: '0.02em', flexShrink: 0, lineHeight: 1.4 }}>
      {hasVideo ? <i className="ri-youtube-fill" style={{ fontSize: 14, color: '#ff0000' }} /> : <i className="ri-linkedin-box-fill" style={{ fontSize: 14, color: '#0a66c2' }} />}
      {hasVideo ? 'Watch talk' : 'View post'}
      <i className="ri-arrow-down-s-line" style={{ fontSize: 15, transform: open ? 'rotate(180deg)' : 'none', transition: 'transform var(--duration-base) var(--ease-standard)' }} />
    </button>
  );
}

function AwardMediaPanel({ a, open }) {
  const hasVideo = !!a.video;
  if (!open || (!hasVideo && !a.embed)) return null;
  return (
    <div style={{ marginTop: '0.5rem', display: 'flex', justifyContent: 'center' }}>
      {hasVideo ? (
        <div style={{ width: '100%', maxWidth: '640px', aspectRatio: '16 / 9', borderRadius: 'var(--radius-md)', overflow: 'hidden', border: '1px solid var(--border-default)', background: '#000' }}>
          <iframe src={a.video} title={a.title} frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen loading="lazy"
            style={{ width: '100%', height: '100%', display: 'block', border: 'none' }} />
        </div>
      ) : (
        <iframe src={a.embed} title={a.title} frameBorder="0" allowFullScreen loading="lazy"
          style={{ width: '100%', maxWidth: '504px', height: (a.embedHeight || 480) + 'px', border: '1px solid var(--border-default)', borderRadius: 'var(--radius-md)', background: 'var(--surface-card)' }} />
      )}
    </div>
  );
}

function AwardRow({ a }) {
  const [open, setOpen] = React.useState(false);
  const hasMedia = !!(a.video || a.embed);
  // Anchor the media trigger to the last detail line so it sits inline on the right.
  const anchor = a.advisors ? 'advisors' : 'org';
  return (
    <li style={{ listStyle: 'none', display: 'flex', gap: '0.95rem', alignItems: 'flex-start' }}>
      <span style={{ color: 'var(--accent)', flexShrink: 0, paddingTop: '0.1rem', width: '1.5rem', display: 'inline-flex', justifyContent: 'center' }}>
        <i className={AWARD_ICONS[a.icon] || 'ri-award-line'} style={{ fontSize: 20 }} />
      </span>
      <div style={{ display: 'flex', flexDirection: 'column', gap: '0.3rem', flex: 1 }}>
        <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'baseline', gap: '0.6rem' }}>
          {a.place ? (
            <span style={{ display: 'inline-flex', alignItems: 'center', padding: '0.1rem 0.5rem', borderRadius: '999px', background: 'var(--accent)', color: '#fff', fontSize: 'var(--text-xs)', fontWeight: 'var(--weight-semibold)', letterSpacing: '0.02em', flexShrink: 0 }}>{a.place}</span>
          ) : null}
          <h3 style={{ margin: 0, fontSize: 'var(--text-base)', fontWeight: 'var(--weight-medium)', color: 'var(--text-primary)', lineHeight: 'var(--leading-snug)', textWrap: 'pretty' }}>
            {a.title}
            {a.url ? (
              <a href={a.url} target="_blank" rel="noopener" aria-label="Award link" style={{ marginLeft: '0.45rem', color: 'var(--accent)', textDecoration: 'none', whiteSpace: 'nowrap', fontSize: 'var(--text-xs)', fontFamily: 'var(--font-mono)' }}>
                <i className="ri-external-link-line" style={{ fontSize: 13, verticalAlign: '-1px' }} /> link
              </a>
            ) : null}
          </h3>
          <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--text-xs)', color: 'var(--text-muted)', marginLeft: 'auto', flexShrink: 0 }}>{a.year}</span>
        </div>
        {a.org ? (
          <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: '0.65rem' }}>
            <p style={{ margin: 0, fontSize: 'var(--text-base)', fontWeight: 'var(--weight-light)', color: 'var(--text-body)', textWrap: 'pretty' }}>{a.org}</p>
            {hasMedia && anchor === 'org' ? <span style={{ marginLeft: 'auto' }}><AwardMediaTrigger a={a} open={open} setOpen={setOpen} /></span> : null}
          </div>
        ) : null}
        {a.team ? <p style={{ margin: 0, fontSize: 'var(--text-sm)', fontWeight: 'var(--weight-light)', color: 'var(--text-muted)' }}><span style={{ color: 'var(--text-body)' }}>Team:</span> {a.team}</p> : null}
        {a.members ? <p style={{ margin: 0, fontSize: 'var(--text-sm)', fontWeight: 'var(--weight-light)', color: 'var(--text-muted)' }}><span style={{ color: 'var(--text-body)' }}>Members:</span> {a.members}</p> : null}
        {a.advisors ? (
          <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: '0.65rem' }}>
            <p style={{ margin: 0, fontSize: 'var(--text-sm)', fontWeight: 'var(--weight-light)', color: 'var(--text-muted)' }}>
              <span style={{ color: 'var(--text-body)' }}>Advisors:</span>{' '}
              {a.advisors.split('A. Celik').map((seg, j, arr) => (
                <React.Fragment key={j}>{seg}{j < arr.length - 1 ? <span style={{ fontWeight: 'var(--weight-semibold)', color: 'var(--text-primary)' }}>A. Celik</span> : null}</React.Fragment>
              ))}
            </p>
            {hasMedia && anchor === 'advisors' ? <span style={{ marginLeft: 'auto' }}><AwardMediaTrigger a={a} open={open} setOpen={setOpen} /></span> : null}
          </div>
        ) : null}
        <AwardMediaPanel a={a} open={open} />
      </div>
    </li>
  );
}

function AwardsView({ data }) {
  const byYear = (x, y) => parseInt(y.year, 10) - parseInt(x.year, 10);
  const individual = (data.awards || []).filter((a) => a.cat === 'individual').sort(byYear);
  const team = (data.awards || []).filter((a) => a.cat === 'team').sort(byYear);
  return (
    <main style={{ display: 'flex', flexDirection: 'column', gap: '2.5rem' }}>
      <XV.SectionHeading title="Awards & Recognition" />

      {individual.length ? (
        <section style={{ display: 'flex', flexDirection: 'column', gap: '1.25rem' }}>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: '0.75rem', borderBottom: '1px solid var(--border-default)', paddingBottom: '0.4rem' }}>
            <h2 style={{ margin: 0, fontSize: 'var(--text-lg)', fontWeight: 'var(--weight-semibold)', letterSpacing: 'var(--tracking-tight)', color: 'var(--text-primary)' }}>Individual Honors</h2>
            <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--text-xs)', color: 'var(--text-muted)' }}>{individual.length}</span>
          </div>
          <ol style={{ margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: '1.6rem' }}>
            {individual.map((a, i) => <AwardRow key={i} a={a} />)}
          </ol>
        </section>
      ) : null}

      {team.length ? (
        <section style={{ display: 'flex', flexDirection: 'column', gap: '1.25rem' }}>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: '0.75rem', borderBottom: '1px solid var(--border-default)', paddingBottom: '0.4rem' }}>
            <h2 style={{ margin: 0, fontSize: 'var(--text-lg)', fontWeight: 'var(--weight-semibold)', letterSpacing: 'var(--tracking-tight)', color: 'var(--text-primary)' }}>Research Team Awards</h2>
            <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--text-xs)', color: 'var(--text-muted)' }}>{team.length}</span>
          </div>
          <p style={{ margin: 0, fontSize: 'var(--text-sm)', fontWeight: 'var(--weight-light)', color: 'var(--text-muted)', textWrap: 'pretty' }}>Awards earned by mentored students/teams</p>
          <ol style={{ margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: '1.6rem' }}>
            {team.map((a, i) => <AwardRow key={i} a={a} />)}
          </ol>
        </section>
      ) : null}
    </main>
  );
}

function PatentItem({ p }) {
  const topics = (p.tags || []).map((l) => (window.TOPICS || []).find((x) => x.label === l)).filter(Boolean);
  return (
    <li style={{ listStyle: 'none', display: 'flex', gap: '0.85rem' }}>
      <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--text-sm)', color: 'var(--text-muted)', flexShrink: 0, paddingTop: '0.15rem', minWidth: '2.5rem' }}>[{p.id}]</span>
      <div style={{ display: 'flex', flexDirection: 'column', gap: '0.45rem', flex: 1 }}>
        <h3 style={{ margin: 0, fontSize: 'var(--text-base)', fontWeight: 'var(--weight-medium)', color: 'var(--text-primary)', lineHeight: 'var(--leading-snug)', textWrap: 'pretty' }}>{p.title}</h3>
        <p style={{ margin: 0, fontSize: 'var(--text-base)', fontWeight: 'var(--weight-light)', color: 'var(--text-body)' }}>
          {(p.authors || '').split('A. Celik').map((seg, j, arr) => (
            <React.Fragment key={j}>{seg}{j < arr.length - 1 ? <span style={{ fontWeight: 'var(--weight-semibold)', color: 'var(--text-primary)' }}>A. Celik</span> : null}</React.Fragment>
          ))}
        </p>
        <p style={{ margin: 0, fontSize: 'var(--text-base)', fontWeight: 'var(--weight-light)', color: 'var(--text-body)' }}>
          <em>{p.venue}</em>{p.date ? <span> · {p.date}</span> : null}
        </p>
        <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: '0.5rem', marginTop: '0.1rem' }}>
          {p.url ? (
            <XV.Button variant="outline" size="sm" href={p.url} target="_blank" aria-label="Patent link"
              style={{ height: '1.85rem', padding: '0 0.6rem', fontSize: 'var(--text-xs)', fontFamily: 'var(--font-mono)', letterSpacing: '0.03em' }}>
              <i className="ri-external-link-line" style={{ fontSize: 14 }} /> Patent
            </XV.Button>
          ) : null}
          <span style={{ display: 'inline-flex', flexWrap: 'wrap', alignItems: 'center', gap: '0.35rem', marginLeft: p.url ? '0.25rem' : 0 }}>
            {p.assignee ? (
              <span style={{ display: 'inline-flex', alignItems: 'center', fontFamily: 'var(--font-mono)', fontSize: 'var(--text-xs)', fontWeight: 'var(--weight-medium)', letterSpacing: '0.02em', lineHeight: 1, padding: '0.28rem 0.5rem', borderRadius: 'var(--radius-sm)', whiteSpace: 'nowrap', color: 'var(--text-muted)', background: 'var(--surface-muted)', border: '1px solid var(--border-default)' }}>{p.assignee}</span>
            ) : null}
            {topics.map((t) => window.TopicTag ? <window.TopicTag key={t.label} topic={t} /> : null)}
          </span>
        </div>
      </div>
    </li>
  );
}

function PatentsView({ data }) {
  const list = data.patents || [];
  const granted = list.filter((p) => p.url);
  const filed = list.filter((p) => !p.url);
  const Group = ({ title, items }) => items.length ? (
    <section style={{ display: 'flex', flexDirection: 'column', gap: '1.1rem' }}>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: '0.75rem', borderBottom: '1px solid var(--border-default)', paddingBottom: '0.4rem' }}>
        <h2 style={{ margin: 0, fontSize: 'var(--text-lg)', fontWeight: 'var(--weight-semibold)', letterSpacing: 'var(--tracking-tight)', color: 'var(--text-primary)' }}>{title}</h2>
        <span style={{ fontFamily: 'var(--font-mono)', fontSize: 'var(--text-xs)', color: 'var(--text-muted)' }}>{items.length}</span>
      </div>
      <ol style={{ margin: 0, padding: 0, display: 'flex', flexDirection: 'column', gap: '1.6rem' }}>
        {items.map((p, i) => <PatentItem key={i} p={p} />)}
      </ol>
    </section>
  ) : null;
  return (
    <main style={{ display: 'flex', flexDirection: 'column', gap: '2.25rem' }}>
      <XV.SectionHeading title="Patents" />
      {list.length === 0 ? (
        <div style={{ padding: '2.5rem 1rem', textAlign: 'center', color: 'var(--text-muted)', border: '1px dashed var(--border-default)', borderRadius: 'var(--radius-xl)' }}>
          <p style={{ margin: 0, fontSize: 'var(--text-base)' }}>Patent listings coming soon.</p>
        </div>
      ) : (
        <React.Fragment>
          <Group title="Granted" items={granted} />
          <Group title="Filed" items={filed} />
        </React.Fragment>
      )}
    </main>
  );
}

Object.assign(window, { NewsView, NewsItem, TalksView, ServiceView, AwardsView, PatentsView });
