/*
* Novasyne — page-specific styles.
*
* These were <style> blocks inside the templates, 15 of them, and pulling them
* into one file is what made two things visible that a per-page block hides.
*
* Six templates each carried their own copy of the DataTables overrides, all
* painting #20519c and already drifted apart — the recordings page had given
* itself a green current-page button while every other table had a blue one.
* That set lives once now, in precision.css, with the rest of the table chrome.
*
* And the old palette was still here long after the theme moved on. A
* page-local block is invisible to a sweep of the stylesheets, which is
* exactly how it survived.
*
* Rules are grouped by page, and where a page styled `body` itself it is
* scoped through the data-page-name attribute the layout already sets.
*/

/* ========================================
   NAVIGATION

   The bar carried no styling of its own — .app-navbar was declared in base.html
   and matched nothing in any stylesheet — so it inherited the page background
   and the logo appeared to float above the content with nothing between them.

   A hairline in --border is the separation; the --surface fill is what makes it
   read as the bottom edge of a bar rather than a rule drawn across the page,
   since the body sits on --background. On the two pages that set the body to
   --surface (index, learn_more) the fill matches and the line carries it alone,
   which is still an unambiguous edge.
   ======================================== */
.app-navbar {
    background: var(--surface);
    border-bottom: 1px solid var(--border);

    /* The links were on Bootstrap's default --bs-navbar-color,
       rgba(0, 0, 0, .65), which composites to #595959 on white — a washed grey
       that no token in the system produces, and the reason the bar read as
       faint. Pointed at the ink token instead: 15.20:1 on --surface against the
       5.92:1 it was. Hover and the current page take the brand colour, so
       "where I am" is carried by hue rather than by yet another grey. */
    --bs-navbar-color: var(--text-primary);
    --bs-navbar-hover-color: var(--primary);
    --bs-navbar-active-color: var(--primary);
    --bs-navbar-disabled-color: var(--text-muted);
}

/* .brand-name and .brand-tagline were divs and matched nothing in any
   stylesheet, so they stacked: logo, then STUDYPRO, then the tagline, three
   lines and about 145px of every page spent on a wordmark. They are spans laid
   out in a row now. Novasyne is the company and STUDYPRO the product, so the
   logo carries the company and the text carries the product. */
.navbar-brand {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.brand-text {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
}

.brand-name {
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: 0.02em;
    color: var(--text-primary);
}

/* The tagline left the masthead and became the footer's brand line, so the
   wordmark is the only thing beside the logo. */

.app-navbar .nav-link.active {
    font-weight: 600;
}

/* --- study-scoped header and tabs -------------------------------------- */

/* The sections of a study used to be split across the study list and
   edit_study with no overlap, so nothing showed them all and the dashboard was
   a dead end. _study_nav.html renders this block on every study page. */
.study-breadcrumb {
    margin-bottom: 0.5rem;
    font-size: 0.875rem;
}

/* Bootstrap's default link blue is not a colour this system uses anywhere
   else, and the breadcrumb sits directly above a heading in --text-primary,
   so the contrast between them read as an accident. */
.study-breadcrumb a {
    color: var(--primary);
    text-decoration: none;
}

.study-breadcrumb a:hover,
.study-breadcrumb a:focus {
    color: var(--primary-dark);
    text-decoration: underline;
}

.study-breadcrumb .breadcrumb-item.active {
    color: var(--text-muted);
}

.study-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
}

.study-header-title {
    font-size: 1.75rem;
    font-weight: 700;
    margin: 0;
    color: var(--text-primary);
}

.study-header-subtitle {
    margin: 0.25rem 0 0;
    color: var(--text-muted);
    font-size: 0.9375rem;
}

.study-header-subtitle strong {
    color: var(--text-primary);
}

.study-status-badge {
    background: var(--surface-hover);
    color: var(--text-primary);
    border: 1px solid var(--border);
    font-weight: 600;
    margin-left: 0.5rem;
}

.study-header-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.study-tabs {
    margin-bottom: 1.5rem;
    flex-wrap: wrap;
}

/* Actions that belong to a section rather than to the study sit under the tab
   strip. Recordings carries five of them, which crowded the study name when
   they shared a row with the heading. */
.study-section-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 1.25rem;
}

.study-tabs .nav-link {
    color: var(--text-secondary);
    border: 1px solid transparent;
    padding: 0.5rem 0.85rem;
}

