// Skrrs portal — Columns (コラム) and News (お知らせ): list + article views.
const { Button: CBtn, Badge: CBadge, Tag: CTag } = window.SkrrsDesignSystem_6013e8;

// ── Columns list ────────────────────────────────────────────
const COL_KEYWORDS = ['オフィス移転','賃料相場','原状回復','居抜き','フリーレント','商圏分析','床荷重','用途地域','初期費用','ハイブリッドワーク'];

function ColumnsScreen({ onNav, onOpenColumn }) {
  const D = window.SKRRS_DATA;
  const { isMobile, isTablet } = window.useViewport();
  const [cat, setCat] = React.useState('all');
  const cats = [['all','すべて'],['office','オフィス'],['retail','店舗'],['rnd','教室'],['industrial','倉庫'],['datacenter','工場']];
  const all = D.columns;
  const featured = all[0];
  const list = all.filter(c => cat==='all' || c.tone===cat).filter(c => c.id !== featured.id || cat!=='all');
  const cols = isMobile?1:isTablet?2:2;
  const ranking = all.slice(0,5);

  // ── sidebar widgets ──
  const Sidebar = (
    <aside style={{ display:'flex', flexDirection:'column', gap:'var(--sp-6)' }}>
      {/* popular ranking */}
      <div style={{ border:'1px solid var(--border-subtle)', borderRadius:'var(--r-lg)', overflow:'hidden', background:'var(--surface)' }}>
        <div style={{ display:'flex', alignItems:'center', gap:8, padding:'14px 18px', background:'var(--blue-900)' }}>
          <window.Icon name="star" size={16} fill="currentColor" style={{ color:'var(--blue-300)' }}/>
          <span style={{ font:'700 var(--t-sm)/1 var(--font-display)', color:'#fff' }}>人気の記事</span>
        </div>
        <div style={{ display:'flex', flexDirection:'column' }}>
          {ranking.map((c,i)=>(
            <a key={c.id} onClick={()=>onOpenColumn(c)} style={{ cursor:'pointer', display:'flex', gap:12, alignItems:'flex-start',
              padding:'14px 18px', borderBottom: i<ranking.length-1?'1px solid var(--border-subtle)':'none' }}>
              <span style={{ flex:'none', display:'grid', placeItems:'center', width:26, height:26, borderRadius:'var(--r-sm)',
                background: i<3?'var(--blue-600)':'var(--surface-sunken)', color: i<3?'#fff':'var(--text-muted)',
                font:`700 ${i<3?'var(--t-sm)':'var(--t-xs)'}/1 var(--font-num)` }}>{i+1}</span>
              <div style={{ display:'flex', flexDirection:'column', gap:5, minWidth:0 }}>
                <span style={{ font:'var(--fw-bold) var(--t-xs)/1.5 var(--font-body)', color:'var(--text-strong)',
                  display:'-webkit-box', WebkitLineClamp:2, WebkitBoxOrient:'vertical', overflow:'hidden' }}>{c.title}</span>
                <span style={{ display:'inline-flex', alignItems:'center', gap:7 }}>
                  <CBadge tone={c.tone} size="xs">{c.cat}</CBadge>
                  <span style={{ font:'var(--fw-regular) var(--t-2xs)/1 var(--font-num)', color:'var(--text-faint)' }}>{c.date}</span>
                </span>
              </div>
            </a>
          ))}
        </div>
      </div>

      {/* keywords */}
      <div style={{ border:'1px solid var(--border-subtle)', borderRadius:'var(--r-lg)', padding:'18px', background:'var(--surface)' }}>
        <div style={{ display:'flex', alignItems:'center', gap:8, marginBottom:14 }}>
          <window.Icon name="search" size={15} style={{ color:'var(--blue-600)' }}/>
          <span style={{ font:'700 var(--t-sm)/1 var(--font-display)', color:'var(--text-strong)' }}>キーワード</span>
        </div>
        <div style={{ display:'flex', flexWrap:'wrap', gap:8 }}>
          {COL_KEYWORDS.map(k=>(
            <span key={k} style={{ display:'inline-flex', alignItems:'center', padding:'5px 12px', borderRadius:'var(--r-pill)',
              background:'var(--blue-50)', color:'var(--blue-700)', font:'var(--fw-medium) var(--t-2xs)/1.3 var(--font-body)' }}>#{k}</span>
          ))}
        </div>
      </div>

      {/* CTA */}
      <div style={{ borderRadius:'var(--r-lg)', overflow:'hidden', position:'relative', background:'var(--blue-900)' }}>
        <window.Photo src={window.SKRRS_IMG.consult} alt="" hue="var(--blue-800)" ratio="auto" position="center" style={{ position:'absolute', inset:0, aspectRatio:'auto' }}/>
        <div style={{ position:'absolute', inset:0, background:'linear-gradient(160deg, rgba(7,24,43,0.92), rgba(7,48,75,0.72))' }}/>
        <div style={{ position:'relative', padding:'var(--sp-6)', display:'flex', flexDirection:'column', gap:12 }}>
          <span style={{ font:'600 var(--t-2xs)/1 var(--font-latin)', letterSpacing:'0.14em', textTransform:'uppercase', color:'var(--blue-300)' }}>Consult</span>
          <span style={{ font:'700 var(--t-h4)/1.5 var(--font-display)', color:'#fff' }}>記事を読んで気になったら、まずは無料相談</span>
          <CBtn variant="inverse" full pill iconLeft={<window.Icon name="mail" size={16}/>} onClick={()=>onNav('contact')}>無料で相談する</CBtn>
        </div>
      </div>
    </aside>
  );

  return (
    <main>
      <window.PageHero marker="Column" icon="doc" image={window.SKRRS_IMG.officeReport}
        title="不動産コラム"
        lead="市場トレンド・実務ノウハウ・移転の進め方まで、事業用不動産の意思決定に役立つインサイトをお届けします。"
        crumbs={[{label:'ホーム',route:'home'},{label:'不動産コラム'}]} onNav={onNav} />

      {!(D.release||{}).columns ? (
        <window.Container style={{ paddingTop:'var(--sp-14)', paddingBottom:'var(--sp-20)' }}>
          <window.ComingSoon area="columns" onNav={onNav} />
        </window.Container>
      ) : (
      <window.Container style={{ paddingTop:'var(--sp-10)', paddingBottom: isMobile?'var(--sp-16)':'var(--sp-20)' }}>
        {/* ── Featured / pick up ── */}
        {cat==='all' && (
          <a className="sk-card" onClick={()=>onOpenColumn(featured)} style={{ cursor:'pointer', display:'grid', gridTemplateColumns: isMobile?'1fr':'1.15fr 1fr',
            gap:0, marginBottom:'var(--sp-10)', borderRadius:'var(--r-xl)', overflow:'hidden', border:'1px solid var(--border-subtle)', boxShadow:'var(--shadow-md)', background:'var(--surface)' }}>
            <div style={{ position:'relative' }}>
              <window.Photo src={featured.img} alt={featured.title} hue={`var(--type-${featured.tone})`} ratio={isMobile?'16 / 9':'4 / 3'} icon="doc" eager/>
              <span style={{ position:'absolute', top:14, left:14, display:'inline-flex', alignItems:'center', gap:6, padding:'6px 14px', borderRadius:'var(--r-pill)',
                background:'var(--blue-600)', color:'#fff', font:'700 var(--t-2xs)/1 var(--font-latin)', letterSpacing:'0.12em' }}><window.Icon name="star" size={12} fill="currentColor"/>PICK UP</span>
            </div>
            <div style={{ display:'flex', flexDirection:'column', justifyContent:'center', gap:14, padding: isMobile?'var(--sp-6)':'var(--sp-10)' }}>
              <div style={{ display:'flex', alignItems:'center', gap:10, flexWrap:'wrap' }}>
                <CBadge tone={featured.tone} size="sm">{featured.cat}</CBadge>
                <span style={{ font:'var(--fw-regular) var(--t-2xs)/1 var(--font-num)', color:'var(--text-faint)' }}>{featured.date}</span>
                <span style={{ display:'inline-flex', alignItems:'center', gap:4, font:'var(--fw-regular) var(--t-2xs)/1 var(--font-body)', color:'var(--text-faint)' }}><window.Icon name="clock" size={12}/>{featured.read}</span>
              </div>
              <h2 style={{ margin:0, font:`700 ${isMobile?'var(--t-h3)':'var(--t-h2)'}/1.4 var(--font-display)`, color:'var(--text-strong)' }}>{featured.title}</h2>
              <p style={{ margin:0, font:'var(--fw-regular) var(--t-sm)/1.8 var(--font-body)', color:'var(--text-muted)',
                display:'-webkit-box', WebkitLineClamp:3, WebkitBoxOrient:'vertical', overflow:'hidden' }}>{featured.excerpt}</p>
              <span style={{ display:'inline-flex', alignItems:'center', gap:6, font:'var(--fw-bold) var(--t-sm)/1 var(--font-body)', color:'var(--blue-600)' }}>続きを読む <window.Icon name="arrowR" size={15}/></span>
            </div>
          </a>
        )}

        {/* ── category tabs ── */}
        <div style={{ display:'flex', gap:8, flexWrap:'wrap', marginBottom:'var(--sp-8)' }}>
          {cats.map(([k,l])=>(<CTag key={k} selected={cat===k} onClick={()=>setCat(k)}>{l}</CTag>))}
        </div>

        {/* ── main grid + sidebar ── */}
        <div style={{ display:'grid', gridTemplateColumns: isMobile?'1fr':'minmax(0,1fr) 300px', gap:'var(--sp-8)', alignItems:'start' }}>
          <div style={{ display:'grid', gridTemplateColumns:`repeat(${cols},minmax(0,1fr))`, gap:'var(--sp-6)' }}>
            {list.map(c=>(
              <a key={c.id} className="sk-card" onClick={()=>onOpenColumn(c)} style={{ cursor:'pointer', display:'flex', flexDirection:'column', minWidth:0,
                background:'var(--surface)', border:'1px solid var(--border-subtle)', borderRadius:'var(--r-md)', overflow:'hidden', boxShadow:'var(--shadow-sm)' }}>
                <window.Photo src={c.img} alt={c.title} hue={`var(--type-${c.tone})`} ratio="16 / 9" icon="doc" />
                <div style={{ padding:'var(--sp-5)', display:'flex', flexDirection:'column', gap:11, flex:1 }}>
                  <div style={{ display:'flex', alignItems:'center', gap:8, flexWrap:'wrap' }}>
                    <CBadge tone={c.tone} size="sm">{c.cat}</CBadge>
                    <span style={{ font:'var(--fw-regular) var(--t-2xs)/1 var(--font-num)', color:'var(--text-faint)' }}>{c.date}</span>
                    <span style={{ display:'inline-flex', alignItems:'center', gap:4, font:'var(--fw-regular) var(--t-2xs)/1 var(--font-body)', color:'var(--text-faint)' }}><window.Icon name="clock" size={12}/>{c.read}</span>
                  </div>
                  <h3 style={{ margin:0, font:'var(--fw-bold) var(--t-h4)/1.45 var(--font-display)', color:'var(--text-strong)',
                    display:'-webkit-box', WebkitLineClamp:3, WebkitBoxOrient:'vertical', overflow:'hidden' }}>{c.title}</h3>
                  <p style={{ margin:0, font:'var(--fw-regular) var(--t-sm)/1.7 var(--font-body)', color:'var(--text-muted)',
                    display:'-webkit-box', WebkitLineClamp:2, WebkitBoxOrient:'vertical', overflow:'hidden' }}>{c.excerpt}</p>
                  <span style={{ marginTop:'auto', display:'inline-flex', alignItems:'center', gap:6, font:'var(--fw-bold) var(--t-sm)/1 var(--font-body)', color:'var(--blue-600)' }}>
                    続きを読む <window.Icon name="arrowR" size={14}/>
                  </span>
                </div>
              </a>
            ))}
          </div>
          {Sidebar}
        </div>
      </window.Container>
      )}
    </main>
  );
}

