/* =========================================================
   AFFORDABLE PERGOLAS DFW THEME
   Auto adapts to browser dark/light preference

   WHAT BELONGS HERE
   Component and page styles live in the component's own <Component>.razor.css,
   next to the .razor. This file is only for rules that CANNOT be scoped:

   1. Design tokens (:root vars) and the dark-theme block.
   2. Bootstrap overrides (.btn, .card, .table, .modal-*, .form-*, .dropdown-*,
      .alert-*, .nav-tabs/.nav-pills, validation, scrollbar). Scoped CSS appends
      a [b-xxxxx] attribute to the selector, and Bootstrap markup we don't render
      (the select caret, .modal-backdrop, a teleported .dropdown-menu) never
      carries it — scoping these would silently drop the theme.
   3. Markup outside the component tree: #loading-overlay and #blazor-error-ui
      (rendered by index.html before any component exists).
   4. Elements created by JS — .sliding-indicator-* (sliding-indicator.js) and
      .place-autocomplete-* (place-autocomplete.js). A node built with
      createElement gets no scope attribute, so a scoped rule would never match.

   Anything else — a class with a single owning component, or one this project
   invented rather than overrode — goes in that component's .razor.css. Use
   ::deep there to reach markup a consumer passes in as a RenderFragment.

   A rule shared by more than one component stays here even if it looks local:
   .nav-pills is used by both Tabs and SegmentedControl, and PipelineSettings
   reaches .tabs-header from its own scope.
   ========================================================= */

/* Light Theme */
:root {
    color-scheme: light;

    /* Brand — one calm blue carries every interactive state (Google-style). */
    --primary: #1A73E8;
    --primary-light: #4285F4;
    --primary-dark: #1765CC;

    /* Accent is aliased to the brand so legacy accent rules stay on-palette.
       The old orange is retired from the chrome. */
    --accent: var(--primary);
    --accent-light: var(--primary-light);
    --accent-dark: var(--primary-dark);

    /* Backgrounds — layered like the dark theme: the body is a grey canvas and
       surfaces (navbar, side navs, cards, modals) sit on it in white, so the
       chrome reads as elevation instead of flat white-on-white. */
    --bg-body: #F8F9FA;
    --bg-surface: #FFFFFF;
    --bg-surface-alt: #F1F3F4;
    --bg-elevated: #FFFFFF;

    /* Text */
    --text-primary: #202124;
    --text-secondary: #5F6368;
    --text-on-primary: #FFFFFF;

    /* Borders */
    --border-color: #DADCE0;

    /* Feedback */
    --success: #1E8E3E;
    --warning: #F9AB00;
    --danger: #D93025;

    /* Navigation */
    --navbar-bg: #FFFFFF;
    --navbar-text: #202124;

    --sidebar-bg: #FFFFFF;
    --sidebar-text: #202124;
    --sidebar-hover: #F1F3F4;

    /* Cards */
    --card-bg: #FFFFFF;
    --card-shadow: 0 1px 2px rgba(60, 64, 67, 0.08), 0 1px 3px rgba(60, 64, 67, 0.05);

    /* Inputs */
    --input-bg: #FFFFFF;
    --input-border: #DADCE0;
    --input-text: #202124;

    /* Misc */
    --radius: 8px;
    --transition: all 0.2s ease-in-out;

    /* Inner padding of a panelled tab's sheet. A token because content inside the
       sheet has to cancel it to reach the edges (a full-width divider, say), and the
       two values must not drift apart. */
    --tab-panel-padding: 1.75rem;

    /* Bootstrap */
    --bs-primary: var(--primary);
    --bs-secondary: var(--accent);
    --bs-secondary-color: var(--text-secondary);


    --bs-body-bg: var(--bg-body);
    --bs-body-color: var(--text-primary);

    --bs-border-color: var(--border-color);

    --bs-card-bg: var(--card-bg);
    --bs-card-color: var(--text-primary);
    --bs-card-border-color: var(--border-color);

    --bs-tertiary-bg: var(--bg-surface-alt);
    --bs-secondary-bg: var(--bg-surface);

    --bs-heading-color: var(--text-primary);

    --bs-link-color: var(--accent);
    --bs-link-hover-color: var(--accent-light);
}

