.camera-layout{display:grid;grid-template-columns:minmax(0,1.6fr) minmax(240px,1fr);gap:24px;align-items:start}
.camera-capture,.camera-record{min-width:0;padding:18px;border:1px solid var(--border,#3b4b5a);border-radius:16px;background:var(--panel,#172431)}
.camera-record h2{margin-top:0}.camera-actions{display:flex;flex-wrap:wrap;gap:10px;margin:12px 0}.camera-actions .btn{min-height:44px}
.camera-zoom{display:flex;align-items:center;gap:10px;margin:0 0 10px;font-size:13px;color:var(--muted,#a2b2ca);scroll-margin-top:calc(var(--top-h,56px) + 8px)}
/* The primary action sits right under the preview, so a marked board is confirmed without scrolling; the status follows. */
.camera-primary{margin:10px 0 0}#cameraStatus{margin:10px 0 0}
.camera-zoom label{white-space:nowrap}
.camera-zoom input[type=range]{flex:1;min-width:60px;margin:0;accent-color:var(--accent,#79dfaf)}
.camera-zoom output{min-width:3.4em;text-align:right;font-variant-numeric:tabular-nums;color:var(--ink,#e6eefb)}
.camera-zoom .btn{min-height:34px;padding:4px 10px;font-size:12px}
/* The box keeps the camera's aspect but never grows past half the screen; the
 * frame inside carries the video and overlay at their shared pixel size. */
#cameraVideoBox{position:relative;width:100%;aspect-ratio:var(--camera-aspect,16/9);max-height:min(56svh,520px);background:#080f16;border-radius:12px;overflow:hidden;cursor:crosshair;user-select:none;-webkit-user-select:none}
#cameraVideoBox:not(.camera-live){min-height:150px}
#cameraFrame{position:absolute;left:0;top:0;width:100%;height:100%;touch-action:pan-y}
#cameraFrame.camera-zoomed{touch-action:none;cursor:grab}
#cameraVideo{display:block;width:100%;height:100%;object-fit:fill;background:#080f16}
#cameraCorners{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible;touch-action:none}
.camera-grid{fill:none;stroke:#79dfaf;stroke-width:1.5;stroke-opacity:.8}
.camera-outline{fill:none;stroke:#79dfaf;stroke-width:3}
.camera-handle{pointer-events:all;cursor:grab}.camera-handle:active{cursor:grabbing}
.camera-handle-hit{fill:#79dfaf;fill-opacity:.08}
.camera-handle-dot{fill:#153b2b;stroke:#a2ffd3;stroke-width:3}
.camera-handle text{fill:#fff;stroke:#15221d;stroke-width:3px;paint-order:stroke;font:700 17px Inter,system-ui,sans-serif}
.camera-piece circle{fill:#000a;stroke:#fff9;stroke-width:1}
.camera-piece text{text-anchor:middle;font:14px serif;fill:#fff}
.camera-piece.black text{fill:#ffd37a}
.camera-side rect{stroke:#0008;stroke-width:1}
.camera-side text{text-anchor:middle;font:700 14px Inter,system-ui,sans-serif}
.camera-side.white rect{fill:#f7f4ea}.camera-side.white text{fill:#14202a}
.camera-side.black rect{fill:#14202a}.camera-side.black text{fill:#f7f4ea}
.camera-placeholder{position:absolute;inset:0;display:grid;place-items:center;color:#bac7ce;pointer-events:none}.camera-live .camera-placeholder{display:none}
#cameraStatus{min-height:3em;margin:12px 0 0;line-height:1.55;padding:12px;background:#193a32;color:#d8fbea;border-radius:8px}#cameraStatus.camera-error{background:#482c2a;color:#ffe3df}
#cameraBoard{display:grid;grid-template-columns:repeat(8,minmax(0,1fr)); grid-template-rows:repeat(8,minmax(0,1fr));width:min(100%,320px);margin:auto;aspect-ratio:1;overflow:hidden;border-radius:6px;font-family:serif}
.camera-square{min-width:0;min-height:0;position:relative;display:grid;place-items:center;font-size:clamp(22px,5vw,33px);line-height:1;color:#121b20}.camera-square.light{background:#dfe5d3}.camera-square.dark{background:#83a995}.camera-square small{position:absolute;font:10px system-ui;color:#152d22}.camera-square .rank{left:2px;top:1px}.camera-square .file{bottom:0;right:2px}
/* What the model sees while verifying or recording. */
.camera-square[data-state]:not([data-state=""])::after{content:"";position:absolute;inset:2px;border-radius:3px;pointer-events:none}
.camera-square[data-state="seen"]::after{box-shadow:inset 0 0 0 2px #3bbf84}
.camera-square[data-state="missing"]::after{box-shadow:inset 0 0 0 3px #e0635a;background:#e0635a40}
.camera-square[data-state="conflict"]::after,.camera-square[data-state="extra"]::after{box-shadow:inset 0 0 0 3px #f0a53a;background:#f0a53a40}
.camera-legend{display:flex;flex-wrap:wrap;gap:6px 14px;justify-content:center;margin:10px 0 0}
.camera-legend span::before{content:"";display:inline-block;width:11px;height:11px;margin-right:5px;border-radius:2px;vertical-align:-1px}
.camera-legend [data-state="seen"]::before{box-shadow:inset 0 0 0 2px #3bbf84}
.camera-legend [data-state="missing"]::before{background:#e0635a}
.camera-legend [data-state="conflict"]::before,.camera-legend [data-state="extra"]::before{background:#f0a53a}
.camera-moves{max-height:130px;overflow:auto;line-height:1.8;overflow-wrap:anywhere}.camera-done{width:100%;min-height:48px;margin-top:12px}.camera-finish{max-width:480px}.camera-finish label{display:flex;flex-direction:column;gap:10px}.camera-finish select{width:100%;min-height:44px}.camera-credit{margin-top:22px}.camera-credit a{color:inherit}
@media(max-width:760px){.camera-layout{grid-template-columns:1fr;gap:14px}.camera-capture,.camera-record{padding:12px}#cameraBoard{max-width:280px}#cameraVideoBox{max-height:min(48svh,460px)}[data-camera-step="3"] #cameraVideoBox.camera-tall{max-height:min(62svh,620px)}.camera-actions .btn{flex:1 1 42%}.camera-primary #cameraBegin{flex-basis:100%}}

.camera-review-progress{padding:12px;margin:12px 0;border:1px solid var(--ui-border,#3c5060);border-radius:10px}.camera-review-progress p{margin:0 0 8px;line-height:1.5;font-size:13px}.camera-review-progress progress{width:100%;accent-color:#79dfaf}.camera-review-progress button{margin-top:8px}.sidebar{scroll-margin-top:80px}

.camera-steps { display:flex; gap:8px; list-style:none; padding:0; margin:22px 0; flex-wrap:wrap; }
.camera-steps li { font-size:13px; color:var(--muted); border-bottom:2px solid var(--line); padding:9px 8px; }
.camera-steps [aria-current="step"] { color:var(--ink); border-color:var(--accent); font-weight:700; }
.camera-guide { margin:20px 0; max-width:720px; }
.camera-guide h2 { font-size:21px; margin-bottom:8px; }
.camera-guide p { font-size:15px; line-height:1.65; color:var(--muted); }
.camera-guide .btn { min-height:44px; }
#cameraCornerGuide svg { width:220px; height:160px; color:var(--ink); font:13px system-ui; }
#cameraCornerGuide circle { fill:var(--surface);stroke:var(--line);stroke-width:2; }
#cameraCornerGuide text { fill:var(--ink); }
#cameraCornerGuide [data-current="true"] circle { fill:var(--accent);stroke:var(--accent); }
#cameraCornerGuide [data-current="true"] text { fill:var(--ui-onaccent,#203015);font-weight:750; }
.camera-layout:not(:has(#cameraRecord:not([hidden]))) { grid-template-columns:1fr; max-width:720px; }
.camera-capture:not(:has(.camera-live)):not(:has(#cameraStart:not([hidden]))) { border:0;background:transparent;padding:0; }
@media(max-width:760px) {.camera-steps { margin:12px 0; }.camera-guide { margin:12px 0; }.camera-guide h2 { font-size:18px; }.camera-guide p { font-size:14px; margin:0 0 8px; }#cameraCornerGuide svg { width:150px; height:110px; font-size:11px; }}
@media(max-width:540px) {.camera-steps { gap:3px; }.camera-steps li { padding:8px 5px;font-size:12px; }}
/* Phone laid on its side (the camera screen frees the orientation lock, see
 * docs/2026-10-29-kamera-na-sirku.md): once the camera runs, the heading, steps
 * and guide give way, the preview takes the height on the left, zoom, buttons
 * and status sit on the right and the digital board follows below. */
@media (orientation:landscape) and (max-height:500px) {
  [data-camera-step="3"] .hub-heading,[data-camera-step="4"] .hub-heading,[data-camera-step="5"] .hub-heading,
  [data-camera-step="3"] .camera-modes,[data-camera-step="4"] .camera-modes,[data-camera-step="5"] .camera-modes,
  [data-camera-step="3"] .camera-steps,[data-camera-step="4"] .camera-steps,[data-camera-step="5"] .camera-steps,
  [data-camera-step="3"] .camera-guide,[data-camera-step="4"] .camera-guide,[data-camera-step="5"] .camera-guide,
  [data-camera-step="3"] #cameraPrivacy,[data-camera-step="4"] #cameraPrivacy,[data-camera-step="5"] #cameraPrivacy { display:none; }
  #hubPage[data-camera-step="3"],#hubPage[data-camera-step="4"],#hubPage[data-camera-step="5"] { max-width:none; }
  .camera-layout { grid-template-columns:1fr; gap:10px; max-width:none; }
  .camera-capture { padding:8px; }
  .camera-capture:has(.camera-live) { display:grid; grid-template-columns:auto minmax(170px,1fr); grid-template-rows:auto auto auto 1fr; gap:6px 10px; align-items:start; }
  .camera-capture:has(.camera-live) #cameraVideoBox { grid-row:1 / 5; grid-column:1; --camera-side:calc(100svh - var(--top-h,48px) - var(--bar-h,56px) - 46px); height:var(--camera-side); max-height:none; width:calc(var(--camera-side) * (var(--camera-aspect,16 / 9))); max-width:60vw; }
  .camera-capture:has(.camera-live) #cameraZoomRow { grid-column:2; margin:0; flex-wrap:wrap; }
  .camera-capture:has(.camera-live) .camera-primary { grid-column:2; margin:0; }
  .camera-capture:has(.camera-live) #cameraStatus { grid-column:2; margin:0; min-height:0; max-height:calc(100svh - var(--top-h,48px) - var(--bar-h,56px) - 150px); overflow:auto; padding:8px 10px; font-size:14px; }
  .camera-capture:has(.camera-live) #cameraPending { grid-column:2; margin:0; }
  .camera-capture:has(.camera-live) .camera-actions .btn { flex:1 1 42%; min-height:40px; }
  .camera-capture:has(.camera-live) .camera-primary #cameraBegin { flex-basis:100%; }
  #cameraBoard { max-width:240px; }
}
/* Move confirmed: the preview's frame blinks green. An inset ring, so nothing around it shifts. */
#cameraVideoBox::after{content:'';position:absolute;inset:0;border-radius:inherit;pointer-events:none;box-shadow:inset 0 0 0 6px #38d26b;opacity:0}
#cameraVideoBox.camera-confirmed::after{animation:camera-confirmed .7s ease-out}
@keyframes camera-confirmed{0%,40%{opacity:1}100%{opacity:0}}
.camera-sound-row{display:flex;gap:8px}.camera-sound-row select{flex:1;min-width:0}
