/* ---------------------------------------------------------------------------
   Scienter eFinance - mobile

   Mobile-first and written from scratch: the web module's scienter-ui.css is
   built around a 12-column desktop grid and is not linked here. What IS carried
   over is the token block below, so the two products look like one.
   --------------------------------------------------------------------------- */

:root {
    /* same values as Assests/css/scienter-ui.css:19-32 in the web module */
    --sui-pri: #064664;
    --sui-pri-2: #0a5f88;
    --sui-pri-soft: #e9f1f5;
    --sui-bd: #d6dee3;
    --sui-lbl: #24373f;
    --sui-txt: #1f2d34;
    --sui-muted: #7a8a93;
    --sui-ok: #1e9e63;
    --sui-danger: #d64545;
    --sui-radius: 6px;
    /* sampled from destinityinspirelogo.png - the accent in the wordmark */
    --brand-orange: #f0801f;
    --sui-font: 'Segoe UI', 'Trebuchet MS', Arial, sans-serif;

    /* mobile-only */
    --tap: 44px;                 /* minimum comfortable touch target */
    --bg: #f4f7f9;
    --safe-top: env(safe-area-inset-top, 0px);
    --safe-bottom: env(safe-area-inset-bottom, 0px);
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
    margin: 0;
    padding: 0;
    min-height: 100%;
}

body {
    font-family: var(--sui-font);
    font-size: 15px;              /* 15-16px: anything smaller invites zoom */
    color: var(--sui-txt);
    background: var(--bg);
    -webkit-text-size-adjust: 100%;
    overscroll-behavior-y: contain;
}

/* screens ------------------------------------------------------------------ */

.screen { display: none; min-height: 100vh; }
.screen.is-active { display: block; }

.content {
    padding: 14px 14px calc(20px + var(--safe-bottom));
}

/* app bar ------------------------------------------------------------------ */

.appbar {
    position: sticky;
    top: 0;
    z-index: 10;
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 52px;
    padding: calc(8px + var(--safe-top)) 12px 8px;
    background: var(--sui-pri);
    color: #fff;
}

.appbar-title { flex: 1 1 auto; min-width: 0; line-height: 1.2; }
.appbar-title strong { display: block; font-size: 15px; font-weight: 700; }
.appbar-title small { display: block; font-size: 11.5px; opacity: .8; }

.appbar-btn,
.appbar-back {
    flex: 0 0 auto;
    min-height: var(--tap);
    min-width: var(--tap);
    padding: 0 10px;
    font: inherit;
    font-size: 13px;
    color: #fff;
    background: transparent;
    border: 0;
    cursor: pointer;
}

.appbar-back { font-size: 22px; line-height: 1; }

/* Icon-only, so it needs a shape to be pressed rather than a word: a round
   tap target that tints on touch. The glyph is the web top bar's own
   logout.png - white on transparent, which is exactly what this bar wants. */
.appbar-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--tap);
    padding: 0;
    border-radius: 50%;
}

    .appbar-icon img {
        display: block;
        width: 21px;
        height: 21px;
    }

    .appbar-icon:active { background: rgba(255, 255, 255, .16); }

/* login ---------------------------------------------------------------------
   Two bands: a dark brand field, and a white sheet that lifts over it.

   The band is dark because the LOGO requires it - "Inspire" and the tagline in
   destinity-inspire.png are white, and only "Destinity" is orange, so on a
   light background half the wordmark vanishes. The teal is the web module's
   own --sui-pri, and the texture over it is the logo's checkerboard motif: the
   screen belongs to the product rather than merely quoting its colours.
   --------------------------------------------------------------------------- */

.login {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100dvh;           /* the honest height once the URL bar collapses */
    background: var(--sui-pri);   /* behind the sheet, so no white edge shows */
}

/* the band ------------------------------------------------------------------
   A single flat gradient reads as a coloured rectangle. Three layers instead:
   the base wash, a cool glow low-left, and the wordmark's own orange high-right
   where the eye lands first. */
