/* ── Grouped list ────────────────────────────────────────────────────────────
 * A settings surface: sections of rows, each row carrying an identity, one line
 * of state, and at most one control. The pattern every iOS/macOS Settings pane
 * uses, and the answer to a portal page that had become a data table for
 * something nobody wants to read as data.
 *
 * Lives in components/ rather than a css/pages/ sheet for the same reason
 * .form-switch does (see forms.css): a shared control that renders unstyled on
 * a page which forgot to include its stylesheet is worse than no component.
 *
 * Markup:
 *   <section class="cs-group">
 *     <h2 class="cs-group__title">Authorities</h2>
 *     <div class="cs-group__rows">
 *       <div class="cs-row"> … </div>
 *     </div>
 *     <p class="cs-group__footer">What this group means.</p>
 *   </section>
 *
 * Build rows with the macros in templates/partials/_list_group.html rather than
 * by hand — they carry the link and separator structure this file assumes.
 */

.cs-group {
  margin: 0 0 var(--cs-space-8);
}

.cs-group__title {
  margin: 0 0 var(--cs-space-2);
  padding-left: var(--cs-space-4);
  font-size: 12px;
  font-weight: var(--cs-weight-semibold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cs-neutral-500);
}

/* One hairline and a soft ground — deliberately not .et-card's three-layer
   glass shadow, which is most of what makes the old surface feel loud.

   No `overflow: hidden` here, tempting as it is for the corners: it would clip
   an info bubble's tooltip, which is positioned above its own row. The first and
   last rows round their own corners instead (below), which keeps the hover
   background inside the shape without trapping anything. */
.cs-group__rows {
  background: var(--cs-glass-bg-deep);
  backdrop-filter: var(--cs-glass-blur-sm);
  -webkit-backdrop-filter: var(--cs-glass-blur-sm);
  border: 1px solid var(--cs-glass-border);
  border-radius: 14px;
}

.cs-group__footer {
  margin: var(--cs-space-3) 0 0;
  padding: 0 var(--cs-space-4);
  font-size: 13px;
  line-height: 1.5;
  color: var(--cs-neutral-500);
}
.cs-group__footer strong { color: var(--cs-neutral-600); font-weight: var(--cs-weight-semibold); }

/* ── Row ─────────────────────────────────────────────────────────────────── */

.cs-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--cs-space-3);
  min-height: 56px;
  padding: var(--cs-space-3) var(--cs-space-4);
}

/* display:flex outranks the UA's [hidden] rule, so a row hidden by the markup —
   a collapsed confirmation, a filtered-out entry — would stay on screen. */
.cs-row[hidden] { display: none; }

/* The group's corners, drawn by the rows rather than clipped by the group. */
.cs-row:first-child { border-radius: 13px 13px 0 0; }
.cs-row:last-child  { border-radius: 0 0 13px 13px; }
.cs-row:only-child  { border-radius: 13px; }

/* The separator is inset to where the text starts, not drawn wall to wall —
   the detail that does most of the work in making a list read as one object. */
.cs-row + .cs-row::before,
.cs-group__rows > form:not(:first-child) > .cs-row:first-child::before,
.cs-group__rows > form + .cs-row::before {
  content: '';
  position: absolute;
  top: 0;
  left: var(--cs-row-rule-inset, var(--cs-space-4));
  right: 0;
  height: 1px;
  background: rgba(0, 0, 0, 0.07);
}
.cs-group__rows--icons { --cs-row-rule-inset: 60px; }

/* A row whose action needs its own endpoint has to carry its own <form> — "Send
   a test delivery", "Retry failed jobs", "Manage billing". The form is not a box
   in the list, so it is taken out of the layout entirely and its row takes its
   place in the flow.
   `display: contents` does not change what :first-child matches, though: the row
   is still the first child *of its form*, so the corner rules below are keyed off
   the form's own position rather than the row's. Without this a "retry" row at
   the bottom of a group draws the rounded corners of a row at the top of one. */
.cs-group__rows > form { display: contents; }
.cs-group__rows > form > .cs-row { border-radius: 0; }
.cs-group__rows > form:first-child > .cs-row:first-child { border-radius: 13px 13px 0 0; }
.cs-group__rows > form:last-child > .cs-row:last-child { border-radius: 0 0 13px 13px; }
.cs-group__rows > form:only-child > .cs-row:only-child { border-radius: 13px; }

/* Two actions that are one decision — duplicate this tenant, or delete it — sat
   side by side rather than as two full-width rows a reader has to scan as if
   they were unrelated settings. The pair divides vertically, so the horizontal
   separators and the stacked corner radii above are turned off for it.

   A confirmation row inside the group still spans both columns: it explains the
   right-hand action and must not be squeezed into half a row. */
.cs-group__rows--split { display: grid; grid-template-columns: 1fr 1fr; }

