/* ═══ Admin: Student Area (AdminStudentArea.vue) ═══
   The staff side of the students' portal: three tabs - the announcements
   board, the two editable copy blocks, and the portal ACCOUNTS list
   (src/components/admin/studentArea/StudentAccountsPanel.vue, `.sta-acc-*`).
   English LTR page inside the admin shell; the generic kit (.admin-table,
   .form-*, .btn, .modal, .toast, .course-filter-tab*) lives in admin.css -
   this file carries only what is specific to this page.

   It also styles ONE class used in AdminCourseCohorts.vue: the attendance
   tab's `.cohort-badge--self` badge (a mark the student reported themselves
   from the student area). It lives here rather than in admin-cohorts.css
   because it is part of this feature, and .cohort-badge in admin.css already
   supplies the shape - this rule only adds the colours. */

/* ── Page sections ──────────────────────────────────────────────────── */

.sta-section {
  margin-bottom: 2rem;
}

/* ── Tab strip ──────────────────────────────────────────────────────── */

/* `.course-filter-tabs` is inline-flex with no wrap of its own, so without
   this the tabs force a horizontal scrollbar at phone widths. Same call as
   .stg-tabs and .pay-tabs. */
.sta-tabs {
  margin-bottom: var(--space-md, 16px);
  flex-wrap: wrap;
  max-width: 100%;
}

/* One quiet sentence under a section title saying what the section is. */
.sta-hint {
  margin: 0.25rem 0 1rem;
  font-size: 0.85rem;
  color: #6b6c78;
}

/* ── Announcements table ────────────────────────────────────────────── */

/* A hidden announcement stays listed (that is the point of the toggle) but
   reads as retired at a glance. */
.sta-row--hidden td {
  opacity: 0.55;
}

/* Title cell: the title on top, the first lines of the body under it. */
.sta-cell-title {
  max-width: 380px;
}

.sta-body-preview {
  margin-top: 0.15rem;
  font-size: 0.8rem;
  color: #6b6c78;
  line-height: 1.35;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  white-space: pre-line;
}

.sta-cell-published {
  white-space: nowrap;
}

.sta-col-visible,
.sta-col-actions {
  white-space: nowrap;
}

/* The visibility toggle: a pill that states the CURRENT fact and flips it on
   press. Green = students see it, grey = they do not. */
.sta-visible-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.25rem 0.65rem;
  font-size: 0.78rem;
  font-weight: 600;
  border-radius: 999px;
  border: 1px solid transparent;
  cursor: pointer;
  background: transparent;
}

.sta-visible-toggle--on {
  background: #ecfdf5;
  border-color: #a7f3d0;
  color: #047857;
}

.sta-visible-toggle--off {
  background: #f3f4f6;
  border-color: #e5e7eb;
  color: #6b7280;
}

.sta-visible-toggle:disabled {
  cursor: default;
  opacity: 0.7;
}

/* ── Announcement modal ─────────────────────────────────────────────── */

.sta-modal-body {
  resize: vertical;
  min-height: 120px;
  font: inherit;
  line-height: 1.4;
}

/* Publish moment: a date input beside a time input, never one datetime-local
   (a datetime-local reports empty until every segment is filled, silently
   discarding a date typed without an hour). Mirrors .cohort-datetime. */
.sta-datetime {
  display: flex;
  gap: 0.5rem;
}

.sta-datetime .sta-dt-date {
  flex: 1 1 auto;
}

.sta-datetime .sta-dt-time {
  flex: 0 0 108px;
}

/* ── Content blocks ─────────────────────────────────────────────────── */

.sta-content-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
}

.sta-content-block {
  display: flex;
  flex-direction: column;
}

.sta-content-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
}

/* The saved / dirty statement. Quiet when everything is saved; amber the
   moment the draft differs from what students would currently read. */
.sta-content-status {
  font-size: 0.75rem;
  color: #6b6c78;
}

.sta-content-status--dirty {
  color: #b45309;
  font-weight: 600;
}