.login-hero {
    position: relative;
    display: flex;
    flex-direction: column;       /* wordmark, then the product line */
    align-items: center;
    justify-content: center;
    padding: calc(42px + var(--safe-top)) 24px 46px;
    background: linear-gradient(158deg, #0b6a97 0%, #064664 52%, #04283a 100%);
    overflow: hidden;
}

    .login-hero::before,
    .login-hero::after {
        content: "";
        position: absolute;
        border-radius: 50%;
        pointer-events: none;
    }

    /* cool light, low and left - lifts the bottom corner off flat */
    .login-hero::before {
        left: -110px;
        bottom: -140px;
        width: 300px;
        height: 300px;
        background: radial-gradient(circle, rgba(64, 190, 238, .30), transparent 70%);
    }

    /* the warm one, from the logo, where the eye arrives */
    .login-hero::after {
        top: -100px;
        right: -90px;
        width: 260px;
        height: 260px;
        background: radial-gradient(circle, rgba(240, 128, 31, .40), transparent 68%);
    }

    /* the mark's checkerboard, barely there, and masked so it fades out before
       it meets the sheet rather than stopping at a hard edge */
    .login-hero-mark {
        position: absolute;
        inset: 0;
        background-image: conic-gradient(rgba(255, 255, 255, .06) 0 25%, transparent 0 50%);
        background-size: 30px 30px;
        -webkit-mask-image: linear-gradient(#000 30%, transparent 92%);
        mask-image: linear-gradient(#000 30%, transparent 92%);
        pointer-events: none;
    }

.login-logo {
    position: relative;           /* above the glows and the texture */
    display: block;
    width: min(78%, 330px);
    height: auto;
}

/* Which product this is. Named, not explained: the same wordmark, the same
   teal and the same product line as the desktop app is what tells someone they
   are in their GL. Saying "mobile version" would only make it sound like the
   smaller one.

   "eFinance" is NOT uppercased - text-transform would render it EFINANCE, which
   is not its name. The caps are on the module half only. */
.login-product {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 9px;
    margin: 18px 0 0;
    padding: 7px 15px 7px 14px;

    /* a piece of glass on the gradient. The blur is progressive enhancement -
       without it the translucent fill alone still reads correctly. */
    background: rgba(255, 255, 255, .10);
    border: 1px solid rgba(255, 255, 255, .18);
    border-radius: 999px;
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    box-shadow: 0 6px 18px rgba(2, 22, 33, .22);
}

    .login-product-a {
        font-size: 13px;
        font-weight: 700;
        letter-spacing: .1px;
        color: #fff;
    }

    /* the separator: the wordmark's orange, and the only warm point on the band
       besides the corner bloom - so the eye ties the two together */
    .login-product-b::before {
        content: "";
        display: inline-block;
        width: 4px;
        height: 4px;
        margin-right: 9px;
        vertical-align: 2px;
        border-radius: 50%;
        background: var(--brand-orange);
        box-shadow: 0 0 0 3px rgba(240, 128, 31, .18);
    }

    .login-product-b {
        font-size: 10.5px;
        font-weight: 700;
        letter-spacing: 1.7px;
        text-transform: uppercase;
        color: rgba(255, 255, 255, .78);
    }

/* the sheet ---------------------------------------------------------------- */

.login-sheet {
    position: relative;
    z-index: 1;
    flex: 1 0 auto;
    margin-top: -24px;            /* the sheet rises over the band */
    padding: 28px 22px calc(20px + var(--safe-bottom));
    background: #fff;
    border-radius: 26px 26px 0 0;
    box-shadow: 0 -14px 34px rgba(3, 26, 38, .34);
}

    /* a lit top edge, so the sheet reads as raised rather than pasted on */
    .login-sheet::before {
        content: "";
        position: absolute;
        top: 0;
        left: 26px;
        right: 26px;
        height: 1px;
        background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .9), transparent);
    }

.login-head { margin-bottom: 22px; }

    .login-head h1 {
        margin: 0 0 3px;
        font-size: 22px;
        font-weight: 700;
        letter-spacing: -.3px;
        color: var(--sui-pri);
    }

    /* the one place the brand accent appears on the white half - enough to tie
       the two bands together without repainting anything */
    .login-head::after {
        content: "";
        display: block;
        width: 34px;
        height: 3px;
        margin-top: 13px;
        border-radius: 2px;
        background: var(--brand-orange);
    }

.login-sub { margin: 0; font-size: 13px; color: var(--sui-muted); }

.login-form { display: flex; flex-direction: column; gap: 15px; }

/* fields, login only --------------------------------------------------------
   Filled rather than outlined: a tinted row is what a phone keyboard is used to
   sitting under, and focus then has somewhere to go - the field lifts to white
   with a teal ring, which stays obvious with a thumb over half the screen.
   Scoped to .login-sheet so the lists and filters elsewhere keep their own
   plainer fields. */
.login-sheet .fld-in {
    position: relative;
    display: block;
}

.login-sheet .fld-ico {
    position: absolute;
    top: 50%;
    left: 13px;
    width: 18px;
    height: 18px;
    transform: translateY(-50%);
    fill: #93a4ad;
    pointer-events: none;
    transition: fill .15s ease;
}

.login-sheet .fld input {
    height: 50px;
    padding: 0 14px 0 42px;
    background: #f4f8fa;
    border: 1px solid #e4ebef;
    border-radius: 12px;
    transition: background .15s ease, border-color .15s ease, box-shadow .15s ease;
}

.login-sheet .fld input:focus {
    background: #fff;
    border-color: var(--sui-pri-2);
    box-shadow: 0 0 0 4px rgba(10, 95, 136, .13);
}

.login-sheet .fld-in:focus-within .fld-ico { fill: var(--sui-pri-2); }

/* password reveal -----------------------------------------------------------
   Typing a password blind on a phone keyboard is where most failed sign-ins
   come from, so the eye earns its place. */
.login-sheet .fld-in input[type="password"],
.login-sheet .fld-in input[type="text"]#txtPassword { padding-right: 48px; }

.fld-eye {
    position: absolute;
    top: 50%;
    right: 5px;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    color: #93a4ad;
    background: none;
    border: 0;
    border-radius: 10px;
    cursor: pointer;
}

    .fld-eye svg { width: 20px; height: 20px; fill: currentColor; }
    .fld-eye:active { background: #eef3f6; }
    .fld-eye.is-on { color: var(--sui-pri-2); }
    .fld-eye .eye-off { display: none; }
    .fld-eye.is-on .eye-on { display: none; }
    .fld-eye.is-on .eye-off { display: block; }

/* the button ----------------------------------------------------------------
   The spinner is driven by :disabled, which app.js already sets for exactly as
   long as the sign-in call runs. No new JS and no second piece of state that
   can fall out of step with the first. */
.login-sheet .btn-primary {
    position: relative;
    gap: 10px;
    margin-top: 8px;
    min-height: 50px;
    font-size: 15.5px;
    letter-spacing: .3px;
    border-radius: 12px;
    background: linear-gradient(180deg, #0c6b99 0%, var(--sui-pri) 100%);
    box-shadow: 0 10px 22px rgba(6, 70, 100, .30);
    transition: transform .12s ease, box-shadow .12s ease;
}

.login-sheet .btn-primary:active {
    transform: scale(.985);
    box-shadow: 0 4px 12px rgba(6, 70, 100, .26);
}

/* signing in: keep it looking live, and say so */
.login-sheet .btn-primary:disabled {
    opacity: 1;
    background: linear-gradient(180deg, #2b7ba3 0%, #1b5a7c 100%);
    box-shadow: none;
}

.btn-spin { display: none; }

.login-sheet .btn-primary:disabled .btn-spin {
    display: block;
    width: 17px;
    height: 17px;
    border: 2px solid rgba(255, 255, 255, .35);
    border-top-color: #fff;
    border-radius: 50%;
    animation: login-spin .7s linear infinite;
}

@keyframes login-spin { to { transform: rotate(360deg); } }

.login-error {
    margin: 0;
    padding: 11px 13px;
    font-size: 13px;
    font-weight: 600;
    color: #8f2b2b;
    background: #fdeeee;
    border: 1px solid #f4c9c9;
    border-left: 3px solid var(--sui-danger);
    border-radius: 10px;
    animation: login-shake .35s ease;
}

/* a refused password should be felt, not just read */
@keyframes login-shake {
    0%, 100% { transform: translateX(0); }
    22% { transform: translateX(-5px); }
    55% { transform: translateX(4px); }
    80% { transform: translateX(-2px); }
}

.login-foot {
    margin-top: 24px;
    padding-top: 14px;
    text-align: center;
    border-top: 1px solid #eef2f4;
}

    .login-by {
        margin: 0;
        font-size: 11px;
        letter-spacing: .5px;
        text-transform: uppercase;
        color: var(--sui-muted);
    }

        .login-by strong {
            font-weight: 800;
            letter-spacing: 1.4px;
            color: var(--sui-pri);
        }

    .login-meta {
        display: flex;
        gap: 8px;
        justify-content: center;
        margin: 7px 0 0;
        font-size: 11px;
        color: #9aa8b0;
    }

.net-state { color: var(--sui-danger); font-weight: 700; }

/* the entrance --------------------------------------------------------------
   Logo, product line, sheet, then the fields in sequence - a little over half a
   second end to end. It is the difference between a page appearing and an app
   opening, and it costs nothing at runtime. */
@keyframes login-rise {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: none; }
}

@keyframes login-sheet-up {
    from { opacity: 0; transform: translateY(30px); }
    to   { opacity: 1; transform: none; }
}

.login-logo    { animation: login-rise .55s .04s both cubic-bezier(.2, .8, .2, 1); }
.login-product { animation: login-rise .55s .16s both cubic-bezier(.2, .8, .2, 1); }
.login-sheet   { animation: login-sheet-up .6s .10s both cubic-bezier(.2, .8, .2, 1); }
.login-head    { animation: login-rise .5s .26s both cubic-bezier(.2, .8, .2, 1); }

.login-form .fld:nth-of-type(1) { animation: login-rise .5s .34s both cubic-bezier(.2, .8, .2, 1); }
.login-form .fld:nth-of-type(2) { animation: login-rise .5s .40s both cubic-bezier(.2, .8, .2, 1); }
.login-form .btn-primary        { animation: login-rise .5s .46s both cubic-bezier(.2, .8, .2, 1); }
.login-foot                     { animation: login-rise .5s .54s both cubic-bezier(.2, .8, .2, 1); }

/* someone who has asked the OS for less motion means it */
@media (prefers-reduced-motion: reduce) {
    .login-logo,
    .login-product,
    .login-sheet,
    .login-head,
    .login-form .fld:nth-of-type(1),
    .login-form .fld:nth-of-type(2),
    .login-form .btn-primary,
    .login-foot,
    .login-error {
        animation: none;
    }

    .login-sheet .btn-primary { transition: none; }
}

/* short screens - landscape, or a small phone with the keyboard up: take the
   room out of the band rather than making the form scroll */
@media (max-height: 640px) {
    .login-hero { padding: calc(24px + var(--safe-top)) 24px 34px; }
    .login-logo { width: min(62%, 260px); }
    .login-product { margin-top: 12px; padding: 6px 13px; }
    .login-head { margin-bottom: 16px; }
    .login-sheet .fld input { height: 46px; }
    .login-foot { margin-top: 16px; }
}

/* fields ------------------------------------------------------------------- */

.fld { display: block; }
.fld[hidden] { display: none; }

.fld-label {
    display: block;
    margin-bottom: 5px;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .3px;
    text-transform: uppercase;
    color: var(--sui-lbl);
}

.fld input,
.fld select {
    width: 100%;
    height: var(--tap);
    padding: 0 12px;
    font-family: inherit;
    font-size: 16px;              /* 16px stops iOS zooming the page on focus */
    color: var(--sui-txt);
    background: #fff;
    border: 1px solid var(--sui-bd);
    border-radius: var(--sui-radius);
    outline: none;
}

.fld input:focus,
.fld select:focus {
    border-color: var(--sui-pri);
    box-shadow: 0 0 0 3px var(--sui-pri-soft);
}

/* buttons ------------------------------------------------------------------ */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--tap);
    padding: 0 18px;
    font-family: inherit;
    font-size: 15px;
    font-weight: 600;
    color: var(--sui-txt);
    background: #eef2f4;
    border: 1px solid var(--sui-bd);
    border-radius: var(--sui-radius);
    cursor: pointer;
}

.btn-primary { color: #fff; background: var(--sui-pri); border-color: var(--sui-pri); }
.btn-primary:active { background: var(--sui-pri-2); }
.btn-block { width: 100%; }
.btn:disabled { opacity: .6; }

/* dashboard ----------------------------------------------------------------
   The web module's landing hero (Default.aspx), narrowed to a phone: the same
   eyebrow, greeting, company/date line and financial year. It carries the
   login screen's band as well, so signing in and arriving here is one surface
   rather than two designs. */

.dash-hero {
    position: relative;
    margin: -14px -14px 14px;     /* out to the edges, over .content padding */
    padding: 18px 18px 20px;
    background: linear-gradient(158deg, #0b6a97 0%, #064664 62%, #04283a 100%);
    overflow: hidden;
}

    /* the same warm corner as the login band */
    .dash-hero::after {
        content: "";
        position: absolute;
        top: -80px;
        right: -70px;
        width: 200px;
        height: 200px;
        border-radius: 50%;
        background: radial-gradient(circle, rgba(240, 128, 31, .34), transparent 68%);
        pointer-events: none;
    }

.dash-hero-inner {
    position: relative;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 14px;
}

.dash-hero-left { min-width: 0; }

.dash-eyebrow {
    margin: 0 0 5px;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .62);
}

.dash-title {
    margin: 0;
    font-size: 19px;
    font-weight: 700;
    letter-spacing: -.2px;
    line-height: 1.25;
    color: #fff;
}

    /* the name is the one warm word on the band */
    .dash-name { color: var(--brand-orange); }

.dash-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 7px;
    margin: 9px 0 0;
    font-size: 12px;
    color: rgba(255, 255, 255, .76);
}

    .dash-co { font-weight: 600; }

    .dash-dot {
        width: 3px;
        height: 3px;
        border-radius: 50%;
        background: rgba(255, 255, 255, .45);
    }

/* the financial year, right, as on the web hero. Hidden until the call
   answers - a failed lookup leaves the band alone rather than showing an
   empty label. */
.dash-fy {
    flex: 0 0 auto;
    padding: 8px 12px;
    text-align: right;
    background: rgba(255, 255, 255, .10);
    border: 1px solid rgba(255, 255, 255, .17);
    border-radius: 12px;
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
}

.dash-fy[hidden] { display: none; }

    .dash-fy-label {
        margin: 0;
        font-size: 9.5px;
        font-weight: 700;
        letter-spacing: 1.1px;
        text-transform: uppercase;
        color: rgba(255, 255, 255, .6);
    }

    .dash-fy-value {
        margin: 3px 0 0;
        font-size: 13px;
        font-weight: 700;
        white-space: nowrap;
        color: #fff;
    }

/* home tiles --------------------------------------------------------------- */

.tiles { display: grid; grid-template-columns: 1fr; gap: 10px; }

/* the sub nav these tiles came from - central's own heading. Quiet: it
   groups, it is not a thing to be read first. */
.tiles-head {
    margin: 14px 2px 2px;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 1.3px;
    text-transform: uppercase;
    color: var(--sui-muted);
}

    .tiles-head:first-child { margin-top: 2px; }

@media (min-width: 560px) {
    /* a heading spans both columns, or the grid would set it beside a tile */
    .tiles-head { grid-column: 1 / -1; }
}

@media (min-width: 560px) {
    .tiles { grid-template-columns: 1fr 1fr; }
}

/* The count is why someone opens the app - "is anything waiting for me" - so
   it sits on the right at the size of a headline, and the tile is laid out
   around it rather than the other way round. */
.tile {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas:
        "title count"
        "hint  count";
    align-items: center;
    column-gap: 12px;
    width: 100%;
    min-height: 72px;
    padding: 14px 14px 14px 16px;
    text-align: left;
    font-family: inherit;
    background: #fff;
    border: 1px solid var(--sui-bd);
    border-left: 4px solid var(--sui-pri);
    border-radius: 12px;
    cursor: pointer;
    transition: background .14s ease, border-color .14s ease, transform .14s ease;
}

.tile:active {
    background: var(--sui-pri-soft);
    border-color: #bfd6e2;
    border-left-color: var(--sui-pri);
    transform: scale(.99);
}

.tile-title {
    grid-area: title;
    display: block;
    font-size: 15px;
    font-weight: 700;
    color: var(--sui-txt);
}

.tile-hint {
    grid-area: hint;
    display: block;
    margin-top: 3px;
    font-size: 12.5px;
    color: var(--sui-muted);
}

.tile-count {
    grid-area: count;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 40px;
    height: 40px;
    padding: 0 9px;
    font-size: 19px;
    font-weight: 800;
    letter-spacing: -.5px;
    border-radius: 12px;
}

    /* something waits */
    .tile-count.is-waiting {
        color: #fff;
        background: linear-gradient(160deg, #0c6b99 0%, var(--sui-pri) 100%);
        box-shadow: 0 4px 10px rgba(6, 70, 100, .24);
    }

    /* the queue is clear - present, but quiet */
    .tile-count.is-clear {
        color: #a9b7be;
        background: #f2f6f8;
    }

    /* still counting, or the count could not be had: no number, no noise */
    .tile-count.is-loading,
    .tile-count.is-unknown {
        min-width: 0;
        padding: 0;
        background: none;
    }

    .tile-count.is-loading::after {
        content: "";
        width: 15px;
        height: 15px;
        border: 2px solid #dfe7eb;
        border-top-color: var(--sui-pri-2);
        border-radius: 50%;
        animation: login-spin .7s linear infinite;
    }

@media (prefers-reduced-motion: reduce) {
    .tile { transition: none; }
    .tile-count.is-loading::after { animation: none; }
}

.empty { padding: 24px 4px; text-align: center; color: var(--sui-muted); font-size: 13.5px; }

/* list --------------------------------------------------------------------- */

/* The bar and the search box, stuck to the top as one piece. The box used
   to scroll away with the rows, which is backwards: a long list is the
   only time you want to filter it, and it was the only time the filter
   was off screen. */
.listhead {
    position: sticky;
    top: 0;
    z-index: 10;
    background: var(--bg);
}

    /* the wrapper sticks, so the bar inside it must not try to as well -
       two sticky boxes in a row would leave the search box behind */
    .listhead .appbar { position: static; }

    .listhead .searchbar {
        margin: 0;
        padding: 10px 14px;
        border-bottom: 1px solid #e3ebef;
    }

        /* the filter reads as part of the header, not as the first row of
           the list, so it takes the same filled field as everything else */
        .listhead .searchbar input {
            height: 42px;
            background: #fff;
            border-radius: 10px;
        }

.searchbar { margin-bottom: 12px; }

.searchbar input {
    width: 100%;
    height: var(--tap);
    padding: 0 12px;
    font-family: inherit;
    font-size: 16px;
    background: #fff;
    border: 1px solid var(--sui-bd);
    border-radius: var(--sui-radius);
    outline: none;
}

.list { display: flex; flex-direction: column; gap: 8px; }

/* one pending item ---------------------------------------------------------
   A card, not a table row: on a phone the amount and the party matter more
   than column alignment, and a whole card is an easier target than a cell. */

.card {
    display: block;
    width: 100%;
    padding: 12px 14px;
    text-align: left;
    font-family: inherit;
    background: #fff;
    border: 1px solid var(--sui-bd);
    border-left: 4px solid var(--sui-pri);
    border-radius: var(--sui-radius);
    cursor: pointer;
}

.card:active { background: var(--sui-pri-soft); }

.card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
}

.card-title { font-size: 14.5px; font-weight: 700; color: var(--sui-txt); }

/* the figure the decision turns on - biggest thing on the card */
.card-amount {
    flex: 0 0 auto;
    font-size: 15px;
    font-weight: 700;
    color: var(--sui-pri);
    white-space: nowrap;
}

.card-sub {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    margin-top: 3px;
    font-size: 12.5px;
    color: var(--sui-muted);
}

.card-sub span:first-child {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.card-date { flex: 0 0 auto; }

.card-meta { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; }

.chip {
    padding: 2px 8px;
    font-size: 11px;
    font-weight: 600;
    color: var(--sui-lbl);
    background: var(--sui-pri-soft);
    border-radius: 10px;
}

.errorbox {
    padding: 20px 14px;
    text-align: center;
    font-size: 13.5px;
    color: var(--sui-muted);
}

.errorbox p { margin: 0 0 12px; }

/* approve / reject --------------------------------------------------------- */

.act-amount {
    margin: 2px 0 0;
    font-size: 17px;
    font-weight: 700;
    color: var(--sui-pri);
}

/* facts, lines and trail scroll together as one column */
.act-scroll {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
}

.act-facts { padding: 4px 16px; }

.fact {
    display: flex;
    gap: 12px;
    padding: 9px 0;
    border-bottom: 1px solid #eef2f5;
}

.fact:last-child { border-bottom: 0; }

.fact-k {
    flex: 0 0 40%;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .3px;
    text-transform: uppercase;
    color: var(--sui-lbl);
}

.fact-v {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 13.5px;
    color: var(--sui-txt);
    word-break: break-word;
}

.act-blocked {
    margin: 0;
    padding: 12px 16px 16px;
    font-size: 13px;
    color: var(--sui-danger);
}

.act-blocked[hidden] { display: none; }

.act-reason { padding: 12px 16px 0; }
.act-reason[hidden] { display: none; }

.act-reason textarea {
    width: 100%;
    margin-top: 5px;
    padding: 9px 11px;
    font-family: inherit;
    font-size: 16px;
    color: var(--sui-txt);
    background: #fff;
    border: 1px solid var(--sui-bd);
    border-radius: var(--sui-radius);
    outline: none;
    resize: none;
}

.act-reason textarea:focus {
    border-color: var(--sui-pri);
    box-shadow: 0 0 0 3px var(--sui-pri-soft);
}

/* document lines + approval trail, inside the scrolling part of the sheet */

.act-extra { padding: 4px 16px 10px; }
.act-extra[hidden] { display: none; }

.act-sub {
    margin: 12px 0 6px;
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: .3px;
    text-transform: uppercase;
    color: var(--sui-muted);
}

.line { padding: 8px 0; border-bottom: 1px solid #eef2f5; }
.line:last-child { border-bottom: 0; }

.line-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.line-acc { font-size: 13px; font-weight: 600; color: var(--sui-txt); }
.line-amt { flex: 0 0 auto; font-size: 13.5px; font-weight: 700; color: var(--sui-pri); white-space: nowrap; }

.line-bottom { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-top: 2px; }
.line-bottom span:first-child { font-size: 12px; color: var(--sui-muted); }

.line-tag {
    flex: 0 0 auto;
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: .4px;
    color: var(--sui-lbl);
}

/* Reject on the left, Approve on the right and wider: the destructive one
   should never be the thing under the thumb by default. */
.act-buttons {
    display: flex;
    gap: 10px;
    padding: 14px 16px calc(16px + var(--safe-bottom));
    border-top: 1px solid var(--sui-bd);
}

.act-buttons[hidden] { display: none; }

.act-buttons .btn { flex: 1 1 0; }
.act-buttons .btn-ok { flex: 1.4 1 0; }

.btn-ok { color: #fff; background: var(--sui-ok); border-color: var(--sui-ok); }
.btn-danger { color: var(--sui-danger); background: #fff; border-color: var(--sui-danger); }
.btn-danger:active { color: #fff; background: var(--sui-danger); }

/* property picker -----------------------------------------------------------
   A centred dialog, sized to its content but capped, so it reads the same with
   one property or twenty: the panel never grows past 78% of the viewport and
   the LIST scrolls inside it, leaving the title and the search box fixed where
   the eye expects them.

   Centred rather than a bottom sheet: this decision gates everything after it,
   so it belongs in the middle of the screen with the app dimmed behind.

   The teal header is scoped to #propSheet on purpose. The approve / reject
   dialog shares these .pick- classes and carries the amount in its own colour
   in the same place - it must not be repainted. */

.pick {
    position: fixed;
    inset: 0;
    z-index: 800;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px 16px calc(20px + var(--safe-bottom));
}

.pick[hidden] { display: none; }

.pick-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(4, 26, 38, .62);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
}

.pick-panel {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 460px;
    max-height: 78vh;              /* long lists scroll inside, never off-screen */
    overflow: hidden;
    background: #fff;
    border-radius: 20px;
    box-shadow: 0 24px 60px rgba(3, 26, 38, .42);
    animation: pick-in .22s cubic-bezier(.2, .8, .2, 1);
}

@keyframes pick-in {
    from { opacity: 0; transform: translateY(12px) scale(.96); }
    to { opacity: 1; transform: none; }
}

/* head + search stay put; only the list moves */
.pick-head {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 16px 16px 12px;
    border-bottom: 1px solid var(--sui-bd);
}

.pick-heading { flex: 1 1 auto; min-width: 0; }

.pick-head h2 {
    margin: 0;
    font-size: 16px;
    font-weight: 700;
    color: var(--sui-pri);
}

.pick-close {
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    margin: -4px -4px 0 0;
    font-size: 24px;
    line-height: 1;
    color: var(--sui-muted);
    background: transparent;
    border: 0;
    border-radius: 50%;
    cursor: pointer;
}

.pick-close:active { background: var(--sui-pri-soft); }

/* the property dialog only - the same band as the login screen it follows -- */

#propSheet .pick-head {
    position: relative;
    align-items: center;
    padding: 17px 16px;
    background: linear-gradient(158deg, #0b6a97 0%, #064664 100%);
    border-bottom: 0;
}

    /* the same orange accent the login screen uses, as a hairline under the
       band rather than a rule on the white */
    #propSheet .pick-head::after {
        content: "";
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        height: 2px;
        background: linear-gradient(90deg, var(--brand-orange), rgba(240, 128, 31, 0) 62%);
    }

    #propSheet .pick-head h2 {
        font-size: 16.5px;
        letter-spacing: -.1px;
        color: #fff;
    }

    #propSheet .pick-close {
        margin: 0 -4px 0 0;
        color: rgba(255, 255, 255, .85);
    }

    #propSheet .pick-close:active { background: rgba(255, 255, 255, .16); }

.pick-search { padding: 12px 16px; border-bottom: 1px solid var(--sui-bd); }
.pick-search[hidden] { display: none; }

.pick-search input {
    width: 100%;
    height: var(--tap);
    padding: 0 12px;
    font-family: inherit;
    font-size: 16px;               /* 16px: anything less and iOS zooms the page */
    background: #fff;
    border: 1px solid var(--sui-bd);
    border-radius: var(--sui-radius);
    outline: none;
}

.pick-search input:focus {
    border-color: var(--sui-pri);
    box-shadow: 0 0 0 3px var(--sui-pri-soft);
}

/* the filled field from the login screen, so the two look like one product */
#propSheet .pick-search { border-bottom: 0; padding: 12px 12px 4px; }

#propSheet .pick-search input {
    height: 46px;
    padding: 0 14px;
    background: #f4f8fa;
    border: 1px solid #e4ebef;
    border-radius: 12px;
}

#propSheet .pick-search input:focus {
    background: #fff;
    border-color: var(--sui-pri-2);
    box-shadow: 0 0 0 4px rgba(10, 95, 136, .13);
}

