/* The capability screens: the Explorer, the Guided grant and the pieces they share.

   This file holds the shared pieces first (badges, method marks, claim chips, the reach cell and
   the gateway report panel, all prefixed capx-), then the Explorer (explorer-, captree-, capdetail-
   and caprail- prefixes), then the Guided grant step of the issue token wizard (grant- prefix).
   Nothing in showcase.css refers to the catalogue any more.

   Every colour is a token from :root in app.css. Nothing in this file declares a palette value of
   its own, because two copies of a palette drift apart and the copy nobody remembers is the one
   that is wrong. A tinted background is the token mixed to 10 percent over whatever surface it
   sits on, which is the one pattern this file has for colouring an area rather than a line.

   Contrast, measured against --surface-hover #16264a, the lightest surface any of this text
   crosses, and re checked on the 10 percent tint of each status colour over that same surface:

       --ink             #f4f7fb   13.9:1    chip values and badge text
       --ink-muted       #9fb0c3    6.7:1    chip keys, reasons and meta, 5.5:1 on any tint
       --gold            #e8b84b    8.1:1    the Allegiant only badge, 6.7:1 on its own tint
       --status-success  #4ade80    8.6:1    Reachable and the approved dot, 7.0:1 on its tint
       --status-danger   #f0677d    4.9:1    Unreachable

   --status-danger on its own 10 percent tint measures 4.4:1, which fails 1.4.3, so danger text
   is never placed on a danger tint here. It sits on the plain surface and the icon beside it
   does the rest. No text in this file uses --ink-faint. */

/* ── Shared ─────────────────────────────────────────────────────────────────────────────────── */

/* Words for assistive technology that take no space on screen. The same clip pattern as
   Bootstrap's sr-only, kept here under this file's prefix so the capability components do not
   depend on a utility stylesheet that a later story may remove. */
.capx-visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* The tinted background pattern. A status colour mixed to 10 percent over the surface beneath,
   so the same modifier reads correctly on a card, a pane or a hover row without a value per
   surface. */
.capx-tint--gold {
    background: color-mix(in srgb, var(--gold) 10%, transparent);
}

.capx-tint--ok {
    background: color-mix(in srgb, var(--status-success) 10%, transparent);
}

.capx-tint--warn {
    background: color-mix(in srgb, var(--status-warning) 10%, transparent);
}

.capx-tint--bad {
    background: color-mix(in srgb, var(--status-danger) 10%, transparent);
}

/* One ring for every control these screens draw, the same ring app.css gives a Radzen button so
   two controls side by side do not focus differently. :focus-visible rather than :focus, so a
   pointer click does not leave a ring behind. */
:where([class*="capx-"]):is(button, a, input, [tabindex]):focus-visible {
    outline: 2px solid var(--gold-bright);
    outline-offset: 2px;
}

.capx-badge,
.capx-method,
.capx-claim {
    transition: color 150ms ease-out, background-color 150ms ease-out, border-color 150ms ease-out;
}

/* WCAG 2.2, 2.3.3. Nothing here moves on its own, but a colour fade is still motion to somebody
   who has asked for less of it. */
@media (prefers-reduced-motion: reduce) {
    [class*="capx-"],
    [class*="capx-"]::before,
    [class*="capx-"]::after {
        transition: none;
        animation: none;
    }
}

/* ── Status and Allegiant only badges ───────────────────────────────────────────────────────── */

.capx-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 8px;
    border: 1px solid var(--hairline);
    border-radius: 999px;
    background: var(--surface-raised);
    color: var(--ink);
    font-size: 11px;
    line-height: 1.45;
    white-space: nowrap;
}

/* The dot takes the badge's colour. It is aria-hidden in the markup because the word beside it
   already says what the colour repeats. */
.capx-badge__dot {
    flex: 0 0 auto;
    width: 5px;
    height: 5px;
    border-radius: 999px;
    background: currentColor;
}

