/* Greenlight Portal — shell chrome (Phase C.1, design §2.3).
 * Mobile-first; the nav collapses to a horizontal scroller under 800px.
 * PR-5: tokens only — no colour literal in this file. */

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  color: var(--ink);
  background: var(--surface-alt);
  -webkit-text-size-adjust: 100%;
}

/* ---------------------------------------------------------------- topbar */

.topbar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--ink);
  text-decoration: none;
  margin-right: auto;
}

.brand .dot {
  width: 10px;
  height: 10px;
  border-radius: var(--radius-pill);
  background: var(--green);
  flex-shrink: 0;
}

.whoami {
  font-size: var(--fs-sm);
  color: var(--muted);
  text-align: right;
  line-height: var(--lh-tight);
}

.whoami strong { display: block; color: var(--ink); font-weight: var(--fw-semibold); }

/* ------------------------------------------------------------------- nav */

.nav {
  display: flex;
  gap: var(--space-1);
  padding: 0 var(--space-2);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.nav a {
  flex: 0 0 auto;
  padding: var(--space-3) var(--space-3);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--muted);
  text-decoration: none;
  border-bottom: 3px solid transparent;
  white-space: nowrap;
}

.nav a:hover { color: var(--ink); }
.nav a[aria-current="page"] { color: var(--ink); border-bottom-color: var(--green); }
.nav a .pill {
  display: inline-block;
  margin-left: var(--space-2);
  padding: 0 var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--surface-alt);
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
}

/* ---------------------------------------------------------------- layout */

.main { max-width: 1040px; margin: 0 auto; padding: var(--space-4) var(--space-3) var(--space-6); }

.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: var(--space-4);
}

.panel-head { margin-bottom: var(--space-4); }
.panel-head h1 { font-size: var(--fs-lg); margin: 0 0 var(--space-1); }
.panel-head .sub { font-size: var(--fs-sm); color: var(--muted); }

.state-msg {
  color: var(--muted);
  font-size: var(--fs-base);
  padding: var(--space-6);
  text-align: center;
  border: 1px dashed var(--line);
  border-radius: var(--radius-md);
  background: var(--surface);
}

/* Pure-CSS spinner. currentColor so it always matches the text/button it sits
   in — never a colour literal (PR-5). Reused verbatim (~8 lines) in every
   stylesheet that needs one; see portal.css/request.css/rules.css and the
   item-view/board-view/aging inline <style> blocks. */
.spinner {
  display: inline-block;
  width: 16px;
  height: 16px;
  margin-right: var(--space-2);
  vertical-align: -3px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: gl-spin .6s linear infinite;
}
@keyframes gl-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .spinner { animation-duration: 1.5s; }
}
/* .btn already spaces its children with `gap` — the margin above is only for
   plain-text contexts like .state-msg, so it must not double up in a button. */
.btn .spinner { margin-right: 0; }

.banner {
  border: 1px solid var(--line);
  border-left-width: 4px;
  border-radius: var(--radius-sm);
  padding: var(--space-3);
  margin-bottom: var(--space-4);
  background: var(--surface);
}

.banner h2 { font-size: var(--fs-base); font-weight: var(--fw-semibold); margin: 0 0 var(--space-1); }
.banner p { margin: 0; font-size: var(--fs-base); }
.banner.error { border-color: var(--red); background: var(--red-tint); }
.banner.info { border-color: var(--blue); background: var(--blue-tint); }
.banner .banner-actions { margin-top: var(--space-3); }

/* --------------------------------------------------------------- buttons */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 40px;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font-family: inherit;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  text-decoration: none;
  cursor: pointer;
}

.btn.primary { background: var(--green); color: var(--on-brand); }
.btn.primary:hover { background: var(--green-dark); }
.btn.ghost { background: var(--surface); color: var(--ink); border-color: var(--line-strong); }
.btn.ghost:hover { background: var(--surface-alt); }
.btn.small { min-height: 30px; padding: 2px var(--space-3); font-size: var(--fs-sm); }
.btn.approve { background: var(--green); color: var(--on-brand); }
.btn.reject { background: var(--surface); color: var(--red); border-color: var(--red); }
.btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }

/* ---------------------------------------------------------------- tables */

.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

