/* ==========================================================================
   Ordo Mini App — mobile-first styles (v2).

   Design language
   - Layers, not shadows: page (Telegram secondary bg) -> panels (section bg).
   - Color carries meaning only:
       green  = done          amber = AI tag needs a human check
       dashed = missing       accent = interactive / selected
   - System fonts only (no network request; works behind the Great Firewall),
     CJK fallbacks included for student names and file names.
   - Follows Telegram theme params; light/dark fallbacks via [data-scheme].
   ========================================================================== */

:root {
    /* Fallbacks used outside Telegram (browser preview). */
    --fb-page: #eef0f4;
    --fb-panel: #ffffff;
    --fb-text: #15191f;
    --fb-hint: #667180;
    --fb-accent: #2563eb;

    /* Telegram theme -> semantic tokens */
    --page: var(--tg-theme-secondary-bg-color, var(--fb-page));
    --panel: var(--tg-theme-section-bg-color, var(--tg-theme-bg-color, var(--fb-panel)));
    --text: var(--tg-theme-text-color, var(--fb-text));
    --hint: var(--tg-theme-hint-color, var(--fb-hint));
    --accent: var(--tg-theme-accent-text-color, var(--tg-theme-link-color, var(--fb-accent)));
    --button: var(--tg-theme-button-color, var(--fb-accent));
    --on-button: var(--tg-theme-button-text-color, #ffffff);

    /* Neutral tints (upgraded below where color-mix is supported) */
    --line: rgba(120, 130, 145, 0.22);
    --fill: rgba(120, 130, 145, 0.12);
    --accent-soft: rgba(120, 130, 145, 0.16);

    /* Status colors */
    --ok: #15803d;
    --ok-solid: #15803d;
    --ok-soft: rgba(21, 128, 61, 0.11);
    --ok-line: rgba(21, 128, 61, 0.38);
    --warn: #a25b00;
    --warn-soft: rgba(217, 119, 6, 0.14);
    --bad: #d13b3b;

    /* Shape */
    --r-card: 16px;
    --r-control: 12px;
    --r-chip: 8px;

    /* Layout */
    --tab-h: 56px;
    --safe-top: calc(
        max(env(safe-area-inset-top, 0px), var(--tg-safe-area-inset-top, 0px))
        + var(--tg-content-safe-area-inset-top, 0px)
    );
    --safe-bottom: max(env(safe-area-inset-bottom, 0px), var(--tg-safe-area-inset-bottom, 0px));

    color-scheme: light;
}

:root[data-scheme="dark"] {
    --fb-page: #0e1116;
    --fb-panel: #181c23;
    --fb-text: #eceff4;
    --fb-hint: #8a95a5;
    --fb-accent: #5b9cff;

    --ok: #4cc27f;
    --ok-solid: #1f8f57;
    --ok-soft: rgba(76, 194, 127, 0.15);
    --ok-line: rgba(76, 194, 127, 0.4);
    --warn: #f0b04a;
    --warn-soft: rgba(240, 176, 74, 0.15);
    --bad: #ff7373;

    color-scheme: dark;
}

@supports (color: color-mix(in srgb, red, blue)) {
    :root {
        --line: color-mix(in srgb, var(--text) 11%, transparent);
        --fill: color-mix(in srgb, var(--text) 6%, transparent);
        --accent-soft: color-mix(in srgb, var(--accent) 13%, transparent);
    }
}

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

/* [hidden] must always win, even over display:flex/grid rules below. */
[hidden] {
    display: none !important;
}

html,
body {
    margin: 0;
    padding: 0;
}

html.modal-open {
    overflow: hidden;
}

body {
    font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", Roboto,
                 "PingFang SC", "Noto Sans SC", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
    background: var(--page);
    color: var(--text);
    font-size: 15px;
    line-height: 1.4;
    -webkit-text-size-adjust: 100%;
    -webkit-font-smoothing: antialiased;
    /* Room for the fixed bottom tab bar. */
    padding-bottom: calc(var(--tab-h) + var(--safe-bottom) + 20px);
    overscroll-behavior-y: contain;
}

h1, h2, p {
    margin: 0;
}

button {
    font: inherit;
    color: inherit;
}

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.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;
}