.sta-content-textarea {
  resize: vertical;
  min-height: 160px;
  font: inherit;
  line-height: 1.45;
}

.sta-content-actions {
  margin-top: 0.6rem;
  display: flex;
  justify-content: flex-end;
}

/* ═══ Accounts tab (StudentAccountsPanel.vue) ════════════════════════ */

/* The lede that says what the table is, and - just as important - what it is
   not. A person can owe money under an email that has no portal account, so
   this is never a debtors list. */
.sta-acc-lede {
  max-width: 74ch;
}

.sta-acc-segments {
  margin-bottom: var(--space-md, 16px);
  flex-wrap: wrap;
  max-width: 100%;
}

/* ── Toolbar and filters ────────────────────────────────────────────── */

.sta-acc-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

/* .form-input carries `direction: rtl; text-align: right` as a DIRECT
   declaration (admin.css), and a direct declaration beats the LTR the admin
   content region hands down - so every text field on an English admin screen
   renders right-aligned unless its page says otherwise. Scoped to this panel's
   own search box on purpose: the announcement title/body/audience fields on the
   sibling tabs have the same latent issue and are deliberately left alone, so
   that fix stays a visible change somebody chose to make. */
.sta-acc-search .form-input {
  direction: ltr;
  text-align: left;
}

.sta-acc-search input {
  width: 260px;
}

.sta-acc-facets {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  margin-bottom: 1rem;
}

.sta-acc-facet-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
}

.sta-acc-facet-label {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #8a93a3;
  margin-right: 0.15rem;
}

/* A filter pill printing its own FACET count: how many rows pressing it would
   show, computed with its own dimension dropped. Pressing an active pill
   releases it. */
.sta-acc-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.3rem 0.7rem;
  border: 1px solid #e3e8f0;
  border-radius: 999px;
  background: #fff;
  color: #4a5261;
  font-size: 0.78rem;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.sta-acc-pill:hover {
  border-color: #c9d4e4;
  background: #f7f9fc;
}

.sta-acc-pill.is-on {
  background: #eef5ff;
  border-color: #b6d3f7;
  color: #0b57a4;
}

.sta-acc-pill-count {
  font-size: 0.7rem;
  font-weight: 600;
  color: #8a93a3;
}

.sta-acc-pill.is-on .sta-acc-pill-count {
  color: #0b57a4;
}

/* The one filter that names a problem rather than a category. Locked-out rows
   are the support calls that have not happened yet, so its pill carries the
   same amber the row does. */
.sta-acc-pill--alarm.is-on {
  background: #fff5e8;
  border-color: #f3d1a0;
  color: #9a5b06;
}

.sta-acc-pill--alarm.is-on .sta-acc-pill-count {
  color: #9a5b06;
}

/* A quiet caveat above the table: the book is bigger than one scan, so the
   facet counts describe the part that was read. Stated rather than hidden - a
   partial count that looks total is how a screen lies quietly. */
.sta-acc-note {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin-bottom: 1rem;
  padding: 0.6rem 0.8rem;
  border: 1px solid #f3d1a0;
  border-radius: 8px;
  background: #fff8ef;
  color: #8a5b12;
  font-size: 0.8rem;
  line-height: 1.45;
}

/* A failed "reset and email", stated PERSISTENTLY. The reset already destroyed
   the student's working password, so the mail failing leaves a real person
   locked out right now - a 3.2-second toast that the next list refresh can
   overwrite is not a report of that. It stays until somebody dismisses it. */
.sta-acc-alert {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  margin-bottom: 1rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid #f0b8bf;
  border-radius: 8px;
  background: #fff5f6;
  color: #8c2029;
  font-size: 0.82rem;
  line-height: 1.5;
}

.sta-acc-alert-text {
  flex: 1 1 auto;
}

