:root {
    --color-primary: #4F46E5;
    --color-primary-hover: #4338CA;
    --color-gray-50: #F9FAFB;
    --color-gray-100: #F3F4F6;
    --color-gray-300: #D1D5DB;
    --color-gray-500: #6B7280;
    --color-gray-700: #374151;
    --color-gray-900: #111827;
    --card-radius: 8px;
    --card-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
    --font-family-base: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --border-strong: #D8DADF;
    --text-primary: var(--color-gray-900);
    --text-secondary: var(--color-gray-700);
    --text-muted: var(--color-gray-500);
    --color-primary-tint: #EEEDFE;
    --color-primary-dark: #3C3489;
    --surface-0: #F3F4F6;
    --surface-1: var(--color-gray-50);
    --surface-2: #fff;
    --border: var(--color-gray-100);
}

body {
    font-family: var(--font-family-base);
    background-color: var(--surface-0);
    color: var(--color-gray-900);
}

a {
    color: var(--color-primary);
}

a:hover {
    color: var(--color-primary-hover);
}

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

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

.card {
    background-color: #fff;
    border-radius: var(--card-radius);
    box-shadow: var(--card-shadow);
    padding: 16px;
    border: 0.5px solid var(--border-strong);
}

.app-header {
    display: flex;
    align-items: center;
    gap: 24px;
    background-color: #fff;
    border-bottom: 1px solid var(--color-gray-100);
    padding: 10px 24px;
}

.app-header-brand {
    font-size: 1.2em;
    font-weight: 700;
    color: var(--color-gray-900) !important;
    white-space: nowrap;
}

.app-header-search {
    position: relative;
    flex: 1 1 auto;
    max-width: 420px;
}

.app-header-search .fa-search {
    position: absolute;
    left: 12px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--color-gray-500);
}

.app-header-search input {
    padding-left: 34px;
    background-color: var(--color-gray-50);
    border-color: var(--color-gray-100);
}

.app-header-menu {
    display: flex;
    align-items: center;
    gap: 4px;
    list-style: none;
    margin: 0;
    padding: 0;
}

.app-header-menu > li {
    list-style: none;
}

.app-header-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
}

.panel.panel-default {
    border: 0.5px solid var(--border-strong);
    border-radius: var(--card-radius);
    box-shadow: var(--card-shadow);
}

.panel.panel-default > .panel-heading {
    background-color: #fff;
    border-bottom: 1px solid var(--color-gray-100);
    border-radius: var(--card-radius) var(--card-radius) 0 0;
    color: var(--color-gray-700);
    font-weight: 600;
}

.kpi-tile {
    background-color: #fff;
    border-radius: var(--card-radius);
    box-shadow: var(--card-shadow);
    border: 0.5px solid var(--border-strong);
    padding: 16px;
    margin-bottom: 16px;
}

.kpi-tile .kpi-value {
    font-size: 1.8em;
    font-weight: 700;
    color: var(--color-primary);
}

.kpi-tile .kpi-label {
    color: var(--color-gray-500);
    font-size: 0.9em;
}

.status-pill {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 999px;
    font-family: var(--font-family-base);
    font-size: 14px;
    font-weight: 500;
    line-height: 1.6;
}

.form-control,
select,
textarea {
    font-family: var(--font-family-base);
    font-size: 14px;
    font-weight: 400;
    line-height: 1.5;
}

.form-control {
    margin-bottom: 0px !important;
    border-radius: 6px;
    border: 0.5px solid var(--border-strong);
    box-shadow: var(--card-shadow);
}

.btn {
    border-radius: 6px;
}

.btn-default,
.btn-light {
    background-color: #fff;
    border-color: var(--color-gray-300);
    color: var(--color-gray-700);
}

.btn-default:hover,
.btn-light:hover {
    background-color: var(--color-gray-50);
    border-color: var(--color-gray-500);
}

/* Header dropdowns: Bootstrap's own JS is not loaded in this app (see
   main/directives.js appDropdown), so .dropdown-menu's .show toggle and the
   .dropdown.open state come from that directive instead of bootstrap.js -
   the position/display rules themselves are still bootstrap.css's defaults. */
.app-header .dropdown-menu {
    margin-top: 8px;
    min-width: 180px;
    padding: 6px;
    background-color: #fff;
    border: 0.5px solid var(--border-strong);
    border-radius: 10px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
}

.app-header .dropdown-menu li {
    list-style: none;
}

.app-header-menu .dropdown-toggle,
.app-header-actions .dropdown-toggle {
    font-family: var(--font-family-base);
    font-size: 14px;
    line-height: 1.5;
}

.app-header .dropdown-menu li > a {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 9px 10px;
    border-radius: 6px;
    color: var(--text-secondary);
    white-space: nowrap;
    font-family: var(--font-family-base);
    font-size: 14px;
    line-height: 1.5;
}

.app-header .dropdown-menu li > a i {
    color: var(--text-secondary);
    width: 16px;
    text-align: center;
    flex-shrink: 0;
}

.app-header .dropdown-menu li > a:hover,
.app-header .dropdown-menu li > a:focus {
    background-color: var(--color-primary-tint);
    color: var(--color-primary-dark);
    text-decoration: none;
}