.cs-group__rows--split > .cs-row::before,
.cs-group__rows--split > form + .cs-row::before { content: none; }

.cs-group__rows--split > .cs-row + .cs-row,
.cs-group__rows--split > form + .cs-row {
  border-left: 1px solid rgba(0, 0, 0, 0.07);
}

.cs-group__rows--split > form:first-child > .cs-row { border-radius: 13px 0 0 13px; }
.cs-group__rows--split > .cs-row:last-child { border-radius: 0 13px 13px 0; }

/* An expanded confirmation takes the bottom corners off the pair above it. */
.cs-group__rows--split:has(.cs-row--confirm:not([hidden])) > form:first-child > .cs-row {
  border-radius: 13px 0 0 0;
}
.cs-group__rows--split:has(.cs-row--confirm:not([hidden])) > .cs-row--destructive {
  border-radius: 0 13px 0 0;
}

.cs-group__rows--split > .cs-row--confirm {
  grid-column: 1 / -1;
  border-left: 0;
  border-top: 1px solid rgba(0, 0, 0, 0.07);
  border-radius: 0 0 13px 13px;
}

/* Centred is right for a lone "Delete tenant" row; beside its twin it has to
   line up with it instead. */
.cs-group__rows--split > .cs-row--destructive { justify-content: flex-start; }

.cs-row__icon {
  flex: none;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  background: var(--cs-blue-500);
  color: #fff;
}
.cs-row__icon svg { width: 17px; height: 17px; }
.cs-row__icon--amber { background: var(--cs-warning); }
.cs-row__icon--grey  { background: var(--cs-neutral-400); }

/* Identity tints for a settings section's tile. These say nothing about state —
   --amber and --grey above do — they only make a long column scannable. */
.cs-row__icon--blue   { background: var(--cs-tint-blue); }
.cs-row__icon--indigo { background: var(--cs-tint-indigo); }
.cs-row__icon--purple { background: var(--cs-tint-purple); }
.cs-row__icon--pink   { background: var(--cs-tint-pink); }
.cs-row__icon--teal   { background: var(--cs-tint-teal); }
.cs-row__icon--green  { background: var(--cs-tint-green); }
.cs-row__icon--cyan   { background: var(--cs-tint-cyan); }
.cs-row__icon--orange { background: var(--cs-tint-orange); }
.cs-row__icon--slate  { background: var(--cs-tint-slate); }
.cs-row__icon--red    { background: var(--cs-tint-red); }

.cs-row__body {
  flex: 1;
  min-width: 0;
}

