/* Splitiz - calm money-app aesthetic
   Design direction: refined clarity, warm neutrals, money-green accent,
   plenty of whitespace, native-feeling on mobile home screens. */

:root {
    /* Colour palette */
    --bg: #FAFAF7;
    --surface: #FFFFFF;
    --surface-2: #F4F4EF;
    --border: #E8E9EC;
    --border-strong: #D4D6DB;

    --primary: #4A9B7E;
    --primary-dark: #3A7D63;
    --primary-soft: #E8F3EE;
    --primary-text: #1F4A38;

    --text: #1A1F2C;
    --text-muted: #6B7280;
    --text-faded: #9CA3AF;

    --owe: #DC4444;
    --owe-soft: #FCEAEA;
    --owed: #16A772;
    --owed-soft: #E5F5EC;
    --warn: #B45309;
    --warn-soft: #FEF3D7;

    --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.04), 0 1px 1px rgba(15, 23, 42, 0.03);
    --shadow-md: 0 4px 12px rgba(15, 23, 42, 0.06), 0 2px 4px rgba(15, 23, 42, 0.04);
    --shadow-lg: 0 12px 32px rgba(15, 23, 42, 0.10);

    --radius-sm: 8px;
    --radius: 12px;
    --radius-lg: 16px;

    --nav-h: 68px;
    --safe-top: env(safe-area-inset-top, 0px);
    --safe-bot: env(safe-area-inset-bottom, 0px);
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--bg);
    color: var(--text);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    font-size: 16px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    overscroll-behavior-y: contain;
    min-height: 100vh;
}

button, input, select, textarea {
    font: inherit;
    color: inherit;
}

a { color: var(--primary-dark); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -0.01em; }
h1 { font-size: 1.6rem; }
h2 { font-size: 1.25rem; }
h3 { font-size: 1.05rem; }
p { margin: 0 0 0.5rem; }

/* --- App layout --- */

#app {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

.page {
    flex: 1;
    padding: calc(var(--safe-top) + 1.25rem) 1.25rem calc(var(--nav-h) + var(--safe-bot) + 1.5rem);
    max-width: 720px;
    width: 100%;
    margin: 0 auto;
}

.page--auth {
    padding-top: calc(var(--safe-top) + 3rem);
    padding-bottom: calc(var(--safe-bot) + 2rem);
}

.page-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.page-header__sub {
    color: var(--text-muted);
    font-size: 0.95rem;
}

/* --- App brand bar ---
   Sits ABOVE #app rather than inside it, because every view replaces the whole
   of #app's innerHTML (setPageHTML) and would wipe it out. It is inserted and
   removed by the router alongside the bottom nav, so it appears on exactly the
   screens that have nav — never on login, register, join or reset.
   Deliberately NOT fixed: scrolling away with the content costs nothing on a
   phone, where vertical space is the scarce thing. */

/* HIDDEN ON MOBILE. On a phone the screen is the scarce resource and the user
   already knows which app they opened — the brand would cost a line of vertical
   space on every screen and tell them nothing. Desktop has room to spare, so
   that is where it earns its place. The router still builds the element either
   way; CSS decides whether it is seen. */
.appbar { display: none; }

@media (min-width: 700px) {
    .appbar {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 0.8rem;
        padding: calc(var(--safe-top) + 1.5rem) 1.25rem 0.9rem;
        background: var(--bg);
    }
    .appbar__logo { width: 54px; height: 54px; display: block; flex: 0 0 54px; }
    .appbar__name {
        font-size: 2.1rem;
        font-weight: 700;
        letter-spacing: -0.035em;
        color: var(--text);
        line-height: 1;
    }
    /* The page supplies its own top padding; with the bar above it, the two
       would stack into a large empty gap. */
    .appbar + #app .page { padding-top: 1rem; }
}

/* --- Bottom nav --- */

.nav {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    background: rgba(255, 255, 255, 0.95);
    backdrop-filter: saturate(180%) blur(16px);
    -webkit-backdrop-filter: saturate(180%) blur(16px);
    border-top: 1px solid var(--border);
    padding-bottom: var(--safe-bot);
    z-index: 50;
    /* Its own compositing layer, on purpose. A fixed element with a
       backdrop-filter is the one combination iOS is known to re-attach to the
       scrolling content mid-flick, which shows up as the bar sliding up the
       screen for a moment and then snapping back. Promoting it keeps it on the
       viewport where it belongs. */
    transform: translateZ(0);
    will-change: transform;
}

/* Columns are counted, not listed, so adding or removing a tab is a change in
   app.js alone. */
.nav__inner {
    max-width: 720px;
    margin: 0 auto;
    height: var(--nav-h);
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
}

.nav__item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.2rem;
    border: none;
    background: transparent;
    color: var(--text-muted);
    padding: 0.5rem 0;
    cursor: pointer;
    transition: color 0.15s;
}

