/* ==========================================================================
   Shared component styles — Atlas-aligned
   - Per-component fine-grained styling lives in *.razor.css files; this file
     holds cross-cutting utilities + a few legacy class overrides that need
     theme variables applied without rewriting app.css.
   - Atlas: solid surfaces, no glass-morphism, no glow shadows.
   ========================================================================== */

/* ── Surface utilities ── */
.surface {
    background: var(--surface);
    border: 1px solid var(--surface-border);
    border-radius: var(--radius-md);
}

.surface-strong {
    background: var(--surface-strong);
    border: 1px solid var(--surface-border-strong);
    border-radius: var(--radius-md);
}

.elevated {
    box-shadow: var(--shadow-md);
}

.text-soft { color: var(--text-soft) !important; }
.text-muted-light { color: var(--text-muted) !important; }
.text-faint { color: var(--text-faint) !important; }

/* ── Atlas card (tokens) ── */
.atlas-card {
    background: var(--surface);
    border: 1px solid var(--surface-border);
    color: inherit;
}

.atlas-card:hover {
    color: inherit;
}

/* ── Buttons ── */
.btn-primary {
    background: var(--brand);
    border: 1px solid var(--text);
    color: var(--text-on-brand);
    transition: background var(--dur-fast) var(--ease-out),
                transform var(--dur-fast) var(--ease-out),
                filter var(--dur-fast) var(--ease-out);
}

.btn-primary:hover {
    background: var(--brand-strong);
    color: var(--text-on-brand);
    transform: translateY(-1px);
}

.btn-primary:active {
    transform: translateY(0);
    filter: brightness(0.95);
}

/* Solid Like button used on the swipe deck and match cards.
     Functional palette exception — the matching gesture must read instantly. */
.btn-like {
    background: var(--like);
    color: var(--text-strong);
    border: 1px solid var(--text);
    border-radius: var(--radius-pill);
    transition: transform var(--dur-fast) var(--ease-spring),
                filter var(--dur-fast) var(--ease-out);
}

.btn-like:hover { transform: scale(1.06); filter: brightness(1.05); }
.btn-like:active { transform: scale(0.96); }

.btn-pass {
    background: var(--surface);
    color: var(--text-soft);
    border: 1px solid var(--surface-border-strong);
    border-radius: var(--radius-pill);
    transition: transform var(--dur-fast) var(--ease-spring),
                background var(--dur-fast) var(--ease-out);
}

.btn-pass:hover { transform: scale(1.06); background: var(--surface-hover); color: var(--text); }
.btn-pass:active { transform: scale(0.96); }

.btn-super {
    background: var(--super);
    color: var(--bg);
    border: 1px solid var(--text);
    border-radius: var(--radius-pill);
    transition: transform var(--dur-fast) var(--ease-spring), filter var(--dur-fast);
}

.btn-super:hover { transform: scale(1.06) rotate(-4deg); filter: brightness(1.05); }
.btn-super:active { transform: scale(0.96); }

/* ── Skeleton shimmer ── */
@keyframes shimmer {
    0% { background-position: -200% 0; }
    100% { background-position: 200% 0; }
}

.skeleton {
    background: linear-gradient(90deg,
        var(--surface) 0%,
        var(--surface-strong) 50%,
        var(--surface) 100%);
    background-size: 200% 100%;
    animation: shimmer 1.4s linear infinite;
    border-radius: var(--radius-input);
}

.skeleton-line { height: 0.85rem; margin: 0.4rem 0; }
.skeleton-line.short { width: 40%; }
.skeleton-line.medium { width: 65%; }
.skeleton-line.long { width: 90%; }
.skeleton-circle { border-radius: 50%; }

/* ── Page padding to keep content clear of the bottom nav on mobile ── */
.dashboard-content {
    padding-bottom: calc(var(--bottom-nav-h) + var(--space-3)) !important;
}

@media (min-width: 900px) {
    .dashboard-content {
        padding-bottom: var(--space-4) !important;
    }
}