.study-tabs .nav-link:hover {
    color: var(--primary);
    border-color: var(--border-light) var(--border-light) var(--border);
}

.study-tabs .nav-link.active {
    color: var(--primary);
    font-weight: 600;
}

/* --- study status badges ------------------------------------------------ */

/* Every status rendered as the same grey pill, so the column carried no
   information you could read at a glance. Four statuses, four treatments. */
.status-badge {
    font-weight: 600;
    border: 1px solid transparent;
}

.status-planned {
    background: var(--surface-hover);
    color: var(--text-secondary);
    border-color: var(--border);
}

.status-ongoing {
    background: var(--accent);
    color: var(--text-inverse);
}

.status-completed {
    background: var(--success-soft);
    color: var(--success);
    border-color: var(--success);
}

.status-withdrawn {
    background: var(--danger-soft);
    color: var(--danger);
    border-color: var(--danger);
}

/* Which studies you administer used to be visible only in a second study list
   buried on the account page. It travels with the study name now. */
.status-admin {
    background: var(--success-soft);
    color: var(--success);
    border-color: var(--success);
}

.account-tabs .nav-link {
    color: var(--text-secondary);
}

.account-tabs .nav-link.active {
    color: var(--primary);
    font-weight: 600;
}

/* --- empty states ------------------------------------------------------- */

/* The visualization pages showed a ~310px options column beside a thousand
   pixels of blank white until you clicked a plot type, which reads as a page
   that failed rather than one waiting for input. */
.plot-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 420px;
    padding: 2rem;
    text-align: center;
    color: var(--text-muted);
    border: 1px dashed var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface-alt);
}

.plot-empty-state i {
    font-size: 2.5rem;
    margin-bottom: 0.75rem;
    color: var(--border-strong);
}

.plot-empty-state h5 {
    color: var(--text-secondary);
    margin-bottom: 0.35rem;
}

.plot-empty-state p {
    margin: 0;
    font-size: 0.9375rem;
}

/* --- analytics run history ---------------------------------------------- */

/* Results used to appear in a modal and vanish when it closed. They render
   inline now, and each run this session leaves a pill here that re-runs it. */
.analysis-run-history {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.analysis-run-pill {
    font-size: 0.8125rem;
}

/* --- wizard stepper ----------------------------------------------------- */

/* "Step 1 of 3" was heading text and nothing more -- no progress indicator,
   and no way to see what the later steps held before reaching them. */
.wizard-steps {
    list-style: none;
    display: flex;
    gap: 1rem;
    padding: 0;
    margin: 0 0 1.5rem;
    flex-wrap: wrap;
}

.wizard-step {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    flex: 1 1 220px;
    padding: 0.75rem 1rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface);
}

.wizard-step-marker {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 1.75rem;
    height: 1.75rem;
    border-radius: 50%;
    background: var(--surface-hover);
    color: var(--text-muted);
    font-weight: 700;
    font-size: 0.875rem;
}

.wizard-step-text {
    display: flex;
    flex-direction: column;
}

.wizard-step-label {
    font-weight: 600;
    color: var(--text-secondary);
    line-height: 1.3;
}

.wizard-step-description {
    font-size: 0.8125rem;
    color: var(--text-muted);
}

.wizard-step-current {
    border-color: var(--primary);
}

.wizard-step-current .wizard-step-marker {
    background: var(--primary);
    color: var(--text-inverse);
}

.wizard-step-current .wizard-step-label {
    color: var(--text-primary);
}

.wizard-step-done .wizard-step-marker {
    background: var(--success);
    color: var(--text-inverse);
}

/* Was an inline background-color: #f8f9fa — Bootstrap's grey rather than
   anything this system defines. */
.wizard-panel {
    background-color: var(--surface-alt);
}

/* --- destructive actions ----------------------------------------------- */

/* Close Your Account on manage_account is the pattern: a bordered card with a
   filled header, so a destructive action cannot be mistaken for the buttons
   next to it. Revoke Study used to be an ordinary red-text button in the same
   row as Export Study. */
.danger-zone {
    border-color: var(--danger);
}

.danger-zone > .card-header {
    background: var(--danger);
    color: var(--text-inverse);
    font-weight: 600;
}

/* --- footer ------------------------------------------------------------ */