.sta-acc-alert-close {
  flex: 0 0 auto;
  background: none;
  border: none;
  color: #a8535c;
  cursor: pointer;
  font-size: 0.95rem;
  padding: 0.15rem 0.35rem;
  line-height: 1;
}

.sta-acc-alert-close:hover {
  color: #8c2029;
}

/* A failed REFRESH, marked for as long as the stale rows are on screen. The
   first load has an error panel of its own, because it has no rows to leave
   behind; a refresh leaves the previous read exactly where it was, and a toast
   gone in 3.2 seconds is not a report of that - staff go on working a list
   that quietly stopped updating. Amber rather than the alert's red: nothing is
   broken and nobody is locked out, the screen is simply older than it looks.
   Dismissible, and a new failure raises it again. */
.sta-acc-stale {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  margin-bottom: 1rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid #f0c98a;
  border-inline-start: 4px solid #dd971f;
  border-radius: 8px;
  background: #fff7ea;
  color: #85570f;
  font-size: 0.82rem;
  line-height: 1.5;
  box-shadow: 0 1px 3px rgba(0, 60, 130, 0.05);
}

.sta-acc-stale-text {
  flex: 1 1 auto;
}

.sta-acc-stale-actions {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 0.35rem;
}

.sta-acc-stale-close {
  background: none;
  border: none;
  color: #a67c34;
  cursor: pointer;
  font-size: 0.95rem;
  padding: 0.15rem 0.35rem;
  line-height: 1;
}

.sta-acc-stale-close:hover {
  color: #85570f;
}

/* ── One-time temporary password ────────────────────────────────────── */

/* Deliberately the same amber panel as the users screen's one-time credential
   box: it is the same promise - shown once, never stored - and staff should
   recognise it on sight. */
.sta-onetime {
  background: #fffbeb;
  border: 1px solid #f5d98b;
  border-radius: 8px;
  padding: 0.9rem 1rem;
  margin-bottom: 1.25rem;
}

.sta-onetime-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9rem;
  color: #1a1a2e;
}

.sta-onetime-head .fa-key {
  color: #b7791f;
}

.sta-onetime-close {
  margin-left: auto;
  background: none;
  border: none;
  color: #6b7280;
  cursor: pointer;
  font-size: 0.95rem;
  padding: 0.15rem 0.35rem;
  line-height: 1;
}

.sta-onetime-close:hover {
  color: #1a1a2e;
}

.sta-onetime-body {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0.65rem 0 0.4rem;
}

.sta-onetime-code {
  font-family: var(--font-mono, monospace);
  font-size: 1rem;
  background: #fff;
  border: 1px solid #e8d9a8;
  border-radius: 6px;
  padding: 0.45rem 0.7rem;
  color: #1a1a2e;
  user-select: all;
}

.sta-onetime-note {
  font-size: 0.78rem;
  color: #8a6d3b;
  line-height: 1.45;
  margin: 0;
}

/* The panel takes focus when it appears (it is shown once, and a reset pressed
   far down the table would otherwise reveal it off screen), so a keyboard
   reader gets a ring saying where they were just moved to. */
.sta-onetime:focus-visible {
  outline: 2px solid #b7791f;
  outline-offset: 2px;
}

/* Resetting a FROZEN account is allowed on purpose, but the password will not
   work until the freeze is lifted - said here, in the dialog, and in the toast,
   because this panel is what staff copy the value out of. */
.sta-onetime-frozen {
  display: flex;
  align-items: flex-start;
  gap: 0.4rem;
  margin: 0 0 0.4rem;
  font-size: 0.8rem;
  font-weight: 600;
  line-height: 1.45;
  color: #3730a3;
}

/* ── The table ──────────────────────────────────────────────────────── */