table { width: 100%; border-collapse: collapse; }

th {
  text-align: left;
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--muted);
  padding: var(--space-2) var(--space-2);
  border-bottom: 2px solid var(--line);
  white-space: nowrap;
}

td {
  padding: var(--space-3) var(--space-2);
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-base);
  vertical-align: middle;
}

tr:hover td { background: var(--surface-alt); }

.item-name { font-weight: var(--fw-semibold); }
.item-name a { color: var(--ink); text-decoration: none; }
.item-name a:hover { text-decoration: underline; color: var(--blue); }
.muted { color: var(--muted); font-size: var(--fs-sm); }
.actions-cell { white-space: nowrap; }
.actions-cell .btn { margin-right: var(--space-1); }

.badge {
  display: inline-block;
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  padding: 2px var(--space-3);
  border-radius: var(--radius-pill);
  color: var(--on-brand);
  background: var(--amber);
  white-space: nowrap;
}

.badge.old { background: var(--red); }
/* Outcome success, NOT the waiting-time semantic the bare .badge carries
   (that one is amber = pending/warning) — an approved decision in History
   must read as success everywhere, matching board status / decision pages. */
.badge.good { background: var(--green); }

/* Narrow screens: drop the two lowest-value columns rather than let the
   decision buttons slide off behind a horizontal scroll. Same trade the
   existing board view makes at 640px. */
@media (max-width: 799px) {
  th, td { padding: var(--space-2) var(--space-1); }
  .col-stage, .col-requested, .col-board { display: none; }
  .actions-cell .btn { min-height: 36px; }
}

/* --------------------------------------------------------- aging buckets */

.buckets {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.bucket {
  border: 1px solid var(--line);
  border-top: 3px solid var(--line);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  background: var(--surface);
}

.bucket .n { font-size: var(--fs-xl); font-weight: var(--fw-semibold); line-height: var(--lh-tight); }
.bucket .l { font-size: var(--fs-xs); color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.bucket.b0 { border-top-color: var(--green); } .bucket.b0 .n { color: var(--green); }
.bucket.b1 { border-top-color: var(--amber); } .bucket.b1 .n { color: var(--amber); }
.bucket.b2 { border-top-color: var(--amber); } .bucket.b2 .n { color: var(--amber); }
.bucket.b3 { border-top-color: var(--red); }   .bucket.b3 .n { color: var(--red); }

/* --------------------------------------------------------- "later" state */

.later { text-align: center; padding: var(--space-6) var(--space-3); }
.later h2 { font-size: var(--fs-lg); margin: 0 0 var(--space-2); }
.later p { margin: 0 auto var(--space-2); max-width: 46ch; font-size: var(--fs-base); color: var(--muted); }
.later .slice {
  display: inline-block;
  margin-bottom: var(--space-3);
  padding: 2px var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--blue-tint);
  color: var(--blue);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: .04em;
}

/* ---------------------------------------------------------- onboarding */

.onboard { padding: var(--space-5) var(--space-3); max-width: 56ch; margin: 0 auto; }
.onboard h2 { font-size: var(--fs-lg); margin: 0 0 var(--space-2); }
.onboard .lede { font-size: var(--fs-base); color: var(--muted); margin: 0 0 var(--space-4); }
.onboard .steps { margin: 0 0 var(--space-3); padding-left: var(--space-5); }
.onboard .steps li { font-size: var(--fs-base); padding: var(--space-1) 0; }
.onboard .hint { font-size: var(--fs-sm); color: var(--muted); margin: 0; }
.onboard .hint.warn { color: var(--red); }

.onboard-cta { margin-top: var(--space-5); padding-top: var(--space-4); border-top: 1px solid var(--line); }
.onboard-cta .hint { margin-top: var(--space-2); font-size: var(--fs-sm); color: var(--muted); }

.banner.ok { border-color: var(--green); background: var(--green-tint); }
.banner.warn { border-color: var(--amber); background: var(--amber-tint); }

/* --------------------------------------------------------- onboarding tab */
/* Numbered checklist. Two columns (number · body) so the copy hangs off a
   consistent left edge; on a 390px phone the number shrinks but stays inline,
   because stacking it above the title breaks the "step 3 of 5" read. */

/* The "two ways, both normal" line. Tinted so it reads as orientation rather
   than as one more instruction. */
.ob-lede {
  margin: 0 0 var(--space-4);
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--blue-tint);
  color: var(--ink);
  font-size: var(--fs-base);
}