/* --------------------------------------------------------------------------
   Icons
   -------------------------------------------------------------------------- */
.sprite {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
}

.icon {
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.icon--lg { width: 28px; height: 28px; stroke-width: 1.6; }
.icon--sm { width: 18px; height: 18px; }
.icon--xs { width: 13px; height: 13px; stroke-width: 2.2; }

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */
.app-header {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: calc(var(--safe-top) + 10px) 14px 10px 16px;
    background: var(--page);
    box-shadow: 0 1px 0 var(--line);
}

.app-header__brand {
    display: flex;
    align-items: center;
    gap: 11px;
    min-width: 0;
}

.brand-logo {
    flex-shrink: 0;
    display: block;
    width: auto;
    height: 30px;
    /* Crop the JPEG's light corner fringe to the icon's own rounded tile. */
    border-radius: 22%;
    object-fit: contain;
}

.app-header h1 {
    font-size: 17px;
    font-weight: 700;
    letter-spacing: -0.01em;
    line-height: 1.2;
}

.app-header__tier {
    margin-top: 2px;
    font-size: 12px;
    line-height: 1.2;
    color: var(--hint);
}

.tier-badge {
    display: inline-block;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    padding: 1px 7px;
    border-radius: 6px;
}

.tier-badge--pro {
    color: var(--ok);
    background: var(--ok-soft);
}

.tier-badge--free {
    color: var(--hint);
    background: var(--fill);
}

.icon-btn {
    flex-shrink: 0;
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--text);
    cursor: pointer;
    transition: background 0.15s ease;
}

.icon-btn:active {
    background: var(--fill);
}

.icon-btn.is-spinning .icon {
    animation: spin 0.8s linear infinite;
}

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

/* Right-side header cluster: language switcher + reload. */
.header-actions {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 4px;
}