.capx-badge--ok {
    color: var(--status-success);
    border-color: color-mix(in srgb, var(--status-success) 40%, transparent);
    background: color-mix(in srgb, var(--status-success) 10%, transparent);
}

.capx-badge--warn {
    color: var(--status-warning);
    border-color: color-mix(in srgb, var(--status-warning) 40%, transparent);
    background: color-mix(in srgb, var(--status-warning) 10%, transparent);
}

.capx-badge--gold {
    color: var(--gold);
    border-color: color-mix(in srgb, var(--gold) 40%, transparent);
    background: color-mix(in srgb, var(--gold) 10%, transparent);
}

/* The lock alone, for a tree row where the words would not fit. The words are still there for a
   screen reader, and the title gives a pointer user the same sentence on hover. */
.capx-badge--compact {
    padding: 2px;
    gap: 0;
}

/* ── HTTP methods ───────────────────────────────────────────────────────────────────────────── */

.capx-methods {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 4px;
}

.capx-method {
    display: inline-block;
    padding: 1px 6px;
    border: 1px solid var(--hairline-strong);
    border-radius: 8px;
    background: var(--surface-raised);
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: 10.5px;
    line-height: 1.45;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.capx-method--none {
    color: var(--ink-muted);
    border-style: dashed;
    text-transform: none;
}

/* ── Claim chips ────────────────────────────────────────────────────────────────────────────── */

.capx-claims {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Monospace, because a claim value is matched character for character by the gateway and a
   lowercase L beside a one has to be tellable apart. */
.capx-claim {
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
    padding: 2px 8px;
    border: 1px solid var(--hairline-strong);
    border-radius: 8px;
    background: var(--surface-raised);
    color: var(--ink);
    font-family: var(--font-mono);
    font-size: 12px;
    line-height: 1.45;
    white-space: nowrap;
}

.capx-claim__key {
    color: var(--ink-muted);
}

/* tenant_class is the one claim that turns a route away from a whole class of tenant rather than
   from a token missing a permission. The key and value already say so; the border and the warn
   colour make it findable at a glance in a row of chips. */
.capx-claim--restrictive {
    border-color: color-mix(in srgb, var(--status-warning) 55%, transparent);
}

.capx-claim--restrictive .capx-claim__value {
    color: var(--status-warning);
}

.capx-claim--none {
    color: var(--ink-muted);
    border-style: dashed;
    font-family: inherit;
}

/* ── Reach cell ─────────────────────────────────────────────────────────────────────────────── */

.capx-reach {
    display: inline-flex;
    flex-direction: column;
    gap: 2px;
    font-size: 13px;
    line-height: 1.45;
}

.capx-reach__state {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    white-space: nowrap;
}

.capx-reach--ok .capx-reach__state {
    color: var(--status-success);
}

/* The word carries the state. The colour, like the icon, repeats it. */
.capx-reach--bad .capx-reach__state {
    color: var(--status-danger);
}

.capx-reach__reason {
    color: var(--ink-muted);
    font-size: 11.5px;
}

/* ── Gateway report panel ───────────────────────────────────────────────────────────────────── */

.capx-report {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 12px 16px;
    border: 1px solid var(--hairline);
    border-radius: 12px;
    background: var(--surface);
}

.capx-report__heading {
    margin: 0 0 4px;
    font-family: InterSemiBold, "Inter", "Segoe UI", sans-serif;
    font-size: 15px;
    color: var(--ink);
}

/* An h5 only so the markup tests keep finding the gateway and the environment in a heading. It
   is sized as the body text of the panel, not as a title. */
.capx-report__gateway {
    margin: 0;
    font-family: InterSemiBold, "Inter", "Segoe UI", sans-serif;
    font-size: 13px;
    line-height: 1.45;
    color: var(--ink);
}

.capx-report__freshness {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin: 0;
    font-size: 12px;
    line-height: 1.45;
    color: var(--ink-muted);
}

.capx-report__freshness .app-icon {
    margin-top: 1px;
    color: var(--status-success);
}

.capx-report__freshness--stale .app-icon {
    color: var(--status-warning);
}

/* ── The Explorer (the capability catalogue page) ──────────────────────────────────────────── */

/* Three panes in one bordered card: the tree, the selected capability, the actions. The side
   panes are fixed and the middle takes the rest, so a long route path widens nothing but its
   own scroller. Below 1100px the three stack, tree first, because on a narrow screen the thing
   to find comes before the thing found.

   Contrast, measured against --shell-800 #0a1220, the darkest surface any of this text sits on,
   and on --surface-hover for the hover row:
       --ink        #f4f7fb   17.8:1   names, paths and body text
       --ink-muted  #9fb0c3    8.4:1   counts, meta and the summary line
       --gold       #e8b84b   10.4:1   the selected name, 8.1:1 on the hover row */

.explorer-page {
    display: flex;
    flex-direction: column;
    gap: 18px;
}

.explorer__toolbar {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 20px;
    flex-wrap: wrap;
}

.explorer__heading {
    margin: 0 0 4px;
    font-family: InterSemiBold, "Inter", "Segoe UI", sans-serif;
    font-size: 22px;
    color: var(--ink);
}

.explorer__subheading {
    margin: 0;
    font-size: 14px;
    color: var(--ink-muted);
}

.explorer__actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

/* The report on its own, for the states with no explorer to put it in. */
.explorer__report {
    max-width: 640px;
}

.explorer__state {
    padding: 22px;
    border: 1px dashed var(--hairline-strong);
    border-radius: 12px;
    background: var(--surface);
    color: var(--ink-muted);
    font-size: 14px;
    line-height: 1.45;
}

.explorer__state strong {
    display: block;
    margin-bottom: 4px;
    color: var(--ink);
}

.explorer__state a {
    color: var(--gold);
}

.explorer {
    display: grid;
    grid-template-columns: 312px minmax(0, 1fr) 288px;
    min-height: 640px;
    border: 1px solid var(--hairline);
    border-radius: 12px;
    background: var(--surface);
    overflow: hidden;
}

.explorer__tree {
    display: flex;
    flex-direction: column;
    min-width: 0;
    background: var(--shell-800);
    border-right: 1px solid var(--hairline);
}

.explorer__detail {
    min-width: 0;
    padding: 28px 32px;
    overflow: auto;
}

.explorer__detail-empty {
    margin: 0;
    font-size: 13px;
    color: var(--ink-muted);
}

.explorer__rail {
    min-width: 0;
    padding: 24px 20px;
    background: var(--shell-800);
    border-left: 1px solid var(--hairline);
}

/* Below the design width the card sits beside a 240px shell sidebar with under 1000px to itself,
   which is not enough for a five column routes table between two fixed panes. The rail drops
   under the detail, which gives the table its width back, and the rail's two sections sit side
   by side so the drop costs little height. */
@media (max-width: 1439px) {
    .explorer {
        grid-template-columns: 288px minmax(0, 1fr);
        grid-template-rows: minmax(0, 1fr) auto;
        grid-template-areas:
            "tree detail"
            "tree rail";
    }

    .explorer__tree {
        grid-area: tree;
    }

    .explorer__detail {
        grid-area: detail;
        padding: 24px;
    }

    .explorer__rail {
        grid-area: rail;
        padding: 20px 24px;
        border-left: 0;
        border-top: 1px solid var(--hairline);
    }

    .explorer .caprail {
        flex-direction: row;
        gap: 32px;
    }

    .caprail__section {
        flex: 1 1 0;
        min-width: 0;
    }
}

/* One column: the tree, then the detail, then the rail. The thing to find comes before the
   thing found. */
@media (max-width: 1099px) {
    .explorer {
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: auto;
        grid-template-areas:
            "tree"
            "detail"
            "rail";
        min-height: 0;
    }

    .explorer__tree {
        border-right: 0;
        border-bottom: 1px solid var(--hairline);
    }

    .explorer__detail {
        padding: 20px 16px;
    }

    .explorer__rail {
        padding: 20px 16px;
    }
}

@media (max-width: 720px) {
    .explorer .caprail {
        flex-direction: column;
        gap: 24px;
    }
}

/* The same ring the shared pieces and the Radzen buttons get, on the Explorer's own controls. */
.captree__search-input:focus-visible,
.captree__search-clear:focus-visible,
.captree__chip:focus-visible,
.captree__link:focus-visible,
.captree__node:focus-visible {
    outline: 2px solid var(--gold-bright);
    outline-offset: 2px;
}

.captree__search-input,
.captree__search-clear,
.captree__chip,
.captree__node {
    transition: color 150ms ease-out, background-color 150ms ease-out, border-color 150ms ease-out;
}

@media (prefers-reduced-motion: reduce) {
    [class*="explorer__"],
    [class*="captree__"],
    [class*="capdetail__"],
    [class*="caprail__"] {
        transition: none;
        animation: none;
    }
}

/* ── The tree ───────────────────────────────────────────────────────────────────────────────── */

.captree__search {
    position: relative;
    padding: 16px 16px 8px;
}

.captree__search-input {
    width: 100%;
    padding: 8px 34px 8px 12px;
    border: 1px solid var(--hairline-strong);
    border-radius: 8px;
    background: var(--surface-raised);
    color: var(--ink);
    font-size: 13px;
    line-height: 1.45;
}

/* Placeholder text is instruction, so it is held to the same floor as everything else rather
   than left on the browser default, which is near invisible on this theme. */
.captree__search-input::placeholder {
    color: var(--ink-muted);
    opacity: 1;
}

.captree__search-input:focus {
    border-color: var(--gold);
}

/* The browser draws its own clear control on a search input. It is unnamed and unstyled, so it
   is hidden and the named button beside it does the job. */
.captree__search-input::-webkit-search-cancel-button {
    -webkit-appearance: none;
    appearance: none;
}

.captree__search-clear {
    position: absolute;
    top: 16px;
    right: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 34px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--ink-muted);
    cursor: pointer;
}

.captree__search-clear:hover {
    color: var(--ink);
}

.captree__chips {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    padding: 0 16px 8px;
}

.captree__chip {
    padding: 3px 10px;
    border: 1px solid var(--hairline-strong);
    border-radius: 8px;
    background: transparent;
    color: var(--ink-muted);
    font-size: 12px;
    line-height: 1.45;
    cursor: pointer;
}

.captree__chip:hover {
    color: var(--ink);
    background: var(--surface-hover);
}

/* Pressed is said by aria-pressed, which is what a screen reader announces. The colour repeats it. */
.captree__chip[aria-pressed="true"] {
    color: var(--gold);
    border-color: color-mix(in srgb, var(--gold) 55%, transparent);
    background: color-mix(in srgb, var(--gold) 10%, transparent);
}

.captree__summary {
    margin: 0;
    padding: 0 16px 8px;
    font-size: 12px;
    color: var(--ink-muted);
}

.captree__none {
    padding: 8px 16px 16px;
    font-size: 13px;
    line-height: 1.45;
    color: var(--ink-muted);
}

.captree__none p {
    margin: 0 0 6px;
}

.captree__link {
    padding: 0;
    border: 0;
    background: none;
    color: var(--gold);
    font-size: 13px;
    text-decoration: underline;
    cursor: pointer;
}

.captree__tree {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1 1 auto;
    padding: 4px 8px 16px;
    overflow: auto;
}

/* One row for every kind of node. The indent is 16px a level, taken from the aria-level the
   markup already states, so the depth a screen reader hears and the depth a sighted user sees
   come from the same number. */
.captree__node {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    min-height: 36px;
    padding: 0 10px 0 calc(10px + (var(--captree-level, 1) - 1) * 16px);
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--ink);
    font-size: 13px;
    line-height: 1.45;
    text-align: left;
    cursor: pointer;
}