// ── 記事本文のレンダラ ───────────────────────────────────────
// body は「文字列（＝段落）」と「オブジェクト」を混在できる。
//   '本文'                                     → 段落
//   { h2:'見出し' } / { h3:'小見出し' }          → 見出し（目次にも載る）
//   { list:['項目1','項目2'] }                  → 箇条書き
//   { note:'補足や注意点' }                     → 目立たせる囲み
//   { table:{ head:['列1','列2'], rows:[[..]] } } → 表
// 文字列だけの既存データもそのまま動く（後方互換）。
const blockHeading = (b) => (b && typeof b === 'object') ? (b.h2 || b.h3 || null) : null;
const slugOf = (t, i) => 'sec-' + i;

function ArticleBody({ blocks }) {
  const { isMobile } = window.useViewport();
  const P = { margin:'0 0 var(--sp-5)', font:'var(--fw-regular) var(--t-base)/1.95 var(--font-body)', color:'var(--text-body)' };
  return (
    <React.Fragment>
      {blocks.map((b,i)=>{
        if (typeof b === 'string') return <p key={i} style={P}>{b}</p>;
        if (!b || typeof b !== 'object') return null;
        if (b.h2) return (
          <h2 key={i} id={slugOf(b.h2,i)} style={{ margin:'var(--sp-10) 0 var(--sp-4)', paddingLeft:14,
            borderLeft:'4px solid var(--blue-600)', font:`700 ${isMobile?'var(--t-h4)':'var(--t-h3)'}/1.5 var(--font-display)`, color:'var(--text-strong)' }}>{b.h2}</h2>
        );
        if (b.h3) return (
          <h3 key={i} id={slugOf(b.h3,i)} style={{ margin:'var(--sp-8) 0 var(--sp-3)',
            font:'700 var(--t-h4)/1.5 var(--font-display)', color:'var(--text-strong)' }}>{b.h3}</h3>
        );
        if (b.list) return (
          <ul key={i} style={{ margin:'0 0 var(--sp-6)', padding:0, listStyle:'none', display:'flex', flexDirection:'column', gap:10 }}>
            {b.list.map((it,j)=>(
              <li key={j} style={{ display:'flex', gap:10, font:'var(--fw-regular) var(--t-base)/1.8 var(--font-body)', color:'var(--text-body)' }}>
                <span style={{ display:'grid', placeItems:'center', width:20, height:20, borderRadius:'var(--r-pill)',
                  background:'var(--blue-50)', color:'var(--blue-600)', flex:'none', marginTop:4 }}><window.Icon name="check" size={12} stroke={3}/></span>
                <span>{it}</span>
              </li>
            ))}
          </ul>
        );
        if (b.note) return (
          <div key={i} style={{ margin:'0 0 var(--sp-6)', padding:'var(--sp-5)', background:'var(--blue-50)',
            border:'1px solid var(--blue-100)', borderRadius:'var(--r-md)', display:'flex', gap:12 }}>
            <window.Icon name="shield" size={19} style={{ color:'var(--blue-600)', flex:'none', marginTop:2 }}/>
            <span style={{ font:'var(--fw-medium) var(--t-sm)/1.85 var(--font-body)', color:'var(--text-body)' }}>{b.note}</span>
          </div>
        );
        if (b.table && b.table.rows) return (
          <div key={i} style={{ margin:'0 0 var(--sp-6)', overflowX:'auto' }}>
            <table style={{ width:'100%', minWidth:420, borderCollapse:'collapse', border:'1px solid var(--border-subtle)' }}>
              {b.table.head && (
                <thead><tr>{b.table.head.map((h,j)=>(
                  <th key={j} style={{ textAlign:'left', padding:'11px 14px', background:'var(--surface-sunken)',
                    borderBottom:'1px solid var(--border-subtle)', font:'var(--fw-bold) var(--t-sm)/1.4 var(--font-body)', color:'var(--text-strong)' }}>{h}</th>
                ))}</tr></thead>
              )}
              <tbody>{b.table.rows.map((r,j)=>(
                <tr key={j}>{r.map((cell,k)=>(
                  <td key={k} style={{ padding:'11px 14px', borderBottom:'1px solid var(--border-subtle)',
                    font:'var(--fw-regular) var(--t-sm)/1.7 var(--font-body)', color:'var(--text-body)' }}>{cell}</td>
                ))}</tr>
              ))}</tbody>
            </table>
          </div>
        );
        return null;
      })}
    </React.Fragment>
  );
}