/* Compact RU/EN switcher - neutral surface so it reads as chrome, not a CTA. */
.lang-selector {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    width: 62px;
    height: 36px;
    padding: 0 22px 0 12px;
    margin: 0;
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    line-height: 1;
    color: var(--text);
    background-color: var(--fill);
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23667180' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 7px center;
    border: 1px solid var(--line);
    border-radius: var(--r-control);
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

.lang-selector:active {
    background-color: var(--accent-soft);
}

.lang-selector:focus-visible {
    outline: none;
    border-color: var(--accent);
}

:root[data-scheme="dark"] .lang-selector {
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238a95a5' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}

.lang-selector option {
    color: var(--text);
    background: var(--panel);
}

/* --------------------------------------------------------------------------
   Main layout
   -------------------------------------------------------------------------- */
.app-main {
    max-width: 640px;
    margin: 0 auto;
    padding: 12px 12px 24px;
}

/* Tab views: visibility is driven by BOTH the [hidden] attribute and
   .active/.hidden classes (kept in sync by app.js switchTab). The rules
   are explicit with !important so a mobile WebView (Telegram) can never
   leave a view stuck on a stale/overridden display value. */
.tab-view {
    display: block;
}

.tab-view.hidden {
    display: none !important;
}

.tab-view.active {
    display: block !important;
    /* Soft entrance when a section becomes visible. `backwards` (not `both`)
       so no lingering transform remains after the animation ends. */
    animation: tab-enter 0.32s cubic-bezier(0.22, 0.8, 0.3, 1) backwards;
}

/* Direction is set by app.js switchTab: moving to a tab on the right slides
   content in from the right, moving left slides it in from the left. */
.tab-view.active[data-dir="back"] {
    animation-name: tab-enter-back;
}

@keyframes tab-enter {
    from { opacity: 0; transform: translate3d(18px, 0, 0); }
    to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

@keyframes tab-enter-back {
    from { opacity: 0; transform: translate3d(-18px, 0, 0); }
    to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

.hint {
    font-size: 13px;
    color: var(--hint);
}

/* --------------------------------------------------------------------------
   States: empty / error / loading
   -------------------------------------------------------------------------- */
.state-panel {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 64px 28px;
    color: var(--hint);
}

.state-panel__icon {
    display: grid;
    place-items: center;
    width: 60px;
    height: 60px;
    margin-bottom: 16px;
    border-radius: 50%;
    background: var(--fill);
    color: var(--hint);
}

.state-panel__title {
    font-size: 17px;
    font-weight: 700;
    color: var(--text);
}

.state-panel__text {
    max-width: 34ch;
    margin-top: 6px;
    font-size: 14px;
    line-height: 1.45;
    text-wrap: pretty;
}

.state-panel .btn {
    margin-top: 20px;
}

.state-panel--error .state-panel__icon {
    background: rgba(209, 59, 59, 0.12);
    color: var(--bad);
}

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

.skeleton-card {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 16px;
    border: 1px solid var(--line);
    border-radius: var(--r-card);
    background: var(--panel);
}

.sk {
    border-radius: 8px;
    background: linear-gradient(90deg, var(--fill) 25%, var(--line) 50%, var(--fill) 75%);
    background-size: 200% 100%;
    animation: shimmer 1.3s ease-in-out infinite;
}

.sk--title { width: 55%; height: 20px; }
.sk--line  { width: 38%; height: 13px; }
.sk--bar   { height: 6px; margin-top: 4px; }
.sk--chips { width: 80%; height: 28px; }

@keyframes shimmer {
    from { background-position: 100% 0; }
    to   { background-position: -100% 0; }
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 44px;
    padding: 0 20px;
    border: none;
    border-radius: var(--r-control);
    background: var(--button);
    color: var(--on-button);
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    transition: transform 0.1s ease, filter 0.15s ease;
}

.btn:active {
    transform: scale(0.97);
    filter: brightness(0.94);
}

.btn--ghost {
    background: transparent;
    color: var(--accent);
    box-shadow: inset 0 0 0 1px currentColor;
}

/* --------------------------------------------------------------------------
   Bottom tab navigation
   -------------------------------------------------------------------------- */
.tab-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 30;
    display: flex;
    height: calc(var(--tab-h) + var(--safe-bottom));
    padding-bottom: var(--safe-bottom);
    background: var(--panel);
    box-shadow: 0 -1px 0 var(--line);
}

.tab-bar__btn {
    position: relative;
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-height: var(--tab-h);
    border: none;
    background: transparent;
    color: var(--hint);
    font-size: 11px;
    font-weight: 600;
    cursor: pointer;
    transition: color 0.15s ease;
}

.tab-bar__btn.is-active {
    color: var(--accent);
}

.tab-bar__btn.is-active::before {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    width: 28px;
    height: 3px;
    border-radius: 0 0 3px 3px;
    background: var(--accent);
    transform: translateX(-50%);
    animation: tab-indicator 0.28s cubic-bezier(0.22, 0.8, 0.3, 1) backwards;
}

.tab-bar__icon {
    width: 24px;
    height: 24px;
    transition: transform 0.25s cubic-bezier(0.22, 0.8, 0.3, 1);
}

.tab-bar__btn.is-active .tab-bar__icon {
    transform: translateY(-1px) scale(1.08);
}

@keyframes tab-indicator {
    from { opacity: 0; transform: translateX(-50%) scaleX(0.3); }
    to   { opacity: 1; transform: translateX(-50%) scaleX(1); }
}

/* --------------------------------------------------------------------------
   Student card
   -------------------------------------------------------------------------- */
.students-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.student-card {
    scroll-margin-top: calc(var(--safe-top) + 72px);
    border: 1px solid var(--line);
    border-radius: var(--r-card);
    background: var(--panel);
    overflow: hidden;
    transition: opacity 0.2s ease;
}

.student-card--complete {
    border-color: var(--ok-line);
}

.student-card.swap-active {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.student-card.is-flash {
    animation: flash 1.3s ease-out;
}

@keyframes flash {
    from { box-shadow: 0 0 0 3px var(--accent); }
    to   { box-shadow: 0 0 0 3px transparent; }
}

.student-card__head {
    padding: 16px 16px 14px;
}

.student-card__name-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
}

.student-card__name {
    font-size: 17px;
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -0.01em;
    overflow-wrap: anywhere;
}

.student-card__meta {
    margin-top: 3px;
    font-size: 13px;
    color: var(--hint);
    overflow-wrap: anywhere;
}

.status-pill {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-top: 1px;
    padding: 3px 9px;
    border-radius: 999px;
    background: var(--fill);
    color: var(--hint);
    font-size: 12px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.status-pill--ready {
    color: var(--ok);
    background: var(--ok-soft);
}

/* Segmented progress: one segment per required document. */
.progress {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 14px;
}

.progress__segments {
    flex: 1;
    display: flex;
    gap: 3px;
}

.progress__seg {
    flex: 1;
    height: 6px;
    border-radius: 3px;
    background: var(--line);
    transition: background 0.3s ease;
}

.progress__seg--ok   { background: var(--ok-solid); }
.progress__seg--warn { background: var(--warn); }

.progress__label {
    flex-shrink: 0;
    font-size: 12px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--hint);
}

/* Checklist chips: done is quiet, exceptions are loud. */
.checklist {
    list-style: none;
    margin: 12px 0 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.checklist__item {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    max-width: 100%;
    padding: 5px 9px 5px 7px;
    border-radius: var(--r-chip);
    background: var(--fill);
    font-size: 12.5px;
    line-height: 1.2;
}

.checklist__item.is-warn {
    background: var(--warn-soft);
}

.checklist__item.is-missing {
    background: transparent;
    box-shadow: inset 0 0 0 1px var(--line);
    color: var(--hint);
}

.checklist__icon {
    display: inline-flex;
}

.checklist__icon--ok      { color: var(--ok); }
.checklist__icon--warn    { color: var(--warn); }
.checklist__icon--missing { color: var(--hint); }

.checklist__label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Files toggle bar */
.student-card__toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    min-height: 48px;
    padding: 0 16px;
    border: none;
    border-top: 1px solid var(--line);
    background: transparent;
    font-size: 14px;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
}

.student-card__toggle:active {
    background: var(--fill);
}

.student-card__toggle:focus-visible {
    outline-offset: -2px;
}

.toggle__summary {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px 10px;
}

.toggle__chevron {
    color: var(--hint);
    transition: transform 0.2s ease;
}

.student-card__toggle[aria-expanded="true"] .toggle__chevron {
    transform: rotate(180deg);
}

.docs-empty {
    padding: 12px 16px;
    border-top: 1px solid var(--line);
    font-size: 13px;
    color: var(--hint);
}

/* --------------------------------------------------------------------------
   Document rows
   Row 1: thumbnail, file name, confidence, preview
   Row 2: classification select + swap
   -------------------------------------------------------------------------- */
.docs {
    border-top: 1px solid var(--line);
}

.doc-row {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 12px 16px 14px;
    transition: background 0.15s ease, opacity 0.15s ease;
}

.doc-row + .doc-row {
    border-top: 1px solid var(--line);
}

/* Low AI confidence: amber edge marks rows that need a human look. */
.doc-row--verify {
    box-shadow: inset 3px 0 0 var(--warn);
}

.doc-row.is-saving {
    opacity: 0.55;
    pointer-events: none;
}

.doc-row__top {
    display: flex;
    align-items: center;
    gap: 12px;
    min-width: 0;
}

.doc-row__thumb,
.doc-row__icon {
    flex-shrink: 0;
    width: 48px;
    height: 48px;
    border-radius: 10px;
    background: var(--fill);
    box-shadow: inset 0 0 0 1px var(--line);
}

.doc-row__thumb {
    object-fit: cover;
}

.doc-row__icon {
    display: grid;
    place-items: center;
    color: var(--hint);
}

.doc-row__info {
    flex: 1;
    min-width: 0;
}

.doc-row__name {
    font-size: 14px;
    font-weight: 600;
    line-height: 1.3;
    /* Full title, never truncated. */
    overflow-wrap: anywhere;
}

.doc-row__sub {
    display: flex;
    align-items: center;
    margin-top: 4px;
}

.badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px 2px 6px;
    border-radius: 6px;
    font-size: 12px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    line-height: 1.3;
}

.badge--ok {
    color: var(--ok);
    background: var(--ok-soft);
}

.badge--warn {
    color: var(--warn);
    background: var(--warn-soft);
}

.doc-row__bottom {
    /* Select on the left, action group pinned to the far right. */
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

/* Swap + Preview buttons, grouped at the far right of the actions row. */
.doc-row__actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}

.doc-select {
    flex: 1;
    min-width: 0;
    height: 44px;
    padding: 0 36px 0 12px;
    border: 1px solid var(--line);
    border-radius: var(--r-control);
    background-color: var(--fill);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238a94a3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    background-size: 18px;
    color: var(--text);
    /* 16px prevents iOS from zooming the page on focus. */
    font: inherit;
    font-size: 16px;
    -webkit-appearance: none;
    appearance: none;
}

.mini-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    flex-shrink: 0;
    height: 44px;
    padding: 0 14px;
    border: 1px solid var(--line);
    border-radius: var(--r-control);
    background: var(--fill);
    color: var(--text);
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: transform 0.1s ease, background 0.15s ease;
}

.mini-btn:active {
    transform: scale(0.96);
}

/* Preview button (row 1). */
.mini-btn--round {
    width: 44px;
    padding: 0;
    border: none;
    border-radius: 50%;
}

/* Swap button (row 2). */
.mini-btn--square {
    padding: 0 14px;
}

.mini-btn.is-active {
    border-color: var(--accent);
    color: var(--accent);
    background: var(--accent-soft);
}

/* ---- Swap mode ---------------------------------------------------------- */
/* Other students fade back so the active card is obvious. */
.is-swapping .student-card:not(.swap-active) {
    opacity: 0.45;
}

.doc-row.swap-candidate {
    cursor: pointer;
    background: var(--fill);
}

/* Any tap on a candidate row is the "second pick": children must not
   intercept it (otherwise the native <select> picker would open). */
.doc-row.swap-candidate > * {
    pointer-events: none;
}

.doc-row.swap-candidate:not(.swap-selected) .doc-row__bottom {
    opacity: 0.4;
}

.doc-row.swap-candidate:active {
    background: var(--accent-soft);
}

.doc-row.swap-selected {
    background: var(--accent-soft);
    box-shadow: inset 3px 0 0 var(--accent);
}

/* --------------------------------------------------------------------------
   Card footer / download
   -------------------------------------------------------------------------- */
.student-card__footer {
    padding: 12px 16px 16px;
    border-top: 1px solid var(--line);
}

.download-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    min-height: 46px;
    border-radius: var(--r-control);
    /* Incomplete dossier: secondary. Complete: the primary action. */
    background: transparent;
    box-shadow: inset 0 0 0 1px var(--line);
    color: var(--text);
    font-size: 15px;
    font-weight: 600;
    text-decoration: none;
    transition: transform 0.1s ease, background 0.15s ease;
}

