:root {
    --defaultBgColor: #f0f4f8;
    --defaultTextColor: #333333;
    --defaultTextColorDisabled: #33333355;
    --defaultLinkColor: #0066cc;
    --defaultLinkHoverColor: #004499;
    --errorColor: red;
    --defaultBorderColor: #333333;
    --defaultBorderColorDisabled: #33333355;
}

html {
  font-size: 14px;
}

@media (min-width: 768px) {
  html {
    font-size: 16px;
  }
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

html {
  position: relative;
  min-height: 100%;
}

body {
    color: var(--defaultTextColor);
    background-color: var(--defaultBgColor);
    padding: 0;
    margin: 0;
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
  color: var(--bs-secondary-color);
  text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
  text-align: start;
}

/*************
 *
 * Main react app styles
 *
 */
#reactApp {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

.flexCenter {
    display: flex;
    flex-direction: row;
    justify-content: center;
}

.pageHeader {
    margin-bottom: 2rem;
}

/* Keeps the footer at the bottom of the window on short pages, and 8rem below the content on long ones */
.pageLayout {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    /* Mobile browsers: the height of the visible area, excluding the address bar */
    min-height: 100dvh;
}

.pageBody {
    flex: 1 0 auto;
}

.pageFooter {
    flex-shrink: 0;
    margin-top: 8rem;
    margin-bottom: 2rem;
}

.linkButton {
    background: transparent;
    border: none;
    padding: 0;
    color: var(--defaultLinkColor);
    cursor: pointer;
    font: inherit;
}

    .linkButton:hover {
        color: var(--defaultLinkHoverColor);
        text-decoration: underline;
    }

.formActions {
    margin-top: 2rem;
}

.spinner {
    display: inline-block;
    width: 16px;
    height: 16px;
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-radius: 50%;
    border-top-color: #fff;
    animation: spin 1s ease-in-out infinite;
    margin-right: 8px;
    vertical-align: middle;
}

@keyframes spin {
    to {
        transform: rotate(360deg);
    }
}

/*************
 *
 * Enter credentials specific classes
 *
 */

.loginFormField {
    width: 20rem;
}

.loginErrMessage {
    color: red;
}

#loginForgotPassword {
    margin-left: 3rem;
}

.requestPasswordResetMessage {
    font-size: larger;
    font-weight: bold;
    margin-bottom: 1rem;
}

.passwordMismatch {
    margin-left: 1rem;
    font-size: smaller;
    color: red;
}

/*************
 *
 *
 *
 */
.mainPageContainer {
    display: flex;
    flex-direction: row;
}

.menu {
    list-style: none;
    min-width: 15rem;
    border-right: 1px solid black;
    margin-right: 2rem;
}

.menuItem {
    margin-bottom: 1rem;
}

    .menuItem:hover {
        background-color: lightblue;
    }

    .menuItem > button {
        background: transparent;
        border: none;
        padding: 0;
        color: var(--defaultLinkColor);
        cursor: pointer;
        font: inherit;
    }

.selectedMenuItem > button {
    font-weight: bold;
    text-decoration: underline;
}

/*************
 *
 *
 *
 */

.manSub-subscriberBlock {
    display: flex;
    flex-direction: column;
    margin-bottom: 1rem;
}
    .manSub-subscriberBlock:hover {
        background-color: lightblue;
    }

.manSub-actions {
    display: flex;
    gap: 0.75rem;
}

    .manSub-actions svg {
        cursor: pointer;
    }

.manSub-addUserButton {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
    margin-bottom: 2.5rem;
}

.manSub-search {
    width: 18rem;
    max-width: 100%;
}

.manSub-searchCount {
    margin-top: 0;
}

.manSub-noMatches {
    font-style: italic;
    color: dimgray;
}

.manSub-matchNote {
    font-size: smaller;
    color: dimgray;
}

.manSub-subscriberList {
    list-style: none;
}

.manSub-isActiveContainer {

}
.manSub-activeSubscriber {

}

.manSub-inactiveSubscriber {
    color: dimgray;
}

.manSub-primaryInfo {
    display: flex;
    flex-direction: row;
}