// ── 目次（h2 が2つ以上ある記事だけ表示） ─────────────────────
function ArticleToc({ blocks }) {
  const items = blocks.map((b,i)=>({ t: (b && typeof b==='object' && b.h2) || null, id: slugOf('',i) }))
                      .filter(x => x.t);
  if (items.length < 2) return null;
  return (
    <nav style={{ margin:'0 0 var(--sp-8)', padding:'var(--sp-6)', background:'var(--surface-sunken)',
      border:'1px solid var(--border-subtle)', borderRadius:'var(--r-md)' }}>
      <span style={{ display:'block', marginBottom:12, font:'700 var(--t-sm)/1 var(--font-display)', color:'var(--text-strong)' }}>この記事の内容</span>
      <ol style={{ margin:0, paddingLeft:20, display:'flex', flexDirection:'column', gap:8 }}>
        {items.map((x,i)=>(
          <li key={i} style={{ font:'var(--fw-medium) var(--t-sm)/1.6 var(--font-body)', color:'var(--blue-700)' }}>
            <a href={'#'+x.id} style={{ color:'inherit' }}>{x.t}</a>
          </li>
        ))}
      </ol>
    </nav>
  );
}

// ── Column article ──────────────────────────────────────────
// 本文の文字数から読了時間を算出する（日本語は毎分500字で概算）。
// データに固定値を書くと、加筆しても古い分数のまま残るため、本文から都度計算する。
function readTimeOf(blocks) {
  let n = 0;
  (blocks||[]).forEach(b => {
    if (typeof b === 'string') { n += b.length; return; }
    if (!b || typeof b !== 'object') return;
    if (b.h2) n += b.h2.length;
    if (b.h3) n += b.h3.length;
    if (b.note) n += b.note.length;
    if (b.list) b.list.forEach(x => { n += String(x).length; });
    if (b.table && b.table.rows) b.table.rows.forEach(r => r.forEach(x => { n += String(x).length; }));
  });
  return Math.max(1, Math.round(n / 500)) + '分';
}

