@import url('brandingPalette.css');

/* === UNIFIED USER ADMINISTRATION ============================================
 *
 * The People directory and the person detail screen: UserDirectoryView and
 * UserDetailView.
 *
 * IN /sharedAssets/ FOR THE SAME REASON userAdmin.js IS. The screen is mounted
 * in three docroots (secure, store, admin) from one set of class files, and
 * sharedAssets/sharedCSS.php globs every *.css in this directory into every
 * portal's <head> — so dropping this file here is the whole of its installation.
 * Three per-docroot copies would drift exactly the way the four copies of
 * loadUserAccess.d.php did.
 *
 * WHY THERE IS A STYLESHEET AT ALL rather than inline styles on the HTML these
 * views concatenate: the two views previously carried `style="..."` on nearly
 * every element, which meant a colour decision lived in a dozen PHP string
 * literals and could not be changed in one place. It also meant three class
 * names the views referenced -- cwh-btn-primary, cwh-btn-secondary and
 * cwh-portal-tab -- were never defined anywhere the screen actually loaded, so
 * every button and every filter tab rendered as unstyled browser chrome.
 *
 * Action buttons are NOT here -- they are the `.cwh-action*` family in
 * cwh-buttons.css, which explains why they avoid Bootstrap's `.btn`.
 * ========================================================================== */

/* ── Page frame ───────────────────────────────────────────────────────────────
 *
 * THE FRAME ITSELF IS NOT DEFINED HERE, AND THAT IS THE POINT. `.page-content`
 * belongs to each portal's own stylesheet and each sizes it differently -- 24px
 * top with 12px sides in secure, 24px with 28px sides in admin -- so the page
 * picks up its host's padding by wearing the host's class rather than by
 * restating a number that would then be wrong in two portals out of three.
 * UserAdminChrome is what puts the class on. Everything below styles only the
 * parts of the header this screen adds. */

.cwh-ua-page {
    font-family: var(--cwh-font-family);
}

/* SECURE'S HEADER SHAPE: a large heading with its supporting line, and the live
   count or status badges pushed to the right. Matches loadStoreList.v.php and
   the other newer head-office screens. */
.cwh-ua-head {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    align-items: flex-end;
    justify-content: space-between;
    margin-bottom: 1rem;
}

.cwh-ua-title {
    font-family: var(--cwh-font-family);
    font-weight: var(--cwh-font-bold);
    font-size: 2rem;
    color: var(--cwh-dark-blue);
    margin: 0;
}

/* ADMIN'S AND STORE'S HEADER SHAPE: everything rides inside `.page-title-box`
   next to an 18px `h4`, so these two rules only have to group the title, its
   aside and its supporting line -- the size and weight come from the portal's
   own `.font-size-18`, which is what keeps this page's heading the same size as
   every other heading in that portal.

   admin/assets/css/custom.css states the order it is protecting outright: "page
   title (18px) > card title (16px) > body text". A 2rem heading here inverted
   it, which is why the People page read as a different application. */