.pick-list {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;  /* scrolling the list never scrolls the page */
    padding: 6px 0;
}

/* Cards, not divided lines. With a single property one card reads as a
   deliberate choice, where one row between two rules reads as a list that
   failed to load. */
#propSheet .pick-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px;
}

/* one row = logo, name, chevron. 56px keeps it comfortably tappable even when
   fifteen of them are stacked. */
.pick-item {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    min-height: 56px;
    padding: 10px 16px;
    text-align: left;
    font-family: inherit;
    background: transparent;
    border: 0;
    cursor: pointer;
}

.pick-item + .pick-item { border-top: 1px solid #eef2f5; }
.pick-item:active { background: var(--sui-pri-soft); }

#propSheet .pick-item {
    min-height: 66px;
    padding: 12px 13px;
    background: #fff;
    border: 1px solid #e7eef2;
    border-radius: 14px;
    transition: background .14s ease, border-color .14s ease, transform .14s ease;
}

#propSheet .pick-item + .pick-item { border-top: 1px solid #e7eef2; }

#propSheet .pick-item:active {
    background: var(--sui-pri-soft);
    border-color: #bfd6e2;
    transform: scale(.988);
}

.pick-logo {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    overflow: hidden;
    font-size: 13px;
    font-weight: 700;
    color: #fff;
    background: var(--sui-pri);
    border-radius: 9px;
}