.ob-steps { list-style: none; margin: 0; padding: 0; }

.ob-step {
  display: flex;
  gap: var(--space-3);
  padding: var(--space-4) 0;
  border-top: 1px solid var(--line);
}

.ob-step:first-child { border-top: none; padding-top: 0; }

.ob-num {
  flex: 0 0 28px;
  height: 28px;
  border-radius: var(--radius-pill);
  background: var(--surface-alt);
  color: var(--muted);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Done steps recede: the point of the list is what is LEFT to do. */
.ob-step[data-state="done"] .ob-num { background: var(--green-tint); color: var(--green-dark); }

.ob-body { flex: 1 1 auto; min-width: 0; }

.ob-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-1);
}

.ob-head h2 { font-size: var(--fs-md); font-weight: var(--fw-semibold); margin: 0; }

.ob-tag {
  padding: 0 var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--surface-alt);
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
}

/* Status sits at the far right on a wide screen and wraps under the title on a
   narrow one — never truncated, because it is the whole point of the row. */
.ob-status {
  margin-left: auto;
  padding: 2px var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  white-space: nowrap;
}

.ob-status.done    { background: var(--green-tint); color: var(--green-dark); }
.ob-status.todo    { background: var(--surface-alt); color: var(--muted); }
.ob-status.optional{ background: var(--blue-tint); color: var(--blue); }
/* Unknown is NOT "not done" — it reads as an outage, not as a task. */
.ob-status.unknown { background: var(--amber-tint); color: var(--ink); }

.ob-what { margin: 0; font-size: var(--fs-base); color: var(--ink); }

/* Click-by-click instructions inside a step. Indented under the copy so the
   step's own number stays the only top-level counter the eye tracks. */
.ob-sub { margin: var(--space-2) 0 0; padding-left: var(--space-5); }
.ob-sub li { font-size: var(--fs-base); color: var(--ink); padding: var(--space-1) 0; }

/* Manual "Mark as done" tick — the one step no server flag can confirm. */
.ob-tick {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  min-height: 40px;
}

.ob-tick:hover { background: var(--surface-alt); }
.ob-tick input { width: 16px; height: 16px; margin: 0; accent-color: var(--green); cursor: pointer; }
.ob-tick:focus-within { outline: none; box-shadow: var(--focus-ring); }
.ob-step[data-state="done"] .ob-tick { border-color: var(--green); background: var(--green-tint); }
.ob-note { margin: var(--space-2) 0 0; font-size: var(--fs-sm); color: var(--muted); }
.ob-extra { margin: var(--space-2) 0 0; font-size: var(--fs-sm); }
.ob-extra a { color: var(--blue); text-decoration: none; font-weight: var(--fw-semibold); }
.ob-extra a:hover { text-decoration: underline; }

/* The inline "Create my approvals board" block is the shared .onboard-cta; in
   this list it must not draw its own divider on top of the step border. */
.ob-body .onboard-cta { margin-top: var(--space-3); padding-top: 0; border-top: none; }

.ob-finish {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
}

.ob-finish .hint { margin: var(--space-2) 0 0; font-size: var(--fs-sm); color: var(--muted); }
.ob-finish .hint a { color: var(--blue); }

@media (max-width: 480px) {
  .ob-step { gap: var(--space-2); }
  .ob-num { flex-basis: 24px; height: 24px; font-size: var(--fs-xs); }
  /* Let the status keep its own line rather than squeezing the title. */
  .ob-status { margin-left: 0; }
  .ob-finish .btn { width: 100%; }
}

/* ------------------------------------------------------------ board picker */

.board-filter { margin-bottom: var(--space-3); }
.board-filter input {
  width: 100%; font-family: inherit; font-size: var(--fs-base); color: var(--ink);
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3); min-height: 40px;
}
.board-filter input:focus { outline: none; border-color: var(--focus); box-shadow: var(--focus-ring); }
.board-filter .hint { margin: var(--space-2) 0 0; font-size: var(--fs-sm); color: var(--muted); }