.cwh-ua-titlebar {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.cwh-ua-titleline {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

/* The status badges beside a person's name, in either header shape. */
.cwh-ua-badges {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

/* Sub-heading / supporting line beneath a title. */
.cwh-ua-sub {
    font-family: var(--cwh-font-family);
    color: var(--cwh-middle-blue);
    font-size: 13px;
    margin: 4px 0 0;
}

/* The "19 people" counter. Tabular figures so it does not jiggle as the
   directory filters down under the operator's cursor. */
.cwh-ua-count {
    font-family: var(--cwh-font-family);
    font-weight: var(--cwh-font-medium);
    color: var(--cwh-dark-blue);
    font-size: 14px;
    font-variant-numeric: tabular-nums;
}

/* IN ADMIN AND STORE THE SUPPORTING TEXT IS GREY, NOT BLUE, AND EVERYWHERE ON THE PAGE.
   Middle blue is the head-office house style -- loadStoreList.v.php and its siblings caption
   every page that way -- but those two portals use --cw-text-sec for everything secondary, and
   blue body text among their screens reads as a link that does nothing.

   Keyed off the frame class UserAdminChrome puts on the page rather than off individual header
   elements, so a caption inside a card follows the same rule as one under the heading. The
   fallback in the var() matters: --cw-text-sec is defined by the two portals that use this
   frame, and the shared token stands in anywhere else this page is ever mounted. */
.cwh-ua-frame--title .cwh-ua-sub {
    color: var(--cw-text-sec, var(--cwh-mid-grey));
    font-size: 12.5px;
}

/* The live count sits beside an 18px heading in this frame rather than opposite a 2rem one, so
   it steps down to match. */
.cwh-ua-frame--title .cwh-ua-count {
    color: var(--cw-text-sec, var(--cwh-mid-grey));
    font-size: 12.5px;
}

/* ── Portal filter tabs ──────────────────────────────────────────────────────
 *
 * NOTHING TO STYLE. These are Bootstrap's own `btn btn-sm btn-primary` /
 * `btn-outline-primary`, which is what the service master lists use for the
 * identical control, so they are painted by whichever portal the page is
 * mounted in -- the same argument as the directory table's header.
 *
 * `.cwh-portal-tab` survives as the JS HOOK ONLY. userAdmin.js selects
 * `#userDirectoryTabs .cwh-portal-tab` and reads `active` off it, and that
 * contract is deliberately independent of how the button is painted. The class
 * used to carry a bespoke pill of its own -- a second filter vocabulary on a
 * screen sitting beside pages that already had one. */

/* ── Search box ──────────────────────────────────────────────────────────────
 *
 * Colour and focus behaviour belong to `.cwh-search-wrap` / `input.cwh-search-input`
 * in cwh-form-controls.css, which owns them estate-wide. Only the GEOMETRY is
 * set here -- every other list page in the estate repeats that geometry as an
 * inline style, which is precisely the duplication this file exists to stop. */

.cwh-ua-search {
    position: relative;
}

.cwh-ua-search .cwh-search-icon {
    position: absolute;
    left: 16px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 18px;
    pointer-events: none;
}

.cwh-ua-search input.cwh-search-input {
    padding-left: 44px;
    border-radius: 24px;
}

/* The width the service master list and the store list both give it: wide, but
   capped and centred in its column rather than stretching to the page edge. */
.cwh-ua-search {
    max-width: 760px;
    margin: 0 auto;
}

/* THE TITLE COLUMN IS CAPPED SO THE SEARCH KEEPS ITS WIDTH. The heading row is an
   auto column for the title and a flexible one for the search, so a long caption
   under the title takes the width straight off the search box -- "Services" is one
   word and leaves the row looking quite different from "People" with a sentence
   beneath it. Capping lets the caption wrap to a second line instead, which is what
   keeps the two pages' rows the same shape. Only where the controls share the row;
   with no controls there is nothing to take width from. */
.cwh-ua-head-cell {
    max-width: 340px;
}

/* Panels toggled open/closed by userAdmin.js use the `hidden` attribute rather
   than an inline `display`, so the view carries no presentational attribute.
   Scoped to this screen so the !important cannot reach anything else. */
.cwh-ua-page [hidden] {
    display: none !important;
}

/* ── Card padding ────────────────────────────────────────────────────────────
 *
 * THE LAST LINE WAS SITTING 2px FROM THE CARD'S EDGE. sharedAssets/css/card.css
 * trims `.cwh-card .card-body` to `padding-bottom: 2px`, which suits a card
 * ending in a table or a button row -- the row's own margin supplies the gap.
 * Every card on this screen ends in TEXT instead: the note under the create
 * form, the caption under a locked email, the hint under a grant section. With
 * 16px above and 2px below, those read as squashed against the border.
 *
 * 24px, which is the value card.css itself uses when it restores this padding
 * for collapsable bodies -- "the tight 2px above is fine for static cards but
 * squashes table/empty-state content". The same sentence describes this screen.
 * 16px only matched the top and still read as tight under a full-width line of
 * small text, which has more visual weight at the bottom of a card than a
 * heading does at the top.
 *
 * Scoped to this page, not to `.cwh-card` estate-wide -- the trim is deliberate
 * everywhere else and undoing it globally would loosen every card in the
 * estate. admin/assets/css/custom.css restores 16px for its own portal for the
 * same reason; this is the page saying it needs a little more than that. */
.cwh-ua-page .card.cwh-card > .card-body {
    padding-bottom: 24px;
}

/* ── Directory table ─────────────────────────────────────────────────────── */

.cwh-ua-table {
    font-family: var(--cwh-font-family);
    width: 100%;
    margin-bottom: 0;
}

/* THE HEADER IS NOT STYLED HERE, DELIBERATELY. This table carries `.table`, and both portals
   that show it already own `.table thead th` completely -- secure paints a light-grey band with
   12px grey sentence-case labels, admin a white one with 12px grey uppercase labels, each with
   its own 2px rule beneath. Every other table in either portal looks like that.

   It used to override all of it with a light-blue band of 11.5px ExtraBold uppercase dark-blue
   text, which matched neither, and won on the cascade because sharedAssets is globbed into the
   <head> last. Removing the override is the whole fix: the directory now takes the host portal's
   table styling for free, and keeps taking it when that styling changes.

   `vertical-align` stays because the rows carry badges and a chevron next to plain text, and
   secure sets it while admin does not -- this is the one rule the content here genuinely needs
   rather than inherits. */
.cwh-ua-table tbody td {
    vertical-align: middle;
}

/* A whole row opens the person. The pointer plus the name underline on hover
   are what say so -- the row is not a link element, because navigation goes
   through loadUserDetail() so the SPA router can mark the route. */
.cwh-ua-row {
    cursor: pointer;
    transition: background 0.12s ease;
}

.cwh-ua-row:hover {
    background: rgba(0, 51, 126, 0.04);
}

.cwh-ua-row:hover .cwh-ua-name {
    text-decoration: underline;
}

/* Column widths. Attributes like `width="26%"` and inline styles on every <th>
   were how this table sized itself before; naming the columns keeps the view's
   HTML free of presentation.

   The email column is deliberately left UNSIZED so it absorbs the remainder: percentage widths
   that sum to exactly 100% round up against the table's own borders and overflow by a pixel or
   two, which is enough to raise a horizontal scrollbar on .table-responsive. */
.cwh-ua-col-name   { width: 24%; }
.cwh-ua-col-portal { width: 24%; }
.cwh-ua-col-status { width: 11%; }
.cwh-ua-col-signin { width: 13%; }
.cwh-ua-col-go     { width: 2%; }

/* Trailing chevron. The estate's list tables normally end in an Action column
   with a "View" button; this directory opens on the whole row instead (the
   navigation has to go through loadUserDetail() so the SPA router can mark the
   route, which a plain link cannot do). The chevron is what tells the operator
   the row is a destination, since there is no button to say it. */
.cwh-ua-go {
    text-align: right;
    color: var(--cwh-light-grey);
    font-size: 1.15rem;
    line-height: 1;
    transition: color 0.12s ease, transform 0.12s ease;
}

.cwh-ua-row:hover .cwh-ua-go {
    color: var(--cwh-dark-blue);
    transform: translateX(2px);
}

.cwh-ua-name {
    font-weight: var(--cwh-font-medium);
    color: var(--cwh-dark-blue);
}

/* An identity with no name recorded — said, but said quietly. */
.cwh-ua-name--unknown {
    font-weight: var(--cwh-font-medium);
    color: var(--cwh-mid-grey);
    font-style: italic;
}

.cwh-ua-email {
    color: var(--cwh-mid-grey);
    font-size: 13px;
    word-break: break-word;
}

/* ── Portal chips ────────────────────────────────────────────────────────────
 *
 * Category chips, not status pills: they name WHICH portals a person holds, so
 * they use the brand accent rather than the badge-soft status palette. A
 * suspended membership is shown outlined rather than dropped — see
 * UserDirectoryView::_renderPortalBadge for why hiding it would be a lie. */

.cwh-ua-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

.cwh-ua-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-family: var(--cwh-font-family);
    font-weight: var(--cwh-font-medium);
    font-size: 11.5px;
    line-height: 1.4;
    padding: 4px 10px;
    border-radius: 20px;
    background: var(--cwh-light-blue);
    border: 1px solid var(--cwh-light-blue);
    color: var(--cwh-dark-blue);
    white-space: nowrap;
}

.cwh-ua-chip--suspended {
    background: transparent;
    border-color: var(--cwh-light-grey);
    color: var(--cwh-mid-grey);
}

/* The " · full" / " · group_restricted" tail on a `secure` chip. */
.cwh-ua-chip-scope {
    opacity: 0.75;
}

/* "none" where the caller administers no portal this person holds. */
.cwh-ua-none {
    color: var(--cwh-mid-grey);
    font-size: 13px;
    font-style: italic;
}

/* ── Status pills ────────────────────────────────────────────────────────────
 *
 * These reuse the estate's badge-soft-* palette (badge-soft.css) rather than
 * inventing a colour, so a status here reads the same as a status on every
 * other screen in the portal. Only the geometry is set locally. */

.cwh-ua-pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-family: var(--cwh-font-family);
    font-weight: var(--cwh-font-medium);
    font-size: 11.5px;
    line-height: 1.4;
    border-radius: 20px;
    white-space: nowrap;
}

/* Padding is deliberately NOT set: card.css owns it estate-wide via
   `.badge { padding: 8px 12px !important }`, and a status pill here should be
   the same size as a status pill on every other screen. */

.cwh-ua-pill > i {
    font-size: 13px;
    line-height: 1;
}

/* ── Empty states ────────────────────────────────────────────────────────── */

.cwh-ua-empty {
    text-align: center;
    padding: 3rem 1.5rem;
    font-family: var(--cwh-font-family);
}

.cwh-ua-empty-icon {
    font-size: 2.75rem;
    line-height: 1;
    display: block;
    color: var(--cwh-light-grey);
    margin-bottom: 0.75rem;
}

.cwh-ua-empty-title {
    font-weight: var(--cwh-font-bold);
    font-size: 15px;
    color: var(--cwh-dark-blue);
    margin-bottom: 0.35rem;
}

.cwh-ua-empty-text {
    color: var(--cwh-mid-grey);
    font-size: 13px;
    margin: 0 auto;
    max-width: 460px;
    line-height: 1.55;
}

/* A short list of "things to try" beneath an empty state. */
.cwh-ua-empty-list {
    list-style: none;
    padding: 0;
    margin: 0.85rem auto 0;
    max-width: 460px;
    text-align: left;
    display: inline-block;
}

.cwh-ua-empty-list li {
    color: var(--cwh-mid-grey);
    font-size: 13px;
    line-height: 1.6;
    padding-left: 22px;
    position: relative;
}

.cwh-ua-empty-list li::before {
    content: "\2022";
    position: absolute;
    left: 8px;
    color: var(--cwh-middle-blue);
}

/* ── Person detail: membership cards ─────────────────────────────────────── */

/* Card header: portal icon, portal name, scope/agent tail, status pill. */
.cwh-ua-card-head {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 0.85rem;
}

.cwh-ua-card-title {
    font-family: var(--cwh-font-family);
    font-weight: var(--cwh-font-bold);
    font-size: 16px;
    color: var(--cwh-dark-blue);
    margin: 0;
    line-height: 1.3;
}

.cwh-ua-card-meta {
    font-family: var(--cwh-font-family);
    font-weight: var(--cwh-font-medium);
    font-size: 12.5px;
    color: var(--cwh-middle-blue);
    margin-top: 2px;
}

/* A head office that could not be resolved -- either its agent_tb row has been deleted or the
   membership never named one. Tinted rather than dimmed: this is the same line as every other
   card's head office, and the whole point is that it must not read as ordinary. */
.cwh-ua-card-meta-rot {
    color: var(--cwh-danger);
    font-style: italic;
}

/* Pushes the status pill to the right edge of the header. */
.cwh-ua-card-head-end {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 8px;
}

/* A suspended membership is dimmed so a page carrying several cards makes the
   inactive one obvious at a glance -- without hiding anything on it. */
.cwh-ua-card--suspended .cwh-ua-card-title,
.cwh-ua-card--suspended .cwh-ua-card-meta {
    color: var(--cwh-mid-grey);
}

/* ── Action hierarchy ────────────────────────────────────────────────────────
 *
 * THE POINT OF THIS BLOCK. Routine actions and destructive ones must not sit
 * shoulder to shoulder at the same visual weight. Routine goes left, reversible
 * and safe; anything destructive is pushed to the far right behind a divider,
 * so reaching it is a deliberate movement rather than a neighbouring click. */

.cwh-ua-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 1rem;
    padding-top: 0.85rem;
    border-top: 1px solid var(--cwh-border);
}