.pick-logo img { width: 100%; height: 100%; object-fit: cover; }

/* the tile picks up the button gradient rather than sitting flat */
#propSheet .pick-logo {
    width: 44px;
    height: 44px;
    font-size: 14px;
    letter-spacing: .4px;
    background: linear-gradient(160deg, #0c6b99 0%, var(--sui-pri) 100%);
    border-radius: 12px;
    box-shadow: 0 4px 10px rgba(6, 70, 100, .22);
}

.pick-text { flex: 1 1 auto; min-width: 0; }

.pick-name {
    display: block;
    font-size: 14.5px;
    font-weight: 600;
    color: var(--sui-txt);
    line-height: 1.25;
}

#propSheet .pick-name { font-size: 15px; line-height: 1.3; }

.pick-go { flex: 0 0 auto; font-size: 18px; color: var(--sui-muted); }

/* the chevron becomes a target rather than a punctuation mark */
#propSheet .pick-go {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    font-size: 17px;
    line-height: 1;
    color: var(--sui-pri-2);
    background: #eff5f8;
    border-radius: 50%;
}

.pick-empty {
    margin: 0;
    padding: 26px 16px;
    text-align: center;
    font-size: 13.5px;
    color: var(--sui-muted);
}

.pick-empty[hidden] { display: none; }

