/* ===========================================================================
   Base element styles and shared primitives.

   Replaces the template's app.css. Load order in App.razor is:
       bootstrap.min.css  ->  tokens.css  ->  fonts.css
                          ->  bootstrap-theme.css  ->  site.css
                          ->  OCreate.styles.css   (scoped, auto-generated)

   Component-specific styling belongs in a scoped `.razor.css` file, not here.
   This file is for element defaults and primitives used across layouts.
   =========================================================================== */

/* --- base --------------------------------------------------------------- */

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }
}

body {
    margin: 0;
    font-family: var(--oc-font-body);
    font-size: var(--oc-text-base);
    line-height: var(--oc-leading-normal);
    color: var(--oc-color-text);
    background-color: var(--oc-color-bg);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
}

/* --- typography --------------------------------------------------------- */

h1, h2, h3, h4, h5, h6 {
    margin-block: 0 var(--oc-space-4);
    font-family: var(--oc-font-display);
    font-weight: var(--oc-weight-semibold);
    line-height: var(--oc-leading-tight);
    letter-spacing: var(--oc-tracking-tight);
    text-wrap: balance;
}

h1 { font-size: var(--oc-text-4xl); }
h2 { font-size: var(--oc-text-3xl); }
h3 { font-size: var(--oc-text-2xl); }
h4 { font-size: var(--oc-text-xl); }
h5 { font-size: var(--oc-text-lg); }
h6 {
    font-size: var(--oc-text-base);
    letter-spacing: var(--oc-tracking-wide);
    text-transform: uppercase;
}

p {
    margin-block: 0 var(--oc-space-4);
    text-wrap: pretty;
}

/* Long-form text gets a comfortable measure. */
p, li {
    max-width: 68ch;
}

a {
    color: var(--oc-color-link);
    text-decoration-thickness: 1px;
    text-underline-offset: 0.15em;
    transition: color var(--oc-duration-fast) var(--oc-ease-out);
}

a:hover {
    color: var(--oc-color-link-hover);
}

strong, b {
    font-weight: var(--oc-weight-semibold);
}

code, kbd, samp, pre {
    font-family: var(--oc-font-mono);
    font-size: 0.9em;
}

hr {
    height: 1px;
    margin-block: var(--oc-space-6);
    border: 0;
    background-color: var(--oc-color-border);
    opacity: 1;
}

img, svg, video {
    max-width: 100%;
    height: auto;
}

/* --- focus -------------------------------------------------------------- */

/* :focus-visible only, so a mouse click doesn't leave a ring behind, but
   keyboard users always get one. */
:focus-visible {
    outline: var(--oc-focus-width) solid var(--oc-color-focus);
    outline-offset: var(--oc-focus-offset);
    border-radius: var(--oc-radius-sm);
}

/* The template removed the outline from focused h1 because FocusOnNavigate
   moves focus there on every navigation. Keep it invisible but preserve the
   focus target so screen readers still announce the new page heading. */
h1:focus,
h1:focus-visible {
    outline: none;
}

/* --- skip link ---------------------------------------------------------- */

.oc-skip-link {
    position: absolute;
    top: 0;
    left: var(--oc-space-4);
    z-index: var(--oc-z-toast);
    padding: var(--oc-space-3) var(--oc-space-4);
    font-weight: var(--oc-weight-semibold);
    color: var(--oc-color-text);
    background-color: var(--oc-amber-brand);
    border-radius: 0 0 var(--oc-radius-md) var(--oc-radius-md);
    /* Black on brand yellow is 13.8:1 — the one fully accessible use of it. */
    transform: translateY(-110%);
    transition: transform var(--oc-duration-fast) var(--oc-ease-out);
}

.oc-skip-link:focus {
    transform: translateY(0);
    color: var(--oc-color-text);
}

/* --- layout primitives -------------------------------------------------- */

.oc-container {
    width: 100%;
    max-width: var(--oc-container-max);
    margin-inline: auto;
    padding-inline: var(--oc-container-pad);
}

.oc-container--narrow {
    max-width: var(--oc-container-narrow);
}

.oc-section {
    padding-block: var(--oc-section-y);
}

.oc-section--subtle {
    background-color: var(--oc-color-bg-subtle);
}

.oc-section--inverse {
    color: var(--oc-color-text-inverse);
    background-color: var(--oc-color-bg-inverse);
}

.oc-section--inverse h1,
.oc-section--inverse h2,
.oc-section--inverse h3 {
    color: var(--oc-color-text-inverse);
}

/* --- text primitives ---------------------------------------------------- */

/* Small uppercase label above a heading. */
.oc-eyebrow {
    display: block;
    margin-block-end: var(--oc-space-2);
    font-family: var(--oc-font-nav);
    font-size: var(--oc-text-sm);
    font-weight: var(--oc-weight-semibold);
    letter-spacing: var(--oc-tracking-caps);
    text-transform: uppercase;
    color: var(--oc-orange-ink);
}

