/* ===========================================================================
   #/access — the people × apps matrix (js/view-access.js).

   Every selector here starts with .ax- (DESIGN.md §7.1: view CSS defines only
   its own prefix, and touches a shared class only through a prefixed
   ancestor, e.g. ".ax-table .switch").

   Layout: the matrix scrolls INSIDE its frame (both ways), so its header rows
   (groups, apps, "New users") stick to the top of the frame and the name
   column sticks to its left edge. A sticky element inside an overflow
   container sticks to that container, not to the page — hence the frame's
   own max-height instead of page-level stickiness.
   =========================================================================== */

.ax-banners:empty, .ax-toolbar:empty { display: none; }
.ax-banners .note { align-items: center; }
.ax-banners .note > div, .ax-banners .note > span:not(.material-symbols-rounded) { flex: 1; }

/* ---------------------------------------------------------------- toolbar */
.ax-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 14px; margin-bottom: 12px; }
.ax-search { flex: 1 1 220px; max-width: 320px; }
.ax-filters { display: flex; flex-wrap: wrap; gap: 6px; }
.ax-filter {
  display: inline-flex; align-items: center; gap: 6px; min-height: 36px; padding: 0 8px 0 12px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--panel); color: var(--ink2); cursor: pointer;
  font-family: var(--font-display); font-weight: 500; font-size: 13px;
  transition: background var(--dur), color var(--dur), border-color var(--dur);
}
.ax-filter:hover { color: var(--ink); border-color: var(--line-strong); }
.ax-filter-n { font-family: var(--font-mono); font-size: 11px; min-width: 22px; text-align: center; padding: 2px 6px; border-radius: 999px; background: var(--panel2); }
.ax-filter[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--bg); }
.ax-filter[aria-pressed="true"] .ax-filter-n { background: color-mix(in srgb, var(--bg) 22%, transparent); color: inherit; }
.ax-dis { margin-left: auto; }
.ax-dis .switch-row { padding: 4px 0; gap: 10px; }
.ax-dis .switch-label { font-size: 13.5px; color: var(--ink2); }

/* ------------------------------------------------------- summary + legend */
.ax-meta { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px 18px; margin-bottom: 12px; }
.ax-summary { display: flex; flex-wrap: wrap; gap: 6px; }
.ax-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; font-size: 12.5px; color: var(--ink2); }
.ax-legend > span { display: inline-flex; align-items: center; gap: 6px; }
.ax-key-staged {
  width: 16px; height: 16px; border-radius: 5px; flex: none;
  background: var(--accent-tint-strong); box-shadow: inset 0 0 0 1.5px var(--accent);
  background-image: radial-gradient(circle at 78% 22%, var(--accent) 0 2.5px, transparent 3px);
}

/* ----------------------------------------------------------------- matrix */
.ax-body { position: relative; min-width: 0; }
.ax-scroll {
  --ax-head-w: 300px;
  --ax-col-w: 46px;
  --ax-row-h: 54px;
  position: relative; overflow: auto; overscroll-behavior: contain;
  width: fit-content; max-width: 100%;
  max-height: max(360px, calc(100dvh - var(--topbar-h) - 300px));
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--e1);
}
:root[data-density="compact"] .ax-scroll { --ax-row-h: 46px; --ax-col-w: 42px; --ax-head-w: 276px; }
/* Fixed layout with an exact width (--ax-n = columns shown, set inline), so
   the name column is its declared width and each app column is equal. */
.ax-table { border-collapse: separate; border-spacing: 0; table-layout: fixed; width: calc(var(--ax-head-w) + var(--ax-n, 1) * var(--ax-col-w)); }
.ax-table .ax-col-head { width: var(--ax-head-w); }
.ax-table .ax-col { width: var(--ax-col-w); }
/* Zero-specificity reset, so every rule below wins without !important. */
:where(.ax-table) :where(th, td) { padding: 0; font-weight: 400; text-align: left; background: var(--panel); }

/* The three header rows stick together to the top of the frame. */
.ax-table thead { position: sticky; top: 0; z-index: 3; }