/* ── Subtle entrance for newly mounted pages ── */
@keyframes page-fade-in {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}

main, .dashboard-main {
    animation: page-fade-in var(--dur-slow) var(--ease-out);
}

/* ── Section title (Atlas-tuned typography) ── */
.section-title-warm {
    color: var(--text);
    font-family: var(--font-sequel);
    font-weight: 400;
    font-size: var(--text-subheading);
    line-height: var(--leading-subheading);
    letter-spacing: var(--tracking-subheading);
    margin-bottom: 0.25rem;
}

.section-subtitle-warm {
    color: var(--text-soft);
    font-size: var(--text-body-lg);
    line-height: var(--leading-body-lg);
    margin-bottom: var(--space-3);
}

/* ── Empty state with illustration spot + suggested action ── */
.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 3rem 1.5rem;
}

.empty-state .empty-art {
    width: 96px;
    height: 96px;
    border-radius: 50%;
    background: var(--brand);
    border: 1px solid var(--text);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-on-brand);
    font-size: 3rem;
    margin-bottom: 1.25rem;
}

.empty-state h2,
.empty-state h3 {
    color: var(--text);
    font-family: var(--font-sequel);
    font-weight: 400;
    font-size: var(--text-subheading);
    line-height: var(--leading-subheading);
    letter-spacing: var(--tracking-subheading);
    margin-bottom: 0.4rem;
}

.empty-state p,
.empty-state-body {
    color: var(--text-soft);
    max-width: 420px;
    line-height: var(--leading-body);
    margin-bottom: 1.25rem;
}

/* ── Lift hover utility ── */
.lift {
    transition: transform var(--dur-base) var(--ease-spring),
                background var(--dur-base) var(--ease-out);
}

.lift:hover {
    transform: translateY(-3px);
    background: var(--surface-strong);
}

/* ── Focus rings consistent across inputs ── */
/* Every focusable thing shows where focus is (WCAG 2.4.7 / 2.4.13). Programmatic targets
   (tabindex="-1", e.g. <main> after a skip link) are left alone. */
.btn:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
button:focus-visible,
a:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible {
    outline: 2px solid var(--text);
    outline-offset: 2px;
    box-shadow: 0 0 0 4px color-mix(in srgb, var(--text) 18%, transparent);
}

/* ── Atlas-light theme: swap a few legacy hard-coded classes ── */
:root[data-theme="light"] .text-muted-light { color: var(--text-muted) !important; }
:root[data-theme="light"] .atlas-card .form-control {
    background: var(--bg-elev-2);
    border: 1px solid var(--control-border);
    color: var(--text);
}
:root[data-theme="light"] .atlas-card .form-control::placeholder { color: var(--text-faint); }
:root[data-theme="light"] .auth-card { background: var(--surface); }
:root[data-theme="light"] .auth-card h1,
:root[data-theme="light"] .auth-card h2 { color: var(--text); }
:root[data-theme="light"] .auth-card .form-label { color: var(--text-soft); }
:root[data-theme="light"] .auth-card .form-control {
    background: var(--bg-elev-2);
    border-color: var(--control-border);
    color: var(--text);
}
:root[data-theme="light"] .navbar-brand,
:root[data-theme="light"] .nav-link,
:root[data-theme="light"] .dash-link,
:root[data-theme="light"] .user-email { color: var(--text-soft); }
:root[data-theme="light"] .nav-link:hover,
:root[data-theme="light"] .dash-link:hover { color: var(--text); }
:root[data-theme="light"] .hero-title { color: var(--text); }

/* ── SingleMeets ─────────────────────────────────────────────────────────────
   A meet is a time and a place, so the card leads with when and where and keeps
   attendance to a count. There is deliberately no attendee avatar row: who else
   is coming to a singles event a few hundred metres away is not something to
   show to strangers. */

