@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&family=Source+Serif+4:opsz,wght@8..60,400;8..60,500;8..60,600&family=IBM+Plex+Mono:wght@400;500&display=swap');

/* Praxis design system — calm modern academic. Re-skins Bootstrap 5 via tokens.
   See DESIGN.md for the rationale behind these values. */

:root {
    /* Neutrals carry a faint sage tint (hue ~150), never warm. */
    --bg: oklch(0.985 0.004 150);
    --surface: oklch(0.972 0.006 150);
    --surface-2: oklch(0.945 0.008 150);
    --border: oklch(0.90 0.008 150);
    --border-strong: oklch(0.83 0.01 150);

    --ink: oklch(0.27 0.012 220);
    --ink-muted: oklch(0.50 0.012 220);
    --ink-faint: oklch(0.62 0.01 220);

    --brand: oklch(0.50 0.072 150);
    --brand-hover: oklch(0.43 0.072 150);
    --brand-tint: oklch(0.94 0.02 150);

    --accent: oklch(0.74 0.10 75);

    /* Hypothesis status — text/dot color + soft tint background. */
    --st-open: oklch(0.50 0.02 250);
    --st-open-bg: oklch(0.95 0.012 250);
    --st-testing: oklch(0.52 0.10 65);
    --st-testing-bg: oklch(0.95 0.035 75);
    --st-supported: oklch(0.48 0.13 155);
    --st-supported-bg: oklch(0.94 0.045 155);
    --st-rejected: oklch(0.53 0.17 25);
    --st-rejected-bg: oklch(0.95 0.032 25);

    --radius: 12px;
    --radius-sm: 8px;
    --shadow-sm: 0 1px 2px rgb(0 0 0 / 0.04);
    --shadow-md: 0 6px 20px -8px rgb(20 30 25 / 0.18);
    --ease: cubic-bezier(0.22, 1, 0.36, 1); /* ease-out-expo-ish */

    /* Hand Bootstrap our tokens so its components inherit the system. */
    --bs-body-bg: var(--bg);
    --bs-body-color: var(--ink);
    --bs-body-font-family: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --bs-border-color: var(--border);
    --bs-border-radius: var(--radius-sm);
    --bs-border-radius-lg: var(--radius);
    --bs-link-color: var(--brand);
    --bs-link-hover-color: var(--brand-hover);
    --bs-emphasis-color: var(--ink);
    --bs-secondary-color: var(--ink-muted);
}

body {
    background-color: var(--bg);
    color: var(--ink);
    font-family: var(--bs-body-font-family);
    -webkit-font-smoothing: antialiased;
}

/* Typography */

h1, h2, h3, .h1, .h2, .h3,
.navbar-brand, .modal-title {
    font-family: 'Source Serif 4', Georgia, serif;
    color: var(--ink);
    letter-spacing: -0.015em;
    text-wrap: balance;
}
h1, h2, h3 { font-weight: 600; }
h4, h5, h6, .h4, .h5, .h6 { font-weight: 600; letter-spacing: -0.01em; }

.text-secondary { color: var(--ink-muted) !important; }
.text-muted { color: var(--ink-faint) !important; }
small, .small { color: inherit; }

/* Mono for terse research metadata: counts, dates, ids, DOIs. */
.mono, .meta {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-variant-numeric: tabular-nums;
}
.meta { color: var(--ink-faint); font-size: 0.82rem; letter-spacing: -0.01em; }

a {
    color: var(--brand);
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
    transition: color 0.15s var(--ease);
}
a:hover { color: var(--brand-hover); }

::selection { background: var(--brand-tint); color: var(--ink); }

/* Visible focus ring on every interactive control. */
:where(a, button, .btn, .form-control, .form-select, .nav-link, input, textarea):focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px color-mix(in oklch, var(--brand) 32%, transparent);
    border-color: var(--brand);
}

/* Buttons */