/* No declared column widths past the identity columns: a width the viewport
   cannot honour hands the remaining columns zero and stacks them on top of
   each other (the cohorts-list defect). The caps below are max-widths, which
   give way instead.

   The email column also carries a FLOOR, and it is the one column that needs
   one. The address is what a row IS here - it is what staff search by, read
   out on the phone and paste into the CRM - and the auto table layout was
   handing this column its leftovers: 130px at 1440, which broke every address
   in the middle of a token across two lines ("noa.levi0@g" / "mail.com").

   A floor, never a fixed width, and 15rem measured rather than guessed: the
   other seven columns need 871px between them at their narrowest, the content
   region is 1112px wide at 1440 with the sidebar out, and 240px is what is
   left. So the whole table still fits with nothing to pan at the width this
   screen is actually read at, and the column holds 24 monospace characters -
   an ordinary address - on one unbroken line. A longer one folds at its "@"
   (see the `<wbr>` note below) rather than mid-token. Where the table cannot
   fit at all it is its own `.adm-table-scroll` wrapper that pans, never the
   page. Re-measure if a column is ever added: the sum of the others, not the
   15, is the real constraint. */
.sta-acc-table .sta-acc-td-email {
  min-width: 15rem;
  max-width: 24rem;
}

.sta-acc-table .sta-acc-td-person {
  max-width: 240px;
}

/* `overflow-wrap: anywhere`, never `word-break: break-all`, and it is the LAST
   resort rather than the mechanism: the markup offers a break at the address's
   "@" (a `<wbr>`), so an address too long for the column folds into its local
   part and its "@domain" instead of being chopped wherever the line ran out.
   This catches what that cannot - a local part longer than the whole column.
   Pairing it with the floor above is also what keeps the column's width in one
   place: the floor says how much room the address gets, and this says the
   address may not demand more, so one student with a very long address cannot
   push the table wider than the screen. */
.sta-acc-email {
  font-family: var(--font-mono, monospace);
  font-size: 0.82rem;
  overflow-wrap: anywhere;
}

.sta-acc-person-link {
  color: var(--primary-color, #0071e3);
  text-decoration: none;
}

.sta-acc-person-link:hover {
  text-decoration: underline;
}

/* A quiet second line under a cell: the cohorts, the freeze authorship, the
   "temporary password not changed yet" note. */
.sta-acc-sub {
  display: block;
  margin-top: 0.15rem;
  font-size: 0.72rem;
  color: #6b6c78;
  line-height: 1.35;
}

.sta-acc-reason {
  font-style: italic;
}

.sta-acc-nomatch,
.sta-acc-nosale,
.sta-acc-never {
  color: #8a93a3;
  font-size: 0.8rem;
}

/* Money at 600, solid, never the brand gradient. `no sale` above is a word,
   not a figure, precisely so it can never be read as a zero balance. */
.sta-acc-due {
  font-weight: 600;
  color: #3d4350;
}

.sta-acc-due--owed {
  color: #191a23;
  font-weight: 700;
}

/* The FIGURE may not wrap; the header above it may. Scoped to the cell rather
   than the column for a measured reason: "Amount due" held on one line was
   asking 143px of the row's width where the word "Amount" needs 93px, and that
   50px is part of what the address column now uses to hold an address. */
td.sta-acc-col-due {
  white-space: nowrap;
}

/* The sortable-header kit pins `white-space: nowrap` on every sortable header
   (`.reg-th-sort`, admin.css), which is why scoping the rule above to the cell
   is not enough on its own. Released here for this one header: it wraps only
   when the table is actually short of room, and a two-line "Amount / due" is a
   cheaper thing to look at than an address broken in half. */
.sta-acc-table th.sta-acc-col-due {
  white-space: normal;
}

.sta-acc-col-actions {
  white-space: nowrap;
}

/* ── Access chips ───────────────────────────────────────────────────── */

/* The access cell's one group: the chip or chips, and under them the freeze
   detail that explains them. A plain block on the desktop table, where it
   changes nothing - the chips flow inline and the detail sits beneath, as
   before. It earns its keep in the card layout below 1024px, where the cell
   itself becomes a flex row. */
.sta-acc-access {
  display: block;
}

/* The freeze date and the reason are ONE thing: when it happened, who did it,
   and why. Kept together so the reason reads as belonging to the freeze. */
.sta-acc-freeze-meta {
  display: block;
}

.sta-acc-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: 0.75rem;
  font-weight: 600;
  white-space: nowrap;
}