// body正規化：CMS(D1)の旧記事は body が「文字列」で来る。配列前提のまま渡すと
// readTimeOf/ArticleToc/ArticleBody が落ち、Error Boundaryが無いため全画面が白くなる。
// 文字列は1段落の配列に包む（NewsArticle と同じ扱いに統一）。
const toBlocks = (b) => Array.isArray(b) ? b : (b ? [String(b)] : []);

function ColumnArticle({ column, onNav, onOpenColumn }) {
  const D = window.SKRRS_DATA;
  const c = column || D.columns[0];
  const { isMobile } = window.useViewport();
  // 関連記事は同じカテゴリを優先し、足りなければ他カテゴリで補う（最大3件）
  const rest = D.columns.filter(x => x.id !== c.id);
  const more = rest.filter(x => x.tone === c.tone).concat(rest.filter(x => x.tone !== c.tone)).slice(0,3);
  const blocks = toBlocks(c.body);
  const readTime = readTimeOf(blocks);

  return (
    <main>
      {/* 下書きプレビュー帯（管理者プレビューでのみ c.draft が立つ） */}
      {c.draft && (
        <div style={{ display:'flex', alignItems:'center', gap:10, padding:'10px 16px',
          background:'#FBF2DC', borderBottom:'1px solid #E8CF96', color:'#7A5A0E', font:'var(--fw-bold) var(--t-xs)/1.5 var(--font-body)' }}>
          <window.Icon name="eye" size={15} />下書きプレビュー — この記事はまだ公開されていません（管理者にのみ表示中）
        </div>
      )}
      <window.PageHero marker={c.cat} icon="doc" title={c.title} image={c.img}
        crumbs={[{label:'ホーム',route:'home'},{label:'不動産コラム',route:'columns'},{label:c.cat}]} onNav={onNav} />
      <window.Container style={{ paddingTop:'var(--sp-10)', paddingBottom:'var(--sp-16)', maxWidth:820 }}>
        <div style={{ display:'flex', alignItems:'center', gap:12, marginBottom:'var(--sp-6)', flexWrap:'wrap' }}>
          <CBadge tone={c.tone}>{c.cat}</CBadge>
          <span style={{ font:'var(--fw-regular) var(--t-xs)/1 var(--font-num)', color:'var(--text-muted)' }}>{c.date}</span>
          {c.updated && (
            <span style={{ font:'var(--fw-regular) var(--t-xs)/1 var(--font-num)', color:'var(--text-muted)' }}>更新 {c.updated}</span>
          )}
          <span style={{ display:'inline-flex', alignItems:'center', gap:5, font:'var(--fw-regular) var(--t-xs)/1 var(--font-body)', color:'var(--text-muted)' }}>
            <window.Icon name="clock" size={13}/>{readTime}
          </span>
          <span style={{ font:'var(--fw-regular) var(--t-xs)/1 var(--font-body)', color:'var(--text-muted)' }}>{c.author}</span>
        </div>
        {/* 記事の写真はページ上部のヘッダーで既に大きく出しているため、ここでは繰り返さない */}
        <p style={{ margin:'0 0 var(--sp-6)', font:'var(--fw-medium) var(--t-lead)/1.9 var(--font-body)', color:'var(--text-strong)' }}>{c.excerpt}</p>
        <ArticleToc blocks={blocks} />
        <ArticleBody blocks={blocks} />
        <div style={{ marginTop:'var(--sp-8)', padding:'var(--sp-6)', background:'var(--blue-50)', border:'1px solid var(--blue-100)',
          borderRadius:'var(--r-lg)', display:'flex', flexDirection:'column', gap:14, alignItems:'flex-start' }}>
          <span style={{ font:'700 var(--t-h4)/1.4 var(--font-display)', color:'var(--text-strong)' }}>この記事の内容について、個別にご相談いただけます</span>
          <p style={{ margin:0, font:'var(--fw-regular) var(--t-sm)/1.7 var(--font-body)', color:'var(--text-body)' }}>記事はあくまで一般的な内容です。実際の物件や契約条件によって判断は変わります。ご相談は無料ですので、具体的な状況をお聞かせください。</p>
          <CBtn variant="primary" pill iconLeft={<window.Icon name="mail" size={17}/>} onClick={()=>onNav('contact')}>無料で相談する</CBtn>
        </div>
        <div style={{ marginTop:'var(--sp-6)' }}>
          <CBtn variant="ghost" iconLeft={<window.Icon name="chevL" size={16}/>} onClick={()=>onNav('columns')}>コラム一覧へ戻る</CBtn>
        </div>
      </window.Container>

      <section style={{ background:'var(--blue-50)', padding:'var(--sp-12) 0' }}>
        <window.Container>
          <h2 style={{ margin:'0 0 var(--sp-6)', font:'700 var(--t-h3)/1.2 var(--font-display)', color:'var(--text-strong)' }}>関連記事</h2>
          <div style={{ display:'grid', gridTemplateColumns:`repeat(${isMobile?1:3},1fr)`, gap:'var(--sp-5)' }}>
            {more.map(m=>(
              <a key={m.id} className="sk-card" onClick={()=>onOpenColumn(m)} style={{ cursor:'pointer', display:'flex', flexDirection:'column',
                background:'var(--surface)', border:'1px solid var(--border-subtle)', borderRadius:'var(--r-md)', overflow:'hidden', boxShadow:'var(--shadow-sm)' }}>
                <window.Photo src={m.img} alt={m.title} hue={`var(--type-${m.tone})`} ratio="16 / 9" icon="doc" />
                <div style={{ padding:'var(--sp-4)', display:'flex', flexDirection:'column', gap:8 }}>
                  <CBadge tone={m.tone}>{m.cat}</CBadge>
                  <span style={{ font:'var(--fw-bold) var(--t-sm)/1.5 var(--font-body)', color:'var(--text-strong)',
                    display:'-webkit-box', WebkitLineClamp:2, WebkitBoxOrient:'vertical', overflow:'hidden' }}>{m.title}</span>
                </div>
              </a>
            ))}
          </div>
        </window.Container>
      </section>
    </main>
  );
}