/* About and Contact used to sit in the primary nav inside the workspace,
   which put marketing chrome beside Studies and Account. They live here now.

   Sticky footer: core already gives body min-height 100vh, but without a
   column flex context the footer sat directly under the content, so a short
   page — an empty Documents tab, Arms with two rows — left it hanging in the
   middle of the viewport with background below it. main takes the slack. */
body {
    display: flex;
    flex-direction: column;
}

.main-container {
    flex: 1 0 auto;
    width: 100%;
}

.app-footer {
    flex-shrink: 0;
    margin-top: auto;
    background: var(--text-primary);
    color: var(--text-inverse);
    padding: 1.15rem 0;
    font-size: 0.875rem;
}

.app-footer .container-fluid {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
}

/* The footer is dark, so its own text cannot use the body ink tokens. White at
   72% carries the secondary weight without needing a second colour. */
.app-footer-brand {
    color: rgba(255, 255, 255, 0.72);
}

.app-footer-links {
    display: flex;
    gap: 1.25rem;
    flex-wrap: wrap;
}

.app-footer-links a {
    color: rgba(255, 255, 255, 0.86);
    text-decoration: none;
}

.app-footer-links a:hover,
.app-footer-links a:focus {
    color: var(--text-inverse);
    text-decoration: underline;
}

/* --- about ------------------------------------------------------------- */
.about-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
    max-width: 900px;
    margin: 2rem auto;
}

.about-header {
    background: var(--primary);
    padding: 2rem;
    text-align: center;
}

.about-header h1 {
    color: var(--text-inverse);
    font-size: 1.75rem;
    font-weight: 700;
    margin: 0;
}

.about-header p {
    color: rgba(255,255,255,0.8);
    font-size: 0.875rem;
    margin: 0.5rem 0 0;
}

.about-body {
    padding: 2.5rem;
}

.about-body .lead {
    font-size: 1.0625rem;
    font-weight: 600;
    color: var(--primary);
    line-height: 1.7;
    margin-bottom: 1.5rem;
    padding-bottom: 1.5rem;
    border-bottom: 2px solid;
}

.about-body p {
    font-size: 0.9375rem;
    color: var(--text-secondary);
    line-height: 1.8;
    margin-bottom: 1.25rem;
    text-align: justify;
}

.about-body p:last-of-type {
    margin-bottom: 0;
}

.about-footer {
    background: var(--surface-alt);
    padding: 1.5rem 2.5rem;
    border-top: 1px solid var(--border);
    text-align: center;
}

.about-footer img {
    max-width: 120px;
    height: auto;
    opacity: 0.9;
    transition: var(--transition);
}

.about-footer img:hover {
    opacity: 1;
}

/* Values Section */
.values-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1.25rem;
    margin-top: 2rem;
    padding-top: 2rem;
    border-top: 1px solid var(--border);
}

@media (max-width: 768px) {
    .values-grid {
        grid-template-columns: 1fr;
    }
}

.value-item {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
}

.value-icon {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    background: var(--accent);
    border-radius: var(--radius);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-inverse);
    font-size: 1.125rem;
}

.value-content h4 {
    font-size: 0.875rem;
    font-weight: 700;
    color: var(--text-primary);
    margin-bottom: 0.25rem;
}

.value-content p {
    font-size: 0.8125rem;
    color: var(--text-muted);
    margin: 0;
    text-align: left;
}

/* --- analytics --------------------------------------------------------- */
#analysisResultModalBody {
    min-height: 400px;
}

#modalLoadingSpinner {
    width: 5rem;
    height: 5rem;
}

#knowledgeFileList {
    max-height: 300px;
    overflow-y: scroll;
    overflow-x: hidden;
}

.bokeh-chart-container .bk-root {
    min-height: 400px;
}

/* --- best_practices ---------------------------------------------------- */
.accordion-button {
    font-weight: 600;
    font-size: 1.1rem;
    color: var(--text-primary);
}

.accordion-button:not(.collapsed) {
    color: var(--surface);
    background-color: var(--primary);
    box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .125);
}

/* Arrow icon color fix for active state */
.accordion-button:not(.collapsed)::after {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23ffffff'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
}

.accordion-button:focus {
    z-index: 3;
    border-color: var(--accent-light);
    outline: 0;
    box-shadow: 0 0 0 0.25rem rgba(32, 81, 156, 0.25);
}

.accordion-body h5 {
    color: var(--primary);
    font-weight: 700;
    margin-top: 1rem;
    margin-bottom: 0.5rem;
    border-bottom: 1px solid var(--border);
    padding-bottom: 5px;
}

