/*
  ----------------------------------------
  UI Components
  ----------------------------------------

  Navigation map:
  - SECTION: Shell, shared primitives, and auth
  - SECTION: Core controls and feedback
  - SECTION: Dialogs, project form modal layout, and maps
  - SECTION: Desktop project workspaces
  - SECTION: PWA header and navigation tabs
  - SECTION: Guides and report inputs
  - SECTION: Shared inventory and capture controls
  - SECTION: Field cards, journal, and forms
  - SECTION: Project photos, annotations, and photo maps
  - SECTION: Project chat
  - SECTION: Floating actions and toggles
  - SECTION: Component layer extras
*/

@layer styles {
    /* Custom CSS: Prewind has no equal-column grid or responsive cell dividers
       for the shared import count strip. */
    .ui-project-import-stats {
        display: grid;
        grid-auto-flow: column;
        grid-auto-columns: minmax(0, 1fr);

        > div + div { border-inline-start: var(--border) solid var(--light); }

        @media (max-width: 640px) {
            grid-auto-flow: row;
            grid-template-columns: repeat(2, minmax(0, 1fr));

            > div:nth-child(odd) { border-inline-start: 0; }
            > div:nth-child(n + 3) { border-top: var(--border) solid var(--light); }
        }
    }

    /*
      SECTION: Shell, shared primitives, and auth
      PWA body locking, shared card/fade helpers, auth layout, and
      PWA form width resets.
    */

    /* PWA Shell
  ---------------------------------- */
    html.ui-pwa-root {
        height: 100%;
        overflow: hidden;
        overscroll-behavior: none;
        background: var(--lighter);
    }

    body.ui-pwa-body {
        box-sizing: border-box;
        display: flex;
        height: 100dvh;
        min-height: 0;
        flex-direction: column;
        overflow: hidden;
        overscroll-behavior: none;
    }

    body.ui-pwa-edge-to-edge-body {
        padding-bottom: 0;
    }

    body.ui-pwa-clipped-main-body > main {
        overflow: hidden;
    }

    .ui-pwa-main {
        flex: 1 1 auto;
        min-height: 0;
        overflow-x: hidden;
        overflow-y: auto;
        overscroll-behavior-y: none;
        -webkit-overflow-scrolling: touch;
    }

    .ui-pwa-main .overflow-y-auto {
        overscroll-behavior-y: none;
        -webkit-overflow-scrolling: touch;
    }

    .truncated {
        position: relative;
        display: block;
        min-width: 0;
        max-width: 100%;
        overflow: hidden;
        white-space: nowrap;
    }

    .truncated::after {
        content: "";
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        width: min(15rem, 40%);
        background: linear-gradient(
            to right,
            transparent 0%,
            var(--white) 100%
        );
        pointer-events: none;
    }

    /* Auth shell
    ---------------------------------- */
    .ui-auth-hero-graphic {
        top: 50%;
        width: clamp(28rem, 56vw, 73rem);
        transform: translate(50%, -50%);
        z-index: -10;
    }

    .ui-auth-card {
        display: flex;
        width: 100%;
        gap: var(--space-md);
        padding: var(--space-lg);
        border-radius: var(--rounded-sm);
        max-width: var(--max-w-form);
        flex-direction: column;
        margin-inline: auto;
        background: var(--white);

        .ui-content-vertical-center {
            display: flex;
            flex-direction: column;
            gap: var(--space-md);
            margin-top: auto;
        }
    }

    .ui-pwa-viewport-page {
        display: flex;
        min-height: var(--ui-pwa-viewport-height, 100dvh);
        height: var(--ui-pwa-viewport-height, 100dvh);
        flex-direction: column;
        overflow: hidden;
        background: var(--lighter);
    }

    .ui-pwa-fluid-fields .ui-field,
    .ui-pwa-fluid-fields .ui-field-control {
        min-width: 0;
        max-width: 100%;
    }

    /*
      SECTION: Core controls and feedback
      Buttons, hamburger/drawer controls, sidebars, avatars, toasts,
      dropdowns, OTP inputs, and shared form logo.
    */

    /* Buttons
  ---------------------------------- */

    .ui-button {
        display: inline-flex;
        width: 100%;
        align-items: center;
        font-size: var(--text-lg);
        justify-content: center;
        padding: var(--space-xs) var(--space-sm);
        line-height: 2.2;
        border: none;
        border-radius: var(--rounded);
        box-shadow: var(--shadow-sm);
        font-weight: 600;
        color: var(--brand-1);
        cursor: pointer;
        background: var(--darker);
        text-decoration: none;
        transition: all var(--ui-duration-fast) var(--ui-ease);
        margin: 0;
        gap: var(--space-xs);

        /* Custom CSS: class display must not defeat a native hidden attribute,
           and button icons share one size independent of per-caller icon size. */
        &[hidden] {
            display: none;
        }

        > svg {
            flex: none;
            width: 1.125rem;
            height: 1.125rem;
        }

        &:hover {
            filter: brightness(1.1);
            box-shadow: var(--shadow);
        }

        &:active {
            transform: translateY(0.5px);
            box-shadow: none;
        }

        &.ui-brand-2,
        &.ui-brand-3,
        &.ui-brand-4,
        &.ui-info,
        &.ui-success,
        &.ui-warning,
        &.ui-error {
            color: var(--white);
            border-color: var(--white);
        }

        /* Custom CSS: one shared button component owns the primary ink-on-gold
           56px write target with its pressed token, the white bordered secondary,
           and the outlined destructive variant; Prewind has no equivalents. */
        &.ui-brand-1 {
            color: var(--darker);
            background: var(--brand-1);
            min-height: var(--ui-tap-write);
        }
        &.ui-brand-1:active {
            background: var(--brand-1-pressed);
        }
        &.ui-brand-2 {
            background: var(--brand-2);
        }
        &.ui-brand-3 {
            background: var(--brand-3);
        }
        &.ui-brand-4 {
            background: var(--brand-4);
        }
        &.ui-neutral {
            min-height: var(--ui-tap-min);
            background: var(--white);
            border: var(--border) solid var(--muted);
            color: var(--darker);
        }
        &.ui-destructive {
            min-height: var(--ui-tap-min);
            background: var(--white);
            border: var(--border) solid var(--error);
            color: var(--error);
        }
        &.ui-info {
            background: var(--info);
        }
        &.ui-success {
            background: var(--success);
        }
        &.ui-warning {
            background: var(--warning);
        }
        &.ui-error {
            background: var(--error);
        }
    }

    .ui-auth-action {
        align-self: stretch;
    }

    @media (min-width: 768px) {
        .ui-auth-action {
            width: auto;
            margin-left: auto;
            font-size: var(--text-base);
            align-self: flex-start;
            padding: 0 var(--space-md);
            height: var(--ui-tap-min);
        }
    }

    /* Desktop admin buttons */
    .admin .ui-button {
        width: auto;
        font-size: var(--text-base);
        padding: 0 var(--space-md);
    }

    .ui-button-plain {
        border: 0;
        background: transparent;
        font: inherit;
    }

    /* Buttons mini-round */
    .ui-button-mini-round {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 1.5rem;
        height: 1.5rem;
        border-radius: var(--rounded-full);
        background: var(--lighter);
        color: var(--darker);
        box-shadow: var(--shadow-sm);
        transition: all var(--ui-duration-move) var(--ui-ease);

        &:active {
            background: var(--brand-1);
            color: var(--darker);
        }
    }

    /* Crud header */
    .crud-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-md);
        min-height: 6rem;

        h3 {
            flex: 1 1 auto;
            margin: 0;
            min-width: 0;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        > :not(h3) {
            flex: 0 0 auto;
        }
    }

    /* Hamburger Button
  ---------------------------------- */
    .ui-hamburger-button {
        --button-width: 30px;
        --button-height: 24px;
        --line-thickness: 3px;
        --line-color: var(--darker);
        --line-radius: 2px;
        --number-of-spins: 5;
        --duration: var(--ui-duration-fast);
        --focus-color: rgba(0, 0, 0, 0.2);

        position: relative;
        display: block;
        width: var(--button-width);
        height: var(--button-height);
        cursor: pointer;
        outline: none;

        .line-1,
        .line-2,
        .line-3 {
            position: absolute;
            display: block;
            width: 100%;
            height: var(--line-thickness);
            background-color: var(--line-color);
            border-radius: var(--line-radius);
            transition: all var(--duration) var(--ui-ease);
        }

        .line-2 {
            top: calc(50% - var(--line-thickness) / 2);
        }

        .line-3 {
            bottom: 0;
        }

        /* Hamburger animate */
        [data-ui-hamburger-open-value="true"] & {
            .line-1 {
                transform: translateY(
                        calc(
                            var(--button-height) / 2 - var(--line-thickness) / 2
                        )
                    )
                    rotate(calc(-1 * 45deg * var(--number-of-spins)));
            }
            .line-2 {
                opacity: 0;
            }
            .line-3 {
                transform: translateY(
                        calc(
                            -1 *
                                (
                                    var(--button-height) / 2 -
                                        var(--line-thickness) / 2
                                )
                        )
                    )
                    rotate(calc(45deg * var(--number-of-spins)));
            }
        }
    }

    /* Hamburger Menu
    ---------------------------------- */
    .ui-hamburger-menu {
        position: fixed;
        right: 0;
        top: 4rem;
        bottom: 0;
        z-index: var(--z-drawer);
        width: 100%;
        background-color: rgba(0, 0, 0, 0.9);
        backdrop-filter: blur(10px);
        box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1);
        transition:
            transform var(--ui-duration-fast) var(--ui-ease-move),
            visibility 0s var(--ui-duration-fast);
        transform: translateX(100%);
        overflow-y: auto;
        visibility: hidden;

        /* Show menu when hamburger is open */
        [data-ui-hamburger-open-value="true"] & {
            visibility: visible;
            transform: translateX(0);
            transition:
                transform var(--ui-duration-fast) var(--ui-ease-move),
                visibility 0s 0s;
        }
    }

    /* PWA Mobile Drawer
    ---------------------------------- */
    .ui-pwa-drawer-overlay {
        position: fixed;
        inset: 0;
        z-index: var(--z-scrim);
        background-color: black;
        opacity: 0;
        visibility: hidden;
        transition:
            opacity var(--ui-duration-fast) var(--ui-ease),
            visibility 0s var(--ui-duration-fast);

        [data-ui-hamburger-open-value="true"] & {
            opacity: 0.5;
            visibility: visible;
            transition:
                opacity var(--ui-duration-fast) var(--ui-ease),
                visibility 0s 0s;
        }
    }

    .ui-pwa-drawer {
        width: 75%;
        border-top-right-radius: 2rem;
        border-bottom-right-radius: 2rem;
        transform: translateX(-100%);
        visibility: hidden;
        transition:
            transform var(--ui-duration-fast) var(--ui-ease-move),
            visibility 0s var(--ui-duration-fast);

        [data-ui-hamburger-open-value="true"] & {
            transform: translateX(0);
            visibility: visible;
            transition:
                transform var(--ui-duration-fast) var(--ui-ease-move),
                visibility 0s 0s;
        }
    }

    /* Org sidebar
    ---------------------------------- */
    .ui-org-sidebar {
        width: 17rem;
        min-width: 17rem;
        border-top-right-radius: 2rem;
        border-bottom-right-radius: 2rem;
    }

    .ui-pwa-safe-area-bottom {
        padding-bottom: env(safe-area-inset-bottom);
    }

    .ui-org-sidebar-link {
        min-height: 3.25rem;
    }

    .ui-org-sidebar-link.is-active {
        color: var(--brand-1);
    }

    button.ui-org-sidebar-link {
        appearance: none;
        background: transparent;
        font: inherit;
    }

    .ui-org-sidebar-icon {
        display: inline-flex;
        width: 2.5rem;
        height: 2.5rem;
        flex: 0 0 auto;
        align-items: center;
        justify-content: center;
        border-radius: var(--rounded-full);
        background: transparent;
        box-shadow: inset 0 0 0 var(--border-lg) var(--brand-1);
        color: var(--brand-1);
    }

    .ui-org-sidebar-link.is-active .ui-org-sidebar-icon {
        background: var(--brand-1);
        box-shadow: none;
        color: var(--brand-1-content);
    }

    .ui-org-sidebar-icon svg {
        width: 1.25rem;
        height: 1.25rem;
    }

    /* Custom CSS: the shared avatar owns size-dependent image and initials sizing.
       Prewind has no text-xs utility.
    ---------------------------------- */
    .ui-avatar {
        &[data-size="sm"] {
            --avatar-size: 1.5rem;
            --initials-font-size: var(--text-xs);
        }

        /* Medium is the default */
        &[data-size="md"] {
            --avatar-size: 2.5rem;
            --initials-font-size: 1rem;
        }

        &[data-size="lg"] {
            --avatar-size: 7.5rem;
            --initials-font-size: 3rem;
        }

        width: var(--avatar-size);
        height: var(--avatar-size);
        border-radius: var(--rounded-full);
        background: var(--brand-1);
        color: var(--brand-1-content);
        overflow: hidden;
        box-shadow: var(--shadow-sm);

        &[data-avatar-color="gold"] {
            background: var(--brand-1);
            color: var(--brand-1-content);
        }

        &[data-avatar-color="sky"] {
            background: var(--brand-2);
            color: var(--white);
        }

        &[data-avatar-color="teal"] {
            background: var(--brand-3);
            color: var(--white);
        }

        &[data-avatar-color="fuchsia"] {
            background: var(--brand-4);
            color: var(--white);
        }

        &[data-avatar-color="green"] {
            background: var(--success);
            color: var(--darker);
        }

        &[data-avatar-color="blue"] {
            background: var(--info);
            color: var(--white);
        }

        &[data-avatar-color="orange"] {
            background: var(--warning);
            color: var(--darker);
        }

        &[data-avatar-color="red"] {
            background: var(--error);
            color: var(--white);
        }

        .initials {
            font-size: var(--initials-font-size);
            line-height: 1;
        }
    }
    /* Toast
  ---------------------------------- */
    .ui-toast {
        position: fixed;
        display: flex;
        top: 1rem;
        left: 50%;
        transform: translateX(-50%);
        z-index: var(--z-toast);
        align-items: center;
        gap: var(--space-xs);
        min-width: 24rem;
        padding: var(--space-sm) var(--space-sm);
        border-radius: var(--rounded);
        box-shadow: var(--shadow);
        background: var(--darker);
        color: var(--light);
        border-left: 6px solid;
        /* The toast lifecycle includes reading time, so it keeps its 8s duration. */
        animation: ephemeral 8s both;

        svg {
            flex-shrink: 0;
            border-radius: 50%;
        }

        .ui-toast-message {
            flex: 1;
        }

        .ui-toast-status-icon {
            display: none;
        }

        .ui-toast-close {
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            border: none;
            border-radius: 100%;
            width: 1.6rem;
            height: 1.6rem;

            &:hover {
                color: var(--white);
                background-color: var(--black);
            }
        }

        &.ui-toast-success {
            border-left-color: var(--success);

            svg.icon {
                color: var(--success);
            }
        }

        &.ui-toast-error {
            border-left-color: var(--error);

            svg.icon {
                color: var(--error);
            }
        }

        &.ui-toast-warning {
            border-left-color: var(--warning);
        }

        &.ui-toast-offline {
            border-left-color: var(--midtone);
        }
    }

    /* Custom CSS: the PWA toast region is outside <main> and owns the single
       bottom anchor. Prewind cannot express fixed clearance above a sibling
       bar. Pages with no bottom surface use the safe area plus the page
       gutter; only the actual bar/composer :has() rules below read the
       measured --ui-measured-notice-clearance, each with a token/safe-area
       fallback when that measurement is absent. */
    .ui-pwa-toast-region {
        position: fixed;
        right: var(--space-sm);
        bottom: calc(env(safe-area-inset-bottom) + var(--space-md));
        left: var(--space-sm);
        z-index: var(--z-toast);
        max-width: 40rem;
        margin: 0 auto;
        pointer-events: none;
    }

    /* Main primary navigation: shared main bar height plus safe area. */
    .ui-pwa-body:has(.ui-pwa-primary-navigation) .ui-pwa-toast-region {
        bottom: calc(
            var(
                    --ui-measured-notice-clearance,
                    calc(var(--ui-pwa-bottom-bar-height) + env(safe-area-inset-bottom))
                )
                + var(--ui-tap-gap)
        );
    }

    /* Project capture bar: distinct taller bar, which already includes safe area. */
    .ui-pwa-body:has(.ui-project-journal-action-bar) .ui-pwa-toast-region {
        bottom: calc(
            var(--ui-measured-notice-clearance, var(--ui-journal-action-bar-height)) + var(--ui-tap-gap)
        );
    }

    /* Chat composer: measured from the composer itself, falling back to safe area. */
    .ui-pwa-body:has(.ui-project-chat-composer) .ui-pwa-toast-region {
        bottom: calc(var(--ui-measured-notice-clearance, env(safe-area-inset-bottom)) + var(--ui-tap-gap));
    }

    .ui-pwa-toast-region .ui-toast {
        position: relative;
        top: auto;
        right: auto;
        left: auto;
        width: auto;
        min-width: 0;
        margin: 0;
        align-items: flex-start;
        transform: none;
        color: var(--dark);
        background: var(--lighter);
        border: 1px solid var(--light);
        border-left-width: 4px;
        pointer-events: auto;

        .ui-toast-status-icon {
            display: block;
            flex: none;
            width: 0.75rem;
            height: 0.75rem;
            margin-top: 0.3rem;
            border-radius: var(--rounded-full);
            background: currentColor;
            font-size: 0;
        }

        /* The PWA region uses the status dot instead of the desktop glyph. */
        svg.icon {
            display: none;
        }

        .ui-toast-title {
            color: var(--darker);
            font-size: var(--text-sm);
        }

        .ui-toast-message {
            color: var(--midtone);
            font-size: var(--text-sm);
            line-height: 1.4;
        }

        .ui-toast-actions {
            display: flex;
            flex-wrap: wrap;
            justify-content: flex-end;
            gap: var(--space-2xs);
            margin-top: var(--space-xs);
        }

        /* Custom CSS: supported toast text actions need the shared 48px target;
           the recovery warning action keeps its own emphasis. */
        .ui-toast-action {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            width: auto;
            min-height: var(--ui-tap-min);
            margin: 0;
            padding: var(--space-2xs) var(--space-xs);
            border: 0;
            border-radius: var(--rounded);
            font: inherit;
            font-size: var(--text-sm);
            font-weight: var(--font-semibold);
            cursor: pointer;
        }

        .ui-toast-action-secondary {
            color: var(--darker);
            background: transparent;
        }

        .ui-toast-action-warning {
            color: var(--darker);
            background: var(--warning);
        }

        &.ui-toast-success {
            color: var(--success);
            border-left-color: var(--success);
        }

        &.ui-toast-warning {
            color: var(--warning);
            border-left-color: var(--warning);

            .ui-toast-status-icon {
                width: auto;
                height: auto;
                margin-top: 0;
                border-radius: 0;
                background: transparent;
                font-size: var(--text-sm);
                line-height: 1;
            }
        }

        &.ui-toast-error {
            color: var(--error);
            border-left-color: var(--error);
        }

        &.ui-toast-offline {
            color: var(--midtone);
            border-left-color: var(--midtone);
        }
    }

    /* Custom CSS: persistent errors and the requested 48px dismiss target belong to the shared toast. */
    .ui-toast-persistent {
        animation: none;
    }

    .ui-toast .ui-toast-close {
        width: var(--ui-tap-min);
        height: var(--ui-tap-min);
        flex: 0 0 var(--ui-tap-min);
    }

    /* Custom CSS: project identity is a 48px interactive title with its own focus outline. */
    .ui-project-title-trigger {
        min-height: var(--ui-tap-min);
        font: inherit;
    }

    .ui-project-title-trigger:focus-visible {
        outline: var(--border-lg) solid var(--brand-1);
        outline-offset: var(--space-3xs);
    }

    /* Custom CSS: the modal scrim starts below the title row, leaving that row
       undimmed while the native dialog still owns focus and backdrop dismissal. */
    .ui-project-tray-dialog {
        position: fixed;
        top: var(--dialog-anchor-bottom, 0px);
        right: 0;
        bottom: 0;
        left: 0;
        width: 100vw;
        height: calc(100dvh - var(--dialog-anchor-bottom, 0px));
        max-width: none;
        max-height: none;
        margin: 0;
        padding: 0;
        border: none;
        background: rgba(0, 0, 0, 0.5);
        overflow: hidden;
    }

    .ui-project-tray-dialog::backdrop {
        background: transparent;
    }

    /* Custom CSS: the tray panel follows measured title bounds with a viewport
       cap and bottom-only corners; retain its existing 30rem width limit. */
    .ui-form-picker.ui-project-tray {
        position: relative;
        top: 0;
        right: auto;
        bottom: auto;
        left: var(--dialog-anchor-left, 0px);
        width: min(30rem, var(--dialog-anchor-width, 100vw));
        max-height: calc(100dvh - var(--dialog-anchor-bottom, 0px) - max(var(--space-md), env(safe-area-inset-bottom)));
        margin: 0;
        border-radius: 0 0 var(--rounded-lg) var(--rounded-lg);
    }

    /* Custom CSS: retain the project tray's 48px close grip at the bottom. */
    .ui-project-tray .ui-form-picker-dismiss {
        height: var(--ui-tap-min);
        flex: 0 0 var(--ui-tap-min);
    }

    /* Custom CSS: Prewind has no utility for the shared 48px tap minimum, which
       the tray's full-width Forms and Edit rows must match. */
    .ui-project-tray-row {
        min-height: var(--ui-tap-min);
    }

    /* Custom CSS: unread Docs counts share one badge owner, independent of the map's marker geometry. */
    .ui-project-unread-badge {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 1.5em;
        padding: var(--space-3xs) var(--space-2xs);
        border-radius: var(--rounded-full);
        background: var(--darker);
        color: var(--white);
        line-height: 1;
    }

    .ui-project-unread-badge[hidden] {
        display: none;
    }

    /* Dropdown
  ---------------------------------- */
    .ui-dropdown {
        position: relative;
        display: inline-block;

        menu,
        ul {
            position: absolute;
            top: 100%;
            right: 0;
            z-index: var(--z-menu);
            min-width: 12rem;
            margin-top: var(--space-2xs);
            padding: var(--space-2xs);
            background: var(--white);
            border-radius: var(--rounded);
            box-shadow: var(--shadow);
            list-style: none;
            opacity: 0;
            visibility: hidden;
            transform: translateY(-8px);
            transition:
                opacity var(--ui-duration-fast) var(--ui-ease),
                transform var(--ui-duration-fast) var(--ui-ease-move),
                visibility 0s var(--ui-duration-fast);

            li {
                margin: 0;
            }

            a,
            button {
                display: flex;
                align-items: center;
                gap: var(--space-2xs);
                width: 100%;
                padding: var(--space-2xs) var(--space-xs);
                border-radius: var(--rounded-sm);
                text-decoration: none;
                color: var(--darker);
                background: transparent;
                border: none;
                cursor: pointer;
                transition: background-color var(--ui-duration-fast) var(--ui-ease);

                &:hover {
                    background-color: var(--lighter);
                }

                svg {
                    flex-shrink: 0;
                }
            }
        }

        /* Show menu when dropdown is open */
        &.is-open menu,
        &.is-open ul {
            opacity: 1;
            visibility: visible;
            transform: translateY(0);
            transition:
                opacity var(--ui-duration-fast) var(--ui-ease),
                transform var(--ui-duration-fast) var(--ui-ease-move),
                visibility 0s 0s;
        }
    }

    /* Auth Verify OTP Input
  ---------------------------------- */
    .ui-auth-verify {
        display: flex;
        justify-content: center;

        .ui-auth-verify-digits {
            display: flex;
            gap: var(--space-xs);

            input {
                width: var(--ui-tap-min);
                height: var(--ui-tap-write);
                padding: 0;
                font-size: 1.5rem;
                font-weight: 700;
                text-align: center;
                border: var(--border-lg) solid var(--light);
                border-radius: var(--rounded);
                background: var(--white);
                color: var(--darker);
                transition:
                    border-color var(--ui-duration-fast) var(--ui-ease),
                    box-shadow var(--ui-duration-fast) var(--ui-ease);

                &:focus {
                    outline: none;
                    border-color: var(--brand-1);
                    box-shadow: 0 0 0 3px
                        color-mix(in srgb, var(--brand-1) 20%, transparent);
                }

                &::placeholder {
                    color: var(--midtone);
                }
            }
        }
    }

    /* Custom CSS: Prewind has no square size using the shared height token for
       organization logo previews in desktop and PWA settings. */
    .ui-organization-logo-preview {
        width: var(--height-md);
        height: var(--height-md);
    }

    /* Shared form logo
   ---------------------------------- */
    .ui-form-logo {
        width: 9rem;
        max-width: 100%;
    }

    .ui-form-logo img {
        display: block;
        width: 100%;
        height: auto;
    }

    /*
      SECTION: Dialogs, project form modal layout, and maps
      Dialog shells, project form modal grids, shared project map frames,
      and common Google Maps marker/status affordances.
    */

    /* Dialog
   ---------------------------------- */
    .ui-dialog {
        border: none;
        border-radius: var(--rounded);
        padding: 0;
        margin: auto;
        max-width: calc(100vw - 2rem);
        max-height: calc(100dvh - 2rem);
        overflow: hidden;
        background: var(--white);
        box-shadow: var(--shadow-lg);

        &::backdrop {
            background: rgba(0, 0, 0, 0.5);
        }
    }

    .ui-project-dialog {
        width: min(1120px, calc(100vw - 2rem));
    }

    .ui-dialog-sheet {
        width: min(26rem, calc(100vw - 1rem));
    }

    /* Custom CSS: Prewind lacks the sheet's viewport limits, open-only layout,
       and safe-area inset. Keep the existing shape and row separators. */
    .ui-form-picker {
        position: fixed;
        top: auto;
        right: 0;
        bottom: 0;
        left: 0;
        width: min(30rem, 100vw);
        max-width: 100vw;
        max-height: calc(100dvh - var(--space-md));
        margin: 0 auto;
        border-radius: var(--rounded-lg) var(--rounded-lg) 0 0;
    }

    .ui-form-picker[open],
    .ui-project-tray-dialog[open] .ui-project-tray {
        display: flex;
        flex-direction: column;
    }

    .ui-form-picker > h2 {
        /* Preserve the heading's 1.2 line height; leading-tight is 1.25. */
        line-height: 1.2;
    }

    .ui-form-picker > ul {
        padding-bottom: max(var(--space-sm), env(safe-area-inset-bottom));
    }

    .ui-form-picker > ul > li + li {
        border-top: var(--border) solid var(--light);
    }

    /* Custom CSS: the Forms picker needs a 48px drag target and 54x5px grip,
       which have no exact Prewind sizes; touch-action applies only to its handle. */
    [data-controller~="form-picker"] > .ui-form-picker-dismiss {
        min-height: var(--ui-tap-min);
        touch-action: none;
        user-select: none;
        cursor: grab;
    }

    .ui-form-picker-dismiss { height: 1.75rem; }

    .ui-form-picker-dismiss::before {
        width: 2.5rem;
        height: 0.25rem;
        border-radius: var(--rounded-full);
        background: var(--light);
        content: "";
    }

    [data-controller~="form-picker"] > .ui-form-picker-dismiss::before { width: 54px; height: 5px; background: var(--midtone); }

    /* Custom CSS: preserve row height and link states without Prewind equivalents. */
    .ui-form-picker-option {
        min-height: 4.5rem;
        -webkit-tap-highlight-color: transparent;
    }

    a.ui-form-picker-option:active {
        background: var(--lighter);
    }

    a.ui-form-picker-option:focus-visible {
        outline: 2px solid var(--darker);
        outline-offset: -2px;
    }

    /* Custom CSS: preserve the existing icon size outside Prewind's sizing scale. */
    .ui-form-picker-icon {
        width: 2.75rem;
        height: 2.75rem;
    }

    /* Custom CSS: Prewind has no text-xs utility for the compact picker badge. */
    .ui-form-picker-badge {
        font-size: var(--text-xs);
        line-height: 1;
    }

    .ui-quick-note-dialog {
        width: min(32rem, calc(100vw - 1rem));
    }

    .ui-member-removal-dialog {
        width: min(var(--max-w-form), calc(100vw - 1rem));
    }

    .ui-support-dialog {
        width: min(42rem, calc(100vw - 1rem));
    }

    .ui-equipment-dialog,
    .ui-vehicle-dialog {
        width: min(var(--max-w-form), calc(100vw - 1rem));
    }

    .ui-equipment-dialog-body,
    .ui-vehicle-dialog-body {
        max-height: calc(100dvh - 8rem);
        overflow-y: auto;
        padding: var(--space-md);
    }

    .ui-quick-note-dialog-body {
        max-height: calc(100dvh - 7rem);
        overflow-y: auto;
        padding: var(--space-md);
    }

    .ui-member-removal-dialog-shell {
        max-height: calc(100dvh - 2rem);
        min-height: 0;
    }

    .ui-member-removal-dialog-body {
        flex: 1 1 auto;
        min-height: 0;
        overflow-y: auto;
        padding: var(--space-md);
        padding-bottom: var(--space-md);
    }

    .ui-support-dialog-body {
        max-height: calc(100dvh - 7rem);
        overflow-y: auto;
        padding: var(--space-md);
    }

    .ui-project-modal-shell {
        width: 100%;
        height: min(52rem, calc(100dvh - 2rem));
        max-height: calc(100dvh - 2rem);
        display: flex;
        flex-direction: column;
        overflow: hidden;
    }

    .ui-project-form-layout {
        display: grid !important;
        grid-template-columns: minmax(0, 1fr) minmax(24rem, 28rem);
        flex-direction: unset !important;
        gap: 0;
        max-width: none !important;
        width: 100%;
        min-height: 0;
        align-items: stretch;
    }

    .ui-project-form-layout-modal {
        flex: 1 1 auto;
        overflow: hidden;
    }

    .ui-project-form-panel {
        padding: var(--space-md) var(--space-lg);
        min-width: 0;
    }

    .ui-project-form-layout-modal .ui-project-form-panel {
        overflow-y: auto;
    }

    .ui-project-form-map-panel {
        position: relative;
        padding: var(--space-md);
        border-left: 1px solid var(--light);
        background: var(--lighter);
        display: flex;
        flex-direction: column;
        gap: var(--space-xs);
        min-width: 0;
        min-height: 0;
    }

    .ui-project-map-frame {
        position: relative;
        flex: 1 1 auto;
        min-height: 24rem;
    }

    .ui-project-map-canvas {
        position: absolute;
        inset: 0;
        border-radius: var(--rounded-sm);
        overflow: hidden;
        background: var(--light);
    }

    /* Custom CSS: the map overlay owns absolute centering; Prewind has no
       text-xs utility, so the light chip keeps its scoped font-size. */
    .ui-map-status-chip {
        position: absolute;
        top: var(--space-sm);
        left: 50%;
        transform: translateX(-50%);
        z-index: calc(var(--z-raised) + 1);
        padding: var(--space-2xs) var(--space-sm);
        border-radius: var(--rounded-full);
        background: var(--white);
        color: var(--darker);
        font-size: var(--text-xs);
        font-weight: var(--font-semibold);
        box-shadow: var(--shadow);
    }

    .ui-user-location-marker {
        box-sizing: border-box;
        position: relative;
        width: 1.125rem;
        height: 1.125rem;
        border: 2px solid var(--white);
        border-radius: var(--rounded-full);
        background: var(--info);
        box-shadow:
            0 0 0 1px color-mix(in srgb, var(--info) 35%, transparent),
            var(--shadow-sm);
        pointer-events: none;
    }

    .ui-user-location-marker::after {
        content: "";
        position: absolute;
        inset: -0.375rem;
        border: 1px solid color-mix(in srgb, var(--info) 40%, transparent);
        border-radius: var(--rounded-full);
    }

    /* Custom CSS: share the existing 1.5rem numbered circle across Gallery,
       project cards and document counts. Prewind lacks this exact size and a
       text-xs utility. Preserve native hiding despite inline-flex. */
    .ui-project-map-reference {
        box-sizing: border-box;
        display: inline-flex;
        width: 1.5rem;
        height: 1.5rem;
        align-items: center;
        justify-content: center;
        border: 1px solid var(--white);
        border-radius: var(--rounded-full);
        background: var(--brand-1);
        color: var(--black);
        font-family: var(--font-body);
        font-size: var(--text-xs);
        font-weight: var(--font-bold);
        line-height: 1;
        box-shadow: var(--shadow-sm);
    }

    .ui-project-map-reference[hidden] {
        display: none;
    }

    .ui-map-empty-card {
        width: min(26rem, 100%);
        padding: var(--space-md);
        border-radius: var(--rounded);
        text-align: center;
        background: rgb(255 255 255 / 94%);
        box-shadow: var(--shadow);
    }

    .ui-map-warning-banner {
        padding: 0.7rem 0.9rem;
        border-radius: var(--rounded-sm);
        background: color-mix(in srgb, var(--warning) 14%, var(--white));
        border: 1px solid color-mix(in srgb, var(--warning) 28%, transparent);
        color: var(--darker);
        box-shadow: var(--shadow-sm);
    }

    /*
      SECTION: Desktop project workspaces
      Desktop project tabs, overview, journal, and forms split-pane layouts.
    */

    /* Desktop project header
    ---------------------------------- */
    .ui-project-desktop-tab,
    .ui-inventory-desktop-tab {
        transition: color var(--ui-duration-fast) var(--ui-ease);
    }

    .ui-project-desktop-tab::after,
    .ui-inventory-desktop-tab::after {
        content: "";
        position: absolute;
        right: 0;
        bottom: calc(var(--border) * -1);
        left: 0;
        height: 3px;
        background: transparent;
        transition: background var(--ui-duration-fast) var(--ui-ease);
    }

    .ui-project-desktop-tab:hover,
    .ui-project-desktop-tab.is-active,
    .ui-inventory-desktop-tab:hover,
    .ui-inventory-desktop-tab.is-active {
        color: var(--darker);
    }

    .ui-project-desktop-tab.is-active::after,
    .ui-inventory-desktop-tab.is-active::after {
        background: var(--brand-1);
    }

    /* Custom CSS: Prewind has no hairline border-color utility; shared desktop
       headers use the same divider, including both sides of project tabs. */
    .ui-admin-shell-header,
    .ui-project-desktop-header {
        border-bottom-color: var(--hairline);
    }

    .ui-project-desktop-tabs {
        border-top-color: var(--hairline);
    }

    /* Desktop project overview
    ---------------------------------- */
    .ui-project-overview-workspace {
        display: grid;
        grid-template-columns: minmax(0, 1.15fr) minmax(20rem, 0.85fr);
        align-items: stretch;
    }

    .ui-project-overview-stats {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .ui-project-overview-stat:hover {
        border-color: var(--brand-1);
    }

    .ui-project-overview-activity {
        grid-column: 1 / -1;
    }

    .ui-project-overview-map-canvas {
        min-height: 22rem;
    }

    .ui-project-overview-activity-icon,
    .ui-project-overview-activity-thumbnail {
        width: 2.5rem;
        height: 2.5rem;
    }

    @media (max-width: 900px) {
        .ui-project-overview-workspace,
        .ui-project-overview-stats {
            grid-template-columns: minmax(0, 1fr);
        }
    }

    /* Desktop project journal
    ---------------------------------- */
    .ui-project-journal-workspace {
        --ui-project-journal-sticky-offset: var(--space-sm);
        display: grid;
        grid-template-columns: minmax(28rem, 3fr) minmax(20rem, 2fr);
        align-items: start;
    }

    .ui-project-journal-map-column {
        position: sticky;
        top: var(--ui-project-journal-sticky-offset);
        min-height: 24rem;
        height: calc(100dvh - 10rem);
    }

    .ui-workspace-detail-frame {
        display: block;
        min-width: 0;
    }

    @media (max-width: 1200px) {
        .ui-project-journal-workspace {
            grid-template-columns: minmax(0, 1fr);
        }

        .ui-project-journal-map-column {
            position: static;
            height: min(50dvh, 24rem);
        }
    }

    /* Desktop team tables */
    .ui-team-table th {
        background: var(--darker);
        color: var(--white);
    }

    /* Desktop equipment tables */
    .ui-equipment-table {
        table-layout: fixed;
    }

    .ui-equipment-table th:last-child,
    .ui-equipment-table td:last-child {
        width: var(--ui-tap-min);
    }

    .ui-vehicle-table {
        min-width: 60rem;
    }

    .ui-vehicle-table th:last-child,
    .ui-vehicle-table td:last-child {
        width: var(--ui-tap-min);
    }

    .ui-team-invite-role-toggle {
        display: flex;
        flex-direction: column;
        gap: var(--space-2xs);
    }

    .ui-team-invite-role-toggle legend {
        padding-bottom: 0;
        font-weight: var(--font-semibold);
    }

    .ui-team-invite-role-toggle .ui-toggle {
        --toggle-width: 3.25rem;
        --toggle-height: 1.75rem;
        --toggle-padding: 0.2rem;
        --toggle-off-bg: var(--light);
        gap: 0;
    }

    /* Desktop project forms
    ---------------------------------- */
    .ui-project-forms-workspace {
        --ui-project-forms-sticky-offset: var(--space-sm);
        display: grid;
        grid-template-columns: minmax(0, 3fr) minmax(20rem, 2fr);
        align-items: start;
    }

    .ui-project-forms-map-column {
        position: sticky;
        top: var(--ui-project-forms-sticky-offset);
        min-height: 24rem;
        height: calc(100dvh - 10rem);
    }

    .ui-project-forms-table {
        table-layout: fixed;
    }

    .ui-project-forms-table th:first-child,
    .ui-project-forms-table td:first-child {
        width: 40%;
        white-space: normal;
    }

    .ui-project-forms-table td {
        vertical-align: middle;
    }

    .ui-project-forms-table tbody tr:hover {
        background: var(--lighter);
    }

    /* Custom CSS: organization history has six columns instead of the project
       table's wide form column. Prewind has no table-layout utility. */
    .ui-forms-history-table {
        table-layout: auto;
    }

    .ui-forms-history-table th:first-child,
    .ui-forms-history-table td:first-child {
        width: auto;
    }

    .ui-project-forms-table-link:hover .ui-project-forms-row-title {
        color: var(--brand-2);
    }

    @media (max-width: 900px) {
        .ui-project-forms-workspace {
            grid-template-columns: minmax(0, 1fr);
        }

        .ui-project-forms-map-column {
            position: static;
            height: min(50dvh, 24rem);
        }
    }

    /*
      SECTION: PWA header and navigation tabs
      Shared mobile app header controls and tab treatment.
    */

    /* PWA Header + Tabs
    ---------------------------------- */
    /* Custom CSS: the shared grid needs safe-area insets, the specified 64px
       header / 48px controls, and the half-icon inset that puts the visible 24px
       glyph edge (not the 48px target) on the one page gutter. */
    .ui-pwa-header-bar {
        --ui-header-icon-inset: calc((var(--ui-tap-min) - 1.5rem) / 2);
        display: grid;
        grid-template-columns: var(--ui-tap-min) minmax(0, 1fr) var(--ui-tap-min);
        height: 4rem;
        align-items: center;
        min-width: 0;
        padding-left: max(var(--space-md), env(safe-area-inset-left));
        padding-right: max(var(--space-md), env(safe-area-inset-right));
    }

    /* Custom CSS: Prewind has no `hairline` border-colour utility; every shared
       header control row (controls, tabs, toolbar) carries the guide's 1px
       --hairline divider. */
    .ui-pwa-header-bar,
    .ui-pwa-header-tabs,
    .ui-pwa-header-toolbar {
        border-bottom-color: var(--hairline);
    }

    .ui-pwa-header-bar-multiple-right-actions {
        grid-template-columns: 6rem minmax(0, 1fr) 6rem;
    }

    .ui-pwa-header-action {
        display: flex;
        align-items: center;
        min-width: 0;
    }

    /* Custom CSS: plain 24px glyphs sit inside 48px targets, so the target pulls
       out by the half-icon inset to land the glyph edge on the gutter. The gold
       Add circle is its own visible edge, so it stays flush; a text control
       aligns by its own inline padding. */
    .ui-pwa-header-action-left {
        justify-content: flex-start;
        margin-left: calc(var(--ui-header-icon-inset) * -1);
    }

    .ui-pwa-header-action-left:has(.ui-pwa-header-control-textual) {
        margin-left: calc(var(--space-xs) * -1);
    }

    .ui-pwa-header-action-right {
        justify-content: flex-end;
        margin-right: calc(var(--ui-header-icon-inset) * -1);
    }

    .ui-pwa-header-action-right:has(.ui-pwa-header-primary-action) {
        margin-right: 0;
    }

    .ui-pwa-header-action-right:has(.ui-pwa-header-control-textual) {
        margin-right: calc(var(--space-xs) * -1);
    }

    .ui-pwa-header-title {
        min-width: 0;
        max-width: 100%;
    }

    .ui-pwa-header-control {
        width: var(--ui-tap-min);
        height: var(--ui-tap-min);
        flex: 0 0 var(--ui-tap-min);
        padding: 0;
        border: 0;
        appearance: none;
        background: transparent;
        font: inherit;
        line-height: 1;
    }

    .ui-pwa-header-primary-action {
        width: var(--ui-tap-min);
        height: var(--ui-tap-min);
        flex: 0 0 var(--ui-tap-min);
    }

    .ui-pwa-header-control svg {
        flex-shrink: 0;
    }

    .ui-pwa-header-control-textual {
        width: auto;
        height: var(--ui-tap-min);
        min-width: 0;
        flex: 0 1 auto;
        gap: var(--space-2xs);
        padding: 0 var(--space-xs);
        font-size: var(--text-base);
        font-weight: var(--font-bold);
        line-height: 1;
        white-space: nowrap;
    }

    .ui-pwa-header-control-icon {
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    .ui-pwa-header-control-text {
        display: block;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .ui-pwa-header-control-icon.hidden,
    .ui-pwa-header-control-text.hidden {
        display: none;
    }

    /* Custom CSS: the current tab's gold underline is a pseudo-element Prewind
       cannot express; its requested 3px derives from the existing 1px + 2px
       border tokens, and it never carries the state alone (the label is bold). */
    .ui-pwa-tab {
        min-height: var(--ui-tap-min);
        -webkit-tap-highlight-color: transparent;
        transition:
            color var(--ui-duration-fast) var(--ui-ease),
            background var(--ui-duration-fast) var(--ui-ease);

        &.active::after {
            content: "";
            position: absolute;
            bottom: 0;
            left: 0;
            right: 0;
            height: calc(var(--border) + var(--border-lg));
            background: var(--brand-1);
        }
    }

    /*
      SECTION: Guides and report inputs
      Field code reference UI and report photo grids.
    */

    /* Field code guide
    ---------------------------------- */
    .ui-field-code-category-track {
        scrollbar-width: none;
        -webkit-overflow-scrolling: touch;

        &::-webkit-scrollbar {
            display: none;
        }
    }

    /* Custom CSS: the existing category count owns its compact circle and active
       state; Prewind has no text-xs utility. */
    .ui-field-code-category-chip {
        line-height: 1;

        .count {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            padding-left: 10px;
            padding-right: 10px;
            min-width: 1.35rem;
            height: 1.35rem;
            border-radius: var(--rounded-full);
            color: var(--white);
            background: var(--darker);
            font-size: var(--text-xs);
            line-height: 1;
        }

        &.is-active {
            .count {
                color: var(--brand-1);
            }
        }
    }

    .ui-field-code-table-wrap {
        -webkit-overflow-scrolling: touch;
    }

    .ui-field-code-table {
        min-width: 42rem;
        border-collapse: collapse;

        th,
        td {
            padding: var(--space-xs) var(--space-md);
            border-bottom: 1px solid var(--light);
            text-align: left;
            vertical-align: top;
        }

        /* Custom CSS: the field-code table shares compact headings across columns;
           Prewind has no text-xs utility. */
        th {
            color: var(--midtone);
            background: var(--lighter);
            font-size: var(--text-xs);
            font-weight: var(--font-heavy);
            letter-spacing: 0.04em;
        }

        tbody tr:last-child td {
            border-bottom: 0;
        }

        .code {
            width: 5rem;
            font-weight: var(--font-heavy);
            white-space: nowrap;
        }
    }

    /* Report forms
    ---------------------------------- */
    .ui-report-photo-grid {
        display: grid;
        grid-template-columns: repeat(5, minmax(0, 1fr));
    }

    /*
      SECTION: Shared inventory and capture controls
      Shared section primitives, vehicle inventory, camera queue, and notes.
    */

    /* Shared inventory flow
    ---------------------------------- */

    /* Shared section primitives.
       - .ui-section-panel: vertical stack with a 1px hairline separator strip
         between rows (achieved via gap on a tinted bg) and top/bottom borders.
       - .ui-section-list: same hairline-separator strip without the borders.
       - .ui-section-label: typographic style for small section headings.
         Combine with utilities like `bg-white px-md py-xs` to create a panel
         header row. */
    .ui-section-panel {
        display: flex;
        flex-direction: column;
        gap: 1px;
        background: var(--light);
        border-top: 1px solid var(--light);
        border-bottom: 1px solid var(--light);
    }

    .ui-section-list {
        display: flex;
        flex-direction: column;
        gap: 1px;
        background: var(--light);
    }

    .ui-section-label {
        color: var(--darker);
        font-size: var(--text-sm);
        font-weight: var(--font-heavy);
        letter-spacing: 0.04em;
    }

    /* Reusable bottom spacing for PWA screens with a fixed primary action. */
    .ui-pwa-fixed-cta-space {
        padding-bottom: calc(env(safe-area-inset-bottom) + var(--ui-tap-min));
    }

    /* Reusable fixed bottom action for full-bleed PWA flows. */
    .ui-pwa-fixed-cta {
        position: fixed;
        left: var(--space-md);
        right: var(--space-md);
        bottom: calc(env(safe-area-inset-bottom) + 1rem);
        width: auto;
        z-index: var(--z-bar);
    }

    /* Inventory rows used inside equipment and vehicle lists. */
    .ui-instrument-row,
    .ui-vehicle-row {
        background: var(--white);
        transition: background var(--ui-duration-fast) var(--ui-ease);

        .button {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: var(--space-sm);
            width: 100%;
            padding: var(--space-xs) var(--space-md);
            color: inherit;
            text-align: left;
        }

        .main {
            display: flex;
            align-items: center;
            gap: var(--space-sm);
            min-width: 0;
            flex: 1;
        }

        .copy {
            display: flex;
            flex-direction: column;
            gap: 0.08rem;
            min-width: 0;
            flex: 1;
        }

        .serial {
            color: var(--midtone);
            font-size: var(--text-base);
            line-height: 1.1;
        }

        .status {
            font-size: var(--text-base);
            font-weight: 700;
            line-height: 1.1;
        }

        /* Custom CSS: the existing selection control owns its circular checkmark
           and selected states; Prewind has no text-xs utility. */
        .control {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            width: 1.5rem;
            height: 1.5rem;
            border: 1.5px solid var(--midtone);
            border-radius: var(--rounded-full);
            color: transparent;
            font-size: var(--text-xs);
            font-weight: var(--font-heavy);
            flex-shrink: 0;
            transition:
                border-color var(--ui-duration-fast) var(--ui-ease),
                background var(--ui-duration-fast) var(--ui-ease),
                color var(--ui-duration-fast) var(--ui-ease);
        }

        &.is-selected {
            background: color-mix(in srgb, var(--brand-1) 10%, var(--white));

            .control {
                border-color: var(--brand-1);
                background: var(--white);
                color: var(--brand-1);
            }
        }
    }

    /* Custom CSS: inventory initials share one icon container; Prewind has no
       text-xs utility for its compact label. */
    .ui-instrument-icon,
    .ui-vehicle-icon {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 2rem;
        height: 2rem;
        border-radius: var(--rounded-sm);
        background: var(--lighter);
        color: var(--darker);
        font-size: var(--text-xs);
        font-weight: var(--font-heavy);
        letter-spacing: 0.03em;
        flex-shrink: 0;
    }

    .ui-instrument-svg-icon {
        display: block;
        width: auto;
        height: 1.35rem;
        max-width: 1.45rem;
        color: var(--darker);
    }

    .ui-instrument-name,
    .ui-vehicle-name {
        color: var(--darker);
        font-size: var(--text-base);
        font-weight: var(--font-heavy);
        line-height: 1.1;
    }

    /* Custom CSS: the modal camera needs a full dynamic viewport and its own
       safe-area inset, independent of the scrolling page that opens it. */
    .ui-camera-overlay {
        box-sizing: border-box;
        height: 100dvh;
        max-height: 100dvh;
        padding-top: env(safe-area-inset-top);
    }

    /* Custom CSS: the camera title is now a semantic heading; retain the
       inherited line height of the previous div instead of global h2 leading. */
    .ui-camera-overlay .ui-pwa-header-title {
        line-height: inherit;
    }

    /* Custom CSS: capture controls require the shared 48px touch target;
       Prewind has no size utility bound to --ui-tap-min. */
    .ui-capture-action { min-width: var(--ui-tap-min); min-height: var(--ui-tap-min); }
    /* Custom CSS: capture write controls use the shared 56px write floor.
       Prewind has no utility bound to --ui-tap-write; ordinary read controls
       keep the 48px floor above. */
    .ui-capture-action-write { min-height: var(--ui-tap-write); }
    /* Custom CSS: the shared capture bar uses a specified 1.75rem thumbnail box; the Gallery
       queue tile must fill it without its own border, radius or shadow. */
    .ui-capture-last-photo { width: 1.75rem; height: 1.75rem; }
    .ui-capture-last-photo .ui-camera-photo-queue-tile {
        width: 100%;
        height: 100%;
        border: 0;
        border-radius: 0;
        box-shadow: none;
    }
    .ui-capture-last-photo .ui-camera-photo-queue-tile:not(:last-child) {
        display: none;
    }

    /* Custom CSS: live video needs a contrast gradient; note controls must
       clear the raised shutter, and the thumbnail count overlaps its corner. */
    .ui-capture-camera-context {
        background: linear-gradient(color-mix(in srgb, var(--black) 65%, transparent), transparent);
        padding-bottom: var(--space-lg);
    }

    .ui-capture-camera-notes {
        margin-bottom: calc(var(--space-lg) + var(--space-sm));
    }

    .ui-capture-photo-count {
        top: calc(-1 * var(--space-xs));
        right: calc(-1 * var(--space-xs));
        font-size: var(--text-xs);
    }

    /* Custom CSS: native hidden state must win over utility display rules
       for optional feedback, retry and last-photo controls. */
    .ui-camera-overlay [hidden],
    .ui-camera-review [hidden],
    .ui-quick-note-camera-controls [hidden],
    .ui-capture-note-sheet [hidden] {
        display: none !important;
    }

    /* Custom CSS: the thumbnail and Undo label are one focusable touch target. */
    .ui-capture-undo:focus-visible {
        outline: var(--ui-field-focus-outline) var(--ui-field-focus-color);
        outline-offset: var(--space-2xs);
    }

    /* Custom CSS: cap the sheet to the dynamic viewport and add breathing room
       above the iPhone safe area. Its body scrolls independently of the footer. */
    .ui-capture-note-sheet[open] {
        display: flex;
        flex-direction: column;
        gap: var(--space-xs);
        max-height: calc(100dvh - var(--space-lg));
        overflow: hidden;
        padding-bottom: calc(var(--space-md) + env(safe-area-inset-bottom));
    }

    /* Custom CSS: Prewind has no token-sized width/height utilities for the
       note sheet's compact photo context. Ordinary layout stays in the view. */
    .ui-capture-note-thumbnail {
        width: var(--space-xl);
        height: var(--space-xl);
    }

    .ui-camera-photo-queue-tile {
        width: 1.35rem;
        height: 1.35rem;
        flex: 0 0 auto;
        overflow: hidden;
        border: 1px solid color-mix(in srgb, var(--white) 78%, transparent);
        border-radius: var(--rounded-sm);
        background: color-mix(in srgb, var(--white) 24%, transparent);
        box-shadow: 0 0 0 1px color-mix(in srgb, var(--black) 24%, transparent);
    }

    .ui-camera-photo-queue-image {
        display: block;
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

    .ui-camera-photo-queue-tile.is-new {
        animation: ui-camera-photo-queue-pop var(--ui-duration-fast) var(--ui-ease-move);
    }

    .ui-field-notes-textarea {
        min-height: 7.5rem;
        font-size: 20px;
    }

    .ui-quick-note-point-input {
        box-sizing: border-box;
        font-size: 20px;
    }

    .ui-quick-note-point-input:focus {
        border-color: var(--ui-field-focus-color);
        outline: var(--ui-field-focus-outline) var(--ui-field-focus-color);
        outline-offset: 0;
    }

    .ui-quick-note-tags-field {
        min-width: 0;
        margin: 0;
        padding: 0;
        border: 0;
    }

    .ui-quick-note-tag-options {
        display: flex;
        flex-wrap: wrap;
        gap: var(--space-xs);
    }

    .ui-quick-note-tag-option {
        position: relative;
        display: inline-flex;
        cursor: pointer;
        touch-action: manipulation;
        -webkit-tap-highlight-color: transparent;

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

        span {
            display: inline-flex;
            min-height: var(--ui-field-height);
            align-items: center;
            justify-content: center;
            padding: var(--space-2xs) var(--space-sm);
            border: 1px solid var(--light);
            border-radius: var(--rounded);
            background: var(--white);
            color: var(--dark);
            font-size: var(--text-sm);
            font-weight: var(--font-bold);
            line-height: 1;
            transition:
                border-color var(--ui-duration-fast) var(--ui-ease),
                background-color var(--ui-duration-fast) var(--ui-ease),
                color var(--ui-duration-fast) var(--ui-ease);
        }

        input:checked + span {
            border-color: var(--brand-1);
            background: var(--brand-1);
            color: var(--darker);
        }

        input:focus-visible + span {
            outline: var(--ui-field-focus-outline) var(--ui-field-focus-color);
            outline-offset: 2px;
        }
    }

    /* Custom CSS: Prewind lacks touch controls, checkbox sibling focus states
       and minimum height using the shared form-control token. Layout uses
       utilities; selected states override utilities in @layer components. */
    .ui-projects-filter-chip {
        touch-action: manipulation;
        -webkit-tap-highlight-color: transparent;

        .ui-projects-filter-chip-label {
            min-height: var(--ui-field-height);
        }

        input:focus-visible + .ui-projects-filter-chip-label {
            outline: var(--ui-focus-ring);
            outline-offset: var(--ui-focus-offset);
        }
    }

    @media (prefers-reduced-motion: reduce) {
        .ui-quick-note-tag-option span {
            transition: none;
        }
    }

    .ui-speech-dictation-waveform {
        width: calc(var(--space-lg) + var(--space-xs));
        height: calc(var(--space-md) + var(--space-2xs));
        gap: var(--space-3xs);
    }

    .ui-speech-dictation-waveform-bar {
        width: var(--space-3xs);
        height: 100%;
        border-radius: var(--rounded-full);
        background: var(--error);
        transform: scaleY(0.2);
        transform-origin: center;
        transition: transform var(--ui-duration-fast) var(--ui-ease-move);
        will-change: transform;
    }

    .ui-speech-dictation-waveform.is-listening
        .ui-speech-dictation-waveform-bar {
        background: var(--error);
    }

    .ui-speech-dictation-spinner {
        width: calc(var(--space-lg) + var(--space-sm));
        height: calc(var(--space-lg) + var(--space-sm));
        border: var(--border-lg) solid var(--dark);
        border-right-color: var(--brand-1);
        border-bottom-color: var(--brand-1);
        border-radius: var(--rounded-full);
        animation: ui-speech-dictation-spin var(--ui-duration-spin) linear infinite;
    }

    .ui-quick-note-dictation-state {
        box-sizing: border-box;
    }

    /* Custom CSS: keep Journal draft actions above the existing 6.25rem bar
       and 1.375rem raised microphone; viewport limits need a scoped rule. */
    .ui-quick-note-capture-recovery {
        position: absolute;
        right: var(--space-sm);
        bottom: var(--ui-journal-footer-space);
        left: var(--space-sm);
        z-index: var(--z-bar);
        box-sizing: border-box;
        max-height: 50%;
        overflow-y: auto;
    }

    .ui-quick-note-dictation-spinner {
        width: var(--space-md);
        height: var(--space-md);
        border-width: var(--border-sm);
    }

    @media (prefers-reduced-motion: reduce) {
        .ui-speech-dictation-waveform-bar {
            transition: none;
        }

        .ui-speech-dictation-spinner {
            animation: none;
        }
    }

    /*
      SECTION: Field cards, journal, and forms
      Journal cards, form cards, and shared detail panels.
    */

    .ui-journal-card {
        /* global */
        --border-color: var(--light);

        background: var(--white);
        border-radius: var(--rounded);
        border: 1px solid var(--border-color);
        overflow: hidden;

        header {
            display: flex;
            background: var(--lighter);
            padding: var(--space-xs) var(--space-sm);
            justify-content: space-between;
            overflow: hidden;
            border-bottom: 1px solid var(--border-color);

            .title {
                font-weight: var(--font-bold);
                color: var(--darker);
            }

            .edit {
                display: flex;
                align-items: center;
                color: var(--dark);
            }

            a {
                display: flex;
                align-items: center;
                gap: var(--space-2xs);

                /* Remove text decoration */
                min-width: 0;
                color: inherit;
                text-decoration: none;
            }
        }

        .row {
            display: flex;
            flex-direction: column;
            gap: var(--space-2xs);
            padding: var(--space-xs) var(--space-sm);
            border-bottom: 1px solid var(--border-color);
            text-decoration: none;

            span:first-child {
                color: var(--dark);
                font-weight: var(--font-heavy);
                line-height: 1.1;
            }

            span:last-child {
                color: var(--midtone);
                line-height: 1.1;
                overflow-wrap: anywhere;
            }
        }

        .photo-preview {
            display: grid;
            grid-template-columns: repeat(4, minmax(0, 1fr));
            justify-content: start;
            gap: var(--space-xs);
            padding: var(--space-sm);
            color: inherit;
            text-decoration: none;
            border-bottom: 1px solid var(--border-color);
        }

        .photo-overflow {
            aspect-ratio: 1;
            display: flex;
            align-items: center;
            justify-content: center;
            overflow: hidden;
            color: var(--darker);
            background: var(--light);
            border-radius: var(--rounded-sm);
            font-weight: var(--font-heavy);
        }

        footer {
            display: grid;
            grid-template-columns: minmax(0, 1fr) auto;
            align-items: center;
            gap: var(--space-xs);
            padding: var(--space-xs) var(--space-sm);
            color: var(--midtone);
        }

        footer span:first-child {
            min-width: 0;
            overflow-wrap: anywhere;
        }

        footer span:last-child {
            text-align: right;
            white-space: nowrap;
        }

        .action-row {
            display: flex;
            align-items: center;
            justify-content: flex-end;
            padding: var(--space-xs) var(--space-sm);
            color: inherit;
            text-decoration: none;
            border-bottom: 1px solid var(--border-color);
        }

        .action-row:active {
            background: var(--lighter);
        }
    }

    /* Journal index cards */
    .ui-journal-card.ui-journal-card-index {
        /* Keep multi-photo entries compact at every card width. */
        --ui-journal-photo-row-height: 112px;
        border-radius: var(--rounded-lg);
    }

    .ui-journal-card.ui-journal-card-index .ui-journal-card-summary-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-sm);
        padding: var(--space-sm) var(--space-sm) 0;
        border: 0;
        background: var(--white);
    }

    .ui-journal-card.ui-journal-card-index .ui-journal-card-summary-link {
        display: flex;
        width: 100%;
        align-items: center;
        flex-wrap: wrap;
        gap: var(--space-2xs);
    }

    .ui-journal-chip {
        display: inline-flex;
        min-width: 0;
        align-items: center;
        gap: var(--space-xs);
        padding: var(--space-2xs) var(--space-xs);
        border: 1px solid transparent;
        border-radius: var(--rounded-full);
        background: var(--lighter);
        color: var(--dark);
        font-size: var(--text-sm);
        font-weight: var(--font-normal);
        line-height: 1;
        white-space: nowrap;
    }

    .ui-journal-chip svg {
        flex: 0 0 auto;
    }

    .ui-journal-chip-capture,
    .ui-journal-chip-point,
    .ui-journal-chip-pending {
        background: var(--warning-light);
        color: var(--warning);
    }

    .ui-journal-chip-control {
        background: var(--success-lighter);
        color: var(--success);
    }

    .ui-journal-chip-form {
        background: var(--info-light);
        color: var(--info);
    }

    .ui-journal-chip-incident {
        background: var(--error-light);
        color: var(--error);
    }

    .ui-journal-chip-structural {
        background: var(--lighter);
        color: var(--darker);
    }

    .ui-journal-chip-subtle {
        background: var(--lighter);
        color: var(--midtone);
    }

    .ui-journal-chip-outline {
        border-color: var(--light);
        border-radius: var(--rounded-sm);
        background: var(--white);
        color: var(--dark);
    }

    .ui-journal-chip-selected {
        border-color: var(--brand-1);
        border-radius: var(--rounded-sm);
        background: var(--brand-1);
        color: var(--brand-1-content);
    }

    .ui-journal-chip-label {
        font-weight: var(--font-bold);
    }

    .ui-journal-ai-transcription {
        padding: var(--space-2xs) var(--space-xs);
        border-radius: var(--rounded-full);
        background: color-mix(in srgb, var(--ai-transcription) 10%, var(--white));
        color: var(--ai-transcription);
    }

    .ui-journal-subtag {
        border-radius: var(--rounded-sm);
    }

    .ui-journal-tag {
        display: inline-flex;
        min-width: 0;
        align-items: center;
        padding: var(--space-2xs) var(--space-xs);
        border-radius: var(--rounded);
        background: var(--brand-1);
        color: var(--brand-1-content);
        font-size: var(--text-sm);
        font-weight: 600;
        line-height: 1;
    }

    /* Custom CSS: shared form summaries use a mixed theme tint and wrapping of
       unbroken equipment names that Prewind utilities do not provide. */
    .ui-journal-form-panel {
        background: color-mix(in srgb, var(--lighter) 45%, var(--white));
    }

    .ui-journal-form-title {
        overflow-wrap: anywhere;
    }

    .ui-journal-card-timestamp {
        flex: 0 0 auto;
        color: var(--midtone);
        font-size: var(--text-sm);
        font-weight: var(--font-normal);
        white-space: nowrap;
    }

    .ui-journal-card-note {
        display: block;
        padding: var(--space-sm);
        color: var(--darker);
        font-size: var(--text-base);
        overflow-wrap: anywhere;
        text-decoration: none;
    }

    .ui-journal-note-expandable summary {
        display: block;
        list-style: none;
        cursor: pointer;
    }

    .ui-journal-note-expandable summary::-webkit-details-marker {
        display: none;
    }

    .ui-journal-note-text {
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 4;
        overflow: hidden;
    }

    .ui-journal-note-expandable[open] .ui-journal-note-text {
        display: block;
    }

    .ui-journal-note-more,
    .ui-journal-note-less {
        margin-top: var(--space-2xs);
        color: var(--warning);
        font-size: var(--text-sm);
        font-weight: var(--font-semibold);
    }

    .ui-journal-note-less,
    .ui-journal-note-expandable[open] .ui-journal-note-more {
        display: none;
    }

    .ui-journal-note-expandable[open] .ui-journal-note-less {
        display: block;
    }

    .ui-journal-card.ui-journal-card-index .photo-preview {
        gap: var(--space-2xs);
        padding: var(--space-xs) var(--space-sm) var(--space-sm);
        border: 0;
    }

    .ui-journal-card.ui-journal-card-index .photo-preview:first-of-type {
        padding-top: var(--space-sm);
    }

    .ui-journal-card.ui-journal-card-index .photo-preview-single {
        grid-template-columns: minmax(0, 1fr);
    }

    .ui-journal-card.ui-journal-card-index .photo-preview-single > * {
        height: calc(var(--ui-journal-photo-row-height) * 1.75);
        aspect-ratio: auto;
    }

    .ui-journal-card.ui-journal-card-index .photo-preview-pair {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .ui-journal-card.ui-journal-card-index .photo-preview-pair > * {
        height: var(--ui-journal-photo-row-height);
        aspect-ratio: auto;
    }

    .ui-journal-card.ui-journal-card-index .photo-preview-grid {
        grid-auto-flow: column;
        grid-auto-columns: minmax(0, 1fr);
        grid-template-columns: none;
    }

    .ui-journal-card.ui-journal-card-index .photo-preview-grid > * {
        height: var(--ui-journal-photo-row-height);
        aspect-ratio: auto;
    }

    .ui-journal-card.ui-journal-card-index .ui-journal-card-footer {
        display: flex;
        min-width: 0;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-xs);
        margin: 0 var(--space-sm);
        padding: var(--space-xs) 0;
        border-top: 1px solid var(--lighter);
    }

    .ui-journal-card-meta {
        display: flex;
        min-width: 0;
        flex: 1 1 auto;
        flex-wrap: wrap;
        align-items: center;
        gap: var(--space-xs);
    }

    .ui-journal-card-meta-item {
        display: inline-flex;
        min-width: 0;
        align-items: center;
        gap: var(--space-3xs);
        color: var(--midtone);
        font-size: var(--text-sm);
        line-height: 1;
        text-decoration: none;
    }

    .ui-journal-card-meta-item svg {
        flex: 0 0 auto;
    }

    .ui-journal-card-meta-item span {
        min-width: 0;
        overflow-wrap: anywhere;
        text-align: left;
        white-space: normal;
    }

    .ui-journal-card.ui-journal-card-index .ui-journal-card-meta > span {
        text-align: left;
        white-space: normal;
    }

    .ui-journal-marker {
        display: inline-flex;
        width: var(--space-md);
        height: var(--space-md);
        flex: 0 0 auto;
        align-items: center;
        justify-content: center;
        border-radius: var(--rounded-full);
        background: var(--brand-1);
        color: var(--brand-1-content);
        font-size: var(--text-sm);
        font-weight: var(--font-bold);
        line-height: 1;
    }

    .ui-journal-card-actions {
        display: inline-flex;
        flex: 0 0 auto;
        align-items: center;
        gap: var(--space-2xs);
    }

    .ui-journal-card-action {
        display: inline-flex;
        min-width: 2rem;
        min-height: 2rem;
        align-items: center;
        justify-content: center;
        padding: var(--space-2xs);
        border: 0;
        background: transparent;
        color: var(--warning);
        font: inherit;
        text-decoration: none;
        cursor: pointer;
    }

    .ui-journal-card-action-delete {
        color: var(--midtone);
    }

    .ui-journal-sync-status {
        margin: var(--space-xs) var(--space-sm) 0;
        padding: var(--space-2xs) var(--space-xs);
        border-radius: var(--rounded-sm);
        background: var(--warning-light);
        color: var(--warning);
        font-size: var(--text-sm);
        font-weight: var(--font-semibold);
    }

    .ui-journal-sync-status-saved {
        background: var(--lighter);
        color: var(--midtone);
    }

    /* Custom CSS: shared PWA action bars own safe-area padding and common action
       sizing across primary navigation and project capture. */
    .ui-pwa-bottom-action-bar {
        box-sizing: border-box;
        display: flex;
        flex: 0 0 auto;
        align-items: stretch;
        padding-bottom: env(safe-area-inset-bottom);
        border: var(--border) solid var(--light);
        border-right: 0;
        border-bottom: 0;
        border-left: 0;
        border-radius: var(--rounded-lg) var(--rounded-lg) 0 0;
        background: var(--white);
    }

    .ui-pwa-bottom-action {
        display: flex;
        min-width: 0;
        min-height: var(--ui-tap-min);
        appearance: none;
        flex: 1 1 0;
        align-items: center;
        justify-content: center;
        flex-direction: column;
        gap: var(--space-3xs);
        padding: 0;
        border: 0;
        background: transparent;
        color: var(--midtone);
        font: inherit;
        font-size: var(--text-base);
        font-weight: var(--font-normal);
        line-height: 1;
        text-align: center;
        text-decoration: none;
        cursor: pointer;
        -webkit-tap-highlight-color: transparent;
    }

    /* Custom CSS: navigation current/expanded and pressed states are not Prewind variants. */
    .ui-pwa-bottom-action.is-active,
    .ui-pwa-bottom-action[aria-current="page"],
    .ui-pwa-bottom-action[aria-expanded="true"] {
        color: var(--darker);
        font-weight: var(--font-bold);
    }

    /* Custom CSS: the current-destination pill sits behind its icon. The
       wrapper isolates a stacking context so the z-index -1 pseudo cannot
       cover the SVG (an absolute pseudo would otherwise paint over it) or
       slip behind the nav ground; Prewind has no isolation utility. Prewind
       also has no utility that sizes a background larger than its element, so
       the 60x32 geometry (16px each side, 2px above and below) is exact. */
    .ui-pwa-bottom-action-icon {
        isolation: isolate;
    }

    .ui-pwa-bottom-action-icon::before {
        position: absolute;
        top: 50%;
        left: 50%;
        z-index: -1;
        width: 60px;
        height: 32px;
        border-radius: var(--rounded-full);
        background: transparent;
        content: "";
        transform: translate(-50%, -50%);
    }

    .ui-pwa-bottom-action.is-active .ui-pwa-bottom-action-icon::before,
    .ui-pwa-bottom-action[aria-current="page"] .ui-pwa-bottom-action-icon::before {
        background: var(--hairline);
    }

    .ui-pwa-bottom-action:active { color: var(--darker); }

    .ui-pwa-bottom-action:focus-visible {
        border-radius: var(--rounded-sm);
        outline: 2px solid var(--darker);
        outline-offset: -2px;
    }

    /* Custom CSS: the shared capture footer includes the existing bar height,
       raised control offset and clearance gap; these calculations have no
       Prewind utility. The bar already includes its safe-area padding. */
    .ui-project-journal-capture-page {
        --ui-journal-footer-space: calc(
            var(--ui-journal-action-bar-height) +
                var(--ui-journal-action-raised-offset) + var(--space-sm)
        );
        box-sizing: border-box;
    }

    .ui-project-journal-capture-footer {
        padding-top: calc(var(--ui-journal-action-raised-offset) + var(--space-sm));
    }

    /* Custom CSS: QuickNote scrolls through the space behind the raised mic.
       Prewind cannot calculate its bottom padding from the shared offset.
       Moving the footer clearance here preserves Save's final scroll gap. */
    .ui-quick-note-pwa-form {
        padding-bottom: calc(var(--ui-journal-action-raised-offset) + 2 * var(--space-sm));
    }

    .ui-quick-note-pwa-form + .ui-project-journal-capture-footer {
        padding-top: 0;
    }

    /* Custom CSS: each bar owns the positioning of its raised center control.
       The footer stays in page flow outside the scrolling content. */
    .ui-project-journal-action-bar {
        position: relative;
        z-index: var(--z-bar);
        height: var(--ui-journal-action-bar-height);
        align-items: center;
        padding-right: max(var(--space-md), env(safe-area-inset-right));
        padding-bottom: max(var(--space-sm), env(safe-area-inset-bottom));
        padding-left: max(var(--space-md), env(safe-area-inset-left));
    }

    .ui-project-journal-action-spacer {
        flex: 1 1 0;
        min-width: 0;
    }

    .ui-project-journal-recording-bar {
        position: relative;
        z-index: var(--z-bar-raised);
        height: var(--ui-journal-action-bar-height);
        align-items: center;
        justify-content: space-between;
        padding-right: max(var(--space-md), env(safe-area-inset-right));
        padding-bottom: max(var(--space-sm), env(safe-area-inset-bottom));
        padding-left: max(var(--space-md), env(safe-area-inset-left));
        box-shadow: var(--shadow-sm);
    }

    .ui-project-journal-recording-cancel,
    .ui-project-journal-recording-stop {
        min-width: calc(var(--space-xl) + var(--space-md));
        min-height: calc(var(--space-md) + var(--space-xs));
        border: 0;
        font: inherit;
        cursor: pointer;
        touch-action: manipulation;
    }

    .ui-project-journal-recording-cancel {
        padding: 0;
        background: transparent;
    }

    .ui-project-journal-recording-center {
        position: absolute;
        top: calc(-1 * var(--ui-journal-action-raised-offset));
        left: 50%;
        gap: var(--space-3xs);
        transform: translateX(-50%);
    }

    .ui-project-journal-recording-indicator {
        width: 3.75rem;
        height: 3.75rem;
        box-sizing: border-box;
        border: 0.25rem solid var(--white);
        box-shadow: 0 0 0 1px var(--light);
    }

    .ui-project-journal-recording-indicator .ui-speech-dictation-waveform-bar,
    .ui-project-journal-recording-indicator.ui-speech-dictation-waveform.is-listening
        .ui-speech-dictation-waveform-bar {
        background: var(--darker);
    }

    .ui-project-journal-recording-time {
        line-height: 1;
    }

    .ui-project-journal-dictation-status:not(.sr-only) {
        position: absolute;
        right: var(--space-md);
        bottom: calc(var(--ui-journal-action-bar-height) + var(--space-xs));
        left: var(--space-md);
        z-index: var(--z-bar-raised);
        padding: var(--space-xs);
        border: var(--border) solid var(--light);
        border-radius: var(--rounded-sm);
        background: var(--white);
        box-shadow: var(--shadow-sm);
    }

    /* Custom CSS: primary navigation includes its shared minimum height plus
       the device safe area; Prewind has no safe-area size utility. */
    .ui-pwa-primary-navigation {
        box-sizing: border-box;
        min-height: calc(var(--ui-pwa-bottom-bar-height) + env(safe-area-inset-bottom));
        padding-top: var(--space-2xs);
        padding-right: max(var(--space-md), env(safe-area-inset-right));
        padding-bottom: max(var(--space-md), env(safe-area-inset-bottom));
        padding-left: max(var(--space-md), env(safe-area-inset-left));
        box-shadow: var(--shadow-sm);
    }

    .ui-pwa-primary-navigation .ui-pwa-bottom-action {
        padding-top: var(--space-xs);
        padding-bottom: var(--space-xs);
        transition: color var(--ui-duration-fast) var(--ui-ease);
    }

    /* Custom CSS: the raised control is shared by the QuickNote bar and the
       camera shutter. Center it with offset properties and auto margins so the
       shared disabled-state rule's transform: none cannot shift it sideways. */
    .ui-project-journal-action-primary {
        position: absolute;
        top: calc(-1 * var(--ui-journal-action-raised-offset));
        right: 0;
        left: 0;
        z-index: var(--z-bar-raised);
        width: 20%;
        margin-inline: auto;
        color: var(--darker);
        font-weight: var(--font-bold);
    }

    .ui-project-journal-action-primary-icon {
        display: flex;
        width: 3.75rem;
        height: 3.75rem;
        box-sizing: border-box;
        align-items: center;
        justify-content: center;
        border: 0.25rem solid var(--white);
        border-radius: 50%;
        background: var(--brand-1);
        box-shadow: 0 0 0 1px var(--light);
    }

    /* Custom CSS: the raised capture control is green for capture while the
       shared geometry, white ring and raised offset stay on the base icon rule. */
    .ui-project-journal-action-primary-icon.ui-project-journal-action-shutter {
        background: var(--success);
    }

    /* Custom CSS: the standalone camera shutter matches the B4 pill's outer 4px
       white ring and soft shadow instead of the base inset border and 1px dark
       outline. Prewind has no ring/shadow utility; scoped to the QuickNote
       camera bar so the legacy Gallery/Forms shutter is unchanged. */
    .ui-camera-capture-bar .ui-project-journal-action-primary-icon.ui-project-journal-action-shutter {
        border: 0;
        box-shadow: 0 0 0 var(--ui-journal-action-ring) var(--white), var(--shadow-sm);
    }

    /* Custom CSS: match the B4 middle column even with asymmetric safe areas;
       Prewind cannot calculate this inset pair or the exact shared 60px size. */
    .ui-camera-capture-bar .ui-project-journal-action-primary {
        right: max(var(--space-md), env(safe-area-inset-right));
        left: max(var(--space-md), env(safe-area-inset-left));
        width: var(--ui-journal-action-split-height);
        min-height: var(--ui-journal-action-split-height);
        padding: 0;
    }

    /* Custom CSS: the split Note/Photo control replaces the single raised
       circle. The flex shell, rounded-full gold ground and soft shadow come
       from markup utilities; this rule group owns only the raised offset, the
       60-high track, the B4 responsive width, the 4px white ring and the 1.5px
       ink divider. The demos use a 76px 1fr 76px bar with the middle track at
       width:100%/max-width:186px; Prewind has no utility for the remaining
       middle width, so the track takes the padded bar minus both gutters and
       the two fixed side columns, capped at 186. The matching left/right
       insets keep it centered on that middle column when safe-area insets are
       asymmetric. */
    .ui-project-journal-action-split {
        position: absolute;
        top: calc(-1 * var(--ui-journal-action-raised-offset));
        right: max(var(--space-md), env(safe-area-inset-right));
        left: max(var(--space-md), env(safe-area-inset-left));
        z-index: var(--z-bar-raised);
        width: min(var(--ui-journal-action-split-max-width), calc(100% - max(var(--space-md), env(safe-area-inset-left)) - max(var(--space-md), env(safe-area-inset-right)) - 2 * var(--ui-journal-action-side-width)));
        height: var(--ui-journal-action-split-height);
        margin-inline: auto;
        box-shadow: 0 0 0 var(--ui-journal-action-ring) var(--white), var(--shadow-sm);
    }

    /* Custom CSS: the B4 bar fixes Gallery and Forms to the demos' 76px side
       columns so the split's flexing middle matches width:100%/max-width:186px
       down to phone widths. Scoped with :has to bars holding the split; other
       camera and navigation bars keep their growing items. */
    .ui-project-journal-action-bar:has(> .ui-project-journal-action-split) > .ui-pwa-bottom-action {
        flex: 0 0 var(--ui-journal-action-side-width);
    }

    .ui-project-journal-action-split-half {
        color: var(--brand-1-content);
        cursor: pointer;
        -webkit-tap-highlight-color: transparent;
    }

    /* Custom CSS: pressed and focus states are state combinations Prewind has no
       variant for; the enabled half uses the existing gold pressed token and keyboard
       focus uses the existing ink ring, inset so the track clip keeps it visible. */
    .ui-project-journal-action-split-half:focus-visible {
        outline: var(--ui-focus-ring);
        outline-offset: calc(-1 * var(--ui-focus-offset));
    }

    .ui-project-journal-action-split-half:not(:disabled):active {
        background: var(--brand-1-pressed);
    }

    .ui-project-journal-action-split-divider {
        width: var(--ui-journal-action-divider-width);
        background: color-mix(in srgb, var(--brand-1-content) 25%, transparent);
    }

    /* Custom CSS: the standalone camera chrome. Prewind has no utility for the
       exact 48px header note control and capture stack, the review dialog's
       viewport/safe-area geometry, the current-thumbnail ink ring or the details
       definition list. This is one camera component, named for its purpose. */
    .ui-camera-note-control {
        width: var(--ui-tap-min);
        height: var(--ui-tap-min);
    }

    .ui-camera-note-dot {
        top: 0.375rem;
        right: 0.375rem;
        width: 0.625rem;
        height: 0.625rem;
        border: 2px solid var(--white);
        border-radius: 50%;
        background: var(--brand-1);
    }

    .ui-camera-stack {
        flex: 0 0 auto;
        padding-inline: var(--space-md);
    }

    .ui-camera-stack-frame {
        width: var(--ui-tap-min);
        height: var(--ui-tap-min);
    }

    /* Custom CSS: the study's photo stack uses a rotated backing card and a
       24px ink count with a white ring. Prewind has no pseudo-element or exact
       badge-size utility; the rest of the thumbnail remains utility styled. */
    .ui-camera-stack-frame:has([data-multiple])::before {
        content: "";
        position: absolute;
        inset: 0;
        border: 2px solid var(--white);
        border-radius: var(--rounded-sm);
        background: var(--light);
        box-shadow: var(--shadow-sm);
        transform: rotate(-8deg) translate(-2px, 1px);
    }

    .ui-camera-stack-count {
        display: flex;
        box-sizing: border-box;
        min-width: 1.5rem;
        height: 1.5rem;
        align-items: center;
        justify-content: center;
        border: 2px solid var(--white);
        line-height: 1;
    }

    /* Custom CSS: capture-review actions extend the existing action component
       with ink controls and its destructive Delete state. The component's base
       colour overrides lower-layer utilities, so these states belong here. */
    .ui-camera-review-actions .ui-pwa-bottom-action {
        color: var(--darker);
    }

    .ui-camera-review-actions .ui-camera-review-delete {
        color: var(--error);
    }

    /* Custom CSS: the camera Done is the shared gold write button, sized as a
       fixed bar control; its gold ground, ink text and font come from
       ui-button/ui-brand-1, so only size and flex behaviour live here. */
    .ui-camera-done {
        flex: 0 0 auto;
        width: auto;
        padding-inline: var(--space-md);
    }

    /* Custom CSS: the review is a full-screen modal dialog like the camera
       overlay; Prewind has no 100dvh/safe-area utility, and an open dialog needs
       an explicit flex display. */
    .ui-camera-review {
        box-sizing: border-box;
        height: 100dvh;
        max-height: 100dvh;
        padding-top: env(safe-area-inset-top);
    }

    .ui-camera-review[open] {
        display: flex;
    }

    .ui-camera-review-strip {
        min-height: calc(var(--ui-tap-min) + 2 * var(--space-xs));
        padding: var(--space-xs) var(--space-md);
    }

    .ui-camera-review-thumb {
        flex: none;
        width: var(--ui-tap-min);
        height: var(--ui-tap-min);
        overflow: hidden;
        padding: 0;
        border: 2px solid transparent;
        border-radius: var(--rounded-sm);
        background: var(--lighter);
        cursor: pointer;
    }

    .ui-camera-review-thumb.is-current {
        border-color: var(--darker);
    }

    .ui-camera-review-thumb img {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

    .ui-camera-review-info {
        width: min(24rem, calc(100vw - 2 * var(--space-md)));
    }

    .ui-camera-review-info-list {
        display: grid;
        grid-template-columns: auto 1fr;
        gap: var(--space-2xs) var(--space-sm);
        padding-block: var(--space-sm);
    }

    .ui-camera-review-info-list dt {
        color: var(--midtone);
    }

    /* Field cards are shared by journal and form surfaces.
       Header + body content + footer/action. */
    .ui-field-card {
        --ui-field-card-action-column: 5.25rem;

        scroll-margin-top: calc(6rem + var(--space-sm));
        display: block;
        margin-bottom: var(--ui-field-card-gap);
        background: var(--ui-field-card-bg);
        border: var(--ui-field-card-border-width) solid
            var(--ui-field-card-border-color);
        border-radius: var(--ui-field-card-radius);
        font-size: var(--ui-field-card-text-size);
    }

    .ui-field-card-session-rows {
        --ui-field-card-action-column: 5.75rem;

        overflow: hidden;
    }

    .ui-field-card-link {
        color: inherit;
        text-decoration: none;
    }

    .ui-field-card-link:active {
        transform: translateY(1px);
    }

    .ui-field-card-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: var(--ui-field-card-padding);
        border-bottom: var(--ui-field-card-divider-width) solid
            var(--ui-field-card-border-color);
    }

    .ui-field-card-header-compact {
        padding: var(--space-sm) var(--ui-field-card-padding-wide)
            var(--space-xs);
        border-bottom: 0;
    }

    .ui-field-card-session-rows .ui-field-card-header-compact {
        background: var(--lighter);
        border-bottom: var(--ui-field-card-divider-width) solid
            var(--ui-field-card-border-color);
    }

    .ui-field-card-title-group {
        display: flex;
        align-items: center;
        gap: var(--space-2xs);
    }

    .ui-field-card-title {
        color: var(--darker);
        font-weight: var(--font-bold);
    }

    .ui-field-card-session {
        color: var(--dark);
        font-weight: 700;
    }

    .ui-field-card-meta {
        display: flex;
        align-items: center;
        gap: var(--space-xs);
        color: var(--midtone);
    }

    .ui-field-card-edit {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        color: var(--darker);
        text-decoration: none;
    }

    .ui-field-card-edit:active {
        transform: translateY(1px);
    }

    .ui-field-card-footer {
        display: grid;
        grid-template-columns: minmax(0, 1fr) var(--ui-field-card-action-column);
        align-items: center;
        gap: var(--space-xs);
        padding: var(--ui-field-card-padding);
    }

    .ui-field-card-crew {
        min-width: 0;
        display: inline-flex;
        align-items: center;
        gap: var(--space-xs);
    }

    .ui-field-card-view {
        justify-self: end;
        margin-right: var(--space-2xs);
        color: var(--brand-2);
        font-weight: 700;
        text-decoration: none;
    }

    .ui-project-form-summary {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        gap: var(--space-sm);
        padding: var(--ui-field-card-padding) var(--ui-field-card-padding-wide);
        border-bottom: var(--ui-field-card-divider-width) solid
            var(--ui-field-card-border-color);
    }

    .ui-project-form-summary-item {
        min-width: 0;
        display: flex;
        flex-direction: column;
        gap: var(--space-3xs);
    }

    .ui-project-form-summary-item span {
        color: var(--dark);
        font-size: var(--text-sm);
        font-weight: var(--font-heavy);
        line-height: 1.1;
    }

    .ui-project-form-summary-item strong {
        min-width: 0;
        color: var(--darker);
        font-weight: var(--font-heavy);
        line-height: 1.15;
        overflow-wrap: anywhere;
    }

    .ui-project-form-signature-pending {
        color: var(--midtone);
        font-style: italic;
    }

    /* Form cards show compact photo previews below the summary. */
    .ui-field-card-photo-preview {
        display: grid;
        grid-template-columns: repeat(4, minmax(0, 1fr));
        justify-content: start;
        gap: var(--space-xs);
        padding: var(--space-sm) var(--ui-field-card-padding-wide);
        border-bottom: var(--ui-field-card-divider-width) solid
            var(--ui-field-card-border-color);
    }

    .ui-field-card-photo-preview-overflow {
        aspect-ratio: 1;
        overflow: hidden;
        border-radius: var(--rounded-sm);
        background: var(--light);
    }

    .ui-field-card-photo-preview-overflow {
        display: flex;
        align-items: center;
        justify-content: center;
        color: var(--darker);
        font-weight: var(--font-heavy);
    }

    .ui-field-detail-list {
        display: flex;
        flex-direction: column;
    }

    .ui-field-detail-panel {
        padding: var(--ui-field-card-padding) var(--ui-field-card-padding-wide);
    }

    .ui-field-detail-panel + .ui-field-detail-panel {
        border-top: var(--ui-field-card-divider-width) solid
            var(--ui-field-card-border-color);
    }

    .ui-field-detail-label {
        display: block;
        color: var(--dark);
        font-weight: var(--font-heavy);
        line-height: 1.1;
    }

    .ui-field-detail-value {
        display: block;
        color: var(--midtone);
        overflow-wrap: anywhere;
    }

    /*
      SECTION: Project photos, annotations, and photo maps
      Project photo grids, offline/upload handoff, desktop map rails,
      annotations, load-more states, Google Maps overrides, and generated
      photo map cards/markers.
    */

    /* Project photo scrolling hides mobile scrollbars; sizing stays in utilities. */
    .ui-project-photo-content {
        -ms-overflow-style: none;
        scrollbar-width: none;
    }

    .ui-project-photo-content::-webkit-scrollbar {
        display: none;
        width: 0;
        height: 0;
    }

    /* Desktop project photos use compact controls and a denser responsive grid. */
    .ui-project-photo-workspace {
        --ui-field-height: calc(var(--space-md) + var(--space-xs));
        --ui-field-padding: var(--space-xs);
        --ui-field-font-size: var(--text-base);
        --ui-field-border-radius: var(--rounded-sm);
        --ui-project-photo-sticky-offset: var(--space-sm);
        --ui-project-photo-filter-sticky-height: 6.75rem;
    }

    form.ui-project-photo-filters {
        position: sticky;
        top: var(--ui-project-photo-sticky-offset);
        z-index: var(--z-sticky);
        width: 100%;
        max-width: none;
        gap: var(--space-xs);
        box-shadow: var(--shadow-sm);
    }

    form.ui-project-photo-filters .ui-project-photo-filter-row.form-row {
        display: grid;
        grid-template-columns:
            minmax(0, 1.15fr) minmax(9rem, 0.7fr) minmax(0, 1fr)
            max-content;
        align-items: flex-end;
        gap: var(--space-2xs);
    }

    form.ui-project-photo-filters .ui-project-photo-filter-row .ui-field {
        min-width: 0;
    }

    /* Custom CSS: Gallery chips include a separate clear target, so they need
       their natural width instead of the Forms half-row cap. */
    .ui-project-photo-label-filters .ui-forms-filter-chip {
        max-width: 100%;
    }

    /* Custom CSS: Prewind cannot bind badge and clear targets to --ui-tap-min.
       Keep each label action usable independently of the photo detail link. */
    .ui-project-photo-label-badge-link,
    .ui-project-photo-label-chip-toggle,
    .ui-project-photo-label-chip-clear {
        min-width: var(--ui-tap-min);
        min-height: var(--ui-tap-min);
    }

    .ui-project-photo-label-chip-clear {
        width: var(--ui-tap-min);
    }

    /* Project photo grid uses CSS Grid because Prewind does not provide grid utilities. */
    .ui-project-photo-grid {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .ui-project-photo-upload-handoff {
        top: 6rem;
        overflow-y: auto;
        background: color-mix(in srgb, var(--white) 94%, transparent);
        backdrop-filter: blur(6px);
        -webkit-backdrop-filter: blur(6px);
        animation: ui-project-photo-upload-handoff-in var(--ui-duration-fast) var(--ui-ease);
    }

    .ui-project-photo-upload-handoff-compact {
        top: calc(6rem + var(--space-xs));
        background: transparent;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }

    .ui-project-photo-upload-spinner {
        width: var(--space-sm);
        height: var(--space-sm);
        border: var(--border-lg) solid
            color-mix(in oklab, var(--white) 35%, transparent);
        border-top-color: var(--brand-1);
        border-radius: var(--rounded-full);
        animation: ui-project-photo-upload-spin var(--ui-duration-spin) linear infinite;
    }

    @media (prefers-reduced-motion: reduce) {
        .ui-project-photo-upload-spinner {
            animation: none;
        }
    }

    .ui-project-photo-upload-surface {
        min-height: 100%;
        padding: var(--space-sm);
    }

    .ui-project-photo-offline-status {
        left: var(--space-md);
        bottom: calc(var(--space-lg) + env(safe-area-inset-bottom));
    }

    .ui-project-photo-offline-status-desktop {
        right: var(--space-md);
        left: auto;
    }

    .ui-project-photo-offline-toggle {
        min-height: 3.25rem;
        border: 0;
        appearance: none;
        -webkit-appearance: none;
    }

    /* Custom CSS: upload headers and queue buttons share the existing 88% dark
       surface and 10px blur, which Prewind cannot express exactly. */
    .ui-project-photo-offline-toggle,
    .ui-upload-queue-header {
        background: color-mix(in srgb, var(--black) 88%, transparent);
        backdrop-filter: blur(10px);
        -webkit-backdrop-filter: blur(10px);
    }

    .ui-project-photo-offline-toggle-desktop {
        max-width: min(32rem, calc(100vw - var(--space-xl)));
    }

    .ui-project-photo-offline-count {
        min-width: 1.65rem;
        height: 1.65rem;
        line-height: 1;
    }

    .ui-project-photo-offline-panel {
        max-height: min(72dvh, 34rem);
        padding-bottom: env(safe-area-inset-bottom);
        border-radius: var(--rounded-lg) var(--rounded-lg) 0 0;
        animation: ui-project-photo-offline-panel-in var(--ui-duration-fast) var(--ui-ease-move);
    }

    .ui-project-photo-offline-panel-desktop {
        right: var(--space-md);
        bottom: var(--space-md);
        width: min(40rem, calc(100vw - var(--space-xl)));
        border-radius: var(--rounded-lg);
    }

    .ui-project-photo-offline-panel-desktop .ui-project-photo-offline-list {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .ui-project-photo-offline-close {
        width: 2.5rem;
        height: 2.5rem;
        border: 0;
        appearance: none;
        -webkit-appearance: none;
    }

    .ui-project-photo-offline-list {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--space-xs);
    }

    .ui-project-photo-grid-desktop {
        grid-template-columns: repeat(auto-fill, minmax(min(100%, 11rem), 1fr));
    }

    .ui-project-photo-page-frame {
        display: contents;
    }

    .ui-project-photo-load-more-frame {
        grid-column: 1 / -1;
    }

    /* Desktop project photos reserve a persistent map rail beside the grid. */
    .ui-project-photo-layout {
        display: grid;
        grid-template-columns: minmax(0, 3fr) minmax(20rem, 2fr);
        gap: var(--space-sm);
        align-items: start;
    }

    .ui-project-photo-map-column {
        position: sticky;
        top: var(--ui-project-photo-sticky-offset);
        min-height: 24rem;
        height: calc(100dvh - 10rem);
    }

    .ui-project-photo-detail-stage {
        flex: 1 1 auto;
        min-height: 0;
    }

    .ui-project-photo-detail-workspace {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(20rem, 0.72fr);
        align-items: start;
    }

    .ui-project-photo-detail-map-column {
        position: sticky;
        top: var(--ui-project-photo-sticky-offset);
        min-height: 24rem;
        height: calc(100dvh - 10rem);
    }

    .ui-project-photo-detail-image {
        max-height: min(62vh, 40rem);
    }

    .ui-project-photo-stage-action {
        position: absolute;
        right: var(--space-sm);
        bottom: var(--space-sm);
        z-index: var(--z-sticky);
    }

    .ui-project-photo-detail-annotation-panel {
        max-height: none;
    }

    @media (max-width: 900px) {
        .ui-project-photo-detail-workspace {
            grid-template-columns: minmax(0, 1fr);
        }

        .ui-project-photo-detail-map-column {
            position: static;
            height: min(50dvh, 24rem);
        }

        .ui-project-photo-detail-annotation-panel {
            max-height: none;
        }
    }

    .ui-project-photo-annotation-frame {
        cursor: crosshair;
    }

    .ui-project-photo-zoom-frame {
        touch-action: none;
        will-change: transform;
    }

    .ui-project-photo-zoom-frame.is-zoomed {
        cursor: grab;
    }

    .ui-project-photo-zoom-frame.is-panning {
        cursor: grabbing;
    }

    .ui-project-photo-zoom-controls {
        top: var(--space-xs);
    }

    .ui-project-photo-zoom-control,
    .ui-project-photo-viewer-menu-trigger {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: var(--ui-tap-min);
        height: var(--ui-tap-min);
        padding: 0;
        border: 0;
        border-radius: var(--rounded-full);
        background: var(--white);
        color: var(--darker);
        box-shadow: var(--shadow-sm);
        cursor: pointer;
    }

    /* Custom CSS: the viewer chrome bar needs a solid dark ground and a hairline
       edge so a zoomed photo clips against it; Prewind has no dark chrome
       component and bg-dark + bg-opacity-90 was the removed third gray. */
    .ui-project-photo-viewer-chrome {
        background: var(--ui-photo-viewer-chrome);
        border-top: 1px solid var(--ui-photo-viewer-hairline);
    }

    .ui-project-photo-viewer-toolbar {
        background: var(--ui-photo-viewer-chrome);
        border-bottom: 1px solid var(--ui-photo-viewer-hairline);
        min-height: var(--ui-tap-min);
    }

    /* Custom CSS: the parent control keeps the 48px target floor; its layout,
       type and colour come from Prewind utilities on the markup. */
    .ui-project-photo-viewer-parent {
        min-height: var(--ui-tap-min);
    }

    /* Custom CSS: the Annotate-target outline marks the picked frame; the
       frame's own focus ring now comes from the shared control focus rule. */
    .ui-project-photo-annotation-frame.is-annotation-target {
        outline: 2px solid var(--brand-1);
        outline-offset: 2px;
    }

    /* Custom CSS: the capability menu rows keep the 56px write-target floor and
       the disabled Delete row stacks its visible explanation; neither the row
       floor nor the disabled layout exists in the shared ui-dropdown menu. */
    .ui-project-photo-viewer-menu a,
    .ui-project-photo-viewer-menu button {
        min-height: var(--ui-tap-write);
    }

    .ui-project-photo-viewer-menu button[disabled] {
        opacity: 1;
        cursor: default;
    }

    .ui-project-photo-viewer-menu button[disabled]:hover {
        background-color: transparent;
    }

    /* Custom CSS: this class owns the repeated associated-reason presentation
       (spacing, size, weight) and its surface contrast; Prewind covers the
       individual small/muted paragraph pieces but not the shared reason role. */
    .ui-disabled-reason {
        margin: var(--space-3xs) 0 0;
        color: var(--midtone);
        font-size: var(--text-sm);
        font-weight: var(--font-normal);
        line-height: 1.3;
    }

    /* Only genuinely dark surfaces restyle the reason; the light viewer
       dropdown inside the dark header keeps its ink text. */
    :is(.ui-pwa-drawer, .ui-project-photo-viewer-chrome) .ui-disabled-reason {
        color: var(--light);
    }

    :is(.ui-project-photo-viewer-menu) .ui-disabled-reason {
        color: var(--midtone);
    }

    /* Custom CSS: the dark viewer header is a treatment the light shared PWA
       header does not provide; only the viewer caller opts in and every other
       header keeps its white ground. */
    .ui-pwa-header-dark {
        background: var(--ui-photo-viewer-chrome);
        color: var(--white);
    }

    /* Custom CSS: a bordered dark header needs the viewer hairline rather than
       the shared light border token. */
    .ui-pwa-header-dark .ui-pwa-header-bar.border-b {
        border-bottom-color: var(--ui-photo-viewer-hairline);
    }

    /* Custom CSS: on the dark viewer header the capability trigger is a bare
       white glyph; the shared light chrome uses the white disc. */
    .ui-pwa-header-dark .ui-project-photo-viewer-menu-trigger {
        width: var(--ui-tap-min);
        height: var(--ui-tap-min);
        background: transparent;
        color: var(--white);
        box-shadow: none;
    }

    /* Custom CSS: the viewer footer is a solid dark bar outside the clipped
       image stage so a zoomed photo clips against its hairline edge; Prewind
       has no dark chrome component. */
    .ui-project-photo-viewer-footer {
        flex-shrink: 0;
        background: var(--ui-photo-viewer-chrome);
        border-top: 1px solid var(--ui-photo-viewer-hairline);
        color: var(--white);
    }

    /* Custom CSS: ghost source actions keep ordinary layout, type and spacing
       from Prewind utilities; only the 48px target floor, dark hairline,
       transparent ground and the focus/hover state are added here. */
    .ui-project-photo-viewer-footer-action {
        min-height: var(--ui-tap-min);
        border: 1px solid var(--ui-photo-viewer-hairline);
        background: transparent;
    }

    .ui-project-photo-viewer-footer-action:hover,
    .ui-project-photo-viewer-footer-action:focus-visible {
        background: var(--ui-photo-viewer-hairline);
    }

    /* Custom CSS: native note/details dialogs need an open-only flex layout so
       long content scrolls within the shared viewport cap and keeps actions visible. */
    .ui-photo-notes-sheet[open],
    .ui-photo-info-sheet[open] {
        display: flex;
        flex-direction: column;
    }

    .ui-photo-notes-sheet > div,
    .ui-photo-info-sheet > div {
        max-height: inherit;
    }

    /* Custom CSS: the Google Photos viewer footer is a white four-up control bar
       with an exact 56px target and a 26px icon over a label; Prewind has no
       grid utilities for the equal columns and no combined label/icon control. */
    .ui-project-photo-viewer-controls {
        display: grid;
        grid-template-columns: repeat(4, minmax(0, 1fr));
        align-items: stretch;
        flex-shrink: 0;
        background: var(--white);
        border-top: 1px solid var(--light);
        color: var(--darkest);
        padding-bottom: env(safe-area-inset-bottom);
    }

    .ui-project-photo-viewer-control {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: var(--space-3xs);
        min-height: var(--ui-tap-write);
        padding: var(--space-3xs) var(--space-xs);
        border: 0;
        background: transparent;
        color: inherit;
        font-size: var(--text-base);
        font-weight: var(--font-semibold);
        line-height: 1.2;
        text-align: center;
        text-decoration: none;
        cursor: pointer;
    }

    .ui-project-photo-viewer-control:disabled {
        color: var(--midtone);
        cursor: default;
    }

    .ui-project-photo-viewer-control-icon {
        position: relative;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    /* Custom CSS: the ink count badge overlaps the comment bubble; the overlap
       geometry and 1rem floor are not expressible with Prewind utilities. */
    /* Custom CSS: an explicitly hidden badge must win over its authored flex display. */
    .ui-project-photo-viewer-control-badge[hidden] { display: none; }

    .ui-project-photo-viewer-control-badge {
        position: absolute;
        top: -0.375rem;
        right: -0.5rem;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 1rem;
        height: 1rem;
        padding: 0 0.25rem;
        border-radius: var(--rounded-full);
        background: var(--darkest);
        color: var(--white);
        font-size: var(--text-xs);
        font-weight: var(--font-bold);
        line-height: 1;
    }

    /* Custom CSS: a disabled Map/Rotate control shows one concise visible reason
       spanning the control row so a sighted touch user can discover it. */
    .ui-project-photo-viewer-controls-reason {
        grid-column: 1 / -1;
        margin: 0;
        padding: var(--space-2xs) var(--space-sm);
        border-top: 1px solid var(--light);
        color: var(--midtone);
        font-size: var(--text-sm);
        text-align: center;
    }

    /* Custom CSS: the white viewer top bar keeps the shared bar look but must
       hold a 48px Back target and the two-line position/time block. */
    .ui-project-photo-viewer-topbar {
        min-height: var(--ui-tap-write);
    }

    .ui-project-photo-viewer-back {
        width: var(--ui-tap-min);
        height: var(--ui-tap-min);
        justify-content: center;
    }

    /* Custom CSS: desktop edge arrows are 48px round controls over the dark
       stage; the circle, translucent ink ground and 26px glyph are Prewind gaps
       (no translucent-black token exists). */
    .ui-project-photo-viewer-arrow {
        width: var(--ui-tap-min);
        height: var(--ui-tap-min);
        background: color-mix(in srgb, var(--black) 45%, transparent);
        color: var(--white);
        box-shadow: var(--shadow-sm);
    }

    .ui-project-photo-viewer-arrow:hover,
    .ui-project-photo-viewer-arrow:focus-visible {
        background: color-mix(in srgb, var(--black) 65%, transparent);
    }

    /* Custom CSS: photo-note markers are 48px hit targets with an ink
       comment-bubble face and a tail at the tapped point; Prewind cannot express
       the inset face or the pseudo-element geometry, and the ink face must not be
       overridden by a status background utility. */
    .ui-project-photo-annotation-pin::before {
        content: "";
        position: absolute;
        top: 50%;
        left: 50%;
        width: 1.5rem;
        height: 1.5rem;
        transform: translate(-50%, -50%);
        border-radius: var(--rounded-full);
        background: var(--darkest);
        box-shadow: var(--shadow-sm);
        z-index: -1;
    }

    .ui-project-photo-annotation-pin::after {
        content: "";
        position: absolute;
        top: 50%;
        left: 25%;
        width: 0.75rem;
        height: 0.75rem;
        background: var(--darkest);
        clip-path: polygon(0 100%, 25% 0, 100% 0);
        z-index: -1;
    }

    /* Custom CSS: a link action disabled while offline keeps a muted control
       state; Prewind has no aria-disabled link treatment. */
    .ui-project-photo-viewer-offline-disabled {
        opacity: 0.5;
        pointer-events: none;
    }

    /* Custom CSS: paint the photo field with the exact #09090B viewer ground
       and clip zoom/pan to the stage; the shared black utility is a different
       token. */
    .ui-project-photo-viewer-stage {
        background: var(--ui-photo-viewer-field);
        overflow: hidden;
    }

    /* Custom CSS: the desktop viewer stage needs a definite height so the
       measured fit can constrain a tall image; the PWA stage already grows
       inside the clipped viewport page. */
    .ui-project-photo-detail-main .ui-project-photo-viewer-stage {
        flex: 0 0 auto;
        height: min(70vh, 42rem);
    }

    /* Custom CSS: a populated annotation list must leave room for the photo
       inside the fixed PWA viewport; Prewind has no proportional height cap.
       Scroll the list itself when it would consume more than half the stage. */
    .ui-pwa-viewport-page .ui-project-photo-detail-annotation-panel {
        max-height: 50%;
        overflow-y: auto;
    }

    /* Custom CSS: the fitted viewer frame is sized in pixels by the viewer
       controller to the displayed image bounds so annotation percentages stay
       aligned; Prewind cannot express the measured two-axis fit. */
    .ui-project-photo-viewer-frame {
        display: block;
        position: relative;
        width: auto;
        height: auto;
        max-width: 100%;
        max-height: 100%;
    }

    .ui-project-photo-viewer-frame.is-fitted .ui-project-photo-viewer-image {
        width: 100%;
        height: 100%;
    }

    /* Custom CSS: the Google Maps pattern is one rectangular white group with a
       divider and 48px targets; the shared zoom controls are circular and sit
       at the top. */
    .ui-project-photo-zoom-stack {
        background: var(--white);
        box-shadow: var(--shadow-sm);
        overflow: hidden;
    }

    .ui-project-photo-zoom-stack .ui-project-photo-zoom-control {
        border-radius: 0;
        background: transparent;
        box-shadow: none;
    }

    .ui-project-photo-zoom-stack .ui-project-photo-zoom-control + .ui-project-photo-zoom-control {
        border-top: 1px solid var(--light);
    }

    /* Custom CSS: stacked plus/minus controls sit bottom-right of the viewer
       stage (Google Maps pattern); Prewind has no stacked control geometry. */
    .ui-project-photo-zoom-controls-stacked {
        top: auto;
        right: var(--space-xs);
        bottom: var(--space-xs);
        left: auto;
    }

    /* Custom CSS: tap-to-hide is a viewer chrome state combination Prewind
       cannot express; important beats the later Prewind flex utilities so hidden
       chrome leaves the flow as well as becoming inert. */
    .ui-project-photo-viewer.is-chrome-hidden [data-project-photo-viewer-target="header"],
    .ui-project-photo-viewer.is-chrome-hidden [data-project-photo-viewer-target="footer"],
    .ui-project-photo-viewer.is-chrome-hidden [data-project-photo-viewer-target="zoomControls"] {
        display: none !important;
    }

    .ui-project-photo-annotation-pin,
    .ui-project-photo-annotation-badge {
        box-sizing: border-box;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        padding: 0.0625rem 0 0;
        color: var(--white);
        font-size: var(--text-sm);
        font-weight: var(--font-bold);
        font-variant-numeric: tabular-nums;
        font-feature-settings: "tnum";
        line-height: 1;
        text-align: center;
        flex-shrink: 0;
    }

    /* The Photo Notes list badge keeps its status face and 1.5rem size. */
    .ui-project-photo-annotation-badge {
        width: 1.5rem;
        height: 1.5rem;
        border-radius: var(--rounded-full);
        box-shadow: var(--shadow-sm);
    }

    /* Custom CSS: annotation pins stack locally: base above the image, temp pin
       one step up. Offsets build on --z-raised to preserve relative ordering. */
    .ui-project-photo-annotation-pin {
        position: absolute;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        padding: 0;
        color: var(--white);
        font-size: var(--text-sm);
        font-weight: var(--font-bold);
        z-index: var(--z-raised);
        width: var(--ui-tap-min);
        height: var(--ui-tap-min);
        appearance: none;
        border: 0;
        border-radius: var(--rounded-full);
        background: transparent;
        box-shadow: none;
        transform: translate(-25%, -75%)
            scale(var(--ui-project-photo-annotation-pin-scale, 1));
        transform-origin: 25% 75%;
        cursor: pointer;
        pointer-events: auto;
    }

    .ui-project-photo-annotation-temp-pin {
        position: absolute;
        z-index: calc(var(--z-raised) + 1);
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 1.5rem;
        height: 1.5rem;
        border-radius: var(--rounded-full);
        transform: translate(-50%, -50%)
            scale(var(--ui-project-photo-annotation-pin-scale, 1));
        transform-origin: center;
        pointer-events: none;
    }

    .ui-project-photo-annotation-popover {
        width: min(16rem, calc(100vw - var(--space-xl)));
        transform: translateX(-50%)
            scale(var(--ui-project-photo-annotation-pin-scale, 1));
        transform-origin: top center;
    }

    .ui-project-photo-annotation-popover.is-above {
        transform: translate(-50%, -100%)
            scale(var(--ui-project-photo-annotation-pin-scale, 1));
        transform-origin: bottom center;
    }

    /* Custom CSS: Prewind has no overflow:clip utility. The Projects page must
       clip its flex column without creating an extra scroll container, so the
       sticky header and toolbar keep a single scroll context for the page. */
    .ui-projects-index-page {
        overflow: clip;
    }

    .ui-projects-list-scroll {
        padding-bottom: calc(env(safe-area-inset-bottom) + 7rem);
    }

    .ui-projects-load-more {
        min-height: calc(var(--space-lg) + var(--space-sm));
    }

    .ui-projects-load-more > .ui-projects-load-more-indicator {
        opacity: 0.72;
        transform: translateY(var(--space-xs));
        transition:
            opacity var(--ui-duration-fast) var(--ui-ease),
            transform var(--ui-duration-fast) var(--ui-ease-move);
    }

    .ui-projects-load-more.is-pulling > .ui-projects-load-more-indicator,
    .ui-projects-load-more.is-loading > .ui-projects-load-more-indicator {
        opacity: 1;
        transform: translateY(0);
    }

    .ui-projects-load-more-spinner {
        width: 1.25rem;
        height: 1.25rem;
        border: var(--border-lg) solid
            color-mix(in oklab, var(--midtone) 28%, transparent);
        border-top-color: var(--brand-1);
        border-radius: var(--rounded-full);
        transform: rotate(0deg);
        transition: transform var(--ui-duration-fast) var(--ui-ease-move);
    }

    .ui-projects-load-more.is-pulling
        > .ui-projects-load-more-indicator
        .ui-projects-load-more-spinner {
        transform: rotate(45deg);
    }

    .ui-projects-load-more.is-loading
        > .ui-projects-load-more-indicator
        .ui-projects-load-more-spinner {
        animation: ui-projects-load-more-spin var(--ui-duration-spin) linear infinite;
    }

    /* Project photo map keeps clamp sizing and Google Maps overrides in component CSS. */
    .ui-project-photo-map-panel {
        flex: 0 0 clamp(11rem, 30dvh, 15.5rem);
    }

    .ui-project-photo-map-panel-desktop {
        flex: 0 1 auto;
    }

    .ui-project-photo-map-view {
        height: min(50dvh, 24rem);
        transition:
            opacity var(--ui-duration-fast) var(--ui-ease),
            visibility var(--ui-duration-fast) var(--ui-ease),
            transform var(--ui-duration-fast) var(--ui-ease-move);
    }

    .ui-project-photo-map-view-full {
        top: 0;
        height: auto;
    }

    .ui-project-photo-map-view-hidden {
        visibility: hidden;
        opacity: 0;
        transform: translateY(var(--space-lg));
        pointer-events: none;
    }

    @media (max-width: 1100px) {
        .ui-project-photo-layout {
            grid-template-columns: minmax(0, 1fr);
        }

        .ui-project-photo-map-column {
            position: static;
            height: min(50dvh, 24rem);
            min-height: 20rem;
        }

        form.ui-project-photo-filters {
            position: static;
        }
    }

    .ui-project-photo-map-panel .gm-style-iw-d {
        overflow: hidden !important;
    }

    .ui-project-photo-map-panel .gm-style-iw-c {
        padding: 0 !important;
        overflow: hidden;
        pointer-events: none;
    }

    .ui-project-photo-map-panel .gm-style-iw-c:focus,
    .ui-project-photo-map-panel .gm-style-iw-c:focus-visible {
        outline: 0 !important;
    }

    .ui-project-photo-map-panel .gm-style-iw-tc {
        pointer-events: none;
    }

    .ui-project-photo-map-panel .gm-style-iw-tc::after {
        background: var(--white);
    }

    .ui-project-photo-map-panel .gm-style-iw-chr {
        position: absolute;
        top: var(--space-3xs);
        right: var(--space-3xs);
        z-index: calc(var(--z-raised) + 2);
        height: 0 !important;
        min-height: 0 !important;
        overflow: visible;
    }

    .ui-project-photo-map-panel .gm-style-iw-ch {
        display: none;
    }

    .ui-project-photo-map-panel .gm-ui-hover-effect {
        width: 1.75rem !important;
        height: 1.75rem !important;
        border-radius: var(--rounded-full);
        background: transparent !important;
        opacity: 1;
        pointer-events: auto;
    }

    .ui-project-photo-map-panel .gm-ui-hover-effect > span {
        margin: 0.375rem !important;
        background-color: var(--white) !important;
    }

    /* Custom CSS: Stimulus-generated map markers share their numbered-circle
       styles here; Prewind has no text-xs utility. */
    .ui-photo-map-marker {
        box-sizing: border-box;
        display: inline-flex;
        width: 2rem;
        height: 2rem;
        align-items: center;
        justify-content: center;
        border: 1px solid var(--white);
        border-radius: var(--rounded-full);
        background: var(--brand-1);
        color: var(--black);
        font-family: var(--font-body);
        font-size: var(--text-xs);
        font-weight: var(--font-bold);
        line-height: 1;
        box-shadow: var(--ui-marker-shadow);
        cursor: pointer;
        user-select: none;
    }

    .ui-photo-map-marker.is-empty {
        width: 1rem;
        height: 1rem;
        background: var(--brand-1);
        color: transparent;
    }

    .ui-photo-map-marker.is-selected {
        box-shadow:
            0 0 0 1px var(--white),
            var(--ui-marker-shadow);
    }

    .ui-photo-map-card {
        box-sizing: border-box;
        width: min(15rem, 72vw);
        height: min(26rem, 72dvh);
        position: relative;
        overflow: hidden;
        border-radius: var(--rounded-sm);
        background: var(--dark);
        color: var(--white);
        font-family: var(--font-body);
        box-shadow: var(--shadow);
        pointer-events: none;
    }

    .ui-photo-map-card-compact {
        width: min(7.5rem, 36vw);
        height: min(13rem, 36dvh);
    }

    .ui-photo-map-card-compact .ui-photo-map-card-body {
        padding: var(--space-xs) var(--space-sm);
    }

    .ui-photo-map-card-compact .ui-photo-map-card-link {
        margin-top: 0;
    }

    .ui-photo-map-card-image {
        box-sizing: border-box;
        display: block;
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
        background: var(--dark);
    }

    .ui-photo-map-card-body {
        box-sizing: border-box;
        position: absolute;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: var(--z-raised);
        width: 100%;
        padding: var(--space-xs) var(--space-sm) var(--space-sm);
        background: var(--ui-photo-viewer-chrome);
    }

    .ui-photo-map-card-detail {
        margin: var(--space-3xs) 0 0;
        color: color-mix(in oklch, var(--white) 88%, transparent);
        font-size: var(--text-base);
        line-height: 1.25;
    }

    .ui-photo-map-card-label {
        color: color-mix(in oklch, var(--white) 72%, transparent);
        font-weight: var(--font-semibold);
    }

    .ui-photo-map-card-link {
        display: inline-flex;
        margin-top: var(--space-xs);
        align-items: center;
        color: var(--white);
        font-size: var(--text-base);
        font-weight: var(--font-bold);
        text-decoration: underline;
        pointer-events: auto;
    }

    .ui-project-photo-detail-overlay {
        text-shadow: 0 1px 2px rgb(0 0 0 / 45%);
    }

    .ui-illustrated-empty-state {
        display: flex;
        flex: 1 1 auto;
        min-height: 16rem;
        align-items: center;
        justify-content: center;
        flex-direction: column;
        padding: var(--space-2xl) var(--space-xl);
        color: var(--darker);
        text-align: center;

        img {
            display: block;
            width: min(100%, 20rem);
            height: auto;
        }
    }

    .ui-pwa-raised-empty-state {
        /* Raise PWA empty states above fixed action areas. */
        padding-bottom: 225px;
    }

    .ui-illustrated-empty-state-copy {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: var(--space-sm);
        max-width: 20rem;
        margin-top: var(--space-xl);

        p {
            margin: 0;
            color: var(--midtone);
            font-size: var(--text-base);
            line-height: 1.25;
        }
    }

    /* Custom CSS: the shared empty state needs a title, action and optional
       who-can helper beyond its original illustration/paragraph callers. */
    .ui-empty-state-title {
        margin: var(--space-sm) 0 0;
        color: var(--darker);
        font-size: var(--text-lg);
        font-weight: var(--font-bold);
        line-height: 1.25;
    }

    .ui-empty-state-action {
        margin-top: var(--space-md);
    }

    .ui-empty-state-who-can {
        margin: var(--space-md) 0 0;
        color: var(--midtone);
        font-size: var(--text-sm);
    }

    /* Custom CSS: the guide's icon-form empty state uses a semibold title and a
       --text-sm explanation; illustration callers keep their original type. */
    .ui-icon-empty-state .ui-empty-state-title {
        font-weight: var(--font-semibold);
    }

    .ui-icon-empty-state .ui-illustrated-empty-state-copy p {
        font-size: var(--text-sm);
    }

    /*
      SECTION: Project chat
      Chat sidebars and PWA message layout.
    */

    .ui-project-chat-sidebar {
        flex: 0 0 min(18rem, 34vw);
    }

    .ui-project-chat-pwa-page {
        height: var(--ui-project-chat-viewport-height, 100dvh);
        min-height: var(--ui-project-chat-viewport-height, 100dvh);
        max-height: var(--ui-project-chat-viewport-height, 100dvh);
        overscroll-behavior: none;
    }

    .ui-project-chat-thread {
        overscroll-behavior-y: contain;
        -webkit-overflow-scrolling: touch;
    }

    .ui-project-chat-thread > :first-child {
        margin-top: auto;
    }

    .ui-project-chat-composer {
        flex: 0 0 auto;
    }

    .ui-project-chat-composer-form .ui-field {
        min-width: 0;
    }

    .ui-project-chat-bubble {
        box-sizing: border-box;
        width: fit-content;
        max-width: min(100%, 44rem);
    }

    .ui-project-chat-content .ui-project-chat-bubble {
        font-size: var(--text-base);
    }

    .ui-project-chat-pwa-page .ui-project-chat-bubble {
        font-size: var(--text-lg);
    }

    /*
      SECTION: Floating actions and toggles
      FAB menu, modal breakpoint overrides, and the shared toggle switch.
    */

    /* Floating Action Button
    ---------------------------------- */
    .ui-fab {
        position: fixed;
        right: var(--space-md);
        bottom: calc(var(--space-lg) + env(safe-area-inset-bottom));
        z-index: var(--z-fab);
        display: flex;
        flex-direction: column;
        align-items: flex-end;
        gap: var(--space-xs);
        pointer-events: none;
    }

    .ui-pwa-primary-navigation ~ .ui-fab {
        bottom: calc(
            4rem + var(--space-sm) +
                max(var(--space-md), env(safe-area-inset-bottom))
        );
    }

    .ui-fab-actions {
        display: flex;
        flex-direction: column;
        align-items: flex-end;
        gap: var(--space-sm);
        opacity: 0;
        transform: translateY(8px) scale(0.95);
        pointer-events: none;
        transition:
            opacity var(--ui-duration-fast) var(--ui-ease),
            transform var(--ui-duration-fast) var(--ui-ease-move);
    }

    .ui-fab[data-ui-fab-side-value="left"] {
        right: auto;
        left: calc(var(--space-md) + env(safe-area-inset-left));
        align-items: flex-start;
    }

    .ui-fab[data-ui-fab-side-value="left"] .ui-fab-actions {
        align-items: flex-start;
    }

    [data-ui-fab-open-value="true"] .ui-fab-actions {
        opacity: 1;
        transform: translateY(0) scale(1);
        pointer-events: auto;
    }

    .ui-fab-action,
    .ui-fab-toggle {
        border: none;
        background: var(--brand-1);
        color: var(--brand-1-content);
        box-shadow: var(--shadow);
        cursor: pointer;
        -webkit-tap-highlight-color: transparent;
        outline: none;

        &:hover {
            filter: brightness(1.08);
        }
    }

    .ui-fab-action {
        display: inline-flex;
        align-items: center;
        gap: var(--space-xs);
        min-height: var(--ui-tap-min);
        padding: var(--space-sm);
        border-radius: var(--rounded);
        font-weight: 600;
        font-size: var(--text-base);
        text-decoration: none;
        white-space: nowrap;
        pointer-events: none;
        transition: filter var(--ui-duration-fast) var(--ui-ease);

        &:active {
            transform: translateY(0.5px);
        }

        svg {
            flex: 0 0 auto;
        }
    }

    [data-ui-fab-open-value="true"] .ui-fab-action {
        pointer-events: auto;
    }

    .ui-fab-toggle {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 4rem;
        height: 4rem;
        border-radius: var(--rounded-lg);
        pointer-events: auto;
        transition:
            transform var(--ui-duration-move) var(--ui-ease-move),
            filter var(--ui-duration-fast) var(--ui-ease);

        &:active {
            transform: scale(0.95);
        }

        .ui-fab-icon-open {
            transition: transform var(--ui-duration-move) var(--ui-ease-move);
        }
    }

    .ui-fab[data-ui-fab-draggable-value="true"] .ui-fab-toggle {
        touch-action: none;
    }

    .ui-fab.is-dragging .ui-fab-toggle {
        cursor: grabbing;
    }

    .ui-fab.is-dragging,
    .ui-fab.is-settling {
        will-change: transform;
    }

    [data-ui-fab-open-value="true"] .ui-fab-toggle .ui-fab-icon-open {
        transform: rotate(135deg);
    }

    @media (max-width: 780px) {
        .ui-project-dialog {
            width: min(42rem, calc(100vw - 1rem));
        }

        .ui-project-modal-shell {
            height: auto;
            max-height: calc(100dvh - 1rem);
        }

        .ui-project-form-layout {
            grid-template-columns: 1fr;
        }

        .ui-project-form-layout-modal {
            overflow: auto;
        }

        .ui-project-form-layout-modal .ui-project-form-panel {
            overflow: visible;
        }

        .ui-project-form-map-panel {
            border-left: 0;
            border-top: 1px solid var(--light);
        }

        .ui-project-map-frame {
            min-height: 18rem;
        }
    }

    /* Toggle Button */
    .ui-toggle {
        --toggle-width: var(--ui-tap-write);
        --toggle-height: 2rem;
        --toggle-text-size: 1.25rem;
        --toggle-padding: 0.25rem;
        --toggle-off-bg: var(--ui-toggle-off);
        --toggle-on-bg: var(--brand-1);
        --toggle-thumb-bg: var(--white);
        --toggle-text-color: #b3b3b3;
        --toggle-text-size: 1rem;

        display: inline-flex;
        align-items: center;
        min-height: var(--ui-tap-min);
        gap: 1rem;
        cursor: pointer;
        user-select: none;
        -webkit-tap-highlight-color: transparent;
    }

    .ui-toggle-input {
        position: absolute;
        opacity: 0;
        pointer-events: none;
    }

    .ui-toggle-switch {
        position: relative;
        flex: 0 0 auto;
        width: var(--toggle-width);
        height: var(--toggle-height);
        border-radius: 9999px;
        background: var(--toggle-off-bg);
        transition: background var(--ui-duration-fast) var(--ui-ease);
    }

    .ui-toggle-switch::after {
        content: "";
        position: absolute;
        top: var(--toggle-padding);
        left: var(--toggle-padding);
        width: calc(var(--toggle-height) - (var(--toggle-padding) * 2));
        height: calc(var(--toggle-height) - (var(--toggle-padding) * 2));
        border-radius: 9999px;
        background: var(--toggle-thumb-bg);
        box-shadow: var(--shadow-sm);
        transition: transform var(--ui-duration-fast) var(--ui-ease-move);
    }

    .ui-toggle-text {
        color: var(--toggle-text-color);
        font-size: var(--toggle-text-size);
        font-weight: 700;
        line-height: 1.2;
    }

    /* Custom CSS: the shared toggle's visual state lives on a sibling span, and
       the guide's disabled tokens replace fading the whole control. The hairline
       is an inset ring so the existing switch size and shape stay unchanged. */
    .ui-toggle:has(.ui-toggle-input:disabled) {
        cursor: not-allowed;
    }

    .ui-toggle-input:disabled + .ui-toggle-switch {
        background: var(--lighter);
        box-shadow: inset 0 0 0 var(--border) var(--hairline);
    }

    .ui-toggle-input:disabled + .ui-toggle-switch::after {
        background: var(--faint);
        box-shadow: none;
    }

    .ui-toggle-input:disabled ~ .ui-toggle-text {
        color: var(--faint);
    }

    .ui-toggle-input:checked:not(:disabled) + .ui-toggle-switch {
        background: var(--toggle-on-bg);
    }

    .ui-toggle-input:checked + .ui-toggle-switch::after {
        transform: translateX(calc(var(--toggle-width) - var(--toggle-height)));
    }

    /* Custom CSS: the input's focus is drawn on its sibling switch, which the
       shared control focus rule cannot select. */
    .ui-toggle-input:focus-visible + .ui-toggle-switch {
        outline: var(--ui-focus-ring);
        outline-offset: var(--ui-focus-offset);
    }
}

/*
  SECTION: Component layer extras
  Debug-only wrappers and shared component-layer controls outside the main
  styles layer.
*/

/* Debug highlight — rendered only when config.x.show_debug_highlights is on.
   Wraps a region in a bright dashed outline with a floating label so
   not-yet-designed / not-yet-wired UI is obvious during dev walkthroughs. */
@layer components {
    .ui-debug-note {
        position: relative;
        outline: 2px dashed oklch(70% 0.2 330);
        outline-offset: 2px;
        border-radius: 4px;
    }

    .ui-debug-note::before {
        content: "? " attr(data-label);
        position: absolute;
        top: -0.75rem;
        left: 0.25rem;
        padding: 0 0.375rem;
        font-size: 0.625rem;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.05em;
        color: white;
        background: oklch(60% 0.22 330);
        border-radius: 4px;
        z-index: var(--z-raised);
        pointer-events: none;
        max-width: 90%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* Shared control states (#235). Custom CSS: Prewind has no :is()/attribute
       state selectors, and the component layer must beat variant utilities such
       as .ui-button.ui-brand-1 without specificity games. */
    :where(.ui-button, .ui-pwa-bottom-action, .ui-journal-chip, .ui-forms-filter-chip,
           .ui-form-picker-option, .ui-fab-action, .ui-project-photo-zoom-control,
           .ui-project-journal-action-split-half):is(:disabled, [aria-disabled="true"]),
    :where(.ui-button, .ui-pwa-bottom-action, .ui-journal-chip, .ui-forms-filter-chip,
           .ui-form-picker-option, .ui-fab-action, .ui-project-photo-zoom-control,
           .ui-project-journal-action-split-half):is(:disabled, [aria-disabled="true"]):hover,
    :where(.ui-button, .ui-pwa-bottom-action, .ui-journal-chip, .ui-forms-filter-chip,
           .ui-form-picker-option, .ui-fab-action, .ui-project-photo-zoom-control,
           .ui-project-journal-action-split-half):is(:disabled, [aria-disabled="true"]):active {
        background: var(--lighter);
        color: var(--faint);
        border-color: var(--hairline);
        box-shadow: none;
        opacity: 1;
        filter: none;
        transform: none;
        cursor: not-allowed;
    }

    /* Busy buttons keep their own native disabling and labels; this only blocks
       pointer input while the action is in progress. */
    :where(.ui-button)[aria-busy="true"] {
        pointer-events: none;
        cursor: progress;
    }

    /* One focus ring for native controls. Custom CSS: Prewind has no
       :focus-visible state, and this replaced the removed per-component gold
       rules so every control shares --ui-focus-ring. */
    :where(button, a, [role="button"], summary, .ui-journal-chip, .ui-forms-filter-chip):focus-visible {
        outline: var(--ui-focus-ring);
        outline-offset: var(--ui-focus-offset);
    }

    /* White ring only on genuinely dark chrome (drawer, dark viewer header and
       its dark footer/toolbar). */
    :where(.ui-pwa-drawer, .ui-pwa-header-dark,
           .ui-project-photo-viewer-toolbar, .ui-project-photo-viewer-footer) :focus-visible {
        outline: var(--ui-focus-ring-on-dark);
    }

    /* Light surfaces nested inside dark chrome keep the ink ring: the viewer
       dropdown's focused children and the light gallery handle. This runs after
       the dark rule so it wins for those descendants. */
    :where(.ui-project-photo-viewer-menu) :focus-visible,
    :where(.ui-gallery-sheet-handle):focus-visible {
        outline: var(--ui-focus-ring);
    }

    /* Dark selected and open filter states (#223). Custom CSS: these must beat
       the light Prewind text utilities on the chips and Journal toggle. */
    :where(.ui-forms-filter-chip)[aria-expanded="true"],
    :where(.ui-journal-filter-panel[open]) > .ui-journal-filter-toggle {
        background: var(--darker);
        border-color: var(--darker);
        color: var(--white);
        font-weight: var(--font-semibold);
    }
}

@layer styles {
    /* Custom CSS: native button reset and a deliberate 44pt (~58.67px) minimum
       have no equivalent Prewind utility; the exact prior minimum is preserved
       and is intentionally larger than the 48px --ui-tap-min floor. */
    .ui-document-download-card {
        appearance: none;
        font: inherit;
        padding: 0;
        min-height: 44pt;
    }

    /* Custom CSS: override the global table cells/striping only for documents;
       collapsed rules and sticky filename cells have no Prewind utilities. */
    .ui-document-table {
        border-collapse: collapse;
        min-width: var(--max-w-form);
    }

    .ui-document-table th,
    .ui-document-table td {
        padding: var(--space-xs) var(--space-sm);
        border-bottom: var(--border) solid var(--lighter);
    }

    .ui-document-table th {
        background: var(--white);
        color: var(--dark);
        font-size: var(--text-sm);
        font-weight: var(--font-semibold);
    }

    .ui-document-table tbody tr {
        --ui-document-row-bg: var(--white);
        background: var(--ui-document-row-bg);
    }

    .ui-document-table tbody tr:nth-child(even) {
        --ui-document-row-bg: color-mix(in srgb, var(--lighter) 50%, var(--white));
        background: var(--ui-document-row-bg);
    }

    .ui-document-table tbody tr:hover {
        --ui-document-row-bg: var(--lighter);
        background: var(--ui-document-row-bg);
    }

    .ui-document-table td {
        background: var(--ui-document-row-bg);
    }

    .ui-document-table th:first-child,
    .ui-document-table td:first-child {
        position: sticky;
        left: 0;
        z-index: var(--z-raised);
        width: 100%;
        min-width: 16rem;
        white-space: normal;
    }

    .ui-document-table [data-document-name] {
        overflow-wrap: anywhere;
    }

    /* Custom CSS: place the row menu above its trigger to keep the last row's
       action inside the horizontally scrolling table, including a one-row list. */
    .ui-document-table .ui-dropdown menu {
        top: auto;
        bottom: calc(100% + var(--space-2xs));
        margin: 0;
    }

    /* Custom CSS: the unread edge retains the Journal card's other borders. */
    .ui-document-unread {
        border-left: var(--space-3xs) solid var(--brand-1);
    }

    /* Custom CSS: cap the desktop queue's viewport height without overlaying
       the document table; Prewind has no viewport-calculation utilities. */
    .ui-document-upload-panel {
        max-height: min(40dvh, 24rem);
    }
}

/* ============================================================
   UI components. Ordinary rules live in `styles`, below Prewind,
   so view utilities win. Rules that intentionally override a
   Prewind utility live in `components`, above Prewind, and name
   the utility they beat.
   ============================================================ */

@layer styles {
    /* Custom CSS: Prewind has no matching size for capped evidence thumbnails. */
    .ui-form-report-photo { width: 10rem; height: 10rem; object-fit: cover; }

    /* Custom CSS: the mobile Forms shortcuts need four equal columns and a stable
       tap area; Prewind has no grid utilities or matching minimum tile height. */
    .ui-forms-shortcuts { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-xs); }
    .ui-forms-shortcut { min-width: 0; min-height: 6.75rem; }

    /* Custom CSS: keep the compact PDF download form from forcing its card wider
       than its container; no Prewind min-width utility applies to this child. */
    .ui-forms-card-download form { min-width: 0; }

    /* Custom CSS: Prewind lacks tile grids, token-based tap heights and open-state transforms.
       The summary keeps its tap height; the open-day group-relative changes live
       in components because they must beat the caller's utilities. */
    .ui-journal-tile-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-xs); padding-block: var(--space-xs); }
    .ui-journal-day-summary { min-height: var(--ui-tap-min); }
    .ui-journal-day[open] .ui-journal-day-chevron { transform: rotate(180deg); }
    @media (min-width: 768px) { .ui-journal-tile-grid { grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr)); } }

    /* Custom CSS: cached tiles expand natively to show their saved content;
       Prewind cannot hide the native summary marker across browsers. */
    .ui-quick-note-offline-detail > summary { list-style: none; cursor: pointer; }
    .ui-quick-note-offline-detail > summary::-webkit-details-marker { display: none; }

    /* Custom CSS: Prewind has no grid utilities for the detail's photo grid. */
    .ui-quick-note-photo-strip { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }

    /* Custom CSS: a single photo reads wide, matching the guide's one-photo rule. */
    .ui-quick-note-photo-strip > :only-child { grid-column: span 2; }
    .ui-quick-note-photo-wide { aspect-ratio: 16 / 9; }

    /* Custom CSS: the guide's exact 12/14px note padding has no Prewind utility pair. */
    .ui-quick-note-note-panel {
        padding: 12px 14px;
    }

    /* Custom CSS: Prewind has no 48px minimum height utility for an openable file row. */
    .ui-quick-note-file-row { min-height: var(--ui-tap-min); }

    /* Custom CSS: offline-disabled menu actions include links, which cannot use
       the native :disabled state; dim them and make them inert. */
    .ui-quick-note-detail-action-disabled {
        opacity: 0.5;
        pointer-events: none;
    }

    /* Custom CSS: decoded document pages need a bounded scroll area and must retain zoom beyond ordinary image max-width rules. */
    .ui-document-preview {
      max-height: 70dvh;
    }
    .ui-document-preview :is(canvas, img) {
      max-width: none;
    }

    /* Custom CSS: map pills require the handoff's exact 36px face and 56x48px tap area; clusters use categorical rings and satellite outlines. */
    .ui-map-marker {
      width: 56px;
      height: 48px;
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;
    }
    .ui-map-marker-face {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: var(--space-3xs);
      min-width: 48px;
      min-height: 36px;
      padding: 0 var(--space-2xs);
      border: 2px solid var(--white);
      border-radius: var(--rounded-full);
      background: var(--brand-1);
      color: var(--darker);
      font-weight: 700;
      box-shadow: var(--ui-marker-shadow);
    }
    /* The decided gold-pin edge: the white face border plus a 1px darker outer ring. */
    .ui-map-marker:not(.ui-map-marker-group):not(.ui-map-marker-notes) .ui-map-marker-face { outline: 1px solid var(--darker); }
    .ui-map-marker-notes .ui-map-marker-face { background: var(--info); color: var(--white); outline: 0; }
    .ui-map-marker-group .ui-map-marker-face {
      min-width: 48px;
      width: 48px;
      height: 48px;
      font-size: var(--text-sm);
      padding: 0;
      background: var(--black);
      color: var(--white);
      border: 3px solid var(--brand-1);
      outline: 2px solid var(--white);
    }
    .ui-map-marker-group.ui-map-marker-notes .ui-map-marker-face { border-color: var(--info); }
    .ui-map-marker-group.ui-map-marker-mixed .ui-map-marker-face { border-color: var(--info) var(--brand-1) var(--brand-1) var(--info); }
    .ui-map-marker-group.ui-map-marker-gallery .ui-map-marker-face { border: 0; }
    .ui-map-marker.is-selected .ui-map-marker-face { transform: translateY(-6px); box-shadow: var(--ui-marker-shadow-lift); }
    /* Custom CSS: the in-map preview card needs scroll-snap, a two-line clamp
       and focus states that Prewind cannot express as utilities; the track gap
       is part of the snap offset the controller reads. Ordinary layout, spacing
       and colors reuse the shipped tokens. */
    .ui-map-preview { position: absolute; right: var(--space-sm); bottom: var(--space-sm); left: var(--space-sm); z-index: var(--z-raised); display: grid; gap: var(--space-2xs); pointer-events: none; }
    .ui-map-preview-position { justify-self: center; margin: 0; padding: var(--space-3xs) var(--space-sm); border-radius: var(--rounded-full); background: color-mix(in oklch, var(--white) 92%, transparent); box-shadow: var(--ui-marker-shadow); font-size: var(--text-sm); font-weight: var(--font-semibold); color: var(--darker); }
    .ui-map-preview-track { display: flex; gap: var(--space-xs); overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; pointer-events: auto; }
    .ui-map-preview-track::-webkit-scrollbar { display: none; }
    .ui-map-preview-card { box-sizing: border-box; display: grid; flex: none; width: 100%; scroll-snap-align: start; grid-template-columns: var(--ui-tap-write) minmax(0, 1fr) 1rem; align-items: center; gap: var(--space-sm); padding: var(--space-xs); border-radius: var(--rounded); background: var(--white); color: var(--darker); text-decoration: none; box-shadow: var(--ui-sheet-shadow); }
    /* A single card fills the bar; a row of cards peeks the next one. */
    .ui-map-preview-card:not(:only-child) { width: 88%; scroll-snap-align: center; }
    .ui-map-preview-card:focus-visible { outline: var(--ui-focus-ring); outline-offset: 2px; }
    .ui-map-preview-media { display: grid; place-items: center; width: var(--ui-tap-write); height: var(--ui-tap-write); overflow: hidden; border-radius: var(--rounded); background: var(--lighter); color: var(--midtone); }
    .ui-map-preview-image { width: 100%; height: 100%; object-fit: cover; }
    .ui-map-preview-body { display: grid; gap: var(--space-3xs); min-width: 0; }
    .ui-map-preview-when { font-size: var(--text-sm); }
    .ui-map-preview-note { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; font-size: var(--text-base); line-height: 1.3; color: var(--dark); }
    .ui-map-preview-summary { font-size: var(--text-sm); color: var(--midtone); }
    .ui-map-preview-chevron { display: grid; place-items: center; color: var(--midtone); }
    /* Custom CSS: the PWA Gallery sheet overlays the map. Keep the selected
       card above its existing half/peek stops; Prewind cannot target this state. */
    [data-gallery-stop="half"] .ui-gallery-map .ui-map-preview { bottom: calc(50% + var(--space-sm)); }
    [data-gallery-stop="peek"] .ui-gallery-map .ui-map-preview { bottom: calc(var(--ui-tap-min) + var(--space-sm)); }
    /* Custom CSS: Google injects its controls with its own sizing and the guide
       requires exact 48px Layers/Fit All buttons; Prewind cannot reach the Maps
       control container. Active state is ink, the named gold exception is only
       for pins and clusters. */
    .ui-map-controls { display: grid; gap: var(--space-xs); margin: var(--space-sm); }
    .ui-map-control { display: grid; place-items: center; width: var(--ui-tap-min); height: var(--ui-tap-min); border: 0; border-radius: var(--rounded-sm); background: var(--white); color: var(--darker); box-shadow: var(--ui-marker-shadow); cursor: pointer; }
    .ui-map-control.is-active { background: var(--darker); color: var(--white); }
    .ui-map-control:focus-visible { outline: var(--ui-focus-ring); outline-offset: 2px; }

    /* Custom CSS: Google injects its zoom buttons with a 40px face. The map's +/-
       must meet the 48px tap floor; Prewind cannot reach into the Maps DOM. */
    [data-controller="maps--projects-map"] .gm-control-active,
    [data-controller="maps--photo-map"] .gm-control-active {
      min-width: var(--ui-tap-min);
      min-height: var(--ui-tap-min);
    }

    /* Custom CSS: independent desktop reading columns and a viewport-bounded map are not covered by Prewind's layout utilities. */
    .ui-journal-reading-workspace { display: grid; grid-template-columns: minmax(18rem, 2fr) minmax(0, 3fr); align-items: start; }
    .ui-journal-reading-pane { position: sticky; top: var(--space-sm); max-height: calc(100dvh - 10rem); overflow-y: auto; }
    .ui-journal-map-viewport { height: 50dvh; min-height: 16rem; }
    .ui-journal-unread-dot { width: var(--space-xs); height: var(--space-xs); flex: none; border-radius: var(--rounded-full); background: var(--info); }
    @media (max-width: 900px) {
      .ui-journal-reading-workspace { grid-template-columns: minmax(0, 1fr); }
      .ui-journal-reading-pane { position: static; max-height: none; }
    }

    /* Custom CSS: sheet stops and map stacking need viewport-relative geometry.
       Preserve the specified 12px map gap at rest and the existing 48px handle.
       The map is the local base; sheet and coverage step up from --z-raised so
       their relative order is explicit. */
    .ui-gallery-map-workspace { isolation: isolate; }
    .ui-gallery-map { z-index: 0; }
    .ui-gallery-sheet { position: absolute; inset: var(--ui-sheet-gap) 0 0; z-index: calc(var(--z-raised) + 1); box-shadow: var(--ui-sheet-shadow); }
    .ui-gallery-sheet-handle { min-height: var(--ui-tap-min); cursor: grab; touch-action: none; user-select: none; border-radius: var(--rounded-lg) var(--rounded-lg) 0 0; }
    /* Custom CSS: Prewind cannot draw the specified centered 54x5px grip, one
       --ui-sheet-gap below the sheet top. This decorative pill leaves the whole
       handle clickable. */
    .ui-gallery-sheet-handle::before { content: ""; position: absolute; top: var(--ui-sheet-gap); left: 50%; width: 54px; height: 5px; transform: translateX(-50%); border-radius: var(--rounded-full); background: var(--ui-sheet-grip); pointer-events: none; }
    [data-gallery-stop="half"] .ui-gallery-sheet { top: 50%; }
    [data-gallery-stop="peek"] .ui-gallery-sheet { top: calc(100% - var(--ui-tap-min)); }
    .ui-gallery-coverage { z-index: calc(var(--z-raised) + 2); bottom: var(--ui-tap-min); }

    /* Custom CSS: existing PDF actions need the specified 48px tap area, including
       compact links/buttons in history cards and tables. Prewind has no exact minimum. */
    .ui-form-pdf-action { display: inline-flex; align-items: center; justify-content: center; min-width: var(--ui-tap-min); min-height: var(--ui-tap-min); }

    /* Custom CSS: Prewind has no CSS Grid, so the shared sheet/dialog heading
       owns fixed 48px side columns that keep its title truly centred while a
       long heading wraps inside the flexible middle track. */
    .ui-dialog-header { display: grid; grid-template-columns: var(--ui-tap-min) minmax(0, 1fr) var(--ui-tap-min); align-items: center; column-gap: var(--space-sm); }

    /* Custom CSS: dedicated dialog close controls need an exact 48px target and
       focus-visible state; small row actions retain their existing sizes. */
    .ui-dialog-close { width: var(--ui-tap-min); height: var(--ui-tap-min); border: 0; background: transparent; cursor: pointer; }
    .ui-dialog-close:active { background: var(--light); }

    /* Custom CSS: Support's specified 56px Send target and the reused Forms SVG's
       28px navigation size have no exact Prewind sizing utilities. */
    .ui-support-send { min-height: var(--ui-tap-write); }
    .ui-project-journal-action-icon { width: 1.75rem; height: 1.75rem; }

    /* Custom CSS: Chat's specified 56px square Send target and 24px glyph have no
       exact Prewind sizing utilities; the round .ui-button would otherwise be
       free-form width. This later styles-layer rule keeps the glyph override over
       the earlier `.ui-button > svg` size on equal specificity. */
    .ui-chat-send { width: var(--ui-tap-write); height: var(--ui-tap-write); min-height: var(--ui-tap-write); }
    .ui-chat-send > svg { width: 1.5rem; height: 1.5rem; }
}

