/* Simple console: page chrome (navbar, pills, buttons, segments) comes from
   style.css; this file only owns the operate stage, the floating controls and
   the settings-page extras that have no advanced-mode counterpart. */
[hidden]{display:none!important}
.symbols{position:absolute;width:0;height:0}

/* ---------- Transient toast ---------- */
/* Semantic info / negative message: flat tinted face, inset ring, no border.
   A drag tracks the finger while lifting the toast; past the threshold it
   hands off to the same `.leaving` transition the close button and the
   auto-hide timer use, so all three exits look identical. */
#message{position:fixed;top:calc(var(--nav-height) + 12px + env(safe-area-inset-top));left:50%;transform:translate(-50%,0);z-index:100;max-width:min(90vw,560px);display:flex;align-items:flex-start;gap:.6em;padding:1em 1.5em;background:var(--primary-tint);box-shadow:0 0 0 1px var(--primary-border) inset,var(--shadow-md);border-radius:var(--radius);color:#276f86;font-weight:700;transition:transform .18s ease,opacity .18s ease;touch-action:none}
#message.leaving{transform:translate(-50%,-28px);opacity:0}
#message.dragging{transition:none}
#message.error{background:var(--negative-tint);color:var(--negative-text);box-shadow:0 0 0 1px var(--negative-border) inset,var(--shadow-md)}
#message:focus-visible{outline:2px solid var(--focus-border);outline-offset:3px}
#message-text{flex:1;padding-top:.05em}
#message-close{flex:none;margin:-.3em -.6em -.3em 0;border:0;background:none;color:inherit;opacity:.55;font-size:20px;line-height:1;padding:.3em .6em;cursor:pointer;transition:opacity .1s ease}
#message-close:hover{opacity:1}
#message-close:focus-visible{outline:2px solid var(--focus-border);outline-offset:2px;opacity:1}

/* ---------- Operate stage ---------- */
#stage{position:relative;height:calc(100dvh - var(--nav-height) - 60px);min-height:330px;max-height:1000px;background:#1b1c1d;border-radius:var(--radius);overflow:hidden;isolation:isolate;touch-action:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none}
#stage video{display:block;width:100%;height:100%;object-fit:contain;pointer-events:none}
#video-status{position:absolute;top:12px;left:12px;color:#ffffffa6;font-size:12px;pointer-events:none}
#stage-toolbar{position:absolute;right:54px;top:10px;z-index:2;display:flex;align-items:center;gap:10px}
#viewer-count{min-height:34px;display:flex;align-items:center;color:rgba(255,255,255,.75);font-size:12px;font-weight:600;pointer-events:none}
#reconnect,#actions-toggle,#focus-auto{border:0;border-radius:var(--radius);background:rgba(0,0,0,.6);box-shadow:0 0 0 1px rgba(255,255,255,.2) inset;color:rgba(255,255,255,.8);padding:4px 9px;font-size:12px;font-weight:700;min-height:34px;cursor:pointer;transition:background-color .1s ease,color .1s ease}
#reconnect:hover,#actions-toggle:hover,#focus-auto:hover{background:var(--primary);box-shadow:none;color:#fff}
#focus-auto{background:rgba(251,189,8,.85);box-shadow:none;color:#1b1c1d}
#focus-auto:focus-visible{outline:2px solid var(--focus-border);outline-offset:3px}
#actions-toggle:focus-visible{outline:2px solid var(--focus-border);outline-offset:3px}
#actions-toggle[aria-expanded="true"]{background:var(--primary);box-shadow:none;color:#fff}
body.immersive #stage-toolbar{top:calc(10px + env(safe-area-inset-top));right:calc(54px + env(safe-area-inset-right))}

/* ---------- Tap-to-focus reticle ---------- */
/* Centred on the long-pressed point (left/top set from JS). The colour is the
   camera's own verdict, carried on every frame as AfState: amber while the
   lens is scanning, green once it reports focus, red when the scan failed and
   the plugin handed focus back to its configured mode. The ring is not on a
   timer -- it holds until that verdict arrives, then fades. */