.accordion-body p, .accordion-body li {
    text-align: justify;
    line-height: 1.6;
    color: var(--text-primary);
}

.accordion-body ul {
    margin-top: 0.5rem;
}

.accordion-body code {
    font-size: 0.875em;
    color: var(--accent-dark);
    word-wrap: break-word;
    background-color: var(--surface-alt);
    padding: 2px 4px;
    border-radius: 4px;
}

/* --- contact ----------------------------------------------------------- */
.contact-wrapper {
    max-width: 520px;
    margin: 2rem auto;
}

.contact-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}

.contact-header {
    background: var(--primary);
    padding: 1.75rem 2rem;
    text-align: center;
}

.contact-header .header-icon {
    width: 48px;
    height: 48px;
    background: rgba(255,255,255,0.15);
    border-radius: var(--radius);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 0.75rem;
    backdrop-filter: blur(8px);
}

.contact-header .header-icon i {
    font-size: 1.5rem;
    color: var(--text-inverse);
}

.contact-header h2 {
    color: var(--text-inverse);
    font-size: 1.375rem;
    font-weight: 700;
    margin: 0;
}

.contact-header p {
    color: rgba(255,255,255,0.8);
    font-size: 0.8125rem;
    margin: 0.5rem 0 0;
}

.contact-body {
    padding: 2rem;
}

.form-group {
    margin-bottom: 1.25rem;
}

.form-group:last-of-type {
    margin-bottom: 1.5rem;
}

.contact-body .form-control,
.contact-body .form-select {
    padding: 0.75rem 1rem;
    font-size: 0.9375rem;
}

.contact-body textarea.form-control {
    min-height: 120px;
    resize: vertical;
}

.btn-submit {
    width: 100%;
    padding: 0.75rem 1.5rem;
    font-size: 0.9375rem;
}

/* Info Cards */
.contact-info {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1rem;
    margin-top: 1.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--border);
}

.info-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem;
    background: var(--surface-alt);
    border-radius: var(--radius);
}

.info-item i {
    font-size: 1.125rem;
    color: var(--primary);
}

.info-item span {
    font-size: 0.8125rem;
    color: var(--text-secondary);
}

@media (max-width: 576px) {
    .contact-info {
        grid-template-columns: 1fr;
    }
}

/* --- create_study_step1 ------------------------------------------------ */
#biomarker_table tbody tr:hover {
    cursor: pointer;
}

/* --- index ------------------------------------------------------------- */
/* Override background for landing page */
body[data-page-name="index"] {
    background: var(--surface);
}

/* Hero Section */
.hero-section {
    background: var(--primary);
    border-radius: var(--radius-xl);
    padding: 3rem;
    margin-bottom: 2rem;
    box-shadow: var(--shadow-lg);
    position: relative;
    overflow: hidden;
}

.hero-section::before {
    content: '';
    position: absolute;
    top: -50%;
    right: -20%;
    width: 60%;
    height: 200%;
    background: rgba(255,255,255,0.03);
    transform: rotate(15deg);
    pointer-events: none;
}

.hero-section .hero-content {
    position: relative;
    z-index: 1;
}

.hero-section h1 {
    color: var(--text-inverse);
    font-size: 2rem;
    font-weight: 700;
    letter-spacing: -0.03em;
    line-height: 1.2;
    margin-bottom: 1rem;
}

.hero-section .lead {
    color: rgba(255,255,255,0.9);
    font-size: 1.0625rem;
    line-height: 1.7;
    margin-bottom: 0;
}

.hero-logo {
    background: rgba(255,255,255,0.1);
    backdrop-filter: blur(8px);
    border-radius: var(--radius-lg);
    padding: 1.5rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.hero-logo img {
    max-width: 200px;
    height: auto;
}

/* Description Card */
.description-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 1.75rem;
    margin-bottom: 2rem;
    box-shadow: var(--shadow);
}

.description-card p {
    color: var(--text-secondary);
    font-size: 0.9375rem;
    line-height: 1.8;
    margin: 0;
    text-align: justify;
}

/* Section Header */
.section-header {
    text-align: center;
    margin-bottom: 2rem;
}

.section-header h2 {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--accent);
    margin-bottom: 0.5rem;
}

.section-header h3 {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--text-primary);
    margin: 0;
}

