.press-on-btn {
    position: absolute;
    left: 28px;
    top: -1.8rem;
    z-index: 20;
    background: transparent;
    border: none;
    outline: none;
    padding: 0.25rem;
    cursor: pointer;
    display: none;
    align-items: center;
    justify-content: center;
    transition: opacity 0.2s ease, transform 0.2s ease;
    opacity: 0.6;
    border-radius: 999px;
}

.press-on-btn.visible {
    display: flex;
}

.press-on-btn:hover {
    opacity: 1;
    transform: scale(1.1);
}

.press-on-btn:focus-visible {
    opacity: 1;
    box-shadow: 0 0 0 2px var(--bg-primary), 0 0 0 4px var(--accent-secondary);
}

.press-on-btn img {
    width: 23px;
    height: 20px;
    object-fit: contain;
    display: block;
}

.press-on-btn.running {
    opacity: 1;
}

/* Pulses until the user presses the button once. Pressing is the whole
   acknowledgement, so nobody has to start a goal to make it stop.

   The pulse is a glow and an opacity swell, NOT a scale. A 20px icon that
   scales is a moving hit target: it is harder to click for everyone and worse
   for anyone with motor difficulty, and automation refuses to click it at all
   ("element is not stable"). The ring draws the eye just as well and the button
   never moves. */
.press-on-btn.awaiting-intro {
    opacity: 1;
    border-radius: 999px;
    animation: press-on-attention 2.2s ease-in-out infinite;
}

/* A ripple: starts tight and opaque, expands as it fades. The spread and the
   alpha must move in opposite directions, or the ring is only ever visible
   where it has no size. */
@keyframes press-on-attention {
    0% {
        box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent-secondary) 70%, transparent);
    }
    70% {
        box-shadow: 0 0 0 7px color-mix(in srgb, var(--accent-secondary) 0%, transparent);
    }
    100% {
        box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent-secondary) 0%, transparent);
    }
}

/* Hovering or focusing is intent; the job is done, so stop the motion. */
.press-on-btn.awaiting-intro:hover,
.press-on-btn.awaiting-intro:focus-visible {
    animation: none;
}

@media (prefers-reduced-motion: reduce) {
    .press-on-btn.awaiting-intro {
        animation: none;
        box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-secondary) 60%, transparent);
    }
}

.press-on-tooltip {
    position: fixed;
    transform: translateY(-50%);
    padding: 0.5rem 0.75rem;
    background: var(--text-primary);
    color: var(--text-inverse);
    font-size: 0.75rem;
    font-weight: 500;
    line-height: 1.4;
    white-space: nowrap;
    border-radius: 0.375rem;
    pointer-events: none;
    z-index: 10002;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
}

/* ============================================================
   Active goal strip

   Two layouts over identical markup, driven by grid areas:
   - Stacked (default): sits in normal flow under the progress bar.
   - Inline (>=1100px): absolutely positioned into the toolbar row's empty
     middle, between the translation switcher and Reset/Random/Prev/Next, so
     an active goal adds ZERO vertical height. The typing page is already
     viewport-bound (passage + virtual keyboard), so pushing content down
     scrolls the keyboard off screen.
   ============================================================ */

.press-on-strip {
    display: none;
    gap: 0.35rem 0.6rem;
    padding: 0.5rem 0.6rem;
    border-radius: 0.4rem;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-light);
    grid-template-columns: minmax(0, 1fr) auto auto auto;
    grid-template-areas:
        "ref count clock actions"
        "bar bar   bar   bar";
    align-items: center;
}

.press-on-strip.visible {
    display: grid;
}

.press-on-strip-ref    { grid-area: ref; }
.press-on-bar          { grid-area: bar; }
.press-on-strip-count  { grid-area: count; }
.press-on-strip-clock  { grid-area: clock; justify-self: end; }
/* Visually hidden, not display:none — the strip is a live region and this is
   the sentence it announces. It changes only when progress or pace changes,
   never on the per-second clock tick. */
.press-on-strip-status {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}
.press-on-strip-actions{ grid-area: actions; justify-self: end; }
.press-on-strip-note   { grid-area: note; display: none; }

/* Pages that cannot advance the goal (prayers, lessons, timed tests, demo) say
   so, and swap Pause for the way back to the goal. */