.captree__node:hover {
    background: var(--surface-hover);
}

.captree__node.is-selected,
.captree__node.is-highlighted {
    background: color-mix(in srgb, var(--gold) 10%, transparent);
}

.captree__node.is-selected .captree__name {
    color: var(--gold);
}

.captree__chevron {
    flex: 0 0 auto;
    color: var(--ink-muted);
}

.captree__node[aria-expanded="true"] .captree__chevron {
    transform: rotate(90deg);
}

/* A capability with no routes has nothing to open. The chevron's space is kept so the names
   stay in one column, but the mark is not drawn. */
.captree__chevron--blank {
    visibility: hidden;
}

.captree__glyph {
    flex: 0 0 auto;
    color: var(--ink-muted);
}

.captree__label {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: InterSemiBold, "Inter", "Segoe UI", sans-serif;
}

/* Monospace, because a name is matched character for character against a claim value. The name
   keeps its first twelve characters whatever else is on the row: the badge beside it gives way
   first, because the badge's words are repeated in the detail and the name is what the row is. */
.captree__name {
    flex: 1 1 auto;
    min-width: 12ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--font-mono);
    font-size: 13px;
}

.captree__node .capx-badge {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
}

.captree__node .capx-badge > span:last-child {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The lock alone is 16px wide and has nothing to give. */
.captree__node .capx-badge--compact {
    flex: 0 0 auto;
}

.captree__node-count {
    flex: 0 0 auto;
    margin-left: auto;
    font-size: 12px;
    color: var(--ink-muted);
    white-space: nowrap;
}

.captree__method {
    flex: 0 0 auto;
    min-width: 42px;
    font-family: var(--font-mono);
    font-size: 10.5px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ink-muted);
}

