/* Settings screen. Extends style.css rather than restating it - the tokens,
 * buttons, panels and [hidden] rule all come from there.
 *
 * Status colours reuse the fixed status roles (good / warning / critical) and
 * are never themed, for the same reason as the findings list: a sync state is
 * a state, not a series. Each one also carries an icon and a word, so colour
 * is never the only encoding. */

/* Shared with the subscriptions and editor pages - see api.nav_html, which
   emits the markup. The three stylesheets have to agree on how the current
   item looks, or the same navigation changes appearance as you move through
   the site. Metrics here match subscriptions.css deliberately. */
.topnav { display: flex; gap: 2px; margin-left: .5rem; }
.topnav a {
  font-size: 14px; color: var(--text-secondary); text-decoration: none;
  padding: 6px 11px; border-radius: 7px;
}
.topnav a:hover { background: var(--surface-2); color: var(--text-primary); }
/* Current item carries weight and a rule, never colour alone. */
.topnav a[aria-current="page"], .topnav a.active {
  background: var(--surface-2); color: var(--text-primary); font-weight: 650;
  box-shadow: inset 0 -2px 0 var(--accent);
}

.h3 { font-size: .85rem; font-weight: 620; margin: 0; }
.tag {
  font-size: .66rem; text-transform: uppercase; letter-spacing: .04em; font-weight: 650;
  color: var(--text-muted); border: 1px solid var(--border);
  border-radius: 999px; padding: .05rem .4rem; white-space: nowrap;
}
.tag-info { color: var(--accent); border-color: var(--accent-quiet); }

/* --- tabs --------------------------------------------------------------- */

.tabs { display: flex; gap: .25rem; border-bottom: 1px solid var(--border); margin-top: .75rem; }
.tab {
  font: inherit; font-size: .88rem; font-weight: 550;
  background: none; border: 0; border-bottom: 2px solid transparent;
  color: var(--text-secondary); padding: .45rem .8rem; cursor: pointer;
  margin-bottom: -1px;
}
.tab:hover { color: var(--text-primary); }
.tab.is-active { color: var(--accent); border-bottom-color: var(--accent); }
.tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* --- knowledge base rows ------------------------------------------------ */

.owner {
  font-family: var(--mono); font-size: .75rem;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 4px; padding: 0 .25rem; margin-left: .2rem;
}
.row-error {
  font-size: .75rem; color: var(--critical); margin-top: .25rem;
  word-break: break-word;
}

.st-icon { width: 1rem; height: 1rem; }
.st-label { font-size: .68rem; text-transform: uppercase; letter-spacing: .04em; font-weight: 650; }
.st-ready   { color: var(--good); }
.st-pending { color: var(--warning); }
.st-failed  { color: var(--critical); }

.btn-sm { font-size: .78rem; padding: .25rem .55rem; }
.danger:hover { color: var(--critical); }

/* --- teams -------------------------------------------------------------- */

.inline-form { display: flex; gap: .5rem; margin: .75rem 0; }
.input {
  font: inherit; padding: .4rem .6rem; border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong); background: var(--surface-1);
  color: var(--text-primary); flex: 1; min-width: 0;
}
.input:focus-visible { outline: 2px solid var(--accent); outline-offset: -1px; }

.team-projects { display: flex; flex-wrap: wrap; gap: .3rem; margin: .55rem 0; }
.chip-check { display: inline-flex; align-items: center; gap: .3rem; cursor: pointer;
  border: 1px solid var(--border-strong); border-radius: 999px;
  padding: .15rem .55rem; font-size: .78rem; font-family: var(--mono); }
.chip-check:hover { background: var(--surface-2); }
.chip-check input { margin: 0; }

/* --- dialog ------------------------------------------------------------- */

.dialog {
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface-1); color: var(--text-primary);
  box-shadow: var(--shadow); padding: 1.25rem; width: min(40rem, 94vw);
}
.dialog::backdrop { background: rgb(0 0 0 / 45%); }
.dialog h2 { margin-bottom: .75rem; }
.dialog-close-form { float: right; }
.dialog-x { font-size: 1.1rem; line-height: 1; padding: .1rem .4rem; }

