/* ============================================================
   App shell — the authenticated experience.   [app-shell v4 · app scan]
   Top header + main scroll + bottom tab bar. Native-app patterns.
   ============================================================ */

/* Kill the default body padding — the shell manages safe areas per region.
   The page itself never scrolls; only .app-scroll does (see below). */
body.is-app {
    padding-top: 0;
    padding-bottom: 0;
    background: var(--paper);
    overflow: hidden;
}

body.is-app.no-scroll {
    overflow: hidden;
}

/* ---- Root layout ----
   Native-app layout: the shell fills the screen and is pinned in place.
   Header (top) and tab bar (bottom) are regular flex rows, and ONLY the
   middle (.app-scroll) scrolls. Previously the whole page scrolled with
   a position:fixed tab bar — on iPhone (Safari + Chrome) the bounce at
   the end of a scroll dragged the tab bar up the screen with it. */

.app-shell {
    position: fixed;
    inset: 0;
    display: flex;
    flex-direction: column;
    background: var(--paper);
}

.app-scroll {
    flex: 1;
    min-height: 0;
    overflow-x: hidden;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
}

/* ============================================================
   Top header — fixed, respects notch/dynamic island.
   ============================================================ */

.app-header {
    position: relative;
    flex: none;
    z-index: 40;
    background: var(--paper);
    border-bottom: 1px solid var(--line);
    padding-top: env(safe-area-inset-top);
}

.app-header-inner {
    height: var(--header-h);
    padding-inline: var(--sp-4);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
}

.app-header-brand {
    display: inline-flex;
    align-items: center;
    height: 100%;
}

.app-header-brand img {
    height: 24px;
    width: auto;
    display: block;
}

.app-header-title {
    font-size: var(--fs-lg);
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--ink);
    flex: 1;
    text-align: center;
    /* When there's no title, keep the space to keep brand + avatar balanced */
    min-height: 1em;
}

.app-header-actions {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
}

.app-header-avatar {
    width: 36px;
    height: 36px;
    border-radius: var(--radius-full);
    background: var(--surface-2);
    color: var(--ink-2);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: var(--fs-sm);
    overflow: hidden;
    border: 1px solid var(--line);
}

.app-header-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* ============================================================
   Main content area — scrolls, respects both nav bars.
   ============================================================ */

.app-main {
    /* Tab bar is its own row now (not overlaying), so just breathing room. */
    padding-bottom: var(--sp-10);
    padding-inline: var(--sp-4);
    padding-top: var(--sp-4);
    max-width: 640px;
    margin-inline: auto;
    width: 100%;
}

/* Large title pattern (iOS 11+ style) — big title at top of screen. */
.app-large-title {
    font-size: var(--fs-3xl);
    line-height: 1.05;
    letter-spacing: -0.03em;
    font-weight: 700;
    margin: var(--sp-4) 0 var(--sp-5);
}

.app-section-title {
    font-size: var(--fs-base);
    font-weight: 600;
    color: var(--ink);
    margin: var(--sp-8) 0 var(--sp-3);
    display: flex;
    align-items: baseline;
    justify-content: space-between;
}

.app-section-title a,
.app-section-title button {
    font-size: var(--fs-sm);
    font-weight: 500;
    color: var(--accent);
}

/* ============================================================
   Bottom tab bar — the primary nav.
   Always visible, always thumb-reachable.
   ============================================================ */

.tab-bar {
    position: relative;
    flex: none;
    z-index: 50;
    background: var(--paper);
    border-top: 1px solid var(--line);
    padding-bottom: env(safe-area-inset-bottom);
}

.tab-bar-inner {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    height: var(--nav-h);
    max-width: 640px;
    margin-inline: auto;
}

.tab-bar-item {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    color: var(--ink-3);
    text-decoration: none;
    transition: color var(--dur-fast) var(--ease-out);
    position: relative;
    padding-top: 6px;
}

.tab-bar-item svg {
    width: 24px;
    height: 24px;
    stroke: currentColor;
    stroke-width: 1.75;
    fill: none;
    display: block;
}

.tab-bar-label {
    font-size: 10px;
    font-weight: 500;
    letter-spacing: 0.02em;
}

.tab-bar-item:hover { color: var(--ink-2); }