/* Everything after this marker is shunted to the right-hand end of the row. */
.cwh-ua-actions-end {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 8px;
}

/* ── Danger zone ─────────────────────────────────────────────────────────────
 *
 * "Disable this person everywhere" reaches beyond the screen it is on: it
 * disables the Cognito user and signs the person out of EVERY portal, the
 * patient portal included. It previously sat immediately beside "Save details",
 * a routine action, in the same card. Here it gets its own card at the bottom of
 * the page, a danger-tinted edge, and a sentence saying what it actually does --
 * distance and explanation, which is what stops a mis-click. */

.cwh-ua-restore-title {
    display: flex;
    align-items: center;
    gap: 8px;
    font-weight: 700;
    color: var(--cwh-navy, #00337e);
    margin-bottom: 6px;
}

.cwh-ua-danger-zone {
    border: 1px solid var(--cwh-danger);
    border-left-width: 4px;
    border-radius: 12px;
    background: var(--cwh-white);
}

.cwh-ua-danger-title {
    font-family: var(--cwh-font-family);
    font-weight: var(--cwh-font-bold);
    font-size: 14px;
    color: var(--cwh-danger);
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 0.35rem;
}

.cwh-ua-danger-text {
    font-family: var(--cwh-font-family);
    font-size: 13px;
    color: var(--cwh-mid-grey);
    line-height: 1.55;
    margin: 0 0 0.85rem;
    max-width: 640px;
}

/* ── Grant sections ──────────────────────────────────────────────────────── */

.cwh-ua-grant {
    margin-bottom: 1rem;
}

.cwh-ua-grant-head {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 0.5rem;
}

.cwh-ua-grant-label {
    font-family: var(--cwh-font-family);
    font-weight: var(--cwh-font-bold);
    font-size: 12px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--cwh-dark-blue);
    margin: 0;
}