.manSub-displayNameContainer {
    display: flex;
    flex-direction: row;
    font-weight: bold;
}

.manSub-displayName {
}

.manSub-displayNameBadge {
    margin-left: 0.5rem;
}

.manSub-contactEmail {

}

.manSub-contactPhoneContainer {
    display: flex;
    flex-direction: row;
}

.manSub-contactPhone {
}

.manSub-contactPhoneBadge {
    margin-left: 0.25rem;
}

.manSub-secondaryInfo {
    margin-left: 3rem;
}

.manSub-notes {
    font-style: italic;
    font-size: smaller;
    /* Notes are typed in a multi-line box; keep their line breaks */
    white-space: pre-line;
}

/*************
 * Manage Instruments panel
 */

.manInst-addInstrumentButton {
    display: flex;
    align-items: center;
    margin-bottom: 2.5rem;
}

.manInst-instrumentList {
    list-style: none;
}

.manInst-instrumentBlock {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 1.5rem;
    margin-bottom: 0.5rem;
}
    .manInst-instrumentBlock:hover {
        background-color: lightblue;
    }

.manInst-symbol {
    font-weight: bold;
    min-width: 8rem;
}

.manInst-actions {
    display: flex;
    gap: 0.75rem;
}

    .manInst-actions svg {
        cursor: pointer;
    }

.manInst-emptyMessage {
    font-style: italic;
    color: dimgray;
}

/* A panel's extra note in the unsaved-changes dialog */
.mainPage-guardNote {
    margin-top: 0.75rem;
    padding: 0.5rem 0.75rem;
    border-left: 3px solid var(--bs-warning-border-subtle);
    background-color: var(--bs-warning-bg-subtle);
}

/*************
 * User Profile panel
 */

.userProf-panel {
    max-width: 36rem;
}

.userProf-section {
    margin-bottom: 3rem;
}

.userProf-sectionTitle {
    font-size: 1.5rem;
    margin-bottom: 1rem;
}

.userProf-subheading {
    font-size: 1.1rem;
    font-weight: bold;
    margin: 1.5rem 0 0.75rem;
}

.userProf-readOnlyValue {
    font-weight: bold;
}

.userProf-note {
    font-size: smaller;
    color: dimgray;
}