#focus-ring{position:absolute;z-index:2;width:84px;height:84px;margin:-42px 0 0 -42px;border:2px solid rgba(251,189,8,.95);border-radius:6px;box-shadow:0 0 0 1px rgba(0,0,0,.35),0 0 0 1px rgba(0,0,0,.35) inset;pointer-events:none;opacity:1;transition:border-color .15s ease,opacity .35s ease,transform .2s ease;animation:focus-land .25s ease-out}
#focus-ring.scanning{animation:focus-land .25s ease-out,focus-pulse 1s ease-in-out .25s infinite}
#focus-ring.focused{border-color:rgba(33,186,69,.95);transform:scale(.88)}
#focus-ring.failed{border-color:rgba(219,40,40,.95)}
#focus-ring.leaving{opacity:0}
@keyframes focus-land{from{transform:scale(1.5);opacity:0}to{transform:scale(1);opacity:1}}
@keyframes focus-pulse{50%{opacity:.5}}
@media(prefers-reduced-motion:reduce){#focus-ring,#focus-ring.scanning{animation:none}#focus-ring.focused{transform:none}}

/* ---------- Collapsible quick-actions dock ---------- */
.actions{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:2;display:flex;flex-direction:row;gap:18px}
/* Semantic circular buttons floating over the video: flat white face, bold
   icon, Semantic's grey hover and the blue/red states from its colour set. */
.round{width:64px;height:64px;border:0;border-radius:50%;padding:18px;background:#fff;color:var(--text-muted);box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 2px 10px 0 rgba(0,0,0,.3);position:relative;cursor:pointer;transition:background-color .1s ease,color .1s ease}
.round:hover:not(:disabled){background:#f2f3f4;color:var(--text)}
.round:disabled{opacity:.45;cursor:not-allowed}
.round:focus-visible{outline:2px solid var(--focus-border);outline-offset:3px}
.round i.icon{display:none;margin:0;width:100%;height:100%;font-size:28px;line-height:1;align-items:center;justify-content:center;pointer-events:none}
.semantic-icons-ready .round i.icon{display:flex}
.semantic-icons-ready .round .icon-fallback{display:none}
.round svg{width:100%;height:100%;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
#light[aria-pressed=true]{background:#fbbd08;color:#fff}
#light[aria-pressed=true]:hover{background:#eaae00}
#light[aria-busy=true]{box-shadow:0 0 0 2px var(--focus-border),0 2px 10px 0 rgba(0,0,0,.3)}
.round.running{color:var(--negative)}
.round.running:before{content:"";position:absolute;inset:-6px;border:3px solid rgba(255,255,255,.35);border-top-color:var(--negative);border-radius:50%;animation:spin 1.3s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* ---------- Touch joysticks ---------- */
/* Hidden until a touch presses a control zone of the stage, then shown centered
   on that touch point (left/top are set from JS) and faded out on release. The
   pads are display-only: input is tracked on #stage, so the finger may drift
   anywhere after engagement. A landscape stage summons the two linear pads from
   its outer thirds; a portrait stage summons the round omni pad from its bottom
   third so one thumb drives both axes. Arrows are CSS triangles, not text: a
   long-press on text arrows would trigger the browser's copy UI. */
.pad{position:absolute;z-index:2;display:flex;align-items:center;justify-content:space-between;padding:7px;background:rgba(255,255,255,.09);border:1px solid rgba(255,255,255,.18);border-radius:999px;pointer-events:none;user-select:none;-webkit-user-select:none;-webkit-touch-callout:none;opacity:0;visibility:hidden;transition:opacity .25s ease,visibility .25s ease}
.pad.visible{opacity:1;visibility:visible;background:rgba(33,133,208,.35);border-color:rgba(101,185,246,.7)}
.pad-arrow{width:0;height:0;flex:none;border:7px solid transparent;pointer-events:none}
.pad-arrow-up{border-bottom-color:rgba(255,255,255,.55);border-top:0}
.pad-arrow-down{border-top-color:rgba(255,255,255,.55);border-bottom:0}
.pad-arrow-left{border-right-color:rgba(255,255,255,.55);border-left:0}
.pad-arrow-right{border-left-color:rgba(255,255,255,.55);border-right:0}
.pad-knob{width:34px;height:34px;flex:none;border-radius:50%;background:rgba(255,255,255,.7);box-shadow:0 2px 10px #0003;pointer-events:none}
.pad.vertical{width:52px;height:172px;flex-direction:column}
.pad.horizontal{width:172px;height:52px}
.pad.omni{width:176px;height:176px;display:block;padding:0}
.pad.omni .pad-arrow{position:absolute}
.pad.omni .pad-arrow-up{left:50%;top:10px;margin-left:-7px}
.pad.omni .pad-arrow-down{left:50%;bottom:10px;margin-left:-7px}
.pad.omni .pad-arrow-left{top:50%;left:10px;margin-top:-7px}
.pad.omni .pad-arrow-right{top:50%;right:10px;margin-top:-7px}
.pad.omni .pad-knob{position:absolute;left:50%;top:50%;margin:-17px 0 0 -17px}

/* ---------- Settings page ---------- */
#settings :is(#speed-value,#led-brightness-value,#video-bitrate-value){color:var(--primary);font-variant-numeric:tabular-nums}

#map{width:100%;height:52dvh;min-height:230px;background:#f9fafb;border:1px solid var(--border);border-radius:var(--radius);touch-action:none;display:block}
.map-tools{display:flex;gap:8px;margin-top:12px}

/* ---------- System panel ---------- */
.system-actions{display:flex;flex-wrap:wrap;gap:8px}
.log-view{margin:14px 0 0;padding:12px;max-height:46dvh;overflow:auto;background:#f9fafb;border:1px solid var(--border);border-radius:var(--radius);color:var(--text-muted);font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px;line-height:1.5;white-space:pre-wrap;overflow-wrap:anywhere;-webkit-overflow-scrolling:touch}
.log-view:focus-visible{outline:2px solid var(--focus-border);outline-offset:2px}

/* ---------- Immersive (video fullscreen) ---------- */
body.immersive{overflow:hidden;padding-top:0}
body.immersive #navbar{display:none}
body.immersive main{max-width:none;padding:0}
body.immersive #stage{height:100dvh;max-height:none;min-height:0;border-radius:0}
body.immersive .fullscreen-btn{top:calc(10px + env(safe-area-inset-top));right:calc(10px + env(safe-area-inset-right))}
body.immersive #video-status{top:calc(14px + env(safe-area-inset-top))}

/* ---------- Responsive ---------- */
@media(max-width:700px){
  main{padding:12px 14px 24px}
  #stage{height:calc(100dvh - var(--nav-height) - 36px);border-radius:var(--radius)}
  .actions{gap:14px}
  .round{width:58px;height:58px;padding:16px}
}
@media(orientation:landscape) and (max-height:550px){
  #stage{height:calc(100dvh - var(--nav-height) - 28px);min-height:220px}
  .round{width:54px;height:54px;padding:14px}
}
@media(prefers-reduced-motion:reduce){.round.running:before{animation-duration:4s}}

/* ---------- Console login ---------- */
/* Semantic "raised segment" on a plain grey page, with Semantic's own form
   field, fluid primary button and negative message. */
.login-page{min-height:100dvh;padding:0;background:var(--page-bg,#f7f7f7)}
.login-shell{min-height:100dvh;display:grid;place-items:center;padding:24px}
.login-card{width:min(100%,420px);padding:2em;background:#fff;border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow-md)}
/* Mark and wordmark sit on one line; the mark carries its own transparent
   padding, so it is pulled left a touch to line its body up with the fields. */
.login-brand{display:flex;align-items:center;gap:6px;margin:0 0 25px}
.login-logo{display:block;width:48px;height:48px;margin-left:-4px}
.login-card h1{margin:0;color:var(--text);font-size:28px;font-weight:700}
#login-form{display:grid;gap:0}
#login-form label{margin-top:1em;margin-bottom:.28571429rem;color:var(--text);font-size:13px;font-weight:700}
#login-form input{width:100%;height:38px;padding:.67857143em 1em;border:1px solid var(--border);border-radius:var(--radius);background:#fff;color:var(--text);font:inherit;outline:none;transition:border-color .1s ease}
#login-form input:focus{border-color:var(--focus-border);box-shadow:none}
.login-submit{width:100%;height:38px;margin-top:1.5em}
.login-submit:disabled{opacity:.45;cursor:wait}
.login-error{margin:1em 0 0;padding:1em 1.5em;border-radius:var(--radius);background:var(--negative-tint);box-shadow:0 0 0 1px var(--negative-border) inset;color:var(--negative-text);font-size:13px;font-weight:700}

@media(max-width:500px){.login-shell{padding:16px}.login-card{padding:28px 22px}}
