.activity-page {
    --accent: #9AB646;
    --danger: #e02d2d;

    --available: #ffe45b;
    --break: #86be7d;
    --rest: #c2debe;
    --driving: #b2b7e8;
    --work: #4286f5;
    --unknown: #b2b7e8;

    i.pa {
        color: var(--accent);

        &::before {
            vertical-align: middle;
        }
    }

    .skeleton {
        min-height: 25rem;

        &:empty {
            background: linear-gradient(90deg,
                    var(--background) 25%,
                    var(--light) 50%,
                    var(--background) 75%);
            background-size: 200% 100%;
            animation: skeleton-loading 3s infinite;
        }
    }

    .view-toggle {
        input {
            display: none;

            &+label {
                padding: 0.25rem 1rem;
                cursor: pointer;
                transition: background-color 0.15s, color 0.15s;
            }

            &:checked+label {
                background-color: var(--primary);
                color: white;
                border-radius: 50rem;
            }

            &:disabled+label {
                opacity: 0.4;
                cursor: not-allowed;
            }
        }

    }

    /* Timeline row structure */
    .timeline-container {
        padding-top: 1rem;
        --activity-bar-height: 5rem;
    }

    .timeline-band--activities {
        height: var(--activity-bar-height);
    }

    /* #386: rest-only day: the card collapses to a single thin rest band, so the
       breathing room above the timeline goes too. */
    .timeline-container--rest-only {
        padding-top: 0;
    }

    .timeline-row--hours {
        height: 1.25rem;
    }

    /* Single-container timeline: markers + pills + activities */
    .timeline {
        position: relative;
    }

    .marker,
    .timeline-pill {
        position: absolute;
        top: 0;
        bottom: 0;
        pointer-events: none;
    }

    .marker:hover,
    .timeline-pill:hover {
        z-index: 50 !important;
    }

    .marker__line,
    .pill__line {
        position: absolute;
        bottom: 0;
        width: 1px;
        background-color: #bbb;
        opacity: 0.4;
        pointer-events: none;
        transition: background-color 0.15s, opacity 0.15s;
    }

    .marker:hover > .marker__line,
    .timeline-pill:hover > .pill__line {
        background-color: #222;
        opacity: 0.8;
    }

    .marker__line--danger {
        background-color: var(--danger);
        opacity: 1;
    }

    .marker__line--warning {
        background-color: var(--warning);
        opacity: 1;
    }

    .marker__line--dark {
        background-color: var(--dark);
    }

    .marker__icon,
    .pill__icon {
        position: absolute;
        left: 50%;
        transform: translate(-50%, -50%) scale(0.85);
        transform-origin: top center;
        transition: transform 0.15s;
        display: inline-flex;
        align-items: center;
        gap: 4px;
        background-color: #f5f5f5;
        border-radius: 100px;
        padding: 3px 8px;
        font-size: 12px;
        color: #333;
        cursor: pointer;
        pointer-events: auto;
        white-space: nowrap;
        flex-shrink: 0;
    }

    .marker__icon:hover,
    .pill__icon:hover {
        background-color: #e8e8e8;
    }

    .pill__icon:hover {
        transform: translate(-50%, -50%) scale(0.95);
    }

    .marker__icon i,
    .pill__icon i {
        font-size: 16px;
        color: #333;
    }

    /* Infringement marker — red bordered pill */
    .marker__icon--danger {
        background-color: #fff;
        border: 1.5px solid var(--danger);
        color: var(--danger);
    }

    .marker__icon--danger:hover {
        background-color: #fff5f5;
    }

    .marker__icon--danger i {
        color: var(--danger);
        font-size: 10px;
    }

    /* Infringement marker on the timeline. Used to be one colour per detection
       version (v1 red, v2 blue, v3 purple); #843 left one detection, so there is
       one colour. Deliberately the same #dc3545 the v1 rule carried, so the
       timeline looks exactly as it did. */
    .marker__line--infringement { background-color: #dc3545; opacity: 1; }

    .marker__icon--infringement { background-color: #fff; border: 1.5px solid #dc3545; color: #dc3545; }

    .marker__icon--infringement i { color: #dc3545; font-size: 10px; }

    /* #895: a finding from before the driver's date_of_employment (or after
       termination_of_employment_at) is not this employer's business, but it
       still sat on the card and is still worth showing the driver - so grey,
       not hidden and not red. Same shape as the red marker on purpose. */
    .marker__line--infringement-outside-employment { background-color: #adb5bd; opacity: 1; }

    .marker__icon--infringement-outside-employment { background-color: #fff; border: 1.5px solid #adb5bd; color: #adb5bd; }

    .marker__icon--infringement-outside-employment i { color: #adb5bd; font-size: 10px; }

    /* Warning marker — amber bordered pill (overspeeding, VU misuse events) */
    .marker__icon--warning {
        background-color: #fff;
        border: 1.5px solid var(--warning);
        color: var(--warning);
    }

    .marker__icon--warning:hover {
        background-color: #fff8ea;
    }

    .marker__icon--warning i {
        color: var(--warning);
        font-size: 10px;
    }

    /* #895: in/uit dienst marker — blue bordered pill, distinct from the red
       (infringement), grey (infringement outside employment), amber (warning)
       and teal (team) markers already in use. */
    .marker__icon--employment {
        background-color: #fff;
        border: 1.5px solid #0d6efd;
        color: #0d6efd;
    }

    .marker__icon--employment:hover {
        background-color: #eff6ff;
    }

    .marker__icon--employment i {
        color: #0d6efd;
        font-size: 14px;
    }

    .marker__line--employment { background-color: #0d6efd; opacity: 1; }

    /* Team driving marker — teal bordered pill */
    .marker__icon--team {
        background-color: #fff;
        border: 1.5px solid #0d9488;
        color: #0d9488;
    }

    .marker__icon--team:hover {
        background-color: #f0fdfa;
    }

    .marker__icon--team i {
        color: #0d9488;
        font-size: 14px;
    }

    .timeline-row--overlays .shift-bar-container {
        height: 0.75rem;
    }

    .timeline-row--overlays .shift-bar {
        height: 0.75rem;
        background-color: var(--app-primary);
        transition: opacity 0.15s, filter 0.15s;
        /* Not the rounded-1 utility: that is !important, so the corners where the
           two halves of a ShiftSegment meet could not be squared off (#904). Same
           value the utility gave, so the bar looks exactly as it did. */
        border-radius: var(--bs-border-radius-sm);
    }

    .timeline-row--overlays .shift-bar__icon {
        transform: translate(-100%, 0%);
        font-size: 0.6rem;
    }

    /* #904: the rust half of a dienst bar. Dienst plus de rust erna is one bar in
       two colours: the work half stays app-primary and the rust half speaks the
       same language as the rest blocks on the timeline (--rest), so the length of
       the tail becomes the signal for how much rest hung on the dienst. Same
       height and same row as the work half, so the bar costs no extra space on a
       screen that has none to give. */
    .timeline-row--overlays .shift-bar--rest {
        /* Leans on --rest, the colour the rest blocks in the activity band use, but
           deepened towards the work half. Straight --rest sat directly under the
           band's own rest block in exactly that colour and the two merged into one
           pale mass, so the rust half of the bar disappeared precisely on the days
           it had something to say. Mixing the bar's own primary back in keeps it in
           the same green family while giving it its own edge. */
        background-color: color-mix(in oklch, var(--rest) 72%, var(--app-primary));
        /* The two halves touch, so the corners on the seam are square and the pair
           reads as one bar instead of two bars parked next to each other. */
        border-top-left-radius: 0;
        border-bottom-left-radius: 0;
    }

    .timeline-row--overlays .shift-bar--joined {
        border-top-right-radius: 0;
        border-bottom-right-radius: 0;
    }

    /* The shared shift-bar hover brightens, which on a colour this pale washes
       the rust half out to near white. Darken it instead, so hovering either
       half makes the whole segment stand out rather than half of it vanish. */
    .timeline-row--overlays .shift-bar--rest:hover,
    .timeline-row--overlays .shift-bar--rest.bar-hover {
        filter: brightness(0.92);
    }

    /* Te korte rust. The short tail says it by itself, but length is a weak
       signal and a state may never ride on colour alone, so it also carries the
       danger arcering (the .shift-bar__team-span texture, in the danger colour). */
    .timeline-row--overlays .shift-bar--rest-short {
        background-image: repeating-linear-gradient(
            -45deg,
            transparent,
            transparent 0.25rem,
            color-mix(in oklch, var(--danger) 60%, transparent) 0.25rem,
            color-mix(in oklch, var(--danger) 60%, transparent) 0.5rem
        );
    }

    /* Dubbele bemanning: a faint teal diagonal texture over the solid app-primary
       bar, so the "arcering" reads as a subtle hint of team driving instead of a
       loud two-tone barber pole (#544). #911 moved it off the bar itself onto a
       child span per is_team run, because the crew shares a stretch of the dienst
       and hardly ever the whole of it; the span carries no background-colour of
       its own so the bar's colour (and its rust half) still shows through. */
    .timeline-row--overlays .shift-bar__team-span {
        top: 0;
        height: 100%;
        /* Follows the bar's own rounding, so a run reaching either end of the bar
           cannot poke its square corner past the bar's. */
        border-radius: inherit;
        background-image: repeating-linear-gradient(
            -45deg,
            transparent,
            transparent 5px,
            rgba(13, 148, 136, 0.35) 5px,
            rgba(13, 148, 136, 0.35) 10px
        );
    }

    .timeline-row--overlays .shift-bar__team-icon {
        right: 0;
        transform: translate(100%, 0%);
        font-size: 0.7rem;
        color: #0d9488;
    }

    .timeline-row--overlays .infringement-bar-container {
        height: 0.4rem;
        /* Bars are visual only; the interaction lives on the infringement marker. */
        pointer-events: none;
    }

    .timeline-row--overlays .infringement-bar {
        height: 100%;
        background-color: var(--danger);
        /* Hidden until its marker is hovered or clicked; the reserved row keeps the layout stable. */
        opacity: 0;
        transition: opacity 0.15s;
    }

    /* #922: the stretch that interrupted a rest (driving on or off a ferry or
       train). The red line runs through it so the rest reads as one period, but
       as a hairline: those minutes were not rest, and the activity band right
       above already shows them as driving. */
    .timeline-row--overlays .infringement-bar--gap {
        background-color: transparent;
        background-image: repeating-linear-gradient(
            to right,
            var(--danger) 0 0.125rem,
            transparent 0.125rem 0.25rem
        );
        background-size: 100% 0.0625rem;
        background-position: center;
        background-repeat: no-repeat;
    }

    .timeline-row--overlays .vehicle-record-bar-container {
        height: 0.5rem;
    }

    .timeline-row--overlays .vehicle-record-bar {
        height: 100%;
        background-color: var(--info);
        opacity: 0.6;
    }

    .timeline-row--overlays .vehicle-record-label {
        top: 0.5rem;
        white-space: nowrap;
    }

    /* #828/#830: the stored segment layer (period_segments), a developer view
       behind the engine dropdown. Six labelled rows on ONE continuous time axis
       spanning the whole selected range: a fortnight or a 16 week reference
       period cut into day-sized pieces cannot be judged at all. It sits between
       the totals and the day cards, at the same altitude as the totals, since
       both describe the range as a whole.
       Status is drawn as a pattern as well as a colour (never colour alone). */
    .segment-overview {
        /* The label column is fixed so the gridline overlay can be offset by it
           without measuring anything at runtime. */
        --segment-label-col: 11rem;
        --segment-label-gap: 0.75rem;
        /* One lane holds one non-overlapping run of segments. The gap between two
           lanes must stay clearly smaller than the gap between two type rows, or
           the lanes read as separate types. */
        --segment-lane-h: 0.45rem;
        --segment-lane-gap: 0.24rem;
        --segment-lane-step: calc(var(--segment-lane-h) + var(--segment-lane-gap));
    }

    .segment-overview__rows {
        position: relative;
        display: grid;
        grid-template-columns: var(--segment-label-col) 1fr;
        column-gap: var(--segment-label-gap);
        row-gap: 0.7rem;
        align-items: center;
    }

    .segment-row__label {
        font-size: 0.65rem;
        line-height: 1.2;
        letter-spacing: 0.02em;
        text-transform: uppercase;
    }

    /* How many segments of this type the range holds. The count is the finding
       as often as the bars are: 39 weeks against 37 fortnights is what says the
       art. 6(3) window rolls per week instead of stepping per two. */
    .segment-row__count {
        display: inline-block;
        margin-left: 0.25rem;
        padding: 0 0.3rem;
        border-radius: 0.6rem;
        background-color: var(--background);
        color: var(--text-subtle);
        font-variant-numeric: tabular-nums;
    }

    .segment-row__track {
        height: calc(var(--lanes, 1) * var(--segment-lane-step) - var(--segment-lane-gap));
        background-color: var(--background);
        border-radius: 0.06rem;
    }

    /* The day boundaries of the cards above, so a bar can be read back to a day.
       Mondays are drawn harder: every week derived segment type begins there. */
    .segment-overview__grid {
        position: absolute;
        top: 0;
        bottom: 0;
        left: calc(var(--segment-label-col) + var(--segment-label-gap));
        right: 0;
        pointer-events: none;
        z-index: 2;
    }

    .segment-overview__gridline {
        position: absolute;
        top: 0;
        bottom: 0;
        border-left: 0.06rem solid var(--border);
        opacity: 0.45;
    }

    .segment-overview__gridline--week {
        border-left-color: var(--text-subtle);
        opacity: 0.75;
    }

    .segment-overview__axis {
        height: 1rem;
        margin-left: calc(var(--segment-label-col) + var(--segment-label-gap));
    }

    .segment-overview__tick {
        top: 0;
        transform: translateX(-50%);
        white-space: nowrap;
    }

    .segment-bar {
        top: calc(var(--lane, 0) * var(--segment-lane-step));
        height: var(--segment-lane-h, 0.55rem);
        border-radius: 0.06rem;
        cursor: pointer;
        transition: filter 0.15s;
    }

    /* Overlapping windows sit in their own lane, but two windows that merely
       touch share one. A tick at each end brackets every segment, so a run of
       consecutive weeks stays countable instead of reading as one long band. */
    .segment-bar::before,
    .segment-bar::after {
        content: '';
        position: absolute;
        top: -0.1rem;
        bottom: -0.1rem;
        width: 0.08rem;
        background-color: var(--text);
        opacity: 0.55;
    }

    .segment-bar::before {
        left: 0;
    }

    .segment-bar::after {
        right: 0;
    }

    .segment-bar:hover,
    .segment-bar.hint-hover {
        filter: brightness(1.15);
        outline: 0.06rem solid var(--dark);
    }

    /* Sluitend: the data covers the whole period, so it may be judged. */
    .segment-bar--closed {
        background-color: var(--success);
    }

    /* Open aan de kop / staart: hatched, leaning towards the open end. */
    .segment-bar--open-head {
        background-color: var(--warning-light);
        background-image: repeating-linear-gradient(45deg,
                var(--warning) 0 0.15rem,
                transparent 0.15rem 0.4rem);
    }

    .segment-bar--open-tail {
        background-color: var(--warning-light);
        background-image: repeating-linear-gradient(-45deg,
                var(--warning) 0 0.15rem,
                transparent 0.15rem 0.4rem);
    }

    /* Gat in het midden: the bar is literally interrupted. */
    .segment-bar--gap {
        background-color: var(--danger-light);
        background-image: repeating-linear-gradient(to right,
                var(--danger) 0 0.25rem,
                transparent 0.25rem 0.5rem);
    }

    /* Buiten het bestandsvenster: an empty outline, nothing was measured. */
    .segment-bar--outside-window {
        background-color: transparent;
        border: 0.06rem dashed var(--text-subtle);
    }

    /* A segment running past the selected range keeps that end square and drops
       its tick: the edge is the range's, not the segment's. */
    .segment-bar--continues-left {
        border-top-left-radius: 0;
        border-bottom-left-radius: 0;
    }

    .segment-bar--continues-left::before {
        display: none;
    }

    .segment-bar--continues-right {
        border-top-right-radius: 0;
        border-bottom-right-radius: 0;
    }

    .segment-bar--continues-right::after {
        display: none;
    }

    .segment-legend__swatch {
        position: static;
        display: inline-block;
        width: 1.75rem;
        height: 0.55rem;
        cursor: default;
    }

    .segment-legend__swatch::before,
    .segment-legend__swatch::after {
        display: none;
    }

    .timeline-hour-label {
        transform: translateX(-50%);
        white-space: nowrap;
    }

    .timeline-gridlines {
        pointer-events: none;
    }

    .pill__arrow {
        font-size: 0.6rem;
    }

    .pill__flag {
        width: 20px;
        height: 14px;
        object-fit: cover;
        border-radius: 2px;
        vertical-align: middle;
        flex-shrink: 0;
    }

    /* Hour gridlines behind activity bars */
    .timeline-row--activities .z-0 {
        z-index: -1 !important;
    }

    .activity-bar {
        border-radius: 2px 2px 0 0;
        cursor: pointer;
        /* Container so the slot-2 corner badge can hide itself on bars that are
           too narrow to fit it (see .activity-bar__slot-badge below). */
        container-type: inline-size;

        &:hover,
        &.hint-hover {
            filter: brightness(1.15);
        }
    }

    .activity-bar--available {
        background-color: var(--available);
        height: 3rem;
    }

    .activity-bar--break {
        background-color: var(--break);
        height: 2rem;
    }

    /* #570: activity bars step down in equal 1rem deltas (driving 5, work 4,
       available 3, break 2), with rest and unknown sharing the bottom 1rem
       tier. Colours are unchanged; only the heights are made evenly spaced. */
    .activity-bar--rest {
        background-color: var(--rest);
        height: 1rem;
    }

    .activity-bar--driving {
        background-color: var(--driving);
        height: 5rem;
    }

    .activity-bar--work {
        background-color: var(--work);
        height: 4rem;
    }

    .activity-bar--unknown {
        background-color: #F7F8FB;
        height: 1rem;
        border: 1px solid #e0e0e0;

        &:hover,
        &.hint-hover {
            filter: brightness(0.92);
        }
    }

    /* Slot-2 (co-driver) activity bars carry a small "2" pictogram in the
       bottom-right corner on the merged driver timeline, so a co-driver block
       is recognisable without a separate track. Hidden until the bar is wide
       enough to hold it (container query on .activity-bar). */
    .activity-bar__slot-badge {
        position: absolute;
        right: 0.15rem;
        bottom: 0.1rem;
        display: none;
        font-size: 0.6rem;
        line-height: 1;
        color: rgba(0, 0, 0, 0.6);
        text-shadow: 0 0 2px rgba(255, 255, 255, 0.7);
        pointer-events: none;
    }

    @container (min-width: 1.1rem) {
        .activity-bar__slot-badge {
            display: block;
        }
    }

    .activity-bar--manual {
        /* Manual entry: lay a faint dark diagonal texture over whatever the base
           activity colour is, so it reads as a subtle hint of hand-typed time.
           Kept lighter/finer than the dubbelbemand teal hatch on purpose (#560). */
        background-image: repeating-linear-gradient(
            -45deg,
            transparent,
            transparent 4px,
            rgba(0, 0, 0, 0.10) 4px,
            rgba(0, 0, 0, 0.10) 8px
        );
    }

    /* #570: same equal-delta staircase at compact scale — 0.5rem steps
       (driving 2.5, work 2, available 1.5, break 1), rest and unknown at the
       shared 0.5rem bottom tier. */
    .timeline-band--compact .activity-bar--driving { height: 2.5rem; }
    .timeline-band--compact .activity-bar--work { height: 2rem; }
    .timeline-band--compact .activity-bar--available { height: 1.5rem; }
    .timeline-band--compact .activity-bar--unknown { height: 0.5rem; }
    .timeline-band--compact .activity-bar--break { height: 1rem; }
    .timeline-band--compact .activity-bar--rest { height: 0.5rem; }

    /* #386: on a rest-only day the passive bars fill the collapsed 1rem band
       exactly. Kept after the generic compact rules so this wins the cascade. */
    .timeline-container--rest-only .activity-bar--rest,
    .timeline-container--rest-only .activity-bar--break,
    .timeline-container--rest-only .activity-bar--unknown {
        height: 1rem;
    }

    .text-accent {
        color: var(--accent);
    }

    .overview-grid {
        overflow-x: auto;
        min-width: max-content;
    }

    /* The day totals could not be scrolled sideways at all: on a long range the
       strip simply ran off the right of the screen. The markup is right (the
       card-body carries Tabler's .overflow-x-auto), but Backpack's CRUD
       common.css lists .card-body in a blanket

           .table-responsive, .dataTables_wrapper, .card, .card-body, .container
           { overflow: visible !important }

       which loads after Tabler and wins on source order, both being one class
       with !important. So the scroll container was flattened back to visible and
       the content just overflowed.

       An id beats a class, so this takes the axis back for this one strip
       without touching the vendor rule or the other cards it guards. !important
       is not decoration here: it is the only way past an !important. */
    #section-stats > .card-body.overflow-x-auto {
        overflow-x: auto !important;
    }

    .overview-column {
        min-width: 6.5rem;
        width: 6.5rem;
        flex-shrink: 0;
    }

    .overview-card {
        background-color: var(--background, #f7f8fb);
    }

    .overview-card .zero-value {
        opacity: 0.3;
    }

    .overview-stat {
        position: relative;
        padding-left: 1.25rem;
        font-size: 0.8rem;
        line-height: 1.4;
    }

    .overview-stat > i {
        position: absolute;
        left: -0.1rem;
        top: 50%;
        transform: translate(0, -50%);
        font-size: 0.85rem;
    }

    .overview-stat__value {
        font-family: 'Roboto Mono', 'SF Mono', 'Menlo', 'Consolas', monospace;
        font-size: 0.75rem;
    }

    .vehicle-span-bar {
        min-height: 1.5rem;
    }

    .vehicle-span {
        top: 0;
        border-bottom: 0.125rem solid var(--app-primary);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        /* Een kenteken krijgt 8rem, ook als het stuk zelf korter duurt, anders
           is het niet te lezen. Vlak voor het einde van de balk is die ruimte
           er niet: dan liep het kenteken het vak uit, tot buiten de kaart, en
           was het ook niet naar toe te scrollen (#797). --vehicle-span-room
           is de ruimte die er rechts van de start nog is; de reservering wordt
           daar nooit groter dan. */
        min-width: min(8rem, var(--vehicle-span-room, 8rem));
        max-width: var(--vehicle-span-room, none);
        cursor: pointer;
        transition: border-color 0.15s, background-color 0.15s;
    }

    .vehicle-span__icon {
        color: var(--app-primary);
    }

    .vehicle-span:hover {
        background-color: color-mix(in srgb, var(--app-primary), transparent 92%);
    }

    /* Timeline markers — base class for absolutely positioned elements above/below the bar */
    .timeline-marker {
        position: absolute;
        z-index: 2;
        transform: translateX(-50%);
        white-space: nowrap;
    }

    .timeline-marker--time-label {
        top: -1.3rem;
        font-size: 0.6rem;
        color: var(--bs-secondary);
        opacity: 0.7;
    }

    .timeline-annotation {
        position: absolute;
        left: 0.5rem;
        bottom: 1.6rem;
        z-index: 2;
        font-size: 13px;
        white-space: nowrap;
        font-weight: 700;
    }

    .timeline-annotation--normal {
        color: #4caf50;
    }

    .timeline-annotation--shortened {
        color: #eb9e2a;
    }

    .timeline-annotation--too_short {
        color: var(--danger);
    }

    /* Infringement group — bar below timeline for duration infringements */
    .infringement-group {
        display: block;
        cursor: pointer;
        min-height: 0.25rem;
    }

    .infringement-group__bar {
        display: block;
        height: 0.5rem;
        background-color: var(--danger);
        border-radius: 2px;
        opacity: 0.6;
    }

    .infringement-group:hover .infringement-group__bar {
        opacity: 1;
    }

    /* Shift + infringement bar hover */
    .shift-bar:hover,
    .shift-bar.bar-hover {
        opacity: 1 !important;
        filter: brightness(1.2);
    }

    /* Reveal a single bar when its marker is hovered (.bar-hover) or clicked/pinned (.bar-pinned). */
    .infringement-bar.bar-hover,
    .infringement-bar.bar-pinned {
        opacity: 1 !important;
    }

    /* Rest pills are interactive: hover highlights the pill and its rest bar(s),
       click opens a details popover. */
    .timeline-annotation {
        cursor: pointer;
    }

    /* Highlight applied to the hovered rest pill and the rest segment(s) it maps
       to. A single rest can light up several bars (across day cards / a
       ferry-train split). No z-index: bars are statically positioned and must
       stay below the positioned pill, else they cover it and cause a hover flicker. */
    .activity-bar.rest-segment-highlight,
    .timeline-annotation.rest-segment-highlight {
        outline: 2px solid var(--primary);
        outline-offset: 0;
        box-shadow: 0 0 0.4rem rgba(var(--bs-primary-rgb), 0.7);
        filter: brightness(1.1);
    }

    /* Floating rest-detail popover: positioned by JS and appended to <body> so it
       is never clipped by the timeline's overflow or stacking contexts. */
    .rest-popover {
        position: absolute;
        z-index: 1080;
        min-width: 14rem;
        max-width: 22rem;
        font-size: 0.8125rem;
        background: #fff;
    }

    /* Infringement pill marker — !! icon in the overlay */
    .marker[data-marker-type="infringement"] i {
        font-size: 0.7rem;
        flex-shrink: 0;
    }

    .infringement-highlighted > .marker__icon--danger {
        animation: infringement-blink 0.3s step-end 3, infringement-pulse 1.5s ease-in-out infinite;
    }

}

@keyframes infringement-blink {
    0%, 100% {
        background-color: var(--danger);
        color: #fff;
    }
    50% {
        background-color: #fff;
        color: var(--danger);
    }
}

@keyframes infringement-pulse {
    0%, 100% {
        box-shadow: 0 0 0 0 rgba(220, 53, 69, 0.6);
    }
    50% {
        box-shadow: 0 0 0 8px rgba(220, 53, 69, 0);
    }
}

@keyframes skeleton-loading {
    0% {
        background-position: 200% 0;
    }

    100% {
        background-position: -200% 0;
    }
}

/* Stats → timeline scroll navigation */
[data-scroll-to] {
    cursor: pointer;
}

[data-scroll-to]:hover {
    opacity: 0.8;
}

.timeline-card--flash {
    animation: card-flash 1.5s ease;
}

.timeline-marker--flash {
    animation: marker-flash 1.5s ease;
}

@keyframes card-flash {
    0%, 100% { box-shadow: none; }
    25% { box-shadow: 0 0 0 3px var(--accent); }
}

@keyframes marker-flash {
    0%, 100% { filter: none; }
    25%, 75% { filter: brightness(1.5) drop-shadow(0 0 4px var(--danger)); }
}

/* ──────────────────────────────────────────────────────────────
   Dark-mode activity palette.
   Rule: keep each activity-status hue so "yellow = available, green = break,
   blue-ish = driving" identity reads identically. Saturate + darken rather than
   lighten — the goal is "same system of colours, evening version".
   ────────────────────────────────────────────────────────────── */

[data-bs-theme="dark"] .activity-page {
    --accent:    #b8d05e;  /* hsl(72,52%,59%) — was #9AB646 (hsl 72,46%,49%); olive lifted slightly so it pops on dark */
    --danger:    #ff6b6b;  /* hsl(0,100%,71%) — matches global dark-mode --danger; was #e02d2d */

    --available: #d9b82d;  /* hsl(49,68%,51%) — was #ffe45b (hsl 49,100%,68%); richer, darker yellow */
    --break:     #5a9050;  /* hsl(113,28%,44%) — was #86be7d (hsl 113,34%,62%); darker green, same hue */
    --rest:      #6d8f6a;  /* hsl(114,14%,49%) — was #c2debe (hsl 113,30%,80%); same hue, halved lightness */
    --driving:   #6a73c4;  /* hsl(236,43%,59%) — was #b2b7e8 (hsl 236,53%,80%); deepened indigo */
    --work:      #2a66d6;  /* hsl(218,67%,50%) — was #4286f5 (hsl 218,90%,61%); slightly darker, still clearly blue */
    --unknown:   #4a5575;  /* hsl(222,23%,37%) — was #b2b7e8; a distinctly muted indigo for "no data" */
}

/* Timeline grid lines — hsl(0,0%,73%) (#bbb) → hsl(0,0%,27%) on dark. */
[data-bs-theme="dark"] .activity-page .marker__line,
[data-bs-theme="dark"] .activity-page .pill__line {
    background-color: #444;  /* hsl(0,0%,27%) */
}

/* Hovered grid line — hsl(0,0%,13%) (#222) → hsl(0,0%,87%) on dark. */
[data-bs-theme="dark"] .activity-page .marker:hover > .marker__line,
[data-bs-theme="dark"] .activity-page .timeline-pill:hover > .pill__line {
    background-color: #ddd;  /* hsl(0,0%,87%) */
}

/* Pill/marker icon chips — light-mode used #f5f5f5 bg with #333 text.
 * Dark-mode: invert both so the chip stays legible against a dark timeline. */
[data-bs-theme="dark"] .activity-page .marker__icon,
[data-bs-theme="dark"] .activity-page .pill__icon {
    background-color: #2a2a2a;  /* hsl(0,0%,16%) — was #f5f5f5 (hsl 0,0%,96%); inverted lightness */
    color: #ddd;                /* hsl(0,0%,87%) — was #333 (hsl 0,0%,20%) */
}

[data-bs-theme="dark"] .activity-page .marker__icon:hover,
[data-bs-theme="dark"] .activity-page .pill__icon:hover {
    background-color: #3a3a3a;  /* hsl(0,0%,23%) — was #e8e8e8 (hsl 0,0%,91%); one step lighter than rest */
}

[data-bs-theme="dark"] .activity-page .marker__icon i,
[data-bs-theme="dark"] .activity-page .pill__icon i {
    color: #ddd;  /* matches chip text */
}

/* Danger marker — light-mode used white pill with red border; dark uses dark pill with red border. */
[data-bs-theme="dark"] .activity-page .marker__icon--danger {
    background-color: #1a1a1a;  /* hsl(0,0%,10%) — was #fff; near-black */
    border: 1.5px solid var(--danger);
    color: var(--danger);
}

[data-bs-theme="dark"] .activity-page .marker__icon--danger:hover {
    background-color: #2a1515;  /* subtle red-tinted dark — was #fff5f5 (very pale pink); inverted spirit */
}

[data-bs-theme="dark"] .activity-page .marker__icon--warning {
    background-color: #1a1a1a;
    border: 1.5px solid var(--warning);
    color: var(--warning);
}

[data-bs-theme="dark"] .activity-page .marker__icon--warning:hover {
    background-color: #2a2515;
}

[data-bs-theme="dark"] .activity-page .marker__icon--team {
    background-color: #1a1a1a;
    border: 1.5px solid #2dd4bf;
    color: #2dd4bf;
}

[data-bs-theme="dark"] .activity-page .marker__icon--team:hover {
    background-color: #152a28;
}

[data-bs-theme="dark"] .activity-page .marker__icon--team i {
    color: #2dd4bf;
}

/* Unknown activity bar — light-mode #F7F8FB with #e0e0e0 border. Dark-mode: near-black bar. */
[data-bs-theme="dark"] .activity-page .activity-bar--unknown {
    background-color: #1c1d22;  /* hsl(230,8%,12%) — was #F7F8FB (hsl 230,27%,98%); inverted */
    border: 1px solid #35383e;  /* hsl(220,7%,22%) — was #e0e0e0 (hsl 0,0%,88%); inverted */
}

/* Rest bar — solid colour in dark mode, no stripe pattern needed. */

/* Skeleton loader — light-mode shimmer uses --background/--light.
 * Those vars already flip via the :root[data-bs-theme="dark"] block in custom.css,
 * so the shimmer inherits correct colours automatically. No override needed. */

/* Timeline annotation colours — semantic meaning preserved; lightness nudged for dark bg. */
[data-bs-theme="dark"] .activity-page .timeline-annotation--normal {
    color: #6fce73;  /* hsl(123,49%,62%) — was #4caf50 (hsl 123,39%,49%); brighter for dark bg */
}

[data-bs-theme="dark"] .activity-page .timeline-annotation--shortened {
    color: #f5b566;  /* hsl(32,88%,68%) — was #eb9e2a (hsl 35,83%,54%); softened for dark bg */
}

/* Overview card — light-mode fallback was #f7f8fb (matches --background var).
 * Var flip already handles it; no override needed here. */

/* View-toggle checked label — light-mode was `color: white` on --primary (dark green).
 * In dark mode --primary flips to pale mint #EBF3EB, so white is illegible. Swap to --light
 * (which is #121212 near-black in dark mode) so the contrast inverts cleanly with the bg. */
[data-bs-theme="dark"] .activity-page .view-toggle input:checked + label {
    color: var(--light);  /* near-black text on pale-mint --primary; mirrors light-mode's white-on-green contrast */
}
