/* XR 웹 진입 화면은 공통 KETI 토큰을 따른다. 헤드셋 HUD는 별도 렌더러다. */
html{height:auto;min-height:100%;overflow:auto}
body{height:auto;min-height:100vh;overflow:visible;margin:0 auto;max-width:1600px;padding:24px 32px;font-size:15px;line-height:1.5}
[hidden]{display:none!important}
header,footer,.viewer-label,.viewer-footer,label{display:flex;align-items:center;justify-content:space-between;gap:14px}
/* 정지 버튼은 스크롤해도 보이도록 제목줄을 고정한다. */
header{position:sticky;top:0;z-index:5;margin:0 -8px 18px;padding:10px 8px;border:0;border-bottom:1px solid var(--line-soft);background:var(--bg);overflow:visible}
.header-actions{display:flex;align-items:center;gap:10px;flex:none}
header .title{min-width:0}
.robot-line{display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px;margin:2px 0 0;font-size:var(--fs-2)}
.robot-line strong{color:var(--ink);font-family:ui-monospace,monospace;letter-spacing:.03em}
.connection-chip{display:inline-flex;align-items:center;gap:7px;padding:2px 10px;border:1px solid var(--line2);border-radius:var(--r-pill);color:var(--ink2)}
.connection-chip i,.connection dt i{flex:none;width:8px;height:8px;border-radius:50%;background:var(--busy)}
.connection-chip i.live,.connection dt i.live{background:var(--link-ok)}
header h1{font-size:27px;font-weight:700;letter-spacing:.05em;color:var(--ink);margin:3px 0}
header h1 span{color:var(--accent)}
header h1::before{content:none}
h2{font-size:20px;margin:5px 0 14px}
small{font-size:var(--fs-1);font-weight:700;letter-spacing:.13em;color:var(--dim)}
button,input,select{font:inherit;color:var(--ink);background:var(--card);border:1px solid var(--line2);border-radius:var(--r-3)}
button{min-height:44px;padding:10px 15px;cursor:pointer}
button:hover:not(:disabled){border-color:var(--accent);background:var(--surface)}
button:disabled{opacity:.55;cursor:not-allowed}
:focus-visible{outline:2px solid var(--focus);outline-offset:3px}
.primary{background:var(--accent);color:var(--on-accent);border-color:var(--accent);font-weight:700}
.primary:hover:not(:disabled){background:var(--accent2);color:var(--on-accent)}
.danger{color:var(--err);border-color:var(--err);background:var(--err-bg);font-weight:700;min-width:112px;min-height:48px}
.danger:hover:not(:disabled){background:var(--err-bg);border-color:var(--err)}
main{display:grid;grid-template-columns:minmax(0,1fr) minmax(300px,330px);gap:18px;align-items:start}
.xr-stage,aside{display:flex;flex-direction:column;gap:16px;min-width:0}
.panel{min-width:0;padding:19px;border:1px solid var(--line);border-radius:var(--r-4);background:var(--panel)}
.launch-panel{border-color:var(--line2);padding:16px 19px}
.launch-body{display:grid;grid-template-columns:minmax(0,1fr) minmax(190px,240px);gap:14px 24px;align-items:end}
.launch-main h2{margin:3px 0 8px}
.launch-status{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));margin:0;border-top:1px solid var(--line-soft)}
.launch-status>div{min-width:0;padding:8px 12px 2px 0}
.launch-status>div+div{padding-left:12px;border-left:1px solid var(--line-soft)}
.launch-status dt{display:flex;align-items:center;gap:7px;font-size:var(--fs-1);color:var(--dim)}
.launch-status dd{margin:2px 0 0;font-size:var(--fs-2);font-weight:700;color:var(--ink);overflow-wrap:anywhere}
.launch-action .primary{width:100%;white-space:nowrap}
.enter-reason{margin:6px 0 0;font-size:var(--fs-1);line-height:1.5;color:var(--ink2)}
.launch-panel>.hint{margin-top:10px;padding-top:10px;border-top:1px solid var(--line-soft)}
.viewer{min-height:420px;position:relative;overflow:hidden;display:flex;align-items:center;justify-content:center;border:1px solid var(--line2);border-radius:var(--r-4);background:var(--bg-0)}
.viewer-label,.viewer-footer{position:absolute;left:20px;right:20px;z-index:1;color:var(--ink2);font-size:var(--fs-1);letter-spacing:.05em}
.viewer-label{top:16px}.viewer-footer{bottom:16px}
.viewer-label span,.viewer-footer span{max-width:75%;padding:4px 8px;border:1px solid var(--line2);border-radius:var(--r-2);background:var(--panel);color:var(--ink);overflow-wrap:anywhere}
.viewer video{width:100%;max-height:630px;object-fit:contain}
#video-placeholder{position:absolute;padding:32px;text-align:center;color:var(--dim)}
#video-placeholder h2{color:var(--ink);margin-bottom:8px}
#video-placeholder p{max-width:440px;margin:0 auto;color:var(--ink2)}
.reticle{font-size:64px;font-weight:200;color:var(--accent)}
.hint{font-size:var(--fs-2);color:var(--ink2);line-height:1.65;margin:12px 0 0}
#collision-status.predicted{color:var(--help)}
#collision-status.contact{color:var(--err);font-weight:700}
.segmented{display:flex}.segmented button{flex:1;padding:9px 3px;border-radius:0}
.segmented button:first-child{border-radius:var(--r-3) 0 0 var(--r-3)}
.segmented button:last-child{border-radius:0 var(--r-3) var(--r-3) 0}
.segmented button.selected{color:var(--accent);border-color:var(--accent);background:var(--surface);font-weight:700}
label{font-size:var(--fs-2);margin-top:14px}
input[type=number]{width:67px;padding:5px;text-align:right}
select{padding:6px;max-width:170px}
input[type=checkbox]{accent-color:var(--accent);width:17px;height:17px}
aside .panel>button,.robot-actions button{display:block;width:100%;margin-top:9px;text-align:left}
aside .panel>button:disabled,.robot-actions button:disabled{opacity:.58}
.control-panel h2{margin-bottom:8px}
.control-state{display:flex;align-items:baseline;gap:10px;font-size:var(--fs-2);color:var(--dim)}
.control-state strong{font-size:var(--fs-4);color:var(--ink)}
.mode-note{margin-top:4px}
.stage-actions{display:flex;gap:7px;margin-top:10px}.stage-actions button{flex:1;min-width:0;padding:9px 7px;font-size:var(--fs-1)}
/* 제어 시작 = 명시적 무장(윤곽 강조). 실제 로봇 1회 동작은 구분선 아래 보조 버튼 — 진한 primary 로 만들지 않는다. */
.control-start{border-color:var(--accent);color:var(--accent);font-weight:700}
.control-start:disabled{border-color:var(--line2);color:var(--dim);background:var(--card)}
.robot-actions{margin-top:14px;padding-top:12px;border-top:1px solid var(--line-soft)}
details{font-size:var(--fs-2);color:var(--ink2)}
aside .panel details{margin-top:14px}
summary{cursor:pointer;font-weight:700;color:var(--ink2)}
summary:hover{color:var(--accent)}
details.panel>summary{font-size:var(--fs-4);color:var(--ink);list-style-position:inside}
.settings-content{padding-top:5px}
pre{white-space:pre-wrap;overflow-wrap:anywhere;font:11px/1.6 monospace}
.model-panel{grid-column:1}
.model-body{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:24px;padding-top:12px}
.model-settings label:first-child{margin-top:0}
#model-preview{display:block;width:100%;height:auto;background:var(--card2);border:1px solid var(--line);border-radius:var(--r-3);margin-top:12px}
#model-head{max-width:175px;font-size:var(--fs-1)}
#model-align{margin-top:15px;width:100%}
.joints{grid-column:2;min-height:140px}
#joints{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,220px),1fr));gap:10px}
#joints .joint{display:flex;flex-wrap:wrap;min-width:0;align-items:center;justify-content:space-between;gap:10px;padding:9px 12px;border-radius:var(--r-3);background:var(--card2);border:1px solid var(--line-soft);font-size:var(--fs-1);color:var(--ink2)}
#joints .joint>span{flex:1 1 100%;min-width:0;overflow-wrap:anywhere}
#joints strong{font-size:var(--fs-2);font-variant-numeric:tabular-nums;font-family:ui-monospace,monospace;color:var(--ink)}
#joints .joint .range{position:relative;flex:1;min-width:56px;height:6px;border-radius:var(--r-1);background:var(--surface);border:1px solid var(--line2)}
#joints .joint .range b{position:absolute;top:-3px;width:10px;height:10px;margin-left:-5px;border-radius:50%;background:var(--link-ok)}
#joints .joint .range.warn b{background:var(--help)}
#joints .joint .range.near b,#joints .joint .range.limit b{background:var(--err)}
#joints .joint .range.unknown{opacity:.35}
#joints .joint em{font-style:normal;min-width:30px;text-align:right;color:var(--ink2)}
#joints .joint.warn em{color:var(--help)}
#joints .joint.near em,#joints .joint.limit em{color:var(--err)}
footer{font-size:var(--fs-1);color:var(--dim);margin:20px 0}
#xr-canvas{display:none}
@media(max-width:1050px){
  main{grid-template-columns:minmax(0,1fr) minmax(270px,300px)}
  /* 좁아지면 상태를 세로 목록으로 — 긴 사유가 세 칸에서 여러 줄로 부풀지 않게. 버튼은 오른쪽에 둔다. */
  .launch-status{grid-template-columns:1fr}
  .launch-status>div,.launch-status>div+div{display:flex;justify-content:space-between;align-items:baseline;gap:12px;padding:6px 0;border-left:0;border-bottom:1px solid var(--line-soft)}
  .launch-status dt{flex:none}
  .launch-status dd{margin:0;text-align:right}
}
@media(max-width:900px){
  body{padding:20px}
  main{grid-template-columns:1fr}
  aside{display:flex;flex-direction:column}
  .launch-body,.model-body{grid-template-columns:1fr}
  #joints{grid-template-columns:1fr}
  .model-panel,.joints{grid-column:1}
  .viewer{min-height:300px}
}
@media(max-width:600px){
  header{gap:10px;align-items:flex-start}header h1{font-size:21px}header .title>small{display:none}
  header button{padding:9px 11px}.danger{min-width:var(--stop-min-w,96px)}
  .launch-body{grid-template-columns:1fr}
  aside{display:flex}
  .model-body{grid-template-columns:1fr}
  .joints{grid-column:1}
  footer{align-items:flex-start;flex-wrap:wrap}
}