/* The note only exists off-track, so its row is only declared there. Declaring
   it unconditionally left an empty grid track costing 6px on every page. */
.press-on-strip.offtrack {
    grid-template-areas:
        "ref  count clock actions"
        "bar  bar   bar   bar"
        "note note  note  note";
}

.press-on-strip.offtrack .press-on-strip-note {
    display: block;
    font-size: 0.66rem;
    font-style: italic;
    color: var(--text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.press-on-strip [data-action="resume-goal"] { display: none; }
.press-on-strip.offtrack [data-action="resume-goal"] { display: inline-block; }
.press-on-strip.offtrack [data-action="pause"] { display: none; }

.press-on-strip-ref {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.press-on-strip-count {
    font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.press-on-strip-clock {
    font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.press-on-strip.behind .press-on-strip-clock { color: var(--warning); }
.press-on-strip.paused .press-on-strip-clock { color: var(--text-secondary); }

/* The bar carries the whole "will I make it" question: the fill is Scripture
   done, the marker is where the clock has reached. Marker behind the fill means
   you are ahead. Same grammar as the passage-level pace guide. */
.press-on-bar {
    position: relative;
    width: 100%;
    min-width: 70px;
    height: 0.4rem;
    border-radius: 0.25rem;
    background: var(--border-light);
    overflow: visible;
}

.press-on-bar-fill {
    height: 100%;
    width: 0%;
    border-radius: 0.25rem;
    background: var(--accent-primary);
    transition: width 0.35s ease;
}

.press-on-strip.behind .press-on-bar-fill { background: var(--warning); }
.press-on-strip.done .press-on-bar-fill { background: var(--success); }

.press-on-bar-marker {
    position: absolute;
    top: -2px;
    left: 0;
    width: 2px;
    height: calc(100% + 4px);
    border-radius: 1px;
    background: var(--text-primary);
    opacity: 0.55;
    transition: left 0.5s linear;
    z-index: 2;
}

.press-on-strip.behind .press-on-bar-marker {
    background: var(--warning);
    opacity: 1;
}

.press-on-strip.paused .press-on-bar-marker { opacity: 0.3; }

.press-on-strip-actions {
    display: flex;
    gap: 0.35rem;
    flex-shrink: 0;
}

.press-on-mini-btn {
    background: transparent;
    border: 1px solid var(--border-medium);
    color: var(--text-secondary);
    border-radius: 0.25rem;
    padding: 0.15rem 0.45rem;
    font-size: 0.65rem;
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.15s ease, color 0.15s ease;
}

.press-on-mini-btn:hover {
    background: var(--accent-primary);
    border-color: var(--accent-primary);
    color: var(--text-inverse);
}

.press-on-mini-btn:focus-visible {
    outline: 2px solid var(--accent-secondary);
    outline-offset: 1px;
}

.press-on-mini-btn[disabled] {
    opacity: 0.45;
    cursor: not-allowed;
}

.press-on-mini-btn[disabled]:hover {
    background: transparent;
    border-color: var(--border-medium);
    color: var(--text-secondary);
}

/* Inline layout: ride the toolbar row, cost no vertical space. */
@media (min-width: 1100px) {
    .press-on-strip.visible {
        position: absolute;
        top: -1.8rem;
        left: 50%;
        transform: translateX(-50%);
        z-index: 19;
        width: max-content;
        max-width: calc(100% - 640px);
        height: 28px;
        padding: 0 0.55rem;
        gap: 0.5rem;
        grid-template-columns: auto minmax(70px, 130px) auto auto auto auto;
        grid-template-areas: "ref bar count clock note actions";
    }

    .press-on-strip.visible .press-on-strip-ref {
        max-width: 190px;
    }

    .press-on-strip.visible .press-on-strip-clock {
        font-size: 0.82rem;
        justify-self: auto;
    }

    .press-on-strip.visible .press-on-mini-btn {
        padding: 0.1rem 0.4rem;
        font-size: 0.62rem;
    }
}

/* Tighter still: drop the reference, keep progress and the clock. The
   off-track note falls back to the strip's title attribute at these widths. */
@media (min-width: 1100px) and (max-width: 1400px) {
    .press-on-strip.visible .press-on-strip-ref,
    .press-on-strip.visible.offtrack .press-on-strip-note {
        display: none;
    }
}

/* ============================================================
   Goal modal
   ============================================================ */

.press-on-modal {
    position: fixed;
    inset: 0;
    z-index: 10001;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}

.press-on-modal.open {
    display: flex;
}

.press-on-modal-overlay {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(2px);
}

.press-on-modal-content {
    position: relative;
    z-index: 1;
    width: min(520px, 100%);
    max-height: 88vh;
    overflow-y: auto;
    background: var(--bg-modal);
    color: var(--text-primary);
    border: 1px solid var(--border-light);
    border-radius: 0.85rem;
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.4);
    padding: 1.4rem;
}

.press-on-modal-header {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    margin-bottom: 1.1rem;
}

/* Scoped to the title icon on purpose. A bare `.press-on-modal-header img`
   also matches the Learn More and close icons and, at (0,1,1), outranks the
   shared .icon-inline / .close-btn-icon sizes. */
.press-on-modal-icon {
    width: 2.2rem;
    height: 2.2rem;
    object-fit: contain;
    flex-shrink: 0;
}

.press-on-modal-title {
    font-size: 1.1rem;
    font-weight: 700;
    margin: 0;
    line-height: 1.25;
}

.press-on-modal-subtitle {
    font-size: 0.8rem;
    color: var(--text-secondary);
    margin: 0.2rem 0 0;
    line-height: 1.4;
}

/* Header controls.

   These deliberately do NOT reuse .btn / .btn-secondary / .btn-small /
   .modal-close-btn. Those look like a shared design system but every one of
   them is scoped to `.race-mode-modal` in race-mode.css, so outside that
   container the close button falls back to the browser default (2px outset
   border) and the action button inherits the base .btn: uppercase, 16px, and a
   filled background. race-mode.css is also not loaded on /lessons, where this
   modal is reachable from the expiry screen. Self-contained here instead,
   matching the race modal's appearance with theme tokens. */
.press-on-guide-btn {
    margin-left: auto;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    white-space: nowrap;
    padding: 0.4rem 0.65rem;
    border-radius: 6px;
    border: 1px solid var(--border-medium);
    background: transparent;
    color: var(--text-secondary);
    font-family: inherit;
    font-size: 0.7rem;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}

.press-on-guide-btn:hover {
    color: var(--text-primary);
    border-color: var(--accent-primary);
    background: var(--bg-tertiary);
}

.press-on-guide-btn:focus-visible {
    outline: 2px solid var(--accent-secondary);
    outline-offset: 1px;
}

.press-on-guide-btn.playing {
    background: var(--accent-primary);
    border-color: var(--accent-primary);
    color: var(--text-inverse);
}

.press-on-guide-btn.playing .press-on-guide-icon {
    animation: press-on-guide-pulse 1.1s ease-in-out infinite;
}

@keyframes press-on-guide-pulse {
    0%, 100% { opacity: 0.45; }
    50% { opacity: 1; }
}

.press-on-modal-close {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    margin-left: 0.35rem;
    width: 28px;
    height: 28px;
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 6px;
    color: var(--text-secondary);
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}

.press-on-modal-close:hover {
    color: var(--text-primary);
    background: var(--bg-tertiary);
}

.press-on-modal-close:focus-visible {
    outline: 2px solid var(--accent-secondary);
    outline-offset: 1px;
}

@media (prefers-reduced-motion: reduce) {
    .press-on-guide-btn.playing .press-on-guide-icon { animation: none; opacity: 1; }
}

@media (max-width: 480px) {
    .press-on-guide-btn .press-on-guide-label { display: none; }
}

.press-on-section-label {
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--text-secondary);
    margin: 0 0 0.55rem;
}

.press-on-tabs {
    display: flex;
    gap: 0.35rem;
    margin-bottom: 0.85rem;
    flex-wrap: wrap;
}

.press-on-tab {
    flex: 1 1 auto;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-light);
    color: var(--text-secondary);
    border-radius: 0.4rem;
    padding: 0.4rem 0.6rem;
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
    white-space: nowrap;
}

.press-on-tab:hover {
    color: var(--text-primary);
    border-color: var(--border-medium);
}

.press-on-tab[aria-selected="true"] {
    background: var(--accent-primary);
    border-color: var(--accent-primary);
    color: var(--text-inverse);
}

.press-on-tab:focus-visible {
    outline: 2px solid var(--accent-secondary);
    outline-offset: 1px;
}

.press-on-panel {
    display: none;
    margin-bottom: 1rem;
}

.press-on-panel.active {
    display: block;
}

.press-on-picks {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 0.45rem;
    max-height: 232px;
    overflow-y: auto;
    padding-right: 0.15rem;
}

.press-on-pick {
    text-align: left;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-light);
    border-radius: 0.45rem;
    padding: 0.5rem 0.6rem;
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease;
    color: var(--text-primary);
}

.press-on-pick:hover {
    border-color: var(--accent-primary);
}

.press-on-pick[aria-pressed="true"] {
    border-color: var(--accent-primary);
    background: color-mix(in srgb, var(--accent-primary) 14%, transparent);
}

.press-on-pick:focus-visible {
    outline: 2px solid var(--accent-secondary);
    outline-offset: 1px;
}

.press-on-pick-name {
    display: block;
    font-size: 0.85rem;
    font-weight: 600;
}

.press-on-pick-meta {
    display: block;
    font-size: 0.68rem;
    color: var(--text-secondary);
    margin-top: 0.12rem;
    font-variant-numeric: tabular-nums;
}

.press-on-fields {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 0.55rem;
}

.press-on-field {
    display: flex;
    flex-direction: column;
    gap: 0.22rem;
}

.press-on-field.full {
    grid-column: 1 / -1;
}

.press-on-field label {
    font-size: 0.7rem;
    font-weight: 600;
    color: var(--text-secondary);
}

.press-on-field select,
.press-on-field input {
    background: var(--bg-input);
    border: 1px solid var(--border-medium);
    color: var(--text-primary);
    border-radius: 0.35rem;
    padding: 0.4rem 0.5rem;
    font-size: 0.85rem;
    font-family: inherit;
    width: 100%;
}

.press-on-field select:focus,
.press-on-field input:focus {
    outline: 2px solid var(--accent-secondary);
    outline-offset: 0;
}

.press-on-summary {
    border-top: 1px solid var(--border-light);
    padding-top: 0.9rem;
    margin-bottom: 0.9rem;
}

.press-on-estimate {
    font-size: 0.83rem;
    line-height: 1.5;
    color: var(--text-primary);
    margin: 0 0 0.75rem;
}

.press-on-estimate strong {
    font-variant-numeric: tabular-nums;
}

.press-on-estimate-source {
    display: block;
    font-size: 0.7rem;
    color: var(--text-secondary);
    margin-top: 0.15rem;
}

.press-on-paces {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(112px, 1fr));
    gap: 0.4rem;
}

