/* Doorway Up to 10 — activity styles.
   1em = 1/50th of activity width (set by doorway.js onResize).
   All sizing in em; no px except borders.

   Flash stage 800×600 px, 1em = 16 px.
   y-position formula: css_top_em = flash_y_px * 0.75 / 16.
   Key Flash measurements:
     - Object area:    y=0–539 px  → occupies top flex region
     - Question text:  y=515.8 px  → 24.18em (visually just above number line)
     - Number line:    y=539 px    → 25.27em, h=81.8 px → 3.83em
     - Object size:    72.05 px    → 4.50em
   Colors (from ffdec SVG export):
     - Stage/object area background:  #ffffff
     - Grid lines (Layout 1/2):       #cccccc
     - Number line slot — up:         #86e25f  border #ff6600 (bright green / orange)
     - Number line slot — hover:      #6dcc4a  (darker green)
     - Number line slot — correct:    #86e25f  border #00aa1a (same fill, green border highlight)
     - Scan highlight border:         #ff6600  (orange, as in Flash sprite5/shape6)
*/

/* --- Welcome screen picture groups ---
   Three side-by-side groups of Flash picture objects, mirroring the original
   Flash welcome screen which showed three groups of counted objects.
   Hosted inside `.welcome_image` so the shared flow-mode chrome treats them
   as the standard welcome illustration block (centred, flow-bounded). */
.utt-welcome-groups {
    display: flex;
    flex-direction: row;
    justify-content: space-around;
    align-items: center;
    width: 100%;
    max-width: 36em;
    max-height: 18em;
    margin: 0 auto;
    gap: 0;
}

/* Each group is a fixed-size relative container holding 4–5 objects.
   Flash object size ~72px → 4.5em; each group ~170px wide × 200px tall →
   scaled to 450px height: ≈ 12.75em wide × 15em tall. */
.utt-welcome-group {
    position: relative;
    width: 13em;
    height: 13em;
    flex-shrink: 0;
}

/* Each object wrapper: absolutely positioned within the group.
   Flash object size: 72px → 4.5em */
.utt-wobj {
    position: absolute;
    width: 4em;
    height: 4em;
}

.utt-wobj img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

/* Flash badge style: small circle with number at bottom-left of object.
   Flash uses outlined circles (white fill, thin black border). */
.utt-wbadge {
    position: absolute;
    bottom: -0.1em;
    left: -0.1em;
    width: 1.3em;
    height: 1.3em;
    background: white;
    border: 0.12em solid var(--dw-color-text-strong);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.75em;
    font-weight: bold;
    color: #111;
    line-height: 1;
}

/* --- Object positions within each group ---
   Object size = 4em. Positions approximate the Flash triangular/scattered layout.
   Football group: 1 top-center, 2 in middle row, 2 in bottom row (triangle).
   Apple group: 2×2 grid + 1 bottom-center.
   Sun group: scattered (1 top-left, 1 top-right, 1 mid, 1 bot-left). */

/* Football group (triangle: apex at top, widening downward).
   Row layout: each row holds two 4em balls with a visible gap between them.
   Bottom row spans the full 13em (left:0 + left:5em → 1em gap, occupies 0–9em).
   Mid row is slightly inset (left:0.5em + left:4.5em → 0.5em gap, occupies 0.5–8.5em).
   Top apex sits centred above the mid pair. */
.utt-welcome-group:nth-child(1) .utt-wobj-top-right  { top: 0;      left: 2.5em; }
.utt-welcome-group:nth-child(1) .utt-wobj-mid-left   { top: 3.5em;  left: 0.5em; }
.utt-welcome-group:nth-child(1) .utt-wobj-mid-right  { top: 3.5em;  left: 5em;   }
.utt-welcome-group:nth-child(1) .utt-wobj-bot-left   { top: 7em;    left: 0;     }
.utt-welcome-group:nth-child(1) .utt-wobj-bot-right  { top: 7em;    left: 5em;   }

/* Apple group (2×2 grid + 1 centred below) */
.utt-welcome-group:nth-child(2) .utt-wobj-top-left   { top: 0;      left: 0.5em; }
.utt-welcome-group:nth-child(2) .utt-wobj-top-right  { top: 0;      left: 5em;   }
.utt-welcome-group:nth-child(2) .utt-wobj-mid-left   { top: 4em;    left: 0.5em; }
.utt-welcome-group:nth-child(2) .utt-wobj-mid-right  { top: 4em;    left: 5em;   }
.utt-welcome-group:nth-child(2) .utt-wobj-bot-center { top: 8em;    left: 2.75em; }

/* Sun group (scattered diagonal pattern) */
.utt-welcome-group:nth-child(3) .utt-wobj-top-left   { top: 0;      left: 0;     }
.utt-welcome-group:nth-child(3) .utt-wobj-top-right  { top: 0.5em;  left: 6em;   }
.utt-welcome-group:nth-child(3) .utt-wobj-mid-center { top: 3.5em;  left: 3em;   }
.utt-welcome-group:nth-child(3) .utt-wobj-bot-left   { top: 7em;    left: 0.5em; }

/* --- Screen layout --- */

/* Flex-column skeleton comes from .dw-activity-screen in shared/doorway.css. */
.utt-screen {
    overflow-y: auto;
    padding: 1.5em var(--dw-space-loose) var(--dw-space-loose);
    gap: var(--dw-space-default);
}

