/* Sequences — page shell + landing list.
 *
 * Scope: everything the page module (sequences-page.js) draws, and ONLY that.
 *
 * EVERY class here is namespaced `.seq-page-*`. That is not tidiness, it is the
 * fix for a real bug: this is a global stylesheet inside a feature whose other
 * two modules (seq-chain.js, seq-step-panel.js) inject their OWN scoped CSS and
 * render INSIDE this page's markup. While these rules carried generic names —
 * .seq-head, .seq-col, .seq-row, .seq-empty, .seq-btn — they leaked straight
 * into the step panel, which had its own `.seq-panel`-scoped rules for the same
 * names but only overrode some properties. The rest won from here: the panel's
 * kind icon sat above its header (flex-direction:column from .seq-head), every
 * field wrapper became a bordered card (.seq-col), inert rows grew a hover
 * accent border and jumped on click (.seq-row), and "No conditions. This step
 * runs every time." rendered as a dashed empty-state box (.seq-empty).
 *
 * Scoping under a page container would NOT have fixed it — the panel renders
 * inside .seq-page. Distinct names is the only thing that actually separates
 * them. So: this file owns `.seq-page-*` and nothing else, and no class either
 * injected module invents later can collide with it.
 *
 * Colour comes only from the app's theme tokens (--card-bg, --text-primary,
 * --ui-border, --accent-color, …), which ui/css/theme.css re-declares under
 * html[data-theme="dark"]. That is why there is almost no dark-mode block here:
 * a page built on the tokens flips for free. The two exceptions are called out
 * where they appear.
 *
 * Layout: the Steps tab is a 33% / 66% split that stacks to one column at
 * <=900px. Every column is min-width:0 with its own overflow-x, so a wide chain
 * or a wide config field scrolls inside its column and the page body never
 * scrolls sideways.
 */