@layer components {
    /* Custom CSS: the download-failure state expands the compact PDF control to a
       full card row, beating the caller's `flex-none` utility. */
    .ui-forms-card-download:has([role="status"]:not(.hidden)) { flex-basis: 100%; max-width: 100%; }

    /* Custom CSS: an open day drops its folded white box; these beat the summary's
       `bg-white`, `border-light`, `rounded-sm` and `border` utilities. */
    .ui-journal-day[open] .ui-journal-day-summary { background: transparent; border-color: transparent; border-radius: 0; }

    /* Custom CSS: the excerpt is line-clamped with -webkit-box; this beats the
       `block` utility on the element. */
    .ui-quick-note-excerpt { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 5; overflow: hidden; overflow-wrap: anywhere; }

    /* Custom CSS: the focused reading row shows its focus border; this beats
       the `border-light` utility on the row. It is not the unread-document
       marker. */
    .ui-journal-reading-row:has(a:focus) { border-color: var(--brand-1); }

    /* Custom CSS: Prewind's `flex` utility overrides the browser's [hidden]
       display, so the applied filter summary must hide explicitly here. */
    .ui-projects-filter-summary[hidden] { display: none; }

    /* Custom CSS: the Projects filter button needs an ink active state with its
       count; this overrides the base `ui-button` background, border and text. */
    .ui-projects-filter-button.is-active { border-color: var(--darker); background: var(--darker); color: var(--white); }

    /* Custom CSS: the checked Me chip must show ink over the caller's
       `bg-white`, `border-light` and `text-dark` utilities. */
    .ui-projects-filter-chip input:checked + .ui-projects-filter-chip-label { border-color: var(--darker); background: var(--darker); color: var(--white); }

    /* Custom CSS: shared focus precedence. The shared ring earlier in this
       layer would win on layer order alone, so these more specific selectors
       keep the marker blue and the dialog/shortcut offsets instead of it. */
    .ui-forms-shortcut:focus-visible { outline: 2px solid var(--darker); outline-offset: var(--space-3xs); }
    .ui-form-pdf-action:focus-visible { outline: 2px solid var(--darker); outline-offset: var(--space-3xs); }
    .ui-dialog-close:focus-visible { outline: 2px solid var(--darker); outline-offset: -2px; }
    .ui-map-marker:focus-visible { outline: 2px solid var(--info); border-radius: var(--rounded); }
}