.utt-screen-title {
    font-size: 2em;
    margin: 0 0 var(--dw-space-default) 0;
    text-align: center;
}

/* --- Activity screen layout --- */

/* Flash stage: object area fills the top ~90 % of the stage height;
   number-line strip is at the bottom and itself contains the question text
   and "Try again." flag (both children of `_root.numberLine` in Flash).
   The activity layout is a simple top-to-bottom flex column:
     - object area  (top, flex: 1)
     - number line wrapper (bottom, fixed height, contains its own labels row) */
.utt-activity-layout {
    display: flex;
    flex-direction: column;
    height: 100%;
    gap: 0;
    position: relative;
}

/* --- Question text ---

   Flash: _root.numberLine.questionText is a child of the numberLine clip and
   sits inside the strip's white area, just above the row of slot buttons.
   In HTML5 the <p> lives inside `.utt-number-line-labels` (the top row of
   `#uttNumberLineWrapper`) so it shows/hides with the strip and occupies the
   same "above the slots" zone as Flash. */
.utt-question-text {
    flex: 1;
    font-size: 1.3em;
    font-weight: bold;
    text-align: center;
    margin: 0;
    padding: 0;
    color: var(--dw-color-text-primary);
    min-height: 1.2em;
    line-height: 1.2;
}

/* --- Object display area --- */

/* Object area sizing.
   Flash: 2-column × 5-row grid centred horizontally in the object area.
   The HTML5 stage is shorter than Flash (450 px vs 600 px), so the grid is
   scaled to fit the available object-area height. Cell size is set via
   --utt-cell-w / --utt-cell-h custom properties so the JS object positioning
   reads the same values (see _computePositions). --utt-obj-size is the
   displayed object size; in grid mode it's shrunk so objects sit inside
   their cell (Flash uses ~72%-of-cell). Layout 3 ("Random") ignores the
   2×5 cell metrics and instead scatters objects across an invisible 8×4
   jittered grid inset 2em from every edge — see scatterPositions in
   up-to-10-render.js. */
.utt-object-area {
    position: relative;
    flex: 1;
    background-color: #ffffff;
    overflow: hidden;
    min-height: 12em;
    --utt-cell-w: 3.6em;
    --utt-cell-h: 3.6em;
    --utt-grid-cols: 2;
    --utt-grid-rows: 5;
    /* Rendered object size. Layouts 1/2 use this as the grid-cell object
       footprint (see _slotPosition); layout 3 uses it to centre each
       scattered object on its jittered anchor. */
    --utt-obj-size: 2.6em;
    /* Vertical band at the bottom of the object area that the number-line
       wrapper covers once it slides in. Layout-3 scatter excludes this
       band from its usable region so objects never sit in a slice that
       will be occluded when the strip reveals. Value covers the wrapper's
       borders + labels row (1.6em) + slots row (2.2em) + inner paddings
       with a small margin for the shared spacing tokens. */
    --utt-scatter-bottom-reserve: 5.5em;
}

.utt-object-area.utt-grid-enabled::before {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: calc(var(--utt-cell-w) * var(--utt-grid-cols));
    height: calc(var(--utt-cell-h) * var(--utt-grid-rows));
    background-image:
        linear-gradient(to right, var(--dw-color-border-light) 1px, transparent 1px),
        linear-gradient(to bottom, var(--dw-color-border-light) 1px, transparent 1px);
    background-size: var(--utt-cell-w) var(--utt-cell-h);
    background-repeat: repeat;
    border: 1px solid var(--dw-color-border-light);
    box-sizing: content-box;
    pointer-events: none;
}

/* Each object is an absolutely positioned img within the object area.
   Flash object size: 72.05 px → 4.50 em at 1em = 16 px.  In grid mode the
   size is reduced via the --utt-obj-size custom property so objects sit
   inside their grid cell with breathing room (matching the Flash ratio).
   Positioning is set dynamically by JS using left/top. */
.utt-object {
    position: absolute;
    width: var(--utt-obj-size, 4.5em);
    height: var(--utt-obj-size, 4.5em);
    cursor: pointer;
    /* Suppress native <button> chrome — the element is a button for
       tab-keyboard activation parity with switch scanning, but visually
       it's just the object image. */
    background: none;
    border: none;
    padding: 0;
    margin: 0;
    font: inherit;
    color: inherit;
}

.utt-object img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* Object fade-in (information-carrying — each fade IS the user seeing the next
   object appear, which drives the implicit count).  Duration is driven by the
   --fade-duration CSS custom property set on the element from JS (mapped from
   the user-selected Speed of Presentation option). */
.utt-object {
    transition: opacity var(--fade-duration, 0.7s) ease-out;
}

/* Objects start transparent; .utt-object-hidden → no class transitions opacity */
.utt-object.utt-object-hidden {
    opacity: 0;
}

/* Wrong-order penalty dim: brief CSS animation that auto-restores. */
.utt-object.utt-object-dim {
    animation: utt-object-dim 0.6s ease-out forwards;
}

@keyframes utt-object-dim {
    0%   { opacity: 0.6; }
    80%  { opacity: 0.6; }
    100% { opacity: 1; }
}