/* Intro paragraph under a page heading. */
.oc-lede {
    max-width: 60ch;
    font-size: var(--oc-text-lg);
    line-height: var(--oc-leading-relaxed);
    color: var(--oc-color-text-muted);
}

/* Display heading in the full brand orange. Only safe at display sizes: the
   brand orange is 3.39:1 on white, which clears AA for large text (3:1) but
   fails for normal text (4.5:1). Use --oc-orange-ink for anything smaller. */
.oc-display-accent {
    color: var(--oc-orange-brand);
}

/* --- upload rows -------------------------------------------------------- */

/* Shared by /quote, /estimate and /dtf. These live here rather than in each page's
   scoped CSS for a specific reason: uploader.js creates the rows at runtime, so they
   never carry a component's b-xxxxx attribute and a scoped rule only reaches them
   through ::deep. Three copies of the same ::deep block had already started to drift
   (the estimator's lost the row__size rule). Unscoped, they just work. */

.upload-list {
    margin-block: var(--oc-space-4);
    padding: 0;
    list-style: none;
}

.upload-row {
    max-width: none;
    padding: var(--oc-space-3) var(--oc-space-4);
    margin-block-end: var(--oc-space-2);
    background-color: var(--oc-gray-050);
    border: 1px solid var(--oc-color-border);
    border-radius: var(--oc-radius-md);
}

.upload-row[data-state="done"] {
    border-inline-start: 4px solid var(--oc-color-success);
}

.upload-row[data-state="error"] {
    border-inline-start: 4px solid var(--oc-color-danger);
    background-color: var(--oc-red-050);
}

.upload-row__head {
    display: flex;
    justify-content: space-between;
    gap: var(--oc-space-3);
    font-size: var(--oc-text-sm);
    font-weight: var(--oc-weight-semibold);
}

.upload-row__size {
    color: var(--oc-color-text-muted);
    font-weight: var(--oc-weight-normal);
    white-space: nowrap;
    margin-inline-start: auto;
}

/* Deliberately not .btn: Bootstrap's button padding and min-height fight the row's
   single-line head. Its accessible name carries the filename and is set with
   setAttribute in uploader.js, never interpolated into markup. */
.upload-row__remove {
    padding: 0;
    border: 0;
    background: none;
    color: var(--oc-color-text-muted);
    font-size: var(--oc-text-xs);
    font-weight: var(--oc-weight-normal);
    text-decoration: underline;
    cursor: pointer;
    white-space: nowrap;
}

.upload-row__remove:hover,
.upload-row__remove:focus-visible {
    color: var(--oc-color-danger);
}

.upload-row__remove:focus-visible {
    outline: 2px solid var(--oc-color-danger);
    outline-offset: 2px;
    border-radius: var(--oc-radius-sm);
}

.upload-row__remove[disabled] {
    opacity: 0.5;
    cursor: default;
    text-decoration: none;
}

.upload-row__bar {
    height: 4px;
    margin-block: var(--oc-space-2);
    background-color: var(--oc-gray-200);
    border-radius: var(--oc-radius-pill);
    overflow: hidden;
}

.upload-row__fill {
    width: 0;
    height: 100%;
    background-color: var(--oc-cyan-brand);
    transition: width var(--oc-duration-fast) linear;
}

.upload-row__status {
    margin: 0;
    font-size: var(--oc-text-xs);
    color: var(--oc-color-text-muted);
}

/* --- Blazor validation -------------------------------------------------- */

/* EditForm emits these alongside Bootstrap's own validation classes. */
.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--oc-color-success);
}

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

.validation-message {
    color: var(--oc-color-danger);
    font-size: var(--oc-text-sm);
}

/* --- Blazor error UI ---------------------------------------------------- */

/* Lives in App.razor rather than a layout, so every layout gets it. That means
   the styles must be unscoped, which is why they're here. */
#blazor-error-ui {
    /* Force light rendering: this bar must stay readable regardless of theme. */
    color-scheme: light only;
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    z-index: var(--oc-z-toast);
    display: none;
    box-sizing: border-box;
    padding: var(--oc-space-3) var(--oc-space-5);
    font-size: var(--oc-text-sm);
    color: var(--oc-black);
    background: var(--oc-amber-100);
    box-shadow: 0 -1px 2px rgb(0 0 0 / 0.2);
}

#blazor-error-ui .reload {
    color: var(--oc-cyan-800);
    font-weight: var(--oc-weight-semibold);
}

#blazor-error-ui .dismiss {
    position: absolute;
    top: var(--oc-space-2);
    right: var(--oc-space-3);
    cursor: pointer;
}

.blazor-error-boundary {
    padding: var(--oc-space-4) var(--oc-space-5);
    color: var(--oc-white);
    background: var(--oc-orange-800);
    border-radius: var(--oc-radius-md);
}

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