.captree__path {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--font-mono);
    font-size: 12px;
}

/* The mark for a route or a capability that a third party tenant could not fully use. Its words
   are in the markup; the colour only says where to look. */
.captree__flag {
    flex: 0 0 auto;
    color: var(--status-warning);
}

/* ── The detail ─────────────────────────────────────────────────────────────────────────────── */

.capdetail {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.capdetail__header {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
}

.capdetail__title {
    margin: 0;
    font-family: var(--font-mono);
    font-size: 24px;
    font-weight: 600;
    line-height: 1.2;
    color: var(--ink);
    overflow-wrap: anywhere;
}

.capdetail__badges {
    display: flex;
    align-items: center;
    gap: 8px;
}

.capdetail__description {
    margin: 0;
    max-width: 72ch;
    font-size: 15px;
    line-height: 1.45;
    color: var(--ink-muted);
}

.capdetail__description--empty {
    font-style: italic;
}

/* Warn tinted, and --ink on the tint rather than the warn colour, because the icon already
   carries the colour and the words have to be read. */
.capdetail__notice {
    display: flex;
    gap: 10px;
    padding: 12px 14px;
    border: 1px solid color-mix(in srgb, var(--status-warning) 40%, transparent);
    border-radius: 8px;
    background: color-mix(in srgb, var(--status-warning) 10%, transparent);
    font-size: 13px;
    line-height: 1.45;
    color: var(--ink);
}

.capdetail__notice .app-icon {
    flex: 0 0 auto;
    margin-top: 2px;
    color: var(--status-warning);
}

.capdetail__notice p {
    margin: 0;
}

.capdetail__facts {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 16px;
    margin: 0;
    padding: 16px 0;
    border-top: 1px solid var(--hairline);
    border-bottom: 1px solid var(--hairline);
}

.capdetail__fact dt {
    margin-bottom: 4px;
    font-size: 12px;
    color: var(--ink-muted);
}

.capdetail__fact dd {
    margin: 0;
    font-size: 13px;
    line-height: 1.45;
    color: var(--ink);
}

.capdetail__fact--mono dd {
    font-family: var(--font-mono);
    font-size: 12px;
    overflow-wrap: anywhere;
}

.capdetail__routes-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    margin-bottom: 12px;
}