/* Counter badge: numbered circle sitting at the bottom-left of the
   object's grid cell. A little over half the object's footprint, with a
   white fill, thin black border, and black numeral — matches the Flash
   counter sprite (white-circle-with-dark-border outline + black numeral)
   and the welcome screen badge styling. The badge's left/top are written
   by JS to anchor its top-left to the cell's bottom-left corner; width/
   height stay fixed here so the badge stays proportional in both grid-on
   and grid-off layouts. */
.utt-counter-badge {
    position: absolute;
    /* Badge diameter = 1.5em × the previous 0.925em font-size shrink,
       expressed directly in parent em so the badge's own font-size stays
       inherited (1em of parent). The digit is scaled by an inner span
       instead: setting font-size on the badge itself would shrink the
       `em` unit used in the badge's inline top/left calc, throwing the
       badge off the object's bottom-left corner in Random layout. */
    width: 1.3875em;
    height: 1.3875em;
    background: #fff;
    color: #000;
    border: 0.12em solid #000;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    z-index: 2;
    box-sizing: border-box;
    /* Pull up by the badge's own height so its bottom sits flush with the
       cell's bottom edge (which JS positions via top). */
    transform: translateY(-100%);
    animation: utt-badge-pop 0.25s ease-out;
}

.utt-counter-badge-text {
    font-size: 0.925em;
    line-height: 1;
    font-weight: bold;
}

/* Counter badge appearance: small scale+fade pop-in.  Decorative — the badge
   number itself is the information; the pop just draws attention. The base
   `transform: translateY(-100%)` (used to flush the badge's bottom to the
   cell's bottom edge) must be reapplied in each keyframe — a `transform`
   value replaces the rule's static transform for the duration of the
   animation. */
@keyframes utt-badge-pop {
    from { transform: translateY(-100%) scale(0.4); opacity: 0; }
    to   { transform: translateY(-100%) scale(1);   opacity: 1; }
}

/* --- Number line wrapper ---
   Flash: numberLine at y=539 px (25.27 em), full width (793 px = 49.6 em),
   height = 81.8 px * 0.75 / 16 = 3.83 em.
   The wrapper is the bottom strip of the activity screen. */

.utt-number-line-wrapper {
    background: #ffffff;
    border-top: 2px solid var(--dw-color-border-light);
    padding: var(--dw-space-narrow) var(--dw-space-snug);
    box-sizing: border-box;
}

/* Override hidden_panel for number line — it uses its own show/hide */
.utt-number-line-wrapper.hidden_panel {
    display: none;
}

/* Number line slide-in (decorative — matches Flash tween of _y from 625→539).
   The class is added when the wrapper becomes visible and removed on
   `animationend` so the slide can be re-triggered on the next question. */
.utt-number-line-wrapper.utt-number-line-entering {
    animation: utt-number-line-slide 0.6s ease-out;
}

@keyframes utt-number-line-slide {
    from { transform: translateY(100%); }
    to   { transform: translateY(0);    }
}

/* Top row of the strip — holds the question text (centred, left-flex) and the
   "Try again." flag (right-flex). When `.utt-try-again` is hidden_panel the
   question text expands to fill the row, which keeps it visually centred. */
.utt-number-line-labels {
    display: flex;
    align-items: baseline;
    gap: var(--dw-space-default);
    padding: 0 var(--dw-space-snug) var(--dw-space-tight);
    min-height: 1.4em;
}

.utt-number-line {
    display: flex;
    gap: 0;
    justify-content: center;
    flex-wrap: nowrap;
}

/* Number line slots.
   Per-product spec (divergence from Flash, agreed): grey fill with thin black
   border so the strip reads as a neutral number line rather than the bright
   Flash green/orange tiles. Text is sized so the digit reads comfortably while
   slot height stays trimmed enough that the wrapper still fits in the 450 px
   HTML5 stage with no scroll.
   Slots are square-cornered and touch each other to match the Flash strip. */
.utt-line-slot {
    font-size: var(--dw-font-size-heading);
    font-weight: bold;
    flex: 1;
    min-width: 0;
    height: 2.2em;
    border: 0.1em solid #000;
    border-radius: 0;
    background: #e0e0e0;
    cursor: pointer;
    text-align: center;
    color: #111;
    padding: 0;
}

/* Silent lock: after a correct answer, non-winning slots are `disabled`
   so they no longer accept hover / focus / click. UA styling would grey
   them out — override to keep the strip visually unchanged so only the
   green pulse on the correct slot draws the eye. */
.utt-line-slot:disabled {
    background: #e0e0e0;
    color: #111;
    cursor: default;
    opacity: 1;
}

/* Avoid doubled borders between adjacent touching slots */
.utt-line-slot + .utt-line-slot {
    border-left-width: 0;
}

/* Hover/focus state: slightly darker grey so the change is still perceptible.
   Outline (rather than box-shadow) keeps the gold focus ring visible even
   though adjacent slots touch and share borders. */
.utt-line-slot:focus-visible {
    background: #c8c8c8;
    outline: 0.3em solid gold;
    outline-offset: -0.15em;
    position: relative;
    z-index: 1;
}
@media (hover: hover) {
    .utt-line-slot:hover {
        background: #c8c8c8;
        outline: 0.3em solid gold;
        outline-offset: -0.15em;
        position: relative;
        z-index: 1;
    }
}

/* Correct-answer state: swap the border to bright green #00aa1a — a clear
   colour-change cue distinct from the resting black border — and run a short
   scale-pulse keyframe. Information is still communicated when motion is
   reduced (border colour change plus audio chain). */
