/* =============================================================================
     Assessment Styles
     Sections:
         1. Instruction Panel
         2. Linear Progress (status-step)
         3. Exercise Countdown
         4. Hand Progress Indicators
         5. Break Overlay
         6. Warmup Overlay
         7. Responsive Adjustments
         8. Capture backdrop (grid + white camera card)
     Conventions: Uses semantic design tokens (see design-tokens.css). Avoid raw hex neutrals.
     ============================================================================= */

/* 0. Webcam / Canvas sizing ------------------------------------------------- */
/* styles.css caps .videoView at height:400px with overflow:hidden on mobile,  */
/* and custom.css makes it a flex container with align-items:center. Together  */
/* they vertically center .webcam-con and clip anything that overflows — which */
/* cuts off the absolute-positioned instruction card at the top. Override both */
/* here so .videoView sizes itself to its content and never clips the overlay. */
/* #liveView.videoView (ID+class) beats the plain .videoView class rule in     */
/* styles.css at every breakpoint without needing a media query.               */
/* align-items:flex-start prevents the flex centering from pushing .webcam-con */
/* above the container top when the camera stream is taller than 4/3 (common  */
/* on mobile), which would clip the instruction card under #demos overflow:hid */
/* The camera box is reserved with a FLOOR, not a ratio. `aspect-ratio: 4/3` here
   sized the card to exactly 0.75 x its width and, because the container is
   overflow:visible, the .take-break-cta that wraps under the feed (section 8)
   hung 83px below the card's white background instead of sitting on it. A
   min-height floors the empty card without ever capping it, so the card grows
   for the control and for a stream taller than 4/3. 500px is the value
   custom.css already used for .videoView before this file zeroed it.
   NOT a ::before spacer with padding-top:75% (tried 2026-08-28, reverted): in a
   wrapping flex row that is a flex ITEM and claims its own line, which put a
   ~470px blank band above the feed on every assessment screen. */
#liveView.videoView {
    height: auto;
    min-height: 500px;
    overflow: visible;
    align-items: flex-start;
}

/* Before the camera starts, #webcamButton (the "Loading…" / "Enable Webcam"     */
/* pill) is the only visible child of the flex container. align-items:flex-start */
/* would pin it to the top of the reserved box; margin:auto centers it both axes */
/* within whatever height the container has, while keeping it in flow so the     */
/* container still sizes to it on mobile (min-height:0). It is hidden once       */
/* the stream starts, so this never affects the live webcam layout.              */
#liveView.videoView #webcamButton {
    margin: auto;
}

/* On mobile (portrait) the stream is taller than the desktop floor, so the      */
/* floor only creates dead space — measured at 390px wide: 500px of card around  */
/* a 370px feed. Let the container size naturally to the video instead.          */
@media (max-width: 768px) {
    #liveView.videoView {
        min-height: 0;
    }
}

/* The <video> element has no intrinsic CSS width, so without a constraint it  */
/* renders at the native camera resolution (640px+), making .webcam-con wider  */
/* than the viewport on mobile. Constrain it here so the container, the canvas */
/* overlay, and the absolute-positioned instruction row all share the same      */
/* rendered width as the camera feed.                                           */
/* .webcam-con is hidden until the video's `playing` event fires (script_2025) */
/* so there is no pre-stream gray placeholder to worry about sizing here.       */
#webcam {
    display: block;
    width: 100%;
    height: auto;
}

/* The canvas has inline style.width/height set by JS each frame, which        */
/* overrides CSS `width`/`height`. Use max-width/max-height instead — they      */
/* constrain the rendered size even against inline values.                      */
#output_canvas {
    max-width: 100%;
    max-height: 100%;
}

/* 1. Instruction Panel ------------------------------------------------------ */
.instruction-panel {
    background: var(--color-surface);
    padding: var(--space-5, 1.5rem);
    border-radius: var(--radius-md, 8px);
    border: 1px solid var(--color-border);
    margin: var(--space-4, 1rem) 0;
}

.instruction-panel p {
    margin-bottom: var(--space-2, 0.5rem);
    font-size: var(--font-size-base, 1.125rem);
}