.capdetail__routes-title {
    margin: 0;
    font-family: InterSemiBold, "Inter", "Segoe UI", sans-serif;
    font-size: 15px;
    color: var(--ink);
}

.capdetail__routes-meta {
    font-size: 12px;
    color: var(--ink-muted);
}

/* Tabular by nature, so it keeps a table and gets its own scroller rather than widening the
   page. This is the only thing on the screen that may scroll sideways. */
.capdetail__scroller {
    overflow-x: auto;
    border: 1px solid var(--hairline);
    border-radius: 8px;
}

.capdetail__table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
    line-height: 1.45;
}

.capdetail__table th,
.capdetail__table td {
    padding: 10px 12px;
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--hairline);
}

/* The path may wrap, but not shred: a column that gives way to the nowrap chips beside it ends
   up four characters wide. Past this floor the table scrolls inside its own scroller. */
.capdetail__table th:first-child,
.capdetail__table td:first-child {
    min-width: 200px;
}

.capdetail__table thead th {
    font-family: InterSemiBold, "Inter", "Segoe UI", sans-serif;
    font-size: 11px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-muted);
    background: var(--shell-800);
    white-space: nowrap;
}

.capdetail__table tbody tr:last-child td {
    border-bottom: 0;
}

.capdetail__table td {
    color: var(--ink);
}