.app-header .dropdown-menu li > a:hover i {
    color: var(--color-primary-dark);
}

.app-header .dropdown.open > .dropdown-toggle {
    color: var(--color-primary);
}

.app-header .dropdown.open > .dropdown-toggle::after {
    transform: rotate(180deg);
}

@media (max-width: 480px) {
    .app-header .dropdown-menu {
        min-width: 160px;
        max-width: calc(100vw - 24px);
    }

    .app-header .dropdown-menu li > a {
        white-space: normal;
    }
}

@media (max-width: 768px) {
    .app-header {
        flex-wrap: wrap;
        gap: 12px;
    }

    .app-header-search {
        order: 3;
        max-width: none;
        flex-basis: 100%;
    }

    .app-header-menu {
        flex-wrap: wrap;
    }
}

/* Two-column transfer list (Available / Assigned pickers) */
.list-group.left,
.list-group.right {
    border: 0.5px solid var(--border-strong);
    border-radius: var(--card-radius);
    box-shadow: var(--card-shadow);
    overflow: hidden;
}

.list-group.left input.form-control,
.list-group.right input.form-control {
    border-radius: 0;
    border: none;
    border-bottom: 1px solid var(--color-gray-100);
}

.list-group.left .list-group-item.active,
.list-group.right .list-group-item.active {
    background-color: var(--color-gray-50);
    border-color: var(--color-gray-100);
    color: var(--color-gray-700);
    font-weight: 500;
}

.list-group.left .list-group-item.animation,
.list-group.right .list-group-item.animation {
    cursor: pointer;
    border-left: none;
    border-right: none;
}

.list-group.left .list-group-item.animation:hover,
.list-group.right .list-group-item.animation:hover {
    background-color: var(--color-gray-50);
}

/* Report / action panels (e.g. Attachment Report, Generate Issues) */
#attachment_report_form {
    background-color: #fff;
    border: 0.5px solid var(--border-strong);
    border-radius: var(--card-radius);
    box-shadow: var(--card-shadow);
    padding: 16px;
    align-items: center;
    gap: 12px;
}

.tab-content form {
    margin-bottom: 0px !important;
}

/* Project/screen tabs (ui-bootstrap 0.13.0 <tabset>). This version renders
   Bootstrap 3-style markup (<li class="active"><a>, no nav-item/nav-link
   classes), which bootstrap.css v4's .nav-tabs .nav-link selectors don't
   match at all - hence zero spacing/padding without these, tabs collapse
   into unreadable run-together text. Targets the actual rendered structure
   directly rather than the classes v4 expects. */
.nav-tabs {
    margin-bottom: 16px;
    background-color: var(--color-gray-100);
    border-bottom: 1px solid var(--color-gray-100);
    border-radius: 6px 6px 0 0;
    padding: 4px 4px 0;
}

.nav-tabs > li {
    display: inline-block;
    margin-right: 4px;
    margin-bottom: -1px;
}

.nav-tabs > li > a {
    display: block;
    padding: 10px 16px;
    border: 1px solid transparent;
    border-radius: 6px 6px 0 0;
    color: var(--color-gray-700);
    text-decoration: none;
    font-family: var(--font-family-base);
    font-size: 14px;
    line-height: 1.5;
}

/* Active tab needs to read as clearly "lifted" off the gray tab bar - a
   plain white bg on a near-white bar (the old --color-gray-100 tab bar) was
   nearly indistinguishable. Real border + a 2px accent underline. */
.nav-tabs > li.active > a {
    color: var(--color-primary);
    border: 1px solid var(--color-gray-300);
    border-bottom: 2px solid var(--color-primary);
    background-color: #fff;
    font-weight: 600;
    margin-bottom: -2px;
}

.nav-tabs > li > a:hover {
    background-color: rgba(255, 255, 255, 0.6);
}

/* New Issue / Add from Template used to sit in their own row between the
   tabs and the grid - now floated into the same row as the tab bar itself
   (ui-bootstrap's <tabset> has no slot for trailing actions, so this is
   positioned over it rather than being a real sibling in that row). Only
   shown while the Issue List tab is active (see project.html's "active"
   binding on that <tab>), matching where these actions actually apply. */
.project-tabs-row {
    position: relative;
}

.project-tabs-actions {
    position: absolute;
    top: 4px;
    right: 0;
    display: flex;
    align-items: center;
    gap: 8px;
}

@media (max-width: 768px) {
    /* At narrow widths the nav-tabs bar itself wraps onto multiple lines
       (5 tabs don't fit on one row), so absolutely-positioning the actions
       over "where the tab row is" no longer has a single row to align to -
       they'd overlap and hide whichever tabs land underneath them. Drop
       back into normal flow, stacked below the tabs instead. */
    .project-tabs-actions {
        position: static;
        margin-top: 8px;
        flex-wrap: wrap;
    }
}

/* Issue List grid: fills the remaining screen space below the title/tabs
   and scrolls internally (sticky <thead>, see .issue-table th) instead of
   growing the page - same pattern as the project grid's
   .project-grid-scroll, but sized to fill the rest of the viewport rather
   than a fixed 60% since there's no sibling content below it to protect. */
