/* ==========================================================================
   ShareFam — family-admin.css
   S04c administration surface: households, roles, temporary access, guardian
   authorities and the capability preview.

   DEV_GUIDE constraints this file is written against:

   #1  ZERO px. Every length below is rem (or a unitless ratio / %/vh/dvh).
       0.0625rem is the hairline, 2.75rem the 44-unit touch target.
   #4  Modal sizing is inherited from `.sf-modal__dialog` in sharefam.css,
       which already sets `max-height: 85vh; max-height: 85dvh` with a
       scrolling body and fixed header/footer. Nothing here overrides it.
   #5  Mobile-first from 22.5rem (360 units): the base rules are the narrow
       layout; the only breakpoints ADD columns going up.
   #6  Touch targets are 2.75rem minimum — the row actions use full-size
       `.sf-btn`, not the dense `.sf-btn-sm`.
   #14 Motion: 0.15s-0.2s, one easing family (`var(--sf-ease)`), and nothing
       loops. `prefers-reduced-motion` removes the entrance transition
       outright; base.css already clamps every duration globally, and the
       block at the end of this file removes the transform as well so there
       is no movement at all, not merely a fast one.
   #31 The dual-mode contract: the `--app-header-offset` TOKEN below, plus the
       embedded-mode chrome rules. Standalone ADDS the offset; embedded adds
       nothing and hides the page's own header, because the SHARED_DASHBOARD
       shell owns the top chrome inside its iframe.
   ========================================================================== */

/* ---------- #31 dual-mode: the header-offset token ----------------------- */
/* Standalone clears ShareFam's fixed 3.75rem `.sf-app-header`; embedded
   clears nothing, because the page renders no header of its own (see
   page-mode.js and sharefam-app.js renderHeader's early return). Additive
   in both directions — never an inline `style="padding-top:…"` on <body>. */
:root {
  --app-header-offset: 3.75rem;
}

html.page-mode-embedded {
  --app-header-offset: 0rem;
}

html.page-mode-standalone body.sf-has-app-header {
  padding-top: var(--app-header-offset);
}

html.page-mode-embedded body.sf-has-app-header {
  padding-top: 0 !important;
}

/* The header host element still exists in the markup; embedded, it must not
   paint. This is a BEFORE-PAINT rule keyed on the class page-mode.js stamps
   synchronously in <head> — not a render-then-hide, which is the bug. */
html.page-mode-embedded .sf-app-header,
html.page-mode-embedded [data-dashboard-chrome] {
  display: none !important;
}

/* ---------- Page shell -------------------------------------------------- */
.sf-fa-alert {
  display: block;
}

.sf-fa-alert:empty {
  display: none;
}

/* ---------- Tabs -------------------------------------------------------- */
.sf-fa-tabs {
  margin-bottom: 0.25rem;
}

/* ---------- Section head (per-panel toolbar) ---------------------------- */
.sf-fa-section {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.sf-fa-section__heading {
  min-width: 0;
}

.sf-fa-section__title {
  font-family: var(--sf-font-display);
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--sf-text);
}

.sf-fa-section__hint {
  margin-top: 0.25rem;
  font-size: 0.875rem;
  color: var(--sf-text-muted);
  max-width: 44rem;
}

.sf-fa-section__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* ---------- Rows -------------------------------------------------------- */
.sf-fa-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* At the 22.5rem floor a row stacks; from 40rem it becomes a row with the
   actions trailing. Mobile-first: the stack is the base rule (#5). */
.sf-fa-list .sf-list-row {
  flex-wrap: wrap;
}

.sf-fa-row__from {
  color: var(--sf-text-muted);
  font-weight: 500;
}

.sf-fa-fact {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem;
  font-size: 0.8125rem;
}

.sf-fa-fact__label {
  color: var(--sf-text-faint);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.6875rem;
  font-weight: 700;
}

.sf-fa-fact__value {
  color: var(--sf-text-muted);
  overflow-wrap: anywhere;
}

/* Row actions.

   `.sf-list-row__trailing` is `flex-shrink: 0` in sharefam.css, and every
   `.sf-btn` is `white-space: nowrap`, so three full-size actions on one line
   pin the row to their combined width — which is wider than a 22.5rem screen
   and pushes the whole PAGE into a horizontal scroll (#5). Mobile-first fix:
   the actions take their own line under the content at the narrow end and
   only sit trailing once there is room for them. The buttons themselves keep
   the full 2.75rem target (#6) — they are given room, never shrunk. */
.sf-fa-list .sf-list-row__trailing {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  flex-basis: 100%;
  flex-shrink: 1;
  min-width: 0;
}

/* ---------- Household detail (memberships under a household) ------------ */
.sf-fa-subpanel {
  margin-top: 0.5rem;
  padding: 0.875rem;
  border: 0.0625rem solid var(--sf-border);
  border-radius: var(--sf-radius-sm);
  background: var(--sf-surface-2);
}

.sf-fa-subpanel__title {
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--sf-text);
  margin-bottom: 0.5rem;
}