.sta-acc-chip + .sta-acc-chip {
  margin-left: 0.3rem;
}

.sta-acc-chip--eligible {
  background: #ecfdf5;
  border-color: #a7f3d0;
  color: #047857;
}

/* The loudest thing on the screen, and deliberately so: this person signs in
   fine and sees an empty portal with no error and no way to repair it. It is
   the row about to generate a support call. */
.sta-acc-chip--locked_out {
  background: #fff1e0;
  border-color: #f0be7c;
  color: #8a4c00;
}

.sta-acc-chip--frozen {
  background: #eef2ff;
  border-color: #c7d2fe;
  color: #3730a3;
}

.sta-acc-chip--unknown {
  background: #f3f4f6;
  border-color: #e5e7eb;
  color: #6b7280;
}

/* A whole-row tint under the chip, so a scan down the table finds the two
   states that need a human before any cell is read. */
.sta-acc-row--locked td {
  background: #fffaf3;
}

.sta-acc-row--frozen td {
  background: #f7f8ff;
}

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

.sta-acc-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3rem;
}

/* The two reset doors stay LABELLED, never two glyphs side by side: the choice
   between them is who gets to see the password, and a tooltip is not where
   that decision belongs. */
.sta-acc-actions .btn {
  white-space: nowrap;
}

/* The written name of an icon action. On the desktop table the row is tight and
   the glyph has hover plus a `title`, so the label is hidden there and shown in
   the card layout below - see the breakpoint. It is not `display: none` on a
   whim: a hidden label would also leave the button unnamed for a screen reader,
   so the markup keeps the text and this rule only stops it PAINTING. */
.sta-acc-actions .btn-icon .sta-acc-action-label {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── Pagination ─────────────────────────────────────────────────────── */

.sta-acc-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  margin-top: 1rem;
}

.sta-acc-pagination-info {
  font-size: 0.8rem;
  color: #6b6c78;
}

/* ── Freeze modal ───────────────────────────────────────────────────── */

.sta-acc-freeze-points {
  margin: 0 0 1rem;
  padding-left: 1.1rem;
  font-size: 0.85rem;
  line-height: 1.5;
  color: #4a5261;
}

.sta-acc-freeze-points li {
  margin-bottom: 0.3rem;
}

.sta-acc-freeze-reason {
  direction: ltr;
  text-align: left;
  resize: vertical;
  min-height: 72px;
  font: inherit;
  line-height: 1.4;
}

/* ── Attendance "self" badge (AdminCourseCohorts.vue) ───────────────── */

/* Colours only - the pill shape comes from .cohort-badge in admin.css. Sits
   beside the Present/Absent toggle when the mark came from the student's own
   report rather than the roster tick. */
.cohort-badge--self {
  background: #fef3c7;
  color: #92400e;
}

/* ── Breakpoints ────────────────────────────────────────────────────── */

