:root {
  --bg: #0e0f0e;
  --surface: #151715;
  --surface-2: #1b1e1b;
  --line: #272a27;
  --ink: #ece9e2;
  --muted: #9b988f;
  --faint: #6b6962;
  --accent: #e8794a;
  --sans: system-ui, -apple-system, "Segoe UI", "Apple SD Gothic Neo", "Noto Sans KR", sans-serif;
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
  --wrap: 1120px;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font-family: var(--sans); font-size: 16px; line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; }
code, pre, kbd { font-family: var(--mono); }
p code, li code, figcaption code {
  font-size: .9em; background: var(--surface-2); border: 1px solid var(--line);
  padding: .05em .35em; border-radius: 4px;
}
.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 16px; }
@media (min-width: 720px) { .wrap { padding: 0 32px; } }

/* nav */
nav { position: sticky; top: 0; z-index: 10; background: rgba(14,15,14,.86); backdrop-filter: blur(8px); border-bottom: 1px solid var(--line); }
nav .wrap { display: flex; align-items: center; gap: 28px; height: 60px; }
nav .brand img { height: 32px; width: auto; display: block; }
nav .links { display: flex; gap: 22px; font-size: 14px; color: var(--muted); }
nav .links a { text-decoration: none; }
nav .links a:hover { color: var(--ink); }
nav .right { margin-left: auto; display: flex; align-items: center; gap: 14px; font-size: 14px; }
nav .gh { display: inline-flex; align-items: center; gap: 8px; text-decoration: none; border: 1px solid var(--line); padding: 6px 12px; border-radius: 8px; color: var(--ink); }
nav .gh:hover { border-color: var(--faint); }
nav .lang { display: flex; align-items: center; gap: 8px; color: var(--faint); font-size: 13px; }
nav .lang a { text-decoration: none; color: var(--muted); white-space: nowrap; }
nav .lang a:hover { color: var(--ink); }
nav .lang a[aria-current="page"] { color: var(--ink); font-weight: 600; text-decoration: underline; text-decoration-color: var(--accent); text-underline-offset: 5px; text-decoration-thickness: 2px; }
@media (max-width: 860px) { nav .links { display: none; } }
@media (max-width: 520px) { nav .gh span { display: none; } nav .gh { padding: 6px 8px; } nav .wrap { gap: 16px; } nav .brand img { height: 26px; } }

/* hero */
.hero { padding: 88px 0 40px; }
.eyebrow { font-family: var(--mono); font-size: 13px; font-weight: 500; line-height: 1.5; color: var(--accent); letter-spacing: .02em; margin: 0 0 18px; }
.rot-stage { display: flex; align-items: flex-start; gap: .28em; font-size: clamp(2.4rem, 6.4vw, 4.6rem); }
.headline { font-size: 1em; line-height: 1.08; letter-spacing: -.03em; margin: 0; font-weight: 750; }
.headline em { font-style: normal; color: var(--accent); }

/* 잡힌 일이 움직이는 모양(moai web 의 view/spin.ts·m-spin·m-glint, TUI 의 SPIN_TICK)을 헤드라인에 옮긴다.
   스피너는 점자 열 프레임을 120ms 씩, 띠는 3칸 폭으로 지나가 8칸 쉬고 다시 온다(--glint-time 은 페이지가 글 길이로 준다).
   강조색 em 을 지키려고 띠는 글 위에 겹친 사본에만 그린다. 움직임을 줄이면 스피너는 첫 프레임에 서고 띠는 없다. */
