/* Night Shift — Focus on Energy branding (see focus_branding.md in smarty).
   Layout mirrors the retired Retool app; colors/typography follow the 2026
   brand guide: Inter, General Blue primary, straight edges, no shadows. */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');

:root {
  --foe-general-blue: #034ea2;
  --foe-general-green: #00ab4e;
  --foe-business: #0072bc;
  --foe-business-2: #e0f3fd;
  --foe-umbrella-2: #b7e4ea;
  --foe-umbrella-3: #11696e;
  --foe-residential-2: #deecc6;
  --foe-residential-4: #06532a;
  --foe-body-text: #3c3c3c;
  --border: #e0e0e0;
  --row-hover: #f5f7f9;
  --row-selected: #e5f3ea;
  --font-family: 'Inter', sans-serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font-family);
  color: var(--foe-body-text);
  background: #fff;
  font-size: 14px;
}

/* Header — Focus Toolbox App Layout Standard (Control Center wiki:
   Focus-Toolbox-App-Layout-Standard). Three rows: white logo bar seating the
   64px logo, solid FoE-blue app-name bar, then the pill tab strip. The logo
   image is the only brand mark — no standalone "Focus on Energy" text. */
.app-header { position: sticky; top: 0; z-index: 40; background: #fff; }

.logo-bar {
  height: 80px;
  background: #fff;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  padding: 0 24px;
}
.logo-bar .logo { height: 64px; width: auto; }

.app-bar {
  height: 34px;
  background: var(--foe-general-blue);
  display: flex;
  align-items: center;
  padding: 0 24px;
}
.app-bar-title {
  color: #fff;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
}
.app-bar-viewer {
  margin-left: auto;
  color: rgba(255, 255, 255, 0.7);
  font-size: 11.5px;
  white-space: nowrap;
}

/* Tabs — pill style in a white strip below the blue bar */
.tabs {
  height: 40px;
  background: #fff;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0 24px;
}
.tab {
  border: none;
  background: none;
  font-family: var(--font-family);
  font-size: 13px;
  font-weight: 500;
  color: #6b7280;
  padding: 5px 11px;
  border-radius: 6px;
  cursor: pointer;
  white-space: nowrap;
}
.tab.active {
  background: #d7f3e3;
  color: #0f6b3a;
  font-weight: 600;
}
.tab:not(.active):hover {
  background: var(--row-hover);
  color: var(--foe-body-text);
}

/* Federated (Control Center) dock — fixed bottom-left, solid opaque card */
.cc-dock {
  position: fixed;
  left: 16px;
  bottom: 16px;
  z-index: 60;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 6px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.10);
  padding: 6px 8px;
}

main { padding: 6px 24px 48px; }
.panel { display: none; }
.panel.active { display: block; }

/* Search + the always-visible status filter, sharing the toolbar row so the
   table starts ~39px higher up the screen (night_shift#22). The search box
   takes whatever width the buttons leave and wraps below them on narrow
   screens rather than squeezing them. */
.search-row {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1 1 260px;
  min-width: 250px;
  margin-right: auto;
}
#task-search {
  flex: 1 1 auto;
  min-width: 140px;
  padding: 5px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  font-family: var(--font-family);
  font-size: 13px;
}
#filter-status {
  flex: none;
  padding: 4px 6px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-family: var(--font-family);
  font-size: 12.5px;
  background: #fff;
  max-width: 190px;
}
#task-search:focus { outline: 2px solid var(--foe-business); border-color: transparent; }

/* Card + toolbar */
.card { border: 1px solid var(--border); background: #fff; }
.toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
  padding: 3px 12px;
  border-bottom: 1px solid var(--border);
}
.tool {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: none;
  background: none;
  font-family: var(--font-family);
  font-size: 13px;
  color: #4b5563;
  padding: 4px 9px;
  border-radius: 6px;
  cursor: pointer;
}
.tool svg { width: 15px; height: 15px; flex: none; }
.tool:hover { background: var(--foe-business-2); color: var(--foe-general-blue); }
.filter-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
  background: #fafafa;
}
.filter-row.hidden { display: none; }

/* Tables
   No inner scroll area (night_shift#22): with pages there is nothing left to
   scroll past, and a scrollbar inside a scrolling page means two scrollbars
   competing for the same wheel. The page scrolls; the header row stays sticky.
   It pins under the app header (80 logo + 34 app bar + 40 tabs = 154px) rather
   than at the very top, where the header would cover it. */
.table-wrap { overflow-x: auto; }
/* Opt back in where an inner scroll really is wanted — the Manual Runs list
   sits beside a fixed-height output pane. */
