/*
 * The supplier grid.
 *
 * Derived from the snag portal's manage.css (the internal project view), stripped to the
 * read-only subset: no cell editors, no dirty/sending states, no save bar. What is kept is the
 * shape that makes a 17-column table usable on a phone — `width: max-content` inside a
 * sideways-scrolling wrapper, a sticky header, and a sticky first column so the row keeps its
 * identity while the numbers scroll.
 *
 * Two things this file does differently from the snag portal, both for phones:
 *   - Headers wrap. `R value certified to Supplier` on one line makes a column three times wider
 *     than the `R7,360.00` under it; capped and wrapped, a money column is as wide as its
 *     widest number. The cap is on the header *title span*, not the cell — auto table layout
 *     ignores max-width on a cell but honours its content's intrinsic width.
 *   - On a phone (narrow, or short because it is held sideways) the wrapper has no max-height.
 *     The page scrolls vertically and only the table scrolls sideways; a scroll box inside a
 *     scrolling page is two gestures on a touch screen. The header stops pinning there — which
 *     is what full screen (`body.is-fullgrid`, the last section) gives back: the wrapper
 *     becomes the viewport, and both frozen panes work again.
 *
 * styles.css loads first and owns the tokens; this file only adds the grid.
 */

/* The sign-in screens are a phone-width column. A grid is not. */
body.sp .wrap { max-width: 1500px; }
body.sp.is-auth .wrap { max-width: 460px; }
body.sp main { padding-top: 24px; padding-bottom: 40px; }

/* The compact variant of .btn. It lived in the snag portal's manage.css, so it came across in the
   markup but not in any stylesheet — "Columns" and "Sign out" were rendering full size. */
.btn--sm { min-height: 36px; padding: 0 16px; font-size: 13px; }

/* ---------- header strip ---------- */
.sp-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 16px;
}
.sp-head h1 { margin: 0 0 2px; font-size: 22px; }
.sp-head__sub { margin: 0; font-size: 13px; color: var(--muted); }
.sp-head__actions { display: flex; align-items: center; gap: 8px; }

/* ---------- tabs ---------- */
.sp-tabs { display: flex; gap: 6px; margin-bottom: 14px; flex-wrap: wrap; }
.sp-tab {
  border: 1.5px solid var(--grey); background: var(--white); color: var(--text);
  border-radius: var(--radius-pill); min-height: 40px; padding: 0 20px;
  font-weight: 500; font-size: 14px;
}
.sp-tab:hover { border-color: var(--navy); color: var(--navy); }
.sp-tab[aria-selected="true"] { background: var(--navy); border-color: var(--navy); color: var(--white); }
.sp-tab__count { opacity: 0.7; font-weight: 400; margin-left: 6px; }

/* ---------- totals ---------- */
/* Separate cards, not a 1px-gap grid. How many totals there are depends on which columns the
   report has, and an auto-fit grid shows its unfilled track as a grey block on a narrow screen. */
.sp-totals { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 14px; }
.sp-total {
  flex: 1 1 170px; background: var(--white); padding: 12px 14px;
  border: 1px solid var(--grey); border-radius: var(--radius-card);
}
.sp-total__label { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.sp-total__value { font-size: 18px; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; margin-top: 2px; }
.sp-total__value.is-neg { color: var(--danger); }

/* ---------- the grid ---------- */
.sp-gridwrap {
  overflow: auto;
  max-height: calc(100vh - 320px);
  background: var(--white);
  border: 1px solid var(--grey);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow);
}
.sp-grid {
  border-collapse: separate;
  border-spacing: 0;
  font-size: 13px;
  width: max-content;
  min-width: 100%;
}
.sp-grid th, .sp-grid td {
  border-bottom: 1px solid var(--grey);
  border-right: 1px solid var(--grey);
  padding: 8px 10px;
  vertical-align: top;
  text-align: left;
}
.sp-grid th:last-child, .sp-grid td:last-child { border-right: 0; }
.sp-grid tbody tr:last-child td { border-bottom: 0; }

.sp-grid thead th {
  position: sticky; top: 0; z-index: 3;
  background: var(--ink); color: var(--white);
  font-weight: 500; font-size: 12px; letter-spacing: 0.02em; line-height: 1.25;
  vertical-align: bottom; padding: 0;
}
/* The whole header cell is the sort control, so the hit area is the cell and not just the text.
   The title wraps; the pencil and arrow sit after its last line. */