/* Short screens: let the dialog use nearly all of the height rather than
   squeezing fifteen rows into a small box. */
@media (max-height: 620px) {
    .pick { padding: 10px; }
    .pick-panel { max-height: 94vh; }
    #propSheet .pick-head { padding: 13px 16px; }
    #propSheet .pick-item { min-height: 58px; }
}

@media (prefers-reduced-motion: reduce) {
    .pick-panel { animation: none; }
    #propSheet .pick-item { transition: none; }
}

/* furniture ---------------------------------------------------------------- */

.busy {
    position: fixed;
    inset: 0;
    z-index: 900;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, .55);
}

.busy[hidden] { display: none; }

.busy-dot {
    width: 34px;
    height: 34px;
    border: 3px solid var(--sui-pri-soft);
    border-top-color: var(--sui-pri);
    border-radius: 50%;
    animation: spin .7s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

.toast {
    position: fixed;
    left: 50%;
    bottom: calc(20px + var(--safe-bottom));
    z-index: 950;
    max-width: 88%;
    padding: 11px 16px;
    font-size: 13.5px;
    color: #fff;
    background: #23323a;
    border-radius: 22px;
    transform: translateX(-50%);
}

.toast[hidden] { display: none; }

/* a thin red rule under the app bar while the device is offline */
body.is-offline .appbar { box-shadow: inset 0 -3px 0 var(--sui-danger); }

@media (prefers-reduced-motion: reduce) {
    .busy-dot { animation-duration: 2s; }
}