.meet-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.meet-card {
    display: grid;
    grid-template-columns: 4.5rem 1fr auto;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg, 12px);
    background: var(--surface);
    cursor: pointer;
    transition: border-color var(--dur-fast) var(--ease-out),
                transform var(--dur-fast) var(--ease-out);
}

.meet-card:hover,
.meet-card:focus-visible {
    border-color: var(--accent);
    transform: translateY(-1px);
}

.meet-card.is-cancelled {
    opacity: 0.55;
}

.meet-when {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    line-height: 1.2;
}

.meet-day {
    color: var(--text-soft);
    font-size: var(--text-body-sm, 0.8125rem);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.meet-time {
    color: var(--text);
    font-size: var(--text-body-lg);
    font-weight: 600;
}

.meet-title {
    color: var(--text);
    font-family: var(--font-sequel);
    font-weight: 400;
    font-size: var(--text-body-lg);
    margin: 0 0 0.15rem;
}

.meet-venue {
    color: var(--text-soft);
    margin: 0 0 0.15rem;
}

.meet-going {
    color: var(--text-soft);
    font-size: var(--text-body-sm, 0.8125rem);
    margin: 0;
}

.meet-badge {
    display: inline-block;
    padding: 0.2rem 0.6rem;
    border-radius: 999px;
    font-size: var(--text-body-sm, 0.8125rem);
    white-space: nowrap;
    border: 1px solid var(--border);
    color: var(--text-soft);
}

.meet-badge.is-yes { border-color: var(--accent); color: var(--accent); }
.meet-badge.is-no,
.meet-badge.is-off { opacity: 0.7; }
.meet-badge.is-new { border-color: var(--accent); color: var(--accent); font-weight: 600; }

.meets-empty {
    padding: var(--space-4) 0;
}

.meet-detail-when {
    color: var(--text);
    font-size: var(--text-body-lg);
    margin-bottom: var(--space-2);
}

.meet-detail-description {
    color: var(--text-soft);
    margin-bottom: var(--space-3);
    max-width: 60ch;
}

.meet-rsvp {
    display: flex;
    gap: var(--space-2);
    margin-top: var(--space-3);
    flex-wrap: wrap;
}

.meet-reminder-note,
.meet-cancelled-notice,
.meet-error {
    color: var(--text-soft);
    font-size: var(--text-body-sm, 0.8125rem);
    margin-top: var(--space-2);
}

.meet-cancelled-notice { color: var(--text); }

/* ── One meet as the bridge to real life (NB-30) ── */
.meet-public { margin-left: var(--space-1); vertical-align: middle; }

.meet-detail-zone,
.meet-detail-address {
    display: block;
    color: var(--text-soft);
    font-size: var(--text-body-sm, 0.8125rem);
}

.meet-detail-address { font-size: var(--text-body); margin-bottom: var(--space-2); }

.meet-section {
    margin-top: var(--space-3);
    max-width: 60ch;
}

.meet-section-title {
    margin: 0 0 var(--space-1);
    color: var(--text);
    font-family: var(--font-sans);
    font-size: var(--text-body-lg);
    font-weight: 500;
}

.meet-host-note { color: var(--text-soft); margin: 0; }

.meet-companions {
    list-style: none;
    margin: 0 0 var(--space-1);
    padding: 0;
    display: grid;
    gap: var(--space-1);
}

.meet-companion { display: flex; align-items: flex-start; gap: var(--space-1); }

.meet-companion-initial {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: var(--radius-full);
    background: var(--surface-strong);
    color: var(--text);
    font-weight: 600;
}

.meet-companion-body { display: flex; flex-direction: column; }
.meet-companion-name { color: var(--text); }
.meet-companion-reason { color: var(--text-soft); font-size: var(--text-body-sm, 0.8125rem); }

.meet-yes { color: var(--text); margin: 0; font-weight: 500; }
.meet-checked-in { color: var(--text); margin-top: var(--space-2); }

.meet-confirm,
.meet-feedback {
    padding: var(--space-2);
    border: 1px solid var(--surface-border);
    border-radius: var(--radius-md);
    background: var(--surface);
}

.meet-confirm:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }

.meet-safety {
    margin: 0;
    padding-left: 1.2em;
    color: var(--text-soft);
    line-height: var(--lh-base);
}

.meet-safety li + li { margin-top: 4px; }

.meet-feelings { border: 0; margin: var(--space-2) 0; padding: 0; }
.meet-feelings-legend { font-size: var(--text-body); color: var(--text); margin-bottom: var(--space-1); }

.meet-feeling {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin-right: var(--space-2);
    min-height: 44px;
}

.meet-feedback-label { display: block; color: var(--text); margin-top: var(--space-1); }
.meet-feedback-note { margin: var(--space-1) 0; }
.meet-feedback-safety { display: flex; }

@media (max-width: 480px) {
    .meet-card {
        grid-template-columns: 3.75rem 1fr;
        grid-template-areas: "when what" "state state";
    }
    .meet-when { grid-area: when; }
    .meet-what { grid-area: what; }
    .meet-state { grid-area: state; }
}

/* ==========================================================================
   Atlas components (NB-25) — the replacements for the Bootstrap leftovers.
   Razor components live in Components/Atlas; these are their styles plus the
   few utilities app pages need. Tokens only; contrast pairs are declared in
   theme.css and checked by Frontend.Tests.
   ========================================================================== */

/* ── Screen-reader-only text (same contract as Bootstrap's, so it survives Bootstrap leaving) ── */
.visually-hidden,
.visually-hidden-focusable:not(:focus):not(:focus-within) {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

/* ── Skip link: the first stop for keyboard users on every app page ── */
.skip-link {
    position: absolute;
    left: var(--space-2);
    top: var(--space-1);
    z-index: 1100;
    padding: 10px 16px;
    border-radius: var(--radius-input);
    background: var(--text);
    color: var(--bg);
    font-size: var(--text-body);
    text-decoration: none;
}

.skip-link:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* ── Text tones (replace text-muted / text-success / text-danger …) ── */
.text-tone-success { color: var(--match) !important; }
.text-tone-danger  { color: var(--danger) !important; }
.text-tone-warning { color: var(--super) !important; }
.text-tone-info    { color: var(--info) !important; }
.text-accent       { color: var(--accent) !important; }

.text-small {
    font-size: var(--text-body-sm);
    line-height: var(--leading-body-sm);
}

/* ── Banner (replaces .alert) ── */
.atlas-banner {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    padding: var(--space-2);
    margin-bottom: var(--space-2);
    border-radius: var(--radius-input);
    border: 1px solid var(--surface-border);
    border-left: 3px solid var(--tone-edge, var(--text-muted));
    background: var(--tone-bg, var(--surface-strong));
    color: var(--text);
    font-size: var(--text-body);
    line-height: var(--leading-body);
}

.atlas-banner-title {
    margin: 0;
    font-weight: 600;
    color: var(--tone-fg, var(--text));
}

.atlas-banner-body > :last-child { margin-bottom: 0; }

.atlas-banner-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    margin-top: var(--space-1);
}

.atlas-banner--info    { --tone-edge: var(--info);   --tone-fg: var(--info);   --tone-bg: var(--info-soft); }
.atlas-banner--success { --tone-edge: var(--match);  --tone-fg: var(--match);  --tone-bg: var(--match-soft); }
.atlas-banner--warning { --tone-edge: var(--super);  --tone-fg: var(--super);  --tone-bg: var(--super-soft); }
.atlas-banner--danger  { --tone-edge: var(--danger); --tone-fg: var(--danger); --tone-bg: var(--danger-soft); }

/* The body text stays --text (highest contrast); only the edge and title carry the tone. */

/* ── Pill (replaces .badge + bg-*) ── */
.atlas-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.15rem 0.6rem;
    border-radius: var(--radius-full);
    border: 1px solid var(--surface-border-strong);
    background: var(--surface-strong);
    color: var(--text-soft);
    font-size: var(--text-caption);
    line-height: var(--leading-caption);
    font-weight: 500;
    white-space: nowrap;
}