.nav__item svg {
    width: 24px;
    height: 24px;
    stroke: currentColor;
    fill: none;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.nav__item--active {
    color: var(--primary);
}

.nav__label {
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.01em;
    /* "Expenses" on a 320px screen shared four ways. Never wrap to two lines —
       that would push the bar taller than --nav-h and leave the page padding
       short. */
    white-space: nowrap;
}

@media (max-width: 359px) {
    .nav__label { font-size: 0.66rem; letter-spacing: 0; }
}

/* --- Cards --- */

.card {
    background: var(--surface);
    border-radius: var(--radius);
    border: 1px solid var(--border);
    padding: 1rem 1.1rem;
    box-shadow: var(--shadow-sm);
}

.card + .card { margin-top: 0.75rem; }

.card--clickable {
    cursor: pointer;
    transition: transform 0.1s, box-shadow 0.15s;
}
.card--clickable:active { transform: scale(0.99); box-shadow: var(--shadow-sm); }

.card-hero {
    background: linear-gradient(135deg, var(--primary), var(--primary-dark));
    color: white;
    border: none;
    box-shadow: var(--shadow-md);
    padding: 1.5rem 1.25rem;
    border-radius: var(--radius-lg);
}

.card-hero__label {
    text-transform: uppercase;
    font-size: 0.72rem;
    letter-spacing: 0.08em;
    font-weight: 600;
    opacity: 0.9;
}

.card-hero__amount {
    font-size: 2rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    margin-top: 0.4rem;
}

.card-hero__sub {
    opacity: 0.9;
    font-size: 0.92rem;
    margin-top: 0.25rem;
}

/* --- Forms --- */

.field {
    margin-bottom: 1rem;
}

.field__label {
    display: block;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text);
    margin-bottom: 0.4rem;
}

.field__help {
    font-size: 0.8rem;
    color: var(--text-muted);
    margin-top: 0.3rem;
}

.input, .select, .textarea {
    width: 100%;
    padding: 0.7rem 0.85rem;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-strong);
    background: var(--surface);
    font-size: 1rem;
    transition: border-color 0.15s, box-shadow 0.15s;
    -webkit-appearance: none;
    appearance: none;
}

.input:focus, .select:focus, .textarea:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 3px rgba(74, 155, 126, 0.15);
}

/* Highlight required fields the user left empty when they try to save.
   :user-invalid only kicks in after interaction/submit, so the form doesn't
   look red the moment it opens. background-color (not background) keeps the
   select's dropdown-arrow image intact. */
.input:user-invalid, .select:user-invalid, .textarea:user-invalid {
    background-color: var(--owe-soft);
    border-color: var(--owe);
}

.select {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path fill='none' stroke='%236B7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' d='M1 1.5l5 5 5-5'/></svg>");
    background-repeat: no-repeat;
    background-position: right 0.85rem center;
    padding-right: 2.25rem;
}

.field--row {
    display: flex;
    gap: 0.75rem;
}
.field--row > * { flex: 1; }

.input-group {
    display: flex;
    gap: 0;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: var(--surface);
}
.input-group:focus-within {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px rgba(74, 155, 126, 0.15);
}
.input-group .select, .input-group .input {
    border: none;
    border-radius: 0;
}

/* --- Buttons --- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.75rem 1.1rem;
    border-radius: var(--radius-sm);
    border: 1px solid transparent;
    background: var(--surface);
    color: var(--text);
    font-weight: 600;
    cursor: pointer;
    transition: transform 0.08s, background 0.15s, border-color 0.15s;
    text-align: center;
    -webkit-tap-highlight-color: transparent;
}

.btn:active { transform: scale(0.98); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }

.btn--primary {
    background: var(--primary);
    color: white;
}
.btn--primary:hover:not(:disabled) { background: var(--primary-dark); }

.btn--ghost {
    background: transparent;
    border-color: var(--border-strong);
}
.btn--ghost:hover:not(:disabled) { background: var(--surface-2); }

.btn--danger {
    background: var(--owe-soft);
    color: var(--owe);
}
.btn--danger:hover:not(:disabled) { background: #f8d4d4; }

.btn--warn {
    background: #F5A623;
    color: #1A1F2C;
    border-color: #E0930F;
}
.btn--warn:hover:not(:disabled) { background: #E0930F; }

.btn--block { width: 100%; }
.btn--sm { padding: 0.5rem 0.75rem; font-size: 0.88rem; }
.btn--lg { padding: 0.95rem 1.25rem; font-size: 1.05rem; }

.btn-row {
    display: flex;
    gap: 0.6rem;
}
.btn-row > .btn { flex: 1; }

.fab {
    position: fixed;
    right: 1.25rem;
    bottom: calc(var(--nav-h) + var(--safe-bot) + 1rem);
    background: var(--primary);
    color: white;
    width: 56px;
    height: 56px;
    border-radius: 28px;
    border: none;
    box-shadow: var(--shadow-lg);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    z-index: 40;
    transition: transform 0.1s;
}
.fab:active { transform: scale(0.95); }
.fab svg { width: 28px; height: 28px; stroke: white; stroke-width: 2.2; fill: none; stroke-linecap: round; }

/* --- Tabs (used in Balances) --- */