.board-list { list-style: none; margin: 0; padding: 0; border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; }
.board-list li + li { border-top: 1px solid var(--line); }
.board-pick {
  display: flex; align-items: center; gap: var(--space-3); width: 100%;
  background: var(--surface); border: none; padding: var(--space-3);
  font: inherit; font-size: var(--fs-base); color: var(--ink); text-align: left; cursor: pointer;
}
.board-pick:hover { background: var(--surface-alt); }
.board-pick:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.board-pick .board-name { font-weight: var(--fw-semibold); }
.board-pick .board-go { margin-left: auto; color: var(--blue); font-size: var(--fs-sm); white-space: nowrap; }

/* --------------------------------------------------------------- settings */

.kv-list { margin: 0; }
.kv-list > div { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-3); padding: var(--space-2) 0; border-top: 1px solid var(--line); }
.kv-list > div:first-child { border-top: none; }
.kv-list dt { flex: 0 0 140px; color: var(--muted); font-size: var(--fs-sm); margin: 0; }
.kv-list dd { flex: 1 1 200px; margin: 0; font-size: var(--fs-base); word-break: break-word; }
.kv-list .muted { color: var(--muted); font-size: var(--fs-sm); }

.pill.ok { background: var(--green-tint); color: var(--green-dark); }
.pill.bad { background: var(--red-tint); color: var(--red); }

.plan-line { margin: 0 0 var(--space-2); font-size: var(--fs-base); text-transform: capitalize; }
.usage-line { margin: 0 0 var(--space-2); font-size: var(--fs-base); }

.meter { height: 8px; border-radius: var(--radius-pill); background: var(--surface-alt); overflow: hidden; }
.meter-fill { display: block; height: 100%; background: var(--green); border-radius: var(--radius-pill); }
.meter-fill.near { background: var(--amber); }

/* --------------------------------------------------------------- footer */

.portal-footer {
  max-width: 1040px;
  margin: 0 auto;
  padding: 0 var(--space-3) var(--space-4);
  text-align: center;
}

.portal-footer a {
  font-size: var(--fs-xs);
  color: var(--muted);
  text-decoration: none;
}

.portal-footer a:hover { color: var(--ink); text-decoration: underline; }

@media (min-width: 800px) {
  .portal-footer { padding: 0 var(--space-5) var(--space-5); }
}

/* ---------------------------------------------------------------- toasts */

.toasts {
  position: fixed;
  left: var(--space-3);
  right: var(--space-3);
  bottom: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  pointer-events: none;
}

.toast {
  background: var(--ink);
  color: var(--on-brand);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  font-size: var(--fs-sm);
  box-shadow: var(--shadow-md);
}

.toast.error { background: var(--red); }
.toast.success { background: var(--green-dark); }

/* .toasts is click-through so a toast never swallows a click on the page
   behind it. A toast that CARRIES a link has to opt back in, or the link is
   unclickable. Scoped to .has-link so plain toasts keep the old behaviour. */
.toast.has-link { pointer-events: auto; display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-3); align-items: baseline; }
.toast.has-link a { color: var(--on-brand); font-weight: var(--fw-semibold); white-space: nowrap; }

/* ------------------------------------------------------------- login page */

.login-wrap {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
}

.login-card {
  width: 100%;
  max-width: 400px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: var(--space-6) var(--space-5);
  text-align: center;
}

.login-card .brand { justify-content: center; margin: 0 0 var(--space-4); font-size: var(--fs-lg); }
.login-card h1 { font-size: var(--fs-lg); margin: 0 0 var(--space-2); }
.login-card p { font-size: var(--fs-base); color: var(--muted); margin: 0 0 var(--space-5); }
.login-card .btn { width: 100%; min-height: 46px; }
.login-card .fine { font-size: var(--fs-sm); margin: var(--space-4) 0 0; }
.login-card .fine a { color: var(--blue); }

/* ------------------------------------------------------------- ≥800px up */

@media (min-width: 800px) {
  .topbar, .nav { padding-left: var(--space-5); padding-right: var(--space-5); }
  .main { padding: var(--space-5); }
  .panel { padding: var(--space-5); }
  .buckets { grid-template-columns: repeat(4, 1fr); }
  .toasts { left: auto; right: var(--space-5); width: 320px; }
}
