/* =====================================================================
   LexLearn Admin — dark blue and white
   ---------------------------------------------------------------------
   Loaded last on every /admin page, over Listeo's own stylesheet. The
   student side never loads this file and keeps the Citytours template's
   own visual language untouched.

   An enterprise console, not a marketing site. What that means here:

     NAVY IS CHROME       The sidebar and the header strip are navy. They
                          are furniture: always there, never competing
                          with the content. Everything the admin actually
                          works on sits on white.

     BLUE IS ACTION       One blue, used for exactly two things — the
                          primary action on a screen, and the active
                          item in the navigation. A blue thing is a thing
                          you can press or are currently inside.

     COLOUR IS STATE      Green, amber and red mean good, needs
                          attention, and wrong. They are never used for
                          decoration and never for a series in a chart,
                          so a red cell in a table always means the same
                          thing wherever it appears.

     STATUS IS NOT COLOUR ALONE  Every status chip carries a glyph and a
                          word as well as its colour, so it survives a
                          photocopy, a projector and colour-blindness.

   Charts: one blue series, or a two-part proportion with both parts
   directly labelled. Status colours are reserved and never reused as
   "series 2". See js/admin/charts.js.

   Contrast, measured rather than eyeballed: navy/white 15.5, blue/white
   6.5, body 9.7, muted 4.7, every status colour above 5 on white and
   above 5.3 on its own tint, form borders 3.2 against white.
   ===================================================================== */

:root {
  /* ---- chrome ---- */
  --ad-navy:       #16243f;   /* sidebar, header strip                 */
  --ad-navy-2:     #1e3154;   /* navy hover                            */
  --ad-navy-line:  rgba(255,255,255,.10);

  /* ---- ink ---- */
  --ad-ink:        #16243f;   /* headings                      15.5:1  */
  --ad-body:       #3a4557;   /* body copy                      9.7:1  */
  --ad-muted:      #697488;   /* secondary text                 4.7:1  */
  --ad-faint:      #8b95a6;   /* axis ticks, placeholders       3.0:1  */

  /* ---- action ---- */
  --ad-blue:       #1f57c3;   /* primary action, active nav     6.5:1  */
  --ad-blue-dark:  #17439a;   /* pressed                        9.1:1  */
  --ad-blue-soft:  #e9f0fb;   /* tint behind a selected row            */

  /* ---- state ---- */
  --ad-good:       #00796b;   /* active, published, captured    5.3:1  (teal, 2026-10-09; was #15683e) */
  --ad-good-soft:  #e6f2f0;
  --ad-warn:       #8a5a00;   /* needs attention, pending       5.9:1  */
  --ad-warn-soft:  #fbf2df;
  --ad-bad:        #b3271b;   /* failed, refused, delete        6.5:1  */
  --ad-bad-soft:   #fbeae8;

  /* ---- surfaces, light to dark ---- */
  --ad-0:  #ffffff;           /* cards                                 */
  --ad-1:  #f6f8fb;           /* page ground                           */
  --ad-2:  #eef2f8;           /* zebra rows, quiet fills               */
  --ad-3:  #e4eaf3;           /* hairline grid                         */
  --ad-4:  #dfe4ec;           /* borders                               */
  --ad-5:  #8592a6;           /* control outlines               3.2:1  */
  --ad-6:  #6b7686;
  --ad-7:  #566173;
  --ad-8:  #3a4557;
  --ad-9:  #27324a;
  --ad-10: #16243f;

  --ad-radius: 3px;
}

/* =====================================================================
   1. GROUND AND CHROME
   ===================================================================== */
body, #wrapper                    { background: var(--ad-1); color: var(--ad-body); }
#dashboard                        { background: var(--ad-1); }
/* #dashboard is a flex row. A flex item defaults to min-width:auto, so a
   wide table sets the content column's minimum size and pushes the whole
   page sideways instead of scrolling inside its own wrapper. This is the
   one line that stops that. */
.dashboard-content                { min-width: 0; }

/* the header strip */
#header-container.dashboard,
#header-container.dashboard #header,
header#header-container           { background: var(--ad-navy) !important; }
#header-container .left-side,
#header-container .right-side     { background: transparent; }
#header-container a,
#header-container .user-name      { color: #fff; }
/* Header readability (2026-10-08). The template's own menu colour (#444) out-ranked the white above, and that
   white also reached the links inside the white user-menu dropdown (white on white). The template also put the
   logo in a grey box (a white one at 1280 px and below); the light logo now sits on the navy bar at every width. */
#header-container #navigation.style-1 > ul > li > a                { color: rgba(255, 255, 255, .82); }
#header-container #navigation.style-1 > ul > li > a:hover,
#header-container #navigation.style-1 > ul > li > a.current        { color: #fff; }
#header-container .user-menu ul                                    { z-index: 1100; }
#header-container .user-menu ul li a                               { color: var(--ad-ink); text-decoration: none; }
#header-container .user-menu ul li a:hover                         { color: var(--ad-navy); }
#header-container.dashboard #logo                                  { background-color: transparent; }
#header-container.dashboard #logo a                                { display: none; }
#header-container.dashboard #logo a.dashboard-logo                 { display: inline-block; }

