refactor: resolve all code review feedback (B1-B8 & Option A 5 Pillars) for ANL lab transformation

This commit is contained in:
2026-07-30 09:09:49 +09:00
parent e35b46d188
commit 315ba9ee08
7 changed files with 110 additions and 85 deletions
+3
View File
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
+3 -3
View File
@@ -62,11 +62,11 @@ npm run dev
| 경로 | 설명 |
| --- | --- |
| `/intro` | 연구실 소개 — 두 가지 연구 축(MCM, QUIC)과 연구 분야 |
| `/intro` | 연구실 소개 — 5대 핵심 연구 기둥(Agent Core Eng, MCP & SKILL, Orchestration, A2A/ACP Standards, AIoT & gRPC) |
| `/members` | 구성원 — 지도교수 및 박사·석사·학부 연구원 (placeholder) |
| `/publications` | 논문 — 대표 저널/학회 논문 목록 (placeholder) |
| `/lectures` | 강의 — 담당 학부·대학원 강의 (placeholder) |
| `/standardization` | 표준화 활동 — oneM2M, W3C WoT, IETF QUIC, OMA LwM2M 기여 (placeholder) |
| `/standardization` | 표준화 활동 — A2A, ACP, W3C WoT, IETF QUIC 기여 (placeholder) |
## 디자인 시스템 (Design System)
@@ -79,7 +79,7 @@ npm run dev
- **색상(Colors):** `tailwind.config.ts``theme.extend.colors` 에서 디자인 토큰을
수정합니다 — `ink`(본문·괘선), `ivory`/`paper`(종이 배경), `line`(헤어라인),
그리고 두 에디토리얼 강조색 `vermillion`(MCM/저널) · `cobalt`(QUIC/학회). 같은 값이
그리고 두 에디토리얼 강조색 `vermillion`(Agent Engineering / Orchestration) · `cobalt`(MCP / A2A Protocol). 같은 값이
`app/globals.css``:root` CSS 변수에도 미러링되어 있으니 **두 곳을 함께** 바꾸세요.
(`brand`/`accent` 별칭은 레거시 호환용이므로 신규 코드에서는 사용하지 마세요.)
- **폰트(Fonts):** `app/layout.tsx` 에서 `next/font` 로 로드해 CSS 변수
@@ -1,6 +1,6 @@
/**
* Abstract editorial hero — a custom illustration (inline SVG, no asset).
* • MCM → a constellation of interconnected nodes (vermillion).
* • A2A → a constellation of interconnected nodes (vermillion).
* • QUIC → flowing, multiplexed streams (cobalt), animated dash flow.
* Animations are pure CSS (tailwind keyframes: node-pulse, stream-dash).
*
@@ -11,7 +11,7 @@ export default function HeroComposition({
}: {
className?: string;
}) {
// MCM node coordinates (interconnected mesh, upper-left field).
// A2A node coordinates (interconnected mesh, upper-left field).
const nodes = [
{ x: 70, y: 90 },
{ x: 160, y: 60 },
@@ -36,7 +36,7 @@ export default function HeroComposition({
<svg
viewBox="0 0 380 380"
role="img"
aria-label="MCM 상호운용 노드와 QUIC 멀티스트림을 형상화한 추상 일러스트레이션"
aria-label="A2A 에이전트 메시와 QUIC/gRPC 멀티스트림을 형상화한 추상 일러스트레이션"
className={className}
>
{/* Frame */}
@@ -66,7 +66,7 @@ export default function HeroComposition({
})}
</g>
{/* ---- MCM: interconnected node mesh (vermillion) ---- */}
{/* ---- A2A: interconnected node mesh (vermillion) ---- */}
<g stroke="#D9342B" strokeWidth="1.5">
{edges.map(([a, b], i) => (
<line
@@ -97,12 +97,12 @@ export default function HeroComposition({
</g>
{/* Annotations — placed in the top corners (y=24), clear of the
MCM node mesh (y=60..240) and the QUIC stream curves (y≥250 with
A2A node mesh (y=60..240) and the QUIC stream curves (y≥250 with
control points reaching y+40=380). See LAYOUT_AUDIT #3 and
REVIEW §3 "P1 #3" — keeping them at y=24 (mirror corners) preserves
a symmetric layout that the original LAYOUT_AUDIT mirror decided on. */}
<text x="20" y="24" fill="#0A0A0A" fontSize="11" fontWeight="600" letterSpacing="2">
MCM · MESH
A2A · MESH
</text>
<text
x="360"
+93 -71
View File
@@ -12,45 +12,80 @@ export const metadata: Metadata = {
"QUIC, gRPC, A2A 기반 에이전트 통신 및 멀티에이전트 오케스트레이션을 연구하는 경북대학교 AI 에이전트 네트워크 연구실 (ANL) 소개.",
};
// CUSTOMIZATION HOOK: the two research thrusts (cover spread comparison).
const thrusts = [
// CUSTOMIZATION HOOK: the five research pillars (5 Pillars, Option A).
const pillars = [
{
no: "Thrust 01",
tag: "MCM",
no: "Pillar 01",
tag: "Agent Eng",
accent: "vermillion" as const,
ko: "메타버스 상호운용성",
en: "Metaverse Interoperability",
desc: "이종(異種) 메타버스 플랫폼 간 객체·아바타·자산의 상호운용을 위한 공통 데이터 모델과 변환 계층을 설계합니다. oneM2M / W3C 표준을 기반으로 서로 다른 가상 환경이 동일한 의미(semantics)로 데이터를 교환합니다.",
ko: "AI 에이전트 3대 핵심 엔지니어링",
en: "Agent Core Engineering",
desc: "프롬프트, 컨텍스트, 하네스 엔지니어링을 결합하여 대화 상태 보존, 외부 기억 바인딩, 도구 연동 인터페이스를 설계하고 자율 추론 경로를 최적화합니다.",
points: [
"공통 정보 모델(Common Information Model) 정의",
"의미 보존 변환(semantic-preserving mapping) 계층",
"상호운용성 테스트베드 및 적합성 검증",
"역할 페르소나 및 Few-shot 최적화",
"동적 컨텍스트 윈도우 & Memory 바인딩",
"물리적 도구(Tool Use) 하네스 연결",
],
},
{
no: "Thrust 02",
tag: "QUIC",
no: "Pillar 02",
tag: "MCP & SKILL",
accent: "cobalt" as const,
ko: "멀티에이전트 오케스트레이션",
en: "Multi-Agent Orchestration",
desc: "다수의 자율 에이전트가 저지연·다중스트림 환경에서 협력하도록 QUIC 전송 위에 오케스트레이션 아키텍처와 통신 인터페이스를 설계합니다. 연결 마이그레이션과 스트림 다중화로 메시지 라우팅을 최적화합니다.",
ko: "AI Agent 기능 확장 프로토콜",
en: "Extensibility & Protocol",
desc: "Anthropic MCP 통일 호환 규격 및 코드+스키마+Few-shot이 패키징된 SKILL 모듈을 통해 에이전트의 로컬/원격 역량을 자율적으로 동적 확장합니다.",
points: [
"QUIC 스트림 다중화 기반 에이전트 메시지 라우팅",
"오케스트레이터–에이전트 제어 인터페이스 설계",
"연결 마이그레이션 기반 모바일·엣지 지원",
"MCP (Model Context Protocol) 통일 규격",
"자율 확장 SKILL 모듈 패키징",
"CLI 기반 자율 코딩 에이전트 제어",
],
},
{
no: "Pillar 03",
tag: "Orchestration",
accent: "vermillion" as const,
ko: "멀티 에이전트 협업 및 오케스트레이션",
en: "Multi-Agent Systems",
desc: "단일 에이전트의 환각과 컨텍스트 인지 한계를 극복하기 위해 역할 세분화(Role Specialization) 및 이종 모델 교차 검증과 오케스트레이션 인프라를 구축합니다.",
points: [
"HERDR 백그라운드 프로세스 컨테이너 격리",
"crewAI 역할/목표 기반 크루 프로세스",
"LangGraph 상태 보존형 순환 그래프 제어",
],
},
{
no: "Pillar 04",
tag: "A2A & ACP",
accent: "cobalt" as const,
ko: "에이전트 상호운용성 개방형 표준",
en: "Interoperability Standards",
desc: "Linux Foundation A2A 및 IBM ACP 오픈 표준 기반으로 이종 에이전트 간 서비스 발견, 태스크 위임, Agent Card 프로필 명세를 구현합니다.",
points: [
"A2A (Agent-to-Agent) 통신 오픈 표준",
"ACP 서비스 발견 & 태스크 위임",
"Agent Card (/.well-known/agent-card.json)",
],
},
{
no: "Pillar 05",
tag: "AIoT & gRPC",
accent: "vermillion" as const,
ko: "AIoT & 고성능 통신 백본",
en: "High-Performance Backbone",
desc: "스마트 팩토리/팜 엣지 자원 제약 환경에서 경량 프로토콜(MQTT/CoAP)과 HTTP/2·HTTP/3 gRPC/QUIC 양방향 스트리밍을 결합한 하이브리드 백본을 설계합니다.",
points: [
"gRPC & QUIC 양방향 스트리밍 메시징",
"Protobuf 바이너리 직렬화 최적화",
"MQTT-gRPC 하이브리드 엣지 메쉬",
],
},
];
// CUSTOMIZATION HOOK: headline figures (animated counters).
// `value: 2026` is marked static so it renders as a fixed year, not a
// 0→2026 count-up. The year is also rendered at the smaller `display-sm`
// scale (the other two figures use the full `display` scale), so the
// 4-digit "2026" does not push the cell padding. See LAYOUT_AUDIT #11 + #13.
const figures = [
{ value: 2, label: "연구 · Research Thrusts", suffix: "", size: "display" as const, static: false },
{ value: 4, label: "표준화 기구 · Standards Bodies", suffix: "", size: "display" as const, static: false },
{ value: 2026, label: "Issue · 발행", suffix: "", size: "display-sm" as const, static: true },
{ value: 5, label: "연구 기둥 · Research Pillars", suffix: "", size: "display-sm" as const, static: false },
{ value: 12, label: "에이전트 프로토콜 · Protocols", suffix: "", size: "display-sm" as const, static: false },
{ value: 99.9, label: "가동률 % · Availability", suffix: "%", size: "display-sm" as const, static: false },
];
// CUSTOMIZATION HOOK: research keyword ticker.
@@ -182,69 +217,56 @@ export default function IntroPage() {
</div>
</section>
{/* ============ TWO THRUSTS — SIDE BY SIDE WITH CONNECTING LINE ============ */}
{/* ============ FIVE RESEARCH PILLARS ============ */}
<section className="border-b border-ink">
<div className="container-content py-16 sm:py-24">
<Reveal>
<SectionLabel index={3} label="Two Research Thrusts" />
<SectionLabel index={3} label="Five Research Pillars" />
</Reveal>
<div className="relative mt-12 grid gap-px lg:grid-cols-2">
{/* Connecting line + node between the two thrusts (desktop) */}
<div
aria-hidden
className="absolute left-1/2 top-1/2 hidden -translate-x-1/2 -translate-y-1/2 lg:block"
>
<div className="flex items-center">
<span className="h-2 w-2 rounded-full bg-vermillion" />
<span className="h-px w-16 bg-ink" />
<span className="flex h-9 w-9 items-center justify-center rounded-full border border-ink bg-ivory font-display text-xs">
×
</span>
<span className="h-px w-16 bg-ink" />
<span className="h-2 w-2 rounded-full bg-cobalt" />
</div>
</div>
{thrusts.map((t, i) => {
const isVerm = t.accent === "vermillion";
<div className="mt-12 grid gap-px bg-line sm:grid-cols-2 lg:grid-cols-3">
{pillars.map((p, i) => {
const isVerm = p.accent === "vermillion";
return (
<Reveal
key={t.tag}
variant={i === 0 ? "left" : "right"}
delay={i * 120}
key={p.tag}
variant={i % 2 === 0 ? "left" : "right"}
delay={i * 80}
className="bg-ivory"
>
<article
className={`group h-full border border-ink p-8 transition-colors duration-500 sm:p-10 ${
className={`group flex h-full flex-col justify-between border border-ink p-8 transition-colors duration-500 sm:p-10 ${
isVerm
? "hover:bg-vermillion hover:text-ivory"
: "hover:bg-cobalt hover:text-ivory"
}`}
>
<div className="flex items-baseline justify-between">
<span className="kicker group-hover:text-ivory/70">{t.no}</span>
<span
className={`font-display text-5xl ${
isVerm ? "text-vermillion" : "text-cobalt"
} group-hover:text-ivory`}
>
{t.tag}
</span>
<div>
<div className="flex items-baseline justify-between">
<span className="kicker group-hover:text-ivory/70">{p.no}</span>
<span
className={`font-display text-2xl ${
isVerm ? "text-vermillion" : "text-cobalt"
} group-hover:text-ivory`}
>
{p.tag}
</span>
</div>
<h3 className="headline-ko mt-6 text-2xl leading-tight">
{p.ko}
</h3>
<p className="font-display mt-1 text-base italic opacity-70">
{p.en}
</p>
<p className="mt-5 text-sm leading-relaxed opacity-90">
{p.desc}
</p>
</div>
<h3 className="headline-ko mt-6 text-3xl leading-tight">
{t.ko}
</h3>
<p className="font-display mt-1 text-lg italic opacity-70">
{t.en}
</p>
<p className="mt-5 text-sm leading-relaxed opacity-90">
{t.desc}
</p>
<ul className="mt-6 space-y-3 text-sm">
{t.points.map((p) => (
<li key={p} className="flex gap-3 border-t border-ink/20 pt-3 group-hover:border-ivory/20">
{p.points.map((pt) => (
<li key={pt} className="flex gap-3 border-t border-ink/20 pt-3 group-hover:border-ivory/20">
<span className="font-display text-xs opacity-60"></span>
<span>{p}</span>
<span>{pt}</span>
</li>
))}
</ul>
+3 -3
View File
@@ -1,6 +1,6 @@
# 디자인 시스템 — "Issue 01"
> 사물인터넷 표준 연구실 랜딩 페이지의 **정본(canonical) 디자인 레퍼런스**입니다.
> AI 에이전트 네트워크 연구실 (ANL) 랜딩 페이지의 **정본(canonical) 디자인 레퍼런스**입니다.
> 코드베이스를 다시 읽지 않고도 디자인 시스템을 이해할 수 있도록 작성했습니다.
> 토큰의 실제 정의는 `tailwind.config.ts` 와 `app/globals.css`(`:root`)에,
> 폰트 로딩은 `app/layout.tsx` 에 있습니다.
@@ -11,7 +11,7 @@
**연구실 웹사이트를 "한 권의 인쇄 잡지(Issue 01)"로 다룬다.**
따뜻한 종이(ivory) 위에 가까운-검정 잉크(ink), 두 개의 편집 강조색
(vermillion = MCM, cobalt = QUIC), 큰 세리프 디스플레이 타이포, 그리고 절제된
(vermillion = Agent Engineering / Orchestration, cobalt = MCP / A2A Protocol), 큰 세리프 디스플레이 타이포, 그리고 절제된
스크롤 등장 모션으로 구성된 **고대비 매거진 스프레드** 시스템입니다. 소수의
토큰에서 사이트 전체가 파생되며, 토큰 하나를 바꾸면 전 페이지에 전파됩니다.
@@ -27,7 +27,7 @@
| **움직임은 절제 (Restrained motion)** | 콘텐츠는 한 번 부드럽게 자리잡고 멈춘다. 튀거나 반복되지 않으며, 단일 이징으로 페이지 전체가 일관된 호흡을 갖는다. |
| **콘텐츠 우선 (Content first)** | 모든 편집 데이터는 각 페이지 상단 `// CUSTOMIZATION HOOK` 배열에 모은다. 모션·장식은 정보를 전달하는 수단이지 그 자체가 목적이 아니다. |
| **한/영 혼식 (KO/EN bilingual setting)** | 한국어 세리프(Noto Serif KR) 헤드라인과 영어 디스플레이 세리프(Fraunces)를 짝지어, 국문 제목 + 영문 디스플레이 단어의 매거진 바이링구얼 조판을 만든다. |
| **의미 있는 색 (Semantic accent pairing)** | 두 강조색은 장식이 아니라 연구 두 축을 인코딩한다 — **vermillion = MCM/메타버스/저널(홀수)**, **cobalt = QUIC/전송/학회(짝수)**. |
| **의미 있는 색 (Semantic accent pairing)** | 두 강조색은 장식이 아니라 연구 영역을 인코딩한다 — **vermillion = Agent Eng / Orchestration (홀수)**, **cobalt = MCP / A2A Protocol (짝수)**. |
---
+2 -2
View File
@@ -10,8 +10,8 @@ import type { Config } from "tailwindcss";
* ink → near-black, all primary type & rules
* ivory → warm paper background
* paper → slightly dimmer paper for cards / insets
* vermillion → MCM thrust accent (hot) [Thrust 1]
* cobalt → QUIC thrust accent (cool) [Thrust 2]
* vermillion → Agent Engineering / Orchestration accent (hot)
* cobalt → MCP / A2A Protocol accent (cool)
* Swap any hex and the entire editorial system follows.
*
* CUSTOMIZATION HOOK — FONTS