.utt-line-slot.utt-slot-correct {
    background: #e0e0e0;
    border-color: #00aa1a;
    color: #005500;
    animation: utt-slot-correct-pulse 0.5s ease-out;
    /* Restore full border so the green outline reads cleanly even though
       adjacent slots share an edge (border-left:0 above). Match the resting
       border thickness (0.1em). */
    border-left-width: 0.1em;
    position: relative;
    z-index: 1;
}

@keyframes utt-slot-correct-pulse {
    0%   { transform: scale(1);   box-shadow: 0 0 0 0 rgba(0, 170, 26, 0.6); }
    50%  { transform: scale(1.1); box-shadow: 0 0 0 0.4em rgba(0, 170, 26, 0.0); }
    100% { transform: scale(1);   box-shadow: 0 0 0 0 rgba(0, 170, 26, 0.0); }
}

/* "Try again." flag — Flash places this on the right of the strip, above the
   slots (see `_root.numberLine.tryagainText`). The labels flex row already
   right-aligns it (question text takes flex:1, leaving try-again to the right). */
.utt-try-again {
    flex: 0 0 auto;
    font-size: var(--dw-font-size-subheading);
    text-align: right;
    color: var(--dw-color-feedback-wrong);
    margin: 0;
    padding: 0;
    line-height: 1.2;
}

.utt-try-again.hidden_panel {
    display: none;
}

/* --- Options fieldsets ---
   Outer section fieldsets (options_group) keep default browser border to match Flash.
   Inner control fieldsets (wrapping radio/checkbox pairs inside the options table)
   must have no visible border — Flash shows no bounding box around these inner groups. */
.user_options fieldset fieldset {
    border: none;
    padding: 0;
    margin: 0;
}

/* --- Number toggle area (options) ---
   Uses the canonical shared dw-toggle-grid / dw-toggle-btn pattern; only the
   row-layout shim (.utt-numbers-row .utt-number-toggles below) is local. */

/* Numbers fieldset: number-toggle row sits left, persistent help/warning text
   sits inline to the right (matches Flash spec). The help text is shown by
   default in neutral grey; when validation fails on submit, JS adds the
   `.utt-warning-error` class to switch to the red error styling. */
.utt-numbers-row {
    display: flex;
    align-items: center;
    gap: var(--dw-space-loose);
    flex-wrap: wrap;
}

.utt-numbers-row .utt-number-toggles {
    flex: 1 1 auto;
    min-width: 0;
}

.utt-warning {
    flex: 0 1 auto;
    font-size: 0.95em;
    color: var(--dw-color-text-muted);
    margin: 0;
    max-width: 12em;
    line-height: 1.2;
}

.utt-warning.utt-warning-error {
    color: var(--dw-color-feedback-wrong);
    font-weight: bold;
    font-size: 1.1em;
}

/* --- Layout fieldset: three pictogram radios + inline checkbox row -------- */

.utt-layout-radios {
    display: flex;
    flex-direction: row;
    justify-content: space-around;
    align-items: stretch;
    gap: var(--dw-space-default);
    flex-wrap: wrap;
}

.utt-layout-radio {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    gap: var(--dw-space-snug);
    padding: var(--dw-space-narrow) var(--dw-space-comfy);
    text-align: center;
    min-width: 7em;
}

.utt-layout-pictogram {
    display: block;
    width: 5em;
    height: 4em;
    line-height: 0;
}

.utt-layout-pictogram svg {
    width: 100%;
    height: 100%;
    display: block;
}

.utt-layout-text {
    font-size: 0.95em;
    line-height: 1.1;
    display: block;
}

/* Inline checkbox row sits under the pictograms, inside the same fieldset. */
.utt-layout-checks {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--dw-space-narrow) 1.5em;
    margin-top: var(--dw-space-comfy);
}

.utt-layout-check {
    display: inline-flex;
    align-items: center;
    gap: var(--dw-space-snug);
}

/* The third checkbox carries a sub-line note ("disabled in scanning mode"),
   so it stacks the note below the checkbox row. */
.utt-layout-check-with-note {
    flex-wrap: wrap;
    column-gap: var(--dw-space-snug);
    row-gap: 0;
}

.utt-check-note {
    flex: 1 0 100%;
    font-size: 0.8em;
    color: var(--dw-color-text-muted);
    margin-left: 1.6em;
    line-height: 1.1;
}

/* Disabled-state visual for the layout checkboxes (grid + count-order are
   disabled in Random layout; force-counters is disabled in scanning mode).
   The shared dw-check styles don't include a :disabled rule, so mirror the
   .dw-toggle-grid pattern (opacity + not-allowed cursor) on both the label
   and its checkbox-square pseudo-element. The associated note text is
   greyed in the same proportion. */
.utt-layout-check input.dw-check-input:disabled + .dw-check-label,
.utt-layout-check input.dw-check-input:disabled + .dw-check-label::before {
    opacity: 0.5;
    cursor: not-allowed;
}

.utt-layout-check-with-note input.dw-check-input:disabled ~ .utt-check-note {
    opacity: 0.5;
}

/* --- Number of Questions + Speed of Presentation: side-by-side row ------- */

.utt-questions-speed-row {
    display: flex;
    flex-direction: row;
    gap: var(--dw-space-loose);
    align-items: stretch;
}