.field { margin: .75rem 0; }
.field > label { display: block; font-size: .78rem; font-weight: 600; margin-bottom: .25rem; }
.url-row { display: flex; gap: .5rem; }

.alert { border-radius: var(--radius-sm); padding: .55rem .7rem; font-size: .85rem; margin: .5rem 0; }
.alert-error { border: 1px solid var(--critical); color: var(--critical); }

.found {
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface-2); padding: .6rem .7rem; margin: .6rem 0;
}

.check-all { font-size: .78rem; display: inline-flex; align-items: center; gap: .35rem; cursor: pointer; }

.page-list {
  display: flex; flex-direction: column; max-height: 17rem; overflow-y: auto;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.page-item {
  display: flex; align-items: center; gap: .5rem; padding: .4rem .6rem;
  font-size: .86rem; cursor: pointer; border-bottom: 1px solid var(--border);
}
.page-item:last-child { border-bottom: 0; }
.page-item:hover { background: var(--surface-2); }
.page-item input { margin: 0; flex: none; }

.dialog-actions { display: flex; justify-content: flex-end; gap: .5rem; margin-top: 1rem; }
.dialog-actions form { display: inline; }

/* --- flash -------------------------------------------------------------- */

.flash {
  position: fixed; bottom: 1rem; left: 50%; transform: translateX(-50%);
  background: var(--surface-1); border: 1px solid var(--border-strong);
  border-left: 3px solid var(--good);
  border-radius: var(--radius-sm); box-shadow: var(--shadow);
  padding: .6rem .9rem; font-size: .85rem; z-index: 50; max-width: 90vw;
}
.flash-error { border-left-color: var(--critical); }

/* The narrow-screen rule that used to live here applied to the card layout
   the tables replaced. Table overflow is handled by .table-wrap instead. */

/* Drafts: visible, legible, and plainly not selectable. Greyed out alone
 * would read as a rendering glitch, so the row also carries a "draft" tag and
 * a sentence saying why it is excluded. */
.page-item.is-draft { opacity: .62; cursor: not-allowed; }
.page-item.is-draft input { cursor: not-allowed; }
.tag-draft { color: var(--warning); border-color: var(--warning); }
.draft-why { display: block; font-size: .72rem; color: var(--text-muted); margin-top: .1rem; }

.st-never { color: var(--text-muted); }
.row-note { font-size: .75rem; color: var(--text-secondary); margin-top: .25rem; }

/* --- users & roles ------------------------------------------------------- */

.tag-admin { color: var(--accent); border-color: var(--accent); }

.role-chip {
  display: inline-flex; align-items: center; gap: .3rem;
  border: 1px solid var(--border-strong); border-radius: 999px;
  padding: .1rem .2rem .1rem .45rem; font-size: .78rem;
}
.role-chip.lead { border-color: var(--accent); }
.role-name { color: var(--text-secondary); }
.role-x {
  font: inherit; font-size: .9rem; line-height: 1; cursor: pointer;
  border: 0; background: none; color: var(--text-muted);
  padding: 0 .25rem; border-radius: 999px;
}
.role-x:hover { color: var(--critical); background: var(--surface-2); }

.user-grant { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; }
.select-sm { font-size: .8rem; padding: .25rem .45rem; }
.grant-sep { width: 1px; height: 1.2rem; background: var(--border); margin: 0 .3rem; }
.grant-help { margin-left: .2rem; }

.src-tabs { display: flex; gap: .25rem; border-bottom: 1px solid var(--border); margin: .5rem 0 .25rem; }
.src-tabs .tab { font-size: .84rem; }
input[type="file"].input { padding: .3rem; }

.sync-badge {
  display: inline-flex; align-items: center; gap: .25rem;
  font-size: .7rem; text-transform: uppercase; letter-spacing: .03em;
  font-weight: 650; white-space: nowrap;
}
.sync-badge .st-icon { width: .9rem; height: .9rem; }

/* ===========================================================================
   Sidebar shell
   ========================================================================= */

.settings-shell {
  flex: 1; display: grid; grid-template-columns: 13rem 1fr;
  gap: 1rem; padding: 1rem; max-width: 84rem; width: 100%; margin: 0 auto;
  align-items: start;
}
@media (max-width: 56rem) { .settings-shell { grid-template-columns: 1fr; } }

.sidebar {
  display: flex; flex-direction: column; gap: .15rem;
  position: sticky; top: 4rem;
}
@media (max-width: 56rem) {
  .sidebar { position: static; flex-direction: row; flex-wrap: wrap; }
}

.side-item {
  font: inherit; font-size: .88rem; font-weight: 550; text-align: left;
  background: none; border: 1px solid transparent; border-radius: var(--radius-sm);
  color: var(--text-secondary); padding: .45rem .7rem; cursor: pointer;
}
.side-item:hover { background: var(--surface-2); color: var(--text-primary); }
.side-item:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Active state carries weight and a left rule as well as colour, so it does
   not depend on hue alone. */
.side-item.is-active {
  background: var(--surface-2); color: var(--text-primary); font-weight: 650;
  border-color: var(--border); box-shadow: inset 2px 0 0 var(--accent);
}

.settings-body { min-width: 0; }
.section-help { margin-top: 0; max-width: 54rem; }

/* --- toolbar / search ---------------------------------------------------- */

.toolbar { display: flex; align-items: center; gap: .6rem; margin: .75rem 0 .25rem; }
.search { max-width: 24rem; }

/* ===========================================================================
   Grid tables
   ========================================================================= */

.table-wrap {
  overflow-x: auto; border: 1px solid var(--border);
  border-radius: var(--radius-sm); background: var(--surface-1);
}
.table-wrap .empty { padding: 1rem; margin: 0; }

table.grid { border-collapse: collapse; width: 100%; font-size: .85rem; }
table.grid th {
  text-align: left; font-size: .68rem; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text-muted); font-weight: 650;
  padding: .55rem .7rem; border-bottom: 1px solid var(--border-strong);
  white-space: nowrap; background: var(--surface-1);
  position: sticky; top: 0; z-index: 1;
}
table.grid td {
  padding: .55rem .7rem; border-bottom: 1px solid var(--border);
  vertical-align: top;
}
table.grid tbody tr:last-child td { border-bottom: 0; }
table.grid tbody tr:hover { background: var(--surface-2); }
table.grid th.num, table.grid td.num {
  text-align: right; font-variant-numeric: tabular-nums; width: 1%;
}
table.grid td.nowrap, table.grid th.nowrap { white-space: nowrap; }