/* "3 of 13 selected" — tells the operator the state of a long list without
   making them open the picker and count it. */
.cwh-ua-grant-count {
    font-family: var(--cwh-font-family);
    font-weight: var(--cwh-font-medium);
    font-size: 12px;
    color: var(--cwh-middle-blue);
    font-variant-numeric: tabular-nums;
}


/* ── Held grants, then a search to add more ──────────────────────────────────
 *
 * THE ASYMMETRY IS THE WHOLE POINT. What a person HOLDS is a handful; what they
 * COULD hold is the entire estate — potentially thousands of sites. So the
 * handful is rendered as a plain readable list with a remove control per row,
 * and the estate is reached through a Select2 that queries the server as the
 * operator types. Show the few, search the many.
 *
 * NOTHING HERE STYLES `.select2-*`. sharedAssets/css/select2.css owns the brand
 * appearance of every Select2 in the estate, so the search box inherits the
 * house look for free and this screen contributes no dropdown styling at all. */

.cwh-ua-held {
    list-style: none;
    margin: 0 0 10px;
    padding: 0;
    border: 1px solid var(--cwh-border);
    border-radius: 10px;
    overflow: hidden;
}

.cwh-ua-held-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px 8px 14px;
    border-bottom: 1px solid var(--cwh-border);
    background: var(--cwh-white);
}