/* Dark Theme */
@media (prefers-color-scheme: dark) {
    :root {
        color-scheme: dark;

        /* Brand — light blue for dark surfaces; dark text sits on it (see
           --text-on-primary) for proper contrast on filled buttons. */
        --primary: #8AB4F8;
        --primary-light: #AECBFA;
        --primary-dark: #669DF6;

        --accent: var(--primary);
        --accent-light: var(--primary-light);
        --accent-dark: var(--primary-dark);

        /* Backgrounds */
        --bg-body: #1F2023;
        --bg-surface: #2A2B2F;
        --bg-surface-alt: #303134;
        --bg-elevated: #3C4043;

        /* Text */
        --text-primary: #E8EAED;
        --text-secondary: #9AA0A6;
        --text-on-primary: #202124;

        /* Borders */
        --border-color: #3C4043;

        /* Feedback */
        --success: #81C995;
        --warning: #FDD663;
        --danger: #F28B82;

        /* Navigation */
        --navbar-bg: #2A2B2F;
        --navbar-text: #E8EAED;

        --sidebar-bg: #2A2B2F;
        --sidebar-text: #E8EAED;
        --sidebar-hover: #3C4043;

        /* Cards */
        --card-bg: #2A2B2F;
        --card-shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 1px 3px rgba(0, 0, 0, 0.24);

        /* Inputs */
        --input-bg: #303134;
        --input-border: #3C4043;
        --input-text: #E8EAED;

        /* Bootstrap */
        --bs-primary: var(--primary);
        --bs-secondary: var(--accent);
        --bs-secondary-color: var(--text-secondary);

        --bs-body-bg: var(--bg-body);
        --bs-body-color: var(--text-primary);

        --bs-border-color: var(--border-color);

        --bs-card-bg: var(--card-bg);
        --bs-card-color: var(--text-primary);
        --bs-card-border-color: var(--border-color);

        --bs-tertiary-bg: var(--bg-surface-alt);
        --bs-secondary-bg: var(--bg-surface);

        --bs-heading-color: var(--text-primary);

        --bs-link-color: var(--accent);
        --bs-link-hover-color: var(--accent-light);
    }
}

/* Global */

html,
body {
    background-color: var(--bg-body);
    color: var(--text-primary);
    transition: var(--transition);

    font-family:
        Inter,
        system-ui,
        -apple-system,
        BlinkMacSystemFont,
        "Segoe UI",
        sans-serif;
}

/* Blazor */

#blazor-error-ui {
    background: var(--danger);
    color: white;

    bottom: 0;
    display: none;

    left: 0;
    padding: 1rem 1.25rem;

    position: fixed;
    width: 100%;
    z-index: 9999;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 1rem;
    top: 0.75rem;
}

#loading-overlay {
    position: fixed;
    inset: 0;
    z-index: 10000;

    display: flex;
    align-items: center;
    justify-content: center;

    background: var(--bg-body);

    opacity: 1;
    transition: opacity 0.5s ease;
}

#loading-overlay.is-hidden {
    opacity: 0;
    pointer-events: none;
}

.loading-logo {
    width: min(40vw, 220px);
    height: auto;
    overflow: visible;
}

.loading-logo-line {
    fill: none;
    stroke: #c93524;
    stroke-width: 28;
    stroke-linecap: round;
    stroke-dasharray: 2000;
    stroke-dashoffset: 2000;
    animation: loading-logo-draw 4s ease-in-out infinite;
}

@keyframes loading-logo-draw {
    0%, 10% { stroke-dashoffset: 2000; opacity: 0; }
    20%     { opacity: 1; }
    40%     { stroke-dashoffset: 0; opacity: 1; }
    80%     { stroke-dashoffset: 0; opacity: 1; }
    90%, 100% { opacity: 0; }
}