.instruction-panel strong {
    color: var(--color-heading);
    font-weight: var(--font-weight-bold, 700);
}

/* 2. Linear Progress (status-step) ----------------------------------------- */
.status-step {
    width: 100%;
    height: 8px;
    background: var(--color-border-decorative);
    border-radius: var(--radius-sm, 4px);
    overflow: hidden;
    margin: var(--space-4, 1rem) 0;
}

.status-step .progress {
    height: 100%;
    background: var(--color-primary, #165C84);
    width: 0%;
    transition: width var(--transition-base, 150ms ease-in-out);
}

/* 3. Exercise Countdown ----------------------------------------------------- */
.exercise-countdown {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2, 0.5rem);
    font-size: var(--font-size-base, 1.125rem);
    font-weight: var(--font-weight-semibold, 600);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    padding: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
    border-radius: var(--radius-sm, 4px);
    color: var(--color-heading);
    margin-bottom: var(--space-3, 0.75rem);
    user-select: none;
}
.exercise-countdown .label {
    text-transform: uppercase;
    font-size: var(--font-size-xs, 0.75rem);
    letter-spacing: .5px;
    color: var(--color-text-muted);
}
.exercise-countdown .seconds {
    min-width: 3ch;
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.exercise-countdown.warning .seconds { color: var(--color-warning, #D97706); }
.exercise-countdown.final .seconds { color: var(--color-alert, #C0392B); }
.exercise-countdown.d-none { display: none !important; }

.status-step.complete .progress {
    background: var(--color-success, #219653);
}

/* 4. Hand Progress Indicators ---------------------------------------------- */
.hand-progress {
    display: flex;
    justify-content: center;
    gap: var(--space-4, 1rem);
    margin: var(--space-4, 1rem) 0;
}

.hand-progress-item {
    background: var(--color-surface);
    border: 2px solid var(--color-border);
    border-radius: var(--radius-md, 8px);
    padding: var(--space-4, 1rem) var(--space-5, 1.5rem);
    min-width: 120px;
    text-align: center;
    transition: background-color var(--transition-base, 150ms ease-in-out),
                border-color var(--transition-base, 150ms ease-in-out),
                color var(--transition-base, 150ms ease-in-out);
}

.hand-progress-item.active {
    background: var(--color-surface);
    border-color: var(--color-primary, #165C84);
    color: var(--color-primary, #165C84);
}

.hand-progress-item.completed {
    background: var(--color-surface);
    border-color: var(--color-success, #219653);
    color: var(--color-success, #219653);
}

.hand-progress-item h6 {
    margin: 0 0 var(--space-1, 0.25rem) 0;
    font-weight: var(--font-weight-bold, 700);
}

.hand-progress-item .status {
    font-size: var(--font-size-sm, 0.8rem);
    opacity: 0.8;
}

/* 5. Break Overlay ---------------------------------------------------------- */
.break-overlay {
    display: none;
    padding: var(--space-4, 1rem);
}

.break-overlay.warmup-overlay {
    position: absolute;
    inset: 4%;
    display: flex;
    align-items: center;
    justify-content: center;
    backdrop-filter: blur(3px);
    background: rgba(255, 255, 255, 0.9);
    z-index: 11;
    box-shadow: 0 4px 18px -4px rgba(0, 0, 0, 0.2);
}

.break-overlay .break-overlay-inner {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md, 8px);
    padding: var(--space-5, 1.5rem);
    width: 100%;
    max-width: 400px;
    box-shadow: var(--elevation-lg, 0 18px 40px -24px rgba(13,32,58,0.45));
    margin: 0 auto;
}

.break-overlay .break-overlay-inner h2 {
    font-size: var(--font-size-lg, 1.5rem);
    color: var(--color-heading);
}

.break-overlay .break-overlay-inner p {
    color: var(--color-text-body);
    font-size: var(--font-size-base, 1.125rem);
}

/* 6. Warmup Overlay --------------------------------------------------------- */
/* Utility: hidden state (JS toggles by removing/adding .is-hidden) */
.is-hidden { display:none !important; }
/* Component root */
.warmup-panel { background: var(--color-surface); border:1px solid var(--color-border); padding: var(--space-4,20px); border-radius: var(--radius-md,8px); font-size:.95rem; }
/* Overlay presentation */
.warmup-panel.warmup-overlay { position:absolute; inset: 4%; display:flex !important; align-items:center; justify-content:center; backdrop-filter:blur(3px); background:rgba(255,255,255,0.88); z-index:10; box-shadow:0 4px 18px -4px rgba(0,0,0,.18); }
@media (max-width: 575px) { .warmup-panel.warmup-overlay { inset:6% 4%; padding:12px; } }
/* Dark mode variant (shares token surface adjustments) */
.dark-mode .warmup-panel.warmup-overlay,
.dark-mode .break-overlay.warmup-overlay { background:rgba(20,22,28,0.82); }
/* Inner layout (fluid clamp for responsiveness) */
.warmup-panel.warmup-overlay .warmup-inner { width:100%; max-width:clamp(300px, 90vw, 520px); margin:0 auto; }
/* Checklist layout adjustments for overlay presentation */
.warmup-panel.warmup-overlay .warmup-checklist { justify-content:space-between; }
.warmup-panel.warmup-overlay .warmup-checklist li { flex:1 1 auto; text-align:center; padding-left:0; }
.warmup-panel.warmup-overlay .warmup-checklist li::before { position:static; margin:0 auto 4px; display:block; }
.warmup-panel.warmup-overlay .warmup-tip { text-align:center; }
/* Progress bar inside warmup */
.warmup-progress-bar { height:10px; background: var(--color-border-decorative); border-radius:6px; overflow:hidden; position:relative; }
.warmup-progress-fill { height:100%; width:0; background: var(--color-primary,#5B4FFF); transition: width .35s var(--transition-base,ease); }
.warmup-progress-label { font-size:.75rem; margin-top:4px; font-weight:600; letter-spacing:.5px; text-transform:uppercase; color: var(--color-text-muted); }
/* Progress wrapper (added for responsive centering / squish) */
.warmup-progress-wrapper { width:100%; max-width:520px; margin:0 auto; display:flex; flex-direction:column; align-items:stretch; }
.warmup-panel .warmup-inner { display:flex; flex-direction:column; align-items:center; gap:var(--space-3, .75rem); }
.warmup-panel .warmup-inner #warmupInstruction { text-align:center; line-height:1.25; max-width:38ch; }
.warmup-progress-bar { width:100%; flex:1 1 auto; }
.warmup-progress-label { text-align:center; }
/* Checklist */
.warmup-checklist { display:flex; gap:12px; flex-wrap:wrap; padding:0; }
.warmup-checklist li { list-style:none; position:relative; padding-left:18px; font-size:.75rem; text-transform:uppercase; letter-spacing:.5px; color: var(--color-text-muted); }
.warmup-checklist li::before { content:''; width:12px; height:12px; border-radius:50%; background: var(--color-border-decorative); position:absolute; left:0; top:2px; box-shadow:0 0 0 1px rgba(0,0,0,.05) inset; }
.warmup-checklist li.done { color: var(--color-heading); font-weight:600; }
.warmup-checklist li.done::before { background: var(--color-success,#2e8b57); }
.warmup-tip { min-height:1.1em; font-size:.75rem; margin-top:4px; }
/* Exit animation */
.warmup-panel.fading-out { opacity:0; transition: opacity .45s ease; pointer-events:none; }

/* 7. Responsive Adjustments ------------------------------------------------- */
/* Warmup-specific tweaks */

/* Tighter overlay in very small viewports */
@media (max-width: 480px) {
    .warmup-panel.warmup-overlay { inset:2% 3%; padding:10px; }
    .warmup-panel.warmup-overlay .warmup-inner { max-width:100%; padding-inline:4px; }
    .warmup-progress-wrapper { max-width:100%; }
    .warmup-panel .warmup-inner #warmupInstruction { max-width:100%; }
    .warmup-checklist { flex-direction:column; gap:8px; }
    .warmup-checklist li { text-align:left; }
}

/* Landscape small height: reduce vertical inset to avoid clipping */
@media (max-height: 480px) and (orientation: landscape) {
    .warmup-panel.warmup-overlay { inset:2% 4%; }
    .warmup-progress-bar { height:8px; }
}


.warmup-panel {
    padding: var(--space-4, 30px) var(--space-4, 20px) 40px var(--space-2, 30px);
    /* top                         right                  bottom  left */
}

/* 8. Tutorial Overlay Video ------------------------------------------------- */
.tutorial-overlay-video {
    display: none; /* shown by JS */
    flex-shrink: 0;
    width: 25%;
    aspect-ratio: 3 / 2; /* 3 wide × 2 tall */
    height: auto;
    border-radius: 6px;
    border: 2px solid rgba(255, 255, 255, 0.7);
    object-fit: cover;
    /* Square (360×360) clips are cropped top/bottom to fill this 3:2 box. Default to keeping
       the frame centered (correct for the hand/thumb ROM clips). The wrist JS always sets
       object-position inline per step (setTutorialVideo), overriding this with 'center top'
       or 'center bottom' for the pron/sup clips. */
    object-position: center;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
    pointer-events: none;
}

/* 9. ROM Header Stack + Instruction Card ------------------------------------ */
/* Column wrapper anchored to the top of .webcam-con; stacks the instruction   */
/* row above the quality banner so neither overlaps the other.                 */
.rom-header-stack {
    position: absolute;
    top: 8px; left: 8px; right: 8px;
    z-index: 20;
    display: flex;
    flex-direction: column;
    gap: 6px;
    pointer-events: none;
}

.rom-header-row {
    display: flex;
    align-items: stretch;
    gap: 8px;
}

.rom-substep-card {
    flex: 1;
    min-width: 0; /* allow flex shrink below content width */
    margin: 0;
    background: rgba(255, 255, 255, 0.82);
    /* No top/right/bottom border: it's a 1px grey line that the clipped progress fill can't  */
    /* cover, leaving a sliver above/below the green. Keep only the left accent.              */
    border: none;
    border-left: 4px solid var(--color-primary, #165C84);
    border-radius: var(--radius-md, 8px);
    padding: var(--space-3, 0.75rem) var(--space-4, 1rem);
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-1, 0.25rem);
    /* Hosts the progress fill (.rom-substep-progress-fill) so the whole card reads as one bar. */
    position: relative;
    overflow: hidden;
}

/* Green fill that grows left->right across the instruction card as the patient holds the    */
/* motion. Driven by the shared `.progress` width updates (assessment-core.js injects it).    */
/* Scoped under .rom-substep-card so it outranks Bootstrap's global `.progress` rules         */
/* (height/background/display), which would otherwise shrink it to a 1rem strip.              */
.rom-substep-card .rom-substep-progress-fill {
    position: absolute;
    top: 0; left: 0; bottom: 0;
    width: 0%;
    height: 100%;
    display: block;
    /* Match the card's left-edge accent (--color-primary) exactly so the fill and the side    */
    /* border read as one continuous green rather than two clashing shades.                    */
    background: var(--color-primary, #165C84);
    border-radius: 0;
    opacity: 1;
    z-index: 0;
    pointer-events: none;
    transition: width var(--transition-base, 150ms ease-in-out);
}

/* Keep text above the fill, each wrapped in its own opaque box so it stays legible over the   */
/* green (avoids green-on-green / tinted-chip-on-green clashes).                               */
.rom-substep-instruction,
.rom-substep-step-label {
    position: relative;
    z-index: 1;
}

.rom-substep-step-label {
    font-size: var(--font-size-xs, 0.75rem);
    font-weight: var(--font-weight-bold, 700);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-primary, #165C84);
    background: rgba(255, 255, 255, 0.95);
    padding: 2px var(--space-2, 0.5rem);
    border-radius: var(--radius-sm, 4px);
}

.rom-substep-instruction {
    font-size: var(--font-size-base, 1rem);
    font-weight: var(--font-weight-semibold, 600);
    color: var(--color-heading);
    margin: 0;
    line-height: 1.25;
    background: rgba(255, 255, 255, 0.95);
    padding: var(--space-1, 0.25rem) var(--space-2, 0.5rem);
    border-radius: var(--radius-sm, 4px);
}

/* Standalone linear bar is now mirrored inside the instruction card; hide it but keep it in   */
/* the DOM so the existing width-setting JS and the HOLD-cue progress check keep functioning.  */
.status-step.status-step--merged {
    display: none;
}

/* (.rom-substep-sub-label rules removed 2026-07-29 — the element left the capture views when  */
/* the instruction card became the progress bar, and the JS that wrote into it is gone too.)   */

/* Narrow portrait screens: tighten padding and scale fonts down so the       */
/* side-by-side card + video row stays compact.                               */
@media (max-width: 520px) {
    .tutorial-overlay-video { width: 28%; }

    .rom-substep-card {
        padding: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
    }

    .rom-substep-instruction { font-size: 0.875rem; }
    .rom-substep-step-label  { font-size: 0.68rem; }
}

/* 10. Calculating Score Overlay (full-viewport, shown after assessment ends) - */
.calculating-overlay {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    background: rgba(10, 20, 35, 0.82);
    z-index: 65;
    display: flex;
    align-items: center;
    justify-content: center;
}

.calculating-overlay-inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    text-align: center;
    color: #fff;
    padding: 2rem;
}

.calculating-spinner {
    width: 56px;
    height: 56px;
    border: 5px solid rgba(255, 255, 255, 0.2);
    border-top-color: #fff;
    border-radius: 50%;
    animation: spin 0.9s linear infinite;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

.calculating-title {
    font-size: 1.5rem;
    font-weight: 700;
    margin: 0;
    letter-spacing: 0.01em;
    color: #fff;
}

.calculating-sub {
    font-size: 0.95rem;
    color: rgba(255, 255, 255, 0.75);
    margin: 0;
}

/* 10b. HOLD cue (shown while holding a freeze-step pose) --------------------- */
/* Inserted just below the instruction row (card + tutorial video) by           */
/* assessment-core.js. Only toggled visible for steps whose tutorial clip       */
/* freezes on its final frame.                                                  */
.hold-indicator {
    /* Centered flex item sitting just below the instruction row / tutorial video. */
    align-self: center;
    margin-top: 6px;
    z-index: 55;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0.4rem 1.6rem;
    background: var(--color-primary, #165C84);
    color: #fff;
    font-size: 1.5rem;
    font-weight: 800;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    border-radius: 999px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
    pointer-events: none;
}

@media (max-width: 520px) {
    .hold-indicator { font-size: 1.15rem; padding: 0.35rem 1.2rem; }
}

/* 11. Step Completion / Hand-Switch Overlay --------------------------------- */
.step-completion-overlay {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    background: rgba(0, 0, 0, 0.60);
    z-index: 60;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 0.5rem;
    opacity: 1;
    transition: opacity 0.35s ease;
    pointer-events: none;
}

.step-completion-overlay.fading-out {
    opacity: 0;
}

.step-completion-title {
    color: #fff;
    font-size: 2rem;
    font-weight: 700;
    text-align: center;
    text-shadow: 0 2px 12px rgba(0, 0, 0, 0.55);
    animation: sco-pop 0.25s ease both;
}

.step-completion-sub {
    color: rgba(255, 255, 255, 0.85);
    font-size: 1rem;
    font-weight: 500;
    text-align: center;
    text-shadow: 0 1px 6px rgba(0, 0, 0, 0.45);
    animation: sco-pop 0.3s 0.05s ease both;
}

@keyframes sco-pop {
    from { transform: scale(0.82); opacity: 0; }
    to   { transform: scale(1);    opacity: 1; }
}

/* 12. Hand Quality / Framing Banner ----------------------------------------- */
/* Shown inside .webcam-con below the instruction row (flex item in               */
/* .rom-header-stack). Centered horizontally via align-self.                      */
.hand-quality-banner {
    align-self: center;
    display: flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.35rem 0.85rem 0.35rem 0.65rem;
    background: rgba(200, 80, 20, 0.88);
    border-radius: 999px;
    color: #fff;
    font-size: 0.82rem;
    font-weight: 600;
    white-space: nowrap;
    pointer-events: none;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
    animation: hqb-appear 0.18s ease both;
}

.hand-quality-icon {
    font-size: 0.9rem;
    line-height: 1;
    flex-shrink: 0;
}

.hand-quality-text {
    line-height: 1.2;
}

@keyframes hqb-appear {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* 13. Voiceover toggle (mirrors skeleton-toggle, stacked above it) ----------- */
.voiceover-toggle {
    position: absolute;
    bottom: calc(var(--space-3, 0.75rem) + 28px);
    right: var(--space-3, 0.75rem);
    z-index: 50;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
}

.voiceover-toggle input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.voiceover-toggle input:checked ~ .skeleton-toggle-track {
    background: var(--color-primary);
    border-color: var(--color-primary);
}

.voiceover-toggle input:checked ~ .skeleton-toggle-track::after {
    transform: translateX(16px);
}

/* 13. Skeleton overlay toggle ----------------------------------------------- */
.skeleton-toggle {
    position: absolute;
    bottom: var(--space-3, 0.75rem);
    right: var(--space-3, 0.75rem);
    z-index: 50;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
}

.skeleton-toggle input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.skeleton-toggle-track {
    position: relative;
    width: 36px;
    height: 20px;
    background: rgba(255,255,255,0.25);
    border: 1px solid rgba(255,255,255,0.45);
    border-radius: var(--radius-round);
    transition: background 0.2s ease, border-color 0.2s ease;
    flex-shrink: 0;
    backdrop-filter: blur(4px);
}

.skeleton-toggle-track::after {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 14px;
    height: 14px;
    background: #fff;
    border-radius: 50%;
    transition: transform 0.2s ease;
    box-shadow: 0 1px 3px rgba(0,0,0,0.3);
}

.skeleton-toggle input:checked ~ .skeleton-toggle-track {
    background: var(--color-primary);
    border-color: var(--color-primary);
}

.skeleton-toggle input:checked ~ .skeleton-toggle-track::after {
    transform: translateX(16px);
}

.skeleton-toggle-icon {
    font-size: 0.85rem;
    color: rgba(255,255,255,0.75);
    margin-right: var(--space-2, 0.5rem);
    pointer-events: none;
}

/* =============================================================================
   Section 14: Dexterity pre-exercise countdown card
   ============================================================================= */
.dex-countdown-overlay {
    position: absolute;
    bottom: var(--space-10, 2.5rem);
    left: 50%;
    transform: translateX(-50%);
    z-index: 45;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
}

.dex-countdown-card {
    background: rgba(255, 255, 255, 0.92);
    border: 1px solid var(--color-border, #dde3ea);
    border-left: 4px solid var(--color-primary, #165C84);
    border-radius: var(--radius-md, 8px);
    padding: 1.1rem 1.75rem 1.25rem;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    pointer-events: auto;
    min-width: 160px;
}

.dex-countdown-label {
    font-size: 0.8rem;
    font-weight: var(--font-weight-bold, 700);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-primary, #165C84);
    margin: 0;
}

/* Slot holds the button and number at a fixed size so the card never reflows */
.dex-countdown-slot {
    position: relative;
    width: 100%;
    height: 3rem;
}

.dex-countdown-number {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    color: var(--color-primary, #165C84);
    font-size: 2.6rem;
    font-weight: 700;
    line-height: 1;
    visibility: hidden;
}

#dex-start-btn {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    white-space: nowrap;
    padding: 0.5rem 1.4rem;
    background: var(--color-primary, #165C84);
    color: #fff;
    border: none;
    border-radius: 999px;
    font-size: 0.9rem;
    font-weight: 700;
    cursor: pointer;
    transition: background 0.15s;
    visibility: visible;
}

#dex-start-btn:hover {
    background: color-mix(in srgb, var(--color-primary, #165C84) 85%, black);
}

/* =============================================================================
   8. Capture backdrop — grid + white camera card
   The look the Research Center's capture pages have carried since the 2026-07-17
   client-branding pass, lifted out of their inline <style> blocks so every capture
   screen shares one definition. Every page that loads this stylesheet is a capture
   screen (the ROM, dexterity, thumb and wrist assessments, plus the four research
   capture pages), so it is applied here rather than behind a page class.

   Values are carried over unchanged from FingerRomCapture/Index.cshtml, which is
   now the consumer of this rather than the owner of it.
   ============================================================================= */

/* Soft green-to-slate gradient, pinned to the viewport. An attachment that
   scrolls with the document leaves an uncovered band once the page scrolls. */
body {
    background: linear-gradient(160deg,
        hsl(150, 30%, 98%) 0%,
        hsl(150, 20%, 96%) 45%,
        hsl(230, 22%, 96%) 100%);
    background-attachment: fixed;
}

/* Uniform 48px grid. The landing hero's radial mask is deliberately dropped: on a
   fixed full-viewport layer its heavy edges render as a stationary band that the
   content appears to scroll "under". */
body::before {
    content: '';
    position: fixed;
    inset: 0;
    pointer-events: none;
    background-image:
        linear-gradient(hsla(150, 25%, 45%, 0.16) 1px, transparent 1px),
        linear-gradient(90deg, hsla(150, 25%, 45%, 0.16) 1px, transparent 1px);
    background-size: 48px 48px;
}

/* custom.css paints .content solid white, which would blank the backdrop for the
   full content height — the grid would then only show past the fold. The stacking
   level keeps the grid behind the text rather than over it. */
main.content {
    position: relative;
    z-index: 1;
    background: transparent;
}

/* The camera sits on a white card on the backdrop, the same treatment as the
   research console's .frr-card and the capture pages' .cap-card. The title above
   it floats directly on the grid (client feedback, 2026-07-17). */
#liveView.videoView {
    background: var(--color-page-bg, #fff);
    border: 1px solid var(--color-border-decorative, #dee2e6);
    border-radius: var(--radius-md, 8px);
    padding: var(--space-3, 0.75rem);
    box-shadow: var(--shadow-sm, 0 1px 2px rgba(20, 26, 51, 0.06));
}

/* The video and its canvas overlay round with the card so the feed's corners do
   not sit square inside it. */
#liveView.videoView .webcam-con,
#liveView.videoView #webcam,
#liveView.videoView .output_canvas {
    border-radius: calc(var(--radius-md, 8px) - 2px);
}

#liveView.videoView .webcam-con {
    overflow: hidden;
}

/* The break control now sits INSIDE the camera card, under the feed. #liveView is a
   flex row, so the control is given a full-width basis to wrap onto its own line
   beneath .webcam-con rather than beside it. */
#liveView.videoView {
    flex-wrap: wrap;
}

/* The control is anchored to the BOTTOM of the card, not to the bottom of the feed.
   Sitting directly under .webcam-con made it move with every change in feed height —
   it rode near the card's top edge in the ~500px empty card before the stream starts,
   then dropped ~440px once the feed appeared, and shifted again between assessments
   whose camera aspect differs. #liveView wraps, so with align-content:stretch (the
   default) the last flex line's bottom edge is the card's content-box bottom;
   align-self:flex-end places the control there in every state. When the feed is
   taller than the min-height floor there is no free space to absorb, so the control
   still lands just below the feed — the position it already had in production. */
#liveView.videoView .take-break-cta {
    flex: 1 1 100%;
    margin-top: var(--space-3, 0.75rem);
    text-align: center;
    align-self: flex-end;
}

/* The per-hand progress indicators ("Left Hand — Waiting") are hidden rather than
   deleted, because they are not only UI: assessment-core.js derives the tutorial
   clip's visibility, the HOLD badge and the clip's left/right mirroring from
   `.hand-progress-item.active` and the status text on these elements. Removing the
   markup would silently stop the tutorial clip and the HOLD cue from ever appearing.
   Making the state explicit and then deleting them is follow-up work — TRK-001 item 88.
   The research capture pages do not render them, so this is inert there. */
.hand-progress {
    display: none;
}
