/* ============================================================================
   Clyptus ATS — report & status design system            assets/reports.css
   ----------------------------------------------------------------------------
   THE PROBLEM THIS SOLVES
   Across the report pages there were 25+ hard-coded hex values and ~35 one-off
   class names (.ar-p, .sr-ok, .at-warn, .rb-dead …) all expressing about five
   ideas. Nothing matched between pages, so "green" meant Present here and
   Selected there, and an amber in one grid was a different amber in the next.

   THE SYSTEM
   FIVE states. That is the whole vocabulary.

     .s-good   green   done, approved, present, on target
     .s-wait   amber   pending, in progress, needs attention soon
     .s-stop   red     rejected, overdue, missing, blocked
     .s-off    grey    not applicable, weekly off, inactive, purged
     .s-info   blue    informational, holiday, neutral highlight

   COLOUR IS NEVER THE ONLY SIGNAL
   Every state carries a glyph as well as a hue, because roughly 8% of men have
   some colour-vision deficiency and these grids get printed in greyscale. The
   glyph comes from CSS ::before so the markup stays clean.

   Load it once in Site.master; every page then uses the same names.
   ============================================================================ */

:root {
    /* Each state has a fill, a text colour and a border. The text colour is
       always the darkest of the family so contrast holds on the pale fill. */
    --s-good-bg:  #e7f6ec;  --s-good-fg:  #0f5132;  --s-good-bd:  #a6d9b8;
    --s-wait-bg:  #fff4d6;  --s-wait-fg:  #7a5200;  --s-wait-bd:  #f0cf7e;
    --s-stop-bg:  #fdeaec;  --s-stop-fg:  #a01f2d;  --s-stop-bd:  #f2b3bb;
    --s-off-bg:   #f1f3f5;  --s-off-fg:   #5b6470;  --s-off-bd:   #dde1e6;
    --s-info-bg:  #e8effd;  --s-info-fg:  #1c4a9e;  --s-info-bd:  #b6cbf2;

    /* One density scale for every report grid, so pages stop drifting apart. */
    --rpt-font:      .78rem;
    --rpt-font-head: .66rem;
    --rpt-pad-y:     .3rem;
    --rpt-pad-x:     .5rem;
    --rpt-radius:    6px;
}

/* ---------------------------------------------------------------------------
   1. Status pill — the default way to show any state
   Usage:  <span class="pill s-good">Approved</span>
   --------------------------------------------------------------------------- */
.pill {
    display: inline-flex; align-items: center; gap: .3em;
    padding: .12em .55em; border-radius: 999px;
    font-size: .74rem; font-weight: 600; line-height: 1.5;
    border: 1px solid transparent; white-space: nowrap;
}
.pill::before { font-weight: 700; font-size: .9em; }

.s-good { background: var(--s-good-bg); color: var(--s-good-fg); border-color: var(--s-good-bd); }
.s-wait { background: var(--s-wait-bg); color: var(--s-wait-fg); border-color: var(--s-wait-bd); }
.s-stop { background: var(--s-stop-bg); color: var(--s-stop-fg); border-color: var(--s-stop-bd); }
.s-off  { background: var(--s-off-bg);  color: var(--s-off-fg);  border-color: var(--s-off-bd); }
.s-info { background: var(--s-info-bg); color: var(--s-info-fg); border-color: var(--s-info-bd); }

/* The glyph. This is what makes the system survive greyscale printing. */
.pill.s-good::before { content: "\2713"; }   /* check      */
.pill.s-wait::before { content: "\25CF"; }   /* solid dot  */
.pill.s-stop::before { content: "\2715"; }   /* cross      */
.pill.s-off::before  { content: "\2014"; }   /* em dash    */
.pill.s-info::before { content: "\2139"; }   /* info       */

/* Drop the glyph where space is tight and the label already says it. */
.pill.bare::before { content: none; }

/* ---------------------------------------------------------------------------
   2. Cell tint — for dense grids where a pill is too heavy
   Usage:  <td class="cell s-stop">L</td>
   --------------------------------------------------------------------------- */
.cell {
    text-align: center; font-weight: 600; font-size: .72rem;
    border-radius: var(--rpt-radius);
}
.cell.s-good { background: var(--s-good-bg); color: var(--s-good-fg); }
.cell.s-wait { background: var(--s-wait-bg); color: var(--s-wait-fg); }
.cell.s-stop { background: var(--s-stop-bg); color: var(--s-stop-fg); }
.cell.s-off  { background: var(--s-off-bg);  color: var(--s-off-fg); }
.cell.s-info { background: var(--s-info-bg); color: var(--s-info-fg); }

/* A cell that needs filling in — dashed, so it reads as "gap" not "bad". */
.cell.s-empty {
    background: #fffdf6; color: #9a7a2e;
    border: 1px dashed #e3c86a; font-weight: 700;
}

