/* App-level layer on top of the Classical design system (classical/styles.css).
   Every color, font, spacing and radius comes from the Classical tokens; the
   only additions are the two status roles below, which the mono palette
   deliberately does not carry, and two in-between spacing steps derived from
   the Classical unit. */

:root {
    /* Status roles for job outcomes - muted, ink-like, in keeping with the
       stroke-not-fill direction. Used as text/border colors with color-mix
       tints for backgrounds, never as solid fills. */
    --app-danger: #8c2f2f;
    --app-success: #3d6b45;

    /* The Classical scale ships --space-1/2/3/4/6/8 only. Several components
       reach for the 5 and 7 steps; without a definition those var()s make the
       whole margin/padding/gap declaration invalid at computed-value time and
       the spacing silently collapses to 0. Derive them from --space-1 so they
       track the unit if the tokens are re-synced (classical/styles.css is
       DesignSync-managed and must not be hand-edited). */
    --space-5: calc(var(--space-1) * 5);
    --space-7: calc(var(--space-1) * 7);
}

a, .btn-link {
    color: var(--color-accent);
}

/* Bootstrap is still loaded, and its button state rules outrank Classical's
   single-class variants: .btn:hover, .btn:focus-visible and .btn:disabled
   (0,2,0), and .btn:first-child:active / :not(.btn-check) + .btn:active
   (0,3,0). They paint color, background and border from Bootstrap's
   --bs-btn-* properties, so a hovered primary got white text and a blue
   border, a pressed or keyboard-focused one a solid blue fill, and a ghost -
   which Bootstrap has no variant for - fell back to the inherited text color
   with a currentcolor border. Rather than out-rank every state selector, feed
   those properties the Classical ink, so every state stays a stroke. The
   values restate the variant rules in classical/styles.css.

   Bootstrap's :focus-visible also takes the hover colors, so a focused button
   shows the hover tint under the ring.

   A page that puts its own role on a variant (the danger-colored ghosts) feeds
   the same properties from its own single class; page style blocks come later
   in the cascade, so those win over these. */
.btn {
    --bs-btn-focus-box-shadow: none;
}

/* Bootstrap's .btn:focus-visible sets outline: 0 over the system's ring. */
.btn:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

.btn-primary {
    --bs-btn-hover-color: var(--color-accent);
    --bs-btn-hover-bg: color-mix(in srgb, var(--color-accent) 12%, transparent);
    --bs-btn-hover-border-color: var(--color-accent);
    --bs-btn-active-color: var(--color-accent);
    --bs-btn-active-bg: color-mix(in srgb, var(--color-accent) 22%, transparent);
    --bs-btn-active-border-color: var(--color-accent);
    --bs-btn-disabled-color: var(--color-accent);
    --bs-btn-disabled-bg: transparent;
    --bs-btn-disabled-border-color: var(--color-accent);
}

.btn-secondary {
    --bs-btn-hover-color: var(--color-text);
    --bs-btn-hover-bg: color-mix(in srgb, var(--color-text) 7%, transparent);
    --bs-btn-hover-border-color: var(--color-divider);
    --bs-btn-active-color: var(--color-text);
    --bs-btn-active-bg: color-mix(in srgb, var(--color-text) 14%, transparent);
    --bs-btn-active-border-color: var(--color-divider);
    --bs-btn-disabled-color: var(--color-text);
    --bs-btn-disabled-bg: transparent;
    --bs-btn-disabled-border-color: var(--color-divider);
}

.btn-ghost {
    --bs-btn-hover-color: var(--color-accent);
    --bs-btn-hover-bg: color-mix(in srgb, var(--color-accent) 10%, transparent);
    --bs-btn-hover-border-color: transparent;
    --bs-btn-active-color: var(--color-accent);
    --bs-btn-active-bg: color-mix(in srgb, var(--color-accent) 18%, transparent);
    --bs-btn-active-border-color: transparent;
    --bs-btn-disabled-color: var(--color-accent);
    --bs-btn-disabled-bg: transparent;
    --bs-btn-disabled-border-color: transparent;
}

.content {
    padding-top: var(--space-4);
}

