/* =============================================================================
   GLOBAL APPLICATION COMPONENT STYLES
   Path: wwwroot/css/app-components.css

   Contains reusable component styles used across the application.
   Include this file after Bootstrap to ensure proper override behavior.

   All colors reference CSS variables from BaseTheme which are updated by ThemeService
   ============================================================================= */

/* =============================================================================
   NAVIGATION TABS (MainLayout menu)
   Override Bootstrap NavLink defaults with maximum specificity
   ============================================================================= */

/* Header must allow overflow for tab pills to show */
header {
    overflow: visible !important;
    position: relative !important;
    z-index: 100 !important;
}

.top-tabs {
    display: flex;
    align-items: flex-end; /* Align items to bottom */
    padding: 0 14px;
    gap: 36px;
    flex: 1 1 auto;
    overflow: visible; /* Allow tab pill to show */
}

/* Nuclear option: maximum specificity to override Bootstrap NavLink */
nav.top-tabs a.tab-link,
nav.top-tabs a.tab-link:link,
nav.top-tabs a.tab-link:visited {
    display: inline-flex !important;
    align-items: flex-end !important; /* Align text to bottom */
    height: 64px !important;
    padding: 0 6px 8px 6px !important; /* 8px bottom padding to move text down */
    color: var(--unselected-tab-foreground) !important;
    text-decoration: none !important;
    text-decoration-line: none !important;
    font-size: 18px !important;
    font-weight: 600 !important;
    position: relative !important;
    background: transparent !important;
}

    nav.top-tabs a.tab-link:hover {
        color: var(--tab-hover-foreground) !important;
        text-decoration: none !important;
    }

    /* Active tab styling */
    nav.top-tabs a.tab-link.active {
        color: var(--selected-tab-foreground) !important;
        font-weight: 700 !important;
        text-decoration: none !important;
        z-index: 1; /* Create stacking context for ::after */
    }

        /* Tab pill background for active tab */
        nav.top-tabs a.tab-link.active::after {
            content: "";
            position: absolute;
            left: -26px;
            right: -26px;
            bottom: -1px; /* Overlap header border */
            height: 40px; /* Adjust this value for tab height */
            background: var(--selected-tab-background);
            border: 1px solid var(--selected-tab-border);
            border-bottom: none; /* Seamless connection to content */
            border-top-left-radius: 10px;
            border-top-right-radius: 10px;
            z-index: -1; /* Behind text but above background */
        }

/* =============================================================================
   ACTION BUTTONS
   Standard action buttons with consistent styling across the application
   ============================================================================= */

.btn-action {
    background-color: var(--button-action-background);
    border: 1px solid var(--button-action-border);
    color: var(--button-action-text);
    font-weight: 600;
    padding: 8px 16px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 0.875rem;
    line-height: 1.5;
    text-align: center;
    vertical-align: middle;
    user-select: none;
    transition: background-color 0.15s ease-in-out;
}

    .btn-action:hover {
        background-color: var(--button-action-hover-background);
        color: var(--button-action-text);
        border-color: var(--button-action-hover-border);
    }

    .btn-action:focus {
        outline: 0;
        box-shadow: 0 0 0 2px rgba(130, 138, 145, 0.5);
    }

    .btn-action:active {
        background-color: var(--button-action-active-background);
        border-color: var(--button-action-active-border);
    }

    .btn-action:disabled {
        background-color: var(--button-action-disabled-background);
        color: var(--button-action-disabled-text);
        border-color: var(--button-action-disabled-border);
        cursor: not-allowed;
        opacity: 0.65;
    }

/* =============================================================================
   FORM CONTROLS - RADIO / CHECK
   Make all radio/checkbox rows look consistent across pages
   ============================================================================= */

/* keep inputs vertically aligned with text in tight UIs */
.form-check-input {
    margin-top: 0;
}

/* default label look */
.form-check-label {
    font-size: 0.9rem;
    line-height: 1.4;
    color: var(--text-primary);
}

/* make radios stronger so they show on light backgrounds */
.form-check-input[type="radio"] {
    width: 1rem;
    height: 1rem;
    border: 1px solid var(--text-primary);
    background-color: var(--input-background);
}