/* the side navigation */
.dashboard-nav                    { background: var(--ad-navy); }
.dashboard-nav ul li a            { color: #b9c4d6; font-weight: 600; }
.dashboard-nav ul li a:hover      { color: #fff; background: var(--ad-navy-2); }
/* The active item is the one place blue appears in the chrome: a blue
   row with a blue rule down its left edge, so the eye finds "where am I"
   in one movement rather than by reading. */
.dashboard-nav ul li.active a,
.dashboard-nav ul li a.active     { color: #fff; background: var(--ad-blue);
                                    font-weight: 800; box-shadow: inset 3px 0 0 #fff; }
.dashboard-nav ul li.active a i   { color: #fff; }
.dashboard-nav ul[data-submenu-title]:before {
  color: #7d8ca5; font-weight: 800;
  letter-spacing: .16em; text-transform: uppercase; font-size: 11px;
}
.dashboard-nav-inner              { border-right: 1px solid var(--ad-navy-line); }

/* =====================================================================
   2. TYPE
   Admin work is reading tables. Type is set for density and scanning,
   not for display.
   ===================================================================== */
body, .dashboard-content          { font-size: 14.5px; line-height: 1.6; }
h1, h2, h3, h4, h5                { color: var(--ad-ink); font-weight: 800; letter-spacing: -.01em; }
h1                                { font-size: 27px; }
h2                                { font-size: 22px; }
h3                                { font-size: 18px; }
h4                                { font-size: 15.5px; }
#titlebar h2, #titlebar h1        { color: var(--ad-ink); }
#titlebar span, #titlebar a       { color: var(--ad-muted); }
#breadcrumbs ul li a              { color: var(--ad-muted); }
#breadcrumbs ul li                { color: var(--ad-ink); }

.lex-eyebrow, .lex-kicker {
  display: inline-block; font-size: 11px; font-weight: 800;
  letter-spacing: .18em; text-transform: uppercase; color: var(--ad-muted);
  margin-bottom: 8px;
}
.lex-help                         { font-size: 13px; color: var(--ad-muted); line-height: 1.55; }

/* =====================================================================
   3. CARDS AND PANELS
   ===================================================================== */
.dashboard-list-box, .lex-panel, .notification, .dashboard-stat {
  background: var(--ad-0);
  border: 1px solid var(--ad-4);
  border-radius: var(--ad-radius);
  box-shadow: none;
}
.dashboard-list-box-headline, .lex-panel-head {
  background: var(--ad-0);
  border-bottom: 1px solid var(--ad-4);
  padding: 16px 22px;
}
.dashboard-list-box-headline h4, .lex-panel-head h4 {
  font-size: 13px; font-weight: 800; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ad-ink); margin: 0;
}
.lex-panel-head                   { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.lex-panel-head .lex-panel-actions { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }
.lex-panel-body                   { padding: 22px; }
.lex-panel-body--flush            { padding: 0; }

/* =====================================================================
   4. STAT TILES
   The number is the chart. Proportional figures, not tabular — at this
   size equal-width digits read loose.
   ===================================================================== */
.dashboard-stat, .lex-stat {
  padding: 20px 22px; background: var(--ad-0);
  border: 1px solid var(--ad-4); border-radius: var(--ad-radius);
}
.lex-stat-value, .dashboard-stat-content h4 {
  font-size: 34px; font-weight: 800; color: var(--ad-ink);
  line-height: 1.05; letter-spacing: -.02em; font-variant-numeric: proportional-nums;
}
.lex-stat-label, .dashboard-stat-content span {
  display: block; font-size: 11.5px; font-weight: 800; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ad-muted); margin-top: 10px;
}
.lex-stat-sub                     { display: block; font-size: 13px; color: var(--ad-muted); margin-top: 6px; }
.lex-stat--lead                   { border-left: 4px solid var(--ad-ink); }
.lex-delta                        { font-size: 13px; font-weight: 700; color: var(--ad-muted); }
.lex-delta:before                 { font-weight: 800; margin-right: 4px; }
.lex-delta.is-up:before           { content: "\2191"; color: var(--ad-ink); }
.lex-delta.is-down:before         { content: "\2193"; color: var(--ad-ink); }
.lex-delta.is-flat:before         { content: "\2192"; }

/* =====================================================================
   5. TABLES — the console's main instrument
   ===================================================================== */
table.basic-table, table.lex-table {
  width: 100%; border-collapse: collapse; background: var(--ad-0);
  font-size: 14px;
}
table.basic-table th, table.lex-table th {
  background: var(--ad-0); color: var(--ad-ink);
  font-size: 11.5px; font-weight: 800; letter-spacing: .12em; text-transform: uppercase;
  text-align: left; padding: 13px 16px;
  border-bottom: 2px solid var(--ad-ink); white-space: nowrap;
}
table.basic-table td, table.lex-table td {
  padding: 13px 16px; border-bottom: 1px solid var(--ad-3);
  color: var(--ad-body); vertical-align: middle;
}
table.basic-table tbody tr:nth-child(even) td,
table.lex-table tbody tr:nth-child(even) td { background: var(--ad-1); }
table.basic-table tbody tr:hover td,
table.lex-table tbody tr:hover td { background: var(--ad-2); }
.lex-table-wrap                   { overflow-x: auto; }
.lex-cell-strong                  { font-weight: 800; color: var(--ad-ink); }
.lex-cell-sub                     { display: block; font-size: 12.5px; color: var(--ad-muted); margin-top: 2px;
                                    overflow-wrap: anywhere; /* long emails wrap instead of widening the table */ }
/* Laptop widths: a little less air per cell so wide tables fit their card. */
@media (max-width: 1600px) {
  table.basic-table th, table.lex-table th,
  table.basic-table td, table.lex-table td { padding-left: 10px; padding-right: 10px; }
  table.basic-table th, table.lex-table th { letter-spacing: .06em; }
}
/* Compact, one-line rows (2026-10-09). A record is one row of cells that each hold one line:
   dates, kinds, audiences, counts, status chips and the action buttons never wrap. The title and its
   optional second line (an email, an id, a description) keep to one line each and are cut with an
   ellipsis at a set width; LexUI puts the full text in a tooltip when it was cut. Wide tables scroll
   inside .lex-table-wrap (the existing narrow-screen strategy) instead of growing tall. */
table.basic-table td, table.lex-table td { padding-top: 9px; padding-bottom: 9px; white-space: nowrap; }
table.basic-table th, table.lex-table th { padding-top: 11px; padding-bottom: 11px; }
table.lex-table td .lex-cell-strong,
table.lex-table td .lex-cell-sub  { display: block; max-width: 340px; overflow: hidden; text-overflow: ellipsis;
                                    white-space: nowrap; overflow-wrap: normal; }
table.lex-table td .lex-cell-sub  { margin-top: 1px; }
/* Plain long text (a university, an audience, a location) is cut at a sensible column width too.
   Cells that hold controls, chips or bars keep their natural width and are never clipped. */
table.lex-table td                { max-width: 240px; overflow: hidden; text-overflow: ellipsis; }
table.lex-table td:has(.lex-btn-row, .lex-btn, button, input, select, textarea, .lex-chip, .lex-badge, .lex-progress,
                       .lex-cell-strong, .lex-cell-sub) {
  max-width: none; overflow: visible;
}
@media (max-width: 1600px) {
  table.lex-table td .lex-cell-strong,
  table.lex-table td .lex-cell-sub { max-width: 230px; }
  table.lex-table td               { max-width: 200px; }
}
@media (max-width: 1440px) {
  table.basic-table th, table.lex-table th,
  table.basic-table td, table.lex-table td { padding-left: 8px; padding-right: 8px; }
  table.lex-table td .lex-cell-strong,
  table.lex-table td .lex-cell-sub { max-width: 190px; }
  table.lex-table td               { max-width: 160px; }
  table.lex-table .lex-btn-row     { gap: 6px; }
}
table.lex-table .lex-btn-row      { flex-wrap: nowrap; gap: 8px; }
table.lex-table .lex-chip,
table.lex-table .lex-badge        { white-space: nowrap; }
.lex-num                          { text-align: right; font-variant-numeric: tabular-nums; }
th.lex-num                        { text-align: right; }
.lex-table-foot {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 14px 16px; border-top: 1px solid var(--ad-4); font-size: 13px; color: var(--ad-muted);
}
.lex-table-foot .lex-pager        { margin-left: auto; display: flex; gap: 6px; }

/* sortable headers */
th[data-sort]                     { cursor: pointer; user-select: none; }
th[data-sort]:after               { content: "\2195"; margin-left: 7px; opacity: .3; font-weight: 700; }
th[data-sort].is-asc:after        { content: "\2191"; opacity: 1; }
th[data-sort].is-desc:after       { content: "\2193"; opacity: 1; }

/* =====================================================================
   6. STATUS — fill, outline, or dotted. Never hue.
   ===================================================================== */
.lex-chip {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11.5px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  padding: 4px 10px; border-radius: 999px; white-space: nowrap;
  border: 1.5px solid var(--ad-ink); color: var(--ad-ink); background: transparent;
}
/* Colour is the fast signal; the glyph and the word are what survive a
   photocopy, a projector and colour-blindness. All three, always. */
.lex-chip--solid                  { background: var(--ad-good-soft); color: var(--ad-good);
                                    border-color: var(--ad-good); }
.lex-chip--quiet                  { background: var(--ad-2); color: var(--ad-muted);
                                    border-color: var(--ad-5); }
.lex-chip--dotted                 { background: var(--ad-0); border-style: dashed;
                                    color: var(--ad-muted); border-color: var(--ad-6); }
.lex-chip--warn                   { background: var(--ad-warn-soft); color: var(--ad-warn);
                                    border-color: var(--ad-warn); }
.lex-chip--bad                    { background: var(--ad-bad-soft); color: var(--ad-bad);
                                    border-color: var(--ad-bad); }
.lex-chip--info                   { background: var(--ad-blue-soft); color: var(--ad-blue);
                                    border-color: var(--ad-blue); }
.lex-chip:before                  { font-size: 13px; line-height: 1; }
.lex-chip--solid:before           { content: "\25CF"; }          /* active, published  */
.lex-chip--quiet:before           { content: "\25CB"; }          /* inactive           */
.lex-chip--dotted:before          { content: "\25CC"; }          /* draft              */
.lex-chip--warn:before            { content: "\26A0"; }          /* needs attention    */
.lex-chip--bad:before             { content: "\2715"; }          /* failed, refused    */
.lex-chip--info:before            { content: "\25D0"; }          /* scheduled          */

/* =====================================================================
   7. BUTTONS
   ===================================================================== */
.button, a.button, button.button, .lex-btn {
  background: var(--ad-blue); color: #fff;
  border: 2px solid var(--ad-blue); border-radius: var(--ad-radius);
  font-size: 13px; font-weight: 800; letter-spacing: .04em;
  padding: 10px 18px; line-height: 1.2; cursor: pointer;
  transition: background .15s ease, color .15s ease, transform .15s ease;
}
.button:hover, .lex-btn:hover     { background: var(--ad-blue-dark); color: #fff; transform: translateY(-1px); }
.button.border, .lex-btn--ghost {
  background: transparent; color: var(--ad-ink); border-color: var(--ad-ink);
}
.button.border:hover, .lex-btn--ghost:hover { background: var(--ad-blue); border-color: var(--ad-blue); color: #fff; }
.lex-btn--quiet                   { background: transparent; color: var(--ad-muted); border-color: var(--ad-5); }
.lex-btn--quiet:hover             { color: var(--ad-blue); border-color: var(--ad-blue); background: transparent; }
.lex-btn--sm                      { padding: 6px 12px; font-size: 12px; }
/* A destructive action is not a colour here — it is underlined, and it
   always asks first. */
/* Destructive actions are outlined in red, never filled: a red block is
   the easiest thing on a screen to hit by accident. The fill arrives on
   hover, after the pointer has committed, and a confirmation still
   stands in front of it. */
.lex-btn--danger                  { background: transparent; color: var(--ad-bad); border-color: var(--ad-bad); }
.lex-btn--danger:hover            { background: var(--ad-bad); color: #fff; }
/* Archive is not delete, and must not look like it. */
.lex-btn--archive                 { background: transparent; color: var(--ad-warn); border-color: var(--ad-warn); }
.lex-btn--archive:hover           { background: var(--ad-warn); color: #fff; }
.lex-btn[disabled], .button[disabled] { opacity: .45; cursor: not-allowed; transform: none; }
.lex-btn-row                      { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }

/* =====================================================================
   8. FORMS
   ===================================================================== */
label                             { font-size: 12.5px; font-weight: 800; letter-spacing: .06em;
                                    text-transform: uppercase; color: var(--ad-ink); margin-bottom: 7px; display: block; }
input[type=text], input[type=email], input[type=password], input[type=number],
input[type=date], input[type=datetime-local], input[type=search], input[type=file],
select, textarea {
  width: 100%; background: var(--ad-0); color: var(--ad-body);
  border: 1.5px solid var(--ad-5); border-radius: var(--ad-radius);
  padding: 11px 13px; font-size: 14.5px; box-shadow: none;
  box-sizing: border-box;   /* bootstrap-grid makes type=search content-box, so width:100% overflowed */
}
input:focus, select:focus, textarea:focus {
  border-color: var(--ad-ink); outline: 2px solid var(--ad-4); outline-offset: 1px;
}
input::placeholder, textarea::placeholder { color: var(--ad-faint); }
.lex-field                        { margin-bottom: 18px; }
.lex-field-hint                   { font-size: 12.5px; color: var(--ad-muted); margin-top: 6px; }
/* display:block here beats the browser's own [hidden] rule, so the
   element has to be hidden explicitly — otherwise every untouched field
   on a fresh form shows a warning glyph with no message beside it. */
.lex-field-error                  { font-size: 12.5px; font-weight: 700; color: var(--ad-bad);
                                    margin-top: 6px; display: block; }
.lex-field-error[hidden]          { display: none; }
.lex-field-error:before           { content: "\26A0 "; }
.has-error label                  { color: var(--ad-bad); }
.has-error input, .has-error select, .has-error textarea {
  border-color: var(--ad-bad) !important; border-width: 2px !important;
  background: var(--ad-bad-soft);
}
fieldset                          { border: 0; padding: 0; margin: 0 0 26px; }
.lex-form-grid                    { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 22px; }
.lex-form-grid--3                 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.lex-form-grid .lex-field--full   { grid-column: 1 / -1; }
@media (max-width: 800px) { .lex-form-grid, .lex-form-grid--3 { grid-template-columns: 1fr; } }

/* =====================================================================
   9. FILTER ROW — one row above everything it scopes, never per card
   ===================================================================== */
.lex-filters {
  display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end;
  padding: 16px 18px; background: var(--ad-0);
  border: 1px solid var(--ad-4); border-radius: var(--ad-radius); margin-bottom: 22px;
}
.lex-filters .lex-field           { margin: 0; min-width: 170px; flex: 0 1 auto; }
.lex-filters label                { font-size: 11px; }
.lex-filters .lex-filter-actions  { margin-left: auto; display: flex; gap: 8px; }
.lex-filters input, .lex-filters select { padding: 8px 11px; font-size: 13.5px; }

/* =====================================================================
   10. BANNERS AND EMPTY STATES
   ===================================================================== */
.lex-note {
  border: 1px solid var(--ad-4); border-left: 4px solid var(--ad-ink);
  background: var(--ad-0); padding: 14px 18px; border-radius: var(--ad-radius);
  font-size: 14px; margin-bottom: 20px;
}
.lex-note strong                  { color: var(--ad-ink); }
.lex-note--quiet                  { border-left-color: var(--ad-5); color: var(--ad-muted); }
.lex-note--warn                   { border-left-color: var(--ad-bad); background: var(--ad-bad-soft);
                                    color: var(--ad-bad); }
.lex-note--info                   { border-left-color: var(--ad-blue); background: var(--ad-blue-soft); }
.lex-note--good                   { border-left-color: var(--ad-good); background: var(--ad-good-soft); }
.lex-note--warn:before            { content: "\26A0"; font-weight: 800; margin-right: 8px; }

.lex-empty {
  text-align: center; padding: 52px 24px; border: 1px dashed var(--ad-5);
  border-radius: var(--ad-radius); background: var(--ad-0);
}
.lex-empty h4                     { margin: 0 0 8px; }
.lex-empty p                      { color: var(--ad-muted); margin: 0 auto 18px; max-width: 420px; }

/* =====================================================================
   11. THE HIERARCHY BROWSER
   Tenant › College › Semester › Subject › Unit, as four linked columns.
   ===================================================================== */
/* The hierarchy browser. Four columns by default; five when the course
   adds a Year level above the semester. */
.lex-tree                         { display: grid; grid-template-columns: repeat(4, minmax(0,1fr));
                                    gap: 0; border: 1px solid var(--ad-4); border-radius: var(--ad-radius);
                                    background: var(--ad-0); overflow: hidden; }
.lex-tree-col                     { border-right: 1px solid var(--ad-4); min-height: 420px; display: flex; flex-direction: column; }
.lex-tree-col:last-child          { border-right: 0; }
.lex-tree-head {
  padding: 12px 16px; border-bottom: 1px solid var(--ad-4);
  font-size: 11px; font-weight: 800; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ad-muted); display: flex; align-items: center; gap: 8px;
}
.lex-tree-head .lex-tree-count    { margin-left: auto; color: var(--ad-ink); }
.lex-tree-list                    { flex: 1; overflow-y: auto; max-height: 460px; }
.lex-tree-item {
  display: block; width: 100%; text-align: left; background: transparent;
  border: 0; border-bottom: 1px solid var(--ad-3);
  padding: 11px 16px; font-size: 13.5px; color: var(--ad-body); cursor: pointer;
}
.lex-tree-item:hover              { background: var(--ad-2); }
.lex-tree-item.is-on              { background: var(--ad-ink); color: #fff; font-weight: 700; }
.lex-tree-item.is-on .lex-tree-meta { color: rgba(255,255,255,.7); }
.lex-tree-meta                    { display: block; font-size: 12px; color: var(--ad-muted); margin-top: 2px; }
.lex-tree-foot                    { padding: 12px 16px; border-top: 1px solid var(--ad-4); }
.lex-tree--5                      { grid-template-columns: repeat(5, minmax(0,1fr)); }
@media (max-width: 1400px) { .lex-tree--5 { grid-template-columns: repeat(3, minmax(0,1fr)); } }
@media (max-width: 1100px) { .lex-tree, .lex-tree--5 { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 700px)  { .lex-tree, .lex-tree--5 { grid-template-columns: 1fr; } }

/* =====================================================================
   12. CHARTS
   The module draws inline SVG; this is its skin. Grid and axes are
   solid hairlines one shade off the surface — never dashed.
   ===================================================================== */
.lex-chart                        { position: relative; }
.lex-chart svg                    { display: block; width: 100%; overflow: visible; }
.lex-chart .grid line             { stroke: var(--ad-3); stroke-width: 1; }
.lex-chart .axis line,
.lex-chart .axis path             { stroke: var(--ad-4); stroke-width: 1; }
.lex-chart .tick                  { font-size: 11.5px; fill: var(--ad-faint); font-variant-numeric: tabular-nums; }
/* One series, one colour. Blue is the data; a quiet bar is the same
   family, lightened, and never a second hue — hue in this console means
   state, and a bar is not a state. */
.lex-chart .bar                   { fill: var(--ad-blue); }
.lex-chart .bar.is-quiet          { fill: #a9bfe6; }
.lex-chart .line                  { fill: none; stroke: var(--ad-blue); stroke-width: 2;
                                    stroke-linejoin: round; stroke-linecap: round; }
.lex-chart .area                  { fill: #e3ecfa; }
.lex-chart .dot                   { fill: var(--ad-blue); stroke: var(--ad-0); stroke-width: 2; }
.lex-chart .label                 { font-size: 12px; font-weight: 700; fill: var(--ad-ink); }
.lex-chart .label--out            { fill: var(--ad-muted); }
.lex-chart-caption                { font-size: 12.5px; color: var(--ad-muted); margin: 10px 0 0; }
.lex-chart-hit                    { fill: transparent; cursor: crosshair; }

.lex-tip {
  position: absolute; pointer-events: none; z-index: 20;
  background: var(--ad-ink); color: #fff; border-radius: var(--ad-radius);
  padding: 8px 11px; font-size: 12.5px; line-height: 1.45; white-space: nowrap;
  transform: translate(-50%, -120%); opacity: 0; transition: opacity .12s ease;
}
.lex-tip.is-on                    { opacity: 1; }
.lex-tip b                        { font-weight: 800; }

/* the proportion bar — two parts, both labelled, one textured */
.lex-prop                         { display: flex; height: 34px; border: 1px solid var(--ad-blue);
                                    border-radius: var(--ad-radius); overflow: hidden; background: var(--ad-0); }
.lex-prop span                    { display: flex; align-items: center; justify-content: center;
                                    font-size: 12.5px; font-weight: 800; white-space: nowrap; }
.lex-prop .p-a                    { background: var(--ad-blue); color: #fff; }
.lex-prop .p-b                    { background: var(--ad-0); color: var(--ad-blue);
                                    background-image: repeating-linear-gradient(135deg,
                                      var(--ad-4) 0 3px, transparent 3px 7px);
                                    border-left: 2px solid var(--ad-0); }
.lex-prop-key                     { display: flex; gap: 20px; flex-wrap: wrap; margin-top: 12px;
                                    font-size: 13px; color: var(--ad-muted); }
/* The legend swatch has to be the same fill as the bar it labels —
   a legend that does not match its own chart is worse than none. */
.lex-prop-key i                   { display: inline-block; width: 13px; height: 13px; margin-right: 7px;
                                    vertical-align: -2px; border: 1px solid var(--ad-blue); }
.lex-prop-key .k-a i              { background: var(--ad-blue); }
.lex-prop-key .k-b i              { background-image: repeating-linear-gradient(135deg,
                                      var(--ad-blue) 0 2px, transparent 2px 5px); }

/* every chart ships a table twin */
.lex-chart-table                  { margin-top: 16px; border-top: 1px solid var(--ad-4); }
.lex-chart-table[hidden]          { display: none; }
.lex-chart-toggle {
  background: transparent; border: 0; padding: 4px 0; cursor: pointer;
  font-size: 12.5px; font-weight: 700; color: var(--ad-muted);
  text-decoration: underline; text-underline-offset: 3px;
}
.lex-chart-toggle:hover           { color: var(--ad-ink); }

/* =====================================================================
   13. THE IMPORT WORKFLOW
   ===================================================================== */
.lex-steps                        { display: flex; gap: 0; margin-bottom: 24px; border: 1px solid var(--ad-4);
                                    border-radius: var(--ad-radius); overflow: hidden; background: var(--ad-0); }
.lex-steps li                     { flex: 1; list-style: none; padding: 14px 18px; display: flex; gap: 10px;
                                    align-items: center; font-size: 13.5px; font-weight: 700;
                                    color: var(--ad-muted); border-right: 1px solid var(--ad-4); }
.lex-steps li:last-child          { border-right: 0; }
.lex-steps li b                   { width: 24px; height: 24px; border-radius: 50%; flex: 0 0 auto;
                                    border: 1.5px solid var(--ad-5); display: flex; align-items: center;
                                    justify-content: center; font-size: 12px; }
.lex-steps li.is-on               { color: var(--ad-ink); background: var(--ad-2); }
.lex-steps li.is-on b             { background: var(--ad-ink); color: #fff; border-color: var(--ad-ink); }
.lex-steps li.is-done b:after     { content: "\2713"; }
.lex-steps li.is-done b           { font-size: 0; }

.lex-drop {
  border: 2px dashed var(--ad-5); border-radius: var(--ad-radius);
  padding: 44px 24px; text-align: center; background: var(--ad-0);
}
.lex-drop.is-over                 { border-color: var(--ad-ink); background: var(--ad-2); }
.lex-drop h4                      { margin: 0 0 6px; }
.lex-drop p                       { color: var(--ad-muted); margin: 0 0 16px; }

/* row outcomes in the validation table — shape, not colour */
/* The five outcomes of an import row. Colour carries the difference at
   a glance; the word in the outcome column carries it for certain. */
tr.row-create td                  { box-shadow: inset 3px 0 0 var(--ad-good); }
tr.row-update td                  { box-shadow: inset 3px 0 0 var(--ad-blue); }
tr.row-archive td                 { box-shadow: inset 3px 0 0 var(--ad-warn); background: var(--ad-warn-soft); }
tr.row-delete td                  { box-shadow: inset 3px 0 0 var(--ad-bad); }
tr.row-create .lex-outcome        { color: var(--ad-good); }
tr.row-update .lex-outcome        { color: var(--ad-blue); }
tr.row-archive .lex-outcome       { color: var(--ad-warn); }
tr.row-delete .lex-outcome        { color: var(--ad-bad); }
tr.row-reject .lex-outcome        { color: var(--ad-bad); }
/* A refused row is hatched as well as red. The hatch is what makes it
   obviously "not going to happen" on a printout and to a reader who
   cannot see the red at all. */
tr.row-reject td                  { background: repeating-linear-gradient(135deg,
                                      var(--ad-bad-soft) 0 6px, var(--ad-0) 6px 12px) !important; }
tr.row-reject td:first-child      { box-shadow: inset 3px 0 0 var(--ad-bad); }
.lex-outcome                      { font-size: 11.5px; font-weight: 800; letter-spacing: .08em;
                                    text-transform: uppercase; }

/* =====================================================================
   14. MISC
   ===================================================================== */
.lex-kv                           { display: grid; grid-template-columns: minmax(120px, 34%) 1fr; gap: 10px 18px; }
.lex-kv dt                        { font-size: 11.5px; font-weight: 800; letter-spacing: .1em;
                                    text-transform: uppercase; color: var(--ad-muted); }
.lex-kv dd                        { margin: 0; color: var(--ad-ink); font-weight: 600; }
.lex-split                        { display: grid; grid-template-columns: 2fr 1fr; gap: 22px; align-items: start; }
@media (max-width: 1000px) { .lex-split { grid-template-columns: 1fr; } }
.lex-grid-4                       { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 18px; }
.lex-grid-3                       { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 18px; }
.lex-grid-2                       { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 18px; }
@media (max-width: 1100px) { .lex-grid-4 { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 760px)  { .lex-grid-4, .lex-grid-3, .lex-grid-2 { grid-template-columns: 1fr; } }
.lex-mb-0                         { margin-bottom: 0; }
.lex-mt-24                        { margin-top: 24px; }

a                                 { color: var(--ad-ink); text-decoration: underline;
                                    text-underline-offset: 2px; text-decoration-thickness: 1px; }
a:hover                           { text-decoration-thickness: 2px; }
.dashboard-nav a, .button, .lex-btn, .lex-chip, .lex-tree-item { text-decoration: none; }

*:focus-visible                   { outline: 3px solid var(--ad-ink); outline-offset: 2px; }

@media print {
  .dashboard-nav, #header-container, .lex-filters, .lex-btn-row { display: none !important; }
  .lex-chart-table[hidden]        { display: table !important; }
  body                            { background: #fff; }
}

/* horizontal bars — the label and the value sit outside the track, so a
   short bar can never clip its own text */
.lex-hbar                         { display: grid; grid-template-columns: minmax(120px, 30%) 1fr auto;
                                    gap: 14px; align-items: center; padding: 9px 0;
                                    border-bottom: 1px solid var(--ad-3); }
.lex-hbar:last-child              { border-bottom: 0; }
.lex-hbar-label                   { font-size: 13.5px; font-weight: 600; color: var(--ad-body);
                                    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lex-hbar-track                   { background: var(--ad-3); height: 14px; border-radius: 2px; display: block; }
.lex-hbar-fill                    { background: var(--ad-blue); height: 14px; display: block;
                                    border-radius: 2px 4px 4px 2px; }
.lex-hbar-value                   { font-size: 13.5px; font-weight: 800; color: var(--ad-ink);
                                    font-variant-numeric: tabular-nums; min-width: 64px; text-align: right; }

/* ===================================================================
   26. THE SIGN-IN CARD
   Every screen outside the dashboard shell — sign in, forgot password,
   reset password — is this one card on a plain ground. It is the only
   admin page a person sees before they are authenticated, so it says
   what the console is for and nothing else.
   =================================================================== */
body.lex-admin-login              { background: var(--ad-2); margin: 0; padding: 0; }
body.lex-admin-login #wrapper     { min-height: 100vh; }
.lex-login-wrap                   { min-height: 100vh; display: flex; align-items: center;
                                    justify-content: center; padding: 48px 16px; }
.lex-login-card {
  width: 100%; max-width: 440px; background: var(--ad-0);
  border: 1px solid var(--ad-4); border-radius: var(--ad-radius);
  padding: 40px 36px; box-shadow: 0 1px 0 var(--ad-3);
}
.lex-login-card h1                { font-size: 26px; font-weight: 800; color: var(--ad-ink);
                                    margin: 4px 0 10px; letter-spacing: -.01em; }
.lex-login-card img               { display: block; }
.lex-login-card .lex-field        { margin-bottom: 18px; }
.lex-login-card form              { margin-top: 26px; }
@media (max-width: 480px) { .lex-login-card { padding: 30px 22px; } }

/* ===================================================================
   27. TOASTS AND THE CONFIRM DIALOG, IN GREYSCALE
   These come from the shared component sheet, which is built on the
   student palette. Inside the console they are restated in black and
   white so a confirmation never arrives in a colour nothing else uses.
   =================================================================== */
#dashboard .lex-toast, body.lex-admin-login .lex-toast,
.lex-admin .lex-toast {
  background: var(--ad-ink); color: #fff; border-left: 3px solid var(--ad-0);
  border-radius: var(--ad-radius);
}
.lex-toast--warn, .lex-toast--error { border-left-color: var(--ad-6); }
.lex-modal {
  background: var(--ad-0); border: 1px solid var(--ad-4); border-radius: var(--ad-radius);
}
.lex-modal h3                     { color: var(--ad-ink); }
.lex-modal p                      { color: var(--ad-body); }
.lex-modal .lex-btn-ghost {
  background: transparent; border: 1px solid var(--ad-5); color: var(--ad-ink);
  border-radius: var(--ad-radius); padding: 10px 18px; font-weight: 700; cursor: pointer;
}

/* ===================================================================
   28. TEXTAREAS
   The question editor is the one place an admin writes prose, so it
   gets a reading measure rather than the form default.
   =================================================================== */
.lex-field textarea {
  width: 100%; border: 1px solid var(--ad-5); border-radius: var(--ad-radius);
  padding: 11px 13px; font: inherit; font-size: 14.5px; color: var(--ad-body);
  background: var(--ad-0); line-height: 1.6; resize: vertical;
}
.lex-field textarea:focus         { border-color: var(--ad-ink); outline: none;
                                    box-shadow: 0 0 0 2px var(--ad-3); }
#qe-answer                        { font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
                                    font-size: 13.5px; }

/* The UI-phase notice bar. It is styled for the student palette in the
   shared component sheet; inside the console it is restated in black so
   the one persistent piece of chrome is not the only coloured thing on
   the screen. */
body.lex-admin .lex-demo-bar, #dashboard .lex-demo-bar,
body.lex-admin-login .lex-demo-bar {
  background: var(--ad-ink); color: var(--ad-5);
}
.lex-demo-bar button:hover, .lex-demo-bar button:focus { background: var(--ad-9); }

/* =====================================================================
   29. SELECTION AND BULK ACTIONS
   An admin who has picked forty rows should act on them once, not forty
   times. The bar appears only when something is selected, and says how
   many — because "Delete" with no number beside it is how accidents
   happen.
   ===================================================================== */
.lex-bulkbar {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  background: var(--ad-blue-soft); border: 1px solid var(--ad-blue);
  border-radius: var(--ad-radius); padding: 12px 18px; margin-bottom: 18px;
}
.lex-bulkbar > span               { font-weight: 800; color: var(--ad-blue); font-size: 14px; }
.lex-bulkbar .lex-btn-row         { margin-left: auto; }

table.lex-table td input[type="checkbox"],
table.lex-table th input[type="checkbox"] {
  width: 17px; height: 17px; accent-color: var(--ad-blue); cursor: pointer; margin: 0;
}

/* An archived row is still listed — that is the point of archiving
   rather than deleting — but it is visibly out of service. */
table.lex-table tr.is-archived td { opacity: .62; }
table.lex-table tr.is-archived .lex-cell-strong { text-decoration: line-through; }

/* =====================================================================
   30. TABLET AND BELOW
   Listeo turns the side navigation into a drop-down under 991px and
   expects it to stack above the content, but leaves #dashboard as a flex
   row — so the 90%-wide nav and the content sit side by side and the
   page scrolls sideways. Stack them, which is what the rest of the
   template's own rules at this width already assume.
   ===================================================================== */
@media (max-width: 991px) {
  #dashboard                      { display: block; }
  .dashboard-content              { max-width: 100%; }
  .lex-filters .lex-field         { min-width: 140px; flex: 1 1 140px; }
  .lex-filters .lex-filter-actions { margin-left: 0; width: 100%; }
  .lex-bulkbar .lex-btn-row       { margin-left: 0; }
}