/* Group band */
.ax-grp {
  height: 30px; padding: 0 6px 0 10px; vertical-align: middle; white-space: nowrap; overflow: hidden;
  font-family: var(--font-display); font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink2); border-bottom: 1px solid var(--line);
}
.ax-grp > span { position: sticky; left: calc(var(--ax-head-w) + 10px); display: block; overflow: hidden; text-overflow: ellipsis; }
.ax-grp.is-gstart, .ax-cell.is-gstart, .ax-app.is-gstart { box-shadow: inset 1px 0 0 var(--line-strong); }

/* Corner */
.ax-corner {
  position: sticky; left: 0; z-index: 2; vertical-align: bottom; padding: 14px 16px 12px;
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.ax-corner-title { display: block; font-family: var(--font-display); font-size: 18px; font-weight: 500; letter-spacing: -.01em; }
.ax-corner-n { display: block; margin-top: 2px; font-size: 13px; color: var(--ink2); }
.ax-corner-hint { display: flex; align-items: center; gap: 6px; margin-top: 14px; font-size: 12px; color: var(--ink2); }
.ax-corner-hint .material-symbols-rounded { font-size: 16px; }

/* App column heads: tile, mode glyph, rotated name. The whole head is the
   column's menu button. */
.ax-app { vertical-align: bottom; border-bottom: 1px solid var(--line); }
.ax-app-btn {
  display: flex; flex-direction: column-reverse; align-items: center; justify-content: flex-start; gap: 8px;
  width: 100%; padding: 10px 0 8px; border: 0; background: none; color: var(--ink); cursor: pointer;
  border-radius: 12px 12px 0 0; font: inherit;
  transition: background var(--dur);
}
.ax-app-btn:hover, .ax-app.is-hot .ax-app-btn { background: var(--panel2); }
.ax-app-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.ax-app-btn[aria-expanded="true"] { background: var(--accent-tint); }
.ax-app-ic { position: relative; display: inline-flex; }
.ax-app-name {
  writing-mode: vertical-rl; transform: rotate(180deg);
  max-height: 100px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: var(--font-display); font-size: 12.5px; font-weight: 500; line-height: 1.2; color: var(--ink);
}
.ax-mode {
  position: absolute; right: -6px; bottom: -5px; display: grid; place-items: center;
  width: 17px; height: 17px; border-radius: 50%; background: var(--panel); box-shadow: 0 0 0 1.5px var(--panel);
}
.ax-mode .material-symbols-rounded { font-size: 13px; font-variation-settings: "FILL" 1; }
.ax-mode.is-private { color: var(--accent-ink); background: color-mix(in srgb, var(--accent) 18%, var(--panel)); }
.ax-mode.is-contribute { color: var(--warn); background: color-mix(in srgb, var(--warn) 20%, var(--panel)); }
.ax-mode.is-public { color: var(--ok); background: color-mix(in srgb, var(--ok) 20%, var(--panel)); }

/* Row heads (sticky left) */
.ax-rowhead {
  position: sticky; left: 0; z-index: 1; height: var(--ax-row-h); padding: 0 8px 0 14px;
  border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.ax-table thead .ax-rowhead { z-index: 2; }
.ax-person { display: flex; align-items: center; gap: 10px; min-width: 0; }
.ax-person-text { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.ax-name {
  font-family: var(--font-display); font-size: 14px; font-weight: 500; color: var(--ink); text-decoration: none;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
a.ax-name:hover { text-decoration: underline; text-underline-offset: 2px; }
.ax-rel { display: block; font-size: 12px; color: var(--ink2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ax-off { display: inline-flex; align-items: center; gap: 2px; margin-right: 6px; color: var(--danger); font-style: normal; font-weight: 500; }
.ax-off .material-symbols-rounded { font-size: 13px; }
.ax-count {
  flex: none; display: inline-flex; align-items: center; gap: 3px; padding: 2px 7px; border-radius: 999px;
  background: var(--panel2); color: var(--ink2); font-family: var(--font-mono); font-size: 11px; font-variant-numeric: tabular-nums;
}
.ax-count.is-all { background: color-mix(in srgb, var(--ok) 14%, transparent); color: var(--ok); font-family: var(--font-display); font-weight: 500; }
.ax-count .material-symbols-rounded { font-size: 14px; }
.ax-pend {
  flex: none; display: inline-flex; align-items: center; gap: 2px; padding: 2px 7px 2px 5px; border-radius: 999px;
  background: var(--accent-fill); color: var(--on-accent); font-family: var(--font-mono); font-size: 11px; font-weight: 500;
}
.ax-pend .material-symbols-rounded { font-size: 13px; }
.ax-pend[hidden] { display: none; }
.ax-rowhead .icon-btn { flex: none; }
.ax-rowhead.is-hot { background: color-mix(in srgb, var(--accent) 6%, var(--panel)); }

/* Cells */
.ax-cell { height: var(--ax-row-h); text-align: center; vertical-align: middle; border-bottom: 1px solid var(--line); }
.ax-hit { display: grid; place-items: center; width: 100%; height: var(--ax-row-h); cursor: pointer; }
.ax-row:hover > th, .ax-row:hover > td:not(.is-staged) { background-color: color-mix(in srgb, var(--ink) 3%, var(--panel)); }
.ax-row.is-disabled .ax-person > .avatar, .ax-row.is-disabled .ax-name { opacity: .6; }
.ax-row.is-disabled .ax-cell .ax-cb { opacity: .7; }

/* A public app is open to everyone regardless: its column is hatched (and its
   head carries the green globe), so a grant there reads as "waiting". */
.ax-cell[data-mode="public"] {
  background-image: repeating-linear-gradient(135deg, transparent 0 7px, color-mix(in srgb, var(--ok) 9%, transparent) 7px 9px);
}

/* The checkbox: a 22 px box, check drawn in CSS (no icon font needed). */
.ax-cb {
  appearance: none; -webkit-appearance: none; margin: 0; display: grid; place-items: center; cursor: pointer;
  width: 22px; height: 22px; border-radius: 7px; border: 1.5px solid var(--line-strong); background: var(--panel);
  transition: background var(--dur), border-color var(--dur), box-shadow var(--dur);
}
.ax-cb::after {
  content: ""; width: 10px; height: 5px; margin-top: -3px;
  border-left: 2.5px solid var(--on-accent); border-bottom: 2.5px solid var(--on-accent);
  transform: rotate(-45deg) scale(0); transition: transform var(--dur) var(--ease-out);
}
.ax-cb:checked { background: var(--accent-fill); border-color: var(--accent-fill); }
.ax-cb:checked::after { transform: rotate(-45deg) scale(1); }
.ax-hit:hover .ax-cb:not(:checked) { border-color: var(--accent); }
.ax-cb:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Staged (changed, not saved): tinted cell, accent ring, and a corner mark
   with + or − — so the state is never carried by colour alone. */
.ax-cell.is-staged { background-color: var(--accent-tint-strong); }
.ax-cell.is-staged .ax-cb { box-shadow: 0 0 0 2px var(--panel), 0 0 0 4px var(--accent); }
.ax-cell.is-staged .ax-hit { position: relative; }
.ax-cell.is-staged .ax-hit::after {
  position: absolute; top: 4px; right: 4px; display: grid; place-items: center; width: 14px; height: 14px; border-radius: 50%;
  background: var(--accent-fill); color: var(--on-accent); font-family: var(--font-mono); font-size: 11px; font-weight: 700; line-height: 1;
}
.ax-cell.is-grant .ax-hit::after { content: "+"; }
.ax-cell.is-revoke .ax-hit::after { content: "−"; }
.ax-row.is-bad > .ax-rowhead { box-shadow: inset 4px 0 0 var(--danger); }
.ax-row.is-bad > td { background-color: color-mix(in srgb, var(--danger) 9%, var(--panel)); }

/* "New users" — part of the sticky head; its switches save at once. */
.ax-new-row > th, .ax-new-row > td { background: color-mix(in srgb, var(--accent) 7%, var(--panel)); border-bottom: 2px solid var(--line-strong); }
.ax-new-ic {
  flex: none; display: grid; place-items: center; width: 30px; height: 30px; border-radius: 10px;
  background: var(--accent-fill); color: var(--on-accent);
}
.ax-new-ic .material-symbols-rounded { font-size: 18px; }
.ax-table .switch { width: 32px; height: 20px; }
.ax-table .switch::before { top: 3px; left: 3px; width: 14px; height: 14px; }
.ax-table .switch:checked::before { transform: translateX(12px); }
.ax-table .switch:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.ax-new.is-busy .switch { opacity: .6; cursor: progress; }
.ax-new-na { padding: 0 16px; font-size: 13px; color: var(--ink2); }
.ax-new-na > span { display: inline-flex; align-items: center; gap: 6px; position: sticky; left: calc(var(--ax-head-w) + 16px); }
.ax-new-na .material-symbols-rounded { font-size: 17px; }

/* The owner: one merged cell. */
.ax-owner-row > th, .ax-owner-row > td { border-bottom: 1px solid var(--line); }
.ax-owner-cell {
  height: var(--ax-row-h); padding: 0 16px; vertical-align: middle; color: var(--ink2); font-size: 13px;
  background-image: repeating-linear-gradient(90deg, transparent 0 calc(var(--ax-col-w) - 1px), var(--line) calc(var(--ax-col-w) - 1px) var(--ax-col-w));
  background-color: color-mix(in srgb, var(--ok) 6%, var(--panel));
}
.ax-owner-note {
  position: sticky; left: calc(var(--ax-head-w) + 16px); display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 12px 4px 8px; border-radius: 999px; background: var(--panel); box-shadow: var(--e1); white-space: nowrap;
}
.ax-owner-note .material-symbols-rounded { font-size: 18px; color: var(--ok); }
.ax-owner-note strong { color: var(--ink); font-weight: 500; }

.ax-none { padding: 18px 16px; }
.ax-none .empty-state { position: sticky; left: 16px; max-width: min(560px, calc(100vw - 80px)); margin: 0; text-align: left; align-items: flex-start; }

/* While a save is in flight the grid is read-only. */
.ax-saving .ax-scroll, .ax-saving .ax-list { pointer-events: none; }
.ax-saving .ax-cell, .ax-saving .ax-tile { opacity: .75; }

/* --------------------------------------------------------------- save bar */
.ax-bar {
  position: sticky; bottom: calc(14px + var(--safe-b)); z-index: 20;
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px 14px;
  width: fit-content; max-width: 100%; margin: 16px auto 0; padding: 10px 10px 10px 16px;
  border-radius: 18px; background: var(--ink); color: var(--bg); box-shadow: var(--e3);
  animation: axBarIn .22s var(--ease-out);
}
@keyframes axBarIn { from { opacity: 0; transform: translateY(12px); } }
.ax-bar[hidden] { display: none; }
.ax-bar-ic { display: grid; place-items: center; width: 34px; height: 34px; border-radius: 11px; background: color-mix(in srgb, var(--bg) 14%, transparent); }
.ax-bar-ic .material-symbols-rounded { font-size: 20px; }
.ax-bar-text { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.ax-bar-n { font-family: var(--font-display); font-size: 15px; font-weight: 500; }
.ax-bar-sub { font-size: 12.5px; opacity: .78; }
.ax-bar-err { max-width: 460px; padding: 6px 10px; border-radius: 10px; background: var(--danger); color: var(--on-danger); font-size: 13px; line-height: 1.35; }
.ax-bar-err[hidden] { display: none; }
.ax-bar-actions { display: flex; align-items: center; gap: 6px; margin-left: auto; }
.ax-bar .ax-bar-discard { color: inherit; }
.ax-bar .ax-bar-discard:hover:not(:disabled) { background: color-mix(in srgb, var(--bg) 14%, transparent); }
.ax-bar .btn-filled:focus-visible, .ax-bar .ax-bar-discard:focus-visible { outline: 2px solid var(--bg); outline-offset: 2px; }

/* --------------------------------------------------------------- skeleton */
.ax-skel { display: grid; gap: 10px; padding: 18px; background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); }
.ax-skel-row { display: flex; align-items: center; gap: 12px; }
.ax-skel-row .ax-skel-cells { flex: 1; height: 22px; border-radius: 7px; }

/* ------------------------------------------------- phone: the accordion list */
.ax-list { display: grid; gap: 10px; }
.ax-acc { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.ax-acc[open] { box-shadow: var(--e1); }
.ax-acc-sum { display: flex; align-items: center; gap: 12px; min-height: 64px; padding: 10px 14px; cursor: pointer; list-style: none; }
.ax-acc-sum::-webkit-details-marker { display: none; }
.ax-acc-sum:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: var(--radius); }
.ax-chev { flex: none; color: var(--ink2); transition: transform var(--dur); }
.ax-acc[open] > .ax-acc-sum .ax-chev { transform: rotate(180deg); }
.ax-acc-new { background: color-mix(in srgb, var(--accent) 6%, var(--panel)); }
.ax-acc-owner .ax-acc-sum { cursor: default; }
.ax-acc.is-staged { border-color: var(--accent); box-shadow: inset 3px 0 0 var(--accent); }
.ax-acc.is-bad { border-color: var(--danger); box-shadow: inset 3px 0 0 var(--danger); }
.ax-acc.is-disabled .ax-acc-sum > .avatar { opacity: .6; }
.ax-acc-empty { padding: 8px; }
.ax-acc-body { display: grid; gap: 14px; padding: 4px 14px 16px; border-top: 1px solid var(--line); padding-top: 14px; }
.ax-acc-tools { display: flex; flex-wrap: wrap; gap: 6px; }
.ax-acc-hint, .ax-acc-na { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--ink2); }
.ax-acc-hint .material-symbols-rounded, .ax-acc-na .material-symbols-rounded { font-size: 17px; }
.ax-agroup { display: grid; gap: 8px; }
.ax-agroup-head { font-family: var(--font-display); font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink2); }
.ax-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(144px, 1fr)); gap: 8px; }
.ax-tile { min-height: 54px; }
/* span.… beats core's ".chk > span:not(…):not(…)" (nowrap + ellipsis). */
.ax-list .ax-tile > span.ax-tile-text, .ax-defrow .ax-tile-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; white-space: normal; overflow: visible; }
.ax-tile-name {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: break-word;
  font-family: var(--font-display); font-weight: 500; font-size: 13px; line-height: 1.2;
}
.ax-list .ax-tile { gap: 8px; padding: 8px 10px; }
/* core's ".chk .material-symbols-rounded" greys and shrinks every glyph in a
   tile, including the one on the app's colour tile. */
.ax-list .ax-tile .app-icon .material-symbols-rounded { font-size: calc(var(--size) * .56); color: #fff; }
.ax-tile-sub { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; font-size: 11px; color: var(--ink2); line-height: 1.3; }
.ax-tile-sub .tag { font-size: 9.5px; padding: 1px 5px; }
.ax-tile-sub .tag .material-symbols-rounded { font-size: 12px; }
.ax-tile[data-mode="public"] {
  background-image: repeating-linear-gradient(135deg, transparent 0 7px, color-mix(in srgb, var(--ok) 8%, transparent) 7px 9px);
}
.ax-list .ax-tile.is-staged { border-style: dashed; border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); position: relative; }
.ax-list .ax-tile.is-staged::after {
  position: absolute; top: -7px; right: -7px; display: grid; place-items: center; width: 18px; height: 18px; border-radius: 50%;
  background: var(--accent-fill); color: var(--on-accent); font-family: var(--font-mono); font-size: 12px; font-weight: 700; line-height: 1;
}
.ax-list .ax-tile.is-grant::after { content: "+"; }
.ax-list .ax-tile.is-revoke::after { content: "−"; }
.ax-deflist { display: grid; gap: 2px; }
.ax-defrow { display: flex; align-items: center; gap: 12px; min-height: 48px; padding: 4px 2px; cursor: pointer; }
.ax-defrow + .ax-defrow { border-top: 1px solid var(--line); }
.ax-defrow.is-busy .switch { opacity: .6; }
.ax-defrow:has(.switch:disabled) { cursor: not-allowed; }

@media (max-width: 900px) {
  .ax-dis { margin-left: 0; }
}
@media (max-width: 699.98px) {
  .ax-search { max-width: none; flex-basis: 100%; }
  .ax-filters { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin: 0 -16px; padding: 2px 16px; max-width: calc(100% + 32px); }
  .ax-filters::-webkit-scrollbar { display: none; }
  .ax-filter { flex: none; }
  .ax-meta { margin-bottom: 10px; }
  .ax-bar { width: auto; margin: 14px 0 0; bottom: calc(10px + var(--safe-b)); padding: 10px 10px 10px 12px; }
  .ax-bar-ic { display: none; }
  .ax-bar-err { max-width: none; flex-basis: 100%; order: 3; }
}
