/* Lobby Watch: shared components (design.md section 6). Class names are binding; views use them as-is and only
   adjust layout (grid, widths) through their own .v-* scope. */

/* ---- 6.1 Glyph -------------------------------------------------------------------------------------------------- */

.g {
  --gc: var(--text-3);
  display: inline-block;
  flex: none;
  width: 7px;
  height: 7px;
  margin-right: 6px;
  vertical-align: 0;
}
.g--live { --gc: var(--accent); }
.g--warn { --gc: var(--warn); }
.g--err  { --gc: var(--err); }
.g--mute { --gc: var(--text-3); }
.g--dim  { --gc: var(--text-2); }

.g--fill { background: var(--gc); }
.g--ring { box-shadow: inset 0 0 0 1.5px var(--gc); }
.g--dash {
  height: 1px;
  vertical-align: 3px;
  background: var(--gc);
}
.g--flush { margin-right: 0; }

/* ---- 6.6 Status: glyph + word ---------------------------------------------------------------------------------- */

.st {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  font-size: var(--fs-dense);
  line-height: var(--lh-dense);
  color: var(--text-2);
}
.st--live { color: var(--text); }
.st--warn { color: var(--warn); }
.st--err  { color: var(--err); }
.st-x {
  margin-left: 6px;
  color: var(--text-3);
}

/* Glyph + word inline, keeping the run on one line ("■ now", "■ Bed Wars 5 · 38m"). */
.st-line {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}