/* Feature Cards */
.feature-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1.25rem;
    margin-bottom: 2rem;
}

@media (max-width: 992px) {
    .feature-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 576px) {
    .feature-grid {
        grid-template-columns: 1fr;
    }
}

.feature-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 1.5rem;
    display: flex;
    gap: 1rem;
    transition: var(--transition);
    box-shadow: var(--shadow-sm);
}

.feature-card:hover {
    box-shadow: var(--shadow);
    border-color: var(--primary);
    transform: translateY(-2px);
}

.feature-icon {
    flex-shrink: 0;
    width: 56px;
    height: 56px;
    border-radius: var(--radius);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

.feature-icon img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

/* The cards were built around a 56px image. Learn More uses Bootstrap icons
   instead, which need the tile drawn rather than supplied by the artwork. */
.feature-icon > i {
    font-size: 1.5rem;
    color: var(--primary);
}

.feature-card:has(> .feature-icon > i) .feature-icon {
    background: var(--primary-soft);
}

/* `.content-section p` justifies, and it matches these paragraphs at the same
   specificity while sitting later in the file, so the cards inherited it.
   Justified text in a 300px column opens rivers between the words. */
.feature-card .feature-content p {
    text-align: left;
    font-size: 0.8125rem;
    line-height: 1.6;
    margin: 0;
}

.feature-content h4 {
    font-size: 0.9375rem;
    font-weight: 700;
    color: var(--text-primary);
    margin-bottom: 0.375rem;
}

.feature-content p {
    font-size: 0.8125rem;
    color: var(--text-secondary);
    line-height: 1.6;
    margin: 0;
}

/* Divider */
.section-divider {
    height: 1px;
    background: var(--border);
    margin: 2rem 0;
}

/* CTA Section */
.cta-section {
    text-align: center;
    padding: 2rem;
    background: var(--surface-alt);
    border-radius: var(--radius-lg);
    border: 1px solid var(--border);
}

.cta-section .btn {
    padding: 0.75rem 2rem;
    font-size: 0.9375rem;
}

/* --- learn_more -------------------------------------------------------- */
/* Override background for content page */
body[data-page-name="learn_more"] {
    background: var(--surface);
}

/* Content Container */
.content-wrapper {
    max-width: 1100px;
    margin: 0 auto;
}

/* Section Styling */
.content-section {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 2.5rem;
    margin-bottom: 1.5rem;
    box-shadow: var(--shadow);
}

.content-section h3 {
    color: var(--primary);
    font-size: 1.375rem;
    font-weight: 700;
    margin-bottom: 1.25rem;
    text-align: center;
    position: relative;
    padding-bottom: 1rem;
}

.content-section h3::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 60px;
    height: 3px;
    background: var(--accent);
    border-radius: 2px;
}

.content-section p {
    font-size: 0.9375rem;
    color: var(--text-secondary);
    line-height: 1.8;
    margin-bottom: 1rem;
    text-align: justify;
}

.content-section ul {
    margin: 1rem 0 1.5rem;
    padding-left: 0;
    list-style: none;
}

.content-section li {
    position: relative;
    padding-left: 1.75rem;
    margin-bottom: 0.875rem;
    font-size: 0.9375rem;
    color: var(--text-secondary);
    line-height: 1.7;
}

.content-section li::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0.5rem;
    width: 8px;
    height: 8px;
    background: rgb(42, 21, 161);
    border-radius: 50%;
}

.content-section li strong {
    color: var(--text-primary);
}

.content-section li em {
    color: var(--primary);
    font-style: normal;
    font-weight: 600;
}

/* Workflow Image */
.workflow-section {
    text-align: center;
    padding: 2rem;
    background: var(--surface-alt);
    border-radius: var(--radius-lg);
    border: 1px solid var(--border);
    margin-bottom: 1.5rem;
}

.workflow-section img {
    max-width: 100%;
    height: auto;
    border-radius: var(--radius);
    box-shadow: var(--shadow-lg);
}

/* Comparison Table */
.comparison-table-wrapper {
    overflow-x: auto;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    margin-top: 1.5rem;
}

.comparison-table {
    width: 100%;
    margin: 0;
    border-collapse: collapse;
}

.comparison-table thead th {
    background: var(--primary);
    color: var(--text-inverse);
    font-size: 0.8125rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding: 1rem 1.25rem;
    border: none;
    text-align: left;
}