.download-btn:active {
    transform: scale(0.98);
    background: var(--fill);
}

.download-btn--complete {
    background: var(--ok-solid);
    box-shadow: none;
    color: #fff;
}

.download-btn--complete:active {
    background: var(--ok-solid);
    filter: brightness(0.92);
}

/* In-flight dossier send / swap requests: buttons lock until resolved. */
.download-btn:disabled,
.mini-btn:disabled,
.btn-primary:disabled {
    opacity: 0.65;
    cursor: default;
    pointer-events: none;
}

.download-btn.is-busy {
    gap: 10px;
}

/* Small inline activity spinner (reuses the shared spin keyframes). */
.spinner {
    flex-shrink: 0;
    width: 16px;
    height: 16px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    display: inline-block;
    vertical-align: -3px;
    animation: spin 0.7s linear infinite;
}

/* --------------------------------------------------------------------------
   Grouped lists (Analytics / Profile)
   -------------------------------------------------------------------------- */
.group {
    margin-top: 22px;
}

.group__title {
    padding: 0 4px 8px;
    font-size: 13px;
    font-weight: 600;
    color: var(--hint);
}

.group__body {
    border: 1px solid var(--line);
    border-radius: var(--r-card);
    background: var(--panel);
    overflow: hidden;
}

.row {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    min-height: 52px;
    padding: 10px 16px;
    border: none;
    background: transparent;
    color: var(--text);
    font-size: 15px;
    text-align: left;
    text-decoration: none;
}