/* 마이크 캡처/송신과 로봇 소리 수신/로컬 재생 — 파랑/민트 두 채널을 한 줄에 둔다. */
.audio-line{display:flex;gap:12px;align-items:center;min-width:0;font-size:12px}
.audio-row{display:flex;align-items:center;gap:6px;min-width:0;white-space:nowrap;min-height:34px}
.audio-row strong{font-size:12px}.audio-meter{display:flex;align-items:center;gap:2px;width:28px;height:18px;color:#4c9aff;flex:none}
.audio-meter.incoming{color:#40cdb3}.audio-meter i{display:block;width:3px;height:3px;border-radius:2px;background:currentColor;opacity:.25;transition:height .18s ease}
.audio-meter i[data-active=true]{opacity:1}.audio-actions{display:flex;gap:8px;margin-top:6px}.audio-actions button{min-height:44px;cursor:pointer;font:inherit;border:1px solid var(--line);border-radius:6px;background:var(--panel,var(--surface));color:inherit;padding:8px 12px}
@media(max-width:600px){.audio-line{gap:8px;font-size:11px}.audio-row{gap:4px}.audio-row strong{font-size:11px}.audio-meter{width:22px;gap:1px}}
@media(prefers-reduced-motion:reduce){.audio-meter i{transition:none}}

/* 메모 인식은 통화 마이크와 별개이며 제목줄에서 한 번 눌러 시작·마침한다. */
#voice-memo{min-height:44px;white-space:nowrap}
#voice-memo[data-state="starting"],#voice-memo[data-state="listening"]{color:var(--accent);border-color:var(--accent)}
.voice-memo-line{display:flex;align-items:center;flex-wrap:wrap;gap:8px 14px;margin:-8px 0 16px;min-height:24px;font-size:13px;color:var(--ink2)}
#voice-memo-preview{max-width:100%;overflow-wrap:anywhere;color:var(--ink)}
.voice-memo-line button{min-height:44px}
@media(max-width:600px){header{flex-wrap:wrap}.header-actions{margin-left:auto}#voice-memo{padding:9px 11px}.voice-memo-line{font-size:12px}}

.sam-controls>button{margin-right:12px}.sam-controls #sam-status{font-size:13px;color:var(--ink2)}
#sam-canvas{display:block;width:100%;height:auto;max-height:540px;background:var(--bg-0);touch-action:none}
.sam-options,.sam-actions,#sam-objects{display:flex;flex-wrap:wrap;gap:10px;margin-top:12px}.sam-options label{flex:1}
#sam-confirm{white-space:pre-wrap;overflow-wrap:anywhere;font-size:12px;max-height:240px;overflow:auto}
/* 일반 콕핏의 한 팔 개입 controller를 같은 제어 칸에서 쓴다. */
.cockpit-arm-intervention{margin:12px 0;padding:12px;border:1px solid var(--line2);border-radius:var(--r-3);background:var(--card)}
.cockpit-arm-intervention[hidden],.cockpit-arm-intervention [hidden]{display:none}
.arm-intervention-heading,.arm-intervention-actions{display:flex;align-items:center;flex-wrap:wrap;gap:8px}
.arm-intervention-heading{justify-content:space-between}.arm-intervention-heading span,.arm-intervention-footnote{color:var(--dim);font-size:12px}
.cockpit-arm-intervention p{margin:8px 0;font-size:13px}.arm-intervention-actions button{flex:1 1 auto}
.arm-intervention-pad{display:flex;flex-direction:column;gap:6px;padding:12px;border:1px solid var(--line2);border-radius:var(--r-3);background:var(--surface);touch-action:none;user-select:none;font-size:13px}
.arm-intervention-pad:focus-visible{outline:2px solid var(--focus)}.cockpit-arm-intervention.moving{border-color:var(--accent2)}
.cockpit-arm-intervention [data-arm="mode-label"]{flex-direction:column;align-items:stretch;gap:6px}.cockpit-arm-intervention [data-arm="mode"]{width:100%}

/* 진입 프로필은 launch 카드 안의 비차단 설정이다. */
.controller-profile{min-width:0;padding-bottom:var(--sp-6,12px);margin-bottom:var(--sp-6,12px);border-bottom:1px solid var(--line)}
.controller-profile select,.controller-profile input{min-width:0;width:100%;max-width:var(--field-w-lg,260px)}
.controller-profile label{display:flex;flex-wrap:wrap;gap:var(--sp-4,8px);align-items:center}
#session-badge{overflow-wrap:anywhere}
#companion-link{display:block;max-width:100%}

.portal { max-width: var(--page-max-w, 1200px); margin: var(--sp-4, 16px) auto; padding: var(--pad-card, 16px); }
.portal-actions, .portal-robot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3, 12px); }
.portal-robot { padding: var(--sp-3, 12px) 0; border-bottom: 1px solid var(--border, #344052); }
.portal a { color: var(--accent, #70d9c2); }

.portal-actions button { min-height:var(--control-h, 32px); padding:var(--sp-2, 8px) var(--sp-3, 12px); border:1px solid var(--accent); border-radius:var(--r-2, 4px); color:var(--accent); background:var(--panel); cursor:pointer; font:inherit; }

.xr-mode-hero-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-5,16px);width:100%;margin-bottom:var(--sp-6,18px)}
.xr-mode-hero-btn,.portal a.xr-mode-hero-btn{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--sp-4,8px);min-width:0;min-height:132px;padding:22px 20px;box-sizing:border-box;border:1px solid var(--line2);border-radius:var(--r-4,8px);background:var(--card);color:var(--ink);text-align:center;text-decoration:none;cursor:pointer}
.xr-mode-hero-btn:hover:not(:disabled){border-color:var(--accent);background:var(--surface)}
.xr-mode-hero-title{font-size:var(--fs-4,18px);font-weight:700;letter-spacing:.04em}
.xr-mode-hero-sub{font-size:var(--fs-2,13px);color:var(--ink2)}
#enter{font-size:0} #enter::before{content:'IMMERSIVE MODE';font-size:var(--fs-4,18px);font-weight:700;letter-spacing:.04em} #enter::after{content:'VR Headset Stereo + 3D URDF';font-size:var(--fs-2,13px);color:var(--ink2)}
@media(max-width:600px){.xr-mode-hero-btn,.portal a.xr-mode-hero-btn{padding:var(--sp-4,8px)}}

#enter[data-active='true']::before{content:'EXIT VR'} #enter[data-active='true']::after{content:'세션 종료'}

body[data-root-portal="true"] .launch-hero-grid{display:none}
.xr-mode-hero-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-5,16px);width:100%;margin-bottom:var(--sp-6,18px)}
.xr-mode-hero-btn,.portal a.xr-mode-hero-btn{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;min-width:0;min-height:148px;padding:24px 20px;box-sizing:border-box;border:2px solid var(--accent,#70d9c2);border-radius:var(--r-4,8px);background:var(--card);color:var(--ink);text-align:center;text-decoration:none;cursor:pointer}
.xr-mode-hero-btn:hover:not(:disabled){border-color:var(--accent2,#9cf6e4);background:var(--surface)}
.xr-mode-hero-title{font-size:24px;font-weight:800;letter-spacing:.06em;color:var(--ink)}
.xr-mode-hero-sub{font-size:var(--fs-2,13px);color:var(--ink2)}
#enter{font-size:0} #enter::before{content:'IMMERSIVE MODE';font-size:24px;font-weight:800;letter-spacing:.06em;color:var(--ink)} #enter::after{content:'VR Headset Stereo + 3D URDF';font-size:var(--fs-2,13px);color:var(--ink2)}
@media(max-width:600px){.xr-mode-hero-btn,.portal a.xr-mode-hero-btn{padding:var(--sp-4,8px)}}
#enter[data-active='true']::before{content:'EXIT VR'} #enter[data-active='true']::after{content:'세션 종료'}