.comparison-table thead th:first-child {
    width: 25%;
}

.comparison-table tbody td {
    padding: 1rem 1.25rem;
    font-size: 0.875rem;
    color: var(--text-secondary);
    border-bottom: 1px solid var(--border);
    vertical-align: top;
    line-height: 1.6;
}

.comparison-table tbody tr:nth-child(even) {
    background: var(--surface-alt);
}

.comparison-table tbody tr:hover {
    background: var(--surface-hover);
}

.comparison-table tbody td:first-child {
    font-weight: 600;
    color: var(--text-primary);
}

.comparison-table tbody td:last-child {

    font-weight: 500;
}

/* CTA Section */
.cta-card {
    background: var(--primary);
    border-radius: var(--radius-lg);
    padding: 2.5rem;
    text-align: center;
    box-shadow: var(--shadow-lg);
}

.cta-card h4 {
    color: var(--text-inverse);
    font-size: 1.25rem;
    font-weight: 700;
    margin-bottom: 0.75rem;
}

.cta-card p {
    color: rgba(255, 255, 255, 0.85);
    font-size: 0.9375rem;
    margin-bottom: 1.5rem;
}

.cta-card .btn {
    background: var(--text-inverse);
    color: var(--primary);
    padding: 0.75rem 2rem;
    font-weight: 600;
}

.cta-card .btn:hover {
    background: var(--surface-alt);
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}



.auth-wrapper {
    max-width: 440px;
    margin: 3rem auto;
}

.auth-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}

.auth-header {
    background: var(--primary);
    padding: 2rem;
    text-align: center;
}

.auth-header .header-icon {
    width: 56px;
    height: 56px;
    background: rgba(255,255,255,0.15);
    border-radius: var(--radius-lg);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 1rem;
    backdrop-filter: blur(8px);
}

.auth-header .header-icon i {
    font-size: 1.75rem;
    color: var(--text-inverse);
}

.auth-header h2 {
    color: var(--text-inverse);
    font-size: 1.375rem;
    font-weight: 700;
    margin: 0;
}

.auth-header p {
    color: rgba(255,255,255,0.8);
    font-size: 0.8125rem;
    margin: 0.5rem 0 0;
}

.auth-body {
    padding: 2rem;
}

.form-group {
    margin-bottom: 1.25rem;
}

.form-group:last-of-type {
    margin-bottom: 1.75rem;
}

.auth-body .form-control {
    padding: 0.75rem 1rem;
    font-size: 0.9375rem;
}

.btn-auth {
    width: 100%;
    padding: 0.75rem 1.5rem;
    font-size: 0.9375rem;
}

.auth-footer {
    text-align: center;
    padding-top: 1.5rem;
    border-top: 1px solid var(--border);
    margin-top: 1.5rem;
}

.auth-footer p {
    margin: 0;
    font-size: 0.875rem;
    color: var(--text-secondary);
}

.auth-footer a {
    color: var(--primary);
    font-weight: 600;
    text-decoration: none;
    transition: var(--transition-fast);
}

.auth-footer a:hover {
    color: var(--primary-light);
    text-decoration: underline;
}

/* Password visibility toggle */
.password-wrapper {
    position: relative;
}

.password-toggle {
    position: absolute;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.password-toggle:hover {
    color: var(--text-secondary);
}

.password-wrapper .form-control {
    padding-right: 2.5rem;
}

/* --- manage_participants ----------------------------------------------- */
.btn-group {
    white-space: nowrap;
}

/* --- manage_subjects --------------------------------------------------- */
.btn-group {
    white-space: normal;
    display: flex;
    flex-wrap: wrap;
}

#subjectHistoryModal .table {
    font-size: 0.85rem;
}

#subjectHistoryModal .form-control,
#subjectHistoryModal .form-select {
    font-size: 0.85rem;
    padding: 0.25rem 0.5rem;
}

.history-datatable_wrapper .dataTables_length,
.history-datatable_wrapper .dataTables_filter,
.history-datatable_wrapper .dataTables_info,
.history-datatable_wrapper .dataTables_paginate {
    display: none !important;
}

#subjectHistoryModal .table {
    width: 100% !important;
}

#subjectHistoryModal .dataTables_wrapper {
    width: 100%;
}

.toast-container {
    z-index: 1090;
}

/* --- register ---------------------------------------------------------- */
.auth-wrapper {
    max-width: 480px;
    margin: 2rem auto;
}