/* Long marketing and help copy starts with the short answer. Native details
   keeps the deeper proof one click away without requiring JavaScript. */
.progressive-details {
    margin-top: var(--space-3);
    border: 1px solid var(--color-divider);
    border-radius: var(--radius-md);
    background: color-mix(in srgb, var(--color-surface) 88%, var(--color-bg));
}

.progressive-details > summary {
    padding: var(--space-3) var(--space-4);
    color: var(--color-accent-700);
    font-weight: 600;
    cursor: pointer;
}

.progressive-details > summary:hover {
    color: var(--color-accent-800);
}

.progressive-details > summary:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

.progressive-details[open] > summary {
    border-bottom: 1px solid var(--color-divider);
}

.progressive-details > :not(summary) {
    margin-left: var(--space-4);
    margin-right: var(--space-4);
}

.progressive-details > :last-child {
    margin-bottom: var(--space-4);
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--color-accent-400);
}

.invalid {
    outline: 1px solid var(--app-danger);
}

.validation-message {
    color: var(--app-danger);
    font-size: 13px;
}

.blazor-error-boundary {
    border: 1px solid var(--app-danger);
    border-left-width: 4px;
    border-radius: var(--radius-md);
    background: color-mix(in srgb, var(--app-danger) 7%, var(--color-bg));
    color: var(--color-text);
    padding: var(--space-3) var(--space-4);
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

/* Bootstrap form-floating placeholders (Account template pages still use them) */
.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: color-mix(in srgb, var(--color-text) 45%, transparent);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* The running-upload strip (resumableUpload.js). Fixed to the bottom of the
   viewport because the upload outlives the page that started it: the family
   moves around the app, or sits on a page whose circuit died while they were
   filming, and this is still where the truth about the upload is. Empty on
   every page until an upload puts a row in it. */
#rt-upload-strip {
    position: fixed;
    left: var(--space-3);
    right: var(--space-3);
    bottom: calc(var(--space-3) + env(safe-area-inset-bottom, 0px));
    z-index: 1080;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    max-width: 34rem;
    max-height: min(60vh, 30rem);
    margin: 0 auto;
    overflow-y: auto;
    overscroll-behavior: contain;
}

#rt-upload-strip:empty {
    display: none;
}

.rt-upload-row {
    position: relative;
    display: grid;
    grid-template-columns: 1fr auto;
    gap: var(--space-1) var(--space-2);
    padding: var(--space-3) var(--space-3) 0;
    background: var(--color-bg);
    border: 1px solid var(--color-divider);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    overflow: hidden;
    flex: none;
}

.rt-upload-text {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.rt-upload-title {
    font-size: 14px;
    color: var(--color-text);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rt-upload-title:hover {
    text-decoration: underline;
}

.rt-upload-note {
    font-size: 12.5px;
    line-height: 1.35;
    color: color-mix(in srgb, var(--color-text) 60%, transparent);
    font-variant-numeric: tabular-nums;
}

.rt-upload-dismiss {
    align-self: start;
    border: 0;
    background: transparent;
    color: color-mix(in srgb, var(--color-text) 55%, transparent);
    font-size: 18px;
    line-height: 1;
    padding: 0 2px;
    cursor: pointer;
}

/* The dismiss control means nothing while an upload is running - hiding the
   message never stops it - so it only appears once the row has an outcome. */
.rt-upload-row:not(.rt-upload-done):not(.rt-upload-problem) .rt-upload-dismiss {
    visibility: hidden;
}

.rt-upload-track {
    grid-column: 1 / -1;
    height: 3px;
    margin: var(--space-2) calc(var(--space-3) * -1) 0;
    background: var(--color-neutral-200);
}

.rt-upload-fill {
    height: 100%;
    width: 0;
    background: var(--color-accent);
    transition: width 0.4s ease;
}

.rt-upload-done .rt-upload-fill {
    background: var(--app-success);
}

.rt-upload-problem {
    border-color: color-mix(in srgb, var(--app-danger) 45%, var(--color-divider));
}

.rt-upload-problem .rt-upload-fill {
    background: var(--app-danger);
}