/* ---------- Capability preview / explanation ---------------------------- */
.sf-fa-preview {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 1rem;
  border: 0.0625rem solid var(--sf-border);
  border-radius: var(--sf-radius-sm);
  background: var(--sf-surface-2);
}

.sf-fa-preview--error {
  border-color: var(--sf-border-strong);
}

.sf-fa-preview__summary {
  font-size: 1rem;
  font-weight: 600;
  color: var(--sf-text);
  line-height: 1.5;
}

.sf-fa-preview__note {
  font-size: 0.875rem;
  color: var(--sf-text-muted);
  line-height: 1.55;
}

.sf-fa-preview__ceiling,
.sf-fa-preview__expiry {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  font-size: 0.875rem;
  color: var(--sf-text);
  line-height: 1.55;
}

.sf-fa-preview__ceiling i,
.sf-fa-preview__expiry i {
  margin-top: 0.1875rem;
  color: var(--sf-accent);
  flex-shrink: 0;
}

.sf-fa-preview-host {
  min-height: 6rem;
}

.sf-fa-confirm__lead {
  font-size: 0.9375rem;
  color: var(--sf-text);
  line-height: 1.55;
}

/* Gained / lost blocks. Colour is a reinforcement, never the only signal —
   each block is titled in words ("… will no longer be able to:"). */
.sf-fa-change {
  padding: 0.75rem;
  border-radius: var(--sf-radius-sm);
  border-left: 0.1875rem solid var(--sf-border-strong);
  background: var(--sf-surface);
}

.sf-fa-change--gained {
  border-left-color: var(--sf-accent);
}

.sf-fa-change--lost {
  border-left-color: var(--sf-danger, var(--sf-border-strong));
}

.sf-fa-change__title {
  font-family: var(--sf-font-body);
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--sf-text);
  margin-bottom: 0.5rem;
}

.sf-fa-change__more {
  margin-top: 0.375rem;
  font-size: 0.8125rem;
  color: var(--sf-text-muted);
}

.sf-fa-cap-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.sf-fa-cap {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}

.sf-fa-cap__action {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--sf-text);
}

.sf-fa-cap__why {
  font-size: 0.8125rem;
  color: var(--sf-text-muted);
}

.sf-fa-cap__until {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--sf-accent);
}

/* ---------- Version conflict (409) -------------------------------------- */
.sf-fa-conflict {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.875rem 1rem;
  border: 0.0625rem solid var(--sf-border-strong);
  border-left-width: 0.1875rem;
  border-radius: var(--sf-radius-sm);
  background: var(--sf-surface-2);
}

.sf-fa-conflict__lead {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--sf-text);
  line-height: 1.5;
}

.sf-fa-conflict__detail,
.sf-fa-conflict__now {
  font-size: 0.875rem;
  color: var(--sf-text-muted);
  line-height: 1.5;
}

.sf-fa-conflict__action {
  display: flex;
  gap: 0.5rem;
}

/* ---------- Withheld roles (a decision, not an absence) ----------------- */
.sf-fa-withheld {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  margin-top: 0.75rem;
  font-size: 0.8125rem;
  color: var(--sf-text-muted);
}

.sf-fa-withheld__item {
  line-height: 1.5;
}

/* ---------- Undo toast action ------------------------------------------ */
.sf-fa-undo {
  margin-top: 0.5rem;
  align-self: flex-start;
}

/* The entrance movement, added only when motion is welcome. 0.2s, the same
   easing family as every other transition on the site (#14). */
.sf-fa-toast--enter {
  animation: sf-fa-toast-in 0.2s var(--sf-ease) both;
}

@keyframes sf-fa-toast-in {
  from {
    transform: translateY(0.5rem);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

/* ---------- Form grid inside the modals --------------------------------- */
.sf-fa-form-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}

.sf-fa-scope-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-height: 12rem;
  overflow-y: auto;
  padding: 0.5rem;
  border: 0.0625rem solid var(--sf-border);
  border-radius: var(--sf-radius-sm);
  background: var(--sf-surface-2);
}

.sf-fa-scope {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.75rem;
  font-size: 0.875rem;
  color: var(--sf-text);
}

.sf-fa-scope input {
  width: 1.125rem;
  height: 1.125rem;
  flex-shrink: 0;
}

/* ---------- Breakpoints — the only thing they do is ADD room (#5) ------- */
@media (min-width: 40rem) {
  .sf-fa-list .sf-list-row__trailing {
    flex-basis: auto;
  }
}

@media (min-width: 48rem) {
  .sf-fa-form-grid {
    grid-template-columns: 1fr 1fr;
  }

  .sf-fa-form-grid .sf-fa-form-grid__wide {
    grid-column: 1 / -1;
  }
}

/* ---------- Reduced motion (#14) ---------------------------------------- */
/* base.css already clamps every duration to ~0; this removes the movement
   itself, so the toast appears rather than arriving. Focus and status
   feedback are untouched — only decorative motion goes. */
@media (prefers-reduced-motion: reduce) {
  .sf-fa-toast--enter {
    animation: none;
  }
}