// ── News list ───────────────────────────────────────────────
function NewsScreen({ onNav, onOpenNews }) {
  const D = window.SKRRS_DATA;
  const { isMobile } = window.useViewport();
  return (
    <main>
      <window.PageHero marker="News" icon="doc" title="お知らせ" image={window.SKRRS_IMG.cityAerial}
        lead="サービスの開始や対応エリアの変更など、Skrrsからのお知らせを掲載しています。"
        crumbs={[{label:'ホーム',route:'home'},{label:'お知らせ'}]} onNav={onNav} />
      {!(D.release||{}).news ? (
        <window.Container style={{ paddingTop:'var(--sp-14)', paddingBottom:'var(--sp-20)', maxWidth:880 }}>
          <window.ComingSoon area="news" onNav={onNav} />
        </window.Container>
      ) : (
      <window.Container style={{ paddingTop:'var(--sp-10)', paddingBottom: isMobile?'var(--sp-16)':'var(--sp-20)', maxWidth:880 }}>
        <div style={{ display:'flex', flexDirection:'column', border:'1px solid var(--border-subtle)', borderRadius:'var(--r-md)', overflow:'hidden' }}>
          {D.news.map((n,i)=>(
            <a key={n.id} onClick={()=>onOpenNews(n)} style={{ cursor:'pointer', display:'flex', gap:16, alignItems:'flex-start',
              padding:'var(--sp-5)', borderBottom: i<D.news.length-1?'1px solid var(--border-subtle)':'none', background:'var(--surface)' }}>
              <span style={{ font:'var(--fw-medium) var(--t-xs)/1.5 var(--font-num)', color:'var(--text-muted)', flex:'none', width:84 }}>{n.date}</span>
              <CBadge tone={(D.newsTagTone||{})[n.tag]||'navy'} size="sm">{n.tag}</CBadge>
              <span style={{ flex:1, font:'var(--fw-medium) var(--t-sm)/1.6 var(--font-body)', color:'var(--text-strong)' }}>{n.text}</span>
              <window.Icon name="chevR" size={16} style={{ color:'var(--text-faint)', flex:'none', marginTop:2 }}/>
            </a>
          ))}
        </div>
      </window.Container>
      )}
    </main>
  );
}