.cell-main { font-weight: 550; display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; }
.cell-main a { color: inherit; text-decoration: none; }
.cell-main a:hover { color: var(--accent); text-decoration: underline; }

.col-title { min-width: 15rem; }
.col-grants { min-width: 14rem; }
.col-grant-ctl { min-width: 17rem; }
.col-actions { width: 1%; }
.col-actions .btn { margin-right: .2rem; }

/* A child page sits under the parent it was added with. The list is already
   ordered parent-then-children server side, so a rule and an indent are
   enough - no grouping logic in the client. */
tr.is-child .col-title { padding-left: 1.5rem; }
.child-rule {
  display: inline-block; width: .7rem; height: 1px;
  background: var(--border-strong); margin-right: .1rem; flex: none;
}

.dash { color: var(--text-muted); }

/* --- assign dialog ------------------------------------------------------- */

.assign-current ul.plain { list-style: none; margin: 0; padding: 0; }
.assign-current li {
  padding: .3rem .5rem; border: 1px solid var(--border);
  border-radius: var(--radius-sm); margin-bottom: .25rem; font-size: .84rem;
}
.role-chip.team { border-style: dashed; }

.page-item.by-key { background: color-mix(in srgb, var(--accent) 7%, transparent); }

/* --- loading ------------------------------------------------------------- */

.empty.loading { display: flex; align-items: center; gap: .55rem; }