.loading-progress {
    position: relative;

    display: block;

    width: 8rem;
    height: 8rem;

    margin: 20vh auto 1rem auto;
}

.loading-progress circle {
    fill: none;
    stroke-width: 0.6rem;
    transform-origin: 50% 50%;
    transform: rotate(-90deg);
}

.loading-progress circle:first-child {
    stroke: var(--border-color);
}

.loading-progress circle:last-child {
    stroke: var(--accent);
    stroke-linecap: round;

    animation: loading-progress-animation 1.2s linear infinite;
}

.loading-progress-text {
    color: var(--text-secondary);

    font-size: 0.9rem;
    font-weight: 500;

    text-align: center;
}

@keyframes loading-progress-animation {
    0% {
        stroke-dasharray: 0 126;
    }

    50% {
        stroke-dasharray: 63 126;
    }

    100% {
        stroke-dasharray: 126 126;
    }
}

/* Links */

a {
    color: var(--accent);
    transition: var(--transition);
}

a:hover {
    color: var(--accent-light);
}

/* Navbar */

.navbar {
    background-color: var(--navbar-bg) !important;

    color: var(--navbar-text);

    border-bottom: 0.5px solid var(--border-color);
}

.navbar-brand,
.navbar .nav-link {
    color: var(--navbar-text) !important;
}

/* Cards */

.card {
    background-color: var(--card-bg);
    color: var(--text-primary);

    border: 1px solid var(--border-color);
    border-radius: var(--radius);

    box-shadow: var(--card-shadow);

    transition: var(--transition);
}

.card-title,
.card-text,
.card-body,
.card-header,
.card-footer {
    color: inherit;
}

.card-header {
    background: transparent;

    border-bottom: 1px solid var(--border-color);
}

/* Buttons */

.btn {
    border-radius: var(--radius);
    transition: var(--transition);
}

.btn-primary {
    background-color: var(--primary) !important;
    border-color: var(--primary) !important;
    color: var(--text-on-primary) !important;
}

.btn-primary:hover,
.btn-primary:focus {
    background-color: var(--primary-light) !important;
    border-color: var(--primary-light) !important;
}

/* Neutral secondary: the brand colour belongs to the primary action only, so the
   secondary button reads as a quiet grey surface (Google-style). */
.btn-secondary {
    background-color: var(--bg-surface-alt) !important;
    border-color: var(--border-color) !important;
    color: var(--text-primary) !important;
}

.btn-secondary:hover,
.btn-secondary:focus {
    background-color: var(--border-color) !important;
    border-color: var(--border-color) !important;
    color: var(--text-primary) !important;
}

.btn-outline-primary {
    color: var(--primary);
    border-color: var(--primary);
}

.btn-outline-primary:hover {
    background-color: var(--primary);
    border-color: var(--primary);
}

/* An icon-only control that is still a real target. Shared by EstimateOptionCard and
   EstimateOptionLine — hence here rather than in either .razor.css.

   Sized from measurement: as bare glyphs these rendered 12x23px a few pixels apart, under
   the 24x24 minimum and easy to mis-hit, with nothing under the pointer to say which one
   was about to be pressed. The square and the tint on hover fix both at once. */
.estimate-action-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: var(--radius);
    line-height: 1;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.estimate-action-button:hover,
.estimate-action-button:focus-visible {
    background-color: var(--bg-surface-alt);
}

/* Forms */

.form-control,
.form-select {
    background-color: var(--input-bg);
    border-color: var(--input-border);

    color: var(--input-text);

    border-radius: var(--radius);
}

/* The native <select> caret is a baked-in SVG whose stroke defaults to a dark
   grey, and Bootstrap scopes the var to .form-select itself — so a :root
   override is shadowed. The project themes via prefers-color-scheme (not
   [data-bs-theme]), so Bootstrap's dark caret never kicks in and the arrow reads
   as washed-out/disabled. Redefine the var on .form-select with a light stroke. */
@media (prefers-color-scheme: dark) {
    .form-select {
        --bs-form-select-bg-img: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23E8EAED' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
    }
}