/* ---------------------------------------------------------------------------
   3. Row emphasis — a left edge, never a full-row wash
   A tinted row fights with the cell tints inside it; an edge does not.
   --------------------------------------------------------------------------- */
.row-good { box-shadow: inset 3px 0 0 #198754; }
.row-wait { box-shadow: inset 3px 0 0 #d9a406; }
.row-stop { box-shadow: inset 3px 0 0 #dc3545; }
.row-off  { opacity: .55; }

/* ---------------------------------------------------------------------------
   4. Report grid — one density for every report in the app
   Add class="rpt" to the GridView.
   --------------------------------------------------------------------------- */
.rpt { font-size: var(--rpt-font); }
.rpt > thead > tr > th,
.rpt > tbody > tr > th {
    font-size: var(--rpt-font-head); text-transform: uppercase;
    letter-spacing: .04em; color: var(--muted); font-weight: 700;
    /* Module 76: was #5b6470 on #f8fafc — a light band with grey text
       across every report table in dark mode. */
    background: var(--canvas); white-space: nowrap;
}
.rpt > thead > tr > th,
.rpt > tbody > tr > td { padding: var(--rpt-pad-y) var(--rpt-pad-x) !important; vertical-align: middle; }
.rpt tbody tr:hover > td { background: var(--line-soft); }

/* Numeric columns read far better right-aligned and tabular. */
.rpt .num { text-align: right; font-variant-numeric: tabular-nums; }

/* Sensitive / masked columns — one amber, used everywhere. */
.rpt th.sensitive, .rpt td.sensitive { background: var(--s-wait-bg) !important; color: var(--s-wait-fg) !important; }

/* ---------------------------------------------------------------------------
   5. Legend — every colour-coded grid should carry one
   Usage:  <div class="legend"><span class="pill s-good">P Present</span>…</div>
   --------------------------------------------------------------------------- */
.legend {
    display: flex; flex-wrap: wrap; gap: .35rem; align-items: center;
    padding: .45rem .6rem; background: #fbfcfe;
    border: 1px solid #eef1f5; border-radius: 8px;
    font-size: .74rem; color: #5b6470; margin-bottom: .6rem;
}
.legend .legend-label { font-weight: 700; margin-right: .2rem; color: #334155; }

/* ---------------------------------------------------------------------------
   6. KPI strip — the numbers above a report
   --------------------------------------------------------------------------- */
.kpis { display: flex; gap: .45rem; flex-wrap: wrap; margin-bottom: .7rem; }
.kpis .kpi {
    flex: 1; min-width: 104px; background: #fff;
    border: 1px solid #eef0f3; border-radius: 10px; padding: .45rem .65rem;
}
.kpis .kpi .v { font-size: 1.2rem; font-weight: 800; line-height: 1.1; color: #16233d; }
.kpis .kpi .t {
    font-size: .63rem; text-transform: uppercase; letter-spacing: .05em;
    color: #94a3b8; font-weight: 700; margin-top: .1rem;
}
.kpis .kpi.good .v { color: #0f5132; }
.kpis .kpi.wait .v { color: #7a5200; }
.kpis .kpi.stop .v { color: #a01f2d; }
.kpis .kpi.info .v { color: #1c4a9e; }

/* ---------------------------------------------------------------------------
   7. Filter bar — consistent across every report page
   --------------------------------------------------------------------------- */
.filters {
    display: flex; align-items: flex-end; gap: .5rem; flex-wrap: wrap;
    padding: .55rem .7rem; background: #fff;
    border: 1px solid #eef0f3; border-radius: 10px; margin-bottom: .7rem;
}
.filters label { font-size: .7rem; font-weight: 600; color: #64748b; margin-bottom: 0; display: block; }
.filters .form-select-sm, .filters .form-control-sm { font-size: .78rem; }

/* ---------------------------------------------------------------------------
   8. Dropdowns — grouped, so a 13-item list reads as four short groups
   optgroup is styled by the browser; these rules make the grouping legible.
   --------------------------------------------------------------------------- */
select optgroup {
    font-size: .68rem; text-transform: uppercase; letter-spacing: .06em;
    /* Module 76: optgroup labels render inside the open menu, so these
       were light-on-light in dark mode. */
    color: var(--muted-2); font-weight: 700; font-style: normal;
    background: var(--canvas);
}
select optgroup option {
    font-size: .82rem; text-transform: none; letter-spacing: 0;
    color: #1b2a52; font-weight: 400; padding-left: .5rem;
}

/* A select that carries a status meaning (e.g. an attendance status picker)
   tints itself to match the chosen value. Add .sel-status and one s-* class. */
.sel-status.s-good { background: var(--s-good-bg); color: var(--s-good-fg); font-weight: 600; }
.sel-status.s-wait { background: var(--s-wait-bg); color: var(--s-wait-fg); font-weight: 600; }
.sel-status.s-stop { background: var(--s-stop-bg); color: var(--s-stop-fg); font-weight: 600; }
.sel-status.s-off  { background: var(--s-off-bg);  color: var(--s-off-fg); }
.sel-status.s-info { background: var(--s-info-bg); color: var(--s-info-fg); font-weight: 600; }

/* ---------------------------------------------------------------------------
   9. Empty state — say what the thing is and what to do, never just "No rows"
   --------------------------------------------------------------------------- */
.empty {
    text-align: center; padding: 2.2rem 1rem; color: #64748b;
    border: 1px dashed #d9dee7; border-radius: 12px; background: #fcfdfe;
}
.empty i { font-size: 2rem; color: #cbd5e1; display: block; margin-bottom: .4rem; }
.empty .empty-title { font-weight: 700; color: #334155; margin-bottom: .2rem; }

/* ---------------------------------------------------------------------------
   10. Print — colour survives, chrome does not
   --------------------------------------------------------------------------- */
@media print {
    .filters, .kpis, .no-print { display: none !important; }
    .rpt { font-size: 8pt; }
    .pill, .cell { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* ============================================================================
   11. Grid enhancements — paired with assets/reports.js
   Applies to any <table class="rpt-x">. Everything degrades gracefully: with
   JavaScript off the table still renders, just without sorting or filtering.
   ============================================================================ */

/* --- sticky header ------------------------------------------------------- */
/* Module 76: these were hardcoded #fff / #f8fafc / #e4e8ee. A sticky header
   and a frozen column MUST be opaque — that is the whole point, they paint
   over the rows scrolling underneath — so in dark mode they became bright
   white bands across a dark table, and the frozen first column a white
   stripe. Tokens, so prefs.css re-tunes them. */
.rpt-x thead th {
    position: sticky; top: 0; z-index: 3;
    background: var(--canvas);
    box-shadow: inset 0 -1px 0 var(--line);
}
/* Two-row header (dates then weekdays) — the second row sits below the first. */
.rpt-x thead tr:nth-child(2) th { top: 1.85rem; z-index: 2; }

/* --- frozen leading columns ---------------------------------------------- */
.rpt-x td.rpt-frozen, .rpt-x th.rpt-frozen {
    position: sticky; z-index: 2; background: var(--surface);
}
.rpt-x thead th.rpt-frozen { z-index: 4; background: var(--canvas); }
.rpt-x .rpt-frozen-last { box-shadow: 2px 0 0 -1px var(--line); }
.rpt-x tbody tr:hover td.rpt-frozen { background: var(--line-soft); }
.rpt-x tbody tr.rpt-odd td.rpt-frozen { background: var(--canvas); }

/* --- sortable headers ---------------------------------------------------- */
.rpt-x th.rpt-sortable { cursor: pointer; user-select: none; padding-right: 1.1em !important; position: relative; }
.rpt-x th.rpt-sortable:hover { color: #1b2a52; background: #eef2f7; }
.rpt-x th.rpt-sortable::after {
    content: "\2195"; position: absolute; right: .35em; opacity: .25; font-weight: 400;
}
.rpt-x th.sort-asc::after  { content: "\2191"; opacity: 1; color: var(--s-info-fg); }
.rpt-x th.sort-desc::after { content: "\2193"; opacity: 1; color: var(--s-info-fg); }
.rpt-x th.rpt-sortable:focus-visible { outline: 2px solid var(--s-info-fg); outline-offset: -2px; }

/* --- zebra + crosshair --------------------------------------------------- */
.rpt-x tbody tr.rpt-odd > td { background: #fcfdfe; }
.rpt-x tbody td.rpt-xh { background: #eef4ff !important; }
.rpt-x tbody tr:hover > td { background: #eaf1fb; }

/* --- toolbar above each grid --------------------------------------------- */
.rpt-toolbar {
    display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
    padding: .4rem .1rem .5rem;
}
.rpt-find { position: relative; display: inline-flex; align-items: center; }
.rpt-find i { position: absolute; left: .55rem; color: #9aa1ad; font-size: .8rem; pointer-events: none; }
.rpt-find input {
    height: 30px; width: 230px; padding: 0 .6rem 0 1.9rem;
    border: 1px solid #dfe3ea; border-radius: 8px; font-size: .78rem; background: #fff;
}
.rpt-find input:focus {
    outline: none; border-color: var(--s-info-fg);
    box-shadow: 0 0 0 3px var(--s-info-bg);
}
.rpt-count { font-size: .74rem; color: #64748b; }
.rpt-count.none { color: var(--s-stop-fg); font-weight: 600; }
.rpt-btn {
    margin-left: auto; height: 30px; padding: 0 .7rem;
    border: 1px solid #dfe3ea; background: #fff; border-radius: 8px;
    font-size: .76rem; color: #475569; cursor: pointer;
}
.rpt-btn:hover { border-color: #b9c2ce; background: #f8fafc; }

@media print {
    .rpt-x thead th, .rpt-x td.rpt-frozen, .rpt-x th.rpt-frozen { position: static; }
    .rpt-x th.rpt-sortable::after { content: none; }
}


/* ============================================================
   Module 65 — runtime overflow guard (see reports.js guardOverflow)
   A table wider than its container is wrapped in one of these at load,
   so no column can end up off the side of the screen.
   ============================================================ */
.rpt-autoscroll { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }
.rpt-autoscroll::-webkit-scrollbar { height: 9px; }
.rpt-autoscroll::-webkit-scrollbar-thumb { background: #cbd2dc; border-radius: 8px; }
.rpt-autoscroll::-webkit-scrollbar-track { background: #f1f3f6; }

/* ============================================================================
   Module 70 — dark mode for the report grids
   ----------------------------------------------------------------------------
   This file predates the theme tokens and writes 70 literal colours: whites for
   the sticky header and frozen columns, cool greys for muted text, and the five
   status shades. Rather than rewrite a working stylesheet — where a mistake
   breaks every report at once — the light values stay exactly as they were and
   this block re-states only what a dark background changes.

   The status COLOURS deliberately keep their meaning: green is still good, red
   is still stop. Only their lightness moves, so a report reads the same either
   way and a printout matches what was on screen.
   ============================================================================ */
[data-theme="dark"] .rpt thead th,
[data-theme="dark"] .rpt-x thead th {
    background: #1C212C;
    color: var(--ink-2);
    box-shadow: inset 0 -1px 0 var(--line);
}
[data-theme="dark"] .rpt tbody tr:hover > td { background: rgba(255,255,255,.045); }
[data-theme="dark"] .rpt td,
[data-theme="dark"] .rpt th { border-color: var(--line); }

/* Sticky header and frozen first columns sit ON TOP of scrolling content, so
   they must be opaque — a transparent freeze shows the rows sliding under it. */
[data-theme="dark"] .rpt-x th.freeze,
[data-theme="dark"] .rpt-x td.freeze { background: var(--surface); }
[data-theme="dark"] .rpt-x thead th.freeze { background: #1C212C; }
[data-theme="dark"] .rpt-x td.freeze { box-shadow: 2px 0 0 -1px var(--line); }

[data-theme="dark"] .kpis .kpi,
[data-theme="dark"] .filters { background: var(--surface); border-color: var(--line); }
[data-theme="dark"] .kpi-l   { color: var(--muted); }
[data-theme="dark"] .rpt-count,
[data-theme="dark"] .rpt-sub { color: var(--muted); }
[data-theme="dark"] .rpt-toolbar { background: #1C212C; border-color: var(--line); }
[data-theme="dark"] .rpt-find input { background: #10141C; border-color: var(--line); color: var(--ink); }
[data-theme="dark"] .rpt-btn { background: transparent; border-color: var(--line); color: var(--ink-2); }
[data-theme="dark"] .rpt-btn:hover { background: rgba(255,255,255,.07); color: var(--ink); }

[data-theme="dark"] .empty {
    background: rgba(255,255,255,.02);
    border-color: var(--line);
    color: var(--muted);
}

/* Crosshair: the light version is a pale wash, invisible on a dark surface. */
[data-theme="dark"] .rpt-xh { background: rgba(255,255,255,.06) !important; }

/* ---- the five states ---------------------------------------------------- */
[data-theme="dark"] {
    --s-good-bg: #12301F;  --s-good-fg: #6EE7A8;  --s-good-bd: #1E5237;
    --s-wait-bg: #35280D;  --s-wait-fg: #F0C46A;  --s-wait-bd: #5A4413;
    --s-stop-bg: #3A1B18;  --s-stop-fg: #F79389;  --s-stop-bd: #622C27;
    --s-off-bg:  #232833;  --s-off-fg:  #98A0B0;  --s-off-bd:  #333A47;
    --s-info-bg: #12293A;  --s-info-fg: #7FC2EC;  --s-info-bd: #1D4560;
}

/* Row tints behind a whole row need to be far weaker than a pill's fill, or
   the row shouts louder than the data in it. */
[data-theme="dark"] .row-good > td { background: rgba(110,231,168,.055); }
[data-theme="dark"] .row-wait > td { background: rgba(240,196,106,.055); }
[data-theme="dark"] .row-stop > td { background: rgba(247,147,137,.06); }
[data-theme="dark"] .row-off  > td { background: rgba(152,160,176,.05); }