.tab-bar-item.is-active,
.tab-bar-item.is-active:hover {
    color: var(--accent);
}

/* Unread badge on a tab item */
.tab-bar-item .badge-dot {
    position: absolute;
    top: 4px;
    right: calc(50% - 15px);
    width: 8px;
    height: 8px;
    border-radius: var(--radius-full);
    background: var(--accent);
    border: 2px solid var(--paper);
}

/* ============================================================
   Card patterns — used inside the app.
   ============================================================ */

/* Hero "your card" preview at the top of Home. */
.hero-card {
    background: var(--surface);
    border-radius: var(--radius-2xl);
    padding: var(--sp-5);
    border: 1px solid var(--line);
    box-shadow: var(--shadow-2);
    display: flex;
    flex-direction: column;
    gap: var(--sp-4);
}

.hero-card-identity {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
}

.hero-card-identity .avatar {
    width: 56px;
    height: 56px;
    font-size: var(--fs-lg);
}

.hero-card-name {
    font-size: var(--fs-xl);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.2;
    color: var(--ink);
}
/* Name + PRO badge on one line; a long name wraps and the badge stays with it. */
.hero-card-identity > div { min-width: 0; }
.hero-card-name .pro-badge { margin-left: 6px; position: relative; top: -2px; }

.hero-card-industry {
    font-size: var(--fs-sm);
    color: var(--ink-3);
    margin-top: 2px;
}

.hero-card-stats {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--sp-3);
    padding: var(--sp-4) 0;
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
}

.hero-card-stat {
    text-align: center;
}

.hero-card-stat-value {
    font-size: var(--fs-2xl);
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--ink);
    line-height: 1;
}

.hero-card-stat-label {
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-3);
    margin-top: var(--sp-2);
}

/* ============================================================
   List rows — used for groups, connections, meetings.
   ============================================================ */

.row {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    background: var(--surface);
    border-radius: var(--radius-lg);
    border: 1px solid var(--line);
    color: inherit;
    text-decoration: none;
}

.row + .row {
    margin-top: var(--sp-2);
}

.row-body {
    flex: 1;
    min-width: 0;
}