.btn {
    --bs-btn-font-family: var(--bs-body-font-family);
    font-weight: 500;
    border-radius: var(--radius-sm);
    padding-inline: 1rem;
    transition: background-color 0.15s var(--ease), border-color 0.15s var(--ease),
                color 0.15s var(--ease), transform 0.1s var(--ease);
}
.btn:active { transform: translateY(0.5px); }

.btn-primary {
    --bs-btn-bg: var(--brand);
    --bs-btn-border-color: var(--brand);
    --bs-btn-hover-bg: var(--brand-hover);
    --bs-btn-hover-border-color: var(--brand-hover);
    --bs-btn-active-bg: var(--brand-hover);
    --bs-btn-active-border-color: var(--brand-hover);
    --bs-btn-disabled-bg: var(--brand);
    --bs-btn-disabled-border-color: var(--brand);
    --bs-btn-color: #fff;
    --bs-btn-hover-color: #fff;
    --bs-btn-active-color: #fff;
}

.btn-outline-secondary {
    --bs-btn-color: var(--ink);
    --bs-btn-border-color: var(--border-strong);
    --bs-btn-bg: var(--surface);
    --bs-btn-hover-bg: var(--surface-2);
    --bs-btn-hover-color: var(--ink);
    --bs-btn-hover-border-color: var(--border-strong);
    --bs-btn-active-bg: var(--surface-2);
    --bs-btn-active-color: var(--ink);
    --bs-btn-active-border-color: var(--border-strong);
}

.btn-link { text-decoration: none; font-weight: 500; }

.text-primary { color: var(--brand) !important; }
.text-success { color: var(--st-supported) !important; }
.bg-primary { background-color: var(--brand) !important; }
.bg-surface { background-color: var(--surface) !important; }

/* Cards / panels */

.card {
    --bs-card-bg: var(--surface);
    --bs-card-border-color: var(--border);
    --bs-card-border-radius: var(--radius);
    --bs-card-cap-bg: transparent;
    box-shadow: var(--shadow-sm);
}

/* Project / hypothesis cards that are links: quiet lift on hover. */
a.card {
    transition: border-color 0.18s var(--ease), box-shadow 0.18s var(--ease),
                transform 0.18s var(--ease);
}
a.card:hover {
    border-color: var(--border-strong);
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

/* Forms */

.form-label { font-weight: 500; color: var(--ink); margin-bottom: 0.35rem; }
.form-control, .form-select {
    background-color: var(--surface);
    border-color: var(--border-strong);
    color: var(--ink);
    border-radius: var(--radius-sm);
    transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease);
}
.form-control::placeholder { color: var(--ink-faint); }
.form-control:focus, .form-select:focus {
    background-color: var(--surface);
    border-color: var(--brand);
    box-shadow: 0 0 0 3px color-mix(in oklch, var(--brand) 28%, transparent);
}

/* Navigation */

.navbar { background-color: var(--surface) !important; }
.navbar.border-bottom, .border-bottom { border-color: var(--border) !important; }
.border-top { border-color: var(--border) !important; }
.border-end { border-color: var(--border) !important; }

.navbar-brand {
    font-weight: 600;
    color: var(--brand) !important;
    letter-spacing: -0.02em;
}

/* Sidebar pills: tinted active state, no stripe. */
.nav-pills {
    --bs-nav-pills-border-radius: var(--radius-sm);
    --bs-nav-pills-link-active-bg: var(--brand-tint);
    --bs-nav-pills-link-active-color: var(--brand-hover);
}
.nav-pills .nav-link {
    color: var(--ink-muted);
    font-weight: 500;
    padding: 0.5rem 0.75rem;
    transition: background-color 0.15s var(--ease), color 0.15s var(--ease);
}
.nav-pills .nav-link:hover { background-color: var(--surface-2); color: var(--ink); }
.nav-pills .nav-link.active { font-weight: 600; }

/* Status badges */