/* ── Withdrawn grants ────────────────────────────────────────────────────────
 *
 * Kept, not deleted: every revoke in PharmacyUserGrants flips a status, so the
 * record of what somebody used to reach survives. These rows ARE that record.
 *
 * They read as inactive rather than merely secondary -- muted text, a dashed
 * left edge -- because the one thing an operator must never do is mistake a
 * withdrawn grant for a live one while deciding what somebody can see. The
 * section header counts them separately for the same reason.
 *
 * Behind a <details> toggle, because history accumulates and the live grants
 * are what the page is for. */

.cwh-ua-held-history {
    margin-top: 10px;
    border-top: 1px solid var(--cwh-border);
    padding-top: 8px;
}

.cwh-ua-held-history-toggle {
    cursor: pointer;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--cwh-muted, #6b7280);
    list-style: none;
    padding: 2px 0;
}

.cwh-ua-held-history-toggle::-webkit-details-marker {
    display: none;
}

/* A TRIANGLE DRAWN WITH BORDERS, not a glyph. This was `content: "\25B8"` and shipped as a
 * literal "B8" preceded by a control character, because the escape was mangled on the way into
 * the file. Borders need no font, no encoding and no escape, so there is nothing left to mangle. */
.cwh-ua-held-history-toggle::before {
    content: "";
    display: inline-block;
    width: 0;
    height: 0;
    margin-right: 8px;
    vertical-align: middle;
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
    border-left: 5px solid currentColor;
    transition: transform 0.15s ease;
}