.spinner {
  width: 1rem; height: 1rem; flex: none; border-radius: 50%;
  border: 2px solid var(--border-strong);
  border-top-color: var(--accent);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* An indefinite spin is exactly the kind of motion that triggers vestibular
   symptoms, so it is replaced rather than merely slowed. */
@media (prefers-reduced-motion: reduce) {
  .spinner { animation: none; border-top-color: var(--border-strong); opacity: .6; }
}


/* ---------- team project assignment ---------- */

/* Read-only keys in the row. The editable list lives in a dialog, because a
   checkbox per project per row stops working the moment the Jira catalogue
   grows - and it only grows. */
.chip-static {
  display: inline-block; padding: 1px 7px; margin: 0 4px 4px 0;
  border: 1px solid var(--border); border-radius: 999px;
  font-size: .78rem; font-weight: 600;
}
.chip-more {
  display: inline-block; padding: 1px 7px; font-size: .78rem;
  color: var(--text-secondary);
}

.pick-list {
  max-height: 46vh; overflow-y: auto; margin: .5rem 0;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: .35rem;
}
.project-pick {
  display: grid; grid-template-columns: auto auto 1fr; gap: .5rem;
  align-items: baseline; padding: .3rem .4rem; border-radius: var(--radius-sm);
  cursor: pointer;
}
.project-pick:hover { background: var(--surface-2); }
.pick-key { font-weight: 600; font-variant-numeric: tabular-nums; }
.pick-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }


/* ---------- type-ahead ---------- */

.typeahead { position: relative; }
.typeahead-list {
  position: absolute; left: 0; right: 0; top: calc(100% + 2px); z-index: 30;
  max-height: 15rem; overflow-y: auto;
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: var(--radius-sm); box-shadow: 0 6px 20px rgba(0,0,0,.12);
}
.typeahead-opt {
  display: block; width: 100%; text-align: left; border: 0; background: none;
  padding: .45rem .6rem; cursor: pointer; font: inherit; color: var(--text-primary);
}
.typeahead-opt:hover,
/* Keyboard highlight has to be a real class, not :hover - arrowing through a
   list the mouse is not over must still show where you are. */
.typeahead-opt.is-active { background: var(--surface-2); }
.typeahead-opt .ta-kind {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text-secondary); margin-right: .4rem;
}
.typeahead-opt .ta-sub { color: var(--text-secondary); font-size: .8rem; }
.typeahead-empty { padding: .5rem .6rem; color: var(--text-secondary); font-size: .85rem; }


/* ---------- charts ---------- */

/* Horizontal scroll rather than squeezing bars: a 24px cap on the mark is
   the spec, and shrinking below it to fit twelve sprints on a phone would
   break the thing the spec protects. */
/* A fixed viewport for the drawing: same box on every board, scrolling in
   both directions when the content is larger. The chart itself is drawn at
   natural size, so a bar is 24px whether the project has 3 closed sprints
   or 30. */
.chart-scroll {
  overflow: auto;
  max-height: 300px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: .5rem;
  background: var(--surface-1);
}
.chart { display: block; }
.chart-empty {
  color: var(--text-secondary); font-size: .9rem;
  padding: 1.5rem .25rem;
}

/* The bar group is the hover target, and it is the whole column - a hit
   target bigger than the mark, as the interaction spec asks. */
.vbar { cursor: default; }
.vbar:hover, .vbar:focus-visible { outline: none; }
.vbar:hover rect, .vbar:hover path,
.vbar:focus-visible path { filter: brightness(1.08); }
.vbar:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.legend {
  display: flex; gap: 1rem; flex-wrap: wrap;
  margin: .5rem 0 0; font-size: .82rem; color: var(--text-secondary);
}
.legend-item { display: inline-flex; align-items: center; gap: .35rem; }
.legend-block { width: 11px; height: 11px; border-radius: 3px; display: inline-block; }
.legend-rule { width: 13px; height: 2px; border-radius: 2px; display: inline-block; }
.legend-dash {
  width: 13px; height: 0; display: inline-block;
  border-top: 1px dashed var(--text-secondary);
}

.chart-table { width: 100%; border-collapse: collapse; font-size: .85rem; margin-top: .5rem; }
.chart-table th {
  text-align: left; font-size: .7rem; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text-secondary); font-weight: 600;
  padding: 0 .5rem .4rem; border-bottom: 1px solid var(--border);
}
.chart-table td { padding: .4rem .5rem; border-bottom: 1px solid var(--border); }
.chart-table .num { text-align: right; font-variant-numeric: tabular-nums; }