/* The route picked in the tree. aria-current says so; the tint shows where. */
.capdetail__table tbody tr.is-highlighted {
    background: color-mix(in srgb, var(--gold) 6%, transparent);
}

.capdetail__path {
    font-family: var(--font-mono);
    font-size: 12.5px;
    color: var(--ink);
    overflow-wrap: anywhere;
}

.capdetail__path-note {
    display: block;
    margin-top: 3px;
    font-size: 11.5px;
    color: var(--ink-muted);
}

.capdetail__footnote {
    margin: 10px 0 0;
    font-size: 12px;
    color: var(--ink-muted);
}

.capdetail__empty {
    padding: 22px;
    border: 1px dashed var(--hairline-strong);
    border-radius: 8px;
    font-size: 13px;
    line-height: 1.45;
    color: var(--ink-muted);
}

.capdetail__empty strong {
    display: block;
    margin-bottom: 4px;
    color: var(--ink);
}

@media (max-width: 1439px) {
    .capdetail__facts {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 720px) {
    .capdetail__facts {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* ── The rail ───────────────────────────────────────────────────────────────────────────────── */

.caprail {
    display: flex;
    flex-direction: column;
    gap: 24px;
}

.caprail__heading {
    margin: 0 0 12px;
    font-family: InterSemiBold, "Inter", "Segoe UI", sans-serif;
    font-size: 15px;
    color: var(--ink);
}

/* Full width, so the two actions line up and neither looks like the default. */
.caprail__action {
    margin-bottom: 8px;
}

.caprail__action .rz-button {
    width: 100%;
    justify-content: center;
}

.caprail__hint {
    margin: 0 0 16px;
    font-size: 12px;
    line-height: 1.45;
    color: var(--ink-muted);
}

.caprail__note {
    margin: 0 0 12px;
    padding: 8px 10px;
    border-left: 2px solid var(--hairline-strong);
    font-size: 12px;
    line-height: 1.45;
    color: var(--ink-muted);
}

/* ── The Guided grant (step 3 of the issue token wizard) ───────────────────────────────────── */

/* The dialog is opened at 1040px. On a narrower screen it yields to the viewport rather than
   overflowing it, and only this dialog, because the others were sized for their own content. */
.rz-dialog.issue-token-dialog {
    max-width: 92vw;
}

.grant {
    min-width: 0;
}

/* The tenant summary strip: who the capabilities are being granted to, and what that means. */
.grant__tenant {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 24px;
    margin: 0 0 16px;
    padding: 16px 20px;
    border: 1px solid var(--hairline);
    border-radius: 12px;
    background: var(--surface-raised);
}

.grant__tenant-main {
    flex: 1 1 auto;
    min-width: 0;
}

.grant__eyebrow {
    margin: 0 0 4px;
    font-size: 12px;
    color: var(--ink-muted);
}

.grant__tenant-name {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin: 0 0 6px;
    font-family: InterSemiBold, "Inter", "Segoe UI", sans-serif;
    font-size: 22px;
    line-height: 1.3;
    color: var(--ink);
}

.grant__tenant-sentence {
    max-width: 64ch;
    margin: 0;
    font-size: 13px;
    line-height: 1.45;
    color: var(--ink-muted);
}

/* The classification as a pill. The words carry it; the gold only says which kind is the
   privileged one. */
.grant__pill {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border: 1px solid var(--hairline-strong);
    border-radius: 999px;
    background: var(--surface);
    font-family: "Inter", "Segoe UI", sans-serif;
    font-size: 11px;
    line-height: 1.45;
    color: var(--ink);
    white-space: nowrap;
}

.grant__pill--gold {
    color: var(--gold);
    border-color: color-mix(in srgb, var(--gold) 55%, transparent);
    background: color-mix(in srgb, var(--gold) 10%, transparent);
}

.grant__facts {
    flex: 0 0 auto;
    display: grid;
    grid-template-columns: auto auto;
    gap: 4px 16px;
    margin: 0;
    font-size: 12px;
    line-height: 1.45;
}

.grant__facts dt {
    color: var(--ink-muted);
    font-weight: normal;
}

.grant__facts dd {
    margin: 0;
    color: var(--ink);
}

.grant__mono {
    font-family: var(--font-mono);
}

/* The search, drawn the same way as the Explorer's so the two screens read as one. */
.grant__search {
    margin: 0 0 8px;
}

.grant__search-box {
    position: relative;
}

.grant__search-input {
    width: 100%;
    padding: 8px 34px 8px 12px;
    border: 1px solid var(--hairline-strong);
    border-radius: 8px;
    background: var(--surface-raised);
    color: var(--ink);
    font-size: 13px;
    line-height: 1.45;
}

.grant__search-input::placeholder {
    color: var(--ink-muted);
    opacity: 1;
}

.grant__search-input:focus {
    border-color: var(--gold);
}

.grant__search-input::-webkit-search-cancel-button {
    -webkit-appearance: none;
    appearance: none;
}

.grant__search-clear {
    position: absolute;
    top: 0;
    right: 4px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 100%;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--ink-muted);
    cursor: pointer;
}

.grant__search-clear:hover {
    color: var(--ink);
}

.grant__search-result {
    margin: 4px 0 0;
    font-size: 12px;
    color: var(--ink-muted);
}

.grant__chosen {
    margin: 0 0 12px;
    font-size: 12px;
    line-height: 1.45;
    color: var(--ink);
}

.grant__chosen-names {
    font-family: var(--font-mono);
}

.grant__state {
    margin: 8px 0;
    font-size: 13px;
    color: var(--ink-muted);
}

/* The two sections, grantable and not. */
.grant__section {
    margin: 16px 0 0;
}

.grant__section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin: 0 0 8px;
}

.grant__section-title {
    margin: 0;
    font-family: InterSemiBold, "Inter", "Segoe UI", sans-serif;
    font-size: 15px;
    line-height: 1.45;
    color: var(--ink);
}

.grant__qualifier {
    font-family: "Inter", "Segoe UI", sans-serif;
    font-size: 12px;
    font-weight: normal;
    color: var(--ink-muted);
}

.grant__section-count {
    flex: 0 0 auto;
    font-size: 12px;
    color: var(--ink-muted);
    white-space: nowrap;
}

.grant__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
}

