/* ==== Dashboard grid + edit mode =======================================
   LIFTED VERBATIM from the BI portal: shared/dashboard.css on main, lines
   396-667 — the widget grid, the widget chrome, "edit this dashboard", the
   resize handles, the hidden-tile and add-tile states, and the shared dialog
   shell, together with the responsive block that belongs to them.

   Nothing below this banner has been edited. It is proven code and rewriting
   it by hand is how bugs get introduced — a first attempt at extracting it
   rule-by-rule silently dropped an @media wrapper, which would have applied
   a two-column narrow-screen layout at every width.

   It speaks the BI portal's colour vocabulary. Rather than touch 272 lines,
   that vocabulary is aliased onto ours immediately below — the same trick that
   lets one engine serve SuperTyres and Rainbow.
   ===================================================================== */

:root {
  --line:                 var(--pb-border, #e2e8f0);
  --muted:                var(--pb-muted, #64748b);
  --ink:                  var(--pb-text, #0f172a);
  --panel-soft:           var(--pb-card-hi, #f8fafc);
  --tenant-primary:       var(--pb-red, #e9262a);
  --tenant-primary-dark:  var(--pb-red, #c01e22);
  --blue:                 var(--pb-red, #e9262a);   /* their accent is blue; ours is the brand red */
  --red:                  #dc2626;
  --amber:                #d97706;
  --green:                #059669;
}

/* â”€â”€â”€ Widget grid (Operations Hub / Financial Hub bodies) â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€ */
.widget-grid {
  background: white;
  border-radius: 18px;
  padding: 18px;
  box-shadow: 0 12px 35px rgba(0,0,0,.18);
  display: grid;
  /* TWELVE columns, not six (Charles, 2026-08-14: "the snapping to grid is quite
     restricted... make the grid a little bit more granular"). Existing widths are
     stored in SIXTHS as `col-N`; dashboard.js reads those as N*2 twelfths, so every
     dashboard built before this looks exactly the same. New widths are stored as
     `c12-N` and can land anywhere from a twelfth to the full width. */
  grid-template-columns: repeat(12, 1fr);
  gap: 14px;
}
.widget { background: var(--panel-soft); border: 1px solid var(--line); border-radius: 12px; padding: 14px; position: relative; }
.widget-kpi             { grid-column: span 4; min-height: 90px; }
.widget-workflow_tile   { grid-column: span 4; min-height: 90px; cursor: pointer; transition: transform 0.1s; }
.widget-workflow_tile:hover { transform: translateY(-1px); box-shadow: 0 4px 10px rgba(0,0,0,.08); }
.widget-chart           { grid-column: span 12; min-height: 280px; padding: 18px; }
.widget-alerts_summary  { grid-column: span 6; min-height: 200px; }
.widget-ai_summary      { grid-column: span 6; min-height: 200px; }
.widget-table           { grid-column: span 12; }

.widget-grid-span-1  { grid-column: span 1; }
.widget-grid-span-2  { grid-column: span 2; }
.widget-grid-span-3  { grid-column: span 3; }
.widget-grid-span-4  { grid-column: span 4; }
.widget-grid-span-5  { grid-column: span 5; }
.widget-grid-span-6  { grid-column: span 6; }
.widget-grid-span-7  { grid-column: span 7; }
.widget-grid-span-8  { grid-column: span 8; }
.widget-grid-span-9  { grid-column: span 9; }
.widget-grid-span-10 { grid-column: span 10; }
.widget-grid-span-11 { grid-column: span 11; }
.widget-grid-span-12 { grid-column: span 12; }

.widget-label { font-size: 11px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .5px; margin-bottom: 4px; word-break: break-word; }
.widget-subtitle { font-size: 11px; color: #9ca3af; font-style: italic; margin-bottom: 8px; }
.widget-value { font-size: 24px; font-weight: 400; color: var(--tenant-primary-dark, var(--blue)); line-height: 1.1; }
.widget-value.text-value { font-size: 15px; font-weight: 400; line-height: 1.35; }
.widget-error { color: var(--red); font-size: 11px; font-style: italic; margin-top: 8px; }

.widget-chart canvas { max-height: 240px; }
.widget-chart-title { font-size: 14px; font-weight: 700; color: var(--blue); margin-bottom: 12px; }

/* Widget header â€” the Explore button sits at the top left, ahead of the title.
   A tile is a fixed view; Explore is the bridge into the full render engine
   where it can be re-sliced, re-charted and saved again. */
.widget-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.widget-head .widget-chart-title,
.widget-head .widget-label { margin-bottom: 0; }
.widget-explore {
  flex-shrink: 0;
  font: inherit; font-size: 10.5px; font-weight: 600; letter-spacing: .3px;
  color: var(--muted); background: #fff;
  border: 1px solid var(--line); border-radius: 999px;
  padding: 3px 10px; cursor: pointer; line-height: 1.5;
  transition: background .12s, color .12s, border-color .12s;
}
.widget-explore:hover,
.widget-explore:focus-visible {
  background: var(--tenant-primary, var(--blue)); border-color: var(--tenant-primary, var(--blue));
  color: #fff; outline: none;
}
.widget-note { font-size: 10.5px; color: var(--amber); margin-bottom: 8px; }

/* â”€â”€â”€ Edit this dashboard â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€
   Arranging in place: drag to move, resize, rename, hide, add. The control is
   styled as one of the section-header tiles (like PERIOD) rather than a stray
   button, and is a ðŸ“Œ rather than a sentence. */
.dash-edit-tile {
  display: flex; align-items: center; gap: 8px;
  margin: 0; padding: 6px 10px; border-radius: 10px;
  background: #fff; border: 1px solid var(--line, #e4e7ec);
  font-size: 12px;
}
.dash-edit-tile.on {
  border-color: var(--tenant-primary, var(--blue));
  box-shadow: 0 0 0 3px rgba(11,45,77,.08);
}
.dash-edit-label {
  font-size: 12px; font-weight: 700; color: var(--blue);
  text-transform: uppercase; letter-spacing: .5px; white-space: nowrap;
}
.dash-edit-pin {
  border: 0; background: transparent; cursor: pointer;
  font-size: 15px; line-height: 1; padding: 2px 3px; border-radius: 6px;
  filter: grayscale(.35); transition: filter .12s, background .12s;
}
.dash-edit-pin:hover, .dash-edit-pin:focus-visible {
  filter: none; background: #eef2f7; outline: none;
}
.dash-edit-btn {
  font: inherit; font-size: 12px; padding: 5px 11px;
  border: 1px solid #cbd5e1; border-radius: 7px;
  background: #fff; color: var(--ink); cursor: pointer; white-space: nowrap;
}
.dash-edit-btn:hover { background: #eef2f7; }
.dash-edit-btn:disabled { opacity: .6; cursor: default; }
.dash-edit-save {
  background: var(--tenant-primary, var(--blue));
  border-color: var(--tenant-primary, var(--blue));
  color: #fff; font-weight: 600;
}
.dash-edit-save:hover { filter: brightness(1.08); background: var(--tenant-primary, var(--blue)); }

.widget-grid-editing { outline: 2px dashed var(--tenant-primary, var(--blue)); outline-offset: 5px; }
.widget-grid-editing .widget { cursor: grab; }
.widget-grid-editing .widget:hover { box-shadow: 0 4px 14px rgba(0,0,0,.10); }
.widget-dragging { opacity: .45; cursor: grabbing; }

/* Drag the boundaries. Snaps to the 6-column grid and to whole row units, so a
   layout arranged on one screen still lines up on another. */
.widget-grid-editing .widget { position: relative; }
.we-rz { position: absolute; z-index: 4; touch-action: none; }
/* While a boundary is being dragged: no text selection, and no scroll chaining
   that could feed back into the size being computed. */
body.dash-resizing { user-select: none; -webkit-user-select: none; overscroll-behavior: contain; }
body.dash-resizing * { cursor: inherit !important; }
.we-rz::after {
  content: ''; position: absolute; inset: 0; margin: auto;
  background: var(--tenant-primary, var(--blue)); opacity: 0;
  border-radius: 3px; transition: opacity .12s;
}
.widget-grid-editing .widget:hover .we-rz::after { opacity: .35; }
.we-rz:hover::after, .we-rz:active::after { opacity: .9 !important; }
.we-rz-e  { top: 22%; bottom: 22%; right: -4px; width: 10px; cursor: ew-resize; }
.we-rz-e::after  { width: 4px; height: 34px; }
.we-rz-s  { left: 22%; right: 22%; bottom: -4px; height: 10px; cursor: ns-resize; }
.we-rz-s::after  { height: 4px; width: 34px; }
.we-rz-se { right: -4px; bottom: -4px; width: 16px; height: 16px; cursor: nwse-resize; }
.we-rz-se::after { width: 8px; height: 8px; border-radius: 2px; }

/* Live size while dragging a boundary â€” the numbers matter more than the ghost. */
.we-rz-readout {
  position: absolute; bottom: 8px; left: 8px; z-index: 5;
  background: var(--blue); color: #fff; font-size: 11px; font-weight: 600;
  padding: 3px 8px; border-radius: 6px; pointer-events: none; white-space: nowrap;
}

/* A tile with an explicit height lets its chart fill the space rather than
   staying pinned at the default canvas cap. */
/* A tile with a chosen height gets a DEFINITE box and clips to it. Sizing it
   with min-height alone let the chart canvas grow, and a responsive canvas
   inside a container whose height it is itself driving feeds back and balloons
   â€” which is what turned one downward drag into a mile-long chart. */
.widget-sized { display: flex; flex-direction: column; overflow: hidden; }
.widget-sized canvas { flex: 1 1 auto; min-height: 0; max-height: 100% !important; }


/* A hidden tile is visible ONLY while editing, and unmistakably inactive â€”
   otherwise "hide" reads as "delete" and nobody trusts it. */
.widget-hidden { opacity: .5; border-style: dashed; }

.widget-editbar {
  position: absolute; top: 6px; right: 6px; z-index: 3;
  display: flex; align-items: center; gap: 4px;
  background: rgba(255,255,255,.96); border: 1px solid var(--line);
  border-radius: 8px; padding: 3px 5px;
  box-shadow: 0 2px 6px rgba(0,0,0,.08);
}
.widget-editbar .we-grip { cursor: grab; color: #9ca3af; font-size: 13px; line-height: 1; padding: 0 2px; }
.widget-editbar .we-chip {
  font: inherit; font-size: 12px; line-height: 1;
  background: transparent; border: 0; border-radius: 5px;
  padding: 3px 5px; cursor: pointer;
}
.widget-editbar .we-chip:hover { background: #eef2f7; }
.widget-editbar .we-chip.we-restore { background: #fef3c7; }
.widget-editbar .we-sel {
  font: inherit; font-size: 10.5px; padding: 2px 4px;
  border: 1px solid var(--line); border-radius: 5px; background: #fff; color: var(--blue);
}

/* The "add a tile" placeholder, last in the grid while editing. */
.widget-add {
  grid-column: span 4; min-height: 90px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; cursor: pointer;
  background: #fff; border: 2px dashed var(--line);
  color: var(--muted); transition: border-color .12s, color .12s, background .12s;
}
.widget-add:hover {
  border-color: var(--tenant-primary, var(--blue));
  color: var(--tenant-primary, var(--blue));
  background: #f8fafc;
}
.widget-add .wa-plus { font-size: 22px; line-height: 1; font-weight: 300; }
.widget-add .wa-text { font-size: 11.5px; font-weight: 600; }

.widget-edit-hint {
  grid-column: 1 / -1;
  font-size: 11.5px; color: var(--muted); line-height: 1.6;
  background: #f8fafc; border: 1px solid var(--line); border-radius: 8px;
  padding: 9px 13px;
}

/* Shared dialog shell â€” rename and add both use it. Esc closes, Enter commits. */
#dashRenameModal, #dashAddModal { position: fixed; inset: 0; z-index: 1500; }
#dashRenameModal .dr-scrim, #dashAddModal .dr-scrim {
  position: absolute; inset: 0; background: rgba(15,23,42,.5);
}
#dashRenameModal .dr-box, #dashAddModal .dr-box {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%);
  width: min(460px, 94vw); background: #fff; border-radius: 12px;
  box-shadow: 0 24px 60px rgba(15,23,42,.35); overflow: hidden;
}
#dashAddModal .da-box { width: min(560px, 94vw); max-height: 86vh; display: flex; flex-direction: column; }
#dashRenameModal .dr-head, #dashAddModal .dr-head {
  padding: 13px 18px; border-bottom: 1px solid var(--line);
  background: #f8fafc; font-size: 14px; color: var(--blue);
}
#dashRenameModal .dr-row {
  display: flex; align-items: center; gap: 12px; padding: 10px 18px 0;
}
#dashRenameModal .dr-row > span {
  width: 66px; flex-shrink: 0; font-size: 12px; font-weight: 600; color: #334155;
}
#dashRenameModal .dr-row input {
  flex: 1; min-width: 0; padding: 7px 10px; border: 1px solid #cbd5e1;
  border-radius: 6px; font: inherit; font-size: 12.5px; background: #fff;
}
#dashRenameModal .dr-foot, #dashAddModal .dr-foot {
  display: flex; align-items: center; gap: 8px;
  padding: 11px 18px; border-top: 1px solid var(--line); background: #f8fafc;
}
#dashRenameModal .dr-foot { margin-top: 14px; }
#dashRenameModal .dr-msg, #dashAddModal .dr-msg {
  flex: 1; font-size: 11.5px; color: var(--red); font-weight: 600;
}
#dashRenameModal .dr-btn, #dashAddModal .dr-btn {
  border: 1px solid #cbd5e1; background: #fff; color: #0f172a; font: inherit;
  font-size: 12.5px; padding: 7px 14px; border-radius: 7px; cursor: pointer;
}
#dashRenameModal .dr-btn:hover, #dashAddModal .dr-btn:hover { background: #eef2f7; }
#dashRenameModal .dr-btn.pri, #dashAddModal .dr-btn.pri {
  background: var(--tenant-primary, var(--blue));
  border-color: var(--tenant-primary, var(--blue)); color: #fff; font-weight: 600;
}
#dashAddModal .da-body { padding: 14px 18px; overflow-y: auto; }
#dashAddModal .da-lead { font-size: 12px; color: var(--muted); line-height: 1.6; margin: 0 0 12px; }
#dashAddModal .da-lead.da-alt { margin: 14px 0 0; padding-top: 12px; border-top: 1px solid var(--line); }
#dashAddModal .da-empty { font-size: 12px; color: #9ca3af; font-style: italic; }
#dashAddModal .da-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; margin-bottom: 7px;
}
#dashAddModal .da-row.off { opacity: .55; }
#dashAddModal .da-name { flex: 1; min-width: 0; font-size: 12.5px; color: var(--ink); font-weight: 600; }
#dashAddModal .da-kind {
  display: block; font-size: 10.5px; font-weight: 400; color: var(--muted);
  text-transform: uppercase; letter-spacing: .4px;
}
#dashAddModal .da-note { font-size: 11px; color: var(--muted); font-style: italic; }
#dashAddModal .da-add { padding: 5px 12px; font-size: 12px; }