.issue-list-scroll {
    max-height: calc(100vh - 260px);
    overflow-y: auto;
    background-color: #fff;
    border: 0.5px solid var(--border-strong);
    border-radius: var(--card-radius);
    box-shadow: var(--card-shadow);
}

/* Destructive action (e.g. Remove/Delete) - red outline, not solid, so it
   doesn't visually compete with the primary Save action */
.btn-danger {
    background-color: #fff;
    border-color: #DC2626;
    color: #DC2626;
}

.btn-danger:hover,
.btn-danger:focus {
    background-color: #DC2626;
    border-color: #DC2626;
    color: #fff;
}

/* Location bar: persistent "where am I" strip below the main header,
   replaces the old two-item <ol class="breadcrumb"> */
.location-bar {
    background-color: var(--color-gray-50);
    border-bottom: 1px solid var(--color-gray-100);
    padding: 10px 24px;
    font-size: 0.95em;
}

.location-bar-title {
    font-weight: 600;
    color: var(--color-primary);
}

.location-bar-subtitle {
    color: var(--color-gray-500);
    margin-left: 4px;
}

/* Responsive grid for breakdown cards: naturally settles into 2-3 columns
   on desktop, 1 on narrow screens, no explicit per-breakpoint classes needed */
.breakdown-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 16px;
    margin-bottom: 24px;
}

/* Shared breakdown card (dashboard "By X" panels) */
.breakdown-card {
    margin-bottom: 16px;
}

.breakdown-card-header {
    font-size: 14px;
    font-weight: 500;
    color: var(--color-gray-700);
    margin-bottom: 4px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--color-gray-100);
}

/* Real data can have dozens of distinct assignees/reporters/due-dates -
   without a cap, those cards stretch far taller than their siblings and
   break the grid's rhythm (confirmed against production: 4000+ issues,
   30+ distinct assignees). Scroll internally instead of hiding data. */
.breakdown-card-body {
    max-height: 320px;
    overflow-y: auto;
}

.breakdown-row {
    cursor: pointer;
    padding: 6px 0;
}

.breakdown-row-top {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 4px;
}

.breakdown-name {
    color: var(--color-gray-900);
    font-size: 13.2px;
}

/* Status-colored label inside a breakdown row - shrunk 2px alongside
   .breakdown-name/.breakdown-percent, scoped here so it doesn't affect
   .status-pill's other uses (Issue List priority pill, etc). */
.breakdown-row .status-pill {
    font-size: 12px;
}

.breakdown-count {
    color: var(--color-gray-500);
    font-size: 0.9em;
    font-weight: 600;
}

.breakdown-bar-track {
    background-color: var(--color-gray-100);
    border-radius: 999px;
    height: 6px;
    overflow: hidden;
}

.breakdown-bar-fill {
    background-color: var(--color-primary);
    height: 100%;
    border-radius: 999px;
    width: 0;
    transition: width 0.9s ease;
}

.breakdown-percent {
    font-size: 10.8px;
    color: var(--color-gray-500);
    text-align: right;
    margin-top: 2px;
}

.breakdown-empty {
    color: var(--color-gray-500);
    font-size: 0.9em;
}

/* "Mis proyectos" home dashboard */
/* Nav->title gap was 0 (container-fluid has no vertical padding, and
   .dashboard-top-row h4's own margin is zeroed for its flex-row
   alignment) while title->grid was 16px via .dashboard-top-row's
   margin-bottom - matches that same 16px above, for both the admin
   (.dashboard-top-row) and non-admin (.dashboard-subtitle first) variants
   of this page. */
.dashboard-page {
    margin-top: 16px;
}

.dashboard-top-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 16px;
    gap: 16px;
    flex-wrap: wrap;
}

.dashboard-top-row h4 {
    margin: 0;
    font-size: 24px;
    font-weight: 600;
    color: var(--color-gray-900);
}

.dashboard-subtitle {
    font-size: 12px;
    font-weight: 500;
    color: var(--color-primary);
    margin-top: 4px;
}

.dashboard-top-row-kpis {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
}

.kpi-tile-compact {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-bottom: 0;
    padding: 12px 20px;
}

.kpi-tile-compact .fa {
    font-size: 1.6em;
    color: var(--color-primary);
}

.kpi-tile-compact .kpi-value {
    font-size: 1.6em;
}

/* Section headers grouping several breakdown cards (non-admin dashboard:
   "Assigned to me" / "Reported by me") - H2 per heading scale. */
.page-header h5 {
    font-size: 18px;
    font-weight: 600;
    margin-top: 0;
    margin-bottom: 6px;
    color: var(--color-gray-900);
}

/* Accent tone given specifically for this dashboard's KPI numbers/icons -
   scoped here rather than changed on the shared --color-primary token, so
   it doesn't drift every other primary-colored element in the app. */
.dashboard-top-row-kpis .kpi-value,
.dashboard-top-row-kpis .fa {
    color: #534AB7;
}

/* Project grid: shared by "/" and "/projects" (both routed to the same
   IndexController/main.html - see app.js), replacing what used to be two
   separate implementations (a horizontal-scroll card strip here, and a
   full table at /projects). */