.seq-page {
  display: flex;
  flex-direction: column;
  gap: 18px;
  max-width: 1400px;
  color: var(--text-primary, #1a1a1a);
}

/* ── landing header ─────────────────────────────────────────────────────── */

.seq-page-head {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.seq-page-title {
  margin: 0;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text-primary, #1a1a1a);
}

.seq-page-sub {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--text-secondary, #4b5563);
  max-width: 70ch;
}

/* ── toolbar (search + count) ───────────────────────────────────────────── */

.seq-page-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.seq-page-search {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1 1 280px;
  max-width: 420px;
  padding: 0 10px;
  border: 1px solid var(--ui-border, #e5e7eb);
  border-radius: 9px;
  background: var(--card-bg, #fff);
  color: var(--text-muted, #6b7280);
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

.seq-page-search:focus-within {
  border-color: var(--accent-color, #3b82f6);
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.16);
}

.seq-page-search-input {
  flex: 1 1 auto;
  min-width: 0;
  border: none;
  outline: none;
  background: transparent;
  font: inherit;
  font-size: 13.5px;
  color: var(--text-primary, #1a1a1a);
  padding: 9px 0;
}

.seq-page-search-input::placeholder {
  color: var(--text-muted, #9ca3af);
}

/* Chrome draws its own dark "x" on type=search, which disappears on a dark
   surface. The clear affordance is Escape and the text itself, not that glyph. */
.seq-page-search-input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}

.seq-page-count {
  font-size: 12.5px;
  color: var(--text-muted, #6b7280);
  white-space: nowrap;
}

/* ── landing list ───────────────────────────────────────────────────────── */

.seq-page-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.seq-page-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto auto;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 11px 12px;
  text-align: left;
  font: inherit;
  color: var(--text-primary, #1a1a1a);
  background: var(--card-bg, #fff);
  border: 1px solid var(--ui-border, #e5e7eb);
  border-radius: 10px;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease, transform 0.12s ease;
}

.seq-page-row:hover {
  background: var(--hover-bg, #f1f5f9);
  border-color: var(--accent-color, #3b82f6);
}

.seq-page-row:focus-visible {
  outline: 2px solid var(--accent-color, #3b82f6);
  outline-offset: 2px;
}

.seq-page-row:active {
  transform: translateY(1px);
}

.seq-page-row-main {
  display: flex;
  align-items: baseline;
  gap: 9px;
  min-width: 0;
  flex-wrap: wrap;
}

.seq-page-row-label {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary, #1a1a1a);
}

.seq-page-row-slug {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11.5px;
  color: var(--text-muted, #6b7280);
  background: var(--hover-bg, #f1f5f9);
  border-radius: 5px;
  padding: 1px 6px;
  word-break: break-all;
}

.seq-page-row-stats {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.seq-page-stat {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--text-secondary, #4b5563);
  background: var(--hover-bg, #f1f5f9);
  border: 1px solid var(--ui-border-soft, rgba(15, 23, 42, 0.06));
  border-radius: 999px;
  padding: 2px 9px;
  white-space: nowrap;
}

.seq-page-row-edited {
  font-size: 11.5px;
  color: var(--text-muted, #9ca3af);
  white-space: nowrap;
}

.seq-page-row-chev {
  display: flex;
  align-items: center;
  color: var(--text-muted, #9ca3af);
}

.seq-page-row:hover .seq-page-row-chev {
  color: var(--accent-color, #3b82f6);
}

/* ── detail header ──────────────────────────────────────────────────────── */

.seq-page-detail-head {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.seq-page-back {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: 1px solid var(--ui-border, #e5e7eb);
  border-radius: 9px;
  background: var(--card-bg, #fff);
  color: var(--text-secondary, #4b5563);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}

.seq-page-back:hover {
  background: var(--hover-bg, #f1f5f9);
  color: var(--text-primary, #1a1a1a);
}

.seq-page-back:focus-visible {
  outline: 2px solid var(--accent-color, #3b82f6);
  outline-offset: 2px;
}

.seq-page-detail-headtext {
  display: flex;
  align-items: baseline;
  gap: 10px;
  min-width: 0;
  flex-wrap: wrap;
}

.seq-page-detail-title {
  margin: 0;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.seq-page-detail-slug {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11.5px;
  color: var(--text-muted, #6b7280);
  background: var(--hover-bg, #f1f5f9);
  border-radius: 5px;
  padding: 2px 7px;
  word-break: break-all;
}

.seq-page-detail-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
}

.seq-page-saved-pill {
  font-size: 12px;
  font-weight: 600;
  color: #15803d;
  background: rgba(22, 163, 74, 0.10);
  border: 1px solid rgba(22, 163, 74, 0.28);
  border-radius: 999px;
  padding: 3px 10px;
  opacity: 0;
  transition: opacity 0.18s ease;
}

.seq-page-saved-pill.is-on {
  opacity: 1;
}

/* Green-on-green needs lifting on the dark surface: #15803d against #1e293b is
   under 3:1, which is exactly the "confirmation nobody can read" failure. */
html[data-theme="dark"] .seq-page-saved-pill {
  color: #4ade80;
  background: rgba(74, 222, 128, 0.12);
  border-color: rgba(74, 222, 128, 0.30);
}

/* ── buttons ────────────────────────────────────────────────────────────── */

.seq-page-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 15px;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  border-radius: 8px;
  border: 1px solid var(--ui-border, #e5e7eb);
  background: var(--card-bg, #fff);
  color: var(--text-primary, #1a1a1a);
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease, opacity 0.12s ease;
}

.seq-page-btn:hover:not(:disabled) {
  background: var(--hover-bg, #f1f5f9);
}

.seq-page-btn:focus-visible {
  outline: 2px solid var(--accent-color, #3b82f6);
  outline-offset: 2px;
}

.seq-page-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.seq-page-btn-primary {
  background: var(--accent-color, #3b82f6);
  border-color: var(--accent-color, #3b82f6);
  color: #fff;
}

.seq-page-btn-primary:hover:not(:disabled) {
  filter: brightness(0.94);
  background: var(--accent-color, #3b82f6);
}

/* --accent-color is a LIGHTER blue in dark mode (it is a foreground token in 22
   of its 24 sites), so white text on it drops to ~2.5:1. Same fix the app
   already applies to .a4p-btn-primary in theme.css. */
html[data-theme="dark"] .seq-page-btn-primary {
  color: #0b1220;
}

/* ── tabs ───────────────────────────────────────────────────────────────── */

.seq-page-tabs {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  border-bottom: 1px solid var(--ui-border, #e5e7eb);
  /* overflow-x:auto on its own computes overflow-y to `auto` as well. The tabs
     used to bleed 1px below this box (margin-bottom:-1px, to cover the border),
     which made scrollHeight exactly 1px taller than clientHeight — enough for
     Chrome to park a permanent vertical scrollbar, arrows and all, at the right
     end of the tab strip, and to eat 15px of width with its gutter. Pinning the
     y axis kills it; x still scrolls if the tabs ever outgrow the width. */
  overflow-x: auto;
  overflow-y: hidden;
}

.seq-page-tab {
  flex: 0 0 auto;
  padding: 9px 14px;
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text-muted, #6b7280);
  background: transparent;
  border: none;
  /* Sits directly on top of the strip's hairline rather than bleeding 1px over
     it — see the overflow note on .seq-page-tabs. */
  border-bottom: 2px solid transparent;
  cursor: pointer;
  transition: color 0.12s ease, border-color 0.12s ease;
}

.seq-page-tab:hover {
  color: var(--text-primary, #1a1a1a);
}

.seq-page-tab:focus-visible {
  outline: 2px solid var(--accent-color, #3b82f6);
  outline-offset: -2px;
  border-radius: 6px 6px 0 0;
}

.seq-page-tab.is-active {
  color: var(--accent-color, #3b82f6);
  border-bottom-color: var(--accent-color, #3b82f6);
}

/* ── steps tab: 33 / 66 split ───────────────────────────────────────────── */

.seq-page-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
  gap: 16px;
  align-items: start;
}

.seq-page-col {
  min-width: 0;
  /* Wide content (a long status token, a wide config row) scrolls inside its
     own column. Without this the page body picks up the overflow and the whole
     app scrolls sideways. */
  overflow-x: auto;
  /* Ticket #193 — and VERTICALLY too. overflow-x:auto already computes
     overflow-y to auto, but with no height bound a long chain or menu tree just
     grew the column and pushed the page down, so you scrolled the whole app to
     read one panel and lost the other one off-screen. Bounding the column to
     the viewport makes each section scroll on its own, which is what the two
     columns being side by side was for. */
  max-height: calc(100vh - 270px);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--card-bg, #fff);
  border: 1px solid var(--ui-border, #e5e7eb);
  border-radius: 12px;
  padding: 14px;
}

/* The landing list of sequences scrolls on its own for the same reason. */
.seq-page-list-host {
  max-height: calc(100vh - 260px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* ── states: loading / empty / error / placeholder ──────────────────────── */

.seq-page-loading {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 34px 12px;
  font-size: 13.5px;
  color: var(--text-muted, #6b7280);
}

.seq-page-spinner {
  width: 15px;
  height: 15px;
  border: 2px solid var(--ui-border, #e5e7eb);
  border-top-color: var(--accent-color, #3b82f6);
  border-radius: 50%;
  animation: seq-page-spin 0.7s linear infinite;
}

@keyframes seq-page-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .seq-page-spinner { animation-duration: 2.4s; }
  .seq-page-row:active { transform: none; }
}

.seq-page-empty,
.seq-page-placeholder {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 26px 18px;
  text-align: center;
  border: 1px dashed var(--ui-border, #e5e7eb);
  border-radius: 11px;
  background: var(--card-bg, #fff);
}

.seq-page-empty-title,
.seq-page-placeholder-title {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary, #1a1a1a);
}

.seq-page-empty-body,
.seq-page-placeholder-body {
  margin: 0;
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-secondary, #4b5563);
  max-width: 62ch;
  align-self: center;
}

.seq-page-placeholder {
  border-color: rgba(245, 158, 11, 0.42);
  background: rgba(245, 158, 11, 0.07);
}

.seq-page-error {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 12px 14px;
  border-radius: 10px;
  background: rgba(239, 68, 68, 0.09);
  border: 1px solid rgba(239, 68, 68, 0.30);
  color: #b91c1c;
}

.seq-page-error-msg {
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  flex: 1 1 240px;
}

.seq-page-error-inline {
  margin-top: 2px;
}

html[data-theme="dark"] .seq-page-error {
  background: rgba(239, 68, 68, 0.14);
  border-color: rgba(248, 113, 113, 0.34);
  color: #fca5a5;
}

.seq-page-save-error-host:empty {
  display: none;
}

/* ── responsive ─────────────────────────────────────────────────────────── */

@media (max-width: 900px) {
  .seq-page-split {
    grid-template-columns: minmax(0, 1fr);
  }
  /* Stacked, the columns sit one above the other, so capping each to the
     viewport would leave two tiny scroll boxes on one long page. Let them size
     to content here and let the page scroll, which is the right behaviour when
     there is only one column of them. */
  .seq-page-col {
    max-height: none;
    overflow-y: visible;
  }
}

@media (max-width: 760px) {
  /* The row's four columns collapse to a stack: label line, then stats, then
     the edited stamp. The chevron goes away rather than fighting for width. */
  .seq-page-row {
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
  }

  .seq-page-row-stats {
    gap: 5px;
  }

  .seq-page-row-chev {
    display: none;
  }

  .seq-page-detail-actions {
    margin-left: 0;
    width: 100%;
    justify-content: flex-end;
  }

  .seq-page-title {
    font-size: 19px;
  }

  .seq-page-detail-title {
    font-size: 17px;
  }

  .seq-page-search {
    max-width: none;
  }
}

/* ── Merged rows panel (landing view) ──────────────────────────────────────
   Sits below the sequence list because its axis is the DEPARTMENT, not a
   deliverable type — a merge node has many member types, so it belongs to no
   single sequence. Opens pages/production/merge-node-editor.js, which injects
   its own .merge-node-editor-scoped CSS; nothing here may leak into it, hence
   the .seq-page-* prefix on every selector (see this file's header). */
.seq-page-merges {
  margin-top: 28px;
  padding-top: 20px;
  border-top: 1px solid var(--ui-border, #e5e7eb);
}

.seq-page-merges-title {
  margin: 0 0 4px;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text-primary, #1a1a1a);
}

.seq-page-merges-sub {
  margin: 0 0 14px;
  max-width: 70ch;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-secondary, #6b7280);
}

.seq-page-merges-rows {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 8px;
}

.seq-page-merges-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 11px 13px;
  border-radius: 10px;
  font: inherit;
  text-align: left;
  cursor: pointer;
  background: var(--card-bg, #fff);
  border: 1px solid var(--ui-border, #e5e7eb);
  transition: border-color 0.12s ease, background 0.12s ease;
}

.seq-page-merges-row:hover {
  border-color: var(--accent, #2563eb);
  background: var(--hover-bg, #f8fafc);
}

.seq-page-merges-row:focus-visible {
  outline: 2px solid var(--accent, #2563eb);
  outline-offset: 2px;
}

.seq-page-merges-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-primary, #1a1a1a);
}

.seq-page-merges-count {
  flex: 0 0 auto;
  font-size: 11px;
  white-space: nowrap;
  color: var(--text-muted, #9ca3af);
}

/* ── Steps tab: the Canvas | List view toggle ────────────────────────────────
 * Lives inside the tab body, not the tab strip: that strip is a role="tablist"
 * with a roving tabindex, and a fourth control that is not a tab would break the
 * arrow-key contract it promises. Styled as a segmented control so it reads as
 * "two views of one thing" rather than two separate actions.
 */
.seq-page-viewbar {
  display: flex;
  justify-content: flex-end;
  margin: 0 0 10px;
}

.seq-page-viewtoggle {
  display: inline-flex;
  border: 1px solid var(--ui-border, #e5e7eb);
  border-radius: var(--radius-md, 8px);
  overflow: hidden;
  background: var(--card-bg, #fff);
}

.seq-page-viewbtn {
  /* 44px min target: this is the control that switches editors, and it is the
   * one a phone user reaches for first. */
  min-height: 36px;
  min-width: 84px;
  padding: 8px 14px;
  border: 0;
  background: transparent;
  color: var(--text-secondary, #444);
  font: inherit;
  font-size: var(--font-size-small, 13px);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

.seq-page-viewbtn + .seq-page-viewbtn {
  border-left: 1px solid var(--ui-border, #e5e7eb);
}

.seq-page-viewbtn:hover:not(:disabled) { background: var(--hover-bg, #f1f5f9); }

.seq-page-viewbtn.is-active {
  background: var(--accent-color, #3b82f6);
  color: #fff;
}

.seq-page-viewbtn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.seq-page-viewbtn:focus-visible {
  outline: 2px solid var(--accent-color, #3b82f6);
  outline-offset: -2px;
}

/* The canvas sizes itself from --nc-shell-h on .nc-root; this wrapper only has
 * to not constrain it. A fixed height here would fight that and clip the graph. */
.seq-page-canvas { display: block; min-width: 0; }

@media (max-width: 900px) {
  .seq-page-viewbar { justify-content: stretch; }
  .seq-page-viewtoggle { flex: 1; }
  .seq-page-viewbtn { flex: 1; min-height: 44px; }
}