.atlas-pill--success { color: var(--match);  background: var(--match-soft);  border-color: transparent; }
.atlas-pill--warning { color: var(--super);  background: var(--super-soft);  border-color: transparent; }
.atlas-pill--danger  { color: var(--danger); background: var(--danger-soft); border-color: transparent; }
.atlas-pill--info    { color: var(--info);   background: var(--info-soft);   border-color: transparent; }
.atlas-pill--accent  { color: var(--accent); background: var(--accent-soft); border-color: transparent; }

/* ── Stat ── */
.atlas-stat {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.atlas-stat-value {
    font-family: var(--font-sequel);
    font-size: var(--text-heading-lg);
    line-height: var(--leading-heading-lg);
    letter-spacing: var(--tracking-heading-lg);
    color: var(--text);
}

.atlas-stat-label {
    font-size: var(--text-body-sm);
    color: var(--text-muted);
}

/* ── Empty state actions ── */
.empty-state-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-1);
}

/* ── Spinner (replaces .spinner-border) ── */
@keyframes atlas-spin {
    to { transform: rotate(360deg); }
}

.atlas-spinner {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    color: var(--text-muted);
    font-size: var(--text-body);
    vertical-align: middle;
}

.atlas-spinner-ring {
    width: 1.5rem;
    height: 1.5rem;
    flex-shrink: 0;
    border-radius: 50%;
    border: 2px solid var(--surface-border-strong);
    border-top-color: var(--accent);
    animation: atlas-spin 0.9s linear infinite;
}

.atlas-spinner--sm .atlas-spinner-ring {
    width: 1rem;
    height: 1rem;
}

.atlas-spinner--block {
    display: flex;
    justify-content: center;
    padding: var(--space-5) 0;
}

/* Inside a filled button the ring follows the button's text colour. */
.btn .atlas-spinner { color: inherit; margin-right: 0.4rem; }
.btn-primary .atlas-spinner-ring { border-color: color-mix(in srgb, var(--text-on-brand) 35%, transparent); border-top-color: var(--text-on-brand); }

/* ── Destructive button (replaces btn-outline-danger) ── */
.btn-danger-atlas {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--danger);
    background: transparent;
    border: 1px solid var(--danger);
    border-radius: var(--radius-outline);
    padding: 8px 16px;
    font-family: var(--font-sans);
    font-size: var(--text-body);
    line-height: 1;
    text-decoration: none;
    transition: background var(--dur-fast) var(--ease-out);
}

.btn-danger-atlas:hover {
    color: var(--danger);
    background: var(--danger-soft);
    border-color: var(--danger);
}

/* Disabled buttons keep their words legible: dimmed, not erased. */
.btn-ghost-atlas:disabled,
.btn-danger-atlas:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* ── Form controls, everywhere in the app (Bootstrap's are white on the black canvas) ── */
.form-control,
.form-select {
    background-color: var(--bg-elev-2);
    color: var(--text);
    border: 1px solid var(--control-border);
    border-radius: var(--radius-input);
}

.form-control:focus,
.form-select:focus {
    background-color: var(--bg-elev-3);
    color: var(--text);
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent);
}

.form-control::placeholder { color: var(--text-faint); }

.form-control:disabled,
.form-select:disabled {
    background-color: var(--bg-elev-1);
    color: var(--text-muted);
}

.form-label { color: var(--text-soft); }
.form-text { color: var(--text-muted); font-size: var(--text-body-sm); }

.form-check-input {
    background-color: var(--bg-elev-2);
    border-color: var(--control-border);
}

.form-check-input:checked {
    background-color: var(--accent);
    border-color: var(--accent);
}

/* ── Minimum target size (WCAG 2.2, 2.5.8): every icon-only control is at least 24×24 ── */
.btn-sm,
.btn-icon {
    min-height: 24px;
    min-width: 24px;
}