.project-grid-card {
    padding: 0;
    margin-bottom: 16px;
    overflow: hidden;
}

.project-grid-toolbar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px;
    border-bottom: 1px solid var(--border);
}

.project-grid-toolbar .form-control {
    flex: 1 1 auto;
    max-width: 320px;
}

.project-grid-toolbar .btn {
    margin-left: auto;
}

/* Grid rows scroll internally past ~60% of viewport height instead of
   growing the whole page - keeps the breakdown cards below always
   reachable without a full-page scroll regardless of project count. The
   toolbar (search/New Project) stays outside this wrapper, always visible. */
.project-grid-scroll {
    max-height: 60vh;
    overflow-y: auto;
}

.project-grid-table {
    table-layout: fixed;
    width: 100%;
}

.project-grid-table thead th {
    background-color: var(--surface-1);
    position: sticky;
    top: 0;
    z-index: 1;
}

.project-grid-table tbody tr {
    cursor: pointer;
}

.project-grid-table td,
.project-grid-table th {
    border-bottom: 0.5px solid var(--border);
}

.project-grid-table th.project-grid-name-col,
.project-grid-table td:first-child {
    width: 34%;
}

.project-grid-table th:nth-child(2),
.project-grid-table td:nth-child(2) {
    width: 14%;
}

.project-grid-table th:nth-child(3),
.project-grid-table td:nth-child(3) {
    width: 16%;
}

.project-grid-table th:nth-child(4),
.project-grid-table td:nth-child(4) {
    width: 6%;
}

.project-grid-table th:nth-child(5),
.project-grid-table td:nth-child(5) {
    width: 12%;
}

.project-grid-table th:nth-child(6),
.project-grid-table td:nth-child(6) {
    width: 18%;
}

.project-grid-recent-label {
    font-size: 0.75em;
    font-weight: 500;
    color: var(--color-primary);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    margin-bottom: 2px;
}

.project-grid-name {
    display: block;
    font-weight: 600;
    color: #534AB7;
    word-break: break-word;
    white-space: normal;
}

.project-grid-table tbody tr:hover .project-grid-name {
    text-decoration: underline;
}

.project-grid-progress-cell {
    min-width: 100px;
}

.project-progress-track {
    background-color: var(--color-gray-100);
    border-radius: 999px;
    height: 6px;
    overflow: hidden;
}

.project-progress-fill {
    height: 100%;
    border-radius: 999px;
    width: 0;
    transition: width 0.9s ease;
}

.project-progress-percent {
    font-size: 0.8em;
    color: var(--color-gray-500);
    margin-top: 2px;
}

.breakdown-grid-5 {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 16px;
    margin-bottom: 16px;
}