.grant__empty {
    margin: 0;
    padding: 12px 14px;
    border: 1px dashed var(--hairline-strong);
    border-radius: 8px;
    font-size: 13px;
    line-height: 1.45;
    color: var(--ink-muted);
}

/* One card per capability. Ticked is said by the checkbox; the gold edge and fill repeat it. */
.grant__card {
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-width: 0;
    padding: 12px 14px;
    border: 1px solid var(--hairline);
    border-radius: 12px;
    background: var(--surface);
    transition: border-color 150ms ease-out, background-color 150ms ease-out;
}

.grant__card--checked {
    border-color: var(--gold);
    background: color-mix(in srgb, var(--gold) 5%, transparent);
}

/* Refused is said by the disabled checkbox and the note. The dashed edge repeats it without
   dimming the text, because a dimmed reason is the one thing on the card that must be read. */
.grant__card--disabled {
    border-style: dashed;
}

.grant__card-head {
    display: flex;
    align-items: flex-start;
    gap: 10px;
}

.grant__check {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    margin: 3px 0 0;
    accent-color: var(--gold);
}

.grant__label {
    flex: 1 1 auto;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    min-width: 0;
    cursor: pointer;
}

.grant__card--disabled .grant__label {
    cursor: default;
}

/* Monospace, because the name is matched character for character against a claim value. */
.grant__name {
    font-family: var(--font-mono);
    font-size: 13px;
    font-weight: 600;
    color: var(--ink);
    word-break: break-all;
}