.widget-workflow_tile .widget-value { font-size: 28px; font-weight: 500; }
.widget-workflow_tile.status-green   .widget-value { color: var(--green); }
.widget-workflow_tile.status-amber   .widget-value { color: var(--amber); }
.widget-workflow_tile.status-red     .widget-value { color: var(--red); }
.widget-workflow_tile.status-unknown .widget-value { color: var(--muted); }

@media (max-width: 1100px) {
  .widget-grid { grid-template-columns: repeat(2, 1fr); }
  /* On a narrow screen the arranged widths are meaningless â€” two columns, and
     the per-tile spans must lose to this or a "span 9" would break the grid. */
  .widget-grid [class*="widget-grid-span-"] { grid-column: span 2; }
  .widget-kpi, .widget-workflow_tile { grid-column: span 1; }
  .widget-chart, .widget-table { grid-column: span 2; }
  .widget-alerts_summary, .widget-ai_summary { grid-column: span 2; }
}

/* ── The edit affordance ──────────────────────────────────────────────────
   Named, not a lone icon. An unlabelled pin sat on the page unnoticed —
   a control that has to be guessed at is a control nobody uses. It also
   only ever renders for a role carrying can_edit_dashboards, so it is never
   a tease. */
.dash-edit-pin {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 14px;
    border: 1px solid var(--border, #dfe4e2);
    border-radius: 8px;
    background: #fff;
    color: var(--text-secondary, #4a5751);
    font: 600 13px/1 inherit;
    cursor: pointer;
    transition: border-color .12s, color .12s, box-shadow .12s;
}
.dash-edit-pin:hover {
    border-color: var(--brand-primary, #e82f1c);
    color: var(--brand-primary, #e82f1c);
    box-shadow: 0 1px 4px rgba(0,0,0,.06);
}
.dash-edit-pin:focus-visible { outline: 2px solid #2a78d6; outline-offset: 2px; }
.dash-edit-pin-text { white-space: nowrap; }
.dash-edit-tile { margin: 0 0 14px; }
.dash-edit-tile.on {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    padding: 10px 14px; border-radius: 8px;
    background: #fff8e6; border: 1px solid #f0dcbb;
}
.dash-edit-label { font-weight: 700; color: #8a5600; }

/* ---------------------------------------------------------------------------
   THE EDIT PIN, SMALLER. It used to own a full-width row above the first
   tile — a whole line of screen for one button. It now sits on the top row
   beside the Ask box and costs no line at all.

   It keeps its LABEL. An unlabelled pin sat on this page for a fortnight and
   read as decoration; "smaller" was the ask, not "harder to find".
   --------------------------------------------------------------------------- */
.page-top .dash-edit-tile { margin: 0; border: 0; background: none; padding: 0; }
.page-top .dash-edit-pin {
    padding: 5px 10px;
    font: 600 11px/1 inherit;
    gap: 5px;
    border-radius: 7px;
    height: 100%;
}
.page-top .dash-edit-tile.on {
    padding: 5px 10px;
    gap: 7px;
}
.page-top .dash-edit-btn { padding: 4px 9px; font-size: 11px; }

/* ---------------------------------------------------------------------------
   THE PIN, ON THE HEADER ROW — the portal's own square tile.
   One glyph, one square, the same height as the Ask box beside it, so the
   whole header row shares a baseline instead of three controls of three
   different heights. The written label moved into the tooltip and the
   accessible name; it is still announced and still discoverable on hover.
   --------------------------------------------------------------------------- */
.page-top .dash-edit-pin {
    /* Same 38px as the Ask box and its button — the header row shares one
       height, so nothing sits proud of anything else. */
    width: 38px; height: 38px; padding: 0; box-sizing: border-box;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 16px; line-height: 1;
    background: var(--rb-card, #fff);
    border: 1px solid var(--rb-border, #e2e8f0);
    border-radius: 9px;
    filter: none;
    transition: border-color .12s, box-shadow .12s, transform .08s;
}
.page-top .dash-edit-pin:hover,
.page-top .dash-edit-pin:focus-visible {
    border-color: var(--brand-primary, #e82f1c);
    box-shadow: 0 1px 5px rgba(0,0,0,.08);
    background: var(--rb-card, #fff);
    transform: translateY(-1px);
}
.page-top .dash-edit-pin-text { display: none; }

/* ---------------------------------------------------------------------------
   TILE COLOUR — a chip on the edit bar and a small menu under it.
   The choices are the validated palette rather than a colour wheel: an
   arbitrary picker is how a dashboard ends up with two series nobody with
   deuteranopia can tell apart.
   --------------------------------------------------------------------------- */
.we-colour { padding: 2px 5px; display: inline-flex; align-items: center; }
.we-swatch {
    display: inline-block; width: 13px; height: 13px; border-radius: 4px;
    border: 1px solid rgba(0,0,0,.18);
}
.we-colour-menu {
    position: absolute; z-index: 3000;
    background: #fff; border: 1px solid var(--line, #e4e7ec);
    border-radius: 10px; padding: 9px 11px;
    box-shadow: 0 8px 26px rgba(0,0,0,.14);
    font-size: 12px;
}
.we-colour-row {
    display: flex; align-items: center; gap: 5px;
    padding: 3px 0; white-space: nowrap;
}
.we-colour-name {
    min-width: 108px; max-width: 190px; overflow: hidden;
    text-overflow: ellipsis; color: var(--ink, #14201c); font-weight: 600;
}
.we-swatch-btn {
    width: 18px; height: 18px; border-radius: 5px; cursor: pointer;
    border: 1px solid rgba(0,0,0,.18); padding: 0;
}
.we-swatch-btn:hover { transform: scale(1.12); }
.we-swatch-btn.on { outline: 2px solid #14201c; outline-offset: 1px; }
