/* ============================================
   site.css - Global Styles
   ============================================
   NOTE: Navbar/Layout styles are in MainLayout.razor.css
   This file contains only non-layout global styles
   ============================================ */

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
    background: var(--color-background, #fafbfc);
    color: var(--color-text-primary, #24292e);
}


/* ==========================================
   CONTAINER & PAGE LAYOUT
   ========================================== */
.container {
    max-width: 1440px;
    margin: 0 auto;
    padding: 24px;
}

/* Wide variant — used on pages whose primary content is a dense table.
   Removes the 1440px cap so the table can use the full viewport width,
   minus the global sidebar. Apply by stacking the class:
       <div class="container container-wide">
   so any rule scoped to .container still matches. Padding stays the same
   so cards/headers still have a comfortable inset. */
.container.container-wide {
    max-width: none;
}

.page-header {
    margin-bottom: 24px;
}

.page-title {
    font-size: 24px;
    font-weight: 600;
    color: var(--color-text-primary, #24292e);
    margin-bottom: 4px;
}

.page-subtitle {
    font-size: 14px;
    color: var(--color-text-secondary, #586069);
}

/* ==========================================
   STATS GRID
   ========================================== */
.stats-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 16px;
    margin-bottom: 24px;
}

.stat-card {
    background: var(--color-surface, white);
    border: 1px solid var(--color-border, #e1e4e8);
    border-radius: 6px;
    padding: 20px;
    transition: box-shadow 0.2s;
    cursor: pointer;
}

    .stat-card:hover {
        box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.08);
    }

.stat-label {
    font-size: 12px;
    color: var(--color-text-secondary, #586069);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-bottom: 8px;
}

.stat-value {
    font-size: 32px;
    font-weight: 700;
    color: var(--color-text-primary, #24292e);
}

/* ==========================================
   CONTENT SECTIONS
   ========================================== */
.content-section {
    background: var(--color-surface, white);
    border: 1px solid var(--color-border, #e1e4e8);
    border-radius: 6px;
}

.section-header {
    padding: 16px 20px;
    border-bottom: 1px solid var(--color-border, #e1e4e8);
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.section-title {
    font-size: 16px;
    font-weight: 600;
    color: var(--color-text-primary, #24292e);
}

/* ==========================================
   DATA TABLES
   ========================================== */
.data-table {
    width: 100%;
    border-collapse: collapse;
}

    .data-table thead th {
        background: var(--color-background, #fafbfc);
        padding: 12px 20px;
        text-align: left;
        font-size: 12px;
        font-weight: 600;
        color: var(--color-text-secondary, #586069);
        text-transform: uppercase;
        letter-spacing: 0.5px;
        border-bottom: 1px solid var(--color-border, #e1e4e8);
    }

    .data-table tbody td {
        padding: 16px 20px;
        border-bottom: 1px solid var(--color-border, #e1e4e8);
        font-size: 14px;
    }

    .data-table tbody tr {
        transition: background 0.2s;
        cursor: pointer;
    }

        .data-table tbody tr:hover {
            background: var(--color-gray-100, #f6f8fa);
        }

.ticket-id {
    font-family: 'Consolas', 'Monaco', monospace;
    color: var(--color-primary, #0366d6);
    font-weight: 600;
    font-size: 13px;
}

/* ==========================================
   DATA TABLE — horizontal scroll + min-widths
   ==========================================
   Wraps wide tables so they overflow horizontally instead of squishing
   columns. The wrapper is the scroll context; the table inside it
   keeps its normal layout. min-widths per-column live below — set on
   the <th data-col-key="..."> so default table-layout propagates the
   width to the body cells without us touching every row.

   Min-widths chosen by content shape:
     id      → 90px   (TKT-00000 monospace number pill)
     title   → 220px  (longest readable cell)
     chip    → 100px  (Type / Status / Priority / Module / Version)
     name    → 140px  (Assignee / CreatedBy / ReportedBy)
     time    → 110px  (Created / Updated / Due / DevDue / Resolved)
     number  → 90px   (Hours / Comments / Attachments counts)
     bool    → 70px   (ReleaseNotes / Highlighted toggle icons)
*/
.data-table-scroll {
    overflow-x: auto;
    overflow-y: visible;
    width: 100%;
    /* Auto-hide scrollbar: the thumb is invisible until you hover the table,
       then it fades in. The track space stays reserved (thin / 10px) so content
       never shifts when it appears — only the thumb's colour changes. Firefox
       uses scrollbar-color; WebKit uses the transparent-thumb rules below. */
    scrollbar-width: thin;
    scrollbar-color: transparent transparent;
}
.data-table-scroll:hover {
    scrollbar-color: var(--color-border, #cbd5e1) transparent;
}
.data-table-scroll::-webkit-scrollbar { height: 10px; width: 10px; }
.data-table-scroll::-webkit-scrollbar-track { background: transparent; }
/* Hidden by default; the thumb appears only while the table is hovered. */
.data-table-scroll::-webkit-scrollbar-thumb { background: transparent; border-radius: 999px; }
.data-table-scroll:hover::-webkit-scrollbar-thumb { background: var(--color-border, #cbd5e1); }
/* Darker while you're actually over the thumb itself. */
.data-table-scroll::-webkit-scrollbar-thumb:hover { background: var(--color-text-muted, #94a3b8); }

/* Per-column min-widths. Anchored to the <th data-col-key="..."> which
   default table-layout uses as the column's hint — body cells inherit
   from the header. Adding a new column? Add a rule here. */
.data-table th[data-col-key="Id"]            { min-width:  90px; }
.data-table th[data-col-key="Title"]         { min-width: 220px; }
.data-table th[data-col-key="Type"]          { min-width: 100px; }
.data-table th[data-col-key="Status"]        { min-width: 100px; }
.data-table th[data-col-key="Priority"]      { min-width: 100px; }
.data-table th[data-col-key="Module"]        { min-width: 100px; }
.data-table th[data-col-key="TargetVersion"] { min-width: 100px; }
.data-table th[data-col-key="Assignee"]      { min-width: 140px; }
.data-table th[data-col-key="CreatedBy"]     { min-width: 140px; }
.data-table th[data-col-key="ReportedBy"]    { min-width: 140px; }
.data-table th[data-col-key="Created"]       { min-width: 110px; }
.data-table th[data-col-key="Updated"]       { min-width: 110px; }
.data-table th[data-col-key="DueDate"]       { min-width: 110px; }
.data-table th[data-col-key="DevDueDate"]    { min-width: 110px; }
.data-table th[data-col-key="QaDueDate"]     { min-width: 110px; }
.data-table th[data-col-key="ResolvedDate"]  { min-width: 110px; }
.data-table th[data-col-key="Comments"]      { min-width:  90px; }
.data-table th[data-col-key="Attachments"]   { min-width:  90px; }
.data-table th[data-col-key="HoursWorked"]   { min-width:  90px; }
.data-table th[data-col-key="Organization"]  { min-width: 120px; }
.data-table th[data-col-key="OrganizationType"] { min-width: 110px; }
.data-table th[data-col-key="ReporterRole"]   { min-width: 120px; }
.data-table th[data-col-key="CreatedByRole"]  { min-width: 120px; }
.data-table th[data-col-key="AssigneeRole"]   { min-width: 120px; }
.data-table th[data-col-key="ReleaseNotes"]  { min-width:  70px; }
.data-table th[data-col-key="Highlighted"]   { min-width:  70px; }
.data-table th[data-col-key="Impact"]        { min-width: 100px; }
.data-table th[data-col-key="Effort"]        { min-width: 100px; }
.data-table th[data-col-key="ParentTicket"]  { min-width: 110px; }

/* Default column WIDTHS — ticket-list tables only (the ones wrapped for
   horizontal scroll). These tables run under `table-layout: fixed` (forced
   inline by the resize interop so drags are pixel-stable), which means the
   rendered column widths come from these `width` declarations, NOT from cell
   content. Each width is sized to comfortably fit that column's FULL header
   label (e.g. "HOURS WORKED", "CREATED BY ROLE") plus the drag grip + sort
   button, so headers never truncate by default.

   TITLE is deliberately given no width: it's the single flexible column, so it
   absorbs any slack (the table fills its container — no right-hand gap) and is
   the only column that narrows when you add another. Every OTHER column keeps
   its exact width when a column is added, and once the total exceeds the
   container the `.data-table-scroll` wrapper scrolls instead of squeezing.

   The per-column `min-width`s above stay as the resize FLOOR (the drag can't go
   narrower than that). Admin tables have no `.data-table-scroll` wrapper, so
   none of these widths touch them. Reordering never changes widths — a column
   carries its width wherever it lands. */
.data-table-scroll .data-table th[data-col-key="Id"]              { width:  96px; }
.data-table-scroll .data-table th[data-col-key="Type"]            { width: 125px; }
.data-table-scroll .data-table th[data-col-key="Status"]          { width: 130px; }
.data-table-scroll .data-table th[data-col-key="Priority"]        { width: 140px; }
.data-table-scroll .data-table th[data-col-key="Assignee"]        { width: 150px; }
.data-table-scroll .data-table th[data-col-key="CreatedBy"]       { width: 155px; }
.data-table-scroll .data-table th[data-col-key="Created"]         { width: 135px; }
.data-table-scroll .data-table th[data-col-key="Comments"]        { width: 155px; }
.data-table-scroll .data-table th[data-col-key="Module"]          { width: 135px; }
.data-table-scroll .data-table th[data-col-key="TargetVersion"]   { width: 190px; }
.data-table-scroll .data-table th[data-col-key="DueDate"]         { width: 140px; }
.data-table-scroll .data-table th[data-col-key="DevDueDate"]      { width: 175px; }
.data-table-scroll .data-table th[data-col-key="QaDueDate"]       { width: 160px; }
.data-table-scroll .data-table th[data-col-key="Updated"]         { width: 135px; }
.data-table-scroll .data-table th[data-col-key="HoursWorked"]     { width: 190px; }
.data-table-scroll .data-table th[data-col-key="Organization"]    { width: 175px; }
.data-table-scroll .data-table th[data-col-key="OrganizationType"]{ width: 140px; }
.data-table-scroll .data-table th[data-col-key="ReporterRole"]    { width: 185px; }
.data-table-scroll .data-table th[data-col-key="CreatedByRole"]   { width: 200px; }
.data-table-scroll .data-table th[data-col-key="AssigneeRole"]    { width: 185px; }
.data-table-scroll .data-table th[data-col-key="ReleaseNotes"]    { width: 185px; }
.data-table-scroll .data-table th[data-col-key="Highlighted"]     { width: 165px; }
.data-table-scroll .data-table th[data-col-key="ResolvedDate"]    { width: 185px; }
.data-table-scroll .data-table th[data-col-key="Impact"]          { width: 125px; }
.data-table-scroll .data-table th[data-col-key="Effort"]          { width: 125px; }
.data-table-scroll .data-table th[data-col-key="ReportedBy"]      { width: 165px; }
.data-table-scroll .data-table th[data-col-key="ParentTicket"]    { width: 185px; }
.data-table-scroll .data-table th[data-col-key="Attachments"]     { width: 175px; }

/* Keep every header label on one line so a column that's wide enough shows the
   full label instead of wrapping it to two lines. */
.data-table-scroll .th-label {
    white-space: nowrap;
}

/* Each table cell becomes a container so adaptive-chip rules below
   can size the chip label against the actual column width, not the
   page width. Modern browsers only — every browser since 2023. */
.data-table td {
    container-type: inline-size;
}

/* Row density — comfortable (default) vs. compact. The page-scoped
   `.data-table tbody td` rules in Dashboard.razor.css / Tickets.razor.css
   set the default 16px/20px padding; these compact overrides apply only
   when the <table> carries `data-density="compact"`. ~50% more rows fit
   on a screen, which is what power users want when triaging a backlog.
   The thead label-row gets tightened too so it doesn't look top-heavy.
   We bump selector specificity with the attribute so we don't have to
   touch the per-page rules. */
.data-table[data-density="compact"] tbody td {
    padding: 6px 12px;
    font-size: 13px;
}
.data-table[data-density="compact"] thead th .th-label-row {
    padding: 6px 10px 2px;
}
.data-table[data-density="compact"] thead th .th-filter-row {
    padding: 0 6px 6px;
}

/* Toolbar button that flips between modes. Matches the visual weight
   of the adjacent Columns picker button so the toolbar reads as a row
   of equal-tier controls, not a hierarchy of primary/secondary. */
.density-toggle-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    border: 1px solid var(--color-border, #d1d5db);
    border-radius: 6px;
    background: var(--color-surface, #fff);
    font-size: 12px;
    font-weight: 500;
    color: var(--color-text-secondary, #586069);
    cursor: pointer;
    transition: all 0.15s ease;
    white-space: nowrap;
}
.density-toggle-btn i { font-size: 14px; }
.density-toggle-btn:hover {
    border-color: var(--color-primary, #6366f1);
    color: var(--color-primary, #6366f1);
}
/* Active state for toggle-style buttons (currently used by Auto-fit
   in its enabled position). Reads as "on" without needing a separate
   indicator dot. */
.density-toggle-btn.active {
    background: color-mix(in srgb, var(--color-primary, #6366f1) 10%, white);
    border-color: var(--color-primary, #6366f1);
    color: var(--color-primary, #6366f1);
}

/* ============================================================
   Auto-fit responsive column hiding
   ────────────────────────────────────────────────────────────
   When the table has `data-autofit="true"`, low-priority columns
   are hidden at narrow viewports instead of forcing horizontal
   scroll. Tiers (1 = always visible, 5 = hide first):

     p1  always visible          Id, Title
     p2  hide  < 768px           Status, Assignee
     p3  hide  < 992px           Priority, Comments, Updated
     p4  hide  < 1200px          Type, Created, CreatedBy,
                                  Module, Organization, ResolvedDate
     p5  hide  < 1400px          TargetVersion, DueDate, DevDueDate,
                                  HoursWorked, ReleaseNotes, Highlighted,
                                  Impact, Effort, ReportedBy,
                                  ParentTicket, Attachments

   Selectors match both <th data-col-key="X"> and <td data-col-key="X">
   so the column collapses cleanly. The Columns picker is the override:
   if a user un-ticks a column there it isn't rendered at all, so it
   takes precedence over these rules. With auto-fit OFF (default),
   none of these rules fire and the user keeps every column they
   enabled regardless of viewport. ============================================================ */

/* p5 — hide first, at 1400px (narrow desktop / tablet landscape) */
@media (max-width: 1400px) {
    .data-table[data-autofit="true"] [data-col-key="TargetVersion"],
    .data-table[data-autofit="true"] [data-col-key="DueDate"],
    .data-table[data-autofit="true"] [data-col-key="DevDueDate"],
    .data-table[data-autofit="true"] [data-col-key="HoursWorked"],
    .data-table[data-autofit="true"] [data-col-key="ReleaseNotes"],
    .data-table[data-autofit="true"] [data-col-key="Highlighted"],
    .data-table[data-autofit="true"] [data-col-key="Impact"],
    .data-table[data-autofit="true"] [data-col-key="Effort"],
    .data-table[data-autofit="true"] [data-col-key="ReportedBy"],
    .data-table[data-autofit="true"] [data-col-key="ParentTicket"],
    .data-table[data-autofit="true"] [data-col-key="Attachments"] {
        display: none;
    }
}

/* p4 — hide at 1200px (standard laptop) */
@media (max-width: 1200px) {
    .data-table[data-autofit="true"] [data-col-key="Type"],
    .data-table[data-autofit="true"] [data-col-key="Created"],
    .data-table[data-autofit="true"] [data-col-key="CreatedBy"],
    .data-table[data-autofit="true"] [data-col-key="Module"],
    .data-table[data-autofit="true"] [data-col-key="Organization"],
    .data-table[data-autofit="true"] [data-col-key="ResolvedDate"] {
        display: none;
    }
}

/* p3 — hide at 992px (small laptop / tablet portrait) */
@media (max-width: 992px) {
    .data-table[data-autofit="true"] [data-col-key="Priority"],
    .data-table[data-autofit="true"] [data-col-key="Comments"],
    .data-table[data-autofit="true"] [data-col-key="Updated"] {
        display: none;
    }
}

/* p2 — hide at 768px (phone / very narrow). Only Id + Title remain. */
@media (max-width: 768px) {
    .data-table[data-autofit="true"] [data-col-key="Status"],
    .data-table[data-autofit="true"] [data-col-key="Assignee"] {
        display: none;
    }
}

/* Inside data-table cells: let chips wrap onto a second line when the
   column is too narrow to fit the full label on one row. Outside the
   table (filter chips, ticket-detail header, etc.) badges keep their
   default nowrap behavior so they don't break in flex toolbars.
   ────────────────────────────────────────────────────────────────────
   We override the `white-space: nowrap` baked into `.badge` only
   inside `.data-table td`, and drop the ellipsis since wrapped chips
   show every line of text. `word-break: break-word` rescues very long
   single tokens (e.g. "Customer-Configurable") that would otherwise
   blow out of the cell. */
.data-table td .badge {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    word-break: break-word;
    line-height: 1.3;
    /* Re-enable shrink + wrap inside cells (global .badge sets
       min-width: max-content, which would otherwise block column wrapping). */
    min-width: 0;
}

/* Truncation hint for freeform-text cells (Title, Assignee, Module,
   Organization, Impact, Effort, etc.). Wraps the cell value in a
   <span class="cell-text" title="..."> so the user sees an ellipsis
   when the column is too narrow and gets the full string back via
   the native browser tooltip on hover. Block-level so `text-overflow`
   actually engages — inline spans don't clip. The `max-width: 100%`
   keeps the span inside the cell's content box; without it, long
   words could push the td wider than the column. */
.data-table td .cell-text {
    display: block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ==========================================
   SYSTEM-ROW BADGE (admin pages)
   ==========================================
   Shows next to the name on lookup rows (status / type / priority)
   whose IsSystem=1. Tells admins "this row is referenced by backend
   code — display name is editable, but SystemCode and Delete are
   protected." Matching CSS for all three admin management pages so
   the badge looks the same everywhere.
*/
.system-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-left: 10px;
    padding: 2px 8px 2px 7px;
    border-radius: 999px;
    font-size: 10.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    background: #0f172a;
    color: #fcd34d;
    vertical-align: middle;
    cursor: help;
}
.system-badge i { font-size: 11px; line-height: 1; }

/* SystemCode column chip — monospace, padded, slightly muted box.
   .system-code-locked uses the dark navy + gold palette to match the
   "🔒 System" badge so the visual language is consistent. */
.system-code {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 4px;
    font-family: ui-monospace, 'SF Mono', Consolas, monospace;
    font-size: 11.5px;
    font-weight: 600;
    background: var(--color-gray-100, #f1f5f9);
    color: var(--color-text-secondary, #334155);
    border: 1px solid var(--color-border, #e2e8f0);
}
.system-code.system-code-locked {
    background: #0f172a;
    color: #fcd34d;
    border-color: #0f172a;
}

/* ==========================================
   BADGES
   ========================================== */
.badge {
    padding: 4px 10px;
    border-radius: 12px;
    font-size: 12px;
    font-weight: 600;
    display: inline-block;
    border: 1px solid;
    /* Cap width so a chip can't blow out its container. Do NOT add
       overflow:hidden here: on a flex item (card-header actions, filter
       toolbars) overflow:hidden drops the flex auto-min-size from min-content
       to 0, letting the badge be squeezed below its text width and collapse
       into the rounded (9999px) pill — i.e. a clipped circle, e.g. a
       "CreateNew" mode badge rendering as "ateN". Cell clipping/wrapping is
       handled by the `.data-table td .badge` rule instead (overflow:visible
       + word-break), so nothing here needs to clip. */
    max-width: 100%;
    /* Hard floor at the label width so a collapsing flex parent (card-header
       actions, result headers, filter toolbars) can't squeeze the chip below
       its text into the rounded pill — i.e. the "CreateNew" → "ateN" circle.
       min-width wins over both a shrinking flex parent and max-width. Cells
       override this back to 0 (see `.data-table td .badge`) so chips wrap. */
    min-width: max-content;
    white-space: nowrap;
    vertical-align: middle;
}

/* Adaptive label tiers — only one of the four .badge-lbl-* spans is
   visible at a time. The Badge component renders all four; CSS picks
   the right one based on the cell's actual width or density mode.

   Default (cell ≥ 110px):  show .badge-lbl-full
   60-110px:                show .badge-lbl-short
   < 60px:                  show .badge-lbl-initial
   COMPACT density mode:    show .badge-lbl-acronym, hover-expand to full
                            (rules below, scoped to compact tables only)

   Outside a table cell (no container ancestor) the queries don't fire
   and only .badge-lbl-full is visible — which is what we want for the
   ticket detail header, filter chips, etc. */
.badge-lbl-full,
.badge-lbl-short,
.badge-lbl-initial,
.badge-lbl-acronym { display: none; }
.badge-lbl-full { display: inline; }

@container (max-width: 110px) {
    .badge-lbl-full { display: none; }
    .badge-lbl-short { display: inline; }
}
@container (max-width: 60px) {
    .badge-lbl-short { display: none; }
    .badge-lbl-initial { display: inline; }
}

/* ════════════════════════════════════════════════════════════════════
   COMPACT MODE — acronym chips with hover-to-expand
   ────────────────────────────────────────────────────────────────────
   When the table carries data-density="compact", every chip in a body
   cell collapses to a 1-3 letter acronym. On hover, the chip smoothly
   animates back to its full label — max-width grows, acronym opacity
   fades out, full label fades in. The chip floats over neighbors during
   the grow (z-index + box-shadow) so the column-width constraints
   don't force the table to relayout.

   Implementation notes:
   • We override the chip-wrap rule above (`.data-table td .badge` sets
     white-space:normal) inside compact mode — wrapped acronyms don't
     make sense; we want a single short pill.
   • The four label spans become inline-block in compact mode so their
     max-width / opacity can transition. We use !important once because
     the container-query rules above set display:none on the spans we
     need to be visible/hidden via max-width here.
   • Cells get overflow:visible so the expanded chip can paint over the
     next column. Combined with z-index:5 on hover, the expanded chip
     never gets clipped or hidden behind a neighbor.
   ════════════════════════════════════════════════════════════════════ */
.data-table[data-density="compact"] td {
    overflow: visible;
}

/* Note the size-class qualifier (.badge.badge-md, .badge-sm, .badge-lg)
   on every compact-mode chip rule. This is deliberate: Shared/Components
   /Badge.razor.css sets `.badge.badge-md { padding: 4px 10px }` and gets
   a Blazor scoped-CSS attribute appended ([b-xxxxxx]) which boosts its
   specificity above plain `.badge` selectors here. Adding the size class
   to our selector matches Badge.razor.css's specificity and then the
   extra `.data-table[data-density="compact"] td` ancestors put us
   solidly ahead, so the padding override actually applies. */
.data-table[data-density="compact"] td .badge.badge-sm,
.data-table[data-density="compact"] td .badge.badge-md,
.data-table[data-density="compact"] td .badge.badge-lg {
    /* Override the cell-wrap rule from .data-table td .badge above —
       compact-mode chips are always a single, short pill. */
    white-space: nowrap;
    overflow: hidden;
    word-break: normal;
    line-height: 1;
    /* Badge.razor.css already sets .badge to display: inline-flex which
       handily eliminates inter-span whitespace. BUT it also sets
       gap: 4px which draws 4px of space between every flex item — even
       items with max-width:0 + opacity:0. With four <span> children
       (full/short/initial/acronym), three of them invisible, flexbox
       still paints 3 × 4px = 12px of gap inside the chip. That's the
       dead space that makes single-letter acronyms look stretched.
       Zero the gap and the chip hugs its visible content. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0;
    /* Tight chip that hugs the acronym. Beats the .badge-md
       padding: 4px 10px baked into Badge.razor.css. */
    padding: 2px 6px;
    font-size: 11px;
    min-width: 0;
    min-height: 0;
    box-sizing: border-box;
    /* Position context so z-index lifts the chip during hover */
    position: relative;
    z-index: 1;
    /* Padding transitions with the width so the rounded ends never
       look pinched at intermediate sizes. */
    transition: padding 0.22s cubic-bezier(0.2, 0, 0, 1),
                font-size 0.16s ease-out,
                box-shadow 0.16s ease-out;
}

/* Hover: restore comfortable padding + font so the expanded full label
   reads at the same density as the chip would outside the table.
   Keep gap:0 — even on hover the three "hidden" label spans are still
   present as 0-width flex items, and a non-zero gap would draw 3 × gap
   pixels of space between them after the visible full label, putting
   dead padding inside the right edge of the expanded chip. None of
   our chips currently render an icon so there's nothing to space. */
.data-table[data-density="compact"] td .badge.badge-sm:hover,
.data-table[data-density="compact"] td .badge.badge-md:hover,
.data-table[data-density="compact"] td .badge.badge-lg:hover {
    padding: 3px 10px;
    font-size: 12px;
}

/* Four label spans share the same chip box. We control which is
   "visible" by sliding max-width between 0 and a sensible cap, plus
   fading opacity in parallel. !important here defeats the container
   queries above that set display:none — in compact mode they all
   need to be inline-block so their max-width transitions fire. */
.data-table[data-density="compact"] td .badge .badge-lbl-full,
.data-table[data-density="compact"] td .badge .badge-lbl-short,
.data-table[data-density="compact"] td .badge .badge-lbl-initial,
.data-table[data-density="compact"] td .badge .badge-lbl-acronym {
    display: inline-block !important;
    overflow: hidden;
    white-space: nowrap;
    vertical-align: middle;
    transition: max-width 0.22s cubic-bezier(0.2, 0, 0, 1),
                opacity   0.16s ease-out;
}

/* Default compact state — only the acronym is visible. */
.data-table[data-density="compact"] td .badge .badge-lbl-full,
.data-table[data-density="compact"] td .badge .badge-lbl-short,
.data-table[data-density="compact"] td .badge .badge-lbl-initial {
    max-width: 0;
    opacity: 0;
}
.data-table[data-density="compact"] td .badge .badge-lbl-acronym {
    max-width: 60px;
    opacity: 1;
}

/* Hover state — swap acronym for full, lift the chip on a soft shadow
   so the user feels the depth change. z-index keeps the expanded chip
   above its column neighbors. */
.data-table[data-density="compact"] td .badge.badge-sm:hover,
.data-table[data-density="compact"] td .badge.badge-md:hover,
.data-table[data-density="compact"] td .badge.badge-lg:hover {
    z-index: 5;
    box-shadow: 0 2px 8px rgba(15, 23, 42, 0.10);
}
.data-table[data-density="compact"] td .badge:hover .badge-lbl-acronym {
    max-width: 0;
    opacity: 0;
}
.data-table[data-density="compact"] td .badge:hover .badge-lbl-full {
    max-width: 240px;
    opacity: 1;
}

.type-badge {
    padding: 2px 8px;
    border-radius: 4px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

/* ==========================================
   BUTTONS
   ========================================== */
.btn {
    padding: 8px 16px;
    border: none;
    border-radius: 6px;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.2s;
}

.btn-primary {
    background: var(--color-primary, #0366d6);
    color: var(--color-text-inverse, white);
}

    .btn-primary:hover {
        background: var(--color-primary-hover, #0256c7);
    }

    /* Disabled primary/success buttons must LOOK disabled, not just be
       inert. Without this, e.g. the Import Wizard's "Continue to Mapping"
       (disabled until a preview loads rows) stayed solid blue and looked
       clickable. Mirrors the existing .btn-danger:disabled treatment. */
    .btn-primary:disabled,
    .btn-primary:disabled:hover,
    .btn-success:disabled,
    .btn-success:disabled:hover {
        background: var(--color-border, #d1d5da);
        color: var(--color-text-muted, #6a737d);
        cursor: not-allowed;
        opacity: 0.6;
        box-shadow: none;
    }

.btn-secondary {
    background: var(--color-surface, white);
    color: var(--color-text-primary, #24292e);
    border: 1px solid var(--color-border, #e1e4e8);
}

    .btn-secondary:hover {
        background: var(--color-gray-100, #f6f8fa);
    }

.btn-danger {
    background: var(--color-danger, #d73a49);
    color: var(--color-text-inverse, white);
}

    .btn-danger:hover {
        background: var(--color-danger-hover, #cb2431);
    }

    .btn-danger:disabled {
        background: var(--color-border, #d1d5da);
        cursor: not-allowed;
        opacity: 0.5;
    }

.btn-sm {
    padding: 6px 12px;
    font-size: 13px;
}

.btn-block {
    width: 100%;
    margin-top: 12px;
}

/* ==========================================
   LOADING & EMPTY STATES
   ========================================== */
.loading, .empty-state {
    text-align: center;
    padding: 40px;
    color: var(--color-text-secondary, #586069);
}

/* ==========================================
   CARDS
   ========================================== */
.card {
    background: var(--color-surface, white);
    border: 1px solid var(--color-border, #e1e4e8);
    border-radius: 6px;
    margin-bottom: 24px;
}

.card-header {
    padding: 16px 20px;
    border-bottom: 1px solid var(--color-border, #e1e4e8);
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.card-title {
    font-size: 16px;
    font-weight: 600;
    color: var(--color-text-primary, #24292e);
}

.card-body {
    padding: 20px;
}

/* ==========================================
   FORMS
   ========================================== */
.form-group {
    margin-bottom: 16px;
}

.form-label {
    display: block;
    margin-bottom: 8px;
    font-size: 13px;
    font-weight: 600;
    color: var(--color-text-primary, #24292e);
}

.form-input, .form-select {
    width: 100%;
    padding: 8px 12px;
    border: 1px solid var(--color-border, #e1e4e8);
    border-radius: 6px;
    font-size: 14px;
    font-family: inherit;
}

    .form-input:focus, .form-select:focus {
        outline: none;
        border-color: var(--color-primary, #0366d6);
        box-shadow: 0 0 0 3px rgba(3, 102, 214, 0.1);
    }

textarea.form-input {
    resize: vertical;
    font-family: inherit;
}

.action-buttons {
    display: flex;
    gap: 8px;
}

/* ==========================================
   MODALS
   ========================================== */
.modal {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.5);
    z-index: 10000;
    align-items: center;
    justify-content: center;
}

    .modal.active {
        display: flex;
    }

.modal-content {
    background: var(--color-surface, white);
    border-radius: 6px;
    width: 90%;
    max-width: 500px;
    max-height: 90vh;
    overflow-y: auto;
}

.modal-header {
    padding: 20px 24px;
    border-bottom: 1px solid var(--color-border, #e1e4e8);
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.modal-title {
    font-size: 18px;
    font-weight: 600;
    color: var(--color-text-primary, #24292e);
}

.modal-close {
    background: none;
    border: none;
    font-size: 24px;
    color: var(--color-text-secondary, #586069);
    cursor: pointer;
    padding: 0;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
}

    .modal-close:hover {
        background: var(--color-gray-100, #f6f8fa);
    }

.modal-body {
    padding: 24px;
}

.modal-footer {
    padding: 16px 24px;
    border-top: 1px solid var(--color-border, #e1e4e8);
    display: flex;
    justify-content: flex-end;
    gap: 12px;
}

/* ==========================================
   ADMIN SIDEBAR
   ========================================== */
.admin-layout {
    display: grid;
    grid-template-columns: 220px 1fr;
    gap: 24px;
}

.sidebar {
    background: var(--color-surface, white);
    border: 1px solid var(--color-border, #e1e4e8);
    border-radius: 6px;
    padding: 16px;
    height: fit-content;
}

.sidebar-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--color-text-primary, #24292e);
    padding: 8px 12px;
    margin-bottom: 8px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.sidebar-menu {
    list-style: none;
    padding: 0;
    margin: 0;
}

.sidebar-item {
    padding: 10px 12px;
    border-radius: 6px;
    cursor: pointer;
    margin-bottom: 4px;
    color: var(--color-text-secondary, #586069);
    font-size: 14px;
    font-weight: 500;
    transition: all 0.2s;
}

    .sidebar-item:hover {
        background: var(--color-gray-100, #f6f8fa);
        color: var(--color-text-primary, #24292e);
    }

    .sidebar-item.active {
        background: var(--color-primary, #0366d6);
        color: var(--color-text-inverse, white);

        /* Override the theme's per-weight phosphor icon-colour variables so the
           selected item's icon reads as the inverse (on-primary) colour. The
           global rules in design-tokens.css paint icons via these variables with
           very high specificity; overriding the variables here beats them without
           a specificity fight. Theme-driven via --color-text-inverse. */
        --icon-color-regular: var(--color-text-inverse, #fff);
        --icon-color-regular-active: var(--color-text-inverse, #fff);
        --icon-color-fill: var(--color-text-inverse, #fff);
        --icon-color-fill-active: var(--color-text-inverse, #fff);
        --icon-color-duotone: var(--color-text-inverse, #fff);
        --icon-color-duotone-active: var(--color-text-inverse, #fff);
        --icon-color-bold: var(--color-text-inverse, #fff);
        --icon-color-bold-active: var(--color-text-inverse, #fff);
        --icon-color-light: var(--color-text-inverse, #fff);
        --icon-color-light-active: var(--color-text-inverse, #fff);
        --icon-color-thin: var(--color-text-inverse, #fff);
        --icon-color-thin-active: var(--color-text-inverse, #fff);
    }

.sidebar-back {
    margin-bottom: 16px;
}

.back-button {
    width: 100%;
    padding: 10px 12px;
    background: var(--color-gray-100, #f6f8fa);
    border: 1px solid var(--color-border, #e1e4e8);
    border-radius: 6px;
    color: var(--color-text-secondary, #586069);
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.2s;
    text-align: left;
}

    .back-button:hover {
        background: var(--color-border, #e1e4e8);
        color: var(--color-text-primary, #24292e);
    }

/* ==========================================
   COLOR INPUTS
   ========================================== */
.color-swatch {
    width: 32px;
    height: 32px;
    border-radius: 6px;
    border: 1px solid var(--color-border, #e1e4e8);
    display: inline-block;
}

.color-input {
    width: 60px;
    height: 40px;
    border: 1px solid var(--color-border, #e1e4e8);
    border-radius: 6px;
    cursor: pointer;
}

/* ==========================================
   FOCUS STYLES
   ========================================== */
h1:focus,
h2:focus,
h3:focus {
    outline: none !important;
}

button:focus-visible,
a:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
    outline: 2px solid var(--color-primary, #0366d6);
    outline-offset: 2px;
}

/* ==========================================
   KNOWLEDGE BASE
   ========================================== */
.articles-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
    gap: 20px;
    padding: 20px;
}

.article-card {
    background: var(--color-surface, white);
    border: 1px solid var(--color-border, #e1e4e8);
    border-radius: 8px;
    padding: 20px;
    cursor: pointer;
    transition: all 0.2s;
}

    .article-card:hover {
        border-color: var(--color-primary, #0366d6);
        box-shadow: 0 4px 12px rgba(0,0,0,0.1);
        transform: translateY(-2px);
    }

.article-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12px;
}

.article-number {
    font-family: 'Consolas', monospace;
    color: var(--color-primary, #0366d6);
    font-weight: 600;
    font-size: 12px;
}

.module-badge {
    background: var(--color-primary-light, #f0f7ff);
    color: var(--color-primary, #0969da);
    padding: 4px 10px;
    border-radius: 12px;
    font-size: 11px;
    font-weight: 600;
}

.article-title {
    font-size: 18px;
    font-weight: 600;
    color: var(--color-text-primary, #24292e);
    margin-bottom: 12px;
    line-height: 1.4;
}

.article-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    font-size: 13px;
    color: var(--color-text-secondary, #586069);
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--color-border, #e1e4e8);
}

.article-footer {
    margin-top: 12px;
    font-size: 12px;
    color: var(--color-text-secondary, #586069);
}

/* ==========================================
   RESPONSIVE
   ========================================== */
@media (max-width: 1200px) {
    .stats-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 768px) {
    .stats-grid {
        grid-template-columns: 1fr;
    }

    .admin-layout {
        grid-template-columns: 1fr;
    }
}

/* Insert-variable chips (release-notes builder inspector + the release editor).
   Global so the shared VariableBar component is styled on any page that uses it. */
.rnb-varbar-wrap { margin-top: 4px; }
.rnb-varbar-hint { display: flex; align-items: center; gap: 5px; font-size: 10.5px; color: #8a93a3; margin-bottom: 6px; line-height: 1.3; }
.rnb-varbar-hint .ph { font-size: 13px; color: var(--color-primary, #006ec0); flex: none; }
.rnb-varbar { display: flex; flex-wrap: wrap; gap: 6px; }
.rnb-varchip { display: inline-flex; align-items: center; gap: 5px; border: 1px solid #d7dce3; background: linear-gradient(#ffffff, #f3f6fa); border-radius: 7px; padding: 4px 9px; font-size: 11.5px; font-weight: 600; color: #3a4252; cursor: pointer; transition: background .12s, border-color .12s, box-shadow .12s, transform .12s, color .12s; box-shadow: 0 1px 0 rgba(16,24,40,.03); }
.rnb-varchip .ph { font-size: 13px; color: #9aa3b2; transition: color .12s; }
.rnb-varchip:hover { background: var(--color-primary, #006ec0); border-color: var(--color-primary, #006ec0); color: #fff; box-shadow: 0 2px 7px rgba(0,110,192,.26); transform: translateY(-1px); }
.rnb-varchip:hover .ph { color: #fff; }
.rnb-varchip:active { transform: translateY(0); box-shadow: 0 1px 0 rgba(16,24,40,.05); }

/* AI release-notes polish — review screen + the admin-side AI-assisted chip */
.ai-note-chip { display: inline-flex; align-items: center; gap: 3px; margin-left: 6px; padding: 1px 7px; border-radius: 999px; background: var(--color-accent-ai-light, #f3ecff); color: var(--color-accent-ai, #6d28d9); font-size: 10.5px; font-weight: 700; vertical-align: middle; }
.ai-note-chip .ph-sparkle { font-size: 12px; }
.polish-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; padding-bottom: 8px; border-bottom: 1px solid #e6e9ee; }
.polish-row { border: 1px solid #e6e9ee; border-radius: 9px; padding: 10px 12px; margin-bottom: 10px; background: #fbfcfd; }
.polish-row-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.polish-ticket { font-weight: 700; font-size: 12.5px; color: var(--color-primary, #006ec0); }
.polish-title { flex: 1; min-width: 0; font-size: 12.5px; color: #333; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.polish-kind { padding: 1px 8px; border-radius: 999px; font-size: 10.5px; font-weight: 700; background: #e8f1fb; color: #0b5394; }
.polish-state { padding: 1px 8px; border-radius: 999px; font-size: 10.5px; font-weight: 700; background: #eef1f4; color: #5b6472; }
.polish-compare { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 8px; }
.polish-col-label { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: #8a93a3; margin-bottom: 3px; }
.polish-text { font-size: 12.5px; line-height: 1.45; padding: 8px 10px; border-radius: 7px; }
.polish-text.original { background: #f2f4f7; color: #555; }
.polish-text.suggestion { background: var(--color-success-light, #eefaf2); color: var(--color-success-text, #1d3b29); border: 1px solid var(--color-success, #c9ecd7); }
.polish-actions { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.polish-error { color: var(--color-danger, #b42318); font-size: 12px; margin-top: 6px; }
.polish-summaries { margin-top: 14px; padding-top: 12px; border-top: 1px solid #e6e9ee; }
.polish-hint { margin-top: 8px; font-size: 12px; color: #555; }

/* ── Column drag-to-reorder (ticket list headers) ────────────────────
   The whole <th> is draggable; the grip is a hover affordance. */
.data-table th.col-reorderable { cursor: grab; }

.data-table th.col-reorderable .col-drag-grip {
    opacity: 0;
    color: var(--color-text-secondary, #9aa3b2);
    cursor: grab;
    margin-right: 4px;
    font-size: 13px;
    vertical-align: middle;
    transition: opacity 0.12s;
}

.data-table th.col-reorderable:hover .col-drag-grip { opacity: 0.65; }
.data-table th.col-reorderable .col-drag-grip:active { cursor: grabbing; }

/* The header being dragged fades; the header it will drop before/onto gets a
   coloured edge so the target is obvious. */
.data-table th.col-dragging { opacity: 0.45; }
.data-table th.col-drag-over { box-shadow: inset 3px 0 0 0 var(--color-primary, #0366d6); }

/* ── Group-by level palette ──────────────────────────────────────────
   Fixed, colourblind-safe categorical palette for grouped-list levels. Like
   the avatar palette this is an intentional hard-coded set — the theme builder
   manages --color-* tokens, not these. Blue + vermillion for the two most-used
   adjacent levels is the canonical CVD-distinguishable pair; every colour is
   dark enough for white text on the numbered circle. Users can override any
   level per-user (stored client-side); the override sets these same vars. */
:root {
    --grp-lvl-1: #0072b2; /* blue */
    --grp-lvl-2: #c2410c; /* vermillion */
    --grp-lvl-3: #047857; /* green */
    --grp-lvl-4: #7c3aed; /* violet */
    --grp-lvl-5: #475569; /* slate */
    --grp-lvl-6: #a21caf; /* magenta */
}

/* ── Group level colour picker popover (appended to <body> by group-colors.js,
   so it lives in global CSS, not a scoped sheet). Theme-token colours. ── */
.pill-order[data-level] { cursor: pointer; }
.pill-order[data-level]:hover { box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 25%, transparent); }

.grp-color-pop {
    position: absolute;
    z-index: 3000;
    width: 208px;
    background: var(--color-surface, #fff);
    border: 1px solid var(--color-border, #e1e4e8);
    border-radius: 10px;
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.16);
    padding: 12px;
}
.gcp-title {
    font-size: 12px;
    font-weight: 700;
    color: var(--color-text-secondary, #586069);
    margin-bottom: 9px;
}
.gcp-grid {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 8px;
    margin-bottom: 10px;
}
.gcp-sw {
    width: 100%;
    aspect-ratio: 1;
    border-radius: 6px;
    border: 2px solid transparent;
    cursor: pointer;
    padding: 0;
    transition: transform 0.08s;
}
.gcp-sw:hover { transform: scale(1.12); }
.gcp-sw.sel { border-color: var(--color-text-primary, #24292e); }
.gcp-reset {
    width: 100%;
    border: 1px solid var(--color-border, #e1e4e8);
    background: var(--color-gray-50, #fafbfc);
    border-radius: 6px;
    padding: 6px;
    font-size: 12px;
    font-weight: 600;
    color: var(--color-text-secondary, #586069);
    cursor: pointer;
}
.gcp-reset:hover { background: var(--color-gray-100, #f6f8fa); }

/* Aggregation accent (matches the Report Builder's purple Σ). */
:root { --agg: #7c3aed; }