.grant__card--checked .grant__name {
    color: var(--gold);
}

.grant__count {
    flex: 0 0 auto;
    margin-left: auto;
    font-size: 12px;
    color: var(--ink-muted);
    white-space: nowrap;
}

/* One line, with the whole description on hover, so a long one does not push the routes off
   the card. */
.grant__description {
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 12px;
    line-height: 1.45;
    color: var(--ink-muted);
}

.grant__routes {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.grant__route {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    max-width: 100%;
    padding: 2px 8px;
    border: 1px solid var(--hairline-strong);
    border-radius: 8px;
    background: var(--surface-raised);
    font-family: var(--font-mono);
    font-size: 12px;
    line-height: 1.45;
    color: var(--ink);
    transition: border-color 150ms ease-out, background-color 150ms ease-out;
}

.grant__route-methods {
    flex: 0 0 auto;
    font-size: 10.5px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ink-muted);
}

.grant__route-path {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* A route the token for this tenant could not reach. The words are in the markup for assistive
   technology; the icon and the tint say where to look. Warn on its own tint measures 6.7:1. */
.grant__route--unreachable {
    border-color: color-mix(in srgb, var(--status-warning) 55%, transparent);
    background: color-mix(in srgb, var(--status-warning) 10%, transparent);
    color: var(--status-warning);
}

.grant__route--unreachable .grant__route-methods {
    color: var(--status-warning);
}

.grant__route--none {
    border-style: dashed;
    font-family: "Inter", "Segoe UI", sans-serif;
    color: var(--ink-muted);
}

.grant__note {
    font-size: 12px;
    line-height: 1.45;
    color: var(--ink-muted);
}

.grant__note:empty {
    display: none;
}

.grant__note--warn,
.grant__note--refused {
    color: var(--status-warning);
}

/* The totals, pinned to the foot of the scrolling step. Opaque, so the cards pass beneath it. */
.grant__footer {
    position: sticky;
    bottom: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 10px;
    margin: 16px 0 0;
    padding: 12px 16px;
    border: 1px solid var(--hairline);
    border-radius: 12px;
    background: var(--surface);
    box-shadow: 0 -8px 24px 0 rgba(0, 0, 0, 0.35);
    font-size: 13px;
    line-height: 1.45;
    color: var(--ink);
}

.grant__footer-routes {
    font-weight: 600;
    color: var(--gold);
}

.grant__footer-meta,
.grant__footer-separator {
    color: var(--ink-muted);
}

.grant__footer-warn {
    color: var(--status-warning);
}

.grant__check:focus-visible,
.grant__search-input:focus-visible,
.grant__search-clear:focus-visible {
    outline: 2px solid var(--gold-bright);
    outline-offset: 2px;
}

@media (max-width: 720px) {
    .grant__tenant {
        flex-direction: column;
    }

    .grant__grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (prefers-reduced-motion: reduce) {
    .grant__card,
    .grant__route {
        transition: none;
    }
}