.tabs {
    display: flex;
    background: var(--surface-2);
    padding: 4px;
    border-radius: var(--radius);
    margin-bottom: 1rem;
}

.tabs__btn {
    flex: 1;
    padding: 0.55rem 0.5rem;
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-weight: 600;
    font-size: 0.9rem;
    border-radius: 9px;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}

.tabs__btn--active {
    background: var(--surface);
    color: var(--text);
    box-shadow: var(--shadow-sm);
}

/* --- Lists --- */

.list-item {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.85rem 1rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    margin-bottom: 0.55rem;
    cursor: pointer;
    transition: background 0.15s;
}

.list-item:hover { background: var(--surface-2); }
.list-item:active { background: var(--surface-2); }

.list-item__icon {
    flex: 0 0 40px;
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: var(--primary-soft);
    color: var(--primary);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.2rem;
    font-weight: 600;
}

.list-item__icon svg {
    width: 22px;
    height: 22px;
    stroke: currentColor;
    fill: none;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* --- Trip icon picker --- */
.icon-picker {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.35rem;
}

.icon-picker__item {
    cursor: pointer;
    border-radius: 10px;
    border: 2px solid transparent;
    padding: 2px;
    transition: border-color 0.15s, background 0.15s;
    -webkit-tap-highlight-color: transparent;
}

.icon-picker__item:hover {
    border-color: var(--border-strong);
}

.icon-picker__item--selected {
    border-color: var(--primary);
    background: var(--primary-soft);
}

.list-item__main {
    flex: 1;
    min-width: 0;
}

.list-item__title {
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.list-item__sub {
    color: var(--text-muted);
    font-size: 0.82rem;
    margin-top: 2px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* A third line — the trip name, when a list is showing more than one trip.
   Adding it would make every row taller, so the extra height is taken back out
   of the row's own padding: a mixed-trip list ends up the same height as a
   single-trip one, and the text simply sits closer to the edges. */
/* The ⓘ beside a heading, and the paragraph it reveals.
   The Account tab is a column of settings, and a permanent explanation under
   every heading pushed the controls themselves below the fold. Most of these
   are read once, if ever — so they are there for the asking instead. */
.info-btn {
    appearance: none;
    -webkit-appearance: none;
    width: 1.3rem;
    height: 1.3rem;
    padding: 0;
    margin-left: 0.4rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--text-muted);
    font: 700 0.78rem/1 Georgia, "Times New Roman", serif;
    cursor: pointer;
    vertical-align: 0.08em;
}
.info-btn:hover { color: var(--text); border-color: var(--text-muted); }
.info-btn[aria-expanded="true"] {
    background: var(--primary);
    border-color: var(--primary);
    color: #fff;
}
.info-text { margin-bottom: 0.75rem; }

.list-item--compact {
    padding-top: 0.4rem;
    padding-bottom: 0.4rem;
}

.list-item__trip {
    font-size: 0.75rem;
    margin-top: 0;
    opacity: 0.85;
}

.list-item__aside {
    text-align: right;
    font-weight: 600;
    font-size: 0.95rem;
}

.list-item__aside--owe { color: var(--owe); }
.list-item__aside--owed { color: var(--owed); }
.list-item__aside--neutral { color: var(--text-muted); font-weight: 500; }

.list-section-label {
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--text-faded);
    margin: 1.25rem 0 0.5rem;
}

/* --- Empty state --- */

.empty {
    text-align: center;
    padding: 2.5rem 1rem 1rem;
    color: var(--text-muted);
}
.empty h3 { color: var(--text); margin-bottom: 0.4rem; }

/* --- Pills --- */

.pill {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.2rem 0.55rem;
    border-radius: 100px;
    font-size: 0.75rem;
    font-weight: 600;
    background: var(--surface-2);
    color: var(--text-muted);
}
.pill--primary { background: var(--primary-soft); color: var(--primary-text); }
.pill--owe { background: var(--owe-soft); color: var(--owe); }
.pill--owed { background: var(--owed-soft); color: var(--owed); }
.pill--warn { background: var(--warn-soft); color: var(--warn); }
/* A factual label, not a status — so quiet, and outlined rather than filled, to
   sit next to the green "You" pill without competing with it. */
.pill--owner { background: var(--surface); color: var(--text); border: 1px solid var(--border-strong); }

.draft-badge {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 600;
    line-height: 1.4;
    background: #f4c430;   /* yellow */
    color: #4a3b00;        /* dark text — readable on yellow in light & dark themes */
    vertical-align: middle;
    white-space: nowrap;
}

/* --- Balance status badges (settle/acknowledge) --- */
.badge {
    display: inline-block;
    margin-left: 0.35rem;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.68rem;
    font-weight: 600;
    line-height: 1.5;
    vertical-align: middle;
    white-space: nowrap;
}
.badge--pending { background: #f4c430; color: #4a3b00; }   /* yellow */
.badge--settled { background: #d7f5e3; color: #0f7a4d; }   /* green */

/* --- Friend chips (split selector) --- */

.friend-row {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    padding: 0.65rem 0.5rem;
    border-bottom: 1px solid var(--border);
}
.friend-row:last-child { border-bottom: none; }

.friend-row__check {
    width: 22px;
    height: 22px;
    border-radius: 11px;
    border: 2px solid var(--border-strong);
    background: var(--surface);
    flex: 0 0 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
}
.friend-row__check svg { width: 14px; height: 14px; stroke: white; stroke-width: 3; fill: none; opacity: 0; }
.friend-row__check.checked {
    background: var(--primary);
    border-color: var(--primary);
}
.friend-row__check.checked svg { opacity: 1; }

.friend-row__name { flex: 1; font-weight: 500; }

.friend-row__amount {
    text-align: right;
    color: var(--text-muted);
    font-size: 0.85rem;
}
.friend-row__paid {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.78rem;
    color: var(--text-muted);
    cursor: pointer;
    white-space: nowrap;
    margin-left: 0.25rem;
}
.friend-row__paid input[type="checkbox"] {
    width: 15px;
    height: 15px;
    accent-color: var(--primary);
    cursor: pointer;
    flex-shrink: 0;
}
.friend-row__paid input[type="checkbox"]:disabled {
    cursor: default;
    opacity: 0.6;
}

.friend-row__shares {
    display: flex;
    align-items: center;
    gap: 0.35rem;
}

.share-btn {
    width: 30px; height: 30px;
    border-radius: 8px;
    border: 1px solid var(--border-strong);
    background: var(--surface);
    font-weight: 700;
    color: var(--text-muted);
    cursor: pointer;
    display: flex; align-items: center; justify-content: center;
}
.share-btn:active { background: var(--surface-2); }
.share-value { min-width: 28px; text-align: center; font-weight: 600; }

/* --- Receipt preview --- */

.receipt-preview {
    border-radius: var(--radius);
    overflow: hidden;
    max-height: 320px;
    background: var(--surface-2);
    border: 1px solid var(--border);
}
.receipt-preview img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

/* Zoomable receipt viewer (ReceiptViewer) */
.rv__stage {
    position: relative;
    border-radius: var(--radius);
    overflow: hidden;
    max-height: 320px;
    background: var(--surface-2);
    border: 1px solid var(--border);
}
.rv__img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
    transform-origin: 50% 50%;   /* pinch/pan maths assume centre origin */
    will-change: transform;
    user-select: none;
    -webkit-user-drag: none;
}
/* Enlarged: fixed to the viewport so it stays truly pinned while the form scrolls
   under it (sticky only holds while its short container is on screen). The spacer
   keeps the document's scroll height where the receipt used to be. */
.rv--big .rv__stage {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    margin: 0 auto;
    max-width: 720px;            /* match .page width; full-width on phones */
    height: 55vh;
    max-height: none;
    z-index: 900;
    border-radius: 0;
    touch-action: none;          /* we handle gestures; don't let the page scroll */
    cursor: grab;
    box-shadow: 0 6px 18px rgba(0,0,0,0.35);
}
.rv__spacer { display: none; }
.rv--big .rv__spacer { display: block; height: 55vh; }
/* touch-action must cover the IMG too, not just the stage: the gesture starts on
   whichever element is under the finger, and without this Safari can claim the
   pinch for page zoom before our handlers see it. */
.rv--big .rv__img { touch-action: none; }

/* Zoom controls — only while enlarged. Pinch is natural but undiscoverable, and
   double-tap even more so, so the buttons are the obvious route. */
.rv__zoom { display: none; }
.rv--big .rv__zoom {
    display: flex;
    gap: 0.4rem;
    position: absolute;
    right: 0.5rem;
    bottom: 0.5rem;
    z-index: 6;
}
.rv__zoom button {
    min-width: 2.4rem;
    height: 2.4rem;
    padding: 0 0.6rem;
    border: none;
    border-radius: 1.2rem;
    background: rgba(0,0,0,0.6);
    color: #fff;
    font-size: 1.1rem;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
}
.rv__zoom button:active { background: rgba(0,0,0,0.8); }

.rv__hint { display: none; }
.rv--big .rv__hint {
    display: block;
    position: absolute;
    left: 0.5rem;
    bottom: 0.5rem;
    z-index: 6;
    max-width: 55%;
    padding: 0.35rem 0.6rem;
    border-radius: 0.9rem;
    background: rgba(0,0,0,0.55);
    color: #fff;
    font-size: 0.72rem;
    line-height: 1.3;
    pointer-events: none;    /* never swallow a drag that starts here */
}

/* Enlarge on the left, any extra action (e.g. Remove) on the right. */
.rv__actions {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.5rem;
}
.rv--big .rv__actions { display: none; }   /* × is the way out when enlarged */
.rv--big .rv__toggle { display: none; }
/* Close (×) button — only visible in the enlarged/pinned pane */
.rv__close { display: none; }
.rv--big .rv__close {
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    top: max(0.5rem, var(--safe-top));
    right: 0.5rem;
    z-index: 6;
    width: 2.5rem;
    height: 2.5rem;
    border: none;
    border-radius: 50%;
    background: rgba(0,0,0,0.6);
    color: #fff;
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
}

.ocr-text {
    background: var(--surface-2);
    border-radius: var(--radius-sm);
    padding: 0.7rem 0.85rem;
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
    font-size: 0.78rem;
    line-height: 1.45;
    max-height: 220px;
    overflow-y: auto;
    white-space: pre-wrap;
    color: var(--text-muted);
    border: 1px dashed var(--border-strong);
}

/* --- Toast / banner --- */

.banner {
    border-radius: var(--radius);
    padding: 0.75rem 1rem;
    font-size: 0.9rem;
    border: 1px solid;
    margin-bottom: 1rem;
}
.banner--error { background: var(--owe-soft); border-color: #f5c2c2; color: var(--owe); }
.banner--info { background: var(--primary-soft); border-color: #cee7da; color: var(--primary-text); }
.banner--warn { background: var(--warn-soft); border-color: #f5e0a8; color: var(--warn); }

#toast-container {
    position: fixed;
    top: calc(var(--safe-top) + 1rem);
    left: 50%;
    transform: translateX(-50%);
    z-index: 1200;   /* above modals — a toast must never be hidden */
    pointer-events: none;
}
.toast {
    background: rgba(26, 31, 44, 0.95);
    color: white;
    padding: 0.7rem 1.1rem;
    border-radius: 10px;
    font-size: 0.9rem;
    box-shadow: var(--shadow-lg);
    margin-bottom: 0.5rem;
    animation: toastIn 0.2s ease-out;
}
.toast--error { background: var(--owe); }
@keyframes toastIn {
    from { opacity: 0; transform: translateY(-8px); }
    to { opacity: 1; transform: translateY(0); }
}

/* --- Loading --- */

.spinner {
    display: inline-block;
    width: 18px;
    height: 18px;
    border: 2px solid rgba(0,0,0,0.1);
    border-top-color: var(--primary);
    border-radius: 50%;
    animation: spin 0.7s linear infinite;
}
.spinner--lg { width: 32px; height: 32px; border-width: 3px; }
.spinner--white { border-color: rgba(255,255,255,0.3); border-top-color: white; }
@keyframes spin { to { transform: rotate(360deg); } }

.loading-screen {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 1rem;
    color: var(--text-muted);
}

/* --- Modal (used for confirm dialogs) --- */

.modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.5);
    z-index: 1100;   /* see stacking order note at end of file */
    display: flex;
    align-items: center;
    justify-content: center;
    padding: max(1.25rem, var(--safe-top)) 1.25rem max(1.25rem, var(--safe-bot));
    animation: fadeIn 0.15s ease-out;
    overflow-y: auto;    /* a very tall card can still be reached end to end */
}

.modal {
    background: var(--surface);
    border-radius: var(--radius-lg);
    padding: 1.25rem;
    max-width: 380px;
    width: 100%;
    box-shadow: var(--shadow-lg);
    animation: modalIn 0.2s ease-out;
    /* A long list (e.g. Fewest payments on a big trip) must scroll INSIDE the
       card. Without this it grew past the viewport on a phone and the buttons at
       the bottom — including the way out — were simply unreachable. */
    max-height: min(80vh, 100% - 2rem);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;   /* don't scroll the page behind it */
}

/* Actions stay put at the bottom of a scrolling card, so Close/Done is always
   reachable no matter how long the list is. */
.modal__actions {
    position: sticky;
    bottom: -1.25rem;
    background: var(--surface);
    padding: 0.75rem 0 0;
    margin-top: 0.5rem;
}

.modal h3 { margin-bottom: 0.5rem; }
.modal p { color: var(--text-muted); margin-bottom: 1rem; }
.modal__actions { display: flex; gap: 0.5rem; }
.modal__actions > .btn { flex: 1; }

/* Full-screen how-to video takeover */
.video-overlay {
    position: fixed;
    inset: 0;
    z-index: 1000;
    background: #000;
    display: flex;
    align-items: center;
    justify-content: center;
}
.video-overlay__video {
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: #000;
}
/* The user guide, shown over the app rather than in a tab of its own — a
   home-screen PWA has no chrome, so a new tab has no way back. White, not
   black: it is a document, and the close button carries its own dark disc. */
.guide-overlay {
    position: fixed;
    inset: 0;
    z-index: 1000;
    background: #FAFAF7;
}
.guide-overlay__frame {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}

.video-overlay__close {
    position: fixed;
    top: max(0.75rem, env(safe-area-inset-top));
    right: max(0.9rem, env(safe-area-inset-right));
    z-index: 1001;
    width: 2.5rem;
    height: 2.5rem;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    font-size: 1.7rem;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes modalIn { from { opacity: 0; transform: translateY(8px) scale(0.98); } to { opacity: 1; transform: translateY(0) scale(1); } }

/* --- Splash / auth screens --- */

.auth-logo {
    width: 80px;
    height: 80px;
    margin: 0 auto 1.5rem;
    display: block;
}

.auth-title {
    text-align: center;
    margin-bottom: 0.4rem;
}
.auth-subtitle {
    text-align: center;
    color: var(--text-muted);
    margin-bottom: 2rem;
}

.auth-switch {
    text-align: center;
    margin-top: 1.25rem;
    color: var(--text-muted);
    font-size: 0.9rem;
}

/* --- Trip detail / friend list --- */

.invite-box {
    background: var(--primary-soft);
    border: 1px dashed var(--primary);
    border-radius: var(--radius);
    padding: 1rem;
    margin-bottom: 1rem;
}
.invite-box__label {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--primary-text);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: 0.4rem;
}
.invite-box__link {
    font-family: ui-monospace, monospace;
    font-size: 0.8rem;
    word-break: break-all;
    color: var(--primary-text);
    background: rgba(255,255,255,0.6);
    padding: 0.5rem;
    border-radius: 6px;
    margin-bottom: 0.5rem;
}

/* --- Misc --- */

.row { display: flex; align-items: center; gap: 0.5rem; }
.row--between { justify-content: space-between; }
.row--wrap { flex-wrap: wrap; }
.gap-sm { gap: 0.35rem; }
.gap { gap: 0.6rem; }
.text-muted { color: var(--text-muted); }
.text-faded { color: var(--text-faded); }
.text-sm { font-size: 0.85rem; }
.text-xs { font-size: 0.75rem; }
.text-right { text-align: right; }
.text-center { text-align: center; }
.mt-sm { margin-top: 0.5rem; }
.mt { margin-top: 1rem; }
.mt-lg { margin-top: 1.5rem; }
.mb-sm { margin-bottom: 0.5rem; }
.mb { margin-bottom: 1rem; }
.hidden { display: none !important; }
.flex-1 { flex: 1; }
.no-select { user-select: none; -webkit-user-select: none; }

/* Toggle switch */
.switch {
    position: relative;
    display: inline-block;
    width: 44px;
    height: 26px;
    flex-shrink: 0;
}
.switch input { display: none; }
.switch__track {
    position: absolute;
    inset: 0;
    background: var(--border-strong);
    border-radius: 13px;
    transition: background 0.15s;
    cursor: pointer;
}
.switch__track::after {
    content: '';
    position: absolute;
    top: 3px;
    left: 3px;
    width: 20px;
    height: 20px;
    background: white;
    border-radius: 10px;
    transition: transform 0.18s ease;
    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
.switch input:checked + .switch__track { background: var(--primary); }
.switch input:checked + .switch__track::after { transform: translateX(18px); }

/* Disable iOS auto-zoom on inputs */
@media screen and (max-width: 480px) {
    .input, .select, .textarea { font-size: 16px; }
}

/* --- Username link --- */
.username-link {
    color: var(--text-muted);
    text-decoration: none;
    border-bottom: 1px dashed transparent;
    transition: border-color 0.15s, color 0.15s;
}
.username-link:hover {
    color: var(--text);
    border-bottom-color: var(--text-muted);
    text-decoration: none;
}
/* Person icon before the name, so it's clearly a tappable link to the account */
.username-link::before {
    content: "";
    display: inline-block;
    width: 0.95em;
    height: 0.95em;
    margin-right: 0.3em;
    vertical-align: -0.12em;
    background-color: currentColor;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 12a5 5 0 1 0 0-10 5 5 0 0 0 0 10zm0 2c-5 0-9 2.5-9 6v2h18v-2c0-3.5-4-6-9-6z'/%3E%3C/svg%3E") no-repeat center / contain;
            mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 12a5 5 0 1 0 0-10 5 5 0 0 0 0 10zm0 2c-5 0-9 2.5-9 6v2h18v-2c0-3.5-4-6-9-6z'/%3E%3C/svg%3E") no-repeat center / contain;
}

/* --- Icon picker photo section --- */
.icon-picker-divider {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin: 0.6rem 0;
    color: var(--text-faded);
    font-size: 0.8rem;
}
.icon-picker-divider::before,
.icon-picker-divider::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--border);
}

.photo-icon-area { margin-top: 0.25rem; }

.photo-icon-preview {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.photo-icon-circle {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    overflow: hidden;
    background: var(--surface-2);
    border: 2px solid var(--primary);
    flex: 0 0 48px;
}

.photo-icon-circle img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* --- Photo crop editor --- */
.crop-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.65);
    z-index: 150;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    animation: fadeIn 0.15s ease-out;
}