.press-on-pace {
    background: var(--bg-tertiary);
    border: 1px solid var(--border-light);
    border-radius: 0.45rem;
    padding: 0.5rem 0.35rem;
    cursor: pointer;
    text-align: center;
    color: var(--text-primary);
    transition: border-color 0.15s ease, background 0.15s ease;
}

.press-on-pace:hover {
    border-color: var(--accent-primary);
}

.press-on-pace[aria-pressed="true"] {
    border-color: var(--accent-primary);
    background: color-mix(in srgb, var(--accent-primary) 14%, transparent);
}

.press-on-pace:focus-visible {
    outline: 2px solid var(--accent-secondary);
    outline-offset: 1px;
}

.press-on-pace-time {
    display: block;
    font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.95rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.press-on-pace-label {
    display: block;
    font-size: 0.72rem;
    font-weight: 600;
    margin-top: 0.1rem;
}

.press-on-pace-blurb {
    display: block;
    font-size: 0.63rem;
    color: var(--text-secondary);
    margin-top: 0.05rem;
}

.press-on-notice {
    border-radius: 0.45rem;
    padding: 0.6rem 0.7rem;
    font-size: 0.78rem;
    line-height: 1.45;
    margin-bottom: 0.9rem;
    display: none;
}

.press-on-notice.visible {
    display: block;
}

.press-on-notice.warning {
    background: color-mix(in srgb, var(--warning) 16%, transparent);
    border: 1px solid color-mix(in srgb, var(--warning) 45%, transparent);
    color: var(--text-primary);
}

.press-on-notice.error {
    background: color-mix(in srgb, var(--error) 16%, transparent);
    border: 1px solid color-mix(in srgb, var(--error) 45%, transparent);
    color: var(--text-primary);
}

.press-on-notice-actions {
    display: flex;
    gap: 0.4rem;
    margin-top: 0.5rem;
    flex-wrap: wrap;
}

.press-on-notice-link {
    background: var(--accent-primary);
    color: var(--text-inverse);
    border: none;
    border-radius: 0.3rem;
    padding: 0.3rem 0.6rem;
    font-size: 0.72rem;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none;
    display: inline-block;
}

.press-on-notice-link:hover {
    filter: brightness(0.92);
}

.press-on-modal-actions {
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
    border-top: 1px solid var(--border-light);
    padding-top: 0.9rem;
}

.press-on-action {
    border-radius: 0.4rem;
    padding: 0.5rem 1rem;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    border: 1px solid transparent;
    font-family: inherit;
}

.press-on-action.primary {
    background: var(--accent-primary);
    color: var(--text-inverse);
}

.press-on-action.primary:hover:not([disabled]) {
    filter: brightness(0.92);
}

.press-on-action.primary[disabled] {
    opacity: 0.5;
    cursor: not-allowed;
}

.press-on-action.ghost {
    background: transparent;
    color: var(--text-secondary);
    border-color: var(--border-medium);
}

.press-on-action.ghost:hover {
    color: var(--text-primary);
    background: var(--bg-tertiary);
}

.press-on-action.danger {
    background: transparent;
    color: var(--error);
    border-color: color-mix(in srgb, var(--error) 45%, transparent);
}

.press-on-action.danger:hover {
    background: color-mix(in srgb, var(--error) 12%, transparent);
}

.press-on-action:focus-visible {
    outline: 2px solid var(--accent-secondary);
    outline-offset: 1px;
}

.press-on-loading {
    font-size: 0.78rem;
    color: var(--text-secondary);
    padding: 0.75rem 0;
}

@media (max-width: 768px) {
    .press-on-btn {
        top: -1rem;
        left: 28px;
    }

    .press-on-modal-content {
        padding: 1.1rem;
    }
}

@media (max-width: 480px) {
    /* Reference and clock share a row; progress, status and actions stack under it. */
    .press-on-strip.visible {
        padding: 0.45rem 0.5rem;
        gap: 0.3rem 0.5rem;
    }

    .press-on-picks {
        grid-template-columns: 1fr;
    }
}

@media (prefers-reduced-motion: reduce) {
    .press-on-bar-fill,
    .press-on-bar-marker,
    .press-on-btn {
        transition: none;
    }
}


/* ============================================================
   Toolbar spacing

   The gear, race flag, bug flag and translation switcher are absolutely
   positioned siblings. They shift right only while the Press On button is
   actually rendered (`has-press-on`, set by updateVisibility). Signed-out
   visitors, /prayers, /lessons and /timed_test keep the original spacing
   instead of a hole where the button would have been.
   ============================================================ */

/* The race trigger and the bug button both transition `all`, so repositioning
   them would animate as a visible slide when the button appears after auth
   resolves. Neither ever needs `left` animated. */
.typing-stats-progress-combined .race-mode-trigger,
.typing-stats-progress-combined .bug-report-btn { transition-property: opacity, transform; }

.typing-stats-progress-combined.has-press-on .race-mode-trigger { left: 59px; }
.typing-stats-progress-combined.has-press-on .bug-report-btn { left: 87px; }
.typing-stats-progress-combined.has-press-on .typing-translation-switcher { left: 121px; }

@media (max-width: 768px) {
    .typing-stats-progress-combined.has-press-on .race-mode-trigger { left: 59px; }
    .typing-stats-progress-combined.has-press-on .bug-report-btn { left: 87px; }
    .typing-stats-progress-combined.has-press-on .typing-translation-switcher { left: 121px; }
}

@media (max-width: 480px) {
    .typing-stats-progress-combined.has-press-on .typing-translation-switcher { left: 64px; }
}