@media (max-width: 1200px) {
    .breakdown-grid-5 {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (max-width: 768px) {
    .breakdown-grid-5 {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 480px) {
    .breakdown-grid-5 {
        grid-template-columns: 1fr;
    }
}

.breakdown-card.dense .breakdown-card-body {
    columns: 2;
    column-gap: 24px;
}

.breakdown-card.dense .breakdown-row {
    break-inside: avoid;
}

@media (max-width: 768px) {
    .breakdown-card.dense .breakdown-card-body {
        columns: 1;
    }
}

.kpi-tile.kpi-tile-lg .kpi-value {
    font-size: 2.6em;
}

/* Login / password recovery hero page */
.auth-page {
    position: fixed;
    inset: 0;
    background: linear-gradient(135deg, var(--color-primary) 0%, var(--color-primary-hover) 100%);
    display: flex;
    flex-direction: column;
    z-index: 10;
    overflow-y: auto;
}

.auth-page-topbar {
    background-color: #fff;
    padding: 14px 24px;
    font-weight: 700;
    font-size: 1.2em;
    color: var(--color-gray-900);
}

.auth-page-content {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}

.auth-card {
    background-color: #fff;
    border-radius: var(--card-radius);
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
    padding: 40px;
    width: 100%;
    max-width: 400px;
}

.auth-card-title {
    margin: 0 0 6px;
    text-align: center;
    color: var(--color-gray-900);
    font-size: 18px;
    font-weight: 600;
}

.auth-card .btn-pill {
    border-radius: 999px;
    padding: 10px 24px;
    font-weight: 600;
}

.auth-card-footer-link {
    text-align: center;
    margin-top: 16px;
}

@media (max-width: 480px) {
    .auth-card {
        padding: 28px 24px;
    }
}

/* Custom modal (not Bootstrap's .modal JS plugin - that plugin's script is
   not loaded in this app, so $(...).modal("show") throws a hard error; this
   was discovered broken on Catalog > Workflows' status/step dialogs while
   building this one, and fixed there too using the same pattern). Plain
   ng-show + a backdrop click/Escape handler (see closeOnEscape directive). */
.app-modal-backdrop {
    position: fixed;
    inset: 0;
    background-color: rgba(17, 24, 39, 0.5);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 40px 16px;
    overflow-y: auto;
    z-index: 1050;
}

.app-modal-backdrop .modal-dialog {
    margin: 0;
    width: 100%;
}

.app-modal-backdrop .modal-dialog.large {
    max-width: 900px;
}

.app-modal-backdrop .modal-content {
    border: 0.5px solid var(--border-strong);
    border-radius: var(--card-radius);
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.25);
}

/* Custom modal titles (shared by every ng-show modal built on this
   component - project data, template select, workflow status/step, change
   password) - H2 per heading scale. margin:0 kept (not the table's 6px)
   since the title sits in a flex row beside the close button; a
   margin-bottom there would only add slack under the row, not real spacing
   before stacked content. */
.modal-header h1,
.modal-header h2,
.modal-header h3,
.modal-header h4,
.modal-header h5,
.modal-header h6 {
    font-size: 18px;
    font-weight: 600;
    margin: 0;
    color: var(--color-gray-900);
}

.app-modal-close {
    background: none;
    border: none;
    font-size: 1.4em;
    line-height: 1;
    color: var(--color-gray-500);
    cursor: pointer;
    padding: 0;
}

.app-modal-close:hover {
    color: var(--color-gray-900);
}

/* Project title button, above the tab bar, opens the project-data modal */
/* Screen-level horizontal margin - was flush against the viewport edges
   before (only container-fluid's 15px), matches the header's 24px. */
.project-screen {
    padding: 0 24px;
}

.project-title-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 8px;
}

.project-title-badges {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.project-count-badge {
    background-color: var(--surface-1);
    border-radius: var(--card-radius);
    padding: 6px 12px;
    font-size: 0.85em;
}

.project-count-badge-label {
    color: var(--text-secondary);
}

.project-count-badge-value {
    color: var(--color-gray-900);
    font-weight: 700;
}

.project-title-button {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: none;
    border: none;
    padding: 8px 0;
    margin-bottom: 0;
    font-size: 24px;
    font-weight: 600;
    color: #534AB7;
    cursor: pointer;
}

/* "Project Users" - a card title within the Users tab, H3 per heading scale.
   Scoped to project.html's specific panel-heading, not the generic
   .panel-heading h4 pattern reused by unrelated (out-of-scope) catalog
   screens. */
.project-screen .panel-heading h4 {
    font-size: 14px;
    font-weight: 500;
    margin-top: 0;
    margin-bottom: 4px;
    color: var(--color-gray-700);
}

.project-title-button:hover {
    color: var(--color-primary-dark);
}

.project-title-button .fa-folder-open {
    color: #534AB7;
}

.project-title-button .fa-chevron-down {
    font-size: 0.7em;
    color: var(--color-gray-500);
}

/* Issue List: grouped-by-status table. Used to be one <table> per group
   (each with its own <thead>), wrapped in an .issue-group div for the
   colored left border - rebuilt as a single table (one sticky <thead>,
   one <tbody> per group) so there's exactly one persistent column header
   instead of one per group scrolling past with the rows. */
.issue-group-header-row td {
    border-left: 3px solid var(--color-gray-300);
    padding: 10px 16px;
    font-family: var(--font-family-base);
    font-size: 14px;
    font-weight: 500;
    color: var(--color-gray-700);
    background-color: var(--color-gray-50);
}

.issue-group-count {
    color: var(--color-gray-500);
    font-weight: 400;
    font-size: 0.9em;
}

.issue-table {
    width: 100%;
    border-collapse: collapse;
}

.issue-table th {
    text-align: left;
    padding: 8px 16px;
    font-family: var(--font-family-base);
    font-size: 14px;
    line-height: 1.5;
    color: var(--color-gray-500);
    background-color: var(--surface-1);
    border-bottom: 1px solid var(--color-gray-100);
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
    position: sticky;
    top: 0;
    z-index: 1;
}

.issue-table th:hover {
    color: var(--color-gray-900);
}

.issue-table th .fa {
    margin-left: 4px;
    font-size: 0.9em;
}

.issue-table td {
    padding: 8px 16px;
    border-bottom: 1px solid var(--color-gray-100);
    font-family: var(--font-family-base);
    font-size: 14px;
    line-height: 1.5;
    vertical-align: middle;
}

.issue-table tbody tr:last-child td {
    border-bottom: none;
}

.issue-table tbody tr:hover {
    background-color: var(--color-gray-50);
}

.issue-key-badge {
    display: inline-block;
    background-color: var(--color-gray-100);
    color: var(--color-gray-700);
    border-radius: 4px;
    padding: 1px 7px;
    font-family: var(--font-family-base);
    font-size: 14px;
    font-weight: 500;
}

.issue-name-resolved {
    text-decoration: line-through;
    color: var(--color-gray-500);
}

/* Issue Tree View */
.issue-tree-node {
    position: relative;
    padding-left: 20px;
    border-left: 1px solid var(--color-gray-300);
    margin-left: 6px;
}

.issue-tree-node:last-child {
    border-left: 1px solid transparent;
}

.issue-tree-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 0;
}

.issue-tree-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex: 0 0 auto;
}

.issue-tree-name {
    flex: 1 1 auto;
}

.issue-tree-name.resolved {
    text-decoration: line-through;
    color: var(--color-gray-500);
}