.crop-editor {
    background: var(--surface);
    border-radius: var(--radius-lg);
    padding: 1.25rem;
    max-width: 440px;
    width: 100%;
    box-shadow: var(--shadow-lg);
}

/* --- Bottom-sheet (balance breakdown) --- */
.sheet-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    z-index: 1000;
    opacity: 0;
    transition: opacity 0.2s ease;
}
.sheet-overlay--open { opacity: 1; }
.sheet {
    width: 100%;
    max-width: 560px;
    max-height: 85vh;
    display: flex;
    flex-direction: column;
    background: var(--surface, #fff);
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -8px 30px rgba(0, 0, 0, 0.25);
    transform: translateY(100%);
    transition: transform 0.25s ease;
}
.sheet-overlay--open .sheet { transform: translateY(0); }
.sheet__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1rem 1.25rem;
    border-bottom: 1px solid var(--border);
}
.sheet__title { margin: 0; font-size: 1.1rem; }
.sheet__close {
    background: none;
    border: none;
    font-size: 1.6rem;
    line-height: 1;
    color: var(--text-muted, #888);
    cursor: pointer;
    padding: 0 0.25rem;
}
.sheet__body {
    padding: 0.5rem 1.25rem 1.5rem;
    overflow-y: auto;
}

/* Photo icon in list items */
.list-item__icon { overflow: hidden; }

/* Circled "i" that opens the payment-username instructions. */
.info-btn {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    border: 1px solid var(--border-strong);
    background: transparent;
    color: var(--text-muted);
    font-size: 0.72rem;
    font-weight: 700;
    font-style: italic;
    line-height: 1;
    padding: 0;
    cursor: pointer;
}
.info-btn:active { background: var(--surface-2); }

/* ---------------------------------------------------------------------------
   Stacking order. Keep these in step — a modal opened FROM a sheet used to
   render behind it (the sheet is 1000, modals were 100), which made the payment
   info popup invisible.

     nav / page chrome .............   40-150
     sheet-overlay .................   1000   (settle sheet, slides up)
     video-overlay .................   1000/1001
     modal-backdrop ................   1100   ABOVE sheets: modals are opened
                                              from sheets, never the reverse
     toast-container ...............   1200   above everything; transient and
                                              pointer-events:none

   Anything new that can be opened from a sheet must sit above 1000.
   --------------------------------------------------------------------------- */

/* Budget progress bar. */
.budget-bar {
    height: 10px;
    border-radius: 5px;
    background: var(--border);
    overflow: hidden;
}
.budget-bar__fill {
    height: 100%;
    border-radius: 5px;
    transition: width 0.25s ease;
}

/* Expense category chips. */
.cat-chips { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.cat-chip {
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    border-radius: 999px;
    padding: 0.4rem 0.7rem;
    font-size: 0.85rem;
    cursor: pointer;
}
.cat-chip--on {
    background: var(--primary);
    border-color: var(--primary);
    color: #fff;
}
.cat-tag {
    display: inline-block;
    font-size: 0.75rem;
    color: var(--text-muted);
    background: var(--surface-2);
    border-radius: 999px;
    padding: 0.1rem 0.5rem;
    margin-left: 0.35rem;
}

/* Add-to-home-screen card. Deliberately understated — it appears on the invite
   screen, where the job is joining the trip, not installing an app. */
.install-card {
    border: 1px solid var(--primary);
    background: var(--primary-soft);
}

/* ---------------------------------------------------------------------------
   Support conversations
   ---------------------------------------------------------------------------
   The iPhone convention, because everybody already knows how to read it: YOU
   are always on the right in green, the other party is on the left in blue.
   So in the app your own messages sit right and support's sit left, and on the
   admin dashboard the same rule puts Carl's replies on the right and the
   user's on the left. One rule, two surfaces, no thinking required.
--------------------------------------------------------------------------- */
.thread { display: flex; flex-direction: column; gap: 0.5rem; padding: 0.25rem 0; }
.bubble {
    max-width: 78%;
    padding: 0.55rem 0.8rem;
    border-radius: 1.05rem;
    font-size: 0.95rem;
    line-height: 1.45;
    white-space: pre-wrap;      /* people press Enter; keep their paragraphs */
    overflow-wrap: anywhere;    /* and paste long links */
}
.bubble--them { align-self: flex-start; background: #E9E9EB; color: #111; border-bottom-left-radius: 0.3rem; }
.bubble--me   { align-self: flex-end;   background: var(--primary); color: #fff; border-bottom-right-radius: 0.3rem; }
.bubble__meta { font-size: 0.7rem; color: var(--text-muted); margin: 0.1rem 0.35rem 0; }
.bubble__meta--me { align-self: flex-end; }
.bubble__meta--them { align-self: flex-start; }

/* One-line rows that open into a thread. Collapsed is the default because a
   list of questions is easier to scan than a wall of conversations. */
.ticket { border: 1px solid var(--border); border-radius: var(--radius); margin-bottom: 0.5rem; overflow: hidden; background: var(--surface); }
.ticket__head { display: flex; align-items: center; gap: 0.5rem; padding: 0.65rem 0.75rem; cursor: pointer; width: 100%; text-align: left; background: none; border: 0; font: inherit; color: inherit; }
.ticket__head:hover { background: var(--surface-2); }
.ticket__subject { flex: 1; min-width: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ticket__when { font-size: 0.75rem; color: var(--text-muted); white-space: nowrap; }
.ticket__body { padding: 0 0.75rem 0.75rem; border-top: 1px solid var(--border); }
.ticket__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--primary); flex: 0 0 auto; }

.pill { display: inline-block; font-size: 0.7rem; font-weight: 700; padding: 0.1rem 0.45rem; border-radius: 5px; white-space: nowrap; }
.pill--new { background: var(--primary-soft); color: var(--primary-text); }
.pill--open { background: var(--warn-soft); color: var(--warn); }
.pill--resolved { background: var(--surface-2); color: var(--text-muted); }

/* The support bell, beside the username at the top of every tab. Only drawn
   when there is a reply waiting, so it never becomes furniture people stop
   seeing. The shake plays twice and stops: an animation that never ends is a
   thing people cover with their thumb. */
.support-bell {
    display: inline-block;
    font-size: 0.95rem;
    line-height: 1;
    filter: drop-shadow(0 0 0.5px var(--owe));
    animation: bell-shake 0.7s ease-in-out 2;
}
@keyframes bell-shake {
    0%, 100% { transform: rotate(0); }
    20% { transform: rotate(-12deg); }
    40% { transform: rotate(10deg); }
    60% { transform: rotate(-6deg); }
    80% { transform: rotate(4deg); }
}

.bubble__shot {
    display: block;
    margin-top: 0.4rem;
    max-width: 220px;
    width: 100%;
    border-radius: 0.6rem;
    border: 1px solid rgba(0, 0, 0, 0.08);
}
.attachrow { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.5rem; font-size: 0.85rem; }

/* ---------------------------------------------------------------------------
   Help folded behind an (i).

   Some cards need a paragraph of explanation the first time and never again.
   Left on the page it becomes wallpaper — the Contributions card had more help
   than feature. Behind the icon it is one tap away and the card reads cleanly.

   A <details> rather than a scripted toggle: it survives a re-render with no
   state to track, and it works before any JS has run.
--------------------------------------------------------------------------- */
.help-note { margin-bottom: 0.5rem; }
.help-note > summary {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    cursor: pointer;
    list-style: none;          /* Firefox */
}
.help-note > summary::-webkit-details-marker { display: none; }
.help-note > summary > h3 { margin: 0; }
.help-note__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 1.2rem;
    height: 1.2rem;
    border: 1px solid var(--border-strong);
    border-radius: 50%;
    color: var(--text-muted);
    font-family: Georgia, "Times New Roman", serif;
    font-size: 0.78rem;
    font-style: italic;
    font-weight: 700;
    line-height: 1;
}
.help-note[open] .help-note__icon {
    background: var(--primary-soft);
    border-color: var(--primary);
    color: var(--primary-text);
}
.help-note > .field__help { margin-top: 0.5rem; }

/* Visible to a screen reader, to nobody else. The (i) above is a glyph with no
   meaning to a screen reader, so the words go here. */
.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* The impersonation bar. Fixed, above everything, and impossible to mistake
   for part of the app. Red once changes are unlocked, because a change made
   then is indistinguishable to the customer from one they made themselves. */
.imp-bar { position: fixed; top: 0; left: 0; right: 0; z-index: 9999;
           display: flex; align-items: center; gap: .75rem;
           padding: calc(env(safe-area-inset-top, 0px) + .5rem) .75rem .5rem;
           background: #4F5DA8; color: #fff; font-size: .85rem; font-weight: 600; }
.imp-bar--write { background: #DC4444; }
.imp-bar span { flex: 1; }
.imp-bar__stop { background: rgba(255,255,255,.2); color: #fff;
                 border: 1px solid rgba(255,255,255,.5); border-radius: 8px;
                 padding: .3rem .7rem; font: inherit; cursor: pointer; }
body.has-imp-bar { padding-top: 3rem; }