.badge {
    font-weight: 500;
    border-radius: 999px;
    padding: 0.34em 0.7em 0.34em 0.62em;
    font-size: 0.76rem;
    letter-spacing: 0;
}

.badge-status-open,
.badge-status-testing,
.badge-status-supported,
.badge-status-rejected {
    display: inline-flex;
    align-items: center;
    gap: 0.42em;
    text-transform: capitalize;
    background: var(--surface-2);
    color: var(--ink-muted);
}
.badge-status-open::before,
.badge-status-testing::before,
.badge-status-supported::before,
.badge-status-rejected::before {
    content: "";
    width: 0.5em;
    height: 0.5em;
    border-radius: 50%;
    background: currentColor;
    flex: none;
}
.badge-status-open      { background: var(--st-open-bg);      color: var(--st-open); }
.badge-status-testing   { background: var(--st-testing-bg);   color: var(--st-testing); }
.badge-status-supported { background: var(--st-supported-bg); color: var(--st-supported); }
.badge-status-rejected  { background: var(--st-rejected-bg);  color: var(--st-rejected); }

/* Generic light badge (project status) → quiet neutral pill. */
.badge.text-bg-light {
    background: var(--surface-2) !important;
    color: var(--ink-muted) !important;
    text-transform: capitalize;
}

/* Tables (admin) */

.table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--ink);
    --bs-table-border-color: var(--border);
    --bs-table-hover-bg: var(--surface-2);
    vertical-align: middle;
}
.table > thead {
    color: var(--ink-muted);
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.table > thead th { border-bottom-color: var(--border-strong); font-weight: 600; }

/* Modals / alerts */

.modal-content {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-md);
}
.modal-header, .modal-footer { border-color: var(--border); }

.alert-danger {
    --bs-alert-bg: var(--st-rejected-bg);
    --bs-alert-border-color: color-mix(in oklch, var(--st-rejected) 30%, transparent);
    --bs-alert-color: var(--st-rejected);
}

/* Landing hero */

.hero {
    background:
        radial-gradient(120% 120% at 50% -20%, var(--brand-tint), transparent 60%),
        var(--bg);
    border-bottom: 1px solid var(--border);
}
.hero h1 { letter-spacing: -0.025em; }

/* Feature icons on landing: quiet, framed, not loud. */
.feature-icon {
    display: inline-grid;
    place-items: center;
    width: 3rem;
    height: 3rem;
    border-radius: var(--radius-sm);
    background: var(--brand-tint);
    color: var(--brand-hover);
    font-size: 1.4rem;
    margin-bottom: 0.5rem;
}

/* Landing product shots */

.window {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}
.shadow-window { box-shadow: 0 24px 60px -24px rgb(20 35 25 / 0.28); }
.window-bar {
    display: flex;
    gap: 0.4rem;
    align-items: center;
    padding: 0.6rem 0.8rem;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
}
.window-bar span {
    width: 0.6rem;
    height: 0.6rem;
    border-radius: 50%;
    background: var(--border-strong);
}
.window img { display: block; width: 100%; height: auto; }

/* Audience photos in the "Who it's for" section. A consistent crop and a calm
   tinted frame keep the three portraits feeling like one set, not stock. */
.audience-photo {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    border-radius: var(--radius);
    border: 1px solid var(--border);
}

.openalex-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.75rem;
    border-radius: 999px;
    background: var(--brand-tint);
    color: var(--brand-hover);
    font-size: 0.82rem;
    font-weight: 500;
}

/* Static OpenAlex search mock: real component styling, fixed content. */
.search-mock { padding: 1rem; background: var(--bg); }
.search-mock-input {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.7rem 0.9rem;
    margin-bottom: 0.9rem;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--ink-muted);
}
.search-mock-result {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    padding: 0.8rem 0.9rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
}
.search-mock-result + .search-mock-result { margin-top: 0.6rem; }
.search-mock-result a { text-decoration: none; }