.utt-questions-speed-row > fieldset {
    flex: 1 1 0;
    min-width: 0;
}

/* --- Results screen ---
   Flash sprite_290 layout (see screenshots/up-to-10/04_results_flash.png):
     - Off-white "paper" panel with a folded top-right corner
     - Title "Doorway Up to 10 - Results" at top-left, Print button top-right
     - Name: / Date: field pair inside the paper, at the top
     - Two side-by-side pairs of ("Up to...", "Tries") columns — 10 rows per
       pair, 20 entries total for maxQuestions=20
     - Vertical column of stars pinned to the right edge of the paper
     - "Total" summary row at the bottom
   Sizing is in em so the whole paper scales with the aspect-locked stage.
*/

/* Top row: title on the left, Print button on the right. */
.utt-results-title-bar {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 0.8em;
    margin: 0 0 var(--dw-space-snug) 0;
    flex: 0 0 auto;
}

.utt-screen-title {
    font-size: var(--dw-font-size-subheading);
    margin: 0;
    text-align: left;
    flex: 1 1 auto;
}

.utt-print-btn {
    flex: 0 0 auto;
}

/* Paper panel — off-white gradient with subtle texture and a folded corner
   drawn via a clip-path notch overlaid with a triangular pseudo-element.
   Stars are painted as a background-image repeated vertically down the
   right edge; the star SVG lives in pictures/star.svg. Reserved
   right-padding = 2.6em so text never runs under the star column. */
.utt-results-paper {
    position: relative;
    background:
        /* stars column, right edge — first star sits under the folded
           corner, so start the column ~1.8em down. */
        url("pictures/star.svg") right 0.4em top 1.8em / 1.5em 1.5em repeat-y,
        /* main paper gradient */
        linear-gradient(180deg, #fefdf6 0%, #faf7ea 100%);
    background-color: #fefdf6;
    border: 1px solid #000;
    border-radius: 0.15em;
    padding: 0.35em 2.6em 0.35em 0.8em;
    /* Folded corner: cut the top-right with a diagonal clip so the paper
       ends in a small triangle notch. */
    clip-path: polygon(
        0 0,
        calc(100% - 1.2em) 0,
        100% 1.2em,
        100% 100%,
        0 100%
    );
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    gap: 0.15em;
    min-height: 0;
}

/* The folded-corner triangle (fills the notch left by clip-path with a
   lighter shade so it reads as the underside of a bent page corner). */
.utt-results-paper::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    width: 1.2em;
    height: 1.2em;
    background: #e6e2d4;
    clip-path: polygon(100% 0, 0 100%, 100% 100%);
    border-left: 1px solid var(--dw-color-border-muted);
    border-bottom: 1px solid var(--dw-color-border-muted);
    pointer-events: none;
}

/* Name / Date row inside the paper. */
.utt-results-fields {
    display: grid;
    grid-template-columns: auto 1fr auto 1fr;
    gap: var(--dw-space-tight) var(--dw-space-narrow);
    align-items: center;
    margin: 0 0 var(--dw-space-tight) 0;
}

.utt-field-label {
    font-size: 0.95em;
    font-weight: bold;
    white-space: nowrap;
}

.utt-text-input {
    border: 1px solid var(--dw-color-border-medium);
    border-radius: 0.15em;
    padding: 0.05em var(--dw-space-snug);
    font-size: 0.95em;
    width: 100%;
    box-sizing: border-box;
    background: transparent;
}

.utt-date-input {
    max-width: 7em;
}

/* Results table: two paired columns ("Up to..." / "Tries") repeated
   twice, giving four table columns and 10 rows per pair (20 entries).
   Uses table-layout: fixed so the four columns split evenly regardless
   of populated content. */
.utt-results-table {
    border-collapse: collapse;
    font-size: 0.85em;
    width: 100%;
    table-layout: fixed;
    margin: 0;
}

.utt-results-table th,
.utt-results-table td {
    padding: 0 var(--dw-space-narrow);
    border-bottom: 1px solid var(--dw-color-border-medium);
    text-align: left;
    background: transparent;
    line-height: 1.2;
}

/* Vertical divider between the two column pairs (columns 2 and 3 sit
   either side of the mid-page divider). */
.utt-results-table th:nth-child(2),
.utt-results-table td:nth-child(2) {
    border-right: 1px solid var(--dw-color-border-medium);
    padding-right: var(--dw-space-comfy);
}
.utt-results-table th:nth-child(3),
.utt-results-table td:nth-child(3) {
    padding-left: var(--dw-space-comfy);
}

.utt-results-table th {
    font-weight: normal;
    font-style: italic;
    border-bottom: 1px solid #000;
    padding: 0 var(--dw-space-narrow) 0.05em;
}

/* Individual row height locked so 10 rows fit inside the paper. */
.utt-results-table tbody td {
    height: 1.2em;
    vertical-align: middle;
}

/* Empty-slot rows still draw the underline so unused entries show as
   blank lines (matches Flash 20-slot ruled paper). */
.utt-results-table tbody td.utt-empty {
    color: transparent;
}

/* Total row: spans all four columns, keeps the same underline style
   as the ruled rows but with a bolder label. */
.utt-results-total-row td {
    padding-top: 0.15em;
    border-bottom: 1px solid #000;
    font-size: 0.95em;
    text-align: left;
}