@media (max-width: 1024px) {
  /* Touch floors (admin mobile revamp): 44px targets and 16px input text
     below 1025px; an iOS input under 16px zooms the whole page on focus. */
  .sta-page .btn,
  .sta-page .btn-icon,
  .sta-page .sta-visible-toggle {
    min-height: 44px;
  }

  .sta-page .form-input,
  .sta-page .form-select,
  .sta-page .sta-content-textarea,
  .sta-page .sta-modal-body {
    font-size: 16px;
  }

  /* A filter pill is a control too, but 44px of height on a strip of nine of
     them eats the screen - they get the width instead and stay tappable. */
  .sta-page .sta-acc-pill {
    min-height: 34px;
    padding-inline: 0.8rem;
  }

  .sta-acc-search input {
    width: 100%;
  }

  .sta-acc-search {
    flex: 1 1 200px;
  }

  /* The stale-refresh banner's own two controls: the retry is a .btn and is
     already 44px by the rule above, and the dismiss is a bare glyph, so it is
     given the same floor here rather than being a 26px target on a phone. The
     banner wraps so neither is squeezed against the sentence. */
  .sta-acc-stale {
    flex-wrap: wrap;
  }

  .sta-acc-stale-actions {
    flex: 1 1 100%;
    justify-content: flex-end;
  }

  /* The other two dismiss glyphs need the same floor for the same reason, and
     the rule above does not reach them: neither is a .btn or a .btn-icon, and
     both sit on notices a phone reader is most likely to want gone - the
     warning that a reset mail never left, and the panel holding a temporary
     password that is shown once. At their own padding they measure about
     26x20px, which is half a touch target. */
  .sta-acc-stale-close,
  .sta-acc-alert-close,
  .sta-onetime-close {
    min-width: 44px;
    min-height: 44px;
  }

  /* ── Card layout for the account tables ───────────────────────────
     The breakpoint is 1024px, not 767px, for the reason every other card
     table in the panel uses it: with the admin sidebar taking its share, a
     1024px screen leaves roughly 760px of content and an eight-column row is
     already unreadable there. Opt-in through `.sta-cards` on the table, never
     a blanket `.sta-page .admin-table` rule - the announcements board is an
     .admin-table under the same page root and must keep its own layout. */

  /* The wrapper's job was to pan a too-wide table. A card list is never too
     wide, and a leftover scroller would clip the cards' shadow. The shared
     `.adm-table-scroll` utility is frozen, so this rides alongside it on the
     same element rather than redefining it. */
  .sta-acc-scroll {
    overflow-x: visible;
  }

  /* The table stops painting a surface: the CARDS carry it now. admin.css
     turns .admin-table into a block scroller at this same breakpoint, which
     is what these three rules undo. */
  .sta-cards {
    display: block;
    min-width: 0;
    overflow: visible;
    background: transparent;
    border: none;
    box-shadow: none;
  }

  .sta-cards thead {
    display: none;
  }

  .sta-cards tbody {
    display: block;
    width: 100%;
  }

  /* One card per row. Taking the `<tr>` off `display: table` in the SAME
     breakpoint that flexes its cells is load-bearing: admin.css sets
     `thead, tbody, tr { display: table; table-layout: fixed }` here, and
     leaving the row a table while the cells become flex items merges every
     cell into one anonymous stacked cell that never scrolls. */
  .sta-cards tbody tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.2rem 0.7rem;
    width: 100%;
    margin-bottom: 0.8rem;
    padding: 0.85rem 1rem 0.7rem;
    background: #fff;
    border: 1px solid #e6ebf2;
    border-radius: 14px;
    box-shadow: 0 1px 3px rgba(0, 60, 130, 0.05);
  }

  .sta-cards tbody tr:last-child {
    margin-bottom: 0;
  }

  /* Cells are laid out by the card now, so they give up every table-era
     property: the padding, the rules between them, the max-widths and the
     nowrap that would overflow instead of folding. */
  .sta-cards tbody td {
    width: auto;
    max-width: none;
    padding: 0;
    border: none;
    white-space: normal;
    font-size: 0.875rem;
    color: #3d4350;
  }

  /* The shared sheet tints `td` on hover. In card mode the tint belongs to
     the card, or a row shows as a few tinted fragments floating on white -
     which is also what the locked-out and frozen row tints must become. */
  .sta-cards tbody tr:hover td,
  .sta-cards tbody tr.sta-acc-row--locked td,
  .sta-cards tbody tr.sta-acc-row--frozen td {
    background: transparent;
  }

  .sta-cards tbody tr.sta-acc-row--locked {
    background: #fffaf3;
    border-color: #f0be7c;
  }

  .sta-cards tbody tr.sta-acc-row--frozen {
    background: #f7f8ff;
    border-color: #c7d2fe;
  }

  /* Labelled rows: a full-width line with its heading in the gutter. Anything
     without a `data-label` is identity and leads the card unlabelled, because
     an email address and a person's name caption themselves. */
  .sta-cards td[data-label] {
    flex: 1 1 100%;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.15rem 0.6rem;
    padding: 0.4rem 0;
    border-top: 1px solid #f1f4f8;
  }

  .sta-cards td[data-label]:empty {
    display: none;
  }

  .sta-cards td[data-label]::before {
    content: attr(data-label);
    flex: 0 0 6.5rem;
    color: #8a93a3;
    font-weight: 600;
    font-size: 0.7rem;
    letter-spacing: 0.04em;
    line-height: 1.9;
    text-transform: uppercase;
  }

  /* The email column's desktop floor is a table-layout instruction and nothing
     else. A card is one column wide, so the floor has to go with the rest of
     the table-era sizing, or a 19rem minimum sits inside a 330px card on a
     phone and pushes the row wider than the screen. */
  .sta-cards .sta-acc-td-email,
  .sta-cards .sta-acc-td-person {
    flex: 1 1 100%;
    min-width: 0;
  }

  /* The access group stays ONE flex item beside the ACCESS label, so the chips
     and the freeze detail read as a block. Loose, they became three items of a
     flex row spread across the whole card, and the italic reason ended up at
     the far right, reading as an afterthought instead of as the explanation of
     the chip beside it. */
  .sta-cards td[data-label] .sta-acc-access {
    flex: 1 1 0;
    min-width: 0;
  }

  /* Under the chip it explains, not beside it. */
  .sta-cards .sta-acc-freeze-meta {
    width: 100%;
    margin-top: 0.1rem;
  }

  /* The actions close the card as one full-width row under a rule. */
  .sta-cards td.sta-acc-col-actions {
    flex: 1 1 100%;
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    justify-content: flex-end;
    margin-top: 0.2rem;
    padding-top: 0.5rem;
    border-top: 1px solid #f1f4f8;
    white-space: normal;
  }

  /* The chips fill the width of the card and read left to right. Right-aligned
     was fine for four bare glyphs; four labelled chips wrap, and a wrapped
     right-aligned row leaves a ragged left edge with no reading order. */
  .sta-cards td.sta-acc-col-actions .sta-acc-actions {
    flex: 1 1 100%;
    gap: 0.4rem;
    justify-content: flex-start;
  }

  /* On the desktop table these are bare glyphs that colour in on hover and
     name themselves in a `title`. A touchscreen has NEITHER - there is no
     hover and a `title` never appears - so on a card they take a visible chip
     AND their written name. Four unlabelled glyphs here are sign-out, freeze,
     unlink-Google and delete, which is not a guess anybody should have to
     make. */
  .sta-cards td.sta-acc-col-actions .btn-icon {
    flex: 0 0 auto;
    gap: 0.4rem;
    min-width: 0;
    padding-inline: 0.75rem;
    border: 1px solid #e3e8f0;
    border-radius: 10px;
    background: #fbfcfe;
    color: #5b6270;
  }

  .sta-cards td.sta-acc-col-actions .btn-icon .sta-acc-action-label {
    position: static;
    width: auto;
    height: auto;
    margin: 0;
    overflow: visible;
    clip-path: none;
    font-size: 0.8rem;
    font-weight: 600;
  }

  .sta-cards td.sta-acc-col-actions .btn-icon.danger {
    border-color: #f4d7db;
    background: #fff8f9;
    color: #b4232f;
  }
}

@media (max-width: 767px) {
  /* The two copy blocks stack on a phone. */
  .sta-content-grid {
    grid-template-columns: 1fr;
  }

  /* A native date picker and a native time picker each need the whole line. */
  .sta-datetime {
    flex-wrap: wrap;
  }

  .sta-datetime .sta-dt-date,
  .sta-datetime .sta-dt-time {
    flex: 1 1 100%;
  }
}