.btn-outline-primary {
    --bs-btn-color: var(--brand);
    --bs-btn-border-color: var(--brand);
    --bs-btn-hover-bg: var(--brand);
    --bs-btn-hover-border-color: var(--brand);
    --bs-btn-hover-color: #fff;
    --bs-btn-active-bg: var(--brand-hover);
    --bs-btn-active-border-color: var(--brand-hover);
    --bs-btn-active-color: #fff;
}

/* App shell */

.app-shell { display: flex; min-height: 100vh; }

.app-sidebar {
    flex: 0 0 248px;
    width: 248px;
    height: 100vh;
    position: sticky;
    top: 0;
    background: var(--surface);
    border-right: 1px solid var(--border);
    padding: 1.25rem 0.9rem;
    display: flex;
    flex-direction: column;
}
.app-sidebar .brand {
    font-family: 'Source Serif 4', Georgia, serif;
    font-weight: 600;
    font-size: 1.4rem;
    letter-spacing: -0.02em;
    color: var(--brand);
    text-decoration: none;
    padding: 0.1rem 0.65rem 1.1rem;
}
.app-nav { display: flex; flex-direction: column; gap: 0.15rem; }
.app-nav a {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.65rem;
    border-radius: var(--radius-sm);
    color: var(--ink-muted);
    font-weight: 500;
    text-decoration: none;
    transition: background-color 0.15s var(--ease), color 0.15s var(--ease);
}
.app-nav a i { font-size: 1.05rem; }
.app-nav a:hover { background: var(--surface-2); color: var(--ink); }
.app-nav a.active { background: var(--brand-tint); color: var(--brand-hover); font-weight: 600; }

.app-sidebar .sidebar-foot {
    margin-top: auto;
    border-top: 1px solid var(--border);
    padding-top: 0.85rem;
}
.app-sidebar .who { padding: 0 0.65rem 0.6rem; line-height: 1.35; }
.app-sidebar .who .name { font-weight: 600; font-size: 0.9rem; color: var(--ink); }
.app-sidebar .who .role {
    font-family: 'IBM Plex Mono', ui-monospace, monospace;
    font-size: 0.72rem;
    color: var(--ink-faint);
    text-transform: capitalize;
}
.app-sidebar .sidebar-foot .btn { width: 100%; }

.app-main { flex: 1 1 auto; min-width: 0; display: flex; justify-content: center; }
/* Center the readable column inside the main pane so the right side does not
   look empty on wide screens. width:100% lets the inner padding still hug the
   sidebar on narrower screens. */
.app-content { max-width: 1040px; width: 100%; margin-inline: auto; }
.app-content.narrow { max-width: 820px; }

@media (max-width: 767.98px) {
    .app-shell { flex-direction: column; }
    .app-sidebar {
        flex-basis: auto;
        width: auto;
        height: auto;
        position: static;
        flex-direction: row;
        align-items: center;
        flex-wrap: wrap;
        gap: 0.4rem;
        padding: 0.6rem 0.9rem;
        border-right: none;
        border-bottom: 1px solid var(--border);
    }
    .app-sidebar .brand { padding: 0 0.5rem 0; font-size: 1.2rem; }
    .app-nav { flex-direction: row; flex: 1 1 auto; }
    .app-sidebar .sidebar-foot {
        margin: 0 0 0 auto;
        border: none;
        padding: 0;
    }
    .app-sidebar .sidebar-foot .btn { width: auto; }
    .app-sidebar .who { display: none; }
}

/* Motion */

/* Smooth the multi-page navigation: the browser crossfades between documents
   instead of flashing white, and the named sidebar is treated as the same
   element across pages so it stays put while only the content changes. */
@view-transition { navigation: auto; }
.app-sidebar { view-transition-name: praxis-sidebar; }

@media (prefers-reduced-motion: reduce) {
    @view-transition { navigation: none; }
    *, *::before, *::after {
        animation-duration: 0.001ms !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }
    a.card:hover { transform: none; }
}