@layer components {
    /* Custom CSS: the note sheet caps the dynamic viewport at the specified 86%,
       contains its scrolling body, and clears the device bottom safe area. */
    .ui-note-sheet[open] {
        max-height: 86dvh;
        overflow: hidden;
        gap: var(--space-sm);
        padding-bottom: calc(var(--space-sm) + env(safe-area-inset-bottom));
    }
    .ui-note-sheet [hidden] { display: none !important; }

    /* Custom CSS: a composite field needs focus-within and space for the in-box
       mic; the helper textarea must share its border with the attachments. */
    .ui-note-sheet-field {
        padding-bottom: calc(var(--space-sm) + var(--ui-tap-min));
        border: 1px solid var(--muted);
    }
    .ui-note-sheet-field:focus-within {
        border-color: var(--darker);
        box-shadow: inset 0 0 0 1px var(--darker);
    }

    /* Custom CSS: exact attachment/button dimensions match guide 5.21. The
       existing 56px write token covers tiles/buttons; 28px has no utility. */
    .ui-note-sheet-attach, .ui-note-sheet-file-type { font-size: var(--text-xs); }
    .ui-note-sheet-attach, .ui-note-sheet-save { min-height: var(--ui-tap-write); }
    .ui-note-sheet-attach, .ui-note-sheet-label { border: 1px solid var(--hairline); }
    .ui-note-sheet-attachment, .ui-note-sheet-file {
        width: var(--ui-tap-write);
        height: var(--ui-tap-write);
    }
    .ui-note-sheet-remove {
        position: absolute;
        top: calc(-1 * var(--space-xs));
        right: calc(-1 * var(--space-xs));
        width: var(--ui-tap-min);
        height: var(--ui-tap-min);
        isolation: isolate;
        background: transparent;
        border: 0;
    }
    .ui-note-sheet-remove::before {
        content: "";
        position: absolute;
        width: 1.75rem;
        height: 1.75rem;
        border-radius: var(--rounded-full);
        background: var(--darker);
        z-index: -1;
    }

    /* Custom CSS: visible label toggles need a 48px target and pressed state. */
    .ui-note-sheet-label { min-height: var(--ui-tap-min); }
    .ui-note-sheet-label[aria-pressed="true"] {
        border-color: var(--darker);
        background: var(--darker);
        color: var(--white);
    }
/* Custom CSS: the Journal §5.8 control needs exact 48px tap targets with the
   field border, a combined selected + focus treatment for chips and the tray's
   native controls, a positioned sort menu and a two-column result row. Prewind
   utilities cover ordinary state and position, but not these combined control
   treatments or the result grid, so only those gaps live here. */
.ui-journal-search-open,
.ui-journal-filter-button {
    min-height: var(--ui-tap-min);
    border: var(--ui-field-border);
}
.ui-journal-search-open { padding-inline: var(--space-sm); }
.ui-journal-filter-button { width: var(--ui-tap-min); padding-inline: var(--space-2xs); }
.ui-journal-filter-button.is-active {
    border-color: var(--darker);
    background: var(--darker);
    color: var(--white);
}
.ui-journal-filter-count {
    min-width: 1.125rem;
    height: 1.125rem;
    padding-inline: var(--space-3xs);
    border-radius: var(--rounded-full);
    background: var(--white);
    color: var(--darker);
    display: inline-grid;
    place-items: center;
}

/* Repeated chip ownership for the Journal search row: a selected ink chip reads
   as one control everywhere. Scoped under .ui-journal-filters so the shared
   .ui-journal-chip badges and sizes stay untouched. */
.ui-journal-filters .ui-journal-chip {
    min-height: var(--ui-tap-min);
    padding-inline: var(--space-sm);
    border: var(--ui-field-border);
    border-radius: var(--rounded-full);
    background: var(--white);
    color: var(--darker);
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
    white-space: nowrap;
}
.ui-journal-filters .ui-journal-chip.is-active {
    border-color: var(--darker);
    background: var(--darker);
    color: var(--white);
}

/* Sort menu overlaps the list; utilities cannot position an overlay */
.ui-journal-sort { position: relative; }
.ui-journal-sort-menu {
    position: absolute;
    z-index: var(--z-popover);
    top: calc(100% + var(--space-3xs));
    left: 0;
    background: var(--white);
    border: 1px solid var(--light);
    border-radius: var(--rounded-sm);
    box-shadow: var(--shadow);
    overflow: hidden;
}
.ui-journal-sort-menu button {
    width: 100%;
    min-height: var(--ui-tap-min);
    padding-inline: var(--space-sm);
    border: 0;
    border-top: 1px solid var(--light);
    background: none;
    text-align: left;
    color: var(--darker);
}
.ui-journal-sort-menu button:first-child { border-top: 0; }

/* The tray's native radios/checkboxes hide visually but stay announced and focusable */
.ui-journal-tray-chip { position: relative; }
.ui-journal-tray-chip input { position: absolute; opacity: 0; pointer-events: none; }
.ui-journal-tray-chip > span {
    min-height: var(--ui-tap-min);
    padding-inline: var(--space-sm);
    border: var(--ui-field-border);
    border-radius: var(--rounded-full);
    background: var(--white);
    color: var(--darker);
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
}
.ui-journal-tray-chip input:checked + span {
    border-color: var(--darker);
    background: var(--darker);
    color: var(--white);
}
.ui-journal-tray-chip input:focus-visible + span {
    outline: 2px solid var(--darker);
    outline-offset: 2px;
}

/* Result row geometry: a fixed thumbnail column with a flexible text column */
.ui-journal-search-result-link {
    display: grid;
    grid-template-columns: 4rem minmax(0, 1fr);
    gap: var(--space-sm);
    align-items: center;
    padding: var(--space-2xs);
    background: var(--white);
    border: 1px solid var(--light);
    border-radius: var(--rounded-sm);
    color: var(--darker);
}
.ui-journal-search-result-thumb {
    position: relative;
    width: 4rem;
    height: 4rem;
    border-radius: var(--rounded-sm);
    display: grid;
    place-items: center;
    background: var(--lighter);
    color: var(--midtone);
}
.ui-journal-search-result-count {
    position: absolute;
    left: var(--space-3xs);
    bottom: var(--space-3xs);
    padding-inline: var(--space-2xs);
    border-radius: var(--rounded-full);
    background: color-mix(in oklab, var(--darker) 78%, transparent);
    color: var(--white);
    font-weight: 700;
}


/* Recent-search rows and Clear All are full 48px tap targets */
.ui-journal-recent-run,
.ui-journal-recent-remove,
.ui-journal-recents-clear { min-height: var(--ui-tap-min); }
.ui-journal-recent-remove { min-width: var(--ui-tap-min); }

/* Cancel is a 48px text action (Guide §5.8) */
.ui-journal-search-cancel {
    min-height: var(--ui-tap-min);
    display: inline-flex;
    align-items: center;
}

/* Custom CSS: the open quick-label row scrolls sideways with a right-edge fade
   (Guide §5.8). The filter pill and sort chip stay pinned outside this row so the
   sort menu is never clipped by the scroll container. */
.ui-journal-search-chips {
    overflow-x: auto;
    flex-wrap: nowrap;
    scrollbar-width: none;
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 2rem), transparent);
    mask-image: linear-gradient(90deg, #000 calc(100% - 2rem), transparent);
}
.ui-journal-search-chips::-webkit-scrollbar { display: none; }
}