.issue-tree-children {
    margin-top: 2px;
}

/* Due-date indicator (shared between Issue List and Issue Tree View) */
.due-indicator {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    flex: 0 0 auto;
    font-size: 0.75em;
    color: #fff;
}

.due-indicator.due-ontime {
    background-color: #059669;
}

.due-indicator.due-risk {
    background-color: #D97706;
}

.due-indicator.due-overdue {
    background-color: #DC2626;
}

.issue-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    padding: 12px 16px;
    background-color: #fff;
    border: 0.5px solid var(--border-strong);
    border-radius: var(--card-radius);
    box-shadow: var(--card-shadow);
    font-size: 0.85em;
    color: var(--color-gray-700);
    margin-bottom: 16px;
}

.issue-legend-item {
    display: flex;
    align-items: center;
    gap: 6px;
}

@media (max-width: 768px) {
    .issue-table {
        display: block;
        overflow-x: auto;
        white-space: nowrap;
    }
}

/* Cross-project issue list (/issue/issues/list) - reached from dashboard
   breakdown-card rows. Same .issue-table typography/padding as the
   in-project Issue List, but a lighter surface-2/border container (not
   the border-strong elevation used for the other white cards) and grouped
   by project instead of status. */
.global-issue-list-scroll {
    max-height: calc(100vh - 220px);
    overflow-y: auto;
    background-color: var(--surface-2);
    border: 0.5px solid var(--border);
    border-radius: 12px;
}

/* Project group header - same structure as the status group header
   (.issue-group-header-row), but the left border is the system accent
   color rather than a per-status color, since a project has no color of
   its own to draw from. */
.global-issue-list-scroll .issue-group-header-row td {
    border-left-color: #534AB7;
}

.project-group-name {
    color: #534AB7;
}

.project-group-header-row .fa-folder-open {
    color: #534AB7;
    margin-right: 4px;
}

/* Subtask row: indented via padding-left (level * 20px, set inline per
   row) with a corner-arrow icon flagging it as a child of another issue
   in the same project group - whether or not that parent is itself
   visible in this filtered result set. */
.issue-task-cell {
    display: flex;
    align-items: center;
    gap: 6px;
}

.issue-child-icon {
    color: var(--color-gray-500);
    font-size: 0.85em;
    flex-shrink: 0;
}

/* Issue Edit - overlaid panel ("ficha superpuesta"). Reuses the same
   .app-modal-backdrop scrim as every other custom modal in this app
   (project data, template select, workflow status/step) for consistency -
   only the panel itself (.issue-edit-panel) gets this screen's own
   larger radius/shadow, since it reads as a distinct overlaid screen
   rather than a small dialog. */
.app-modal-backdrop .modal-dialog.issue-edit-panel {
    max-width: 980px;
}

.issue-edit-panel .modal-content {
    border-radius: 16px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
}

.issue-edit-panel .btn {
    font-family: var(--font-family-base);
    font-size: 14px;
}

.issue-edit-panel label {
    font-size: 12px;
    font-weight: 500;
    color: var(--text-secondary);
    margin-bottom: 4px;
}

.issue-edit-header {
    padding: 20px 24px 0;
}

.issue-edit-header-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
}

/* Parent chain: Project -> ... -> current task. Every segment but the
   last is a link in the system accent color; the current task is plain
   --text-primary, no link, to mark "you are here". */
.issue-breadcrumb {
    font-size: 12px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-bottom: 4px;
}

.issue-breadcrumb a {
    color: #534AB7;
}

.issue-breadcrumb .fa-chevron-right {
    font-size: 0.75em;
    color: var(--color-gray-300);
}

.issue-breadcrumb-current {
    color: var(--text-primary);
}

.issue-edit-title {
    font-size: 18px;
    font-weight: 600;
    color: var(--text-primary);
    margin: 0 0 16px;
}

/* Tabs + action bar share one row - reuses .project-tabs-row/
   .project-tabs-actions verbatim (same position:absolute-over-the-tab-bar
   trick already established for New Issue/Add from Template on the
   project screen) rather than duplicating the pattern under a new name.
   Only the horizontal padding (borrowed from .project-screen there, which
   doesn't exist in this overlaid panel) and the pill shape for this row's
   specific buttons are scoped locally. */
.issue-edit-panel .project-tabs-row,
.user-edit-panel .project-tabs-row {
    padding: 0 24px;
}

/* Base .nav-tabs/.project-tabs-actions (shared with project.html) size
   themselves from padding/line-height rather than a fixed row height, so
   the absolutely-positioned actions only land close to the tab bar, not
   perfectly centered on it. Scoped here to a real 44px band shared by
   both the tabs and the actions so every element in the row centers on
   the same line, without touching the shared base rules project.html
   still relies on. Also gets its own surface-1 background so tabs and
   actions read as sitting inside one contained bar. Also used by
   .user-edit-panel (no action bar there, just the tab row itself). */
.issue-edit-panel .nav-tabs,
.user-edit-panel .nav-tabs {
    height: 44px;
    display: flex;
    align-items: stretch;
    background-color: var(--surface-1);
    border-bottom: none;
    border-radius: var(--card-radius) var(--card-radius) 0 0;
    padding: 0 14px;
}