.utt-total-label {
    font-weight: bold;
    font-style: italic;
    margin-right: var(--dw-space-snug);
}

.utt-score-text {
    font-weight: normal;
}

.utt-action-buttons {
    display: flex;
    gap: var(--dw-space-loose);
    justify-content: center;
    margin-top: var(--dw-space-narrow);
    padding-top: var(--dw-space-tight);
    flex-wrap: wrap;
}

.utt-print-hint {
    font-size: 0.75em;
    color: var(--dw-color-text-muted);
    text-align: center;
    margin: var(--dw-space-snug) 0 0 0;
}

/* --- Print stylesheet — show only the results paper --- */
@media print {
    @page { margin: 1.5cm; }

    body { background: #fff; }

    #dwNavigationHeader,
    .dw-screen-header,
    .dw-app-footer,
    #dwWelcomeScreen,
    #dwUserOptions,
    #dwActivityScreen,
    .utt-action-buttons,
    .utt-print-btn,
    .utt-print-hint {
        display: none !important;
    }

    .doorway_application,
    .doorway_fullscreen_div,
    .doorway_aspect_outer_div,
    .doorway_aspect_div,
    main {
        position: static !important;
        width: auto !important;
        height: auto !important;
        max-width: none !important;
        max-height: none !important;
        overflow: visible !important;
        transform: none !important;
        padding: 0 !important;
        margin: 0 !important;
    }

    #dwResultsScreen {
        position: static !important;
        display: block !important;
        width: 100% !important;
        height: auto !important;
        padding: 0 !important;
        overflow: visible !important;
        font-size: 12pt;
    }

    .utt-results-paper {
        /* Keep the paper look on print — background colours print in
           browser dialogs when the user opts in (or "Save as PDF"). */
        overflow: visible !important;
        max-width: none;
    }
    .utt-results-table {
        max-width: none;
        font-size: 1em;
    }
    .utt-results-table th { background: transparent; }
}

/* --- Scan highlight ---
   Flash: sprite5/shape6 = orange #ff6600 border frame (outer rect minus inner rect).
   Retune the shared ring colour to Flash's orange via the custom property. */

.scan_highlight {
    --scan-highlight-colour: #ff6600;
    --scan-highlight-thickness: 0.4em;
}

/* --- Activity progress indicator ---
   Small top-right "Question X of Y" label; sits on the activity screen
   above the object area. Matches the number-table nt-table-counter
   pattern (right-aligned, muted colour, small font). */
.utt-progress-text {
    font-size: 0.9em;
    text-align: right;
    color: var(--dw-color-text-muted);
    margin: 0 0 var(--dw-space-tight) 0;
    min-height: 1.1em;
}

.utt-progress-text:empty {
    /* Hide reserved space when there's nothing to announce yet. */
    display: none;
}

/* --- Picture preload container ---
   Off-screen, no-layout-impact container that holds <img> elements for
   every picture in the deck. Ensures the browser has decoded each SVG
   before the first `attachObjects` call, avoiding a brief blank-frame
   render on the first question of a new activity load. */
.utt-picture-preload {
    position: absolute;
    top: -9999px;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
    pointer-events: none;
}

.utt-picture-preload img {
    width: 1px;
    height: 1px;
}

/* --- Accessibility --- */

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0,0,0,0);
    white-space: nowrap;
    border: 0;
}

/* --- Reduced motion ---
   Collapse decorative animations/transitions. The `.utt-object` opacity
   fade is exempt: its duration is driven by the user-selected Speed of
   Presentation (via --fade-duration), so that control is authoritative.
   When reduced-motion is on, up-to-10-options.js seeds the fresh-session
   default for fadeLength to Instant (0.001s), so users land on no-fade
   by default but can opt into animation via the options screen.
*/
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
    .utt-object {
        transition-duration: var(--fade-duration, 0.7s) !important;
    }
    /* The dwell ring's sweep is the visible dwell clock, driven by the
       same JS timer that fires the action, so its fill animation stays
       at its configured duration. */
    .dw-dwell-fill {
        animation-duration: var(--dw-dwell-ms, 1200ms) !important;
    }
}

/* --- Options-screen overrides for the flow-mode layout ---
   In flow mode, the Questions/Speed two-column row needs to wrap when the
   viewport narrows below the combined fieldset width — otherwise the two
   inner fieldsets get crushed below their content's intrinsic width. */
body.dw-screen-options .utt-questions-speed-row {
    flex-wrap: wrap;
}
body.dw-screen-options .utt-questions-speed-row > fieldset {
    flex: 1 1 18em;
}

/* Large, always-on scrollbar on the options screen.
   Scoped to aspect-locked mode only: in flow mode the page itself scrolls
   (shared chrome makes #dwUserOptions overflow:visible), so a form-level
   scrollbar would either be redundant or fight the page scroll. */
body.dw-aspect-locked #dwUserOptions {
    overflow-y: scroll;            /* always render the gutter, not just on overflow */
    scrollbar-width: thick;        /* Firefox */
    scrollbar-color: var(--dw-color-text-secondary) var(--dw-color-border-faint);    /* thumb / track */
}