:root { --review: color-mix(in srgb, #a855f7 70%, var(--ink)); --glint-edge: #fbc04e; --glint-core: #FFE7A3; }
/* 스피너는 글꼴의 점자(⠋…)가 아니라 같은 열 프레임을 점 여섯 개로 그린다 — 글꼴의 점은 굵기를 올려도
   두꺼워지지 않아, 큰 헤드라인 옆에서 가늘게 보였다. 켜진 점은 review 의 보라, 꺼진 점은 흐리게 남겨 칸 모양을 둔다.
   움직임을 줄이면 첫 프레임(⠋)에 선다. */
.rot-stage .spin { flex: none; display: block; width: .5em; height: .75em; margin-top: .22em; --off: .13; }
.rot-stage .spin svg { display: block; width: 100%; height: 100%; fill: var(--review); }
.rot-stage .spin circle { opacity: var(--off); }
.rot-stage .spin :is(.d1, .d2, .d4) { opacity: 1; }
.held-body { position: relative; display: block; min-width: 0; }
.held-glint { position: absolute; inset: 0; display: none; color: transparent; pointer-events: none; }
/* 회전판(히어로의 핵심 다섯 가지). 장은 한 칸에 겹쳐 두어 가장 긴 장의 높이를 지킨다 — 넘길 때 아래가 출렁이지 않는다.
   감춘 장은 visibility 로 감춰 읽기 도구에서도 빠진다. 진행 막대가 다 차면 site.js 가 다음 장으로 넘기고, 마우스가 올라가
   있거나 키보드 포커스가 들면 막대가 멈춰 넘기지도 않는다. 움직임을 줄이면 막대가 돌지 않아 스스로 넘기지 않는다. */
.rot-slides { flex: 1 1 auto; min-width: 0; display: grid; }
.slide { grid-area: 1 / 1; transition: opacity .45s ease, transform .45s ease, visibility 0s linear 0s; }
.slide[hidden] { display: block; visibility: hidden; opacity: 0; transform: translateY(10px); transition: opacity .3s ease, transform .3s ease, visibility 0s linear .3s; }
.slide .lede { margin: 26px 0 0; max-width: 760px; line-height: 1.75; }
.rot-tabs { display: flex; gap: 8px; margin: 34px 0 40px; }
.rot-tab { position: relative; flex: 1 1 0; min-width: 0; display: flex; align-items: baseline; gap: 8px; padding: 12px 0 0; border: 0; background: none; color: var(--faint); font: 500 13px var(--sans); text-align: left; cursor: pointer; }
.rot-tab:hover { color: var(--muted); }
.rot-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 2px; }
.rot-tab[aria-selected="true"] { color: var(--ink); }
.rot-n { font-family: var(--mono); font-size: 12px; }
.rot-tab[aria-selected="true"] .rot-n { color: var(--accent); }
.rot-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rot-bar { position: absolute; top: 0; left: 0; right: 0; height: 2px; border-radius: 2px; background: var(--line); overflow: hidden; }
.rot-bar::after { content: ""; position: absolute; inset: 0; background: var(--accent); transform: scaleX(0); transform-origin: left; }
.rot-tab[aria-selected="true"] .rot-bar::after { transform: scaleX(1); }
@media (max-width: 560px) { .rot-name { display: none; } .rot-tab { justify-content: center; } }
.held-glint em { color: transparent; }
@media (prefers-reduced-motion: no-preference) {
  .rot-stage .spin .d1 { animation: spin-d1 1.2s step-start infinite; }
  .rot-stage .spin .d2 { animation: spin-d2 1.2s step-start infinite; }
  .rot-stage .spin .d3 { animation: spin-d3 1.2s step-start infinite; }
  .rot-stage .spin .d4 { animation: spin-d4 1.2s step-start infinite; }
  .rot-stage .spin .d5 { animation: spin-d5 1.2s step-start infinite; }
  .rot-stage .spin .d6 { animation: spin-d6 1.2s step-start infinite; }
  .held-glint { display: block; }
  .rot-tab[aria-selected="true"] .rot-bar::after { animation: rot-fill var(--rot-time, 8s) linear forwards; }
  .rotator:hover .rot-bar::after { animation-play-state: paused; }
  /* :has 를 모르는 브라우저가 줄째 버리지 않게 따로 둔다 */
  .rotator:has(:focus-visible) .rot-bar::after { animation-play-state: paused; }
  .slide:not(.is-on) .held-glint > span { animation: none; }
  .held-glint > span {
    --glint-band: 2.2em;
    background-image: linear-gradient(90deg, transparent, var(--glint-edge) 25%, var(--glint-core) 50%, var(--glint-edge) 75%, transparent);
    background-size: var(--glint-band) 100%; background-repeat: no-repeat;
    -webkit-background-clip: text; background-clip: text;
    -webkit-box-decoration-break: slice; box-decoration-break: slice;
    animation: m-glint var(--glint-time, 4s) linear infinite;
  }
}
@keyframes spin-d1 { 0% { opacity: 1; } 10% { opacity: 1; } 20% { opacity: 1; } 30% { opacity: .13; } 40% { opacity: .13; } 50% { opacity: .13; } 60% { opacity: .13; } 70% { opacity: 1; } 80% { opacity: 1; } 90% { opacity: 1; } }
@keyframes spin-d2 { 0% { opacity: 1; } 10% { opacity: .13; } 20% { opacity: .13; } 30% { opacity: .13; } 40% { opacity: .13; } 50% { opacity: .13; } 60% { opacity: 1; } 70% { opacity: 1; } 80% { opacity: 1; } 90% { opacity: 1; } }
@keyframes spin-d3 { 0% { opacity: .13; } 10% { opacity: .13; } 20% { opacity: .13; } 30% { opacity: .13; } 40% { opacity: 1; } 50% { opacity: 1; } 60% { opacity: 1; } 70% { opacity: 1; } 80% { opacity: 1; } 90% { opacity: 1; } }
@keyframes spin-d4 { 0% { opacity: 1; } 10% { opacity: 1; } 20% { opacity: 1; } 30% { opacity: 1; } 40% { opacity: 1; } 50% { opacity: .13; } 60% { opacity: .13; } 70% { opacity: .13; } 80% { opacity: .13; } 90% { opacity: 1; } }
@keyframes spin-d5 { 0% { opacity: .13; } 10% { opacity: 1; } 20% { opacity: 1; } 30% { opacity: 1; } 40% { opacity: 1; } 50% { opacity: 1; } 60% { opacity: .13; } 70% { opacity: .13; } 80% { opacity: .13; } 90% { opacity: .13; } }
@keyframes spin-d6 { 0% { opacity: .13; } 10% { opacity: .13; } 20% { opacity: 1; } 30% { opacity: 1; } 40% { opacity: 1; } 50% { opacity: 1; } 60% { opacity: 1; } 70% { opacity: 1; } 80% { opacity: .13; } 90% { opacity: .13; } }
@keyframes rot-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes m-glint {
  from { background-position: calc(-1 * var(--glint-band)) 0; }
  to { background-position: calc(100% + var(--glint-band) + 8ch) 0; }
}
.lede { font-size: clamp(1.05rem, 1.6vw, 1.22rem); color: var(--muted); max-width: 640px; margin: 0 0 36px; }
.lede strong { color: var(--ink); font-weight: 600; }

.install { display: flex; align-items: center; gap: 12px; max-width: 640px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 14px 14px 14px 18px; }
.install code { flex: 1; font-size: 14px; white-space: nowrap; overflow-x: auto; scrollbar-width: none; }
.install code::-webkit-scrollbar { display: none; }
.install code .p { color: var(--faint); user-select: none; }
.copy { flex: none; font: 500 13px var(--sans); color: var(--ink); background: var(--surface-2); border: 1px solid var(--line); border-radius: 6px; padding: 6px 12px; cursor: pointer; }
.copy:hover { border-color: var(--faint); }
.meta { margin: 14px 0 0; font-size: 13px; color: var(--faint); }
.meta a { color: var(--muted); }


/* 녹화를 담는 창틀: 터미널과 브라우저 */
.window { background: #0a0b0a; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; box-shadow: 0 30px 80px -40px rgba(0,0,0,.8); }
.window .bar { display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-bottom: 1px solid var(--line); background: var(--surface); }
.window .bar i { width: 11px; height: 11px; border-radius: 50%; background: #2c302c; display: block; }
.window .bar span { margin-left: 10px; font: 12px var(--mono); color: var(--faint); }
.window .bar .addr { flex: 1; margin-left: 14px; padding: 3px 12px; border-radius: 6px; background: var(--bg); }
.window .cast { background: #121212; }
.window .cast .ap-wrapper, .window .cast .ap-player { border-radius: 0; }
.window video { display: block; width: 100%; height: auto; aspect-ratio: 1440 / 900; background: #13161a; }

/* logo marquee */
.logos { padding: 72px 0 8px; }
.logos h2 { text-align: center; font-size: 14px; font-weight: 500; color: var(--muted); margin: 0 0 26px; letter-spacing: .01em; }
.marquee { overflow: hidden; -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
/* 로고 묶음을 세 벌 이어 두고 한 벌 폭만큼 흘린다 — 한 벌이 본문 폭보다 좁아도 빈자리가 안 보인다 */
.track { display: flex; gap: 20px; width: max-content; animation: slide 30s linear infinite; }
.marquee:hover .track { animation-play-state: paused; }
@keyframes slide { to { transform: translateX(calc((100% + 20px) / -3)); } }
@media (prefers-reduced-motion: reduce) { .track { animation: none; } .slide, .slide[hidden] { transition: none; transform: none; } }
/* 로고는 제 색 그대로 둔다. 투명 바탕이라 흰 판을 깔고, 흰 글자 로고(Data HUB)만 검은 판에 얹는다 */
.slot { flex: none; height: 56px; padding: 0 26px; border-radius: 10px; background: #fff; display: flex; align-items: center; }
.slot img { display: block; height: 26px; width: auto; }
.slot.dark { background: #000; box-shadow: inset 0 0 0 1px var(--line); }

/* 장면: 글을 위에, 녹화를 아래에. 녹화는 본문과 같은 세로선 안에 선다 — 터미널 녹화는 그 폭에서 글자가
   읽히도록 120칸으로 찍는다(scripts/site-demo/record-tui.sh 의 SIZE) */
section.see { padding: 96px 0 24px; }
.sec-head { max-width: 720px; margin: 0 0 64px; }
h2.big { font-size: clamp(1.8rem, 3.6vw, 2.6rem); letter-spacing: -.02em; line-height: 1.18; margin: 0 0 14px; }
.sec-head p { color: var(--muted); margin: 0; font-size: 17px; }
.scene { margin: 0 0 112px; }
.scene-text { max-width: 760px; margin: 0 0 28px; }
.scene .n { font: 600 12px var(--mono); color: var(--accent); margin-bottom: 10px; }
.scene h3 { font-size: clamp(1.4rem, 2.6vw, 2rem); letter-spacing: -.015em; line-height: 1.22; margin: 0 0 14px; }
.scene p { margin: 0; color: var(--muted); }
.scene .run { margin-top: 20px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.scene .run .tag { font: 500 12px var(--sans); color: var(--faint); border: 1px solid var(--line); border-radius: 999px; padding: 3px 10px; }
.scene .run code { font-size: 13px; color: var(--ink); background: var(--surface-2); border: 1px solid var(--line); border-radius: 6px; padding: 4px 10px; }
.scene-media { min-width: 0; }

/* final cta */
.cta { padding: 110px 0 100px; text-align: center; }
.cta h2 { font-size: clamp(2rem, 4.6vw, 3.2rem); letter-spacing: -.025em; line-height: 1.15; margin: 0 0 16px; }
.cta p { color: var(--muted); margin: 0 auto 32px; max-width: 560px; }
.cta .install { margin: 0 auto; text-align: left; }

footer { border-top: 1px solid var(--line); padding: 36px 0 48px; color: var(--faint); font-size: 13px; }
footer .wrap { display: flex; flex-wrap: wrap; align-items: center; gap: 14px 28px; }
footer img { height: 24px; width: auto; display: block; opacity: .85; }
footer .links { display: flex; gap: 18px; margin-left: auto; }
footer a { text-decoration: none; color: var(--muted); }
footer a:hover { color: var(--ink); }

/* asciinema-player 의 색: 녹화한 TUI 가 쓰는 16색을 이 페이지의 바탕에 맞춘다 */
.asciinema-player-theme-moai {
  --term-color-foreground: #d9d6cf; --term-color-background: #121212;
  --term-color-0: #1b1e1b; --term-color-1: #e5534b; --term-color-2: #57ab5a; --term-color-3: #e2b857;
  --term-color-4: #539bf5; --term-color-5: #b083f0; --term-color-6: #39c5cf; --term-color-7: #cdd1cc;
  --term-color-8: #6b6962; --term-color-9: #f47067; --term-color-10: #6bc46d; --term-color-11: #fbc04e;
  --term-color-12: #6cb6ff; --term-color-13: #dcbdfb; --term-color-14: #56d4dd; --term-color-15: #ece9e2;
}

/* 감독·일꾼: 벤더가 다른 에이전트 셋과 moai tui 가 한 tmux 창에 선다 */
section.team { padding: 48px 0 8px; }
.team .window { margin: 0 0 44px; }
.team .sec-head { margin-bottom: 28px; }
.team-points { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; max-width: 760px; color: var(--muted); }
.team-points li { position: relative; padding-left: 22px; }
.team-points li::before { content: "▸"; position: absolute; left: 0; color: var(--accent); }
.team-points q { color: var(--ink); quotes: "“" "”"; }