.userProf-formActions {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

/* Where an alert stands (e.g. "Waiting for you to confirm"), under its switch */
.userProf-alertStatus {
    font-size: smaller;
    color: dimgray;
    margin: -0.25rem 0 0.75rem 2.5rem;
}

.userProf-alertConfirmed {
    color: var(--bs-success-text-emphasis);
}

.userProf-alertAction {
    padding: 0 0 0 0.5rem;
    vertical-align: baseline;
    font-size: inherit;
}

/*************
 * Alert confirmation popup
 */

.alertConf-section + .alertConf-section {
    margin-top: 1.5rem;
    padding-top: 1rem;
    border-top: 1px solid var(--bs-border-color);
}

.alertConf-heading {
    font-size: 1.1rem;
    font-weight: bold;
}

.alertConf-codeRow {
    display: flex;
    gap: 0.5rem;
}

.alertConf-code {
    max-width: 9rem;
    letter-spacing: 0.15em;
}

.alertConf-resend {
    padding-left: 0;
}

/*************
 * Site Settings panel
 */

.siteSet-panel {
    max-width: 36rem;
}

.siteSet-intro {
    color: dimgray;
    margin-bottom: 1.5rem;
}

.siteSet-sectionTitle {
    font-size: 1.5rem;
    margin: 2rem 0 1rem;
}

.siteSet-subheading {
    font-size: 1.1rem;
    font-weight: bold;
    margin: 1.5rem 0 0.25rem;
}

.siteSet-bodyLabelRow {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
}

.siteSet-startFromDefault {
    padding: 0;
}

.siteSet-bodyEditor {
    font-family: var(--bs-font-monospace);
    font-size: 0.85rem;
}

.siteSet-lifetime {
    max-width: 18rem;
}

.siteSet-formActions {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

.siteSet-secretStatus {
    margin-top: 0;
    margin-bottom: 0.25rem;
}

/*************
 * Locked Subscribers panel
 */

.lockSub-panel {
    max-width: 60rem;
}

.lockSub-toolbar {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1rem;
}

.lockSub-sectionTitle {
    font-size: 1.5rem;
    margin: 1.5rem 0 0.5rem;
}

.lockSub-empty {
    font-style: italic;
    color: dimgray;
}

.lockSub-countdown {
    font-family: var(--bs-font-monospace);
    font-weight: bold;
}

.lockSub-ipSource {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.lockSub-ipBlock {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}

.lockSub-inlineButton {
    padding: 0;
}

.lockSub-actions {
    white-space: nowrap;
}

    .lockSub-actions .btn + .btn {
        margin-left: 0.5rem;
    }

.lockSub-notSubscriber {
    font-style: italic;
    color: dimgray;
}

.requiredField {
    margin-left: 0.5rem;
    color: red;
    font-size: smaller;
}

/*************
 * Site Logs panel
 *************/
.siteLogs-panel {
    max-width: 90rem;
}

.siteLogs-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1rem;
}

.siteLogs-summary {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

.siteLogs-summaryTitle {
    font-weight: bold;
    margin-right: 0.25rem;
}

.siteLogs-summaryItem {
    display: inline-flex;
    align-items: baseline;
    gap: 0.4rem;
    padding: 0.25rem 0.75rem;
    border: 1px solid #ced4da;
    border-radius: 1rem;
    background-color: #f8f9fa;
    color: dimgray;
}

    .siteLogs-summaryItem:hover {
        border-color: #6c757d;
    }

.siteLogs-summaryItemWarning {
    border-color: #ffc107;
    background-color: #fff3cd;
    color: #664d03;
}

.siteLogs-summaryItemError {
    border-color: #dc3545;
    background-color: #f8d7da;
    color: #842029;
}

.siteLogs-summaryCount {
    font-weight: bold;
    font-size: 1.1rem;
}

.siteLogs-filters {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
    gap: 0.5rem 1rem;
    align-items: end;
    margin-bottom: 1rem;
}

    .siteLogs-filters .form-label {
        margin-bottom: 0.1rem;
        font-size: smaller;
    }

.siteLogs-empty {
    font-style: italic;
    color: dimgray;
}

.siteLogs-table {
    font-size: 0.9rem;
}

.siteLogs-reloading {
    opacity: 0.6;
}

.siteLogs-row {
    cursor: pointer;
}

.siteLogs-rowExpanded > td {
    background-color: #e7f1ff;
}

.siteLogs-time {
    white-space: nowrap;
}

.siteLogs-message {
    max-width: 40rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.siteLogs-muted {
    color: dimgray;
}

.siteLogs-filterLink {
    padding: 0;
    font-size: inherit;
    text-align: left;
    word-break: break-all;
}

.siteLogs-detailRow > td {
    background-color: #f8f9fa;
}

.siteLogs-detailBody {
    padding: 0.5rem;
}

.siteLogs-fullMessage {
    white-space: pre-wrap;
    word-break: break-word;
    font-weight: bold;
    margin-bottom: 0.75rem;
}

.siteLogs-detailList {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 0.2rem 1rem;
    margin-bottom: 0.75rem;
}

    .siteLogs-detailList dt {
        font-weight: normal;
        color: dimgray;
    }

    .siteLogs-detailList dd {
        margin: 0;
        word-break: break-word;
    }

.siteLogs-properties {
    width: auto;
    max-width: 100%;
}

    .siteLogs-properties td {
        word-break: break-word;
    }

.siteLogs-exception {
    max-height: 20rem;
    overflow: auto;
    padding: 0.5rem;
    background-color: #fff;
    border: 1px solid #dee2e6;
    font-size: 0.8rem;
}

/*************
 * Dashboard panel
 *************/
.dash-panel {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(22rem, 1fr));
    gap: 1.5rem;
    align-items: start;
    max-width: 90rem;
}

.dash-widget {
    border: 1px solid #ced4da;
    border-radius: 0.5rem;
    padding: 1rem 1.25rem;
    background-color: #fff;
}

.dash-widgetTitle {
    font-size: 1.15rem;
    font-weight: bold;
    margin: 0 0 0.75rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid #e9ecef;
}

.dash-details {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 0.35rem 1rem;
    margin: 0;
}

    .dash-details dt {
        font-weight: normal;
        color: dimgray;
    }

    .dash-details dd {
        margin: 0;
        word-break: break-word;
    }

/* The Alerts widget's last audit summary and its Run Audit Now button */
.dash-auditSummary {
    margin: 0.25rem 0 0;
}

.dash-auditFailed {
    color: var(--bs-danger-text-emphasis);
}

.dash-actions {
    margin-top: 0.75rem;
}

.dash-muted {
    color: dimgray;
}

/*************
 *
 * Indicator panel (the live chart)
 *
 */

/* The chart uses all the room beside the menu (other panels keep their own width) */
.mainPagePanel:has(> .chart-panel) {
    flex: 1 1 auto;
    min-width: 0;
}

.chart-toolbar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 0 2rem;
}

.chart-symbolSelect {
    width: auto;
    min-width: 10rem;
}

/* The chart fills this box and follows its size */
.chart-canvasBox {
    position: relative;
    margin: 2rem;
    height: 75vh;
    min-height: 24rem;
    background-color: #000;
}

    .chart-canvasBox > .chart-host {
        position: absolute;
        inset: 0;
    }

/* Above the chart: the data isn't real, so it mustn't be traded on */
/* Alerts that triggered while the chart was open, until dismissed */
.chart-alerts {
    margin: 1rem 2rem 0;
}

.chart-alertsTitle {
    font-weight: bold;
}

.chart-alertList {
    margin: 0.25rem 0 0;
    padding-left: 1.25rem;
}

/* The newest alert's toast, above the chart */
.chart-toastContainer {
    z-index: 1060;
    padding: 1rem;
}

.chart-sampleBanner {
    margin: 1rem 2rem 0;
    padding: 0.75rem 1rem;
    border: 3px solid #c00;
    color: #c00;
    font-size: 1.75rem;
    font-weight: bold;
    text-align: center;
}

/* Above the chart, under the sample data banner */
.chart-disclaimer {
    margin: 1rem 2rem 0;
    font-size: 0.85rem;
    color: dimgray;
}

    .chart-disclaimer > p {
        margin-bottom: 0.5rem;
    }

        .chart-disclaimer > p:last-child {
            margin-bottom: 0;
        }

/* Across the middle of the chart, faint enough to read the bars through and ignoring the mouse so
   the crosshair and scrolling still work. Under the status line and legend, which must stay readable. */
.chart-sampleWatermark {
    position: absolute;
    z-index: 2;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    color: rgba(255, 0, 0, 0.35);
    font-size: clamp(3rem, 9vw, 9rem);
    font-weight: bold;
    white-space: nowrap;
    transform: rotate(-30deg);
    pointer-events: none;
    user-select: none;
}

/* Over the chart, in the top-left corner of the price pane */
.chart-status {
    position: absolute;
    z-index: 3;
    top: 0.5rem;
    left: 0.75rem;
    color: #8c8c8c;
    font-size: 0.85rem;
    pointer-events: none;
}

/* Under the status line: the values of the bar under the crosshair, or of the latest bar */
.chart-legend {
    position: absolute;
    z-index: 3;
    top: 1.9rem;
    left: 0.75rem;
    padding: 0.15rem 0.4rem;
    background-color: rgba(0, 0, 0, 0.6);
    color: #c8c8c8;
    font-size: 0.8rem;
    line-height: 1.35;
    font-variant-numeric: tabular-nums;
    white-space: pre;
    pointer-events: none;
}

.chart-message {
    margin: 2rem;
    color: dimgray;
}

/* The TradingView notice required by the chart library's licence, under the chart's lower-right corner */
.chart-attribution {
    margin: -1.5rem 2rem 2rem;
    text-align: right;
    font-size: 0.75rem;
    color: dimgray;
}