.issue-edit-panel .nav-tabs > li,
.user-edit-panel .nav-tabs > li {
    display: flex;
    align-items: center;
    margin-bottom: 0;
}

.issue-edit-panel .nav-tabs > li > a,
.user-edit-panel .nav-tabs > li > a {
    display: flex;
    align-items: center;
    height: 100%;
    padding: 0 16px;
}

.issue-edit-panel .nav-tabs > li.active > a,
.user-edit-panel .nav-tabs > li.active > a {
    margin-bottom: 0;
}

/* height:44px only while the actions bar shares the row with the tabs
   (position:absolute, desktop) - below 768px the base rule in
   .project-tabs-actions drops to position:static + flex-wrap so its 5
   buttons can wrap onto a second line; a fixed height there would clip
   that second line.

   right:38px (not the base rule's right:0) because an absolutely
   positioned element's containing block is its ancestor's padding edge,
   which ignores that ancestor's own padding - right:0 here would put
   the buttons flush with .project-tabs-row's outer edge, 24px past
   where .nav-tabs's own background actually ends (its 24px row padding)
   plus its 14px internal padding, i.e. spilling out of the visible bar
   entirely. 38px = 24 + 14 lines the actions back up with .nav-tabs's
   own padded content edge, matching the tabs' left inset on the other
   side. Confirmed by measuring both edges in a harness. */
@media (min-width: 769px) {
    .issue-edit-panel .project-tabs-actions {
        top: 0;
        right: 38px;
        height: 44px;
    }
}

.issue-edit-panel .project-tabs-actions .btn-pill {
    border-radius: 999px;
}

.issue-edit-body {
    padding: 16px 24px 24px;
}

/* The 820px panel is narrower than this form's old full-page container,
   so the narrow date/status columns (col-md-2) are tight enough that a
   DD-MM-YYYY HH:mm value or a longer status name wraps and collides with
   the row below. Truncate read-only field values instead of wrapping -
   inputs/selects/textareas are unaffected. */
.issue-edit-body span.form-control {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Project/Created/Status row: Project has no natural max length (project
   names vary a lot) so it gets the flexible remaining space, while
   Created/Status are fixed-format values (a date, a short status name)
   that only need a compact, right-aligned column instead of matching
   Project's width. Not a .row/.col-md-* grid - flex directly, since the
   three no longer share equal-ish widths. */
.issue-row-project-status {
    display: flex;
    align-items: flex-start;
    gap: 16px;
}

.issue-field-project {
    flex: 1 1 auto;
    min-width: 0;
}

.issue-field-created {
    flex: 0 0 170px;
    text-align: right;
}

.issue-field-status {
    flex: 0 0 130px;
    text-align: right;
}

/* Resolved isn't in the approved mockup's 3-field row (it's usually
   hidden - only shown once item.resolvedDate is set), but needs to live
   somewhere in this row now that it's flex instead of a 12-col grid.
   Kept as a 4th compact right-aligned column matching Created/Status'
   treatment for visual consistency rather than left on the old grid. */
.issue-field-resolved {
    flex: 0 0 150px;
    text-align: right;
}

/* Unlike the rest of this form (bootstrap col-md-* collapses to
   full-width/stacked below 768px automatically), this row's fixed pixel
   widths don't have that built in - Created(170)+Status(130)+gaps(32)
   alone already exceeds a 375px viewport's content width, squeezing
   Project to nothing and clipping Status off-screen. Stack all fields
   full-width like their siblings once the fixed widths no longer fit. */
@media (max-width: 768px) {
    .issue-row-project-status {
        flex-wrap: wrap;
        gap: 0;
    }

    .issue-field-project,
    .issue-field-created,
    .issue-field-status,
    .issue-field-resolved {
        flex: 1 1 100%;
        text-align: left;
    }
}

/* Attachments/Subtasks subsections - same surface-1 fill + radius/padding
   used elsewhere for a "recessed" content block, header+action button(s)
   on one row matching .breakdown-card-header's H3 treatment (14px/500). */
.issue-subsection {
    margin-top: 0;
    margin-bottom: 16px;
}

/* Separates the task-data block from Attachments, and Attachments from
   Subtasks, so the three no longer read as one continuous block. 20px on
   both sides (not just top) - a top-only margin left "Upload Files" /
   "Add Subtask" sitting right under the line with no breathing room,
   since .issue-subsection-header itself has no top spacing of its own. */
.issue-divider {
    border: none;
    border-top: 0.5px solid var(--border-strong);
    margin: 20px 0;
}

.issue-subsection-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    font-size: 14px;
    font-weight: 500;
    color: var(--color-gray-700);
    margin-bottom: 4px;
}

.issue-subsection-actions {
    display: flex;
    align-items: center;
    gap: 8px;
}

.issue-subsection-body {
    background-color: var(--surface-1);
    border-radius: var(--card-radius);
    padding: 16px;
}

.issue-subsection-empty {
    font-size: 12px;
    color: var(--text-muted);
}