.cwh-ua-held-history[open] > .cwh-ua-held-history-toggle::before {
    transform: rotate(90deg);
}

.cwh-ua-held--suspended {
    margin-top: 6px;
}

.cwh-ua-held-row--suspended {
    background: transparent;
    border-left: 2px dashed var(--cwh-border);
}

.cwh-ua-held-row--suspended .cwh-ua-held-label,
.cwh-ua-held-row--suspended .cwh-ua-held-sub {
    color: var(--cwh-muted, #6b7280);
}

.cwh-ua-held-row--suspended .cwh-ua-held-label {
    text-decoration: line-through;
    text-decoration-thickness: 1px;
}

.cwh-ua-held-restore {
    flex: 0 0 auto;
    padding: 3px 10px;
    font-size: 0.75rem;
}

.cwh-ua-held-row:last-child {
    border-bottom: 0;
}

.cwh-ua-held-row:hover {
    background: rgba(0, 51, 126, 0.03);
}

.cwh-ua-held-text {
    min-width: 0;
    flex: 1 1 auto;
}

.cwh-ua-held-label {
    display: block;
    font-family: var(--cwh-font-family);
    font-weight: var(--cwh-font-medium);
    font-size: 13.5px;
    color: var(--cwh-dark-blue);
    word-break: break-word;
}

/* The owning client, so two similarly-named branches are tellable apart. */
.cwh-ua-held-sub {
    display: block;
    font-family: var(--cwh-font-family);
    font-size: 12px;
    color: var(--cwh-middle-blue);
    margin-top: 1px;
}

/* Withdrawing one grant. Quiet at rest — it sits on every row, and a column of
   red crosses reads as a list of problems rather than a list of access. It
   colours to danger only on hover, at the point of intent. */
.cwh-ua-held-remove {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border: 1px solid transparent;
    border-radius: 8px;
    background: transparent;
    color: var(--cwh-mid-grey);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.cwh-ua-held-remove:hover,
.cwh-ua-held-remove:focus {
    background: var(--cwh-danger-bg);
    border-color: var(--cwh-danger);
    color: var(--cwh-danger);
}

/* "Nothing assigned yet" — recessive, and it says what to do next. */
.cwh-ua-held-empty {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    font-family: var(--cwh-font-family);
    font-size: 12.5px;
    color: var(--cwh-mid-grey);
    line-height: 1.5;
    background: rgba(0, 51, 126, 0.03);
    border-radius: 8px;
    padding: 10px 12px;
    margin: 0 0 10px;
}

.cwh-ua-held-empty > i {
    color: var(--cwh-middle-blue);
    font-size: 15px;
    line-height: 1.35;
    flex-shrink: 0;
}

/* The add-a-grant search. Layout only. */
.cwh-ua-add-label {
    font-family: var(--cwh-font-family);
    font-weight: var(--cwh-font-medium);
    font-size: 12.5px;
    color: var(--cwh-mid-grey);
    margin-bottom: 0.3rem;
}

/* Secondary line inside a Select2 result — the site's owning client. Colour and
   size only; the result row's own chrome belongs to select2.css. */
.cwh-ua-opt-sub {
    display: block;
    font-family: var(--cwh-font-family);
    font-size: 11.5px;
    color: var(--cwh-middle-blue);
    margin-top: 1px;
}

/* "Showing the first 25 matches" — the operator must not conclude they have
   seen everything there is. */
.cwh-ua-grant-notice {
    font-family: var(--cwh-font-family);
    font-size: 11.5px;
    color: var(--cwh-mid-grey);
    margin: 6px 0 0;
}

/* ── Add-access card ─────────────────────────────────────────────────────── */

/* The single-grantable-audience case: a sentence, not a one-option select. */
.cwh-ua-single-audience {
    font-family: var(--cwh-font-family);
    font-size: 13.5px;
    color: var(--cwh-dark-blue);
    margin: 0;
    padding: 9px 0;
}

.cwh-ua-single-audience strong {
    font-weight: var(--cwh-font-bold);
}

/* ---------------------------------------------------------------------------------------
   Access level -- the two shapes a `secure` membership can have.

   The group picker is nested inside this block rather than sitting beside it, because the
   groups are only meaningful for one of the two choices. Indenting them under the radio makes
   that relationship visible without a sentence explaining it.
   --------------------------------------------------------------------------------------- */

.cwh-ua-level {
    font-family: var(--cwh-font-family);
    border-top: 1px solid var(--cwh-border);
    margin-top: 18px;
    padding-top: 16px;
}

.cwh-ua-level-option {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 12px;
    margin-bottom: 6px;
    border: 1px solid var(--cwh-border);
    border-radius: 10px;
    cursor: pointer;
}

.cwh-ua-level-option:hover {
    border-color: var(--cwh-light-blue);
}

/* The chosen shape is the one the person is in, so it carries the brand tint rather than a
   generic focus outline. :has() is supported by every browser this estate targets. */
.cwh-ua-level-option:has(input:checked) {
    border-color: var(--cwh-open-blue);
    background: rgba(153, 209, 250, 0.12);
}

.cwh-ua-level-option input {
    margin-top: 3px;
    accent-color: var(--cwh-dark-blue);
}

.cwh-ua-level-text {
    display: flex;
    flex-direction: column;
}

.cwh-ua-level-text strong {
    color: var(--cwh-dark-blue);
    font-weight: var(--cwh-font-medium);
}

.cwh-ua-level-hint {
    color: var(--cwh-middle-blue);
    font-size: 13px;
}

/* Indented to sit under the choice that owns them. */
.cwh-ua-level-groups {
    margin: 4px 0 0 28px;
    padding-left: 14px;
    border-left: 2px solid var(--cwh-light-blue);
}

.cwh-ua-level-note {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 8px 0 0;
    color: var(--cwh-open-blue);
    font-size: 13px;
}

.cwh-ua-level-apply {
    margin-top: 12px;
}