.sp-grid thead th button {
  display: flex; align-items: flex-end; gap: 5px;
  width: 100%; height: 100%; padding: 8px 10px;
  background: transparent; border: 0; color: inherit; font: inherit;
  text-align: left;
}
.sp-grid thead th button:hover { background: rgba(255, 255, 255, 0.09); }
.sp-grid thead th.num button { justify-content: flex-end; text-align: right; }
/* The cap that lets a column be as narrow as its values. Numbers are short; titles are not. */
.sp-grid thead th.num .sp-th__t { max-width: 100px; }
.sp-grid thead th:not(.num):not(.sticky) .sp-th__t { max-width: 200px; }
.sp-grid thead th .arrow { opacity: 0; font-size: 10px; flex: none; padding-bottom: 2px; }
.sp-grid thead th[aria-sort] .arrow { opacity: 0.85; }

/* The row's identity stays put while the rest scrolls sideways. */
.sp-grid th.sticky, .sp-grid td.sticky {
  position: sticky; left: 0; z-index: 2;
  background: var(--white);
  border-right: 2px solid var(--grey);
  box-shadow: 2px 0 6px rgba(18, 18, 18, 0.06);
}
.sp-grid thead th.sticky { z-index: 4; background: var(--ink); }

.sp-grid tbody tr:nth-child(even) td { background: #FCFCFB; }
.sp-grid tbody tr:nth-child(even) td.sticky { background: #FCFCFB; }
.sp-grid tbody tr:hover td { background: #FAFCFE; }
.sp-grid tbody tr:hover td.sticky { background: #FAFCFE; }

.sp-grid td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.sp-grid td.is-neg { color: var(--danger); }
.sp-grid td .clip { display: block; max-width: 360px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sp-grid td.empty-cell { color: #B9B9B9; }

/* ---------- column picker ---------- */
.sp-cols { position: relative; }
.sp-cols > summary { list-style: none; }
.sp-cols > summary::-webkit-details-marker { display: none; }
.sp-cols__panel {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 30;
  width: 300px; max-height: 420px; overflow: auto;
  background: var(--white); border: 1px solid var(--grey);
  border-radius: var(--radius-card); box-shadow: var(--shadow); padding: 10px 12px;
}
.sp-cols__panel label { display: flex; gap: 8px; align-items: center; padding: 5px 2px; font-size: 13px; cursor: pointer; }

.sp-foot { margin-top: 10px; font-size: 12px; color: var(--muted); }

/* ---------- the way into full screen ---------- */
/* A quiet secondary button on a desktop, where the grid already fits; the phone block below
   turns it into a full-width call to action. */
.sp-gridbar { display: flex; justify-content: flex-end; margin-bottom: 8px; }
.sp-gridbar[hidden] { display: none; }
.sp-expand { background: var(--white); color: var(--navy); border-color: var(--navy); gap: 6px; }
.sp-expand:hover { background: var(--pale); }
.sp-expand__icon { font-size: 16px; line-height: 1; }

/* ---------- the one editable column ---------- */
/* Amount Claimed by Supplier is the only cell a supplier can change, so it has to look like the
   only one: a pale wash on the column, a pencil in the header, and a real input in the cell. */
.sp-grid thead th.is-editable { background: var(--navy); }
.sp-grid thead th.is-editable .pencil { font-size: 12px; opacity: 0.9; }
.sp-grid tbody td.is-editable { background: var(--pale) !important; padding: 4px 6px; }
.sp-grid tbody tr:hover td.is-editable { background: #D6E5F0 !important; }
.sp-edit {
  width: 130px; max-width: 100%;
  padding: 5px 8px;
  font: inherit; font-size: 13px; text-align: right; font-variant-numeric: tabular-nums;
  color: var(--ink); background: var(--white);
  border: 1px solid var(--sky); border-radius: 6px;
}
.sp-edit:focus { outline: 2px solid var(--navy); outline-offset: 0; border-color: var(--navy); }
.sp-edit::placeholder { color: #B9B9B9; }
.sp-edit.is-invalid { border-color: var(--danger); background: var(--danger-bg); }
.sp-grid tbody tr.is-saving td { opacity: 0.55; }
.sp-grid tbody tr.is-saving .sp-edit { background: var(--light); }

/* ---------- phones ---------- */
/* Last in the file so it wins on order over everything above, the editable column included.
   The table keeps its shape and scrolls sideways; everything around it gets out of the way.
   One scroll direction each: the page goes up and down, the wrapper only left and right. */
/* The second clause is a phone held sideways: 812px wide, so not "narrow", but 375px tall, where
   the desktop scroll box (100vh - 320px) came out at 55px. */
@media (max-width: 720px), ((max-width: 1024px) and (max-height: 500px)) {
  .sp-head { align-items: flex-start; }

  /* The way in. Same weight as the sign-in button, directly above the grid where a thumb lands. */
  .sp-expand {
    width: 100%; min-height: 48px; font-size: 15px;
    background: var(--navy); border-color: var(--navy); color: var(--white);
  }
  .sp-expand:hover { background: var(--navy-deep); border-color: var(--navy-deep); color: var(--white); }

  .sp-gridwrap {
    max-height: none;
    /* Bleed to the screen edges — 40px of .wrap padding is a column's worth on a 375px screen. */
    margin: 0 -20px; border-radius: 0; border-left: 0; border-right: 0;
  }
  .sp-grid { font-size: 12.5px; }
  .sp-grid th, .sp-grid td { padding: 6px 8px; }
  .sp-grid thead th button { padding: 7px 8px; gap: 3px; }
  /* Tighter than the desktop caps so a money header (three short lines) is narrower than
     `R148,235.50` underneath and the value, not the title, sets the column. */
  .sp-grid thead th.num .sp-th__t { max-width: 72px; }
  .sp-grid thead th:not(.num):not(.sticky) .sp-th__t { max-width: 110px; }

  /* The frozen first column: narrow and wrapped, so it names the row without owning the screen. */
  .sp-grid td.sticky .clip {
    max-width: 140px; white-space: normal; overflow: hidden;
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  }
  .sp-grid td .clip { max-width: 180px; }

  /* 16px is the size below which iOS Safari zooms the page when a field is focused. */
  .sp-edit { width: 110px; min-height: 40px; font-size: 16px; }

  .sp-total { flex: 1 1 calc(50% - 5px); padding: 10px 12px; }
  .sp-total__value { font-size: 16px; }

  .sp-cols__panel { width: min(300px, calc(100vw - 40px)); }

  /* Sideways: three rows of totals would be the whole screen. One swipeable strip instead. */
  @media (max-height: 500px) {
    .sp-totals { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 4px; }
    .sp-total { flex: 0 0 160px; }
  }
}

/* ---------- full screen ---------- */
/* The grid as the whole screen. The wrapper is pinned to the viewport and becomes the thing that
   scrolls, so the sticky header row and sticky first column above pin again — frozen panes, the
   way a spreadsheet app does it. Nothing else is rewritten: the bar sits on top, the page
   underneath is simply not scrollable. */
body.is-fullgrid { overflow: hidden; }
body.is-fullgrid .sp-gridwrap {
  position: fixed; z-index: 60;
  top: calc(48px + env(safe-area-inset-top, 0px)); left: 0; right: 0; bottom: 0;
  max-height: none; margin: 0; border: 0; border-radius: 0; box-shadow: none;
  overflow: auto; -webkit-overflow-scrolling: touch;
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
/* Switching reports inside full screen: the spinner, an error or "nothing here" must show over
   the layer, not under it. */
body.is-fullgrid #sp-loading, body.is-fullgrid #sp-error, body.is-fullgrid #sp-empty {
  position: fixed; z-index: 61; left: 0; right: 0; margin: 0; border-radius: 0;
  top: calc(48px + env(safe-area-inset-top, 0px));
}
.sp-fullbar {
  position: fixed; z-index: 61; top: 0; left: 0; right: 0;
  display: flex; align-items: center; gap: 8px;
  height: calc(48px + env(safe-area-inset-top, 0px));
  padding: env(safe-area-inset-top, 0px) 12px 0;
  background: var(--ink); color: var(--white);
}
.sp-fullbar[hidden] { display: none; }
.sp-tabs--full { margin: 0; gap: 6px; flex-wrap: nowrap; }
.sp-tabs--full .sp-tab {
  min-height: 32px; padding: 0 12px; font-size: 13px; white-space: nowrap;
  background: transparent; color: var(--white); border-color: rgba(255, 255, 255, 0.35);
}
.sp-tabs--full .sp-tab:hover { border-color: var(--white); color: var(--white); }
.sp-tabs--full .sp-tab[aria-selected="true"] { background: var(--navy); border-color: var(--navy); }
/* The rotate hint: its own thin row under the tabs, portrait phones only — there is no room for
   it beside two pills and Done on a 375px bar. The bar and the wrapper's top grow together. */
.sp-fullbar__hint { display: none; }
@media (orientation: portrait) and (max-width: 720px) {
  .sp-fullbar { flex-wrap: wrap; height: calc(70px + env(safe-area-inset-top, 0px)); align-content: flex-start; padding-top: calc(8px + env(safe-area-inset-top, 0px)); }
  .sp-fullbar__hint {
    display: block; flex: 1 0 100%; order: 9;
    font-size: 11px; line-height: 22px; text-align: center; opacity: 0.75;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  body.is-fullgrid .sp-gridwrap,
  body.is-fullgrid #sp-loading, body.is-fullgrid #sp-error, body.is-fullgrid #sp-empty {
    top: calc(70px + env(safe-area-inset-top, 0px));
  }
}
.sp-fullbar__done {
  margin-left: auto; flex: none;
  background: transparent; color: var(--white); border-color: rgba(255, 255, 255, 0.6);
}
.sp-fullbar__done:hover { background: rgba(255, 255, 255, 0.12); color: var(--white); border-color: var(--white); }
body.is-fullgrid .toast { z-index: 70; }