// ── News article ────────────────────────────────────────────
function NewsArticle({ item, onNav, onOpenNews }) {
  const D = window.SKRRS_DATA;
  const n = item || D.news[0];
  // body は文字列でも配列でも受ける（配列なら見出し・箇条書き・表が使える）
  const blocks = Array.isArray(n.body) ? n.body : [n.body || ''];
  const others = D.news.filter(x => x.id !== n.id).slice(0, 3);
  return (
    <main>
      <window.PageHero marker="News" icon="doc" title={n.text} image={n.img || window.SKRRS_IMG.cityAerial} position="center 45%"
        crumbs={[{label:'ホーム',route:'home'},{label:'お知らせ',route:'news'},{label:n.tag}]} onNav={onNav} />
      <window.Container style={{ paddingTop:'var(--sp-10)', paddingBottom:'var(--sp-16)', maxWidth:780 }}>
        <div style={{ display:'flex', alignItems:'center', gap:12, marginBottom:'var(--sp-6)' }}>
          <CBadge tone={(D.newsTagTone||{})[n.tag]||'navy'} size="sm">{n.tag}</CBadge>
          <span style={{ font:'var(--fw-regular) var(--t-xs)/1 var(--font-num)', color:'var(--text-muted)' }}>{n.date}</span>
        </div>
        <ArticleBody blocks={blocks} />

        <div style={{ marginTop:'var(--sp-8)', padding:'var(--sp-6)', background:'var(--blue-50)', border:'1px solid var(--blue-100)',
          borderRadius:'var(--r-lg)', display:'flex', flexDirection:'column', gap:12, alignItems:'flex-start' }}>
          <span style={{ font:'700 var(--t-h4)/1.4 var(--font-display)', color:'var(--text-strong)' }}>ご不明な点は、お気軽にお問い合わせください</span>
          <CBtn variant="primary" pill iconLeft={<window.Icon name="mail" size={17}/>} onClick={()=>onNav('contact')}>お問い合わせ</CBtn>
        </div>

        {others.length > 0 && (
          <div style={{ marginTop:'var(--sp-10)' }}>
            <h2 style={{ margin:'0 0 var(--sp-4)', font:'700 var(--t-h4)/1.4 var(--font-display)', color:'var(--text-strong)' }}>ほかのお知らせ</h2>
            <div style={{ display:'flex', flexDirection:'column', border:'1px solid var(--border-subtle)', borderRadius:'var(--r-md)', overflow:'hidden' }}>
              {others.map((o,i)=>(
                <a key={o.id} onClick={()=> onOpenNews ? onOpenNews(o) : onNav('news')}
                  style={{ cursor:'pointer', display:'flex', gap:14, alignItems:'flex-start', padding:'var(--sp-4) var(--sp-5)',
                    borderBottom: i<others.length-1?'1px solid var(--border-subtle)':'none', background:'var(--surface)' }}>
                  <span style={{ font:'var(--fw-medium) var(--t-xs)/1.5 var(--font-num)', color:'var(--text-muted)', flex:'none', width:78 }}>{o.date}</span>
                  <span style={{ flex:1, font:'var(--fw-medium) var(--t-sm)/1.6 var(--font-body)', color:'var(--text-strong)' }}>{o.text}</span>
                  <window.Icon name="chevR" size={15} style={{ color:'var(--text-faint)', flex:'none', marginTop:2 }}/>
                </a>
              ))}
            </div>
          </div>
        )}

        <div style={{ marginTop:'var(--sp-6)' }}>
          <CBtn variant="ghost" iconLeft={<window.Icon name="chevL" size={16}/>} onClick={()=>onNav('news')}>お知らせ一覧へ戻る</CBtn>
        </div>
      </window.Container>
    </main>
  );
}

// ArticleBody / ArticleToc は PrivacyScreen（InfoPages.jsx）でも使うため公開する。
Object.assign(window, { ColumnsScreen, ColumnArticle, NewsScreen, NewsArticle, ArticleBody, ArticleToc });