.form-control:focus,
.form-select:focus {
    background-color: var(--input-bg);
    color: var(--input-text);
}

.form-control::placeholder {
    color: var(--text-secondary);
}

/* Floating labels: themed background for the label backdrop + muted resting color. */
.form-floating > label {
    color: var(--text-secondary);
}

.form-floating > .form-control:focus ~ label,
.form-floating > .form-control:not(:placeholder-shown) ~ label,
.form-floating > .form-select ~ label {
    color: var(--text-secondary);
}

/* The label sits on an opaque strip when floated; match it to the input background
   so it never shows the surface/border behind it (light & dark). */
.form-floating > .form-control:focus ~ label::after,
.form-floating > .form-control:not(:placeholder-shown) ~ label::after,
.form-floating > .form-select ~ label::after {
    background-color: var(--input-bg);
}

/* The unchecked switch knob is a baked-in SVG with a near-black fill. Bootstrap
   only lightens it under [data-bs-theme=dark]; we theme via prefers-color-scheme,
   so in dark the knob reads as washed-out/disabled. Lighten it to match. */
@media (prefers-color-scheme: dark) {
    .form-switch .form-check-input:not(:checked):not(:focus) {
        --bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.25%29'/%3e%3c/svg%3e");
    }
}

/* Validation */

.valid.modified:not([type=checkbox]) {
    outline: 2px solid var(--success);
}

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

.validation-message {
    color: var(--danger);

    font-size: 0.875rem;
    margin-top: 0.25rem;
}

/* Tables */

.table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--text-primary);
    /* --bs-table-border-color: var(--border-color); */
    --bs-table-striped-bg: var(--bg-surface-alt);
    --bs-table-striped-color: var(--text-primary);
    --bs-table-hover-bg: var(--bg-surface-alt);
    --bs-table-hover-color: var(--text-primary);
    --bs-table-active-bg: var(--bg-surface-alt);
    --bs-table-active-color: var(--text-primary);

    color: var(--text-primary);
    border-color: var(--border-color);
}

.table > :not(caption) > * > * {
    background-color: transparent;
    color: var(--text-primary);
    border-bottom-color: var(--border-color);
}

.table > thead {
    color: var(--text-secondary);
}

.table > thead > tr > th {
    /* background-color: var(--bg-surface-alt); */
    color: var(--text-secondary);

    border-bottom: 1px solid var(--border-color);

    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: 0.78rem;
}

.table > thead > tr > th.sortable-header:hover {
    color: var(--text-primary);
}

.table-hover > tbody > tr:hover > * {
    background-color: var(--bg-surface-alt);
    color: var(--text-primary);
}

.table > tbody > tr:last-child > * {
    border-bottom: 0;
}

.table-responsive {
    border-radius: 12px;
}

/* Dropdown */

.dropdown-menu {
    background-color: var(--bg-surface);

    border: 1px solid var(--border-color);

    border-radius: var(--radius);
}

.dropdown-item {
    color: var(--text-primary);
}

.dropdown-item:hover {
    background-color: var(--bg-surface-alt);
}

/* A disabled item reads as an intentional "already done" state (muted, no hover)
   rather than the washed-out default greys. */
.dropdown-item:disabled,
.dropdown-item.disabled {
    color: var(--text-secondary);
    opacity: 1;
    cursor: default;
    background-color: transparent;
}

/* Modal */

.modal-content {
    background-color: var(--bg-surface);

    border: 1px solid var(--border-color);

    border-radius: var(--radius);

    color: var(--text-primary);
}

.modal-header,
.modal-footer {
    border: 0;
}

.modal-header .btn-close {
    --bs-btn-close-color: var(--text-primary);
    filter: none;
}

@media (prefers-color-scheme: dark) {
    .modal-header .btn-close {
        filter: invert(1) grayscale(100%) brightness(200%);
    }
}

.modal-dialog-scrollable .modal-content > form {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    max-height: 100%;
}

.modal-dialog-scrollable .modal-content > form > .modal-body {
    overflow-y: auto;
}