/* User detail panel - same overlay pattern as .issue-edit-panel (see
   .app-modal-backdrop above). Widened from the original 620px (right for
   a flat single-tab form) to match Issue Edit's ~980px once the Groups/
   Assigned/Reported/Reviewer/Checker Issues tabs came back - those need
   real table width, and the tab bar itself matches Issue Edit's
   treatment (see .user-edit-panel .nav-tabs below), so the panel should
   read as the same class of screen. */
.app-modal-backdrop .modal-dialog.user-edit-panel {
    max-width: 980px;
}

.user-edit-panel .modal-content {
    border-radius: 16px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
}

.user-edit-panel .btn {
    font-family: var(--font-family-base);
    font-size: 14px;
}

.user-edit-panel label {
    font-size: 12px;
    font-weight: 500;
    color: var(--text-secondary);
    margin-bottom: 4px;
}

.user-edit-header {
    padding: 20px 24px 0;
}

.user-edit-title {
    font-size: 18px;
    font-weight: 600;
    color: var(--text-primary);
    margin: 0 0 16px;
}

.user-edit-body {
    padding: 16px 24px 24px;
}

.user-edit-readonly {
    font-size: 14px;
    color: var(--color-gray-700);
    padding: 6px 0;
}

.user-edit-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
    flex-wrap: wrap;
}

.user-edit-actions .btn-danger {
    margin-right: auto;
}

/* Shared boolean switch - used for Active/Is system administrator/Email
   notifications/Notify its own changes, all four identical. A styled
   checkbox rather than a custom directive/component, since this is the
   first toggle in the app (no prior pattern to match - see the
   research note in the redesign prompt) and a bare <input type=checkbox>
   wrapped in a label is the simplest way to keep it a real, accessible,
   ng-model-bindable form control. */
.toggle-switch {
    position: relative;
    display: inline-flex;
    align-items: center;
    width: 36px;
    height: 20px;
    flex: 0 0 auto;
}

.toggle-switch input {
    position: absolute;
    opacity: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    cursor: pointer;
}

.toggle-switch-track {
    position: absolute;
    inset: 0;
    background-color: var(--surface-1);
    border: 0.5px solid var(--border-strong);
    border-radius: 999px;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

.toggle-switch-track::before {
    content: '';
    position: absolute;
    top: 1px;
    left: 1px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background-color: #fff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
    transition: transform 0.15s ease;
}

.toggle-switch input:checked ~ .toggle-switch-track {
    background-color: #639922;
    border-color: #639922;
}

.toggle-switch input:checked ~ .toggle-switch-track::before {
    transform: translateX(16px);
}

.toggle-switch input:focus-visible ~ .toggle-switch-track {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

.user-toggle-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 0;
    border-bottom: 1px solid var(--color-gray-100);
}

.user-toggle-row:last-child {
    border-bottom: none;
}

.user-toggle-label {
    font-size: 14px;
    color: var(--color-gray-900);
}

/* Active pill in the User List grid - a real <button>, not just a
   .status-pill span, since it toggles on click without opening the
   detail panel. */
.user-active-toggle {
    border: none;
    cursor: pointer;
    font-family: var(--font-family-base);
}

/* Groups tab - restored dual add/remove list, same
   .issue-subsection-header/-body/-empty surface-1 card treatment already
   used for Attachments/Subtasks in Issue Edit, instead of the old bare
   Bootstrap .list-group styling. */
.user-groups-columns {
    display: flex;
    gap: 16px;
}

.user-groups-col {
    flex: 1 1 0;
    min-width: 0;
}

.user-groups-list {
    max-height: 320px;
    overflow-y: auto;
    padding: 8px;
}

.user-groups-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 8px 10px;
    border-radius: 6px;
    font-size: 14px;
    color: var(--color-gray-900);
    cursor: pointer;
}

.user-groups-item:hover {
    background-color: var(--color-gray-100);
}

.user-groups-item .fa {
    color: var(--color-gray-400);
    font-size: 0.85em;
}

@media (max-width: 480px) {
    .user-groups-columns {
        flex-direction: column;
    }
}

/* 6 tabs (Details/Groups/4 issue lists) don't fit on one 44px-tall row
   below tablet width - they wrap, but the fixed height didn't grow with
   them, so wrapped tabs overlapped the tab content underneath. Issue
   Edit never needed this fallback (only 2 tabs, never wraps even at
   375px) - .user-edit-panel needs its own. */
@media (max-width: 768px) {
    .user-edit-panel .nav-tabs {
        height: auto;
        flex-wrap: wrap;
        padding: 4px 14px;
    }
    .user-edit-panel .nav-tabs > li > a {
        height: auto;
        padding: 8px 16px;
    }
}

@media (max-width: 480px) {
    .user-edit-header,
    .user-edit-body {
        padding-left: 16px;
        padding-right: 16px;
    }
    .user-edit-panel .project-tabs-row {
        padding-left: 16px;
        padding-right: 16px;
    }
}

@media (max-width: 480px) {
    .issue-edit-header,
    .issue-edit-body {
        padding-left: 16px;
        padding-right: 16px;
    }
    .issue-edit-panel .project-tabs-row {
        padding-left: 16px;
        padding-right: 16px;
    }
}