.row-title {
    font-size: var(--fs-base);
    font-weight: 600;
    color: var(--ink);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.row-meta {
    font-size: var(--fs-sm);
    color: var(--ink-3);
    margin-top: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.row-chevron {
    color: var(--ink-4);
    flex: none;
}

/* ============================================================
   Empty states — for when a tab has nothing yet.
   ============================================================ */

.empty-state {
    text-align: center;
    padding: var(--sp-16) var(--sp-4) var(--sp-10);
    color: var(--ink-3);
}

.empty-state svg {
    width: 48px;
    height: 48px;
    stroke: var(--ink-4);
    stroke-width: 1.5;
    fill: none;
    margin: 0 auto var(--sp-4);
    display: block;
}

.empty-state h3 {
    color: var(--ink);
    font-size: var(--fs-lg);
    font-weight: 600;
    margin-bottom: var(--sp-2);
}

.empty-state p {
    max-width: 32ch;
    margin-inline: auto;
    line-height: var(--lh-body);
}

.empty-state .btn {
    margin-top: var(--sp-6);
}

/* ============================================================
   Unread badge on a tab (e.g. pending connection requests).
   ============================================================ */

.tab-bar-badge {
    position: absolute;
    top: 2px;
    left: calc(50% + 5px);
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: var(--radius-full);
    background: var(--accent);
    color: var(--accent-ink);
    font-size: 10px;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
    box-shadow: 0 0 0 2px var(--paper);
}

/* ============================================================
   People lists — Network + Alerts.
   ============================================================ */

.person-list {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.person-row {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    color: inherit;
    text-decoration: none;
}

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

a.person-row:hover,
.person-row-link:hover { background: var(--surface-2); }

.person-row-link {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    color: inherit;
    text-decoration: none;
    margin: calc(var(--sp-3) * -1) 0 calc(var(--sp-3) * -1) calc(var(--sp-4) * -1);
    padding: var(--sp-3) 0 var(--sp-3) var(--sp-4);
}

.person-row-main { flex: 1; min-width: 0; }

.person-row-name {
    font-weight: 600;
    font-size: var(--fs-base);
    color: var(--ink);
    line-height: 1.25;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.person-row-meta {
    font-size: var(--fs-sm);
    color: var(--ink-3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* How you connected (Your network): "Met in Orlando, FL · Oct 14" */
.person-row-context {
    display: flex;
    align-items: center;
    gap: 0;
    margin-top: 3px;
    font-size: var(--fs-xs);
    color: var(--ink-3);
    min-width: 0;
}
.person-row-context-label {
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.person-row-context-date { flex: none; white-space: pre; }
.person-row-context-icon {
    width: 13px;
    height: 13px;
    flex: none;
    stroke: var(--ink-4);
    fill: none;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    margin-right: 5px;
}

.person-row-actions {
    display: flex;
    align-items: center;
    gap: var(--sp-1);
    flex: none;
}

.person-row-actions form { margin: 0; }

.person-row-chevron { color: var(--ink-4); flex: none; }

.flash {
    padding: var(--sp-3) var(--sp-4);
    border-radius: var(--radius-md);
    margin-bottom: var(--sp-5);
    font-size: var(--fs-sm);
    font-weight: 500;
    background: var(--surface-2);
    color: var(--ink-2);
}

.flash-success {
    background: rgba(22, 163, 74, 0.08);
    color: #166534;
}

.page-back {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    margin-top: var(--sp-4);
    font-size: var(--fs-sm);
    font-weight: 500;
    color: var(--ink-3);
    text-decoration: none;
}

.page-back:hover { color: var(--ink); }

/* ============================================================
   Home — Share My Card + QR side by side.
   ============================================================ */

.hero-card-actions {
    display: flex;
    gap: var(--sp-2);
}

.hero-card-actions .btn-primary { flex: 1; }

.btn-qr {
    flex: none;
    padding-inline: var(--sp-4);
}

.btn-qr svg {
    width: 18px;
    height: 18px;
    stroke: currentColor;
    fill: none;
    stroke-width: 2;
}

/* Scan — iPhone/Android app only, and only when the installed app build
   has the QR scanner (html.can-scan, set by native_tags()). */
html:not(.can-scan) .native-scan { display: none; }
.native-scan svg { stroke-linecap: round; stroke-linejoin: round; }

/* With Scan there are three buttons — too many for one line on a phone.
   Share My Card takes the full width, QR and Scan split the row below. */
.can-scan .hero-card-actions { flex-wrap: wrap; }
.can-scan .hero-card-actions .btn-primary { flex: 1 0 100%; }
.can-scan .hero-card-actions .btn-qr { flex: 1 1 0; min-width: 0; }

/* ============================================================
   "My QR code" bottom sheet (<dialog>).
   ============================================================ */

.qr-sheet {
    /* Pinned to the bottom explicitly — older browsers (e.g. Samsung
       Internet on older Galaxy phones) center modal dialogs otherwise. */
    position: fixed;
    top: auto;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    max-width: 480px;
    max-height: 100%;
    margin: 0 auto;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--ink);
    overflow: visible;
}

.qr-sheet:focus,
.qr-sheet:focus-visible {
    outline: none;
}

.qr-sheet::backdrop {
    /* --qr-dim fades the backdrop while the sheet is swiped down. */
    background: rgba(10, 10, 11, var(--qr-dim, 0.45));
}

.qr-sheet-inner {
    /* We handle vertical drags ourselves (swipe down to close). */
    touch-action: none;
    background: var(--surface);
    border-radius: 24px 24px 0 0;
    padding: var(--sp-3) var(--sp-6) calc(var(--sp-6) + env(safe-area-inset-bottom));
    text-align: center;
    box-shadow: 0 -8px 32px rgba(10, 10, 11, 0.12);
}

.qr-sheet[open] .qr-sheet-inner {
    animation: qr-sheet-up 240ms var(--ease-out);
}

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

.qr-sheet-handle {
    width: 40px;
    height: 5px;
    border-radius: var(--radius-full);
    background: var(--ink-4);
    opacity: 0.5;
    margin: 0 auto var(--sp-5);
}

.qr-code {
    width: min(70vw, 260px);
    aspect-ratio: 1;
    margin: 0 auto var(--sp-5);
    padding: var(--sp-2);
    background: #FFFFFF;
    border: 1px solid var(--line);
    border-radius: var(--radius-xl);
}

.qr-code svg {
    width: 100%;
    height: 100%;
    display: block;
}

.qr-sheet-name {
    font-size: var(--fs-xl);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.2;
}

.qr-sheet-meta {
    font-size: var(--fs-sm);
    color: var(--ink-3);
    margin-top: 2px;
}

.qr-sheet-hint {
    font-size: var(--fs-sm);
    color: var(--ink-3);
    line-height: 1.45;
    max-width: 32ch;
    margin: var(--sp-4) auto var(--sp-6);
}

/* Short screens (smaller Android phones with the browser bar showing):
   shrink the QR and spacing so the whole sheet fits. */
@media (max-height: 700px) {
    .qr-sheet-handle { margin-bottom: var(--sp-3); }
    .qr-code { width: min(62vw, 210px); margin-bottom: var(--sp-3); }
    .qr-sheet-hint { margin: var(--sp-2) auto var(--sp-4); }
    .qr-sheet-wallet { margin-top: var(--sp-3); }
}
@media (max-height: 600px) {
    .qr-code { width: min(55vw, 170px); }
    .qr-sheet-hint { display: none; }
    .qr-sheet-actions { margin-top: var(--sp-4); }
}

.qr-sheet-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--sp-3);
}

/* Add to Apple / Google Wallet (QR sheet + You page) */
.qr-sheet-wallet {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-2);
    margin-top: var(--sp-4);
}
.wallet-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    width: 100%;
    min-height: 48px;
    padding: 0 var(--sp-5);
    border-radius: var(--radius-full);
    background: #000;
    color: #fff;
    font-size: var(--fs-base);
    font-weight: 600;
    text-decoration: none;
    -webkit-tap-highlight-color: transparent;
}
.wallet-btn svg { width: 22px; height: 22px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.wallet-btn:active { transform: scale(0.98); }
.wallet-btn.is-loading { opacity: 0.6; pointer-events: none; }
/* In the app, Apple Wallet needs the ryfa-native plugin (html.can-wallet);
   an older app build can't hand the pass to Wallet, so hide it there. */
html.is-native:not(.can-wallet) .wallet-btn[data-wallet="apple"] { display: none; }
@media (hover: hover) { a.wallet-btn:hover { color: #fff; background: #222; } }
.wallet-btn.has-badge { width: auto; min-height: 0; padding: 0; background: none; border-radius: 0; }
.wallet-btn.has-badge img { height: 48px; width: auto; display: block; }
.you-wallet { margin-top: var(--sp-3); display: flex; flex-direction: column; gap: var(--sp-2); }

/* Non-tappable row (e.g. "Settings — coming soon"). */
.row.is-disabled { opacity: 0.55; }

/* ============================================================
   Groups — initials tile (Home, group page, lists).
   ============================================================ */

.group-tile {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    border-radius: 28%;
    background: var(--accent-soft);
    color: var(--accent);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1;
}

/* Calendar-style date block (Upcoming Meetings on Home). */
.meeting-date {
    width: 44px;
    height: 44px;
    flex: none;
    border-radius: var(--radius-md);
    background: var(--surface-2);
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    line-height: 1;
}
.meeting-date-month {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--accent);
}
.meeting-date-day {
    font-size: var(--fs-lg);
    font-weight: 700;
    color: var(--ink);
    margin-top: 2px;
}

/* Private team tile — ink instead of coral so teams read differently. */
.group-tile.is-team {
    background: var(--ink);
    color: var(--paper);
}
.group-tile.is-team svg {
    width: 44%;
    height: 44%;
    stroke: currentColor;
    fill: none;
    stroke-width: 2;
}

/* "Create your team" call-to-action row on Home. */
.team-cta {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    border: 1px dashed var(--line);
    border-radius: var(--radius-lg);
    color: inherit;
    text-decoration: none;
    background: transparent;
}
.team-cta:hover { background: var(--surface); }
.team-cta-icon {
    width: 44px;
    height: 44px;
    flex: none;
    border-radius: 28%;
    background: var(--surface-2);
    color: var(--ink-2);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.team-cta-icon svg { width: 20px; height: 20px; stroke: currentColor; fill: none; stroke-width: 2; }
.person-list + .team-cta { margin-top: var(--sp-2); }

/* ============================================================
   Chats tab list.
   ============================================================ */
.chat-row-top,
.chat-row-bottom {
    display: flex;
    align-items: baseline;
    gap: var(--sp-2);
    min-width: 0;
}
.chat-row-top .person-row-name,
.chat-row-bottom .person-row-meta { flex: 1; min-width: 0; }
/* Chats tab: "Team" / "Groups" headers — the first sits close to the page title. */
.app-large-title + .chat-section-title { margin-top: 0; }

.chat-row-time {
    flex: none;
    font-size: var(--fs-xs);
    color: var(--ink-3);
}
.chat-row-badge {
    flex: none;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: var(--radius-full);
    background: var(--accent);
    color: var(--accent-ink);
    font-size: 11px;
    font-weight: 700;
    line-height: 20px;
    text-align: center;
    align-self: center;
}
.chat-row.is-unread .person-row-meta { color: var(--ink); font-weight: 500; }
.chat-row.is-unread .chat-row-time { color: var(--accent); font-weight: 600; }

/* Pro lifecycle banner (Home + Settings): payment failed, Pro ending, choose groups, rejoin */
.dg-banner {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin: var(--sp-4) 0;
    padding: var(--sp-3) var(--sp-4);
    border-radius: var(--radius-md);
    background: var(--accent-soft);
    color: var(--ink-2);
    font-size: var(--fs-sm);
    line-height: 1.45;
    text-decoration: none;
}
.dg-banner strong { color: var(--accent); font-weight: 600; }
.dg-banner.is-warn { background: rgba(220, 38, 38, 0.08); }
.dg-banner.is-warn strong { color: var(--danger); }
.dg-banner.is-success { background: rgba(22, 163, 74, 0.08); }
.dg-banner.is-success strong { color: #166534; }
@media (hover: hover) { a.dg-banner:hover { color: var(--ink); } }

/* Older browsers without aspect-ratio: keep the QR box square. */
@supports not (aspect-ratio: 1 / 1) {
    .qr-code { height: min(70vw, 260px); }
}
@media (max-height: 700px) { @supports not (aspect-ratio: 1 / 1) { .qr-code { height: min(62vw, 210px); } } }
@media (max-height: 600px) { @supports not (aspect-ratio: 1 / 1) { .qr-code { height: min(55vw, 170px); } } }

/* "Upcoming" on Home jumps to the Upcoming Meetings list inside the scroll area. */
#upcoming { scroll-margin-top: var(--sp-4); }
.app-scroll { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { .app-scroll { scroll-behavior: auto; } }

/* ============================================================
   Card views (You page, migration 015)
   ============================================================ */
.views-card {
    padding: var(--sp-4);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
}
.views-top { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
.views-num b { display: block; font-size: var(--fs-2xl); font-weight: 700; letter-spacing: -0.02em; line-height: 1.1; color: var(--ink); }
.views-num span { display: block; margin-top: 2px; font-size: var(--fs-xs); font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); }
.views-trend { margin: var(--sp-3) 0 0; font-size: var(--fs-sm); color: var(--ink-3); }
.views-trend.is-up { color: #15803D; font-weight: 600; }
.views-sources { list-style: none; margin: var(--sp-3) 0 0; padding: var(--sp-3) 0 0; border-top: 1px solid var(--line); }
.views-sources li { display: flex; justify-content: space-between; padding: 4px 0; font-size: var(--fs-sm); color: var(--ink-2); }
.views-sources b { font-weight: 600; color: var(--ink); }
.views-empty { margin: var(--sp-3) 0 0; font-size: var(--fs-sm); color: var(--ink-3); line-height: 1.5; }
.views-private { display: flex; align-items: center; gap: 6px; margin: var(--sp-3) 0 0; padding-top: var(--sp-3); border-top: 1px solid var(--line); font-size: var(--fs-sm); color: var(--ink-3); }
.views-private svg { flex: none; width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.views-private a { color: var(--accent); font-weight: 600; text-decoration: none; margin-left: auto; }