/* WebKit / Blink (Chrome, Safari, Edge) */
body.dw-aspect-locked #dwUserOptions::-webkit-scrollbar {
    width: 1.2em;
}
body.dw-aspect-locked #dwUserOptions::-webkit-scrollbar-track {
    background: var(--dw-color-border-faint);
    border-radius: 0.6em;
}
body.dw-aspect-locked #dwUserOptions::-webkit-scrollbar-thumb {
    background: var(--dw-color-text-secondary);
    border-radius: 0.6em;
    border: 0.15em solid var(--dw-color-border-faint);
}
@media (hover: hover) {
    body.dw-aspect-locked #dwUserOptions::-webkit-scrollbar-thumb:hover {
        background: var(--dw-color-text-primary);
    }
}

/* --- Options screen: eye-gaze mockup toggle row ---
   Sits inside the Accessibility fieldset, under the Scanning on/off row.
   The checkbox + inline note mirror the look of the force-counters row. */
.utt-eye-gaze-row {
    margin-top: var(--dw-space-narrow);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    column-gap: var(--dw-space-snug);
    row-gap: 0;
}

.utt-eye-gaze-row .utt-check-note {
    flex: 1 0 100%;
}

/* --- Eye-gaze mockup activity-screen restyle ------------------------------

   When .utt-eye-gaze-mode is on #dwActivityScreen, the number-line strip
   splits into two vertical rails pinned to the left and right edges of the
   activity area, and both the rails and the counting objects become
   enlarged dwell targets.

   The ten slots stay as one flat DOM row; a three-column CSS grid on the
   number-line container puts slots 1-5 in column 1, slots 6-10 in column 3,
   leaving the centre column as a spacer for the object area. See the per-
   slot grid-column rules below.
*/

/* Hide the usual bottom-strip chrome in eye-gaze mode; the two rails
   replace the strip's affordance entirely. The wrapper still holds the
   question text / try-again caption, so we keep it visible but anchored
   to the top of the activity area rather than sliding in from below. */
.utt-eye-gaze-mode .utt-activity-layout {
    position: relative;
    height: 100%;
}

/* Zero out the stage's top chrome padding: the shared nav header and the
   #uttProgressText counter both relocate to side strips flanking the rails
   (see rules further down), so no cross-stage top band is needed. The
   bottom padding stays — the rails have their own internal top/bottom
   padding and the stage-edge gutter keeps the slots off the screen edge. */
.utt-eye-gaze-mode.utt-screen {
    padding-top: 0;
}

/* Object area: horizontally inset wider than the rail columns (6.5em) so
   the random layout's scatter — which reads this element's live width —
   can never place an object centre or edge over a rail slot. Top reserve
   keeps scattered objects below the top-anchored question-text label;
   bottom reserve has a safety margin below the lowest scatter row so no
   object clips against the activity-area bottom. --utt-scatter-sprite-inset
   opts into shrinking the scatter anchor range by half the sprite's
   footprint so the sprite's edges — not just its centre — stay inside the
   inset band (unset elsewhere → 0 → centre-only clip). Objects get larger
   so they're easier dwell targets. */
.utt-eye-gaze-mode .utt-object-area {
    --utt-cell-w: 4.2em;
    --utt-cell-h: 4.2em;
    --utt-obj-size: 3.4em;
    --utt-scatter-top-reserve: 2.5em;
    --utt-scatter-bottom-reserve: 3em;
    --utt-scatter-sprite-inset: 1;
    margin: 0 8.5em;
    min-height: 14em;
}

/* Number-line wrapper is split visually into two side rails via CSS.
   The underlying DOM stays flat (one wrapper, one row of 10 buttons);
   we project each half onto its own absolutely-positioned column. */
.utt-eye-gaze-mode .utt-number-line-wrapper {
    position: absolute;
    inset: 0;
    background: transparent;
    border: none;
    padding: 0;
    pointer-events: none;
}

/* Replace the Flash-style bottom-up slide with per-rail slide-ins: slots
   1-5 enter from the left edge, 6-10 from the right. The wrapper itself
   just fades so the question-text block doesn't jolt. */
.utt-eye-gaze-mode .utt-number-line-wrapper.utt-number-line-entering {
    animation: utt-eye-gaze-fade 0.3s ease-out;
}

@keyframes utt-eye-gaze-fade {
    from { opacity: 0; }
    to   { opacity: 1; }
}

.utt-eye-gaze-mode .utt-number-line-wrapper.utt-number-line-entering .utt-line-slot:nth-child(-n+5) {
    animation: utt-eye-gaze-slide-left 0.45s ease-out;
}

.utt-eye-gaze-mode .utt-number-line-wrapper.utt-number-line-entering .utt-line-slot:nth-child(n+6) {
    animation: utt-eye-gaze-slide-right 0.45s ease-out;
}

@keyframes utt-eye-gaze-slide-left {
    from { transform: translateX(-120%); opacity: 0; }
    to   { transform: translateX(0);     opacity: 1; }
}

@keyframes utt-eye-gaze-slide-right {
    from { transform: translateX(120%); opacity: 0; }
    to   { transform: translateX(0);    opacity: 1; }
}

/* Question text + try-again caption float along the top of the activity
   area, centred between the rails. */
.utt-eye-gaze-mode .utt-number-line-labels {
    position: absolute;
    top: 0;
    left: 8.5em;
    right: 8.5em;
    pointer-events: auto;
    min-height: 2em;
}