/* ---- 6.2 Buttons ------------------------------------------------------------------------------------------------ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  padding: 0 12px;
  border: 1px solid var(--line-control);
  border-radius: 2px;
  background-color: var(--raised);
  color: var(--text);
  font-size: var(--fs-ui);
  line-height: var(--lh-ui);
  font-weight: 500;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 80ms linear;
}
.btn:hover {
  background-color: var(--btn-hover);
}
.btn:active {
  background-color: var(--btn-active);
}
.btn:disabled,
.btn[aria-disabled="true"] {
  color: var(--text-3);
  border-color: var(--rule-strong);
  background-color: var(--raised);
  cursor: default;
}

.btn--sm {
  height: 28px;
}

.btn--primary {
  background-color: var(--text);
  color: var(--bg);
  border-color: transparent;
}
.btn--primary:hover,
.btn--primary:active {
  background-color: var(--primary-hover);
}
.btn--primary:disabled {
  background-color: var(--btn-active);
  color: var(--text-3);
  border-color: transparent;
}

.btn--danger,
.btn.is-confirm {
  background-color: var(--raised);
  color: var(--err);
  border-color: var(--err-rule);
}
.btn--danger:hover,
.btn.is-confirm:hover {
  background-color: var(--btn-hover);
}

.btn--block {
  display: flex;
  width: 100%;
}

/* Text button */
.tbtn {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 4px 0;
  border: 0;
  background: none;
  color: var(--text-2);
  font-size: var(--fs-ui);
  line-height: var(--lh-ui);
  font-weight: 400;
  text-align: left;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
.tbtn:hover {
  color: var(--text);
  text-decoration: underline 1px currentColor;
  text-underline-offset: 3px;
}
.tbtn:disabled {
  color: var(--text-3);
  text-decoration: none;
  cursor: default;
}
.tbtn.is-on {
  color: var(--text);
  font-weight: 500;
}
.tbtn.is-confirm {
  color: var(--err);
}
.tbl .tbtn {
  font-size: var(--fs-dense);
  line-height: var(--lh-dense);
}

/* Row of text actions */
.acts {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 16px;
}
.btns {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
}

/* Inline error line under an action (12/16) */
.err-line {
  font-size: var(--fs-meta);
  line-height: var(--lh-meta);
  color: var(--err);
}
.err-line:empty {
  display: none;
}
.ok-line {
  font-size: var(--fs-dense);
  line-height: var(--lh-dense);
  color: var(--text-2);
}

/* ---- 6.3 Inputs --------------------------------------------------------------------------------------------------- */

.in {
  display: block;
  height: 32px;
  width: 100%;
  min-width: 0;
  padding: 0 10px;
  border: 1px solid var(--line-control);
  border-radius: 2px;
  background: var(--sunken);
  color: var(--text);
  font-size: var(--fs-ui);
  line-height: var(--lh-ui);
}
.in::placeholder {
  color: var(--text-3);
  opacity: 1;
}
.in:focus,
.in:focus-visible {
  border-color: var(--accent);
  outline: none;
}
.in:disabled {
  color: var(--text-3);
  border-color: var(--rule-strong);
}
.in--sm {
  height: 28px;
}
.in--home {
  height: 40px;
  font-size: var(--fs-lede);
  line-height: var(--lh-lede);
}
.in--err,
.in--err:focus {
  border-color: var(--err);
}
select.in {
  appearance: auto;
  padding-right: 4px;
}
input[type="datetime-local"].in {
  width: auto;
}
.in::-webkit-calendar-picker-indicator {
  opacity: 0.7;
}

.lbl {
  display: block;
  margin-bottom: 4px;
  font-size: var(--fs-meta);
  line-height: var(--lh-meta);
  color: var(--text-3);
}

.field + .field {
  margin-top: 12px;
}
.field-err {
  margin-top: 4px;
  font-size: var(--fs-meta);
  line-height: var(--lh-meta);
  color: var(--err);
}
.field-err:empty {
  display: none;
}
.help {
  margin-top: 4px;
  font-size: var(--fs-meta);
  line-height: var(--lh-meta);
  color: var(--text-3);
}

input[type="checkbox"],
input[type="radio"] {
  width: 14px;
  height: 14px;
  margin: 0;
  accent-color: var(--accent);
  flex: none;
}
.chk {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 28px;
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
}
.chk:has(input:disabled) {
  color: var(--text-3);
  cursor: default;
}

/* <details> disclosure with a "›" that turns when open (the one allowed transform, not animated). */
.sum {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 32px;
  font-weight: 500;
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
  user-select: none;
}
.sum::before {
  content: "›";
  display: inline-block;
  width: 8px;
  color: var(--text-2);
}
details[open] > .sum::before {
  transform: rotate(90deg);
}

/* ---- 6.4 Focus: inputs use their border; everything else the global outline. ---------------------------------- */

.in:focus-visible {
  outline: none;
}

/* ---- 6.5 Tables ----------------------------------------------------------------------------------------------- */

.tbl {
  width: 100%;
  border-collapse: collapse;
}
.tbl--fixed {
  table-layout: fixed;
}
.tbl th {
  height: 28px;
  padding: 0 12px;
  border-bottom: 1px solid var(--rule-strong);
  font-size: var(--fs-meta);
  line-height: var(--lh-meta);
  font-weight: 500;
  color: var(--text-3);
  text-align: left;
  white-space: nowrap;
  vertical-align: middle;
}
.tbl td {
  height: 32px;
  padding: 0 12px;
  border-bottom: 1px solid var(--rule);
  font-size: var(--fs-dense);
  line-height: var(--lh-dense);
  color: var(--text-2);
  vertical-align: middle;
}
.tbl th:first-child,
.tbl td:first-child {
  padding-left: 0;
}
.tbl th:last-child,
.tbl td:last-child {
  padding-right: 0;
}
/* For tables whose rows highlight (hover, selection, arrival bar): keep text off the highlight's edges. */
.tbl--inset th:first-child,
.tbl--inset td:first-child {
  padding-left: 12px;
}
.tbl--inset th:last-child,
.tbl--inset td:last-child {
  padding-right: 12px;
}

.tbl td.c-key {
  color: var(--text);
  font-weight: 500;
}
.tbl .num {
  text-align: right;
}
.tbl td.mono {
  font-family: var(--mono);
  font-size: var(--fs-meta);
}
.clip {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tbl td.clip {
  max-width: 0;
}

.th-sort {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  white-space: nowrap;
  cursor: pointer;
}
.th-sort:hover,
.th-sort.is-sorted {
  color: var(--text);
}

.tbl tbody tr:hover {
  background: var(--raised);
}
.tbl tbody tr.is-link {
  cursor: pointer;
}
.tbl tbody tr.is-sel {
  background: var(--sel);
}
.tbl tbody tr.is-sel > td:first-child {
  box-shadow: inset 2px 0 0 var(--accent);
}
.tbl tbody tr.tbl-empty:hover,
.tbl tbody tr.edit-row:hover {
  background: none;
}
.tbl tr.tbl-empty > td {
  height: auto;
  padding: 8px 0;
  font-size: var(--fs-ui);
  line-height: var(--lh-ui);
  color: var(--text-2);
  border-bottom: 0;
}
.tbl tr.is-muted > td,
.tbl tr.is-muted > td.c-key {
  color: var(--text-3);
}

/* Links inside table cells are navigation-like. */
.tbl td a:not(.btn) {
  color: inherit;
  text-decoration: none;
}
.tbl td a:not(.btn):hover {
  text-decoration: underline 1px currentColor;
  text-underline-offset: 3px;
}

/* Inline edit row: a full-width cell on --raised. */
.tbl tr.edit-row > td {
  height: auto;
  padding: 16px;
  background: var(--raised);
  color: var(--text);
}

/* ---- Arrival bar (section 7) -------------------------------------------------------------------------------------- */

/* Only rows that receive arrivals (the home list, the roster) fade the bar; every other row change is instant, so the
   selection bar in search results never animates. */
.tbl-online tbody tr > td:first-child,
.arrive {
  transition: box-shadow 600ms linear;
}
.tbl tbody tr.is-new > td:first-child,
.arrive.is-new {
  box-shadow: inset 2px 0 0 var(--accent);
}
@media (prefers-reduced-motion: reduce) {
  .tbl-online tbody tr > td:first-child,
  .arrive {
    transition: none;
  }
}

/* ---- 6.7 Player name and head ------------------------------------------------------------------------------------- */

.pn {
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
a.pn:hover {
  text-decoration: underline 1px currentColor;
  text-underline-offset: 3px;
}
.tbl .pn {
  font-weight: 500;
}

.pn-row {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.headbox {
  position: relative;
  flex: none;
  display: block;
  width: 16px;
  height: 16px;
}
.headbox--64 {
  width: 66px;
  height: 66px;
  border: 1px solid var(--rule-strong);
}
.head {
  display: block;
  width: 100%;
  height: 100%;
  image-rendering: pixelated;
  border-radius: 0;
}
.head-ph {
  display: none;
  width: 100%;
  height: 100%;
  background: var(--raised);
}
.head--none {
  display: none;
}
.head--none + .head-ph {
  display: block;
}

/* ---- 6.8 Number strip ------------------------------------------------------------------------------------------------ */

.strip {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.strip-n {
  --sc: var(--rule-strong);
  display: inline-block;
  min-width: 28px;
  height: 28px;
  padding: 0 6px;
  border-bottom: 2px solid var(--sc);
  font-size: var(--fs-dense);
  line-height: 28px;
  font-weight: 500;
  color: var(--text-2);
  text-align: center;
  text-decoration: none;
}
.strip-n:hover {
  color: var(--text);
  background: var(--raised);
  text-decoration: none;
}
.strip-n.is-current {
  color: var(--text);
}
.strip-n--live { --sc: var(--accent); }
.strip-n--warn { --sc: var(--warn); }
.strip-n--err  { --sc: var(--err); }
.strip-n--mute { --sc: var(--rule-strong); }

/* ---- 6.9 Player search box -------------------------------------------------------------------------------------------- */

.ps {
  position: relative;
  min-width: 0;
}
.ps .in {
  padding-right: 28px;
}
.ps--home {
  width: 480px;
  max-width: 100%;
}
.ps-hint {
  position: absolute;
  top: 0;
  bottom: 0;
  right: 10px;
  display: flex;
  align-items: center;
  font-family: var(--mono);
  font-size: var(--fs-meta);
  color: var(--text-3);
  pointer-events: none;
}
.ps:focus-within .ps-hint,
.ps .in:not(:placeholder-shown) ~ .ps-hint {
  display: none;
}
/* Phone-only words inside table cells: a row block has no column headers, so a bare date or "never" gets the word
   its header carried ("first seen 23 Sep", "used 3h ago"). Desktop cells stay as the table draws them. */
.c-phone {
  display: none;
}

.dd {
  position: absolute;
  z-index: 20;
  top: calc(100% + 4px);
  left: 0;
  min-width: max(100%, 320px);
  max-width: calc(100vw - 2 * var(--gutter));
  padding: 4px 0;
  background: var(--raised);
  border: 1px solid var(--rule-strong);
  border-radius: 2px;
}
.dd-row {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 32px;
  padding: 0 12px;
  font-size: var(--fs-dense);
  line-height: var(--lh-dense);
  color: var(--text);
  text-decoration: none;
  cursor: pointer;
}
.dd-row:hover {
  background: var(--btn-hover);
  text-decoration: none;
}
.dd-row.is-sel {
  background: var(--sel);
  box-shadow: inset 2px 0 0 var(--accent);
}
.dd-row .pn {
  flex: 0 1 auto;
}
.dd-st {
  margin-left: auto;
  padding-left: 12px;
  display: inline-flex;
  align-items: center;
  font-size: var(--fs-meta);
  line-height: var(--lh-meta);
  color: var(--text-3);
  white-space: nowrap;
}
.dd-st--on {
  color: var(--text);
}
.dd-all {
  color: var(--text-2);
  border-top: 1px solid var(--rule);
}
.dd-empty {
  padding: 6px 12px;
  font-size: var(--fs-dense);
  line-height: var(--lh-dense);
  color: var(--text-2);
}

@media (max-width: 719.98px) {
  /* No "/" key to press on a phone: the hint would be a stray glyph in the input. */
  .ps-hint {
    display: none;
  }
  .c-phone {
    display: inline;
  }
  #topbar .dd {
    position: fixed;
    top: var(--topbar-h);
    left: 0;
    right: 0;
    min-width: 0;
    max-width: none;
    border-left: 0;
    border-right: 0;
    border-radius: 0;
  }
}

/* ---- 6.10 Text tabs ------------------------------------------------------------------------------------------------- */

.tabs {
  display: flex;
  align-items: stretch;
  gap: 16px;
  min-height: 28px;
}
.tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 0;
  border: 0;
  background: none;
  color: var(--text-2);
  font-size: var(--fs-ui);
  line-height: var(--lh-ui);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
.tab:hover {
  color: var(--text);
  text-decoration: none;
}
.tab.is-active {
  color: var(--text);
  font-weight: 500;
  box-shadow: inset 0 -2px 0 var(--accent);
}
.tab-n {
  font-size: var(--fs-meta);
  line-height: var(--lh-meta);
  font-weight: 400;
  color: var(--text-3);
}

/* ---- 6.17 Section header ---------------------------------------------------------------------------------------------- */

.sec {
  min-width: 0;
}
.sec + .sec {
  margin-top: 32px;
}
.sec-h {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--rule-strong);
}
.sec-t {
  font-size: var(--fs-ui);
  line-height: var(--lh-ui);
  font-weight: 600;
  color: var(--text);
}
.sec-n {
  font-size: var(--fs-meta);
  line-height: var(--lh-meta);
  color: var(--text-3);
}
/* One convention for counts everywhere: "Lobbies · 12", as 5a writes it, with 4 px either side of the dot. */
.sec-n:not(:empty) {
  margin-left: -4px;
}
.sec-n:not(:empty)::before {
  content: "·";
  margin-right: 4px;
}
.sec-a {
  margin-left: auto;
  display: flex;
  align-items: baseline;
  gap: 16px;
}
/* Full 28 px hit area in the header's 20 px line: the padding is taken back with a negative margin (6.2). */
.sec-a .tbtn {
  min-height: 28px;
  padding: 4px 0;
  margin: -4px 0;
}
.sec-b {
  padding-top: 8px;
}

/* ---- 6.18 State lines -------------------------------------------------------------------------------------------------- */

.state {
  display: block;
  padding: 8px 0;
}
.state--empty {
  font-size: var(--fs-ui);
  line-height: var(--lh-ui);
  color: var(--text-2);
}
.state--loading {
  font-size: var(--fs-dense);
  line-height: var(--lh-dense);
  color: var(--text-3);
  visibility: hidden;
}
.state--loading.is-shown {
  visibility: visible;
}
.state--error {
  font-size: var(--fs-ui);
  line-height: var(--lh-ui);
  color: var(--err);
}
.state--error .tbtn {
  margin-left: 8px;
  min-height: 0;
  padding: 0;
}
.state code,
.state .mono {
  font-family: var(--mono);
  font-size: var(--fs-meta);
}

/* ---- 6.11 Chat line --------------------------------------------------------------------------------------------------- */

/* A list of chat rows. --cl-ind is where the body column starts (for notes, day separators). */
.cl-list {
  --cl-pad: 24px;
  --cl-ind: calc(var(--cl-pad) + 64px + 8px + 12px + 8px);
  padding: 8px 0;
}
.cl-list--multi {
  --cl-ind: calc(var(--cl-pad) + 64px + 8px + 112px + 8px + 12px + 8px);
}

.cl {
  display: grid;
  grid-template-columns: 64px 12px minmax(0, 1fr);
  column-gap: 8px;
  padding: 2px var(--cl-pad, 24px);
  min-height: 24px;
  font: 400 14px/20px var(--sans);
}
.cl--multi {
  grid-template-columns: 64px 112px 12px minmax(0, 1fr);
}
.cl:hover {
  background: var(--well-hover);
}

.cl-t {
  font-family: var(--mono);
  font-size: var(--fs-meta);
  line-height: 20px;
  color: var(--text-3);
  text-decoration: none;
  white-space: nowrap;
}
.cl-t:hover {
  color: var(--text-2);
  text-decoration: underline 1px currentColor;
  text-underline-offset: 3px;
}

.cl-l {
  font-size: var(--fs-meta);
  line-height: 20px;
  color: var(--text-2);
  text-decoration: none;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cl-l:hover {
  color: var(--text);
  text-decoration: underline 1px currentColor;
  text-underline-offset: 3px;
}
.cl-l--inline {
  display: none;
}

.cl-k {
  font-family: var(--mono);
  font-size: var(--fs-meta);
  line-height: 20px;
  color: var(--text-3);
  text-align: center;
  user-select: none;
}

.cl-b {
  min-width: 0;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}
.cl--join .cl-b,
.cl--system .cl-b {
  font-size: var(--fs-dense);
}

/* Minecraft formatting runs */
.f-b { font-weight: 600; }
.f-i { font-style: italic; }
.f-u { text-decoration: underline; text-underline-offset: 2px; }
.f-s { text-decoration: line-through; }
.f-u.f-s { text-decoration-line: underline line-through; }
.f-k { text-decoration: underline dotted 1px; }

/* Speaker link keeps the run colours; each run underlines in its own colour on hover. */
.cl-name {
  color: inherit;
  text-decoration: none;
}
.cl-name:hover span {
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* Search / filter hit */
.hit {
  text-decoration: underline 2px;
  text-decoration-color: var(--text);
  text-underline-offset: 3px;
}

/* One-line rendered message (lobby tables "Last message") */
.mc-line {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cl-day {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 24px;
  padding: 0 var(--cl-pad, 24px) 0 var(--cl-ind, 116px);
  font-size: var(--fs-meta);
  line-height: var(--lh-meta);
  color: var(--text-3);
  white-space: nowrap;
}
.cl-day > i {
  flex: 1 1 auto;
  height: 1px;
  background: var(--rule);
}

.cl-note {
  padding: 4px var(--cl-pad, 24px) 4px var(--cl-ind, 116px);
  font-size: var(--fs-meta);
  line-height: var(--lh-meta);
  color: var(--text-3);
  overflow-wrap: anywhere;
}
.cl-note--warn {
  color: var(--warn);
}

.cl-mark {
  display: flex;
  align-items: center;
  height: 24px;
  padding: 0 var(--cl-pad, 24px);
}
.cl-mark > span {
  position: relative;
  margin-left: -8px;
  padding: 0 8px;
  background: var(--sunken);
  font-family: var(--mono);
  font-size: var(--fs-meta);
  line-height: var(--lh-meta);
  color: var(--text);
}
.cl-mark > i {
  flex: 1 1 auto;
  height: 1px;
  background: var(--accent);
}

@media (max-width: 719.98px) {
  .cl-list {
    --cl-pad: 16px;
  }
  .cl-list--multi {
    --cl-ind: calc(var(--cl-pad) + 56px + 8px + 12px + 8px);
  }
  .cl--multi {
    grid-template-columns: 56px 12px minmax(0, 1fr);
  }
  .cl--multi > .cl-l {
    display: none;
  }
  .cl--multi .cl-l--inline {
    display: inline;
    margin-right: 8px;
    overflow: visible;
  }
}

/* ---- 6.12 Chat well ------------------------------------------------------------------------------------------------------- */

.well {
  position: relative;
  background: var(--sunken);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.well--box {
  border: 1px solid var(--rule-strong);
  border-radius: 0;
  overflow: visible;
}
.well > .state {
  padding: 12px var(--gutter);
}

/* "14 new lines · Jump to latest ↓" pinned to the bottom of a paused well; "7 new above · Show" to the top of a list. */
.newbar {
  position: sticky;
  bottom: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 16px;
  height: 32px;
  padding: 0 24px;
  background: var(--raised);
  border-top: 2px solid var(--accent);
  font-size: var(--fs-dense);
  line-height: var(--lh-dense);
  font-weight: 500;
  color: var(--text);
  cursor: pointer;
}
.newbar .tbtn {
  margin-left: auto;
  font-size: var(--fs-dense);
}
.newbar--top {
  top: 0;
  bottom: auto;
  border-top: 0;
  border-bottom: 2px solid var(--accent);
}
@media (max-width: 719.98px) {
  .newbar {
    padding: 0 16px;
  }
}

/* ---- 6.13 Definition list --------------------------------------------------------------------------------------------------- */

.dl {
  display: grid;
  grid-template-columns: 128px minmax(0, 1fr);
  row-gap: 6px;
  column-gap: 16px;
  margin: 0;
}
.dl dt {
  font-size: var(--fs-meta);
  line-height: 20px;
  color: var(--text-3);
}
.dl dd {
  margin: 0;
  min-width: 0;
  font-size: var(--fs-dense);
  line-height: var(--lh-dense);
  color: var(--text);
  overflow-wrap: anywhere;
}
@media (max-width: 719.98px) {
  .dl {
    grid-template-columns: 112px minmax(0, 1fr);
  }
}

/* ---- 6.14 Activity strip ------------------------------------------------------------------------------------------------------ */

.act {
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr);
  row-gap: 4px;
}
.act-l {
  font-family: var(--mono);
  font-size: var(--fs-meta);
  line-height: 16px;
  color: var(--text-3);
  white-space: nowrap;
}
.act-t {
  position: relative;
  height: 16px;
  border-bottom: 1px solid var(--rule);
}
.act-g {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--rule);
}
.act-bar {
  position: absolute;
  top: 4px;
  height: 8px;
  min-width: 2px;
  background: var(--text-2);
}
.act-bar:hover {
  background: var(--text);
}
.act-bar--open {
  background: var(--accent);
}
.act-now {
  position: absolute;
  top: 0;
  bottom: -1px;
  width: 1px;
  background: var(--text-3);
}
.act-hours {
  position: relative;
  height: 16px;
  font-family: var(--mono);
  font-size: var(--fs-meta);
  line-height: 16px;
  color: var(--text-3);
}
.act-hours > span {
  position: absolute;
  top: 0;
  white-space: nowrap;
}
.act-hours > span.mid {
  margin-left: -1ch;
}
.act-cap {
  margin-top: 8px;
  font-size: var(--fs-meta);
  line-height: var(--lh-meta);
  color: var(--text-3);
}

/* ---- 6.15 Permission checkboxes ----------------------------------------------------------------------------------------------- */

.perms {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.perm {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  column-gap: 8px;
  min-height: 28px;
  padding: 4px 0;
  cursor: pointer;
}
.perm input {
  align-self: center;
}
.perm-id {
  font-family: var(--mono);
  font-size: var(--fs-dense);
  line-height: var(--lh-dense);
  color: var(--text);
}
.perm-d {
  font-size: var(--fs-meta);
  line-height: var(--lh-meta);
  color: var(--text-3);
}
.perm:has(input:disabled) {
  cursor: default;
}
.perm:has(input:disabled) .perm-id {
  color: var(--text-3);
}
.perms-note {
  font-size: var(--fs-meta);
  line-height: var(--lh-meta);
  color: var(--text-3);
}
/* Phones: every description takes its own line under the id, so the seven rows share one shape instead of wrapping
   or not by string length. The box stays in column 1 beside the id. */
@media (max-width: 719.98px) {
  .perm {
    display: grid;
    grid-template-columns: 14px minmax(0, 1fr);
    align-items: baseline;
  }
  .perm input {
    align-self: start;
    margin-top: 3px;
  }
  .perm > :not(input) {
    grid-column: 2;
  }
}

/* ---- One-off panels: shown-once key, MSA sign-in block --------------------------------------------------------------------------- */

.panel {
  padding: 16px;
  background: var(--raised);
  border: 1px solid var(--rule-strong);
}
.keyval {
  display: block;
  padding: 8px 10px;
  background: var(--sunken);
  font-family: var(--mono);
  font-size: var(--fs-dense);
  line-height: var(--lh-dense);
  font-weight: 500;
  color: var(--text);
  user-select: all;
  word-break: break-all;
}

.msa {
  padding: 16px 16px 16px 18px;
  background: var(--raised);
  box-shadow: inset 2px 0 0 var(--warn);
}
.msa + .msa {
  margin-top: 12px;
}
.msa-code {
  font-family: var(--mono);
  font-size: var(--fs-name);
  line-height: var(--lh-name);
  font-weight: 500;
  color: var(--text);
  letter-spacing: 0;
}

/* ---- Phones: tables become row blocks (6.5) --------------------------------------------------------------------------------------- */

@media (max-width: 719.98px) {
  .tbl,
  .tbl tbody {
    display: block;
    width: 100%;
  }
  .tbl thead {
    display: none;
  }
  /* No flex gap: the meta cells space themselves with their " · " separator, and the right-hand cell of line 1
     carries its own padding, so the rhythm is symmetric around every dot. */
  .tbl tbody tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: 0;
    padding: 10px 0;
    border-bottom: 1px solid var(--rule);
  }
  .tbl--inset tbody tr {
    padding: 10px 12px;
  }
  /* Line break between line 1 (key/end) and the meta line. */
  .tbl tbody tr::before {
    content: "";
    order: 3;
    flex-basis: 100%;
    height: 0;
  }
  .tbl tbody tr > td,
  .tbl--inset tbody tr > td:first-child,
  .tbl--inset tbody tr > td:last-child {
    display: block;
    height: auto;
    padding: 0;
    border: 0;
    min-width: 0;
    max-width: none;
    text-align: left;
  }
  /* Column classes that would otherwise beat the block reset: numbers align left in a block, clipped cells keep
     their width (the .c-sub line clips itself). */
  .tbl tbody tr > td.num {
    text-align: left;
  }
  .tbl tbody tr > td.clip {
    max-width: none;
  }
  /* The key cell's basis is 1 px, not 0: with 0 the 100 % line-break pseudo-element fits beside it on line 1 and
     the key never gets any width (a row with no .c-end cell renders nameless). With 1 px the break always wraps,
     and unlike `auto` a long name still truncates instead of pushing .c-end onto line 2. */
  .tbl tbody tr > td.c-key {
    order: 1;
    flex: 1 1 1px;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .tbl tbody tr > td.c-end {
    order: 2;
    flex: 0 0 auto;
    margin-left: auto;
    padding-left: 12px;
    text-align: right;
  }
  .tbl tbody tr > td.c-meta {
    order: 4;
    flex: 0 1 auto;
    font-size: var(--fs-meta);
    line-height: var(--lh-meta);
    color: var(--text-3);
    font-family: inherit;
  }
  /* An empty meta cell (a lone "—" placeholder) vanishes from the row block, and the " · " only comes after a meta
     cell that is actually shown, so line 2 never starts with a dash or a dot. */
  .tbl tbody tr > td.c-meta:has(> .is-empty:only-child),
  .tbl tbody tr > td.c-sub:has(> .is-empty:only-child) {
    display: none;
  }
  .tbl tbody tr > td.c-meta:where(:not(:has(> .is-empty:only-child))) ~ td.c-meta::before {
    content: " · ";
    white-space: pre;
  }
  .tbl tbody tr > td.c-meta.mono {
    font-family: var(--mono);
  }
  .tbl tbody tr > td.c-sub {
    order: 6;
    flex: 1 1 100%;
    margin-top: 2px;
    font-size: var(--fs-meta);
    line-height: var(--lh-meta);
    color: var(--text-3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .tbl tbody tr > td.c-act {
    order: 8;
    flex: 1 1 100%;
    margin-top: 4px;
  }
  .tbl tbody tr > td.c-act .acts,
  .tbl tbody tr > td.c-act .btns {
    justify-content: flex-start;
  }
  .tbl tbody tr > td.c-hide {
    display: none;
  }
  .tbl tbody tr > td[colspan] {
    order: 9;
    flex: 1 1 100%;
  }
  .tbl tbody tr.is-sel > td:first-child {
    box-shadow: none;
  }
  .tbl tbody tr.is-sel {
    box-shadow: inset 2px 0 0 var(--accent);
  }
  .tbl tbody tr.is-new > td:first-child {
    box-shadow: none;
  }
  .tbl tbody tr.is-new {
    box-shadow: inset 2px 0 0 var(--accent);
  }
  .tbl-online tbody tr {
    transition: box-shadow 600ms linear;
  }
  @media (prefers-reduced-motion: reduce) {
    .tbl-online tbody tr {
      transition: none;
    }
  }
  .tbl tr.tbl-empty,
  .tbl tr.edit-row {
    padding: 0;
    border-bottom: 0;
  }
  .tbl tr.tbl-empty::before,
  .tbl tr.edit-row::before {
    display: none;
  }
  .tbl tr.edit-row > td {
    padding: 16px !important;
  }
}