.row + .row {
    border-top: 1px solid var(--line);
}

.row--action {
    cursor: pointer;
}

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

.row__icon {
    flex-shrink: 0;
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    border-radius: 9px;
    background: var(--fill);
    color: var(--hint);
}

.row__main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.row__sub {
    font-size: 13px;
    color: var(--hint);
    overflow-wrap: anywhere;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.row__value {
    flex-shrink: 0;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.row__value--warn { color: var(--warn); }
.row__value--muted { color: var(--hint); font-weight: 500; }

.row__chev {
    flex-shrink: 0;
    color: var(--hint);
}

.row--stack {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    padding-top: 14px;
    padding-bottom: 14px;
}

.row__line {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.meter {
    height: 6px;
    border-radius: 3px;
    background: var(--line);
    overflow: hidden;
}

.meter__fill {
    height: 100%;
    border-radius: 3px;
    background: var(--accent);
    transition: width 0.3s ease;
}

.meter__fill--full {
    background: var(--warn);
}

.group__more {
    padding: 10px 4px 0;
    font-size: 13px;
    color: var(--hint);
}

/* --------------------------------------------------------------------------
   Analytics
   -------------------------------------------------------------------------- */
.summary {
    padding: 4px 4px 0;
}

.summary__headline {
    font-size: 22px;
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -0.015em;
    text-wrap: balance;
}

.split-bar {
    display: flex;
    gap: 3px;
    height: 10px;
    margin-top: 16px;
}

.split-bar__part {
    min-width: 6px;
    border-radius: 5px;
    transition: flex-grow 0.4s ease;
}

.split-bar__part--ready { background: var(--ok-solid); }
.split-bar__part--rest  { background: var(--line); }

.summary__sub {
    margin-top: 10px;
    font-size: 13px;
    color: var(--hint);
}

/* --------------------------------------------------------------------------
   Profile
   -------------------------------------------------------------------------- */
.profile-card {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 16px;
    border: 1px solid var(--line);
    border-radius: var(--r-card);
    background: var(--panel);
}

.profile-card__avatar {
    flex-shrink: 0;
    display: grid;
    place-items: center;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--button);
    color: var(--on-button);
    font-size: 24px;
    font-weight: 700;
}

.profile-card__info {
    flex: 1;
    min-width: 0;
}

.profile-card__name {
    font-size: 18px;
    font-weight: 700;
    letter-spacing: -0.01em;
    overflow-wrap: anywhere;
}

.profile-card__meta {
    margin-top: 2px;
    font-size: 13px;
    color: var(--hint);
    font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   Preview modal: full-screen viewer on phones, centered dialog on tablets.
   -------------------------------------------------------------------------- */
.modal {
    position: fixed;
    inset: 0;
    z-index: 50;
    display: flex;
    align-items: stretch;
    justify-content: center;
}

.modal__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(5, 8, 13, 0.7);
    animation: fade-in 0.2s ease;
}

.modal__dialog {
    position: relative;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    background: #0b0e13;
    color: #f2f4f8;
    overflow: hidden;
    animation: sheet-in 0.25s ease;
}

.modal__header {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: calc(var(--safe-top) + 6px) 8px 6px 16px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.modal__header .icon-btn {
    color: #f2f4f8;
}

.modal__header .icon-btn:active {
    background: rgba(255, 255, 255, 0.12);
}

.modal__title {
    flex: 1;
    min-width: 0;
    font-size: 15px;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.modal__body {
    flex: 1;
    min-height: 0;
    display: flex;
    overflow: auto;
    padding-bottom: var(--safe-bottom);
    -webkit-overflow-scrolling: touch;
}

/* margin:auto centers without clipping the top of tall images. */
.modal__body img {
    display: block;
    margin: auto;
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    cursor: zoom-in;
}

.modal__body.is-zoomed img {
    max-width: none;
    max-height: none;
    width: 230%;
    height: auto;
    margin: 0;
    cursor: zoom-out;
}

/* Explicit responsive preview container: flex centering + a minimum height
   keep the viewer from collapsing to zero inside mobile WebViews. */
.modal-preview {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 200px;
    width: 100%;
    margin: auto;
    padding: 16px;
}

.modal-preview img {
    display: block;
    max-width: 100%;
    max-height: 70vh;
    margin: 0 auto;
    object-fit: contain;
    border-radius: 8px;
    cursor: zoom-in;
}

/* PDF fallback card (mobile WebViews cannot render a raw PDF inline). */
.pdf-card {
    margin: auto;
    width: min(100%, 360px);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 32px 24px;
    text-align: center;
    color: #f2f4f8;
    background: rgba(255, 255, 255, 0.06);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 16px;
}

.pdf-card__icon {
    font-size: 44px;
    line-height: 1;
}

.pdf-card h2 {
    font-size: 18px;
    font-weight: 700;
}

.pdf-card__name {
    font-size: 13px;
    color: #aeb8c4;
    word-break: break-all;
}

.btn-primary {
    margin-top: 8px;
    min-height: 46px;
    padding: 0 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    border: none;
    border-radius: var(--r-control);
    background: var(--button, var(--accent));
    color: var(--on-button, #fff);
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    transition: transform 0.1s ease, filter 0.15s ease;
}

.btn-primary:active {
    transform: scale(0.98);
    filter: brightness(0.92);
}

.modal__body iframe {
    flex: 1;
    width: 100%;
    height: 100%;
    border: 0;
    background: #fff;
}

.modal__fallback {
    margin: auto;
    padding: 40px 24px;
    text-align: center;
    color: #f2f4f8;
}

.modal__fallback .icon {
    width: 40px;
    height: 40px;
    margin-bottom: 12px;
    color: #8a95a5;
}

.modal__fallback p + p {
    margin-top: 8px;
}

.modal__fallback a {
    color: #8ab4ff;
}

@media (min-width: 720px) {
    .modal {
        align-items: center;
    }

    .modal__dialog {
        width: min(92vw, 880px);
        height: min(90vh, 900px);
        border-radius: 18px;
        box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
    }

    .modal__header {
        padding-top: 6px;
    }
}

@keyframes fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@keyframes sheet-in {
    from { opacity: 0; transform: translateY(20px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* --------------------------------------------------------------------------
   Swap bar & toasts (kept above the bottom tab bar)
   -------------------------------------------------------------------------- */
.swap-bar {
    position: fixed;
    left: 50%;
    bottom: calc(var(--tab-h) + var(--safe-bottom) + 14px);
    transform: translateX(-50%);
    z-index: 40;
    display: flex;
    align-items: center;
    gap: 10px;
    width: max-content;
    max-width: calc(100vw - 24px);
    padding: 8px 8px 8px 14px;
    border-radius: 16px;
    background: var(--text);
    color: var(--page);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
    font-size: 13.5px;
    line-height: 1.3;
    animation: rise-in 0.2s ease;
}

.swap-bar .btn--ghost {
    min-height: 34px;
    padding: 0 12px;
    font-size: 13px;
    color: var(--page);
}

.toast-container {
    position: fixed;
    left: 50%;
    bottom: calc(var(--tab-h) + var(--safe-bottom) + 76px);
    transform: translateX(-50%);
    z-index: 60;
    display: flex;
    flex-direction: column;
    gap: 8px;
    align-items: center;
    pointer-events: none;
    width: calc(100vw - 32px);
    max-width: 420px;
}

.toast {
    max-width: 100%;
    padding: 10px 16px;
    border-radius: 14px;
    background: var(--text);
    color: var(--page);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
    font-size: 14px;
    text-align: center;
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 0.2s ease, transform 0.2s ease;
}

.toast.is-visible {
    opacity: 1;
    transform: translateY(0);
}

.toast--error {
    background: var(--bad);
    color: #fff;
}

@keyframes rise-in {
    from { opacity: 0; transform: translate(-50%, 10px); }
    to   { opacity: 1; transform: translate(-50%, 0); }
}

/* --------------------------------------------------------------------------
   Reduced motion
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}