/* make checkboxes visible with darker border */
.form-check-input[type="checkbox"] {
    border: 1px solid var(--checkbox-border);
    background-color: var(--input-background);
}

    /* checked checkboxes: use Bootstrap blue */
    .form-check-input[type="checkbox"]:checked {
        background-color: var(--checkbox-checked-background);
        border-color: var(--checkbox-checked-border);
    }

/* READ-ONLY CHECKBOX - a checkbox that only DISPLAYS a value (a grid cell, a summary row). Use  class="form-check-input fs-check-readonly" disabled.
   Bootstrap fades any disabled input to half strength, which on a data grid reads as "broken" and hides the value, so this keeps the checkbox
   at full strength in the SAME theme variables as every other checkbox (--checkbox-border, --checkbox-checked-background/-border, set per Theme
   in BaseTheme) - a theme change re-colours it with the rest. pointer-events none so a click or double-click on it reaches the row/cell under
   it. Opt-in on purpose: an ordinary disabled checkbox still reads as "unavailable". */
.form-check-input[type="checkbox"].fs-check-readonly {
    pointer-events: none;
}

.form-check-input[type="checkbox"].fs-check-readonly:disabled {
    opacity: 1;
    border: 1px solid var(--checkbox-border);
    background-color: var(--input-background);
}

.form-check-input[type="checkbox"].fs-check-readonly:disabled:checked {
    background-color: var(--checkbox-checked-background);
    border-color: var(--checkbox-checked-border);
}

/* checked radios: use Bootstrap blue */
.form-check-input[type="radio"]:checked {
    background-color: var(--checkbox-checked-background);
    border-color: var(--checkbox-checked-border);
}

/* disabled radios should still be visible */
.form-check-input[type="radio"]:disabled {
    opacity: 1;
    background-color: var(--input-background);
    border-color: var(--text-primary);
}

    /* and their labels should not be greyed out */
    .form-check-input[type="radio"]:disabled + .form-check-label {
        color: var(--text-primary);
        opacity: 1;
    }

/* =============================================================================
   ICON CONTROLS (Generate / Reload / Edit icon buttons)
   Shared between MainLayout and pages like PagProjects
   ============================================================================= */