.cs-row__title {
  font-size: 15px;
  font-weight: var(--cs-weight-medium);
  color: var(--cs-neutral-800);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cs-row__sub {
  margin-top: 1px;
  font-size: 13px;
  color: var(--cs-neutral-500);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cs-row__sub--alert { color: var(--cs-error); }

/* A value shown on the right of a static row: the Settings.app "current setting"
   position. Wraps and goes monospace for identity strings. */
.cs-row__value {
  flex: none;
  max-width: 62%;
  font-size: 13px;
  color: var(--cs-neutral-500);
  text-align: right;
  word-break: break-word;
}
.cs-row__value--mono {
  font-family: var(--cs-font-mono);
  font-size: 12px;
}

/* A value that can be edited in place. Borderless until it is focused, so a row
   of them reads as a list of facts rather than as a form. */
.cs-row__input {
  flex: none;
  width: 58%;
  padding: 5px var(--cs-space-2);
  font: inherit;
  font-size: 14px;
  color: var(--cs-neutral-800);
  text-align: right;
  background: none;
  border: 1px solid transparent;
  border-radius: 8px;
}
.cs-row__input:hover:not(:disabled) { border-color: var(--cs-glass-border); }
/* The alignment does NOT flip to the left on focus: the value jumping across the
   row is what a caret is for, and moving the text out from under the pointer the
   moment it is clicked loses the reader's place mid-edit. */
.cs-row__input:focus {
  outline: none;
  background: var(--cs-white-80, #fff);
  border-color: var(--cs-blue-500);
}
.cs-row__input:disabled { opacity: 0.6; }

/* A secret shown in a field: monospace so a rotated value can be checked
   character by character, and never wider than the row. */
.cs-row__input--secret {
  width: 44%;
  font-family: var(--cs-font-mono);
  font-size: 12px;
  letter-spacing: 0.04em;
}

/* A choice between a few named values. Same "borderless until you touch it"
   treatment as .cs-row__input, so a group of settings reads as a list of facts
   rather than as a form — the native arrow is what says it can be changed. */
.cs-row__select {
  flex: none;
  max-width: 58%;
  padding: 5px 26px 5px var(--cs-space-2);
  font: inherit;
  font-size: 14px;
  color: var(--cs-neutral-800);
  background: none;
  border: 1px solid transparent;
  border-radius: 8px;
  cursor: pointer;
  /* The control sits flush right, but its box is as wide as the *longest*
     option, so a short selection ("Personal" under "Government / Public
     Sector") read as left-aligned against every neighbouring .cs-row__input.
     With `appearance: none` the alignment is honoured, which is why the
     chevron is drawn here rather than left to the engine. */
  text-align: right;
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%2394a3b8' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 4.75L6 7.75l3-3'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 6px center;
  background-size: 12px;
}
/* The open list is a list, not a value: it reads left-aligned like every other
   menu, whatever the closed control does. */
.cs-row__select option { text-align: left; }
.cs-row__select:hover:not(:disabled) { border-color: var(--cs-glass-border); }
.cs-row__select:focus {
  outline: none;
  background-color: var(--cs-white-80, #fff);
  border-color: var(--cs-blue-500);
}
.cs-row__select:disabled { opacity: 0.6; cursor: default; }

/* A provider's monogram — the identity of the thing a row connects to, where
   .cs-row__icon carries the identity of a *section*. Coloured by the caller
   through --cs-mark-color, since the palette belongs to the provider. */
.cs-row__mark {
  flex: none;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  background: var(--cs-mark-color, var(--cs-neutral-500));
  color: #fff;
  font-size: 11px;
  font-weight: var(--cs-weight-bold);
  letter-spacing: 0.02em;
}

/* A row whose text is prose rather than a label: it wraps instead of
   ellipsising, and its controls sit at the top of the block. */
.cs-row--wrap { align-items: flex-start; }
.cs-row--wrap .cs-row__title,
.cs-row--wrap .cs-row__sub { white-space: normal; overflow: visible; }
.cs-row--wrap .cs-row__title { line-height: 1.35; }

/* The bubble that explains a row's setting, sat after its label. */
.cs-row__title .cs-info { margin-left: 5px; vertical-align: -3px; }

.cs-row__trail {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--cs-space-2);
}

/* A trail holding a field takes the row's free space instead of shrinking to
   its content. `flex: none` made the percentage widths below resolve against
   the trail's own max-content width — so a 58% field sat at the *left* of a
   box the size of its own text, leaving a gutter down the right of the row
   that no other row type had. With a definite width to resolve against, the
   percentages mean what they say and the control ends flush with the row. */
.cs-row__trail:has(.cs-row__input, .cs-row__select) {
  flex: 1 1 auto;
  min-width: 0;
}

.cs-row__chevron {
  flex: none;
  width: 16px;
  height: 16px;
  color: var(--cs-neutral-300);
}

/* The whole row is clickable, but only the title is a real link: a wrapping <a>
   around the row would swallow the trailing switch. The stretched pseudo-element
   is what gives the rest of the row the hit area without nesting controls. */
.cs-row__link::after {
  content: '';
  position: absolute;
  inset: 0;
}
.cs-row:has(.cs-row__link):hover { background: rgba(0, 0, 0, 0.022); }
.cs-row__link {
  color: inherit;
  text-decoration: none;
}
.cs-row__link:focus-visible::after {
  outline: 2px solid var(--cs-blue-500);
  outline-offset: -2px;
  border-radius: 6px;
}
/* The trailing controls sit above the stretched link so they stay clickable. */
.cs-row__trail { position: relative; z-index: 1; }

/* A row that is an action rather than a destination. */
.cs-row--button {
  width: 100%;
  background: none;
  border: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
  color: var(--cs-blue-600);
}
.cs-row--button:hover { background: rgba(0, 0, 0, 0.022); }
.cs-row--button .cs-row__title { color: inherit; font-weight: var(--cs-weight-medium); }

.cs-row--destructive { justify-content: center; color: var(--cs-error); }
.cs-row--destructive .cs-row__title { color: var(--cs-error); }

/* Centred is right for a bare "Delete" row — destructive_row's shape. One built
   like the list entries above it, with a __body (and often an icon), lines up
   with them instead. */
.cs-row--destructive:has(.cs-row__body) { justify-content: flex-start; }

/* A collapsed confirmation is display:none, so the row above it is the visible
   last one and has to draw the group's bottom corners itself. */
.cs-group__rows > .cs-row:has(+ .cs-row--confirm[hidden]) { border-radius: 0 0 13px 13px; }

/* The confirmation a destructive row expands into, in place of a native
   confirm() — which strips every word explaining what is about to break. */
.cs-row--confirm {
  gap: var(--cs-space-4);
  background: var(--cs-error-bg);
}
.cs-row--confirm .cs-row__sub { white-space: normal; color: var(--cs-neutral-700); }
.cs-row--confirm .cs-row__trail { gap: var(--cs-space-2); }

/* A value that copies itself when clicked (a thumbprint, a key). */
.cs-row__value[data-tc-copy] { cursor: pointer; }
.cs-row:has([data-tc-copy]):hover { background: rgba(0, 0, 0, 0.022); }
.cs-row__value.is-copied { color: var(--cs-success); }

/* ── Empty state ─────────────────────────────────────────────────────────── */

.cs-empty {
  padding: var(--cs-space-10) var(--cs-space-6);
  text-align: center;
}
.cs-empty__icon {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  margin: 0 auto var(--cs-space-4);
  border-radius: 14px;
  background: var(--cs-neutral-100);
  color: var(--cs-neutral-400);
}
.cs-empty__icon svg { width: 26px; height: 26px; }
.cs-empty__text {
  max-width: 40ch;
  margin: 0 auto var(--cs-space-5);
  font-size: 14px;
  line-height: 1.55;
  color: var(--cs-neutral-500);
}

/* The one field an empty state asks for, so a surface with nothing on it yet
   does not need a dialog to get its first row. */
.cs-empty__form {
  display: flex;
  gap: var(--cs-space-2);
  max-width: 34rem;
  margin: 0 auto;
}
.cs-empty__form .form-input { flex: 1; min-width: 0; }
@media (max-width: 560px) {
  .cs-empty__form { flex-direction: column; }
}

/* ── Page header for a grouped-list surface ──────────────────────────────── */

.cs-settings-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--cs-space-4);
  margin: 0 0 var(--cs-space-6);
}
.cs-settings-head__title {
  margin: 0;
  font-size: var(--cs-text-3xl);
  font-weight: var(--cs-weight-bold);
  letter-spacing: var(--cs-tracking-tight);
  color: var(--cs-neutral-900);
}
.cs-settings-head__sub {
  margin: var(--cs-space-1) 0 0;
  font-size: 14px;
  color: var(--cs-neutral-500);
}
.cs-settings {
  max-width: 720px;
  margin: 0 auto;
}

/* Push navigation: one step back up the stack, not a breadcrumb trail. The list
   page keeps its breadcrumb — it is the top of the stack and has nowhere up. */
.cs-back {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  margin: 0 0 var(--cs-space-4);
  font-size: 14px;
  font-weight: var(--cs-weight-medium);
  color: var(--cs-blue-600);
  text-decoration: none;
}
.cs-back:hover { color: var(--cs-blue-700, var(--cs-blue-600)); }
.cs-back svg { width: 16px; height: 16px; }

/* A write that the server refused, said next to what refused it. */
.cs-error-note {
  margin: 0 0 var(--cs-space-4);
  padding: var(--cs-space-3) var(--cs-space-4);
  font-size: 13px;
  color: var(--cs-error);
  background: var(--cs-error-bg);
  border-radius: 10px;
}

/* Something true about the account that the reader has to act on — a trial that
   has ended, an allowance grown past. Not an error: nothing was refused, so it
   is amber and it keeps its link. */
.cs-note {
  margin: 0 0 var(--cs-space-4);
  padding: var(--cs-space-3) var(--cs-space-4);
  font-size: 13px;
  line-height: 1.5;
  color: var(--cs-neutral-700);
  background: var(--cs-glass-bg-deep);
  border: 1px solid var(--cs-glass-border);
  border-radius: 10px;
}
.cs-note a { color: var(--cs-blue-600); }
.cs-note--warn {
  color: #92400e;
  background: #fffbeb;
  border-color: #fde68a;
}
.cs-note--warn a { color: #b45309; }

/* The Save for a pane that writes its record as a whole, sat under the group it
   belongs to rather than at the far bottom of the page. */
.cs-group__actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--cs-space-2);
  margin: var(--cs-space-3) 0 var(--cs-space-5);
  padding: 0 var(--cs-space-1);
}
.cs-group__actions--split { justify-content: space-between; }

@media (max-width: 560px) {
  .cs-row__value { max-width: 50%; }
  .cs-row__select { max-width: 50%; }
  .cs-row__input { width: 50%; }
  .cs-settings-head { align-items: flex-start; flex-direction: column; }

  /* Two half-width actions do not survive a phone: the pair stacks and gets its
     horizontal separator and stacked corners back. */
  .cs-group__rows--split { grid-template-columns: 1fr; }
  .cs-group__rows--split > .cs-row + .cs-row,
  .cs-group__rows--split > form + .cs-row { border-left: 0; }
  .cs-group__rows--split > form + .cs-row::before { content: ''; }
  .cs-group__rows--split > form:first-child > .cs-row,
  .cs-group__rows--split:has(.cs-row--confirm:not([hidden])) > form:first-child > .cs-row {
    border-radius: 13px 13px 0 0;
  }
  .cs-group__rows--split > .cs-row:last-child { border-radius: 0 0 13px 13px; }
  .cs-group__rows--split:has(.cs-row--confirm:not([hidden])) > .cs-row--destructive {
    border-radius: 0;
  }
}