/* Rails: slots 1-5 on the left column, 6-10 on the right. CSS grid with
   grid-auto-flow: column fills DOM-order (1..10) top-to-bottom down the
   left column first, then down the right. The container covers the whole
   activity area; the middle column is a spacer so the object area between
   the rails stays interactive — pointer-events are suppressed on the
   container and re-enabled per slot. Five equal rows (repeat(5, 1fr))
   with align-items: stretch so each slot fills its share of the stage
   height. */
.utt-eye-gaze-mode .utt-number-line {
    position: absolute;
    inset: 0;
    display: grid;
    grid-template-columns: 6.5em 1fr 6.5em;
    grid-template-rows: repeat(5, 1fr);
    grid-auto-flow: column;
    justify-items: center;
    align-items: stretch;
    row-gap: 0.5em;
    column-gap: 0;
    pointer-events: none;
    padding: 2.2em 0 0.4em;
    box-sizing: border-box;
}

.utt-eye-gaze-mode .utt-number-line .utt-line-slot {
    pointer-events: auto;
}

/* Explicit per-slot placement: slots 1-5 fill column 1 top-to-bottom,
   slots 6-10 fill column 3 top-to-bottom. The middle column stays empty
   as the spacer for the object area. */
.utt-eye-gaze-mode .utt-line-slot:nth-child(1)  { grid-column: 1; grid-row: 1; }
.utt-eye-gaze-mode .utt-line-slot:nth-child(2)  { grid-column: 1; grid-row: 2; }
.utt-eye-gaze-mode .utt-line-slot:nth-child(3)  { grid-column: 1; grid-row: 3; }
.utt-eye-gaze-mode .utt-line-slot:nth-child(4)  { grid-column: 1; grid-row: 4; }
.utt-eye-gaze-mode .utt-line-slot:nth-child(5)  { grid-column: 1; grid-row: 5; }
.utt-eye-gaze-mode .utt-line-slot:nth-child(6)  { grid-column: 3; grid-row: 1; }
.utt-eye-gaze-mode .utt-line-slot:nth-child(7)  { grid-column: 3; grid-row: 2; }
.utt-eye-gaze-mode .utt-line-slot:nth-child(8)  { grid-column: 3; grid-row: 3; }
.utt-eye-gaze-mode .utt-line-slot:nth-child(9)  { grid-column: 3; grid-row: 4; }
.utt-eye-gaze-mode .utt-line-slot:nth-child(10) { grid-column: 3; grid-row: 5; }

/* Slot: large dwell target. Width is fixed so the two columns of five
   align neatly on each rail; height stretches to fill its grid row so
   each slot gets its full share of the stage height. */
.utt-eye-gaze-mode .utt-line-slot {
    position: relative;
    flex: 0 0 auto;
    width: 6em;
    height: 100%;
    min-height: 2.4em;
    font-size: 1.4em;
    border: 0.1em solid #000;
    border-radius: 0.4em;
    margin: 0;
    background: #f0f6ff;
    box-shadow: 0 0.1em 0.2em rgba(0, 0, 0, 0.08);
}

/* Reset the touching-border rule inherited from the strip layout. */
.utt-eye-gaze-mode .utt-line-slot + .utt-line-slot {
    border-left-width: 0.1em;
}

/* Dwell ring: geometry comes from shared/dwell.css (.dw-dwell-indicator
   fills the host element's inset:0 box). Objects need overflow:visible
   so the ring reads clearly around their SVG bounds. */
.utt-eye-gaze-mode .utt-object {
    overflow: visible;
}

/* Counted objects should visibly settle so the dwell cue reads as
   "already counted — move on". */
.utt-eye-gaze-mode .utt-object.utt-object-counted {
    filter: saturate(0.6) brightness(0.95);
}

/* Hover affordance on rail slots: subtle lift so sighted testers see
   where their pointer is before the dwell completes. */
@media (hover: hover) {
    .utt-eye-gaze-mode .utt-line-slot:hover {
        background: #e3eeff;
    }
}

.utt-eye-gaze-mode .utt-line-slot:focus-visible {
    background: #e3eeff;
    outline: 0.3em solid gold;
    outline-offset: 0.1em;
}

/* Correct-answer state inside eye-gaze mode: match the shared pulse but
   with a green tint consistent with the rest of the activity. */
.utt-eye-gaze-mode .utt-line-slot.utt-slot-correct {
    background: #d6f5db;
    border-color: #00aa1a;
    color: #005500;
}

/* --- Top-chrome relocation --------------------------------------------
   The shared nav header (teacher gear + full-screen + audio toggle) is
   hidden on the activity screen in eye-gaze mode: a dwell-driven user
   can't reach the small icon strip reliably, and the demo wants the
   stage uncluttered. The #uttProgressText counter stays, pinned top-left
   above the left rail, inside the rail's 2.2em top padding so it never
   overlaps the slots.

   .utt-eye-gaze-mode on #dwAspectDiv is applied by initActivity so the
   nav header — a sibling of <main> — can be targeted here; it's cleared
   on activity-screen exit so welcome / options / results keep the
   standard top-strip chrome. */
.doorway_aspect_div.utt-eye-gaze-mode > #dwNavigationHeader {
    display: none;
}

.utt-eye-gaze-mode .utt-progress-text {
    position: absolute;
    top: 0.3em;
    left: 0.3em;
    width: 7em;
    font-size: 0.75em;
    line-height: 1.1;
    margin: 0;
    text-align: left;
    white-space: nowrap;
    z-index: 11;
}