/* Container for small icon buttons (inline in pages) */
.generation-controls {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* Container used in the header (keeps its padding) */
.top-controls {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 10px;
}

/* Icon buttons: small, borderless */
.icon-btn {
    width: 32px;
    height: 32px;
    background: transparent;
    border: none;
    outline: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    cursor: pointer;
}

    .icon-btn:focus {
        outline: none;
    }

    .icon-btn:hover {
        filter: brightness(0.95);
    }

/* Icons */
.icon-img {
    width: 22px;
    height: 22px;
    display: block;
}

/* =============================================================================
   FORM CONTROLS - INPUT / SELECT / TEXTAREA
   Theme-driven consistent controls across the entire application
   ============================================================================= */

/* MudBlazor's Outlined variant (MudTextField/MudSelect/MudAutocomplete) draws its border
   via this custom property, not via any class the rules below can target directly (the
   border lives on an internal <fieldset>, not the <input> itself). Bridge it to the same
   theme token so Mud "Outlined" controls match the blue-bordered look of plain textboxes. */
:root {
    /* !important: MudThemeProvider injects its own :root palette variables client-side,
       after this stylesheet loads, so it otherwise wins the cascade at equal specificity. */
    --mud-palette-lines-inputs: var(--input-border) !important;
}

/* Apply to Bootstrap form controls + plain inputs.
   NOTE: background-color, not the `background` shorthand — `background` resets every
   sub-property it doesn't specify, including background-image, which silently wipes out
   Bootstrap's built-in .form-select dropdown chevron (and the one restored below for every
   native <select>). This was the recurring "missing dropdown arrow" bug across the app. */
.form-control,
.form-select,
textarea.form-control,
input[type="text"],
input[type="password"],
input[type="email"],
input[type="number"],
input[type="search"],
input[type="url"],
select,
textarea {
    border: 1px solid var(--input-border);
    background-color: var(--input-background);
    color: var(--text-primary);
    border-radius: 8px;
}

/* Bootstrap's own bootstrap.css (App.razor) ships .form-select:disabled/.form-control:disabled
   rules of the same class+pseudo specificity as the plain selectors above - the :disabled
   pseudo-class doesn't change specificity vs. a plain class, so these only win because they're
   declared later in the cascade (site.css/ETS.styles.css loads after bootstrap.css). Without
   this, a disabled select/input silently fell back to Bootstrap's --bs-secondary-bg instead of
   the theme's own --input-background (confirmed live, 2026-08-18 - Sales Rep dropdown). Same
   "re-assert on :disabled" fix already used for .form-check-input[type="radio"]:disabled above. */
.form-control:disabled,
.form-select:disabled,
select:disabled,
input:disabled,
textarea:disabled {
    background-color: var(--input-background);
    color: var(--text-primary);
    opacity: 1;
}

/* Dropdown chevron — standardized here so every <select>/.form-select in the app gets one,
   regardless of Bootstrap's own CSS load order relative to this stylesheet. */
.form-select,
select {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 14px 10px;
    padding-right: 34px;
}

/* Consistent height for single-line inputs/selects - single point of control via
   --input-height/--input-font-size (BaseTheme.cs: InputHeight/InputFontSize), so every app/theme
   that wants a different control size (e.g. ETS's compact controls, see its own local
   wwwroot/css/app-components.css) changes it in exactly one place and both this rule AND the
   MudBlazor rule below stay in sync automatically - they were two independently-hardcoded numbers
   before this (2026-08-19) and drifted apart, which is what broke MudSelect/MudDatePicker height
   matching plain textboxes in the first place. */
.form-control,
.form-select,
input[type="text"],
input[type="password"],
input[type="email"],
input[type="number"],
input[type="search"],
input[type="url"],
select {
    /* Fallback values (44px/16px) match what this rule hardcoded before it became variable-
       driven — protects any app whose own build hasn't picked up BaseTheme.cs's new InputHeight/
       InputFontSize yet (a stale build leaves these two variables genuinely undefined, which
       would otherwise make the whole height/font-size declaration invalid and fall through to
       the browser's own default sizing instead of this app's original 44px/16px look). */
    height: var(--input-height, 44px);
    font-size: var(--input-font-size, 16px);

    /* Vertical padding is a FORMULA, not the flat 10px this used to be - same fix, same reason,
       as the .mud-input-outlined rule below: a hardcoded padding only looks right at the one
       height it was tuned for. This box is box-sizing:border-box (Bootstrap's global reset) with
       a 1px border each side (see the border rule above), so content-height = height - 2*padding
       - 2px border; line-height:1 pins rendered text to exactly font-size tall, so solving for
       padding gives (height - font-size)/2 - 1px. Confirmed live, 2026-08-23 - ETS's own 26px/
       14px override left only ~4px of content box under the old flat 10px padding, invisible to
       the eye in a <select> (an <input> tolerates the overflow and still shows its text; a
       <select>'s closed-state label clips strictly to the padding box, so it renders as
       genuinely empty even though the correct option is selected underneath). */
    line-height: 1;
    padding: calc((var(--input-height, 44px) - var(--input-font-size, 16px)) / 2 - 1px) 12px;
}

/* Match MudBlazor's Outlined single-line fields (MudSelect/MudDatePicker/MudTextField) to the
   same --input-height/--input-font-size as the plain controls above, via a formula rather than a
   hardcoded number tuned for one specific size (a hardcoded fix here already broke twice,
   2026-08-19, once when the target height assumption was wrong and once when it didn't account
   for MudBlazor's own baked-in padding). line-height:1 pins the rendered text to exactly
   --input-font-size tall (no font-metric guessing), so the padding needed to reach
   --input-height total is exactly (height - font-size) / 2 - works for any value either variable
   is set to, not just the one this was tested against.
   .mud-input-root is the inner text element (box-sizing:content-box) - not the visible bordered
   box, which is .mud-input-outlined itself and follows its content's height. Scoped to
   .mud-input-outlined (not a bare .mud-input-root, which MudBlazor reuses internally elsewhere
   with different padding/margin this rule has no business touching).
   !important: MudBlazor's own compiled CSS sets padding/font-size on this same element with a
   selector this rule's specificity doesn't reliably beat (confirmed live, 2026-08-19 - without
   !important here, MudBlazor's own ~52px sizing won regardless of what --input-height/
   --input-font-size were set to). */
.mud-input-outlined .mud-input-root {
    font-size: var(--input-font-size, 16px) !important;
    line-height: 1 !important;
    padding-top: calc((var(--input-height, 44px) - var(--input-font-size, 16px)) / 2) !important;
    padding-bottom: calc((var(--input-height, 44px) - var(--input-font-size, 16px)) / 2) !important;
}

/* Select's dropdown-arrow icon and DatePicker's calendar-icon button default to sizes tuned for
   MudBlazor's own ~52px box - left alone, the calendar icon button (a real 48px Material touch
   target) would stick out above and below anything shorter than 48px. min() keeps their original
   size wherever --input-height is generous enough for it (the untouched default, 44px, lands
   right back at MudBlazor's own ~24px/48px sizing) and only shrinks them proportionally once
   --input-height gets smaller than that - verified live against ETS's 26px value, 2026-08-19. */
.mud-input-outlined .mud-input-adornment {
    height: var(--input-height, 44px);
    display: flex;
    align-items: center;
}

.mud-input-outlined .mud-input-adornment-icon {
    width: min(24px, calc(var(--input-height, 44px) * 0.7));
    height: min(24px, calc(var(--input-height, 44px) * 0.7));
}

.mud-input-outlined .mud-input-adornment-icon-button {
    width: min(48px, var(--input-height, 44px));
    height: min(48px, var(--input-height, 44px));
    padding: 0;
}

    .mud-input-outlined .mud-input-adornment-icon-button svg {
        width: min(24px, calc(var(--input-height, 44px) * 0.7));
        height: min(24px, calc(var(--input-height, 44px) * 0.7));
    }

/* Textareas */
textarea,
textarea.form-control {
    min-height: 100px;
    font-size: 16px;
    padding: 10px 12px;
}

    /* Focus ring aligned to theme */
    .form-control:focus,
    .form-select:focus,
    input:focus,
    select:focus,
    textarea:focus {
        outline: none;
        border-color: var(--input-border);
        box-shadow: 0 0 0 2px rgba(130, 138, 145, 0.35);
    }

/* =============================================================================
   FORM LABELS - theme-driven label color across the application
   ============================================================================= */

label,
.form-label {
    color: var(--text-primary);
}

/* =============================================================================
   CmpIncrementalSearch - the standard "scope dropdown + search + Add + Edit" widget
   used in menu bars across all apps. See FSCommon.Blazor/Components/IncrementalSeacrh.
   ============================================================================= */

.cmp-incremental-search {
    display: flex;
    align-items: center;
    gap: 2px;
}

.cmp-incremental-search-title {
    font-size: 13px;
    font-weight: 600;
    color: var(--text-secondary, #555);
    white-space: nowrap;
    margin-right: 6px;
}

/* Scope dropdown (Name / ID Number, etc.) is intentionally borderless (Variant.Text
   in the component) to de-emphasize it relative to the actual search box - it still
   shows its dropdown chevron so users know it's a selector. The explicit border/box-shadow
   removal below is a belt-and-suspenders backstop — Variant.Text + DisableUnderLine should
   already do this, but MudBlazor's own default border/shadow rules have proven sticky. */
.cmp-incremental-search-scope {
    opacity: 0.85;
}

    .cmp-incremental-search-scope .mud-input,
    .cmp-incremental-search-scope .mud-input:before,
    .cmp-incremental-search-scope .mud-input:after {
        border: none !important;
        box-shadow: none !important;
    }

/* Compact height — MudBlazor's Outlined variant reserves 18.5px top/bottom padding on
   .mud-input-slot for floating-label space (Dense mode doesn't remove this); this component
   uses Placeholder, not Label, so that space is pure wasted height. Overriding the padding
   directly (rather than just min-height, which can only set a floor, not shrink content that's
   already taller) is what actually brings the box down to a compact size. */
.cmp-incremental-search-input .mud-input-slot,
.cmp-incremental-search-scope .mud-input-slot {
    padding-top: 6px !important;
    padding-bottom: 6px !important;
}

.cmp-incremental-search-add,
.cmp-incremental-search-edit {
    color: var(--text-secondary, #666);
}

/* Custom <img>-based Add/Edit buttons (AddIconUrl/EditIconUrl) - plain icon buttons matching
   the app's existing .icon-btn look, used when an app supplies its own icon image instead of
   the MudBlazor Material icon fallback. */
.cmp-incremental-search-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: none;
    background: transparent;
    cursor: pointer;
}

    .cmp-incremental-search-icon-btn:hover {
        filter: brightness(0.9);
    }

.cmp-incremental-search-icon-img {
    width: 20px;
    height: 20px;
    display: block;
}