/* Alerts */

.alert {
    color: var(--text-primary);
}

.alert-success {
    background-color: rgba(46, 158, 91, 0.15);
    border-color: var(--success);
}

.alert-warning {
    background-color: rgba(245, 165, 36, 0.15);
    border-color: var(--warning);
}

.alert-danger {
    background-color: rgba(217, 45, 32, 0.15);
    border-color: var(--danger);
}

/* Sliding indicator (shared)
   Injected by sliding-indicator.js into nav-like hosts; JS owns the moving
   coordinates (left/width or top/height), these rules own the look. Selection
   styling for tabs/pills/side navs lives here so every host animates the same
   way — don't re-style the active item with its own background/border. */

.sliding-indicator-host {
    position: relative;
}

.sliding-indicator {
    position: absolute;
    z-index: 0;
    opacity: 0;
    pointer-events: none;
    list-style: none;
    transition:
        left 0.25s cubic-bezier(0.4, 0, 0.2, 1),
        width 0.25s cubic-bezier(0.4, 0, 0.2, 1),
        top 0.25s cubic-bezier(0.4, 0, 0.2, 1),
        height 0.25s cubic-bezier(0.4, 0, 0.2, 1),
        opacity 0.15s ease;
}

.sliding-indicator--on {
    opacity: 1;
}

/* Small underline that travels horizontally under the active item. */
.sliding-indicator--underline {
    bottom: 0;
    height: 2px;
    border-radius: 999px;
    background-color: var(--accent);
    transform: scaleX(0.6);
}

/* Raised segment that slides behind the active pill of a segmented control.
   --bg-elevated (not body/surface) so the thumb still reads as raised now that
   the light body is grey and the track is grey too. */
.sliding-indicator--thumb {
    top: 3px;
    bottom: 3px;
    border-radius: 9px;
    background-color: var(--bg-elevated);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}

/* Thin side line that travels vertically along the active item. */
.sliding-indicator--bar {
    left: 0;
    width: 3px;
    border-radius: 999px;
    background-color: var(--accent);
    transform: scaleY(0.55);
}

/* Tabs — notebook tabs: the active one is a sheet that reads as continuous with
   the panel below it (own surface, rounded top corners, sitting on the header's
   bottom border), the inactive ones stay recessed behind it. The sliding
   underline still marks the selection and travels the tab's full width, so the
   moving part and the sheet edge line up instead of competing. */

.nav-tabs {
    border-bottom: 0;
    gap: 0.25rem;
}

.nav-tabs .nav-link {
    background-color: transparent;
    color: var(--text-secondary);

    border: 0;
    border-radius: var(--radius) var(--radius) 0 0;

    padding: 1.125rem 1.75rem;
    font-size: 1rem;

    font-weight: 500;
    transition: color 0.15s ease, background-color 0.15s ease;
}

/* Recessed tabs lift slightly on hover, hinting they are separate sheets. */
.nav-tabs .nav-link:hover {
    background-color: var(--bg-surface-alt);
    color: var(--text-primary);
}

.nav-tabs .nav-link.active,
.nav-tabs .nav-link.active:hover {
    background-color: var(--bg-surface);
    color: var(--accent);
}

.nav-tabs .nav-link:focus,
.nav-tabs .nav-link:focus-visible {
    box-shadow: none;
    outline: none;
}

/* A tab that carries its own action: the sheet moves up to the item, so the
   button and the trailing menu share one continuous surface. The button then
   drops its own background and its right padding, which the action takes over. */
.nav-tabs .nav-item-with-action {
    display: flex;
    align-items: center;
    border-radius: var(--radius) var(--radius) 0 0;
    transition: background-color 0.15s ease;
}

.nav-tabs .nav-item-with-action:hover {
    background-color: var(--bg-surface-alt);
}

.nav-tabs .nav-item-with-action.active,
.nav-tabs .nav-item-with-action.active:hover {
    background-color: var(--bg-surface);
}