.auth-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}

.auth-header {
    background: var(--primary);
    padding: 2rem;
    text-align: center;
}

.auth-header .header-icon {
    width: 56px;
    height: 56px;
    background: rgba(255,255,255,0.15);
    border-radius: var(--radius-lg);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 1rem;
    backdrop-filter: blur(8px);
}

.auth-header .header-icon i {
    font-size: 1.75rem;
    color: var(--text-inverse);
}

.auth-header h2 {
    color: var(--text-inverse);
    font-size: 1.375rem;
    font-weight: 700;
    margin: 0;
}

.auth-header p {
    color: rgba(255,255,255,0.8);
    font-size: 0.8125rem;
    margin: 0.5rem 0 0;
}

.auth-body {
    padding: 2rem;
}

.form-group {
    margin-bottom: 1.25rem;
}

.form-group:last-of-type {
    margin-bottom: 1.75rem;
}

.auth-body .form-control {
    padding: 0.75rem 1rem;
    font-size: 0.9375rem;
}

.btn-auth {
    width: 100%;
    padding: 0.75rem 1.5rem;
    font-size: 0.9375rem;
}

.auth-footer {
    text-align: center;
    padding-top: 1.5rem;
    border-top: 1px solid var(--border);
    margin-top: 1.5rem;
}

.auth-footer p {
    margin: 0;
    font-size: 0.875rem;
    color: var(--text-secondary);
}

.auth-footer a {
    color: var(--primary);
    font-weight: 600;
    text-decoration: none;
    transition: var(--transition-fast);
}

.auth-footer a:hover {
    color: var(--primary-light);
    text-decoration: underline;
}

/* Password wrapper */
.password-wrapper {
    position: relative;
}

.password-toggle {
    position: absolute;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

.password-toggle:hover {
    color: var(--text-secondary);
}

.password-wrapper .form-control {
    padding-right: 2.5rem;
}

/* Helper text */
.form-helper {
    font-size: 0.75rem;
    color: var(--text-muted);
    margin-top: 0.375rem;
    font-style: italic;
}

/* Password strength indicator */
.password-requirements {
    background: var(--surface-alt);
    border-radius: var(--radius);
    padding: 0.75rem 1rem;
    margin-top: 0.75rem;
}

.password-requirements p {
    font-size: 0.75rem;
    color: var(--text-secondary);
    margin: 0 0 0.5rem;
    font-weight: 600;
}

.password-requirements ul {
    margin: 0;
    padding-left: 1.25rem;
    font-size: 0.75rem;
    color: var(--text-muted);
}

.password-requirements li {
    margin-bottom: 0.25rem;
}

/* --- study_dashboard --------------------------------------------------- */
.kpi-card {
    background-color: var(--surface-alt);
    border: 1px solid var(--border);
    border-radius: .25rem;
    padding: 1rem;
    text-align: center;
    margin-bottom: 1rem;
}

.kpi-value {
    font-size: 1.75rem;
    font-weight: bold;
    color: var(--primary);
}

.kpi-label {
    font-size: 0.9rem;
    color: var(--text-muted);
}

/* "Remaining Budget: $37,500.00" gave a number with no denominator. */
.kpi-context {
    font-size: 0.8125rem;
    color: var(--text-muted);
    margin-top: 0.15rem;
}

.no-data-msg {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 350px;
    color: var(--text-muted);
    font-style: italic;
}

.bk-root {
    min-height: 350px;
}

div[data-root-id] .bk-root {
    min-height: 250px;
}

.event-card-header {
    font-size: 0.9rem;
    font-weight: bold;
    color: var(--primary);
    margin-top: 1rem;
    margin-bottom: 0.5rem;
    border-bottom: 1px solid var(--border-light);
    padding-bottom: 4px;
}

.event-table {
    font-size: 0.8rem;
}

.event-table th {
    font-weight: 600;
    color: var(--text-primary);
}

.event-table td {
    color: var(--text-secondary);
}

/* --- study_recordings -------------------------------------------------- */
#calendar {
    max-width: 80%;
    margin: 0 auto;
    height: 60%;
}

#calendarModal .modal-dialog {
    max-height: 90vh;
    height: auto;
}

#calendarModal .modal-body {
    padding: 0;
    max-height: 60%;
    overflow: hidden;
}

.dt-buttons {
    margin-bottom: 0.5rem;
}