.table-wrap.scroll-y { max-height: 65vh; overflow-y: auto; }
/* The task list opts OUT of overflow entirely, and it has to: any `overflow`
   value other than visible makes the wrapper the scrollport that `position:
   sticky` resolves against, so `top: 154px` stopped meaning "pin under the app
   header" and started meaning "sit 154px down inside the table" — the header
   row floated on top of rows 6-10. Caught headless; it renders wrong, it is
   not a theoretical worry. The cells already ellipsis at max-width: 480px, so
   there is nothing here that needs a horizontal scrollbar. */
.table-wrap.sticky-head { overflow: visible; }
table { width: 100%; border-collapse: collapse; }
/* top: 0 is the safe default — inside a wrapper that scrolls (or one that has
   any overflow set) the header pins to the top of that wrapper, which is what
   the stats tables want. Only .sticky-head, whose wrapper is overflow: visible,
   resolves against the viewport, and only there does the 154px app-header
   offset mean anything. Getting this backwards left a header row floating in
   the middle of every stats table. */
thead th {
  position: sticky;
  top: 0;
  z-index: 30;
  background: #fff;
  text-align: left;
  font-weight: 600;
  font-size: 13px;
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.table-wrap.sticky-head thead th { top: 154px; }
/* Anything scrolled into view has to clear the app header (154px) AND the
   sticky column header, or it lands underneath them and cannot be clicked. */
#tasks-table, #tasks-table tbody tr, #tasks-table tbody td {
  scroll-margin-top: 200px;
}
tbody td {
  padding: 6px 10px;
  font-size: 13px;
  line-height: 1.15;
  border-bottom: 1px solid #f0f0f0;
  white-space: nowrap;
  max-width: 480px;
  overflow: hidden;
  text-overflow: ellipsis;
}
th.num, td.num { text-align: right; }
tbody tr:hover { background: var(--row-hover); }
tbody tr.selected { background: var(--row-selected); }
.col-note {
  padding: 6px 12px;
  font-size: 12px;
  line-height: 1.45;
  color: #6b7280;
  background: #fafbfc;
  border-top: 1px solid var(--border);
}
.col-note strong { color: var(--foe-body-text); font-weight: 600; }
.table-footer {
  padding: 6px 14px;
  font-size: 12px;
  color: #6b7280;
  text-align: center;
  border-top: 1px solid var(--border);
}
.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
}
.pager-btn {
  border: 1px solid var(--border);
  background: #fff;
  border-radius: 6px;
  font-family: var(--font-family);
  font-size: 12px;
  color: var(--foe-general-blue);
  padding: 3px 10px;
  cursor: pointer;
}
.pager-btn:hover:not(:disabled) { background: var(--foe-business-2); }
.pager-btn:disabled { color: #b6bcc4; cursor: not-allowed; }

/* Performance Stats (night_shift#22) */
.perf-heading {
  font-size: 15px;
  font-weight: 700;
  color: var(--foe-general-blue);
  margin: 20px 0 8px;
}
.perf-heading:first-child { margin-top: 4px; }
.perf-summary {
  border: 1px solid var(--border);
  background: #fafbfc;
  padding: 12px 16px;
}
.perf-date { font-size: 15px; font-weight: 600; color: #111; }
.perf-tiles { display: flex; flex-wrap: wrap; gap: 10px; margin: 10px 0 8px; }
.perf-tile {
  background: #fff;
  border: 1px solid var(--border);
  padding: 8px 14px;
  min-width: 108px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.perf-tile.ok { border-left: 3px solid var(--foe-general-green); }
.perf-tile.bad { border-left: 3px solid #a3161b; }
.perf-tile.warn { border-left: 3px solid #c07a00; }
.perf-num { font-size: 22px; font-weight: 700; color: #111; }
.perf-lbl { font-size: 11.5px; color: #6b7280; }
.perf-times { font-size: 12.5px; color: #4b5563; }
.perf-scope { font-size: 12px; color: #6b7280; margin-top: 6px; line-height: 1.45; }
.perf-split { display: flex; gap: 32px; align-items: flex-start; }
.perf-col { flex: 0 1 720px; min-width: 0; }
.daily-controls {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}
.daily-controls label { font-size: 12px; color: #6b7280; }
.daily-controls select {
  min-width: 160px;
  padding: 5px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-family: var(--font-family);
  font-size: 13px;
}
/* A failed row is marked, not just annotated — see #1: a failure never gets an
   end_time, so an unmarked table makes it look like it is still running. */
tbody tr.row-failed { background: #fff4f4; }
tbody tr.row-failed td:first-child { box-shadow: inset 3px 0 0 0 #a3161b; }
td.bad-num { color: #a3161b; font-weight: 600; }
.adhoc { color: #8a5a00; }
.stat-card { padding-top: 24px; min-width: 240px; }
@media (max-width: 1100px) {
  .perf-split { flex-direction: column; }
  .perf-col { flex: 1 1 auto; width: 100%; }
}
.stat-title { font-weight: 600; font-size: 14px; }
.stat-row { display: flex; align-items: center; gap: 8px; margin: 6px 0; }
.stat-value { font-size: 32px; font-weight: 700; color: #111; }
.stat-delta {
  font-size: 12px;
  font-weight: 600;
  padding: 2px 6px;
}
.stat-delta.up { color: var(--foe-residential-4); background: var(--foe-residential-2); }
.stat-delta.down { color: #8d3a1e; background: #fcd58f; }
.stat-sub { color: #9ca3af; font-size: 12px; }

/* Modal */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(17, 24, 39, 0.5);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 20px 16px;
  overflow-y: auto;
  z-index: 50;
}
.modal-backdrop.hidden { display: none; }
/* The dialog never grows past the window: the title row and the Cancel/Submit
   row are pinned and only .modal-body scrolls, so Submit is on screen from the
   moment the editor opens. It used to render 1322px tall at 1440x900.
   night_shift#22. */
.modal {
  background: #fff;
  width: 100%;
  max-width: 880px;
  max-height: calc(100vh - 40px);
  display: flex;
  flex-direction: column;
  padding: 16px 24px;
}
.modal-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex: none;
}
.modal h2 {
  margin: 0 0 10px;
  font-size: 17px;
  color: var(--foe-general-blue);
}
.modal-x {
  border: none;
  background: none;
  font-size: 24px;
  line-height: 1;
  color: #8a9099;
  cursor: pointer;
  padding: 0 4px;
  margin-top: -2px;
}
.modal-x:hover { color: var(--foe-body-text); }
#task-form {
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1 1 auto;
}
.modal-body {
  overflow-y: auto;
  min-height: 0;
  flex: 1 1 auto;
  padding-right: 4px;
}
.section-heading {
  font-size: 14px;
  font-weight: 700;
  margin: 14px 0 6px;
}
.field { display: flex; flex-direction: column; gap: 3px; margin-bottom: 8px; }
.field label { font-size: 12px; font-weight: 500; }
.field input, .field select, .field textarea {
  padding: 6px 10px;
  border: 1px solid var(--border);
  font-family: var(--font-family);
  font-size: 13px;
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: 2px solid var(--foe-business);
  border-color: transparent;
}
/* ~22 lines, and draggable taller — 23 of 193 tasks hold more than 100 lines
   of code and the old 140px box showed 8. night_shift#22. */
.field textarea {
  font-family: 'SFMono-Regular', Consolas, monospace;
  font-size: 13px;
  line-height: 1.4;
  background: #1f2428;
  color: #e6edf3;
  min-height: 420px;
  resize: vertical;
}
.tooltip-hint {
  font-size: 12px;
  color: #6b7280;
  background: #f9fafb;
  border: 1px solid var(--border);
  padding: 6px 10px;
  min-height: 16px;
}
.tooltip-hint:empty { display: none; }
.field.arg { display: none; }
.field.arg.visible { display: flex; }

.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  flex: none;
}
.foe-btn-primary {
  background: var(--foe-business);
  color: #fff;
  padding: 9px 22px;
  border: none;
  font-family: var(--font-family);
  font-weight: 600;
  font-size: 14px;
  cursor: pointer;
}
.foe-btn-secondary {
  background: var(--foe-umbrella-2);
  color: var(--foe-general-blue);
  padding: 9px 22px;
  border: none;
  font-family: var(--font-family);
  font-weight: 600;
  font-size: 14px;
  cursor: pointer;
}

/* Toast */
.toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--foe-general-blue);
  color: #fff;
  padding: 12px 20px;
  font-size: 14px;
  z-index: 100;
}
.toast.error { background: #8d3a1e; }
.toast.hidden { display: none; }
.hidden { display: none; }

/* ── Sign-in gate (night_shift#11) ─────────────────────────────────────────── */
.auth-gate {
  position: fixed; inset: 0; z-index: 60;
  display: flex; align-items: center; justify-content: center;
  background: #f4f6f8;
}
.auth-card {
  background: #fff; border-radius: 10px; padding: 40px 44px; max-width: 460px;
  text-align: center; box-shadow: 0 2px 14px rgba(0, 0, 0, .12);
}
.auth-logo { height: 56px; margin-bottom: 18px; }
.auth-card h1 { margin: 0 0 12px; font-size: 22px; color: #034ea2; }
.auth-card p { margin: 0 0 20px; color: #444; line-height: 1.5; }
.btn-primary {
  background: #034ea2; color: #fff; border: 0; border-radius: 6px;
  padding: 10px 22px; font-size: 15px; cursor: pointer;
}
.btn-primary:hover { background: #023d80; }

/* ── Reordering + multi-select (night_shift#20) ────────────────────────────── */
.grip-cell { width: 26px; text-align: center; padding: 0 !important; }
.check-cell { width: 30px; text-align: center; padding: 0 !important; }
.grip {
  color: #b3b9c2; cursor: grab; user-select: none;
  letter-spacing: -3px; font-size: 15px;
}
.grip:active { cursor: grabbing; }
.grip.disabled { color: #e2e5e9; cursor: not-allowed; }
#tasks-table tbody tr.dragging { opacity: .45; }
#tasks-table tbody tr.drop-above td { box-shadow: inset 0 2px 0 0 #034ea2; }
#tasks-table tbody tr.drop-below td { box-shadow: inset 0 -2px 0 0 #034ea2; }

/* Parked tasks keep their slot in the list but never run — say so quietly
   rather than hiding them, so un-parking one returns it to where it was. */
#tasks-table tbody tr.inactive td { color: #98a0aa; }
#tasks-table tbody tr.inactive td.run-order { color: #c4cad1; }

.selection-count { margin-left: 4px; color: #034ea2; font-size: 13px; font-weight: 600; }
.tool:disabled { opacity: .45; cursor: not-allowed; }

/* This stylesheet only ever defined .hidden per-element (.filter-row.hidden,
   .modal-backdrop.hidden, .toast.hidden). The sign-in gate needs a general
   one — kept last so it wins, and scoped to the elements that rely on it so
   no existing component changes behaviour. */
#app-shell.hidden,
#auth-gate.hidden,
#auth-action.hidden { display: none !important; }

/* ── no-access page + role banner (#38 / cc#151) ─────────────────────────── */
.auth-sub {
  margin: 0 0 16px; color: #5b6470; font-size: 13.5px; line-height: 1.5;
}
.auth-note {
  margin: 14px 0 0; color: #0f6b3a; font-size: 13.5px; line-height: 1.5;
}
.auth-note.bad { color: #a3282d; }
#auth-request:disabled { background: #6b7f96; cursor: default; }
#auth-switcher-hint { margin-top: 18px; margin-bottom: 0; }

.role-banner {
  background: #fdf3d7; border-bottom: 1px solid #ecd9a0; color: #6b4e00;
  font-size: 12.5px; padding: 6px 24px;
}

/* The Focus Toolbox dock must stay VISIBLE on the no-access page, not merely
   mounted: the app switcher is the one way forward we offer someone who is
   signed in but not on this app. Both are fixed and full-viewport-ish, so make
   the dock's place above the gate explicit rather than leaving it to which
   element happens to come last in the document. */
.cc-dock { z-index: 70; }

/* ── Runs tab (night_shift#16) ─────────────────────────────────────────────── */
.runs-split { display: flex; gap: 14px; align-items: stretch; }
.runs-list { flex: 0 0 52%; }
.run-detail {
  flex: 1 1 auto; display: flex; flex-direction: column;
  border: 1px solid #e2e5e9; border-radius: 6px; background: #fff; min-width: 0;
}
.run-detail-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 12px; border-bottom: 1px solid #e2e5e9; font-weight: 600;
  color: #034ea2; font-size: 13px;
}
.run-output {
  margin: 0; padding: 12px; overflow: auto; max-height: 60vh; flex: 1 1 auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px; line-height: 1.45; white-space: pre-wrap; word-break: break-word;
  color: #24292f; background: #fbfcfd;
}
.run-pill {
  display: inline-block; padding: 1px 9px; border-radius: 10px;
  font-size: 12px; font-weight: 600;
}
.run-queued    { background: #eef1f4; color: #55606c; }
.run-running   { background: #d7f3e3; color: #0f6b3a; }
.run-done      { background: #d7f3e3; color: #0f6b3a; }
.run-failed    { background: #fde2e2; color: #a3161b; }
.run-cancelled { background: #fdf0d5; color: #8a5a00; }
.runs-busy { margin-left: 12px; color: #8a5a00; font-size: 12px; }
#runs-table tbody tr { cursor: pointer; }
td.empty { text-align: center; color: #8a9099; padding: 18px; }
@media (max-width: 1100px) {
  .runs-split { flex-direction: column; }
  .runs-list { flex: 1 1 auto; }
}

/* The running code version in the header (#26). Deliberately quiet: it is
   reference information you go looking for after a deploy, not something that
   should compete with the task list. It sits next to the viewer name because
   that is the other "what is true about this session" fact on the bar. */
.app-bar-version {
  /* No margin-left:auto here — .app-bar-viewer already has the one that
     pushes this pair to the right, and a second auto margin would split the
     free space between them and strand this in the middle of the bar. */
  margin-left: 10px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11px;
  letter-spacing: 0.02em;
  opacity: 0.55;
  white-space: nowrap;
}
.app-bar-version:hover { opacity: 0.9; }