.nav-tabs .nav-item-with-action .nav-link,
.nav-tabs .nav-item-with-action .nav-link:hover,
.nav-tabs .nav-item-with-action .nav-link.active {
    background-color: transparent;
    padding-right: 0.75rem;
}

/* A status under the title. Its own line, so the strip's width stays tied to the
   titles rather than to whatever the badge says. */
.nav-tabs .nav-link-subtitle {
    display: block;
    margin-top: 0.25rem;
    font-size: 0.75rem;
    font-weight: 400;
    line-height: 1;
}

/* The action is muted until its tab is open or hovered, so a row of tabs doesn't
   read as a row of menus. */
.nav-tabs .nav-item-action {
    display: flex;
    align-items: center;
    align-self: stretch;
    padding-right: 1.25rem;
    color: var(--text-secondary);
    opacity: 0.5;
    transition: opacity 0.15s ease;
}

.nav-tabs .nav-item-with-action:hover .nav-item-action,
.nav-tabs .nav-item-with-action.active .nav-item-action {
    opacity: 1;
}

/* Full-width under a notebook tab: the indicator is the open sheet's edge here,
   not a centred marker, so it spans the tab rather than the default 60%. */
.nav-tabs.sliding-indicator-host .sliding-indicator--underline {
    transform: none;
}


/* Pills — iOS-style segmented control: a quiet track whose raised "thumb"
   (the sliding indicator) glides to the selected segment. */

.nav-pills {
    display: inline-flex;
    gap: 2px;
    padding: 3px;
    background-color: var(--bs-tertiary-bg);
    border: 1px solid var(--border-color);
    border-radius: 12px;
}

.nav-pills .nav-link {
    position: relative;
    z-index: 1;
    padding: 0.4rem 1.1rem;
    border-radius: 9px;
    color: var(--text-secondary);
    font-weight: 500;
    background-color: transparent;
    transition: color 0.15s ease;
}

.nav-pills .nav-link:hover {
    color: var(--text-primary);
}

.nav-pills .nav-link.active {
    color: var(--text-primary);
    background-color: transparent;
}

.nav-pills .nav-link:focus,
.nav-pills .nav-link:focus-visible {
    box-shadow: none;
    outline: none;
}

/* Scrollbar */

::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

::-webkit-scrollbar-thumb {
    background: var(--border-color);
    border-radius: 999px;
}

::-webkit-scrollbar-thumb:hover {
    background: var(--text-secondary);
}

::-webkit-scrollbar-track {
    background: transparent;
}

/* Utilities */

.cursor-pointer {
    cursor: pointer;
}

.dropdown-menu.show {
    z-index: 1050;
}

/* =========================================================
   GOOGLE PLACES ADDRESS AUTOCOMPLETE
   Suggestion dropdown rendered by place-autocomplete.js, anchored to the
   position-relative Street field. Bootstrap .dropdown-menu handles theming;
   each item shows a pin + main/secondary lines, and the menu closes with the
   Google-required "Powered by Google" attribution.
   ========================================================= */
.place-autocomplete-menu {
    top: 100%;
    left: 0;
    margin-top: 0.125rem;
    max-height: 18rem;
    overflow-y: auto;
    padding-bottom: 0;
}

.place-autocomplete-item {
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
    white-space: normal;
}

.place-autocomplete-pin {
    margin-top: 0.15rem;
    flex: 0 0 auto;
    color: var(--primary);
    font-size: 0.9rem;
}

.place-autocomplete-item.active .place-autocomplete-pin,
.place-autocomplete-item.active .place-autocomplete-secondary {
    color: inherit;
}

.place-autocomplete-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
    line-height: 1.25;
}

.place-autocomplete-main {
    font-weight: 500;
}

.place-autocomplete-secondary {
    font-size: 0.78rem;
}

.place-autocomplete-attribution {
    position: sticky;
    bottom: 0;
    padding: 0.4rem 1rem;
    font-size: 0.7rem;
    text-align: right;
    background-color: var(--bs-dropdown-bg, var(--bg-surface));
    border-top: 1px solid var(--border-color);
}