/* The Bootstrap 5 integration puts .btn-group on the export button container,
   and .btn-group > .btn is flex: 1 1 auto, so two buttons split the full row
   width between them. An inline-flex container sizes to its content instead. */
.dt-buttons.btn-group {
    display: inline-flex;
    width: auto;
}

#dateRecordingsModal {
    z-index: 1060;
}

#exportPacketModal {
    z-index: 1060;
}

#confirmDeleteModal {
    z-index: 1060;
}

#importTemplateModal {
    z-index: 1060;
}

/* Only a *stacked* backdrop is raised above the modal beneath it. `:nth-of-type`
   counted every div in <body>, so the single backdrop of an ordinary modal was
   the second one and got raised over its own dialog. */
.modal-backdrop.show ~ .modal-backdrop.show {
    z-index: 1055;
}

/* DataTables' length/search controls are laid out with a Bootstrap .row, and a
   .row carries negative left and right margins. Its parent .dataTables_wrapper
   is the element precision.css makes `overflow-x: auto`, so that row sits
   1.5rem wider than the box that scrolls it — a horizontal scrollbar at every
   viewport width, on tables whose content fitted perfectly well.

   Zeroing the gutter removes the cause. `overflow-x: hidden` on the wrapper
   would hide it, but it would also clip a table that is genuinely too wide,
   which is the case the wrapper's scrolling exists to handle. */
.dataTables_wrapper > .row {
    --bs-gutter-x: 0;
    margin-left: 0;
    margin-right: 0;
}

/* Every table header in the application is navy, which is what the recordings
   table already did and what the comparison table on the landing page has
   always done. Subjects and Participants took the light default from
   precision.css, Documents and the redcap tables carried Bootstrap's
   .table-light, and the same kind of data looked like three different products
   depending on which tab you were on. The tokens are the ones
   .comparison-table uses, so there is one navy, not two.

   !important because Bootstrap applies .table-light through
   `.table > :not(caption) > * > *` and DataTables ships its own thead rule from
   a CDN sheet; the markup classes are gone but page-level CSS still competes. */
.table thead th,
table.dataTable thead th {
    background-color: var(--primary) !important;
    color: var(--text-inverse) !important;
    border-bottom-color: var(--primary) !important;
}

/* The sort chevrons are drawn by DataTables as pseudo-element glyphs that
   inherit colour from the cell. Without this they stayed dark on navy. */
table.dataTable thead th.sorting::before,
table.dataTable thead th.sorting::after,
table.dataTable thead th.sorting_asc::before,
table.dataTable thead th.sorting_asc::after,
table.dataTable thead th.sorting_desc::before,
table.dataTable thead th.sorting_desc::after {
    color: var(--text-inverse);
}

.table tbody tr:hover {
    background-color: var(--surface-hover);
}

.search-wrapper {
    position: relative;
}

.search-results {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 1061;
    /* Higher than modal */
    border: 1px solid var(--border);
    background: white;
    max-height: 200px;
    overflow-y: auto;
}

.search-results .list-group-item {
    cursor: pointer;
}

.search-results .list-group-item:hover {
    background-color: var(--surface-hover);
}

/* --- study_dashboard --------------------------------------------------- */

/* Every plot panel is the same height. Three of the Bokeh figures are a fixed
   350px, but the recording heatmap is sized from the subject count and the
   biomarker chart from the number of categories, so the six panels rendered at
   six different heights and the grid looked broken.

   The panel is fixed and the two content-driven plots scroll inside it. The
   alternative — forcing those figures to 350px — would compress fifty subjects
   into a band a few pixels tall, which trades one visual problem for a
   legibility one. */
.dashboard-panel {
    height: 460px;
}

.dashboard-panel > .card-body {
    overflow: auto;
}

/* --- view_audit_log ---------------------------------------------------- */
#auditLogTable thead th {
    cursor: pointer;
}

/* --- finances ---------------------------------------------------------- */

/* The track used to be literal green with a bg-danger fill, so a study that
   had spent a quarter of its budget was drawn as three quarters "good" and a
   quarter "error". Spending budget is what budget is for: the fill is a plain
   series colour, and only crossing 90% warrants the danger tone. */
.budget-progress {
    height: 25px;
    background-color: var(--surface-hover);
}

.budget-progress .progress-bar {
    background-color: var(--series-1);
}

.budget-progress .budget-progress-bar-over {
    background-color: var(--danger);
}
