wing-ops/frontend/src/tabs/hns/components/HNSTheoryView.tsx

6363 lines
225 KiB
TypeScript
Executable File
Raw Blame 히스토리

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState, useRef } from 'react';
const theoryTabs = [
{ icon: '🔬', name: '시스템 개요' },
{ icon: '🌀', name: '가우시안 모델' },
{ icon: '🧪', name: '물질별 시나리오' },
{ icon: '🌊', name: '해양환경 보정' },
{ icon: '✅', name: '모델 검증' },
{ icon: '⚡', name: '실시간 비교' },
{ icon: '🚀', name: 'WRF-Chem·발전' },
];
/* ═══ 공통 스타일 유틸 ═══ */
const card = 'rounded-[10px] p-[14px] mb-4';
const cardBg = 'bg-bg-card border border-stroke';
const labelStyle = (color: string) =>
({ fontSize: 'var(--font-size-title-3)', fontWeight: 700, color, marginBottom: '10px' }) as const;
const tag = (color: string) =>
({
padding: '3px 8px',
borderRadius: '4px',
fontSize: 'var(--font-size-label-2)',
color,
background: `${color}14`,
border: `1px solid ${color}30`,
}) as const;
const bodyText = 'text-label-1 text-fg-sub leading-[1.8]';
/* ═══ 패널 0: 시스템 개요 ═══ */
function SystemOverviewPanel() {
return (
<>
{/* 시스템 개요 */}
<div className={`${card} ${cardBg}`}>
{/* 1행: 정의 + 목적 */}
<div className="grid grid-cols-2 gap-4 mb-4">
<div>
<div style={labelStyle('var(--fg-default)')}>📋 HNS ?</div>
<div className={bodyText}>
<b>(Hazardous &amp; Noxious Substances, HNS)</b>
· .
(<b>WRF</b>) (<b>Chem</b>)
.
</div>
</div>
<div>
<div style={labelStyle('var(--fg-default)')}>🎯 </div>
<div className="flex flex-col gap-[6px] text-label-1 text-fg-sub">
<div className="flex items-center gap-[6px] px-[10px] py-[6px] rounded-[10px] bg-bg-base">
<span style={{ color: 'var(--fg-default)', fontWeight: 700 }}></span> {' '}
<b> </b>
</div>
<div className="flex items-center gap-[6px] px-[10px] py-[6px] rounded-[10px] bg-bg-base">
<span style={{ color: 'var(--fg-default)', fontWeight: 700 }}></span>
<b> </b>
</div>
<div className="flex items-center gap-[6px] px-[10px] py-[6px] rounded-[10px] bg-bg-base">
<span style={{ color: 'var(--fg-default)', fontWeight: 700 }}></span>
<b> </b>
</div>
</div>
</div>
</div>
{/* 2행: 물질 특성 + 기상 데이터 + 확산 알고리즘 */}
<div className="grid grid-cols-3 gap-4">
<div>
<div style={labelStyle('var(--fg-default)')}>🧪 </div>
<div
style={{
fontSize: 'var(--font-size-label-2)',
color: 'var(--fg-sub)',
lineHeight: 1.7,
marginBottom: '10px',
}}
>
HNS는 <b> 6,000 </b>, .
.
</div>
<div className="flex flex-wrap gap-1">
{['증발률', '독성', '기화 특성', '비중', '인화점', '용해도'].map((item) => (
<span
key={item}
style={{
padding: '2px 8px',
borderRadius: '4px',
fontSize: 'var(--font-size-label-2)',
color: 'var(--fg-sub)',
background: 'var(--bg-base)',
}}
>
{item}
</span>
))}
</div>
</div>
<div>
<div style={labelStyle('var(--fg-default)')}>🌬 </div>
<div
style={{
fontSize: 'var(--font-size-label-2)',
color: 'var(--fg-sub)',
lineHeight: 1.7,
marginBottom: '10px',
}}
>
<b> </b> .
</div>
<div
className="flex flex-col gap-1"
style={{ fontSize: 'var(--font-size-label-2)', color: 'var(--fg-sub)' }}
>
{[
'💨 풍향·풍속 (KMA·ECMWF)',
'🌡 기온·습도·강수',
'📊 대기 안정도 (Pasquill-Gifford)',
].map((item) => (
<div
key={item}
style={{ padding: '4px 8px', borderRadius: '4px', background: 'var(--bg-base)' }}
>
{item}
</div>
))}
</div>
</div>
<div>
<div style={labelStyle('var(--fg-default)')}>🔬 </div>
<div
style={{
fontSize: 'var(--font-size-label-2)',
color: 'var(--fg-sub)',
lineHeight: 1.7,
marginBottom: '10px',
}}
>
/ WRF-Chem <b> </b>
.
</div>
<div
className="flex flex-col gap-1"
style={{ fontSize: 'var(--font-size-label-2)', color: 'var(--fg-sub)' }}
>
{['📍 Gaussian Plume/Puff', '⚡ WRF-Chem (기상+화학)', '🔧 ALOHA / CAMEO'].map(
(item) => (
<div
key={item}
style={{
padding: '4px 8px',
borderRadius: '4px',
background: 'var(--bg-base)',
}}
>
{item}
</div>
),
)}
</div>
</div>
</div>
</div>
{/* 주요 기능 및 특징 */}
<div className={`${cardBg} rounded-[10px] p-4 mb-4`}>
<div
style={{
fontSize: 'var(--font-size-title-4)',
fontWeight: 700,
color: 'var(--fg-default)',
marginBottom: '14px',
}}
>
</div>
<div className="grid grid-cols-3 gap-3">
<div
style={{
padding: '14px',
background: 'var(--bg-base)',
border: '1px solid var(--stroke-default)',
borderRadius: '8px',
}}
>
<div className="flex items-center gap-[6px] mb-2">
<span style={{ fontSize: 'var(--font-size-title-1)' }}>📡</span>
<span
style={{
fontSize: 'var(--font-size-label-1)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
</span>
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.7,
}}
>
'<b style={{ color: 'var(--color-accent)' }}>HNS 유출 블랙박스 시스템</b>'
.
.
</div>
</div>
<div
style={{
padding: '14px',
background: 'var(--bg-base)',
border: '1px solid var(--stroke-default)',
borderRadius: '8px',
}}
>
<div className="flex items-center gap-[6px] mb-2">
<span style={{ fontSize: 'var(--font-size-title-1)' }}>🎯</span>
<span
style={{
fontSize: 'var(--font-size-label-1)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
</span>
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.7,
}}
>
{' '}
<b style={{ color: 'var(--color-accent)' }}>// </b> AEGL·ERPG
. .
</div>
</div>
<div
style={{
padding: '14px',
background: 'var(--bg-base)',
border: '1px solid var(--stroke-default)',
borderRadius: '8px',
}}
>
<div className="flex items-center gap-[6px] mb-2">
<span style={{ fontSize: 'var(--font-size-title-1)' }}></span>
<span
style={{
fontSize: 'var(--font-size-label-1)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
</span>
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.7,
}}
>
<b style={{ color: 'var(--color-accent)' }}> DB</b>
. DB를 {' '}
<b style={{ color: 'var(--color-accent)' }}> </b> .
</div>
</div>
</div>
</div>
{/* 주요 기술 아키텍처 */}
<div className={`${cardBg} rounded-[10px] p-4 mb-4`}>
<div
style={{
fontSize: 'var(--font-size-title-4)',
fontWeight: 700,
color: 'var(--fg-default)',
marginBottom: '14px',
}}
>
🏗
</div>
{/* Flow diagram */}
<div className="flex items-center justify-center flex-wrap gap-0 mb-4">
{[
{
icon: '🧪',
label: 'HNS 물질 DB',
sub: '6,000+ 물질',
},
{
icon: '🌬',
label: '기상 데이터',
sub: 'KMA / AWS',
},
{
icon: '🔬',
label: '확산 모델 엔진',
sub: 'WRF-Chem / Gaussian',
},
{
icon: '🗺',
label: 'GIS 시각화',
sub: '위험 구역 맵',
},
{
icon: '🚨',
label: '대응 의사결정',
sub: '대피·방제 명령',
},
].map((item, idx) => (
<>
<div
key={item.label}
style={{
padding: '10px 16px',
background: 'var(--bg-base)',
border: '1px solid var(--stroke-default)',
borderRadius: '8px',
textAlign: 'center',
minWidth: idx === 2 ? '140px' : '120px',
}}
>
<div style={{ fontSize: 'var(--font-size-title-2)', marginBottom: '4px' }}>
{item.icon}
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
fontWeight: 700,
color: 'var(--color-accent)',
}}
>
{item.label}
</div>
<div
className="font-mono"
style={{ fontSize: 'var(--font-size-caption)', color: 'var(--fg-disabled)' }}
>
{item.sub}
</div>
</div>
{idx < 4 && (
<div
key={`arrow-${idx}`}
style={{
fontSize: 'var(--font-size-title-2)',
color: 'var(--fg-disabled)',
padding: '0 6px',
}}
>
</div>
)}
</>
))}
</div>
{/* 기술 상세 비교 */}
<div className="grid grid-cols-3 gap-[10px]">
<div
style={{
padding: '12px',
background: 'var(--bg-base)',
border: '1px solid rgba(6,182,212,.15)',
borderRadius: '8px',
}}
>
<div
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '8px',
}}
>
WRF-Chem
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.7,
}}
>
(<b style={{ color: 'var(--color-accent)' }}>WRF</b>) (
<b style={{ color: 'var(--color-accent)' }}>Chem</b>) . 3 ·
·· .
<br />
<span
className="font-mono"
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
해상도: 1~3 km / 시간분해능: 1 hr
</span>
</div>
</div>
<div
style={{
padding: '12px',
background: 'var(--bg-base)',
border: '1px solid rgba(6,182,212,.15)',
borderRadius: '8px',
}}
>
<div
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '8px',
}}
>
Gaussian Plume/Puff
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.7,
}}
>
ALOHA/CAMEO . (
<b style={{ color: 'var(--color-accent)' }}>Plume</b>) (
<b style={{ color: 'var(--color-accent)' }}>Puff</b>) . {' '}
<b> </b> .
<br />
<span
className="font-mono"
style={{ fontSize: 'var(--font-size-caption)', color: 'var(--color-accent)' }}
>
: &lt; 10 / : ±10~40%
</span>
</div>
</div>
<div
style={{
padding: '12px',
background: 'var(--bg-base)',
border: '1px solid rgba(6,182,212,.15)',
borderRadius: '8px',
}}
>
<div
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '8px',
}}
>
ROMS
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.7,
}}
>
Regional Ocean Modeling System과 {' '}
<b style={{ color: 'var(--color-accent)' }}> + </b>
. .
<br />
<span
className="font-mono"
style={{ fontSize: 'var(--font-size-caption)', color: 'var(--color-accent)' }}
>
/
</span>
</div>
</div>
</div>
</div>
{/* WING 시스템 적용 전략 */}
<div className={`${card} ${cardBg}`}>
<div className="flex items-center gap-2 mb-3">
<div
style={{
fontSize: 'var(--font-size-title-4)',
fontWeight: 700,
color: 'var(--color-accent)',
}}
>
🖥 WING
</div>
<span
style={{
padding: '2px 8px',
borderRadius: '10px',
background: 'rgba(6,182,212,.12)',
color: 'var(--color-accent)',
fontSize: 'var(--font-size-caption)',
fontWeight: 600,
}}
>
</span>
</div>
<div className="grid grid-cols-4 gap-2">
{[
{
icon: '🧪',
label: 'HNS DB 연동',
sub: 'CHRIS/CAMEO DB\n6,000+종 물질 검색',
bar: 'var(--color-accent)',
},
{
icon: '⚡',
label: '가우시안 모델',
sub: 'ALOHA + 이문진박사모델\n초기 대응 10초 이내',
bar: 'var(--color-accent)',
},
{
icon: '🌐',
label: 'WRF-Chem',
sub: '정밀 수치 모의\n3D 확산 시뮬레이션',
bar: 'var(--color-accent)',
},
{
icon: '🌊',
label: 'ROMS 연동',
sub: '해양-대기 결합\n장기 모의 지원',
bar: 'var(--color-accent)',
},
].map((item) => (
<div
key={item.label}
style={{
padding: '10px',
background: 'var(--bg-card)',
border: '1px solid var(--stroke-default)',
borderRadius: '6px',
textAlign: 'center',
}}
>
<div style={{ fontSize: 'var(--font-size-heading-3)', marginBottom: '4px' }}>
{item.icon}
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
{item.label}
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
marginTop: '2px',
}}
>
{item.sub.split('\n').map((line, i) => (
<span key={i}>
{line}
{i === 0 && <br />}
</span>
))}
</div>
<div
style={{
marginTop: '6px',
height: '3px',
background: item.bar,
borderRadius: '2px',
}}
/>
</div>
))}
</div>
<div
className="flex gap-3 mt-[10px]"
style={{ fontSize: 'var(--font-size-caption)', color: 'var(--fg-disabled)' }}
>
<span className="flex items-center gap-1">
<span
style={{
display: 'inline-block',
width: '10px',
height: '3px',
background: 'var(--color-accent)',
borderRadius: '2px',
}}
/>{' '}
</span>
<span className="flex items-center gap-1">
<span
style={{
display: 'inline-block',
width: '10px',
height: '3px',
background: 'var(--color-accent)',
borderRadius: '2px',
}}
/>{' '}
</span>
<span className="flex items-center gap-1">
<span
style={{
display: 'inline-block',
width: '10px',
height: '3px',
background: 'var(--color-accent)',
borderRadius: '2px',
}}
/>{' '}
</span>
</div>
</div>
{/* HNS 사고 실태 및 항만별 위험도 */}
<div className={`${cardBg} rounded-[10px] p-4 mt-4 mb-4`}>
<div className="flex items-center justify-between mb-[14px]">
<div className="flex items-center gap-2">
<div
style={{
width: '28px',
height: '28px',
borderRadius: '6px',
background: 'rgba(6,182,212,.15)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: 'var(--font-size-title-3)',
}}
>
🚨
</div>
<div>
<div
style={{
fontSize: 'var(--font-size-title-4)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
HNS
</div>
<div style={{ fontSize: 'var(--font-size-caption)', color: 'var(--fg-disabled)' }}>
(2013), · (2010, 2011)
</div>
</div>
</div>
<span
style={{
padding: '3px 10px',
borderRadius: '6px',
background: 'rgba(6,182,212,.08)',
border: '1px solid rgba(6,182,212,.2)',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
fontWeight: 600,
}}
>
HNS 6,500+
</span>
</div>
<div className="grid grid-cols-2 gap-[14px]">
{/* 주요 항만별 위험도 */}
<div>
<div
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '8px',
}}
>
🏭 ··
</div>
<div style={{ overflowX: 'auto' }}>
<table
style={{
width: '100%',
borderCollapse: 'collapse',
fontSize: 'var(--font-size-caption)',
}}
>
<thead>
<tr style={{ background: 'rgba(6,182,212,.06)' }}>
<th
style={{
padding: '6px 8px',
textAlign: 'left',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--color-accent)',
}}
>
</th>
<th
style={{
padding: '6px 8px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--fg-sub)',
}}
>
</th>
<th
style={{
padding: '6px 8px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--fg-sub)',
}}
>
</th>
<th
style={{
padding: '6px 8px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--fg-sub)',
}}
>
</th>
<th
style={{
padding: '6px 8px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--fg-sub)',
}}
>
HNS()
</th>
</tr>
</thead>
<tbody>
{[
{
name: '울산',
fire: '◎',
exp: '◎',
leak: '◎',
hns: '27,574',
danger: true,
},
{
name: '여수·광양',
fire: '◎',
exp: '◎',
leak: '◎',
hns: '38,700',
danger: true,
},
{ name: '대산', fire: '◎', exp: '○', leak: '◎', hns: '19,401', danger: false },
{ name: '인천', fire: '○', exp: '◎', leak: '○', hns: '41,618', danger: false },
{ name: '부산', fire: '○', exp: '△', leak: '○', hns: '25,417', danger: false },
{
name: '평택·당진',
fire: '○',
exp: '◎',
leak: '○',
hns: '29,248',
danger: false,
},
].map((row) => (
<tr
key={row.name}
style={{
borderBottom: '1px solid rgba(255,255,255,.04)',
background: row.danger ? 'rgba(6,182,212,.03)' : undefined,
}}
>
<td
style={{
padding: '5px 8px',
fontWeight: 700,
color: row.danger ? 'var(--color-accent)' : 'var(--fg-default)',
}}
>
{row.name}
</td>
<td style={{ textAlign: 'center' }}>{row.fire}</td>
<td style={{ textAlign: 'center' }}>{row.exp}</td>
<td style={{ textAlign: 'center' }}>{row.leak}</td>
<td
className="font-mono"
style={{
textAlign: 'center',
color: row.danger ? 'var(--color-accent)' : 'var(--color-accent)',
}}
>
{row.hns}
</td>
</tr>
))}
</tbody>
</table>
</div>
<div
className="flex gap-2 mt-[6px]"
style={{ fontSize: 'var(--font-size-caption)', color: 'var(--fg-disabled)' }}
>
<span> </span>
<span> </span>
<span> </span>
<span> </span>
<span className="ml-auto">단위: 천톤, 2010 </span>
</div>
</div>
{/* HNS 구분 및 사고 유형 */}
<div>
<div
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '8px',
}}
>
HNS vs
</div>
<div className="grid grid-cols-2 gap-[6px] mb-2">
<div
style={{
padding: '8px',
background: 'rgba(6,182,212,.04)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '6px',
}}
>
<div
style={{
fontSize: 'var(--font-size-caption)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '4px',
}}
>
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.5,
}}
>
·····
</div>
<div className="flex flex-wrap gap-[2px] mt-1">
{['포장위험물', '산적고체', '산적액체', '액화가스'].map((t) => (
<span
key={t}
style={{
padding: '1px 5px',
borderRadius: '3px',
background: 'rgba(6,182,212,.06)',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
{t}
</span>
))}
</div>
</div>
<div
style={{
padding: '8px',
background: 'rgba(6,182,212,.04)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '6px',
}}
>
<div
style={{
fontSize: 'var(--font-size-caption)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '4px',
}}
>
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.5,
}}
>
· ()
</div>
<div className="flex flex-wrap gap-[2px] mt-1">
{['유해액체', '포장유해', '대기오염', '폐기물'].map((t) => (
<span
key={t}
style={{
padding: '1px 5px',
borderRadius: '3px',
background: 'rgba(6,182,212,.06)',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
{t}
</span>
))}
</div>
</div>
</div>
<div
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '6px',
}}
>
📊 vs HNS
</div>
<div
style={{
display: 'grid',
gridTemplateColumns: 'auto 1fr 1fr',
fontSize: 'var(--font-size-caption)',
}}
>
<div
style={{
padding: '4px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
fontWeight: 600,
color: 'var(--color-accent)',
}}
>
</div>
<div
style={{
padding: '4px 6px',
background: 'rgba(6,182,212,.04)',
border: '1px solid rgba(6,182,212,.08)',
textAlign: 'center',
fontWeight: 600,
color: 'var(--color-accent)',
}}
>
</div>
<div
style={{
padding: '4px 6px',
background: 'rgba(6,182,212,.04)',
border: '1px solid rgba(6,182,212,.08)',
textAlign: 'center',
fontWeight: 600,
color: 'var(--color-accent)',
}}
>
HNS
</div>
{[
{
label: '물질',
oil: '눈으로 확인 가능',
hns: '보이지 않는 경우 多',
hnsC: 'var(--color-accent)',
},
{
label: '위험',
oil: '낮은 위험성',
hns: '독성·폭발·화재 복합',
hnsC: 'var(--color-accent)',
},
{
label: '예측',
oil: '단기 예측 가능',
hns: '다매체 피해예측 필요',
hnsC: 'var(--color-accent)',
},
{
label: '대응',
oil: '초기대응자 방제가능',
hns: '전문가 방제 필수',
hnsC: 'var(--color-accent)',
},
].map((row) => (
<>
<div
key={`${row.label}-label`}
style={{
padding: '3px 6px',
border: '1px solid var(--stroke-light)',
color: 'var(--fg-disabled)',
}}
>
{row.label}
</div>
<div
key={`${row.label}-oil`}
style={{
padding: '3px 6px',
border: '1px solid var(--stroke-light)',
color: 'var(--fg-sub)',
textAlign: 'center',
}}
>
{row.oil}
</div>
<div
key={`${row.label}-hns`}
style={{
padding: '3px 6px',
border: '1px solid var(--stroke-light)',
color: row.hnsC,
textAlign: 'center',
}}
>
{row.hns}
</div>
</>
))}
</div>
</div>
</div>
</div>
{/* 국내외 대응 체계 비교 */}
<div className="grid grid-cols-2 gap-[14px] mb-4">
{/* 한국 */}
<div className={`${cardBg} rounded-[10px] p-[14px]`}>
<div className="flex items-center gap-[6px] mb-[10px]">
<span style={{ fontSize: 'var(--font-size-title-3)' }}>🇰🇷</span>
<span
style={{
fontSize: 'var(--font-size-label-1)',
fontWeight: 700,
color: 'var(--color-accent)',
}}
>
HNS
</span>
</div>
<div className="flex flex-col gap-[6px]" style={{ fontSize: 'var(--font-size-caption)' }}>
{[
{
title: 'OPRC-HNS 의정서',
sub: '2008.1.11 가입 → 2008.4.11 발효',
color: 'var(--color-accent)',
},
{
title: '국가/지역 긴급방제계획',
sub: "HNS 국가긴급방제계획 수립 ('09.6)",
color: 'var(--color-accent)',
},
{
title: 'CARIS 대응정보시스템',
sub: '사고대응 매뉴얼 + 화학물질 정보',
color: 'var(--color-accent)',
},
{
title: '통합 대응 체계',
sub: '대통령 → 중앙안전관리위 → 중앙방제대책본부(해양경찰청장)',
color: 'var(--color-accent)',
},
{
title: '현장 대응팀',
sub: '상황관리팀 → 사고대응팀(통제반·물질탐지반·방제작업반·제독지원반)',
color: 'var(--color-accent)',
},
].map((item) => (
<div
key={item.title}
style={{
padding: '6px 8px',
background: 'var(--bg-base)',
borderRadius: '4px',
display: 'flex',
alignItems: 'center',
gap: '6px',
}}
>
<div>
<b style={{ color: 'var(--fg-default)' }}>{item.title}</b>
<br />
<span style={{ color: 'var(--fg-disabled)' }}>{item.sub}</span>
</div>
</div>
))}
</div>
</div>
{/* 미국 */}
<div className={`${cardBg} rounded-[10px] p-[14px]`}>
<div className="flex items-center gap-[6px] mb-[10px]">
<span style={{ fontSize: 'var(--font-size-title-3)' }}>🇺🇸</span>
<span
style={{
fontSize: 'var(--font-size-label-1)',
fontWeight: 700,
color: 'var(--color-accent)',
}}
>
HNS
</span>
</div>
<div className="flex flex-col gap-[6px]" style={{ fontSize: 'var(--font-size-caption)' }}>
{[
{
title: 'OPA90 / NCP',
sub: '국가긴급계획 ESF #10 — HNS 포함',
color: 'var(--color-accent)',
},
{
title: '공동의장 체제',
sub: '환경청(EPA) + 해안경비대(USCG) 공동 지휘',
color: 'var(--color-accent)',
},
{
title: 'CAMEO / ALOHA / MARPLOT',
sub: '6,000+종 화학물질 통합 DB · 대기확산 모델',
color: 'var(--color-accent)',
},
{
title: 'NRT / RRT / NSF',
sub: '국가방제팀 + 지역방제팀 + 국가기동타격대',
color: 'var(--color-accent)',
},
{
title: '통합지휘시스템(ICS)',
sub: '16개 부처 + 주·지방정부 + 유출책임자 통합 조정',
color: 'var(--color-accent)',
},
].map((item) => (
<div
key={item.title}
style={{
padding: '6px 8px',
background: 'var(--bg-base)',
borderRadius: '4px',
display: 'flex',
alignItems: 'center',
gap: '6px',
}}
>
<div>
<b style={{ color: 'var(--fg-default)' }}>{item.title}</b>
<br />
<span style={{ color: 'var(--fg-disabled)' }}>{item.sub}</span>
</div>
</div>
))}
</div>
</div>
</div>
{/* 국제 협약 체계 */}
<div className={`${card} ${cardBg}`}>
<div className="flex items-center gap-2 mb-[10px]">
<span
style={{
fontSize: 'var(--font-size-title-4)',
fontWeight: 700,
color: 'var(--color-accent)',
}}
>
🌐 HNS
</span>
</div>
<div
style={{
display: 'grid',
gridTemplateColumns: 'auto 1fr 1fr 1fr',
fontSize: 'var(--font-size-caption)',
}}
>
{[{ label: '구분', : '협약', : '담당', : '대상', header: true }].map(() => (
<>
<div
key="h-div"
style={{
padding: '5px 8px',
background: 'rgba(6,182,212,.08)',
fontWeight: 700,
color: 'var(--color-accent)',
border: '1px solid rgba(6,182,212,.12)',
}}
>
</div>
<div
key="h-conv"
style={{
padding: '5px 8px',
background: 'rgba(6,182,212,.08)',
fontWeight: 600,
color: 'var(--fg-default)',
textAlign: 'center',
border: '1px solid rgba(6,182,212,.12)',
}}
>
</div>
<div
key="h-resp"
style={{
padding: '5px 8px',
background: 'rgba(6,182,212,.08)',
fontWeight: 600,
color: 'var(--fg-default)',
textAlign: 'center',
border: '1px solid rgba(6,182,212,.12)',
}}
>
</div>
<div
key="h-target"
style={{
padding: '5px 8px',
background: 'rgba(6,182,212,.08)',
fontWeight: 600,
color: 'var(--fg-default)',
textAlign: 'center',
border: '1px solid rgba(6,182,212,.12)',
}}
>
</div>
</>
))}
{/* 안전 */}
<div
style={{
padding: '4px 8px',
border: '1px solid var(--stroke-light)',
color: 'var(--fg-disabled)',
}}
>
</div>
<div
style={{
padding: '4px 8px',
border: '1px solid var(--stroke-light)',
color: 'var(--color-accent)',
textAlign: 'center',
}}
>
74 SOLAS
</div>
<div
style={{
padding: '4px 8px',
border: '1px solid var(--stroke-light)',
color: 'var(--fg-sub)',
textAlign: 'center',
}}
>
IMO
</div>
<div
style={{
padding: '4px 8px',
border: '1px solid var(--stroke-light)',
color: 'var(--fg-sub)',
textAlign: 'center',
}}
>
</div>
{/* 보호 */}
<div
style={{
padding: '4px 8px',
border: '1px solid var(--stroke-light)',
color: 'var(--fg-disabled)',
}}
>
</div>
<div
style={{
padding: '4px 8px',
border: '1px solid var(--stroke-light)',
color: 'var(--color-accent)',
textAlign: 'center',
}}
>
MARPOL 73/78
</div>
<div
style={{
padding: '4px 8px',
border: '1px solid var(--stroke-light)',
color: 'var(--fg-sub)',
textAlign: 'center',
}}
>
IMO
</div>
<div
style={{
padding: '4px 8px',
border: '1px solid var(--stroke-light)',
color: 'var(--fg-sub)',
textAlign: 'center',
}}
>
····
</div>
{/* 대비·대응 */}
<div
style={{
padding: '4px 8px',
border: '1px solid var(--stroke-light)',
background: 'rgba(6,182,212,.03)',
color: 'var(--color-accent)',
fontWeight: 600,
}}
>
·
</div>
<div
style={{
padding: '4px 8px',
border: '1px solid var(--stroke-light)',
background: 'rgba(6,182,212,.03)',
color: 'var(--color-accent)',
textAlign: 'center',
fontWeight: 600,
}}
>
2000 OPRC-HNS
</div>
<div
style={{
padding: '4px 8px',
border: '1px solid var(--stroke-light)',
background: 'rgba(6,182,212,.03)',
color: 'var(--fg-sub)',
textAlign: 'center',
}}
>
IMO
</div>
<div
style={{
padding: '4px 8px',
border: '1px solid var(--stroke-light)',
background: 'rgba(6,182,212,.03)',
color: 'var(--color-accent)',
textAlign: 'center',
fontWeight: 600,
}}
>
·(HNS)
</div>
{/* 배상 */}
<div
style={{
padding: '4px 8px',
border: '1px solid var(--stroke-light)',
color: 'var(--fg-disabled)',
}}
>
</div>
<div
style={{
padding: '4px 8px',
border: '1px solid var(--stroke-light)',
color: 'var(--color-accent)',
textAlign: 'center',
}}
>
96 HNS협약
</div>
<div
style={{
padding: '4px 8px',
border: '1px solid var(--stroke-light)',
color: 'var(--fg-sub)',
textAlign: 'center',
}}
>
IMO
</div>
<div
style={{
padding: '4px 8px',
border: '1px solid var(--stroke-light)',
color: 'var(--fg-sub)',
textAlign: 'center',
}}
>
</div>
</div>
</div>
{/* HATS 사고이력 통계 */}
<div className={`${cardBg} rounded-[10px] p-4 mb-4`}>
<div className="flex items-center justify-between mb-[14px]">
<div className="flex items-center gap-2">
<div
style={{
width: '28px',
height: '28px',
borderRadius: '6px',
background: 'rgba(6,182,212,.15)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: 'var(--font-size-title-3)',
}}
>
📊
</div>
<div>
<div
style={{
fontSize: 'var(--font-size-title-4)',
fontWeight: 700,
color: 'var(--color-accent)',
}}
>
HNS (23 76)
</div>
<div style={{ fontSize: 'var(--font-size-caption)', color: 'var(--fg-disabled)' }}>
· (2017) HATS · 1994~2016
</div>
</div>
</div>
<span
style={{
padding: '3px 10px',
borderRadius: '6px',
background: 'rgba(6,182,212,.08)',
border: '1px solid rgba(6,182,212,.2)',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
fontWeight: 700,
}}
>
3.3
</span>
</div>
<div className="grid grid-cols-5 gap-2 mb-[14px]">
{[
{
label: '사고시기 1위',
val: '41%',
title: '춘계 (3~5월)',
sub: '동절기 30%',
color: 'var(--color-accent)',
border: 'rgba(6,182,212,.12)',
},
{
label: '사고장소 1위',
val: '51%',
title: '계류장',
sub: '항만 29% · 연안 17%',
color: 'var(--color-accent)',
border: 'rgba(6,182,212,.12)',
},
{
label: '오염원 1위',
val: '49%',
title: '케미컬운반선',
sub: '육상시설 32%',
color: 'var(--color-accent)',
border: 'rgba(6,182,212,.12)',
},
{
label: '사고원인 1위',
val: '45%',
title: '승무원 과실',
sub: '화물 22% · 외적원인 17%',
color: 'var(--color-accent)',
border: 'rgba(6,182,212,.12)',
},
{
label: '사고물질 1위',
val: '12%',
title: '자일렌류',
sub: '옥탄올·라텍스·팜유 순',
color: 'var(--color-accent)',
border: 'rgba(6,182,212,.12)',
},
].map((item) => (
<div
key={item.label}
style={{
padding: '10px',
background: 'var(--bg-base)',
border: `1px solid ${item.border}`,
borderRadius: '6px',
textAlign: 'center',
}}
>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
marginBottom: '4px',
}}
>
{item.label}
</div>
<div
className="font-mono"
style={{ fontSize: 'var(--font-size-title-1)', fontWeight: 800, color: item.color }}
>
{item.val}
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
{item.title}
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
marginTop: '2px',
}}
>
{item.sub}
</div>
</div>
))}
</div>
<div className="grid grid-cols-2 gap-3">
{/* 유출량 분포 */}
<div>
<div
style={{
fontSize: 'var(--font-size-caption)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '6px',
}}
>
📈 (76)
</div>
<div
className="flex flex-col gap-[3px]"
style={{ fontSize: 'var(--font-size-caption)' }}
>
{[
{
range: '0~50L',
width: '36%',
gradient: 'var(--color-accent)',
count: '27건',
color: 'var(--fg-default)',
},
{
range: '1K~10KL',
width: '20%',
gradient: 'var(--color-accent)',
count: '15건',
color: 'var(--fg-default)',
},
{
range: '101~500L',
width: '13%',
gradient: 'var(--color-accent)',
count: '10건',
color: 'var(--fg-default)',
},
{
range: '100만L+',
width: '12%',
gradient: 'var(--color-accent)',
count: '9건',
color: 'var(--color-accent)',
rangeColor: 'var(--color-accent)',
},
].map((bar) => (
<div key={bar.range} className="flex items-center gap-[6px]">
<div
style={{
width: '60px',
color: (bar as { rangeColor?: string }).rangeColor ?? 'var(--fg-disabled)',
}}
>
{bar.range}
</div>
<div
style={{
flex: 1,
height: '14px',
background: 'var(--bg-base)',
borderRadius: '3px',
overflow: 'hidden',
}}
>
<div
style={{
width: bar.width,
height: '100%',
background: bar.gradient,
borderRadius: '3px',
}}
/>
</div>
<span
style={{
color: bar.color,
fontWeight: 600,
width: '32px',
textAlign: 'right',
}}
>
{bar.count}
</span>
</div>
))}
</div>
<div
style={{
marginTop: '4px',
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
}}
>
(50L이하) (100L+)
</div>
</div>
{/* HATS 표준코드 체계 */}
<div>
<div
style={{
fontSize: 'var(--font-size-caption)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '6px',
}}
>
🏷 HATS 10
</div>
<div
style={{
display: 'grid',
gridTemplateColumns: 'repeat(5,1fr)',
gap: '3px',
fontSize: 'var(--font-size-caption)',
textAlign: 'center',
}}
>
{[
{ label: '1.오염원', color: 'var(--color-accent)', bg: 'rgba(6,182,212,.06)' },
{ label: '2.위치·일시', color: 'var(--color-accent)', bg: 'rgba(6,182,212,.06)' },
{ label: '3.기상환경', color: 'var(--color-accent)', bg: 'rgba(6,182,212,.06)' },
{ label: '4.사고유형', color: 'var(--color-accent)', bg: 'rgba(6,182,212,.06)' },
{ label: '5.유출물질', color: 'var(--color-accent)', bg: 'rgba(6,182,212,.06)' },
{ label: '6.대응', color: 'var(--color-accent)', bg: 'rgba(6,182,212,.06)' },
{ label: '7.피해복구', color: 'var(--color-accent)', bg: 'rgba(6,182,212,.06)' },
{ label: '8.사고원인', color: 'var(--color-accent)', bg: 'rgba(6,182,212,.06)' },
{ label: '9.피해상황', color: 'var(--color-accent)', bg: 'rgba(6,182,212,.06)' },
{ label: '10.영향', color: 'var(--color-accent)', bg: 'rgba(6,182,212,.06)' },
].map((item) => (
<div
key={item.label}
style={{
padding: '5px 2px',
background: item.bg,
borderRadius: '3px',
color: item.color,
fontWeight: 600,
}}
>
{item.label}
</div>
))}
</div>
<div
style={{
marginTop: '6px',
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.5,
}}
>
(GPS , , , , CAS번호·SEBC ).{' '}
<b style={{ color: 'var(--color-accent)' }}>WING </b>
.
</div>
</div>
</div>
</div>
{/* 국내외 사고관리시스템 비교 */}
<div className={`${cardBg} rounded-[10px] p-4 mb-4`}>
<div
style={{
fontSize: 'var(--font-size-label-1)',
fontWeight: 700,
color: 'var(--fg-default)',
marginBottom: '10px',
}}
>
🌐 HNS/
</div>
<div style={{ overflowX: 'auto' }}>
<table
style={{
width: '100%',
borderCollapse: 'collapse',
fontSize: 'var(--font-size-caption)',
}}
>
<thead>
<tr style={{ background: 'rgba(6,182,212,.06)' }}>
<th
style={{
padding: '6px 8px',
textAlign: 'left',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--color-accent)',
}}
>
</th>
<th
style={{
padding: '6px 8px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--color-accent)',
}}
>
eMARS (EU)
</th>
<th
style={{
padding: '6px 8px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--color-accent)',
}}
>
PSID ()
</th>
<th
style={{
padding: '6px 8px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--color-accent)',
}}
>
RISCAD ()
</th>
<th
style={{
padding: '6px 8px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--color-accent)',
}}
>
CSC ()
</th>
<th
style={{
padding: '6px 8px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--color-accent)',
fontWeight: 800,
}}
>
WING ()
</th>
</tr>
</thead>
<tbody>
{[
{
label: '운영기관',
eu: 'EC',
us: 'CCPS',
jp: 'JST·AIST',
kr: '화학물질안전원',
wing: '해양경찰청',
},
{
label: '대상',
eu: '중대화학사고',
us: '공정사고',
jp: '화학사고',
kr: '화학사고',
wing: '해상 HNS',
},
{
label: '초점',
eu: '산업시설',
us: '산업시설',
jp: '사고원인·산업',
kr: '사고물질',
wing: '해역·선박·확산',
},
{ label: '형태', eu: '웹DB', us: '앱CD', jp: '웹', kr: '앱', wing: '웹+GIS 통합' },
{
label: '해상 특화',
eu: '△',
us: '✕',
jp: '✕',
kr: '△',
wing: '◎',
wingColor: 'var(--color-accent)',
},
].map((row, i) => (
<tr
key={row.label}
style={{ borderBottom: i < 4 ? '1px solid rgba(255,255,255,.04)' : undefined }}
>
<td style={{ padding: '5px 8px', color: 'var(--fg-disabled)' }}>{row.label}</td>
<td style={{ textAlign: 'center', color: 'var(--fg-sub)' }}>{row.eu}</td>
<td style={{ textAlign: 'center', color: 'var(--fg-sub)' }}>{row.us}</td>
<td style={{ textAlign: 'center', color: 'var(--fg-sub)' }}>{row.jp}</td>
<td
style={{
textAlign: 'center',
color: i === 4 ? 'var(--color-accent)' : 'var(--fg-sub)',
}}
>
{row.kr}
</td>
<td
style={{
textAlign: 'center',
color: (row as { wingColor?: string }).wingColor ?? 'var(--color-accent)',
fontWeight: 600,
}}
>
{row.wing}
</td>
</tr>
))}
</tbody>
</table>
</div>
<div
style={{
marginTop: '8px',
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
}}
>
WING은 HATS + CAMEO/ALOHA + WRF-Chem + ROMS를
</div>
</div>
{/* WING 적용 시사점 */}
<div className={`${card} ${cardBg}`}>
<div className="flex items-center gap-2 mb-[10px]">
<span
style={{
fontSize: 'var(--font-size-label-1)',
fontWeight: 700,
color: 'var(--color-accent)',
}}
>
💡 WING
</span>
</div>
<div className="grid grid-cols-5 gap-2" style={{ fontSize: 'var(--font-size-caption)' }}>
{[
{
icon: '🔗',
title: '통합정보시스템',
sub: 'CARIS·CAMEO·기상·GIS 통합 → 사고 대응 의사결정 지원',
style: {},
},
{
icon: '🏭',
title: '항만별 특화 대응',
sub: '울산·여수·대산 등 고위험 항만 맞춤 시나리오 사전 구축',
style: {},
},
{
icon: '📡',
title: '실시간 모니터링',
sub: 'HNS 블랙박스 + 대기확산 예측 + 위험구역 자동 설정',
style: {},
},
{
icon: '🤝',
title: '통합지휘 지원',
sub: '미국 ICS 모델 참조 — 다기관 협업 정보공유 플랫폼',
style: {},
},
{
icon: '📊',
title: 'HATS 사고이력',
sub: '표준코드 DB 연동 → 동일해역·물질 과거사고 즉시 조회',
style: {
background: 'rgba(6,182,212,.04)',
border: '1px solid rgba(6,182,212,.15)',
},
titleColor: 'var(--color-accent)',
},
].map((item) => (
<div
key={item.title}
style={{
padding: '10px',
background: 'var(--bg-card)',
border: '1px solid var(--stroke-default)',
borderRadius: '6px',
textAlign: 'center',
...item.style,
}}
>
<div style={{ fontSize: 'var(--font-size-title-2)', marginBottom: '4px' }}>
{item.icon}
</div>
<div
style={{
fontWeight: 700,
color: (item as { titleColor?: string }).titleColor ?? 'var(--fg-default)',
marginBottom: '3px',
}}
>
{item.title}
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
lineHeight: 1.5,
}}
>
{item.sub}
</div>
</div>
))}
</div>
</div>
</>
);
}
function GaussianModelPanel() {
return (
<>
<div className="grid grid-cols-2 gap-4 mb-4">
{/* 가우시안 플룸 모델 */}
<div className={`${cardBg} rounded-[10px] p-4`}>
<div className="flex items-center gap-2 mb-3">
<div
style={{
width: '28px',
height: '28px',
borderRadius: '6px',
background: 'rgba(6,182,212,.15)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: 'var(--font-size-title-3)',
}}
>
🌀
</div>
<div>
<div
style={{
fontSize: 'var(--font-size-title-4)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
Gaussian Plume Model
</div>
<div
className="font-mono"
style={{ fontSize: 'var(--font-size-caption)', color: 'var(--color-accent)' }}
>
(Continuous Release)
</div>
</div>
</div>
<div
style={{
background: 'var(--bg-base)',
border: '1px solid rgba(6,182,212,.2)',
borderRadius: '8px',
padding: '14px',
marginBottom: '12px',
}}
className="font-mono"
>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
marginBottom: '6px',
fontWeight: 600,
}}
>
📌 (Concentration Equation)
</div>
<div
style={{
fontSize: 'var(--font-size-label-2)',
color: 'var(--color-accent)',
lineHeight: 2,
letterSpacing: '.3px',
}}
>
C(x,y,z) = <span style={{ color: 'var(--color-accent)' }}>Q</span> / (2π ·{' '}
<span style={{ color: 'var(--color-accent)' }}>
σ<sub>y</sub>
</span>{' '}
·{' '}
<span style={{ color: 'var(--color-accent)' }}>
σ<sub>z</sub>
</span>{' '}
· <span style={{ color: 'var(--color-accent)' }}>u</span>)
<br />× exp(-y² / 2
<span style={{ color: 'var(--color-accent)' }}>
σ<sub>y</sub>
</span>
²)
<br />× [exp(-(z-H)² / 2
<span style={{ color: 'var(--color-accent)' }}>
σ<sub>z</sub>
</span>
²) + exp(-(z+H)² / 2
<span style={{ color: 'var(--color-accent)' }}>
σ<sub>z</sub>
</span>
²)]
</div>
</div>
<div
className="grid grid-cols-2 gap-[6px]"
style={{ fontSize: 'var(--font-size-caption)' }}
>
<div
style={{
padding: '6px 8px',
background: 'rgba(6,182,212,.05)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '4px',
}}
>
<span className="font-mono" style={{ color: 'var(--color-accent)', fontWeight: 700 }}>
Q
</span>{' '}
<span style={{ color: 'var(--fg-disabled)' }}>= (g/s)</span>
</div>
<div
style={{
padding: '6px 8px',
background: 'rgba(6,182,212,.05)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '4px',
}}
>
<span className="font-mono" style={{ color: 'var(--color-accent)', fontWeight: 700 }}>
u
</span>{' '}
<span style={{ color: 'var(--fg-disabled)' }}>= (m/s)</span>
</div>
<div
style={{
padding: '6px 8px',
background: 'rgba(6,182,212,.05)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '4px',
}}
>
<span className="font-mono" style={{ color: 'var(--color-accent)', fontWeight: 700 }}>
σ<sub>y</sub>
</span>{' '}
<span style={{ color: 'var(--fg-disabled)' }}>= </span>
</div>
<div
style={{
padding: '6px 8px',
background: 'rgba(6,182,212,.05)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '4px',
}}
>
<span className="font-mono" style={{ color: 'var(--color-accent)', fontWeight: 700 }}>
σ<sub>z</sub>
</span>{' '}
<span style={{ color: 'var(--fg-disabled)' }}>= </span>
</div>
<div
style={{
padding: '6px 8px',
background: 'rgba(6,182,212,.04)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '4px',
gridColumn: 'span 2',
}}
>
<span className="font-mono" style={{ color: 'var(--color-accent)', fontWeight: 700 }}>
H
</span>{' '}
<span style={{ color: 'var(--fg-disabled)' }}>
= (m) +
</span>
</div>
</div>
<div
style={{
marginTop: '10px',
padding: '8px',
background: 'rgba(6,182,212,.04)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '6px',
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.6,
}}
>
💡 <b style={{ color: 'var(--color-accent)' }}> :</b> ,
, . HNS .
</div>
</div>
{/* 가우시안 퍼프 모델 */}
<div className={`${cardBg} rounded-[10px] p-4`}>
<div className="flex items-center gap-2 mb-3">
<div
style={{
width: '28px',
height: '28px',
borderRadius: '6px',
background: 'rgba(6,182,212,.15)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: 'var(--font-size-title-3)',
}}
>
💨
</div>
<div>
<div
style={{
fontSize: 'var(--font-size-title-4)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
Gaussian Puff Model
</div>
<div
className="font-mono"
style={{ fontSize: 'var(--font-size-caption)', color: 'var(--color-accent)' }}
>
(Instantaneous Release)
</div>
</div>
</div>
<div
style={{
background: 'var(--bg-base)',
border: '1px solid rgba(6,182,212,.2)',
borderRadius: '8px',
padding: '14px',
marginBottom: '12px',
}}
className="font-mono"
>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
marginBottom: '6px',
fontWeight: 600,
}}
>
📌 (Puff Concentration)
</div>
<div
style={{
fontSize: 'var(--font-size-label-2)',
color: 'var(--color-accent)',
lineHeight: 2,
letterSpacing: '.3px',
}}
>
C(x,y,z,t) = <span style={{ color: 'var(--color-accent)' }}>M</span> / [(2π)
<sup>3/2</sup> ·{' '}
<span style={{ color: 'var(--color-accent)' }}>
σ<sub>x</sub>
</span>{' '}
·{' '}
<span style={{ color: 'var(--color-accent)' }}>
σ<sub>y</sub>
</span>{' '}
·{' '}
<span style={{ color: 'var(--color-accent)' }}>
σ<sub>z</sub>
</span>
]
<br />× exp(-(x-<span style={{ color: 'var(--color-accent)' }}>u</span>t)² / 2
<span style={{ color: 'var(--color-accent)' }}>
σ<sub>x</sub>
</span>
²)
<br />× exp(-y² / 2
<span style={{ color: 'var(--color-accent)' }}>
σ<sub>y</sub>
</span>
²)
<br />× [exp(-(z-H)² / 2
<span style={{ color: 'var(--color-accent)' }}>
σ<sub>z</sub>
</span>
²) + exp(-(z+H)² / 2
<span style={{ color: 'var(--color-accent)' }}>
σ<sub>z</sub>
</span>
²)]
</div>
</div>
<div
className="grid grid-cols-2 gap-[6px]"
style={{ fontSize: 'var(--font-size-caption)' }}
>
<div
style={{
padding: '6px 8px',
background: 'rgba(6,182,212,.05)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '4px',
}}
>
<span className="font-mono" style={{ color: 'var(--color-accent)', fontWeight: 700 }}>
M
</span>{' '}
<span style={{ color: 'var(--fg-disabled)' }}>= (g)</span>
</div>
<div
style={{
padding: '6px 8px',
background: 'rgba(6,182,212,.05)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '4px',
}}
>
<span className="font-mono" style={{ color: 'var(--color-accent)', fontWeight: 700 }}>
t
</span>{' '}
<span style={{ color: 'var(--fg-disabled)' }}>= (s)</span>
</div>
<div
style={{
padding: '6px 8px',
background: 'rgba(6,182,212,.05)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '4px',
gridColumn: 'span 2',
}}
>
<span className="font-mono" style={{ color: 'var(--color-accent)', fontWeight: 700 }}>
σ<sub>x</sub>
</span>{' '}
<span style={{ color: 'var(--fg-disabled)' }}>
= Plume에서는 u에
</span>
</div>
</div>
<div
style={{
marginTop: '10px',
padding: '8px',
background: 'rgba(6,182,212,.04)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '6px',
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.6,
}}
>
💡 <b style={{ color: 'var(--color-accent)' }}> :</b> ,
· . LPG/LNG , .
</div>
</div>
</div>
{/* Pasquill-Gifford 확산 계수 테이블 */}
<div className={`${cardBg} rounded-[10px] p-4 mb-4`}>
<div className="flex items-center justify-between mb-[14px]">
<div
style={{
fontSize: 'var(--font-size-title-4)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
📊 Pasquill-Gifford
</div>
<div
className="font-mono"
style={{ fontSize: 'var(--font-size-caption)', color: 'var(--fg-disabled)' }}
>
σ<sub>y</sub> = a·x<sup>b</sup> , σ<sub>z</sub> = c·x<sup>d</sup> + f
</div>
</div>
<div style={{ overflowX: 'auto' }}>
<table
style={{
width: '100%',
borderCollapse: 'collapse',
fontSize: 'var(--font-size-caption)',
}}
>
<thead>
<tr style={{ background: 'rgba(6,182,212,.08)' }}>
<th
style={{
padding: '8px 10px',
textAlign: 'left',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--color-accent)',
fontWeight: 700,
}}
>
</th>
<th
style={{
padding: '8px 10px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--fg-sub)',
}}
>
</th>
<th
style={{
padding: '8px 10px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--fg-sub)',
}}
>
</th>
<th
className="font-mono"
style={{
padding: '8px 10px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--color-accent)',
}}
>
σ<sub>y</sub> (a, b)
</th>
<th
className="font-mono"
style={{
padding: '8px 10px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--color-accent)',
}}
>
σ<sub>z</sub> (c, d, f)
</th>
<th
style={{
padding: '8px 10px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--color-accent)',
}}
>
</th>
<th
style={{
padding: '8px 10px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--color-accent)',
}}
>
</th>
</tr>
</thead>
<tbody>
{[
{
grade: 'A',
class: '매우 불안정',
cond: '맑은 날 강한 일사',
sy: '0.3658, 0.9024',
sz: '0.192, 0.936, 0',
wind: '< 2 m/s',
ocean: {
label: '드물게',
bg: 'rgba(6,182,212,.12)',
color: 'var(--color-accent)',
},
gradeColor: 'var(--color-accent)',
rowBg: undefined,
},
{
grade: 'B',
class: '불안정',
cond: '맑은 날 약한 일사',
sy: '0.2751, 0.9031',
sz: '0.156, 0.922, 0',
wind: '23 m/s',
ocean: {
label: '드물게',
bg: 'rgba(6,182,212,.12)',
color: 'var(--color-accent)',
},
gradeColor: 'var(--color-accent)',
rowBg: undefined,
},
{
grade: 'C',
class: '약간 불안정',
cond: '흐린 날 주간',
sy: '0.2090, 0.9031',
sz: '0.116, 0.905, 0',
wind: '35 m/s',
ocean: {
label: '적합',
bg: 'rgba(6,182,212,.12)',
color: 'var(--color-accent)',
},
gradeColor: 'var(--color-accent)',
rowBg: undefined,
},
{
grade: 'D ★',
class: '중립',
cond: '흐린 날 / 해상풍',
sy: '0.1471, 0.9031',
sz: '0.079, 0.881, 0',
wind: '56 m/s',
ocean: {
label: '★ 해양 대표',
bg: 'rgba(6,182,212,.15)',
color: 'var(--color-accent)',
fontWeight: 700,
},
gradeColor: 'var(--color-accent)',
rowBg: 'rgba(6,182,212,.03)',
},
{
grade: 'E',
class: '약간 안정',
cond: '야간 약한 바람',
sy: '0.1046, 0.9031',
sz: '0.064, 0.871, 0',
wind: '35 m/s',
ocean: {
label: '적합',
bg: 'rgba(6,182,212,.12)',
color: 'var(--color-accent)',
},
gradeColor: 'var(--color-accent)',
rowBg: undefined,
},
{
grade: 'F',
class: '안정',
cond: '야간 맑은 하늘',
sy: '0.0722, 0.9031',
sz: '0.051, 0.814, 0',
wind: '< 3 m/s',
ocean: {
label: '위험↑',
bg: 'rgba(6,182,212,.12)',
color: 'var(--color-accent)',
},
gradeColor: 'var(--color-accent)',
rowBg: undefined,
},
].map((row, idx) => (
<tr
key={row.grade}
style={{
borderBottom: idx < 5 ? '1px solid rgba(255,255,255,.04)' : undefined,
background: row.rowBg,
}}
>
<td style={{ padding: '7px 10px', fontWeight: 700, color: row.gradeColor }}>
{row.grade}
</td>
<td
style={{ padding: '7px 10px', textAlign: 'center', color: 'var(--fg-default)' }}
>
{row.class}
</td>
<td style={{ padding: '7px 10px', textAlign: 'center', color: 'var(--fg-sub)' }}>
{row.cond}
</td>
<td
className="font-mono"
style={{
padding: '7px 10px',
textAlign: 'center',
color: 'var(--color-accent)',
}}
>
{row.sy}
</td>
<td
className="font-mono"
style={{
padding: '7px 10px',
textAlign: 'center',
color: 'var(--color-accent)',
}}
>
{row.sz}
</td>
<td
className="font-mono"
style={{
padding: '7px 10px',
textAlign: 'center',
color: 'var(--color-accent)',
}}
>
{row.wind}
</td>
<td style={{ padding: '7px 10px', textAlign: 'center' }}>
<span
style={{
padding: '2px 6px',
borderRadius: '4px',
background: row.ocean.bg,
color: row.ocean.color,
fontSize: 'var(--font-size-caption)',
fontWeight: (row.ocean as { fontWeight?: number }).fontWeight ?? 600,
}}
>
{row.ocean.label}
</span>
</td>
</tr>
))}
</tbody>
</table>
</div>
<div
style={{
marginTop: '10px',
padding: '8px 10px',
background: 'rgba(6,182,212,.04)',
border: '1px solid rgba(6,182,212,.1)',
borderRadius: '6px',
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.6,
}}
>
<b style={{ color: 'var(--color-accent)' }}>D ()</b>
. · A~C . F ()
<b style={{ color: 'var(--color-accent)' }}> </b>.
</div>
</div>
{/* 플룸 vs 퍼프 비교 */}
<div className={`${cardBg} rounded-[10px] p-4`}>
<div
style={{
fontSize: 'var(--font-size-title-4)',
fontWeight: 700,
color: 'var(--fg-default)',
marginBottom: '14px',
}}
>
Plume vs Puff
</div>
<div className="grid grid-cols-2 gap-3">
<div
style={{
padding: '12px',
background: 'rgba(6,182,212,.04)',
border: '1px solid rgba(6,182,212,.15)',
borderRadius: '8px',
}}
>
<div
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '8px',
}}
>
🌀 Plume ( )
</div>
<div
className="flex flex-col gap-[5px]"
style={{ fontSize: 'var(--font-size-caption)', color: 'var(--fg-sub)' }}
>
{[
'유출 지속시간 > 10분',
'탱크 균열/배관 파손 — 지속적 누출',
'풍속 > 1.5 m/s (정상류 가정 가능)',
'톨루엔, 벤젠, 자일렌 등 증발성 액체',
'암모니아 냉동 저장탱크 누출',
].map((item) => (
<div key={item} className="flex items-center gap-[5px]">
<span style={{ color: 'var(--color-accent)' }}></span> {item}
</div>
))}
</div>
</div>
<div
style={{
padding: '12px',
background: 'rgba(6,182,212,.04)',
border: '1px solid rgba(6,182,212,.15)',
borderRadius: '8px',
}}
>
<div
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '8px',
}}
>
💨 Puff ( )
</div>
<div
className="flex flex-col gap-[5px]"
style={{ fontSize: 'var(--font-size-caption)', color: 'var(--fg-sub)' }}
>
{[
'유출 지속시간 < 10분',
'탱크 폭발/BLEVE — 순간 방출',
'풍향 변동이 큰 경우 (여러 퍼프 중첩)',
'LPG, 수소, LNG 탱크 파열',
'컨테이너 화학물질 돌발 유출',
].map((item) => (
<div key={item} className="flex items-center gap-[5px]">
<span style={{ color: 'var(--color-accent)' }}></span> {item}
</div>
))}
</div>
</div>
</div>
</div>
</>
);
}
function SubstanceScenarioPanel() {
return (
<>
<div className="grid grid-cols-2 gap-4 mb-4">
{/* 암모니아 */}
<div className={`${cardBg} rounded-[10px] p-4`}>
<div className="flex items-center justify-between mb-[10px]">
<div className="flex items-center gap-2">
<span style={{ fontSize: 'var(--font-size-title-1)' }}>🧪</span>
<span
style={{
fontSize: 'var(--font-size-title-3)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
(NH)
</span>
</div>
<span
style={{
padding: '3px 8px',
borderRadius: '6px',
background: 'rgba(6,182,212,.12)',
color: 'var(--color-accent)',
fontSize: 'var(--font-size-caption)',
fontWeight: 700,
}}
>
</span>
</div>
<div className="grid grid-cols-3 gap-[6px] mb-[10px]">
{[
{ val: '-33°C', label: '비등점', color: 'var(--color-accent)' },
{ val: '0.682', label: '비중', color: 'var(--color-accent)' },
{ val: '300 ppm', label: 'IDLH', color: 'var(--color-accent)' },
].map((item) => (
<div
key={item.label}
style={{
padding: '6px',
background: 'var(--bg-base)',
borderRadius: '4px',
textAlign: 'center',
}}
>
<div
className="font-mono"
style={{
fontSize: 'var(--font-size-title-3)',
fontWeight: 700,
color: item.color,
}}
>
{item.val}
</div>
<div style={{ fontSize: 'var(--font-size-caption)', color: 'var(--fg-disabled)' }}>
{item.label}
</div>
</div>
))}
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.7,
}}
>
<div>
<b style={{ color: 'var(--color-accent)' }}> </b> Flash
Evaporation
</div>
<div>
2D :{' '}
<span className="font-mono" style={{ color: 'var(--color-accent)' }}>
= 0.0168t 0.01
</span>
</div>
<div>
3D :{' '}
<span className="font-mono" style={{ color: 'var(--color-accent)' }}>
= 0.0182t 0.0112
</span>
</div>
<div>
<b style={{ color: 'var(--color-accent)' }}> 10km</b>
</div>
</div>
</div>
{/* 메탄올 */}
<div className={`${cardBg} rounded-[10px] p-4`}>
<div className="flex items-center justify-between mb-[10px]">
<div className="flex items-center gap-2">
<span style={{ fontSize: 'var(--font-size-title-1)' }}>🧫</span>
<span
style={{
fontSize: 'var(--font-size-title-3)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
(CHOH)
</span>
</div>
<span
style={{
padding: '3px 8px',
borderRadius: '6px',
background: 'rgba(6,182,212,.12)',
color: 'var(--color-accent)',
fontSize: 'var(--font-size-caption)',
fontWeight: 700,
}}
>
+
</span>
</div>
<div className="grid grid-cols-3 gap-[6px] mb-[10px]">
{[
{ val: '64.7°C', label: '비등점', color: 'var(--color-accent)' },
{ val: '0.791', label: '비중', color: 'var(--color-accent)' },
{ val: '6,000 ppm', label: 'IDLH', color: 'var(--color-accent)' },
].map((item) => (
<div
key={item.label}
style={{
padding: '6px',
background: 'var(--bg-base)',
borderRadius: '4px',
textAlign: 'center',
}}
>
<div
className="font-mono"
style={{
fontSize: 'var(--font-size-title-3)',
fontWeight: 700,
color: item.color,
}}
>
{item.val}
</div>
<div style={{ fontSize: 'var(--font-size-caption)', color: 'var(--fg-disabled)' }}>
{item.label}
</div>
</div>
))}
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.7,
}}
>
<div>
+ <b style={{ color: 'var(--color-accent)' }}> </b>
</div>
<div>
{' '}
<span className="font-mono" style={{ color: 'var(--color-accent)' }}>
11°C
</span>{' '}
</div>
<div>
· <b style={{ color: 'var(--color-accent)' }}> </b>,
</div>
<div>
LFL~UFL:{' '}
<span className="font-mono" style={{ color: 'var(--color-accent)' }}>
6.0% ~ 36.5%
</span>
</div>
</div>
</div>
{/* 수소 */}
<div className={`${cardBg} rounded-[10px] p-4`}>
<div className="flex items-center justify-between mb-[10px]">
<div className="flex items-center gap-2">
<span style={{ fontSize: 'var(--font-size-title-1)' }}></span>
<span
style={{
fontSize: 'var(--font-size-title-3)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
(H)
</span>
</div>
<span
style={{
padding: '3px 8px',
borderRadius: '6px',
background: 'rgba(6,182,212,.12)',
color: 'var(--color-accent)',
fontSize: 'var(--font-size-caption)',
fontWeight: 700,
}}
>
</span>
</div>
<div className="grid grid-cols-3 gap-[6px] mb-[10px]">
{[
{ val: '-253°C', label: '비등점', color: 'var(--color-accent)' },
{ val: '0.071', label: '비중', color: 'var(--color-accent)' },
{ val: 'N/A', label: 'IDLH(질식)', color: 'var(--color-accent)' },
].map((item) => (
<div
key={item.label}
style={{
padding: '6px',
background: 'var(--bg-base)',
borderRadius: '4px',
textAlign: 'center',
}}
>
<div
className="font-mono"
style={{
fontSize: 'var(--font-size-title-3)',
fontWeight: 700,
color: item.color,
}}
>
{item.val}
</div>
<div style={{ fontSize: 'var(--font-size-caption)', color: 'var(--fg-disabled)' }}>
{item.label}
</div>
</div>
))}
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.7,
}}
>
<div>
<b style={{ color: 'var(--color-accent)' }}>14 </b>
</div>
<div>
LFL~UFL:{' '}
<span className="font-mono" style={{ color: 'var(--color-accent)' }}>
4.0% ~ 75.0%
</span>{' '}
( )
</div>
<div>
{' '}
<span className="font-mono" style={{ color: 'var(--color-accent)' }}>
0.017 mJ
</span>{' '}
( )
</div>
<div>
Puff <b style={{ color: 'var(--color-accent)' }}>BLEVE/VCE</b>
</div>
</div>
</div>
{/* LNG */}
<div className={`${cardBg} rounded-[10px] p-4`}>
<div className="flex items-center justify-between mb-[10px]">
<div className="flex items-center gap-2">
<span style={{ fontSize: 'var(--font-size-title-1)' }}>🔵</span>
<span
style={{
fontSize: 'var(--font-size-title-3)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
LNG (CH)
</span>
</div>
<span
style={{
padding: '3px 8px',
borderRadius: '6px',
background: 'rgba(6,182,212,.12)',
color: 'var(--color-accent)',
fontSize: 'var(--font-size-caption)',
fontWeight: 700,
}}
>
</span>
</div>
<div className="grid grid-cols-3 gap-[6px] mb-[10px]">
{[
{ val: '-162°C', label: '비등점', color: 'var(--color-accent)' },
{ val: '0.450', label: '비중', color: 'var(--color-accent)' },
{ val: 'N/A', label: 'IDLH(질식)', color: 'var(--color-accent)' },
].map((item) => (
<div
key={item.label}
style={{
padding: '6px',
background: 'var(--bg-base)',
borderRadius: '4px',
textAlign: 'center',
}}
>
<div
className="font-mono"
style={{
fontSize: 'var(--font-size-title-3)',
fontWeight: 700,
color: item.color,
}}
>
{item.val}
</div>
<div style={{ fontSize: 'var(--font-size-caption)', color: 'var(--fg-disabled)' }}>
{item.label}
</div>
</div>
))}
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.7,
}}
>
<div>
<b style={{ color: 'var(--color-accent)' }}>RPT</b>(Rapid Phase
Transition)
</div>
<div>
Pool {' '}
<span className="font-mono" style={{ color: 'var(--color-accent)' }}>
0.025t
</span>
</div>
<div>
:{' '}
<span className="font-mono" style={{ color: 'var(--color-accent)' }}>
5.0% ~ 15.0%
</span>
</div>
<div>
<b style={{ color: 'var(--color-accent)' }}> </b>
</div>
</div>
</div>
</div>
{/* 물질별 AEGL 비교표 */}
<div className={`${cardBg} rounded-[10px] p-4`}>
<div
style={{
fontSize: 'var(--font-size-title-4)',
fontWeight: 700,
color: 'var(--fg-default)',
marginBottom: '12px',
}}
>
📊 AEGL/ERPG (ppm, 1 )
</div>
<div
style={{
display: 'grid',
gridTemplateColumns: 'repeat(5,1fr)',
gap: '8px',
fontSize: 'var(--font-size-caption)',
}}
>
{/* 헤더 */}
<div
style={{
padding: '8px',
background: 'var(--bg-base)',
borderRadius: '6px',
textAlign: 'center',
}}
>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
marginBottom: '4px',
}}
>
</div>
<div style={{ fontWeight: 700, color: 'var(--fg-default)' }}></div>
</div>
{[
{ icon: '🧪', label: 'NH₃', color: 'var(--color-accent)' },
{ icon: '🧫', label: 'MeOH', color: 'var(--color-accent)' },
{ icon: '⚡', label: 'H₂', color: 'var(--color-accent)' },
{ icon: '🔵', label: 'LNG', color: 'var(--color-accent)' },
].map((item) => (
<div
key={item.label}
style={{
padding: '8px',
background: 'var(--bg-base)',
borderRadius: '6px',
textAlign: 'center',
}}
>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
marginBottom: '4px',
}}
>
{item.icon}
</div>
<div style={{ fontWeight: 700, color: item.color }}>{item.label}</div>
</div>
))}
{/* AEGL-1 */}
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.06)',
borderRadius: '4px',
textAlign: 'center',
fontWeight: 600,
color: 'var(--color-accent)',
}}
>
AEGL-1
</div>
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.04)',
borderRadius: '4px',
textAlign: 'center',
}}
className="font-mono"
>
30
</div>
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.04)',
borderRadius: '4px',
textAlign: 'center',
}}
className="font-mono"
>
670
</div>
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.04)',
borderRadius: '4px',
textAlign: 'center',
color: 'var(--fg-disabled)',
}}
className="font-mono"
>
N/A
</div>
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.04)',
borderRadius: '4px',
textAlign: 'center',
color: 'var(--fg-disabled)',
}}
className="font-mono"
>
N/A
</div>
{/* AEGL-2 */}
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.06)',
borderRadius: '4px',
textAlign: 'center',
fontWeight: 600,
color: 'var(--color-accent)',
}}
>
AEGL-2
</div>
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.04)',
borderRadius: '4px',
textAlign: 'center',
}}
className="font-mono"
>
160
</div>
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.04)',
borderRadius: '4px',
textAlign: 'center',
}}
className="font-mono"
>
2,100
</div>
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.04)',
borderRadius: '4px',
textAlign: 'center',
color: 'var(--fg-disabled)',
}}
className="font-mono"
>
N/A
</div>
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.04)',
borderRadius: '4px',
textAlign: 'center',
color: 'var(--fg-disabled)',
}}
className="font-mono"
>
N/A
</div>
{/* AEGL-3 */}
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.06)',
borderRadius: '4px',
textAlign: 'center',
fontWeight: 600,
color: 'var(--color-accent)',
}}
>
AEGL-3
</div>
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.04)',
borderRadius: '4px',
textAlign: 'center',
color: 'var(--color-accent)',
fontWeight: 600,
}}
className="font-mono"
>
1,100
</div>
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.04)',
borderRadius: '4px',
textAlign: 'center',
color: 'var(--color-accent)',
fontWeight: 600,
}}
className="font-mono"
>
14,000
</div>
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.04)',
borderRadius: '4px',
textAlign: 'center',
color: 'var(--fg-disabled)',
}}
className="font-mono"
>
N/A
</div>
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.04)',
borderRadius: '4px',
textAlign: 'center',
color: 'var(--fg-disabled)',
}}
className="font-mono"
>
N/A
</div>
{/* LFL */}
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.06)',
borderRadius: '4px',
textAlign: 'center',
fontWeight: 600,
color: 'var(--color-accent)',
}}
>
LFL (%)
</div>
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.04)',
borderRadius: '4px',
textAlign: 'center',
}}
className="font-mono"
>
15.0
</div>
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.04)',
borderRadius: '4px',
textAlign: 'center',
}}
className="font-mono"
>
6.0
</div>
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.04)',
borderRadius: '4px',
textAlign: 'center',
color: 'var(--color-accent)',
fontWeight: 600,
}}
className="font-mono"
>
4.0
</div>
<div
style={{
padding: '6px',
background: 'rgba(6,182,212,.04)',
borderRadius: '4px',
textAlign: 'center',
}}
className="font-mono"
>
5.0
</div>
</div>
<div
style={{
marginTop: '8px',
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
}}
>
H, LNG는 / AEGL LFL/UFL, (kPa)
</div>
</div>
</>
);
}
/* ═══ Panel 3: 해양환경 보정 ═══ */
function OceanCorrectionPanel() {
return (
<div className="grid grid-cols-2 gap-4 mb-4">
{/* 해양 보정 인자 */}
<div className={`${card} ${cardBg} p-4`}>
<div style={labelStyle('var(--color-accent)')}>🌊 </div>
<div className="flex flex-col gap-2.5">
{/* 해풍·육풍 순환 보정 */}
<div
className="p-2.5 bg-bg-base rounded-md"
style={{ border: '1px solid rgba(6,182,212,.15)' }}
>
<div className="flex items-center justify-between mb-1.5">
<span className="text-label-2 font-bold text-fg">· </span>
<span style={tag('var(--color-accent)')}> </span>
</div>
<div className="text-caption text-fg-sub leading-[1.7]">
()·() .
, <b style={{ color: 'var(--color-accent)' }}> </b>
.
<br />
<span
className="font-mono"
style={{ fontSize: 'var(--font-size-caption)', color: 'var(--color-accent)' }}
>
θ(t) = θ + Δθ · sigmoid((t - t<sub>shift</sub>)/τ)
</span>
</div>
</div>
{/* 해수면 거칠기 */}
<div
className="p-2.5 bg-bg-base rounded-md"
style={{ border: '1px solid rgba(6,182,212,.15)' }}
>
<div className="flex items-center justify-between mb-1.5">
<span className="text-label-2 font-bold text-fg"> (z) </span>
<span style={tag('var(--color-accent)')}></span>
</div>
<div className="text-caption text-fg-sub leading-[1.7]">
(
<span className="font-mono" style={{ color: 'var(--color-accent)' }}>
z 0.0002 m
</span>{' '}
vs 0.5~2.0 m). Charnock :
<br />
<span
className="font-mono"
style={{ fontSize: 'var(--font-size-caption)', color: 'var(--color-accent)' }}
>
z = α<sub>c</sub> · u*² / g (α<sub>c</sub> 0.011~0.018)
</span>
</div>
</div>
{/* SST 영향 */}
<div
className="p-2.5 bg-bg-base rounded-md"
style={{ border: '1px solid rgba(6,182,212,.15)' }}
>
<div className="flex items-center justify-between mb-1.5">
<span className="text-label-2 font-bold text-fg"> (SST) </span>
<span style={tag('var(--color-accent)')}></span>
</div>
<div className="text-caption text-fg-sub leading-[1.7]">
.
SST &lt; T<sub>air</sub> {' '}
<b style={{ color: 'var(--color-accent)' }}> </b>.
</div>
</div>
{/* MABL */}
<div
className="p-2.5 bg-bg-base rounded-md"
style={{ border: '1px solid rgba(6,182,212,.15)' }}
>
<div className="flex items-center justify-between mb-1.5">
<span className="text-label-2 font-bold text-fg"> (MABL) </span>
<span style={tag('var(--color-accent)')}></span>
</div>
<div className="text-caption text-fg-sub leading-[1.7]">
. {' '}
<span className="font-mono" style={{ color: 'var(--color-accent)' }}>
300~800 m
</span>
( 1~2 km) . Fumigation {' '}
<b style={{ color: 'var(--color-accent)' }}> </b>.
</div>
</div>
</div>
</div>
{/* 보정 계수 시각화 */}
<div className="flex flex-col gap-4">
<div className={`${card} ${cardBg} p-4`}>
<div style={labelStyle('var(--color-accent)')}>
📈 (σ<sub>y</sub> at 1km)
</div>
<div className="flex flex-col gap-2">
<div className="flex items-center gap-2">
<span className="text-caption text-fg-disabled min-w-[70px]">P-G </span>
<div className="flex-1 h-5 bg-bg-base rounded overflow-hidden relative">
<div
className="h-full rounded"
style={{
width: '60%',
background: 'var(--color-accent)',
}}
/>
</div>
<span
className="font-mono text-caption min-w-[50px] text-right"
style={{ color: 'var(--color-accent)' }}
>
68 m
</span>
</div>
<div className="flex items-center gap-2">
<span className="text-caption text-fg-disabled min-w-[70px]"> </span>
<div className="flex-1 h-5 bg-bg-base rounded overflow-hidden relative">
<div
className="h-full rounded"
style={{
width: '82%',
background: 'var(--color-accent)',
}}
/>
</div>
<span
className="font-mono text-caption min-w-[50px] text-right"
style={{ color: 'var(--color-accent)' }}
>
92 m
</span>
</div>
<div className="flex items-center gap-2">
<span className="text-caption text-fg-disabled min-w-[70px]">ALOHA</span>
<div className="flex-1 h-5 bg-bg-base rounded overflow-hidden relative">
<div
className="h-full rounded"
style={{
width: '72%',
background: 'var(--color-accent)',
}}
/>
</div>
<span
className="font-mono text-caption min-w-[50px] text-right"
style={{ color: 'var(--color-accent)' }}
>
78 m
</span>
</div>
</div>
<div className="mt-2 text-caption text-fg-disabled">
D등급(), 5 m/s, 1 km
</div>
</div>
<div className={`${card} ${cardBg} p-4`}>
<div style={labelStyle('var(--color-accent)')}>🔬 ALOHA vs </div>
<div className="grid grid-cols-2 gap-2 text-caption">
<div className="p-2 bg-bg-base rounded-md">
<div className="font-bold mb-1" style={{ color: 'var(--color-accent)' }}>
ALOHA (EPA)
</div>
<div className="text-fg-sub leading-[1.6]">
<br />
<br />
<br />
<br /> 1
</div>
</div>
<div
className="p-2 rounded-md"
style={{ background: 'rgba(6,182,212,.04)', border: '1px solid rgba(6,182,212,.1)' }}
>
<div className="font-bold mb-1" style={{ color: 'var(--color-accent)' }}>
( )
</div>
<div className="text-fg-sub leading-[1.6]">
+
<br />
<br />
Charnock z
<br />
/
<br /> MABL
</div>
</div>
</div>
</div>
</div>
</div>
);
}
/* ═══ Panel 4: 모델 검증 ═══ */
function VerificationPanel() {
return (
<div className="grid gap-4 mb-4" style={{ gridTemplateColumns: '2fr 1fr' }}>
{/* 검증 결과 테이블 */}
<div className={`${card} ${cardBg} p-4`}>
<div style={labelStyle('var(--color-accent)')}>
</div>
<div className="overflow-x-auto">
<table className="w-full text-caption" style={{ borderCollapse: 'collapse' }}>
<thead>
<tr style={{ background: 'rgba(6,182,212,.06)' }}>
<th
className="p-2 text-left"
style={{
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--color-accent)',
}}
>
</th>
<th
className="p-2 text-center"
style={{
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--color-accent)',
}}
>
ALOHA
</th>
<th
className="p-2 text-center"
style={{
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--color-accent)',
}}
>
</th>
<th
className="p-2 text-center"
style={{ borderBottom: '2px solid var(--stroke-light)', color: 'var(--fg-sub)' }}
>
</th>
<th
className="p-2 text-center"
style={{ borderBottom: '2px solid var(--stroke-light)', color: 'var(--fg-sub)' }}
>
</th>
</tr>
</thead>
<tbody>
<tr style={{ borderBottom: '1px solid rgba(255,255,255,.04)' }}>
<td className="p-2 text-fg">NH (AEGL-2)</td>
<td className="p-2 text-center font-mono" style={{ color: 'var(--color-accent)' }}>
8.2 km
</td>
<td className="p-2 text-center font-mono" style={{ color: 'var(--color-accent)' }}>
7.1 km
</td>
<td className="p-2 text-center font-mono text-fg">6.8 km</td>
<td className="p-2 text-center">
<span className="font-bold font-mono" style={{ color: 'var(--color-accent)' }}>
+20.6%
</span>
{' / '}
<span className="font-bold font-mono" style={{ color: 'var(--color-accent)' }}>
+4.4%
</span>
</td>
</tr>
<tr style={{ borderBottom: '1px solid rgba(255,255,255,.04)' }}>
<td className="p-2 text-fg"> 1km (ppm)</td>
<td className="p-2 text-center font-mono" style={{ color: 'var(--color-accent)' }}>
245
</td>
<td className="p-2 text-center font-mono" style={{ color: 'var(--color-accent)' }}>
198
</td>
<td className="p-2 text-center font-mono text-fg">187</td>
<td className="p-2 text-center">
<span className="font-bold font-mono" style={{ color: 'var(--color-accent)' }}>
+31.0%
</span>
{' / '}
<span className="font-bold font-mono" style={{ color: 'var(--color-accent)' }}>
+5.9%
</span>
</td>
</tr>
<tr style={{ borderBottom: '1px solid rgba(255,255,255,.04)' }}>
<td className="p-2 text-fg">MeOH (km²)</td>
<td className="p-2 text-center font-mono" style={{ color: 'var(--color-accent)' }}>
4.8
</td>
<td className="p-2 text-center font-mono" style={{ color: 'var(--color-accent)' }}>
3.6
</td>
<td className="p-2 text-center font-mono text-fg">3.4</td>
<td className="p-2 text-center">
<span className="font-bold font-mono" style={{ color: 'var(--color-accent)' }}>
+41.2%
</span>
{' / '}
<span className="font-bold font-mono" style={{ color: 'var(--color-accent)' }}>
+5.9%
</span>
</td>
</tr>
<tr style={{ borderBottom: '1px solid rgba(255,255,255,.04)' }}>
<td className="p-2 text-fg">H (m)</td>
<td className="p-2 text-center font-mono" style={{ color: 'var(--color-accent)' }}>
280
</td>
<td className="p-2 text-center font-mono" style={{ color: 'var(--color-accent)' }}>
235
</td>
<td className="p-2 text-center font-mono text-fg">220</td>
<td className="p-2 text-center">
<span className="font-bold font-mono" style={{ color: 'var(--color-accent)' }}>
+27.3%
</span>
{' / '}
<span className="font-bold font-mono" style={{ color: 'var(--color-accent)' }}>
+6.8%
</span>
</td>
</tr>
<tr>
<td className="p-2 text-fg">LNG Pool (m)</td>
<td className="p-2 text-center font-mono" style={{ color: 'var(--color-accent)' }}>
165
</td>
<td className="p-2 text-center font-mono" style={{ color: 'var(--color-accent)' }}>
142
</td>
<td className="p-2 text-center font-mono text-fg">138</td>
<td className="p-2 text-center">
<span className="font-bold font-mono" style={{ color: 'var(--color-accent)' }}>
+19.6%
</span>
{' / '}
<span className="font-bold font-mono" style={{ color: 'var(--color-accent)' }}>
+2.9%
</span>
</td>
</tr>
</tbody>
</table>
</div>
<div
className="mt-3 p-2.5 text-caption text-fg-sub leading-[1.7] rounded-md"
style={{ background: 'rgba(6,182,212,.04)', border: '1px solid rgba(6,182,212,.12)' }}
>
<b style={{ color: 'var(--color-accent)' }}>:</b> ALOHA는 {' '}
<b style={{ color: 'var(--color-accent)' }}> 20~40% </b> .
{' '}
<b style={{ color: 'var(--color-accent)' }}> ±5~7%</b> . 1km
.
</div>
</div>
{/* 참고문헌 + 시스템 적용 */}
<div className="flex flex-col gap-3">
<div className={`${card} ${cardBg} p-4`}>
<div className="text-label-1 font-bold text-fg mb-2.5">📚 </div>
<div className="flex flex-col gap-2 text-caption text-fg-sub leading-[1.6]">
<div
className="p-2 bg-bg-base rounded"
style={{ borderLeft: '3px solid var(--color-accent)' }}
>
, "해양 HNS 사고 시 대기확산 예측을 위한 가우시안 모델의 해양환경 보정에 관한
연구", ·, 2014
</div>
<div
className="p-2 bg-bg-base rounded"
style={{ borderLeft: '3px solid var(--color-accent)' }}
>
, "친환경 선박연료 해양 유출 시 대기확산 특성 연구 — 암모니아 기화율 모델링",
KIOST, 2023
</div>
<div
className="p-2 bg-bg-base rounded"
style={{ borderLeft: '3px solid var(--color-accent)' }}
>
EPA, "ALOHA User's Manual", 2024
</div>
<div
className="p-2 bg-bg-base rounded"
style={{ borderLeft: '3px solid var(--color-accent)' }}
>
Pasquill, F., "The Estimation of the Dispersion of Windborne Material", Meteorological
Magazine, 1961
</div>
<div
className="p-2 bg-bg-base rounded"
style={{ borderLeft: '3px solid var(--color-accent)' }}
>
Charnock, H., "Wind stress on a water surface", Q.J.R. Meteorol. Soc., 1955
</div>
<div
className="p-2 bg-bg-base rounded"
style={{ borderLeft: '3px solid var(--color-accent)' }}
>
, "HNS 재난사고에 대한 해양경찰의 대응 방안", , 9(11), pp.77-92,
2013
</div>
<div
className="p-2 bg-bg-base rounded"
style={{ borderLeft: '3px solid var(--color-accent)' }}
>
, "HNS 사고 국가 대비 대응 체제 선진화 방안 연구용역 최종보고서", 2011
</div>
<div
className="p-2 bg-bg-base rounded"
style={{ borderLeft: '3px solid var(--color-accent)' }}
>
· , "해양산업시설 배출 위험유해물질(HNS)의 해양확산 수치모의",
·, 30(s4), pp.42-51, 2024
</div>
<div
className="p-2 bg-bg-base rounded"
style={{ borderLeft: '3px solid var(--color-accent)' }}
>
· , "신속한 의사결정을 위한 HNS 사고이력관리시스템 설계 및 구현",
·, 23(2), pp.168-176, 2017
</div>
<div
className="p-2 bg-bg-base rounded"
style={{ borderLeft: '3px solid var(--color-accent)' }}
>
····, "인공위성 원격탐사 기반 AI 활용 위험·유해물질(HNS)
탐지 기술 개발", · , pp.125-126, 2025 HNS의
·, Sentinel-2 AI HNS
·, . (RS-2023-00254781)
</div>
<div
className="p-2 bg-bg-base rounded"
style={{ borderLeft: '3px solid var(--color-accent)' }}
>
·····, "다항목 HNS 데이터의 실시간 취득 및 AI를
활용한 결측값 실시간 처리 기술 개발", , pp.85-86,
2024 LSTM(Long Short-Term Memory) HNS
· , ·.
(RS-2021-KS211535)
</div>
</div>
</div>
<div
className="rounded-[10px] p-[14px]"
style={{
background: 'rgba(6,182,212,.04)',
border: '1px solid rgba(6,182,212,.2)',
}}
>
<div className="text-label-2 font-bold mb-2" style={{ color: 'var(--color-accent)' }}>
💡
</div>
<div className="text-caption text-fg-sub leading-[1.7]">
WING ALOHA {' '}
<b style={{ color: 'var(--color-accent)' }}> </b>
. (ALOHA)
() .
</div>
</div>
</div>
</div>
);
}
/* ═══ Panel 5: 실시간 비교 ═══ */
function RealtimeComparePanel() {
return (
<div className={`${card} ${cardBg} p-4 mb-4`}>
{/* 헤더 */}
<div className="flex items-center justify-between mb-3.5">
<div className="text-label-1 font-bold text-fg"> </div>
<div className="flex gap-1.5">
<button
className="px-4 py-1.5 rounded-md text-caption font-bold cursor-pointer text-white"
style={{
background: 'var(--color-accent)',
border: 'none',
}}
>
</button>
<button
className="px-3 py-1.5 rounded-md text-caption font-semibold cursor-pointer text-fg-sub bg-bg-card"
style={{ border: '1px solid var(--stroke-default)' }}
>
</button>
</div>
</div>
{/* 입력 필드 */}
<div className="grid grid-cols-6 gap-2 mb-3.5">
<div>
<label className="text-caption text-fg-disabled block mb-1"></label>
<select
className="px-2 py-1.5 text-caption w-full bg-bg-base text-fg rounded-md outline-none"
style={{ border: '1px solid var(--stroke-default)' }}
>
<option></option>
<option></option>
<option></option>
<option>LNG</option>
<option></option>
</select>
</div>
<div>
<label className="text-caption text-fg-disabled block mb-1"> (kL)</label>
<input
type="number"
defaultValue={12.0}
readOnly
className="px-2 py-1.5 text-caption w-full bg-bg-base text-fg rounded-md outline-none font-mono box-border"
style={{ border: '1px solid var(--stroke-default)' }}
/>
</div>
<div>
<label className="text-caption text-fg-disabled block mb-1"> (m/s)</label>
<input
type="number"
defaultValue={5.2}
readOnly
className="px-2 py-1.5 text-caption w-full bg-bg-base text-fg rounded-md outline-none font-mono box-border"
style={{ border: '1px solid var(--stroke-default)' }}
/>
</div>
<div>
<label className="text-caption text-fg-disabled block mb-1"></label>
<select
className="px-2 py-1.5 text-caption w-full bg-bg-base text-fg rounded-md outline-none"
style={{ border: '1px solid var(--stroke-default)' }}
>
<option>A</option>
<option>B</option>
<option>C</option>
<option>D</option>
<option>E</option>
<option>F</option>
</select>
</div>
<div>
<label className="text-caption text-fg-disabled block mb-1"> (°C)</label>
<input
type="number"
defaultValue={8.5}
readOnly
className="px-2 py-1.5 text-caption w-full bg-bg-base text-fg rounded-md outline-none font-mono box-border"
style={{ border: '1px solid var(--stroke-default)' }}
/>
</div>
<div>
<label className="text-caption text-fg-disabled block mb-1">SST (°C)</label>
<input
type="number"
defaultValue={12.3}
readOnly
className="px-2 py-1.5 text-caption w-full bg-bg-base text-fg rounded-md outline-none font-mono box-border"
style={{ border: '1px solid var(--stroke-default)' }}
/>
</div>
</div>
{/* 결과 카드 */}
<div className="grid grid-cols-3 gap-3">
{/* ALOHA */}
<div
className="p-3.5 rounded-lg text-center"
style={{ background: 'rgba(6,182,212,.04)', border: '1px solid rgba(6,182,212,.2)' }}
>
<div className="text-caption font-bold mb-2" style={{ color: 'var(--color-accent)' }}>
ALOHA (EPA)
</div>
<div
className="font-bold font-mono"
style={{ fontSize: 'var(--font-size-heading-2)', color: 'var(--color-accent)' }}
>
3.8 <span style={{ fontSize: 'var(--font-size-label-1)' }}>km</span>
</div>
<div className="text-caption text-fg-disabled mt-0.5">AEGL-2 </div>
<div className="mt-2 grid grid-cols-2 gap-1 text-caption">
<div className="p-1 bg-bg-base rounded">
<span className="text-fg-disabled"></span>
<br />
<span className="font-bold font-mono" style={{ color: 'var(--color-accent)' }}>
12.3 km²
</span>
</div>
<div className="p-1 bg-bg-base rounded">
<span className="text-fg-disabled"></span>
<br />
<span className="font-bold font-mono" style={{ color: 'var(--color-accent)' }}>
520 ppm
</span>
</div>
</div>
</div>
{/* 이문진박사모델 */}
<div
className="p-3.5 rounded-lg text-center"
style={{ background: 'rgba(6,182,212,.04)', border: '1px solid rgba(6,182,212,.2)' }}
>
<div className="text-caption font-bold mb-2" style={{ color: 'var(--color-accent)' }}>
()
</div>
<div
className="font-bold font-mono"
style={{ fontSize: 'var(--font-size-heading-2)', color: 'var(--color-accent)' }}
>
2.9 <span style={{ fontSize: 'var(--font-size-label-1)' }}>km</span>
</div>
<div className="text-caption text-fg-disabled mt-0.5">AEGL-2 </div>
<div className="mt-2 grid grid-cols-2 gap-1 text-caption">
<div className="p-1 bg-bg-base rounded">
<span className="text-fg-disabled"></span>
<br />
<span className="font-bold font-mono" style={{ color: 'var(--color-accent)' }}>
8.4 km²
</span>
</div>
<div className="p-1 bg-bg-base rounded">
<span className="text-fg-disabled"></span>
<br />
<span className="font-bold font-mono" style={{ color: 'var(--color-accent)' }}>
410 ppm
</span>
</div>
</div>
</div>
{/* 차이 분석 */}
<div
className="p-3.5 rounded-lg text-center"
style={{ background: 'rgba(6,182,212,.04)', border: '1px solid rgba(6,182,212,.2)' }}
>
<div className="text-caption font-bold mb-2" style={{ color: 'var(--color-accent)' }}>
</div>
<div
className="font-bold font-mono"
style={{ fontSize: 'var(--font-size-heading-2)', color: 'var(--color-accent)' }}
>
-23.7<span style={{ fontSize: 'var(--font-size-label-1)' }}>%</span>
</div>
<div className="text-caption text-fg-disabled mt-0.5"> </div>
<div className="mt-2 grid grid-cols-2 gap-1 text-caption">
<div className="p-1 bg-bg-base rounded">
<span className="text-fg-disabled"></span>
<br />
<span className="font-bold font-mono" style={{ color: 'var(--color-accent)' }}>
-31.7%
</span>
</div>
<div className="p-1 bg-bg-base rounded">
<span className="text-fg-disabled"></span>
<br />
<span className="font-bold font-mono" style={{ color: 'var(--color-accent)' }}>
-21.2%
</span>
</div>
</div>
</div>
</div>
{/* 결과 설명 */}
<div
className="mt-3 p-2.5 text-caption text-fg-sub leading-[1.7] rounded-md"
style={{ background: 'rgba(6,182,212,.04)', border: '1px solid rgba(6,182,212,.12)' }}
>
<b style={{ color: 'var(--color-accent)' }}> :</b> ALOHA의
. (z), MABL , SST-
.{' '}
<b>
ALOHA ,
</b>
.
</div>
</div>
);
}
/* ═══ 패널 6: WRF-Chem·발전 ═══ */
function WrfChemPanel() {
return (
<>
{/* WRF-Chem 모델 상세 */}
<div className={`${card} ${cardBg} p-4`} style={{ padding: '16px' }}>
<div className="flex items-center gap-2" style={{ marginBottom: '14px' }}>
<div
style={{
width: '32px',
height: '32px',
borderRadius: '8px',
background: 'rgba(6,182,212,.15)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: 'var(--font-size-title-2)',
}}
>
🌐
</div>
<div>
<div
style={{
fontSize: 'var(--font-size-title-3)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
WRF-Chem
</div>
<div style={{ fontSize: 'var(--font-size-caption)', color: 'var(--fg-disabled)' }}>
Weather Research and Forecasting model coupled with Chemistry
</div>
</div>
</div>
<div className="grid grid-cols-2 gap-3.5">
{/* 구성 요소 */}
<div>
<div
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '8px',
}}
>
</div>
<div className="flex flex-col gap-1.5">
{/* WRF */}
<div
style={{
padding: '10px',
background: 'var(--bg-base)',
border: '1px solid rgba(6,182,212,.15)',
borderRadius: '6px',
}}
>
<div className="flex items-center justify-between" style={{ marginBottom: '4px' }}>
<span
style={{
fontSize: 'var(--font-size-caption)',
fontWeight: 700,
color: 'var(--color-accent)',
}}
>
WRF ()
</span>
<span
className="font-mono"
style={{
fontSize: 'var(--font-size-caption)',
padding: '2px 6px',
borderRadius: '3px',
background: 'rgba(6,182,212,.1)',
color: 'var(--color-accent)',
}}
>
v4.x
</span>
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.6,
}}
>
(non-hydrostatic) . 3 , , ,
. (nesting) 1km까지 .
</div>
</div>
{/* Chem */}
<div
style={{
padding: '10px',
background: 'var(--bg-base)',
border: '1px solid rgba(6,182,212,.15)',
borderRadius: '6px',
}}
>
<div className="flex items-center justify-between" style={{ marginBottom: '4px' }}>
<span
style={{
fontSize: 'var(--font-size-caption)',
fontWeight: 700,
color: 'var(--color-accent)',
}}
>
Chem ()
</span>
<span
className="font-mono"
style={{
fontSize: 'var(--font-size-caption)',
padding: '2px 6px',
borderRadius: '3px',
background: 'rgba(6,182,212,.1)',
color: 'var(--color-accent)',
}}
>
Online
</span>
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.6,
}}
>
(advection), (diffusion),
·(deposition), . Offline .
</div>
</div>
{/* 결합 효과 */}
<div
style={{
padding: '10px',
background: 'var(--bg-base)',
border: '1px solid rgba(6,182,212,.15)',
borderRadius: '6px',
}}
>
<div className="flex items-center justify-between" style={{ marginBottom: '4px' }}>
<span
style={{
fontSize: 'var(--font-size-caption)',
fontWeight: 700,
color: 'var(--color-accent)',
}}
>
</span>
<span
className="font-mono"
style={{
fontSize: 'var(--font-size-caption)',
padding: '2px 6px',
borderRadius: '3px',
background: 'rgba(6,182,212,.1)',
color: 'var(--color-accent)',
}}
>
Feedback
</span>
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.6,
}}
>
(feedback). : 대량의
.
</div>
</div>
</div>
</div>
{/* HNS 사고 적용 시 장점 */}
<div>
<div
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '8px',
}}
>
HNS
</div>
<div className="flex flex-col gap-1.5">
{[
{
num: '1',
text: (
<>
<b style={{ color: 'var(--fg-default)' }}>3D :</b>
. fumigation
</>
),
},
{
num: '2',
text: (
<>
<b style={{ color: 'var(--fg-default)' }}> :</b>
(), ,
</>
),
},
{
num: '3',
text: (
<>
<b style={{ color: 'var(--fg-default)' }}> :</b> ,
,
</>
),
},
{
num: '4',
text: (
<>
<b style={{ color: 'var(--fg-default)' }}> :</b> 24~72
</>
),
},
].map(({ num, text }) => (
<div
key={num}
className="flex gap-2"
style={{ padding: '8px', background: 'var(--bg-base)', borderRadius: '6px' }}
>
<div
className="font-mono flex items-center justify-center flex-shrink-0"
style={{
width: '24px',
height: '24px',
borderRadius: '50%',
background: 'rgba(6,182,212,.15)',
fontSize: 'var(--font-size-caption)',
fontWeight: 800,
color: 'var(--color-accent)',
}}
>
{num}
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.5,
}}
>
{text}
</div>
</div>
))}
</div>
<div
style={{
marginTop: '10px',
padding: '8px',
background: 'rgba(6,182,212,.05)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '6px',
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.5,
}}
>
<b style={{ color: 'var(--color-accent)' }}> :</b> WRF-Chem은
<b>100~1,000</b> . ,
WRF-Chem으로 <b style={{ color: 'var(--color-accent)' }}> </b> .
</div>
</div>
</div>
</div>
{/* ROMS 해양확산 수치모의 검증 */}
<div className={`${card} ${cardBg} p-4`} style={{ padding: '16px' }}>
<div className="flex items-center justify-between" style={{ marginBottom: '14px' }}>
<div className="flex items-center gap-2">
<div
style={{
width: '28px',
height: '28px',
borderRadius: '6px',
background: 'rgba(6,182,212,.15)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: 'var(--font-size-title-3)',
}}
>
🌊
</div>
<div>
<div
style={{
fontSize: 'var(--font-size-title-4)',
fontWeight: 700,
color: 'var(--color-accent)',
}}
>
ROMS
</div>
<div style={{ fontSize: 'var(--font-size-caption)', color: 'var(--fg-disabled)' }}>
· (2024), · Vol.30
</div>
</div>
</div>
<span
style={{
padding: '3px 10px',
borderRadius: '6px',
background: 'rgba(6,182,212,.1)',
border: '1px solid rgba(6,182,212,.2)',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
fontWeight: 700,
}}
>
75~96%
</span>
</div>
<div className="grid grid-cols-2 gap-3.5">
{/* Nesting 격자 구성 */}
<div>
<div
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '8px',
}}
>
📐 Nesting
</div>
<table
style={{
width: '100%',
borderCollapse: 'collapse',
fontSize: 'var(--font-size-caption)',
}}
>
<thead>
<tr style={{ background: 'rgba(6,182,212,.06)' }}>
<th
style={{
padding: '5px 6px',
textAlign: 'left',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--color-accent)',
}}
>
</th>
<th
style={{
padding: '5px 6px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--fg-sub)',
}}
>
</th>
<th
style={{
padding: '5px 6px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--fg-sub)',
}}
>
</th>
<th
style={{
padding: '5px 6px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--fg-sub)',
}}
>
</th>
</tr>
</thead>
<tbody>
<tr style={{ borderBottom: '1px solid rgba(255,255,255,.04)' }}>
<td style={{ padding: '4px 6px', color: 'var(--fg-default)' }}>
(· )
</td>
<td
className="font-mono"
style={{ textAlign: 'center', color: 'var(--color-accent)' }}
>
0.05°
</td>
<td className="font-mono" style={{ textAlign: 'center' }}>
5
</td>
<td className="font-mono" style={{ textAlign: 'center' }} rowSpan={3}>
20
</td>
</tr>
<tr style={{ borderBottom: '1px solid rgba(255,255,255,.04)' }}>
<td style={{ padding: '4px 6px', color: 'var(--fg-default)' }}>
( )
</td>
<td
className="font-mono"
style={{ textAlign: 'center', color: 'var(--color-accent)' }}
>
0.01°
</td>
<td className="font-mono" style={{ textAlign: 'center' }}>
1
</td>
</tr>
<tr style={{ background: 'rgba(6,182,212,.03)' }}>
<td
style={{
padding: '4px 6px',
color: 'var(--color-accent)',
fontWeight: 600,
}}
>
(5 )
</td>
<td
className="font-mono"
style={{
textAlign: 'center',
color: 'var(--color-accent)',
fontWeight: 600,
}}
>
0.002°(200m)
</td>
<td className="font-mono" style={{ textAlign: 'center' }}>
12
</td>
</tr>
</tbody>
</table>
<div
style={{
marginTop: '8px',
fontSize: 'var(--font-size-caption)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '6px',
}}
>
🔗
</div>
<div
className="grid grid-cols-2 gap-1"
style={{ fontSize: 'var(--font-size-caption)' }}
>
<div
style={{
padding: '4px 6px',
background: 'var(--bg-base)',
borderRadius: '3px',
}}
>
<span style={{ color: 'var(--color-accent)', fontWeight: 600 }}>ERA5</span>{' '}
<span style={{ color: 'var(--fg-disabled)' }}>(··)</span>
</div>
<div
style={{
padding: '4px 6px',
background: 'var(--bg-base)',
borderRadius: '3px',
}}
>
<span style={{ color: 'var(--color-accent)', fontWeight: 600 }}>HYCOM</span>{' '}
<span style={{ color: 'var(--fg-disabled)' }}>··</span>
</div>
<div
style={{
padding: '4px 6px',
background: 'var(--bg-base)',
borderRadius: '3px',
}}
>
<span style={{ color: 'var(--color-accent)', fontWeight: 600 }}>TPXO9</span>{' '}
<span style={{ color: 'var(--fg-disabled)' }}> 15 </span>
</div>
<div
style={{
padding: '4px 6px',
background: 'var(--bg-base)',
borderRadius: '3px',
}}
>
<span style={{ color: 'var(--color-accent)', fontWeight: 600 }}>WAMIS</span>{' '}
<span style={{ color: 'var(--fg-disabled)' }}>5 </span>
</div>
</div>
</div>
{/* 관측-모델 비교 */}
<div>
<div
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '8px',
}}
>
- (··)
</div>
<table
style={{
width: '100%',
borderCollapse: 'collapse',
fontSize: 'var(--font-size-caption)',
}}
>
<thead>
<tr style={{ background: 'rgba(6,182,212,.06)' }}>
<th
style={{
padding: '5px 6px',
textAlign: 'left',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--color-accent)',
}}
>
</th>
<th
style={{
padding: '5px 6px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--fg-sub)',
}}
>
(mg/L)
</th>
<th
style={{
padding: '5px 6px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--fg-sub)',
}}
>
(mg/L)
</th>
<th
style={{
padding: '5px 6px',
textAlign: 'center',
borderBottom: '2px solid var(--stroke-light)',
color: 'var(--color-accent)',
}}
>
</th>
</tr>
</thead>
<tbody>
<tr style={{ borderBottom: '1px solid rgba(255,255,255,.04)' }}>
<td style={{ padding: '3px 6px', color: 'var(--fg-default)' }}>IC01()</td>
<td className="font-mono" style={{ textAlign: 'center' }}>
0.0160
</td>
<td className="font-mono" style={{ textAlign: 'center' }}>
0.0167
</td>
<td
className="font-mono"
style={{ textAlign: 'center', color: 'var(--color-accent)', fontWeight: 600 }}
>
95.32%
</td>
</tr>
<tr style={{ borderBottom: '1px solid rgba(255,255,255,.04)' }}>
<td style={{ padding: '3px 6px', color: 'var(--fg-default)' }}>IC03()</td>
<td className="font-mono" style={{ textAlign: 'center' }}>
0.0240
</td>
<td className="font-mono" style={{ textAlign: 'center' }}>
0.0256
</td>
<td
className="font-mono"
style={{ textAlign: 'center', color: 'var(--color-accent)', fontWeight: 600 }}
>
93.45%
</td>
</tr>
<tr style={{ borderBottom: '1px solid rgba(255,255,255,.04)' }}>
<td style={{ padding: '3px 6px', color: 'var(--fg-default)' }}>PT01()</td>
<td className="font-mono" style={{ textAlign: 'center' }}>
0.0215
</td>
<td className="font-mono" style={{ textAlign: 'center' }}>
0.0235
</td>
<td
className="font-mono"
style={{ textAlign: 'center', color: 'var(--color-accent)' }}
>
90.55%
</td>
</tr>
<tr
style={{
borderBottom: '1px solid rgba(255,255,255,.04)',
background: 'rgba(6,182,212,.02)',
}}
>
<td style={{ padding: '3px 6px', color: 'var(--color-accent)' }}>PT02()</td>
<td className="font-mono" style={{ textAlign: 'center' }}>
0.0200
</td>
<td className="font-mono" style={{ textAlign: 'center' }}>
0.0249
</td>
<td
className="font-mono"
style={{ textAlign: 'center', color: 'var(--color-accent)' }}
>
75.57%
</td>
</tr>
<tr
style={{
borderBottom: '1px solid rgba(255,255,255,.04)',
background: 'rgba(6,182,212,.03)',
}}
>
<td
style={{
padding: '3px 6px',
color: 'var(--color-accent)',
fontWeight: 600,
}}
>
DS01()
</td>
<td className="font-mono" style={{ textAlign: 'center' }}>
0.0040
</td>
<td className="font-mono" style={{ textAlign: 'center' }}>
0.0042
</td>
<td
className="font-mono"
style={{ textAlign: 'center', color: 'var(--color-accent)', fontWeight: 700 }}
>
95.88%
</td>
</tr>
<tr>
<td style={{ padding: '3px 6px', color: 'var(--fg-default)' }}>DS03()</td>
<td className="font-mono" style={{ textAlign: 'center' }}>
0.0130
</td>
<td className="font-mono" style={{ textAlign: 'center' }}>
0.0145
</td>
<td
className="font-mono"
style={{ textAlign: 'center', color: 'var(--color-accent)' }}
>
88.60%
</td>
</tr>
</tbody>
</table>
<div
style={{
marginTop: '6px',
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
}}
>
현장조사: 2023.06.27~28 / 10
</div>
</div>
</div>
{/* 페놀 거동 특성 + 최대 농도 */}
<div className="grid grid-cols-3 gap-2.5" style={{ marginTop: '14px' }}>
<div
style={{
padding: '10px',
background: 'var(--bg-base)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '6px',
textAlign: 'center',
}}
>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
marginBottom: '4px',
}}
>
</div>
<div
className="font-mono"
style={{
fontSize: 'var(--font-size-title-1)',
fontWeight: 700,
color: 'var(--color-accent)',
}}
>
0.1089<span style={{ fontSize: 'var(--font-size-caption)' }}> mg/L</span>
</div>
</div>
<div
style={{
padding: '10px',
background: 'var(--bg-base)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '6px',
textAlign: 'center',
}}
>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
marginBottom: '4px',
}}
>
</div>
<div
className="font-mono"
style={{
fontSize: 'var(--font-size-title-1)',
fontWeight: 700,
color: 'var(--color-accent)',
}}
>
0.3822<span style={{ fontSize: 'var(--font-size-caption)' }}> mg/L</span>
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
fontWeight: 600,
marginTop: '2px',
}}
>
3.5
</div>
</div>
<div
style={{
padding: '10px',
background: 'var(--bg-base)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '6px',
textAlign: 'center',
}}
>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
marginBottom: '4px',
}}
>
·
</div>
<div
className="font-mono"
style={{
fontSize: 'var(--font-size-title-1)',
fontWeight: 700,
color: 'var(--color-accent)',
}}
>
0.1916<span style={{ fontSize: 'var(--font-size-caption)' }}> mg/L</span>
</div>
</div>
</div>
<div
style={{
marginTop: '10px',
padding: '8px 10px',
background: 'rgba(6,182,212,.04)',
border: '1px solid rgba(6,182,212,.1)',
borderRadius: '6px',
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.6,
}}
>
<b style={{ color: 'var(--color-accent)' }}> :</b> Sinker {' '}
<b style={{ color: 'var(--color-accent)' }}> </b>
,{' '}
<b style={{ color: 'var(--color-accent)' }}> 3D </b>.
· ROMS . Opendrift(
) Cedre() HNS .
</div>
</div>
{/* 지역별 해양산업시설 현황 */}
<div className={`${card} ${cardBg} p-4`} style={{ padding: '16px' }}>
<div
style={{
fontSize: 'var(--font-size-label-1)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '10px',
}}
>
🏭 (10 )
</div>
<div
className="grid gap-1 text-center"
style={{
gridTemplateColumns: 'repeat(7, 1fr)',
fontSize: 'var(--font-size-caption)',
}}
>
{[
{
name: '울산',
vol: '414,620',
sites: '1,037개소',
volColor: 'var(--fg-default)',
sitesColor: 'var(--color-accent)',
bg: 'rgba(6,182,212,.06)',
nameColor: 'var(--color-accent)',
},
{
name: '여수',
vol: '124,890',
sites: '382개소',
volColor: 'var(--fg-default)',
sitesColor: 'var(--fg-disabled)',
bg: 'rgba(6,182,212,.04)',
nameColor: 'var(--color-accent)',
},
{
name: '인천',
vol: '91,658',
sites: '3,073개소',
volColor: 'var(--fg-default)',
sitesColor: 'var(--fg-disabled)',
bg: 'rgba(6,182,212,.04)',
nameColor: 'var(--color-accent)',
},
{
name: '광양',
vol: '86,395',
sites: '253개소',
volColor: 'var(--fg-default)',
sitesColor: 'var(--fg-disabled)',
bg: 'rgba(6,182,212,.03)',
nameColor: 'var(--fg-sub)',
},
{
name: '평택',
vol: '85,475',
sites: '781개소',
volColor: 'var(--fg-default)',
sitesColor: 'var(--fg-disabled)',
bg: 'rgba(6,182,212,.03)',
nameColor: 'var(--fg-sub)',
},
{
name: '대산',
vol: '65,101',
sites: '246개소',
volColor: 'var(--fg-default)',
sitesColor: 'var(--fg-disabled)',
bg: 'rgba(6,182,212,.03)',
nameColor: 'var(--fg-sub)',
},
{
name: '부산',
vol: '38,292',
sites: '469개소',
volColor: 'var(--fg-default)',
sitesColor: 'var(--fg-disabled)',
bg: 'rgba(6,182,212,.03)',
nameColor: 'var(--fg-sub)',
},
].map(({ name, vol, sites, volColor, sitesColor, bg, nameColor }) => (
<div key={name} style={{ padding: '6px', background: bg, borderRadius: '4px' }}>
<div style={{ fontWeight: 700, color: nameColor }}>{name}</div>
<div
className="font-mono"
style={{ color: volColor, fontSize: 'var(--font-size-caption)', marginTop: '2px' }}
>
{vol}
</div>
<div style={{ color: 'var(--fg-disabled)' }}>m³/</div>
<div
className="font-mono"
style={{
color: sitesColor,
fontSize: 'var(--font-size-caption)',
marginTop: '1px',
}}
>
{sites}
</div>
</div>
))}
</div>
<div
style={{
marginTop: '8px',
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
}}
>
1 (2,000m³/ ) 배출량: 21.847 kg 882 31.851
kg/ (KOSIS·NICS 2021)
</div>
</div>
{/* 한계 및 발전 방향 */}
<div className="grid grid-cols-2 gap-4 mb-4">
{/* 현재 한계점 */}
<div className={`${cardBg} rounded-[10px]`} style={{ padding: '16px' }}>
<div
style={{
fontSize: 'var(--font-size-title-4)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '12px',
}}
>
</div>
<div className="flex flex-col gap-2">
{[
{
title: '입자 추적 방식의 한계',
body: (
<>
{' '}
<b style={{ color: 'var(--color-accent)' }}> </b>
. , .
</>
),
},
{
title: '대용량 데이터 전송',
body: (
<>
DB(, ) {' '}
<b style={{ color: 'var(--color-accent)' }}> </b>
. WRF-Chem GB .
</>
),
},
{
title: '물질 다양성',
body: (
<>
HNS 6,000+ {' '}
<b style={{ color: 'var(--color-accent)' }}> DB </b>.
.
</>
),
},
{
title: '해양 환경 특수성',
body: (
<>
, , Wake
<b style={{ color: 'var(--color-accent)' }}> </b>
.
</>
),
},
].map(({ title, body }) => (
<div
key={title}
style={{
padding: '10px',
background: 'rgba(6,182,212,.03)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '6px',
}}
>
<div
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--fg-default)',
marginBottom: '4px',
}}
>
{title}
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.6,
}}
>
{body}
</div>
</div>
))}
</div>
</div>
{/* 발전 방향 */}
<div className={`${cardBg} rounded-[10px]`} style={{ padding: '16px' }}>
<div
style={{
fontSize: 'var(--font-size-title-4)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '12px',
}}
>
🚀
</div>
<div className="flex flex-col gap-2">
{[
{
title: 'ROMS 해양 수치모델 도입',
badge: {
text: '✅ 검증완료',
bg: 'rgba(6,182,212,.15)',
color: 'var(--color-accent)',
},
body: (
<>
· (2024) {' '}
<b style={{ color: 'var(--color-accent)' }}>
ROMS
</b>
. Nesting ( 0.05° 0.01° 0.002°/200m) 5
(····) .
<br />
:{' '}
<span style={{ color: 'var(--color-accent)' }}>
ERA5() + HYCOM() + TPXO9( 15)
</span>
. 5 + · .
<br />
<b style={{ color: 'var(--color-accent)' }}>
정확도: 75.57%(PT02) ~ 95.88%(DS01)
</b>{' '}
10 · .
</>
),
},
{
title: 'AI/ML 기반 신속 예측',
badge: {
text: '연구중',
bg: 'rgba(6,182,212,.1)',
color: 'var(--color-accent)',
},
body: (
<>
WRF-Chem {' '}
<b style={{ color: 'var(--color-accent)' }}> (Surrogate Model)</b>
. .
</>
),
},
{
title: '실시간 데이터 파이프라인',
badge: { text: '개발중', bg: 'rgba(6,182,212,.1)', color: 'var(--color-accent)' },
body: (
<>
<b style={{ color: 'var(--color-accent)' }}> DB</b> +
. DB ·
.
</>
),
},
{
title: 'HNS 블랙박스 시스템 고도화',
badge: { text: '목표', bg: 'rgba(6,182,212,.1)', color: 'var(--color-accent)' },
body: (
<>
{' '}
<b style={{ color: 'var(--color-accent)' }}> </b>. +
AI + /WRF-Chem .
</>
),
},
].map(({ title, badge, body }) => (
<div
key={title}
style={{
padding: '10px',
background: 'rgba(6,182,212,.03)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '6px',
}}
>
<div className="flex items-center justify-between" style={{ marginBottom: '4px' }}>
<span
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
{title}
</span>
<span
style={{
fontSize: 'var(--font-size-caption)',
padding: '2px 6px',
borderRadius: '3px',
background: badge.bg,
color: badge.color,
fontWeight: 600,
}}
>
{badge.text}
</span>
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.6,
}}
>
{body}
</div>
</div>
))}
</div>
</div>
</div>
{/* 관련 국내 논문 */}
<div className={`${card} ${cardBg} p-4`} style={{ padding: '16px' }}>
<div className="flex items-center gap-2" style={{ marginBottom: '14px' }}>
<div
style={{
width: '28px',
height: '28px',
borderRadius: '6px',
background: 'rgba(6,182,212,.15)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: 'var(--font-size-title-3)',
}}
>
📚
</div>
<div>
<div
style={{
fontSize: 'var(--font-size-title-4)',
fontWeight: 700,
color: 'var(--color-accent)',
}}
>
HNS ·
</div>
<div style={{ fontSize: 'var(--font-size-caption)', color: 'var(--fg-disabled)' }}>
· · · ·
</div>
</div>
</div>
<div className="flex flex-col gap-2.5">
{/* 논문 ① */}
<div
style={{
padding: '12px',
background: 'var(--bg-base)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '8px',
borderLeft: '3px solid var(--color-accent)',
}}
>
<div className="flex items-start justify-between" style={{ marginBottom: '6px' }}>
<div className="flex items-center gap-1.5">
<span
className="font-mono flex items-center justify-center"
style={{
width: '20px',
height: '20px',
borderRadius: '50%',
background: 'rgba(6,182,212,.15)',
fontSize: 'var(--font-size-caption)',
fontWeight: 800,
color: 'var(--color-accent)',
}}
>
</span>
<span
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
·(HNS)
</span>
</div>
<span
style={{
padding: '2px 8px',
borderRadius: '4px',
background: 'rgba(6,182,212,.08)',
border: '1px solid rgba(6,182,212,.15)',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
fontWeight: 600,
whiteSpace: 'nowrap',
}}
>
KRISO
</span>
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
marginBottom: '6px',
}}
>
···· Vol.21 No.6, pp.672-678, 2015
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.6,
}}
>
EURAM/CRS-KOREA II .{' '}
<b style={{ color: 'var(--color-accent)' }}>Risk = Toxicity × Exposure</b>{' '}
585 . (···)
·(BCF)·· .{' '}
<b style={{ color: 'var(--color-accent)' }}> 20 </b>(Aniline,
Acrylonitrile, Phenol, Coal tar ) . GESAMP .
</div>
<div className="flex gap-1 flex-wrap" style={{ marginTop: '6px' }}>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
</span>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
585
</span>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
GESAMP
</span>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
</span>
</div>
</div>
{/* 논문 ② */}
<div
style={{
padding: '12px',
background: 'var(--bg-base)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '8px',
borderLeft: '3px solid var(--color-accent)',
}}
>
<div className="flex items-start justify-between" style={{ marginBottom: '6px' }}>
<div className="flex items-center gap-1.5">
<span
className="font-mono flex items-center justify-center"
style={{
width: '20px',
height: '20px',
borderRadius: '50%',
background: 'rgba(6,182,212,.15)',
fontSize: 'var(--font-size-caption)',
fontWeight: 800,
color: 'var(--color-accent)',
}}
>
</span>
<span
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
·
</span>
</div>
<span
style={{
padding: '2px 8px',
borderRadius: '4px',
background: 'rgba(6,182,212,.08)',
border: '1px solid rgba(6,182,212,.15)',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
fontWeight: 600,
whiteSpace: 'nowrap',
}}
>
KEI
</span>
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
marginBottom: '6px',
}}
>
· Vol.25 No.6, pp.402-413, 2016
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.6,
}}
>
NOAA ESI · .{' '}
<b style={{ color: 'var(--color-accent)' }}>
····/
</b>{' '}
5 100 ( 500) . 74 .
McLaughlin et al.(2002) , Fattal et al.(2010) SEv
. <b style={{ color: 'var(--color-accent)' }}>HNS </b>
.
</div>
<div className="flex gap-1 flex-wrap" style={{ marginTop: '6px' }}>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
ESI
</span>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
500
</span>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
74
</span>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
</span>
</div>
</div>
{/* 논문 ③ */}
<div
style={{
padding: '12px',
background: 'var(--bg-base)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '8px',
borderLeft: '3px solid var(--color-accent)',
}}
>
<div className="flex items-start justify-between" style={{ marginBottom: '6px' }}>
<div className="flex items-center gap-1.5">
<span
className="font-mono flex items-center justify-center"
style={{
width: '20px',
height: '20px',
borderRadius: '50%',
background: 'rgba(6,182,212,.15)',
fontSize: 'var(--font-size-caption)',
fontWeight: 800,
color: 'var(--color-accent)',
}}
>
</span>
<span
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
HNS
</span>
</div>
<span
style={{
padding: '2px 8px',
borderRadius: '4px',
background: 'rgba(6,182,212,.08)',
border: '1px solid rgba(6,182,212,.15)',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
fontWeight: 600,
whiteSpace: 'nowrap',
}}
>
KAIST
</span>
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
marginBottom: '6px',
}}
>
·· Vol.17 No.4, pp.307-315, 2017
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.6,
}}
>
HNS {' '}
<b style={{ color: 'var(--color-accent)' }}> (SD) </b> .
4 (HNS ···) .{' '}
<b style={{ color: 'var(--color-accent)' }}>
DB
</b>{' '}
(Accessibility) . Two-step ( ETF) {' '}
<b style={{ color: 'var(--color-accent)' }}>15% 9.5% </b>
(116105), 90 80.78 ( 20 ).
</div>
<div className="flex gap-1 flex-wrap" style={{ marginTop: '6px' }}>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
SD
</span>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
</span>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
ETF Two-step
</span>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
MARITIME MAISIE
</span>
</div>
</div>
{/* 논문 ④ */}
<div
style={{
padding: '12px',
background: 'var(--bg-base)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '8px',
borderLeft: '3px solid var(--color-accent)',
}}
>
<div className="flex items-start justify-between" style={{ marginBottom: '6px' }}>
<div className="flex items-center gap-1.5">
<span
className="font-mono flex items-center justify-center"
style={{
width: '20px',
height: '20px',
borderRadius: '50%',
background: 'rgba(6,182,212,.15)',
fontSize: 'var(--font-size-caption)',
fontWeight: 800,
color: 'var(--color-accent)',
}}
>
</span>
<span
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
HNS의
</span>
</div>
<span
style={{
padding: '2px 8px',
borderRadius: '4px',
background: 'rgba(6,182,212,.08)',
border: '1px solid rgba(6,182,212,.15)',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
fontWeight: 600,
whiteSpace: 'nowrap',
}}
>
KEI+KRISO
</span>
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
marginBottom: '6px',
}}
>
····· Vol.29 , pp.8-17,
2023
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.6,
}}
>
NOAA CAMEO/CAFE · EU MARINER/Bonn Agreement {' '}
<b style={{ color: 'var(--color-accent)' }}> HNS </b>{' '}
. (5.4km)(1.8km)(80~110m, ) 3 .
, HNS · ,{' '}
<b style={{ color: 'var(--color-accent)' }}>
+ GIS
</b>{' '}
. SEBC (G/E/F/D/S) . 5 (···/·)
.
</div>
<div className="flex gap-1 flex-wrap" style={{ marginTop: '6px' }}>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
</span>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
CAMEO/MARINER
</span>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
SEBC
</span>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
</span>
</div>
</div>
{/* 논문 ⑤ */}
<div
style={{
padding: '12px',
background: 'var(--bg-base)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '8px',
borderLeft: '3px solid var(--color-accent)',
}}
>
<div className="flex items-start justify-between" style={{ marginBottom: '6px' }}>
<div className="flex items-center gap-1.5">
<span
className="font-mono flex items-center justify-center"
style={{
width: '20px',
height: '20px',
borderRadius: '50%',
background: 'rgba(6,182,212,.15)',
fontSize: 'var(--font-size-caption)',
fontWeight: 800,
color: 'var(--color-accent)',
}}
>
</span>
<span
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
HNS
</span>
</div>
<span
style={{
padding: '2px 8px',
borderRadius: '4px',
background: 'rgba(6,182,212,.08)',
border: '1px solid rgba(6,182,212,.15)',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
fontWeight: 600,
whiteSpace: 'nowrap',
}}
>
</span>
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
marginBottom: '6px',
}}
>
9 11, pp.77-92, 2013
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.6,
}}
>
(·) HNS .{' '}
<b style={{ color: 'var(--color-accent)' }}> </b>, HNS
,{' '}
<b style={{ color: 'var(--color-accent)' }}>
CAMEO/ALOHA/MARPLOT
</b>{' '}
, 68 . NRT/NSF
{' '}
<b style={{ color: 'var(--color-accent)' }}>ICS() </b> .
2006~2010 HNS 13 , (··) ··{' '}
<b style={{ color: 'var(--color-accent)' }}> </b> . OPRC-HNS
(2008.4 ) .
</div>
<div className="flex gap-1 flex-wrap" style={{ marginTop: '6px' }}>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
</span>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
CAMEO/ALOHA
</span>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
ICS
</span>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
OPRC-HNS
</span>
</div>
</div>
{/* 논문 ⑥ */}
<div
style={{
padding: '12px',
background: 'var(--bg-base)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '8px',
borderLeft: '3px solid var(--color-accent)',
}}
>
<div className="flex items-start justify-between" style={{ marginBottom: '6px' }}>
<div className="flex items-center gap-1.5">
<span
className="font-mono flex items-center justify-center"
style={{
width: '20px',
height: '20px',
borderRadius: '50%',
background: 'rgba(6,182,212,.15)',
fontSize: 'var(--font-size-caption)',
fontWeight: 800,
color: 'var(--color-accent)',
}}
>
</span>
<span
style={{
fontSize: 'var(--font-size-label-2)',
fontWeight: 700,
color: 'var(--fg-default)',
}}
>
HNS의
</span>
</div>
<span
style={{
padding: '2px 8px',
borderRadius: '4px',
background: 'rgba(6,182,212,.08)',
border: '1px solid rgba(6,182,212,.15)',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
fontWeight: 600,
whiteSpace: 'nowrap',
}}
>
KEI+KRISO
</span>
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
marginBottom: '6px',
}}
>
····· Vol.29 , pp.8-17,
2023
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-sub)',
lineHeight: 1.6,
}}
>
NOAA{' '}
<b style={{ color: 'var(--color-accent)' }}>
CAFE(Chemical Aquatic Fate and Effects)
</b>{' '}
DB(32,377 ·4,498 ){' '}
<b style={{ color: 'var(--color-accent)' }}>CAMEO Suite</b>, EU{' '}
<b style={{ color: 'var(--color-accent)' }}>MARINER </b>(119 HNS
·187 DB) Bonn Agreement . SEBC (G/E/F/D/S)
. HNS 개발:
광역(5.4km)(1.8km)(80~110m, ){' '}
<b style={{ color: 'var(--color-accent)' }}>3 Nesting </b> ,
, HNS · ,{' '}
<b style={{ color: 'var(--color-accent)' }}>
+ GIS
</b>{' '}
. 5 (···/·) .
</div>
<div className="flex gap-1 flex-wrap" style={{ marginTop: '6px' }}>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
CAFE·CAMEO
</span>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
MARINER
</span>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
SEBC
</span>
<span
style={{
padding: '2px 6px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.12)',
borderRadius: '3px',
fontSize: 'var(--font-size-caption)',
color: 'var(--color-accent)',
}}
>
</span>
</div>
</div>
</div>
</div>
{/* WING HNS 모델 로드맵 */}
<div
style={{
background: 'rgba(6,182,212,.04)',
border: '1px solid rgba(6,182,212,.2)',
borderRadius: '10px',
padding: '16px',
}}
>
<div
style={{
fontSize: 'var(--font-size-title-4)',
fontWeight: 700,
color: 'var(--fg-default)',
marginBottom: '14px',
}}
>
📅 WING HNS
</div>
<div className="flex items-stretch" style={{ gap: 0 }}>
{/* Phase 1 */}
<div
style={{
flex: 1,
padding: '10px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.2)',
borderRadius: '8px 0 0 8px',
textAlign: 'center',
}}
>
<div
style={{
fontSize: 'var(--font-size-caption)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '4px',
}}
>
Phase 1 ()
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
fontWeight: 600,
color: 'var(--fg-default)',
marginBottom: '4px',
}}
>
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
lineHeight: 1.5,
}}
>
ALOHA + Lee
<br />
6,000+ HNS DB
<br />
AEGL/ERPG
</div>
</div>
<div
style={{
width: '2px',
background: 'var(--color-accent)',
}}
/>
{/* Phase 2 */}
<div
style={{
flex: 1,
padding: '10px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.2)',
textAlign: 'center',
}}
>
<div
style={{
fontSize: 'var(--font-size-caption)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '4px',
}}
>
🔧 Phase 2 ()
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
fontWeight: 600,
color: 'var(--fg-default)',
marginBottom: '4px',
}}
>
WRF-Chem
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
lineHeight: 1.5,
}}
>
3D
<br />
<br />
-
</div>
</div>
<div
style={{
width: '2px',
background: 'var(--color-accent)',
}}
/>
{/* Phase 3 */}
<div
style={{
flex: 1,
padding: '10px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.2)',
textAlign: 'center',
}}
>
<div
style={{
fontSize: 'var(--font-size-caption)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '4px',
}}
>
🔬 Phase 3 ()
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
fontWeight: 600,
color: 'var(--fg-default)',
marginBottom: '4px',
}}
>
ROMS + AI
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
lineHeight: 1.5,
}}
>
<br />
ML
<br />
</div>
</div>
<div
style={{
width: '2px',
background: 'var(--color-accent)',
}}
/>
{/* Phase 4 */}
<div
style={{
flex: 1,
padding: '10px',
background: 'rgba(6,182,212,.06)',
border: '1px solid rgba(6,182,212,.2)',
borderRadius: '0 8px 8px 0',
textAlign: 'center',
}}
>
<div
style={{
fontSize: 'var(--font-size-caption)',
fontWeight: 700,
color: 'var(--color-accent)',
marginBottom: '4px',
}}
>
🎯 Phase 4 ()
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
fontWeight: 600,
color: 'var(--fg-default)',
marginBottom: '4px',
}}
>
</div>
<div
style={{
fontSize: 'var(--font-size-caption)',
color: 'var(--fg-disabled)',
lineHeight: 1.5,
}}
>
<br />
+AI
<br />
</div>
</div>
</div>
</div>
</>
);
}
export function HNSTheoryView() {
const [activePanel, setActivePanel] = useState(0);
const contentRef = useRef<HTMLDivElement>(null);
const handleExportPDF = () => {
if (!contentRef.current) return;
const clone = contentRef.current.cloneNode(true) as HTMLElement;
clone.querySelectorAll('[data-html2pdf-ignore]').forEach((el) => el.remove());
const content = clone.innerHTML;
const styles = Array.from(document.querySelectorAll('style, link[rel="stylesheet"]'))
.map((el) => el.outerHTML)
.join('\n');
const fullHtml = `<!DOCTYPE html>
<html><head><meta charset="utf-8"/>
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:;">
<title>HNS 대기확산 모델 이론</title>
${styles}
<style>
:root { --t1: #ffffff !important; --t2: #d0d6e6 !important; --t3: #a8b0c8 !important; }
@media print { @page { size: A4; margin: 10mm; } body { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; } }
body { background: var(--bg-base); color: var(--fg-default); font-family: var(--font-korean); padding: 20px 24px; }
</style>
</head><body>${content}</body></html>`;
const blob = new Blob([fullHtml], { type: 'text/html; charset=utf-8' });
const url = URL.createObjectURL(blob);
const win = window.open(url, '_blank');
if (win) {
win.addEventListener('afterprint', () => URL.revokeObjectURL(url));
setTimeout(() => {
win.document.title = 'HNS_대기확산_모델_이론';
win.print();
}, 500);
}
setTimeout(() => URL.revokeObjectURL(url), 30000);
};
return (
<div className="flex flex-col flex-1 h-full overflow-hidden bg-bg-base">
<div
className="flex-1 overflow-y-auto scrollbar-thin p-5"
style={{ scrollbarGutter: 'stable' }}
ref={contentRef}
>
{/* 헤더 */}
<div className="flex items-center justify-between mb-5">
<div className="flex items-center gap-3">
<div
className="w-[42px] h-[42px] rounded-[10px] flex items-center justify-center text-heading-3"
style={{
background: 'rgba(6,182,212,.04)',
border: '1px solid rgba(6,182,212,.3)',
}}
>
📐
</div>
<div>
<div className="text-title-2 font-bold text-fg">HNS </div>
<div className="text-label-2 text-fg-disabled mt-0.5">
WRF-Chem · Gaussian Plume/Puff · ROMS · Based on Lee Moon-Jin et al.
</div>
</div>
</div>
<button
onClick={handleExportPDF}
data-html2pdf-ignore
className="px-3.5 py-1.5 rounded-sm text-label-2 font-semibold cursor-pointer text-color-accent"
style={{
border: '1px solid rgba(6,182,212,.3)',
background: 'rgba(6,182,212,.08)',
}}
>
📤 PDF
</button>
</div>
{/* 서브탭 */}
<div className="flex gap-0.5 rounded-lg p-1 mb-5 bg-bg-card border border-stroke">
{theoryTabs.map((tab, i) => (
<button
key={i}
onClick={() => setActivePanel(i)}
className={`flex-1 py-2 px-1 text-label-1 font-medium rounded-md transition-all duration-150 cursor-pointer border ${
activePanel === i
? 'border-stroke-light bg-bg-elevated text-fg'
: 'border-transparent bg-bg-card text-fg-disabled hover:text-fg-sub'
}`}
>
{tab.icon} {tab.name}
</button>
))}
</div>
{/* 패널 콘텐츠 */}
{activePanel === 0 && <SystemOverviewPanel />}
{activePanel === 1 && <GaussianModelPanel />}
{activePanel === 2 && <SubstanceScenarioPanel />}
{activePanel === 3 && <OceanCorrectionPanel />}
{activePanel === 4 && <VerificationPanel />}
{activePanel === 5 && <RealtimeComparePanel />}
{activePanel === 6 && <WrfChemPanel />}
</div>
</div>
);
}