/* sb-policy-stack-card.css
   3-band card + scope-group accordion + Owned/Effective tabs for the
   policy stack surface. Spec: docs/superpowers/specs/2026-06-24-policy-stack-3band-card-design.md
   Replaces the deleted source/mode/verdict pill styling. */

/* ─── Card surface ─────────────────────────────────────────────── */

.sb-policy-card {
    background: var(--color-base-100);
    border: 1px solid var(--color-base-300);
    border-radius: 0.5rem;
    padding: 0;
    margin-block-end: 0.75rem;
     /* overflow: clip keeps the inner band backgrounds contained inside the
       rounded border without establishing a scroll container, so an
       ancestor with position: sticky (the scope-group header) still
       sticks. Drop-in upgrade over the older overflow: hidden. */
    overflow: clip;
    transition: transform 100ms ease-out, box-shadow 100ms ease-out;
}
.sb-policy-card:hover {
    transform: translateY(-1px);
    box-shadow: 0 2px 8px color-mix(in srgb, var(--color-base-content) 8%, transparent);
}
/* Inherited cards in the Effective panel are read-only at this scope --
   they belong to a broader-scope group. Don't lift on hover so the visual
   doesn't suggest direct editability. */
.sb-effective-row[data-inherited="true"] .sb-policy-card:hover {
    transform: none;
    box-shadow: none;
}

/* Drag-in-progress visual. policy-stack-reorder.js sets the
   .sb-row-dragging class on the <li> that owns the dragged card; we style
   the inner card so the border-radius + shadow ride along cleanly. */
.sb-row-dragging .sb-policy-card {
    opacity: 0.5;
    transform: rotate(0.5deg);
    cursor: grabbing;
}

/* ─── Band 1: Headline ─────────────────────────────────────────── */

.sb-policy-card-head {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 0.75rem;
    padding: 0.625rem 1rem;
    border-block-end: 1px solid var(--color-base-300);
}
.sb-policy-card-priority {
    font: 500 0.75rem/1 ui-monospace, monospace;
    color: color-mix(in srgb, var(--color-base-content) 50%, transparent);
}
.sb-policy-card-target {
    font: 600 0.875rem/1.2 ui-monospace, monospace;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sb-policy-card-actions {
    display: flex;
    gap: 0.25rem;
}
.sb-policy-card-edit, .sb-policy-card-drag {
    border: 0;
    background: transparent;
    color: color-mix(in srgb, var(--color-base-content) 50%, transparent);
    cursor: pointer;
    padding: 0.25rem 0.5rem;
    border-radius: 0.25rem;
    line-height: 1;
}
.sb-policy-card-edit:hover, .sb-policy-card-drag:hover {
    color: var(--color-base-content);
    background: var(--color-base-200);
}

/* ─── Band 2: Body ─────────────────────────────────────────────── */

.sb-policy-card-body {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 0.25rem 0.75rem;
    padding: 0.75rem 1rem;
    background: color-mix(in srgb, var(--color-base-200) 30%, transparent);
}
.sb-policy-card-if, .sb-policy-card-then { display: contents; }
.sb-policy-card-keyword {
    font: 500 0.625rem/1 ui-sans-serif, system-ui;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: color-mix(in srgb, var(--color-base-content) 50%, transparent);
    align-self: center;
}
.sb-policy-card-action {
    font: 400 0.875rem/1.4 ui-sans-serif, system-ui;
}

/* Predicate chips inside the card -- flat tokens, not badges */
.sb-policy-card-chips,
.predicate-chips.sb-policy-card-chips {
    font: 400 0.875rem/1.4 ui-sans-serif, system-ui;
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0.375rem;
}
.sb-policy-card-chips .chip {
    display: inline-flex;
    gap: 0.25rem;
    padding: 0.125rem 0.375rem;
    border: 1px solid var(--color-base-300);
    border-radius: 0.25rem;
    background: var(--color-base-100);
    font-family: ui-monospace, monospace;
    font-size: 0.8125rem;
}
.sb-policy-card-chips .kw {
    color: color-mix(in srgb, var(--color-base-content) 45%, transparent);
    text-transform: uppercase;
    font-size: 0.6875rem;
    letter-spacing: 0.05em;
}

/* ─── Band 3: Meta ─────────────────────────────────────────────── */

.sb-policy-card-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    align-items: center;
    padding: 0.5rem 1rem;
    font: 400 0.75rem/1.2 ui-sans-serif, system-ui;
    color: color-mix(in srgb, var(--color-base-content) 60%, transparent);
}
.sb-policy-card-mode {
    display: inline-flex;
    gap: 0.375rem;
    align-items: center;
}
.sb-policy-card-mode-dot {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: var(--color-base-300);
    display: inline-block;
}
.sb-policy-card-mode.mode-live     .sb-policy-card-mode-dot { background: var(--color-success); }
.sb-policy-card-mode.mode-observe  .sb-policy-card-mode-dot { background: var(--color-info); }
.sb-policy-card-mode.mode-draft    .sb-policy-card-mode-dot { background: color-mix(in srgb, var(--color-base-content) 40%, transparent); }
.sb-policy-card-mode.mode-disabled .sb-policy-card-mode-dot { background: var(--color-base-300); }
.sb-policy-card-no-hits, .sb-policy-card-diverged {
    color: var(--color-warning);
}
.sb-policy-card-diverged code {
    background: transparent;
    padding: 0;
    font: inherit;
}

/* ─── Scope-group accordion ────────────────────────────────────── */

.sb-policy-scope-group {
    margin-block-end: 1.5rem;
}
.sb-policy-scope-group-head {
    position: sticky;
    top: 0;
    background: var(--color-base-100);
    z-index: 1;
    padding: 0.5rem 0;
}
.sb-policy-scope-group-disclosure {
    display: inline-flex;
    gap: 0.5rem;
    align-items: center;
    background: transparent;
    border: 0;
    cursor: pointer;
    font: 600 0.875rem/1.2 ui-sans-serif, system-ui;
    padding: 0;
    color: inherit;
}
.sb-policy-scope-group-caret {
    transition: transform 100ms ease;
    display: inline-block;
}
.sb-policy-scope-group-disclosure[aria-expanded="false"] .sb-policy-scope-group-caret {
    transform: rotate(-90deg);
}
.sb-policy-scope-group-type {
    color: color-mix(in srgb, var(--color-base-content) 60%, transparent);
    text-transform: lowercase;
}
.sb-policy-scope-group-target code {
    background: transparent;
    padding: 0;
    font: inherit;
}
.sb-policy-scope-group-count {
    color: color-mix(in srgb, var(--color-base-content) 50%, transparent);
    font-weight: 400;
    font-size: 0.8125rem;
}
.sb-policy-scope-group-desc {
    font: 400 0.8125rem/1.4 ui-sans-serif, system-ui;
    color: color-mix(in srgb, var(--color-base-content) 55%, transparent);
    font-style: italic;
    margin: 0.125rem 0 0 0;
}

/* ─── Owned / Effective tabs ───────────────────────────────────── */

.sb-policy-scope-group-tabs {
    display: flex;
    gap: 0.25rem;
    border-block-end: 1px solid var(--color-base-300);
    margin-block-end: 0.75rem;
}
.sb-policy-scope-group-tab {
    background: transparent;
    border: 0;
    padding: 0.5rem 0.875rem;
    font: 500 0.8125rem/1 ui-sans-serif, system-ui;
    cursor: pointer;
    color: color-mix(in srgb, var(--color-base-content) 55%, transparent);
    border-block-end: 2px solid transparent;
}
.sb-policy-scope-group-tab[aria-selected="true"] {
    color: var(--color-base-content);
    border-block-end-color: var(--color-primary);
}
.sb-policy-scope-group-add {
    display: inline-block;
    margin-block-start: 0.5rem;
    font: 400 0.8125rem/1 ui-sans-serif, system-ui;
    color: var(--color-primary);
    text-decoration: none;
}
.sb-policy-scope-group-add:hover {
    text-decoration: underline;
}
/* Empty state — icon stacked above a bold headline + muted help line.
   Used by both the Owned panel ("no rules at this scope") and the
   Effective panel ("no rules fire here"); the partials supply the icon
   class + the two text strings. */
.sb-policy-scope-group-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.25rem;
    padding: 1.25rem 0.5rem;
    color: color-mix(in srgb, var(--color-base-content) 60%, transparent);
}
.sb-policy-scope-group-empty-icon {
    font-size: 1.5rem;
    color: color-mix(in srgb, var(--color-base-content) 35%, transparent);
    margin-block-end: 0.125rem;
}
.sb-policy-scope-group-empty-head {
    font: 600 0.875rem/1.3 ui-sans-serif, system-ui;
    color: color-mix(in srgb, var(--color-base-content) 75%, transparent);
    margin: 0;
}
.sb-policy-scope-group-empty-help {
    font: 400 0.8125rem/1.4 ui-sans-serif, system-ui;
    color: color-mix(in srgb, var(--color-base-content) 55%, transparent);
    margin: 0;
}
.sb-policy-scope-group-empty-help strong {
    color: color-mix(in srgb, var(--color-base-content) 75%, transparent);
    font-weight: 600;
}

/* ─── Effective panel — inherited / shadowed / unreachable ─────── */

.sb-effective-row[data-inherited="true"] .sb-policy-card {
    border-left: 3px solid var(--color-info);
}
.sb-effective-row[data-shadowed="true"] .sb-policy-card {
    opacity: 0.55;
}
.sb-effective-row[data-unreachable="true"] .sb-policy-card {
    opacity: 0.4;
    border-style: dashed;
}
.sb-effective-inherited {
    font: 400 0.75rem/1.2 ui-sans-serif, system-ui;
    color: color-mix(in srgb, var(--color-base-content) 50%, transparent);
    margin: -0.25rem 0 0.5rem 1rem;
}
.sb-effective-inherited code {
    background: transparent;
    padding: 0;
    font: inherit;
}
.sb-effective-annotations {
    list-style: none;
    padding: 0;
    margin: 1rem 0;
    font-size: 0.8125rem;
    color: color-mix(in srgb, var(--color-base-content) 60%, transparent);
}
.sb-effective-annotation {
    padding: 0.25rem 0;
}

/* Legacy classes from the deleted pill design intentionally NOT defined here.
   .badge.source-pill / .badge.mode-pill / .verdict — REMOVED 2026-06-24. */

/* ─── B8: card-shaped inline expand surface ────────────────────── */

/* Editing-state visual: keep the band 1 / 2 / 3 chrome from the compact
   card and just highlight the border so the operator knows which card is
   in edit mode. */
.sb-policy-card-editing {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-primary) 15%, transparent);
}
.sb-policy-card-editing:hover {
    transform: none;
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-primary) 15%, transparent);
}

.sb-policy-card-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}
.sb-policy-card-save {
    background: var(--color-primary);
    color: white;
    border: 0;
    padding: 0.375rem 0.875rem;
    border-radius: 0.25rem;
    cursor: pointer;
    font: 600 0.8125rem/1.2 ui-sans-serif, system-ui;
}
.sb-policy-card-save:hover {
    background: color-mix(in srgb, var(--color-primary) 9%, transparent);
}
.sb-policy-card-cancel {
    background: transparent;
    color: color-mix(in srgb, var(--color-base-content) 7%, transparent);
    border: 1px solid var(--color-base-300);
    padding: 0.375rem 0.875rem;
    border-radius: 0.25rem;
    cursor: pointer;
    font: 400 0.8125rem/1.2 ui-sans-serif, system-ui;
}
.sb-policy-card-cancel:hover {
    color: var(--color-base-content);
    border-color: color-mix(in srgb, var(--color-base-content) 40%, transparent);
}

.sb-policy-card-expand-body {
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.sb-policy-card-if-builder {
    border: 1px solid var(--color-base-300);
    border-radius: 0.375rem;
    padding: 0.625rem 0.875rem;
}
.sb-policy-card-if-builder legend {
    font: 600 0.6875rem/1.2 ui-sans-serif, system-ui;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: color-mix(in srgb, var(--color-base-content) 60%, transparent);
    padding: 0 0.5rem;
}
.sb-policy-card-keyword {
    color: var(--color-primary);
}

/* Facet picker rows. The picker is render-only in B8 (the textarea is the
   source of truth) so all inputs render disabled. The visual still groups
   the facet / op / value triple as a row. */
.sb-facet-picker {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}
.sb-facet-picker-empty {
    margin: 0.25rem 0;
    font-size: 0.8125rem;
    color: color-mix(in srgb, var(--color-base-content) 50%, transparent);
}
.sb-facet-picker-row {
    display: grid;
    grid-template-columns: minmax(8rem, 1fr) auto minmax(8rem, 2fr) auto;
    gap: 0.5rem;
    align-items: center;
    padding: 0.25rem 0;
}
.sb-facet-picker-row select,
.sb-facet-picker-row input[type="text"],
.sb-facet-picker-row input[type="number"] {
    padding: 0.25rem 0.375rem;
    border: 1px solid var(--color-base-300);
    border-radius: 0.25rem;
    background: var(--color-base-100);
    color: var(--color-base-content);
    font: 400 0.8125rem/1.2 ui-sans-serif, system-ui;
    min-width: 0;
}
.sb-facet-picker-row select:disabled,
.sb-facet-picker-row input:disabled {
    opacity: 0.7;
    cursor: not-allowed;
}
.sb-facet-picker-value {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    min-width: 0;
}
.sb-facet-picker-glob-input {
    flex: 1 1 auto;
    font-family: ui-monospace, monospace;
}
.sb-facet-picker-glob-hint {
    font-size: 0.6875rem;
    color: color-mix(in srgb, var(--color-base-content) 50%, transparent);
    white-space: nowrap;
}
/* CIDR input -- one text field + help line + inline error span. Same
   row layout as the glob input so the cidr branch reuses the value
   cell's flex gap without reflowing the picker grid. */
.sb-facet-picker-cidr {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.375rem;
    flex: 1 1 auto;
    min-width: 0;
}
.sb-facet-picker-cidr-input {
    flex: 1 1 auto;
    font-family: ui-monospace, monospace;
}
.sb-facet-picker-cidr-input[aria-invalid="true"] {
    border-color: var(--color-error);
    outline-color: var(--color-error);
}
.sb-facet-picker-cidr-hint {
    font-size: 0.6875rem;
    color: color-mix(in srgb, var(--color-base-content) 50%, transparent);
    white-space: nowrap;
}
.sb-facet-picker-cidr-error {
    font-size: 0.6875rem;
    color: var(--color-error);
    white-space: nowrap;
    flex-basis: 100%;
}
.sb-facet-picker-help {
    grid-column: 1 / -1;
    margin: 0.125rem 0 0 0;
    font-size: 0.75rem;
    line-height: 1.35;
    color: color-mix(in srgb, var(--color-base-content) 60%, transparent);
    font-style: italic;
}
.sb-facet-picker-remove {
    background: transparent;
    color: color-mix(in srgb, var(--color-base-content) 40%, transparent);
    border: 0;
    cursor: pointer;
    padding: 0 0.5rem;
    font-size: 1.125rem;
    line-height: 1;
}
.sb-facet-picker-remove:hover:not(:disabled) {
    color: var(--color-error);
}
.sb-facet-picker-remove:disabled {
    cursor: not-allowed;
}

.sb-facet-picker-actions {
    margin-top: 0.5rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.sb-facet-picker-add {
    background: transparent;
    color: var(--color-primary);
    border: 1px dashed color-mix(in srgb, var(--color-primary) 40%, transparent);
    border-radius: 0.25rem;
    padding: 0.25rem 0.5rem;
    cursor: pointer;
    font: 500 0.8125rem/1.2 ui-sans-serif, system-ui;
}
.sb-facet-picker-add:disabled {
    cursor: not-allowed;
    opacity: 0.55;
}
.sb-facet-picker-hint {
    font-size: 0.6875rem;
    color: color-mix(in srgb, var(--color-base-content) 50%, transparent);
}

/* The wrapping div around the embedded _EditRow partial. The header's
   "Save" button submits the inner form via form="@formId"; nothing extra
   is needed here, but we strip the editor's own duplicated header/save
   button background so the article reads as a single card surface. */
.sb-policy-card-expand-editor {
    display: contents;
}
.sb-policy-card-expand-editor .sb-policy-stack-edit-row {
    border: 0;
    padding: 0;
    background: transparent;
}

/* Hysteresis disclosure. Same chrome style as the other <details>
   disclosures on the card; the grid pairs sustain + recover. */
.sb-policy-card-hysteresis summary,
.sb-policy-card-auto-promote-note {
    font: 400 0.75rem/1.4 ui-sans-serif, system-ui;
    color: color-mix(in srgb, var(--color-base-content) 7%, transparent);
    cursor: pointer;
}
.sb-policy-card-hysteresis[open] summary {
    margin-block-end: 0.5rem;
}
.sb-policy-card-hysteresis-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem;
}
.sb-policy-card-hysteresis-grid label {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.75rem;
    color: color-mix(in srgb, var(--color-base-content) 75%, transparent);
}
.sb-policy-card-hysteresis-grid input[type="number"] {
    padding: 0.25rem 0.375rem;
    border: 1px solid var(--color-base-300);
    border-radius: 0.25rem;
    background: var(--color-base-100);
    color: var(--color-base-content);
    font: 400 0.8125rem/1.2 ui-sans-serif, system-ui;
    max-width: 8rem;
}
.sb-policy-card-hysteresis-help {
    margin: 0.5rem 0 0 0;
    font-size: 0.6875rem;
    line-height: 1.4;
    color: color-mix(in srgb, var(--color-base-content) 55%, transparent);
}
.sb-policy-card-hysteresis-help em {
    font-style: normal;
    font-weight: 600;
    color: color-mix(in srgb, var(--color-base-content) 75%, transparent);
}
.sb-policy-card-auto-promote-note {
    margin: 0;
    font-style: italic;
    color: color-mix(in srgb, var(--color-base-content) 60%, transparent);
}

.sb-policy-card { position: relative; }
.sb-policy-card-intent {
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 4px;
    background: color-mix(in srgb, var(--color-base-content) 12%, transparent);
    border-top-left-radius: 8px;
    border-bottom-left-radius: 8px;
}
.sb-policy-card[data-intent="block"]     .sb-policy-card-intent { background: var(--color-error); }
.sb-policy-card[data-intent="challenge"] .sb-policy-card-intent { background: var(--color-warning); }
.sb-policy-card[data-intent="throttle"]  .sb-policy-card-intent { background: color-mix(in srgb, var(--color-warning) 70%, var(--color-base-100)); }
.sb-policy-card[data-intent="allow"]     .sb-policy-card-intent { background: var(--color-success); }
.sb-policy-card[data-intent="tag"]       .sb-policy-card-intent { background: color-mix(in srgb, var(--color-base-content) 40%, transparent); }
.sb-policy-card[data-intent="observe"]   .sb-policy-card-intent { background: var(--color-info); }
.sb-policy-card[data-intent="lockdown"]  .sb-policy-card-intent { background: color-mix(in srgb, var(--color-error) 65%, black); }

.sb-action-pill {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 2px 10px; border-radius: 999px;
    font-weight: 600; font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase;
    background: color-mix(in srgb, var(--color-base-content) 8%, transparent);
    color: var(--color-base-content);
}
.sb-action-pill-icon { width: 14px; height: 14px; flex: 0 0 14px; }
.sb-action-pill[data-intent="block"]     { background: color-mix(in srgb, var(--color-error) 18%, transparent);     color: var(--color-error); }
.sb-action-pill[data-intent="challenge"] { background: color-mix(in srgb, var(--color-warning) 18%, transparent);   color: var(--color-warning); }
.sb-action-pill[data-intent="throttle"]  { background: color-mix(in srgb, var(--color-warning) 14%, transparent);   color: var(--color-warning); }
.sb-action-pill[data-intent="allow"]     { background: color-mix(in srgb, var(--color-success) 18%, transparent);   color: var(--color-success); }
.sb-action-pill[data-intent="tag"]       { background: color-mix(in srgb, var(--color-base-content) 14%, transparent); color: var(--color-base-content); }
.sb-action-pill[data-intent="observe"]   { background: color-mix(in srgb, var(--color-info) 18%, transparent);      color: var(--color-info); }
.sb-action-pill[data-intent="lockdown"]  { background: color-mix(in srgb, var(--color-error) 22%, transparent);     color: color-mix(in srgb, var(--color-error) 65%, black); }
.sb-action-pill-detail { margin-left: 8px; color: color-mix(in srgb, var(--color-base-content) 55%, transparent); font-size: 12px; }

.sb-facet-pill {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 3px 9px; border-radius: 999px;
    font-size: 12px; line-height: 1;
    background: color-mix(in srgb, var(--color-base-content) 6%, transparent);
    border: 1px solid color-mix(in srgb, var(--color-base-content) 8%, transparent);
}
.sb-facet-pill .sb-facet-pill-icon { width: 13px; height: 13px; opacity: 0.7; }
.sb-facet-pill-cat  { font-weight: 600; color: var(--color-base-content); }
.sb-facet-pill-op   { color: color-mix(in srgb, var(--color-base-content) 55%, transparent); }
.sb-facet-pill-val  { color: var(--color-base-content); font-family: ui-monospace, SFMono-Regular, monospace; font-size: 11px; }
.sb-facet-pill[data-uncatalogued="true"] { opacity: 0.7; font-style: italic; }

/* Phase C8: template gallery + intent-coloured template cards. The card
   reuses the same intent-strip vocabulary as the rule card so the
   templates tab feels visually consistent with the owned-rules tab.
   Strip colour is driven entirely off data-intent (no JS), grid is
   responsive auto-fill so 280px is the minimum card width. */
.sb-template-gallery {
    display: grid;
    gap: 16px;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    margin-top: 12px;
}
.sb-template-card {
    position: relative;
    background: var(--color-base-100);
    border: 1px solid color-mix(in srgb, var(--color-base-content) 12%, transparent);
    border-radius: 10px;
    padding: 16px 16px 12px 20px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.sb-template-card-intent {
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 4px;
    border-top-left-radius: 10px;
    border-bottom-left-radius: 10px;
    background: color-mix(in srgb, var(--color-base-content) 14%, transparent);
}
.sb-template-card[data-intent="block"]     .sb-template-card-intent { background: var(--color-error); }
.sb-template-card[data-intent="challenge"] .sb-template-card-intent { background: var(--color-warning); }
.sb-template-card[data-intent="throttle"]  .sb-template-card-intent { background: color-mix(in srgb, var(--color-warning) 70%, var(--color-base-100)); }
.sb-template-card[data-intent="allow"]     .sb-template-card-intent { background: var(--color-success); }
.sb-template-card[data-intent="tag"]       .sb-template-card-intent { background: color-mix(in srgb, var(--color-base-content) 40%, transparent); }
.sb-template-card[data-intent="observe"]   .sb-template-card-intent { background: var(--color-info); }
.sb-template-card[data-intent="lockdown"]  .sb-template-card-intent { background: color-mix(in srgb, var(--color-error) 65%, black); }
.sb-template-card-head {
    display: flex;
    align-items: center;
    gap: 8px;
}
.sb-template-card-title {
    font-size: 15px;
    font-weight: 600;
    margin: 0;
    color: var(--color-base-content);
}
.sb-template-card-desc {
    font-size: 13px;
    line-height: 1.5;
    color: color-mix(in srgb, var(--color-base-content) 75%, transparent);
    margin: 0;
    white-space: pre-line;
}
.sb-template-card-actions {
    display: flex;
    gap: 8px;
    margin-top: 8px;
}
.sb-template-use,
.sb-template-preview {
    border: 1px solid color-mix(in srgb, var(--color-base-content) 18%, transparent);
    background: transparent;
    color: var(--color-base-content);
    padding: 6px 14px;
    border-radius: 6px;
    font-size: 12px;
    cursor: pointer;
}
.sb-template-use {
    background: var(--color-primary);
    color: var(--color-primary-content, white);
    border-color: var(--color-primary);
    font-weight: 600;
}
.sb-template-card-preview:empty { display: none; }

/* C-UX5: named conflict-pair list inside the preview panel. The summary
   keeps the existing one-line "N rule(s) would become shadowed" warn
   text; the disclosure body enumerates each pair so the operator sees
   which template rule shadows which existing rule by priority + action
   + mode instead of having to count the surprise. */
.sb-template-conflict-list { margin: 8px 0; }
.sb-template-conflict-list > summary { cursor: pointer; }
.sb-template-conflict-pairs {
    list-style: none;
    padding: 0;
    margin: 8px 0 0 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.sb-template-conflict-pair {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px 12px;
    background: color-mix(in srgb, var(--color-warning) 8%, transparent);
    border-left: 3px solid var(--color-warning);
    border-radius: 4px;
    font-size: 12px;
}
.sb-template-conflict-arrow {
    text-align: center;
    color: color-mix(in srgb, var(--color-base-content) 50%, transparent);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.sb-template-conflict-template {
    color: color-mix(in srgb, var(--color-error) 65%, black);
    font-weight: 600;
}
.sb-template-conflict-existing {
    color: color-mix(in srgb, var(--color-base-content) 70%, transparent);
}

/* C12 -- zero-rules empty state on the Effective / Stack tabs. The
   container is the muted card; the actions row pairs the primary
   "Browse templates" button (.sb-template-use from C8) with the
   neutral "Start blank" link (.sb-template-preview from C8). */
.sb-policy-empty {
    padding: 24px 16px;
    text-align: center;
    color: color-mix(in srgb, var(--color-base-content) 65%, transparent);
    background: color-mix(in srgb, var(--color-base-200) 50%, transparent);
    border-radius: 8px;
    margin: 12px 0;
}
.sb-policy-empty-actions {
    display: inline-flex;
    gap: 8px;
    margin-top: 12px;
}

/* C15 -- posture summary card replacing the dry "N requests / N rules /
   N triggered" footer. The data-posture attribute drives the left border
   colour (lockdown=primary, strict=error, balanced=warning, permissive=
   muted) so the operator gets a glanceable at-rest read on how much
   enforcement is live at this scope. */
.sb-posture-card {
    background: var(--color-base-100);
    border: 1px solid color-mix(in srgb, var(--color-base-content) 12%, transparent);
    border-radius: 10px;
    padding: 14px 18px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-top: 16px;
}
.sb-posture-card[data-posture="lockdown"]   { border-left: 4px solid color-mix(in srgb, var(--color-error) 65%, black); }
.sb-posture-card[data-posture="strict"]     { border-left: 4px solid var(--color-error); }
.sb-posture-card[data-posture="balanced"]   { border-left: 4px solid var(--color-warning); }
.sb-posture-card[data-posture="permissive"] { border-left: 4px solid color-mix(in srgb, var(--color-base-content) 30%, transparent); }
.sb-posture-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
}
.sb-posture-label {
    color: color-mix(in srgb, var(--color-base-content) 60%, transparent);
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.sb-posture-level {
    font-size: 16px;
}
.sb-posture-stats {
    font-size: 12px;
    color: color-mix(in srgb, var(--color-base-content) 75%, transparent);
    margin: 0;
}
.sb-posture-suggestion {
    font-size: 13px;
    color: var(--color-base-content);
    margin: 4px 0 0 0;
    display: flex;
    align-items: center;
    gap: 10px;
}

/* ─── C-UX2: action radio-card list ───────────────────────────────
   Replaces the bare <select name="action.kind"> in _EditAction.cshtml
   with a visible radio-card list so an operator sees what they're
   choosing BEFORE they commit. Each card is the click target for its
   own radio; the whole row is the <label>, so clicking anywhere on
   the card selects the radio. Keyboard arrow-keys walk through the
   list naturally because the inputs are real radios in a role=radiogroup.

   The data-intent attribute matches the C3/C4 rule-card vocabulary
   (block / allow / challenge / throttle / tag / observe) so the
   coloured stripe on the left of each card reads as a small version
   of the rule-card intent strip and the operator's selection feels
   visually consistent with the rule-card surface they're authoring. */

.sb-action-radio-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-block-end: 12px;
}

.sb-action-radio-card {
    position: relative;
    display: grid;
    grid-template-columns: auto auto 1fr;
    grid-template-areas:
        "icon label   label"
        "icon explain explain";
    column-gap: 12px;
    row-gap: 2px;
    align-items: center;
    padding: 10px 14px 10px 22px;
    border: 1px solid color-mix(in srgb, var(--color-base-content) 12%, transparent);
    border-radius: 8px;
    background: var(--color-base-100);
    cursor: pointer;
    transition: border-color 100ms ease-out, background 100ms ease-out, box-shadow 100ms ease-out;
}
.sb-action-radio-card:hover {
    border-color: color-mix(in srgb, var(--color-base-content) 28%, transparent);
    background: color-mix(in srgb, var(--color-base-200) 35%, var(--color-base-100));
}

/* Left coloured stripe — same intent vocabulary as the rule card so
   the picker reads as "small versions of the thing I'm picking". */
.sb-action-radio-stripe {
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 4px;
    background: color-mix(in srgb, var(--color-base-content) 14%, transparent);
    border-top-left-radius: 8px;
    border-bottom-left-radius: 8px;
}
.sb-action-radio-card[data-intent="block"]     .sb-action-radio-stripe { background: var(--color-error); }
.sb-action-radio-card[data-intent="challenge"] .sb-action-radio-stripe { background: var(--color-warning); }
.sb-action-radio-card[data-intent="throttle"]  .sb-action-radio-stripe { background: color-mix(in srgb, var(--color-warning) 70%, var(--color-base-100)); }
.sb-action-radio-card[data-intent="allow"]     .sb-action-radio-stripe { background: var(--color-success); }
.sb-action-radio-card[data-intent="tag"]       .sb-action-radio-stripe { background: color-mix(in srgb, var(--color-base-content) 40%, transparent); }
.sb-action-radio-card[data-intent="observe"]   .sb-action-radio-stripe { background: var(--color-info); }

/* The actual radio is visually hidden but stays focusable so arrow-key
   navigation across the radiogroup still works. Hiding via opacity/size
   rather than display:none keeps it part of the focus order. */
.sb-action-radio-input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
    margin: 0;
}

.sb-action-radio-icon {
    grid-area: icon;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    color: color-mix(in srgb, var(--color-base-content) 60%, transparent);
}
.sb-action-radio-icon .sb-action-pill-icon {
    width: 18px;
    height: 18px;
}

.sb-action-radio-label {
    grid-area: label;
    font: 600 0.8125rem/1.2 ui-sans-serif, system-ui;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-base-content);
}

.sb-action-radio-explain {
    grid-area: explain;
    font: 400 0.8125rem/1.4 ui-sans-serif, system-ui;
    color: color-mix(in srgb, var(--color-base-content) 65%, transparent);
}

/* Selected-state pop — the card carries the intent colour in its
   border + a soft tinted background so the operator's choice is
   visible at a glance. The icon picks up the same intent colour so
   the head row reads as a single coloured token. */
.sb-action-radio-card:has(.sb-action-radio-input:checked) {
    border-color: color-mix(in srgb, var(--color-base-content) 35%, transparent);
    background: color-mix(in srgb, var(--color-base-200) 60%, var(--color-base-100));
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-base-content) 22%, transparent);
}
.sb-action-radio-card[data-intent="block"]:has(.sb-action-radio-input:checked) {
    border-color: var(--color-error);
    background: color-mix(in srgb, var(--color-error) 8%, var(--color-base-100));
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-error) 35%, transparent);
}
.sb-action-radio-card[data-intent="block"]:has(.sb-action-radio-input:checked) .sb-action-radio-icon { color: var(--color-error); }
.sb-action-radio-card[data-intent="challenge"]:has(.sb-action-radio-input:checked) {
    border-color: var(--color-warning);
    background: color-mix(in srgb, var(--color-warning) 9%, var(--color-base-100));
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-warning) 35%, transparent);
}
.sb-action-radio-card[data-intent="challenge"]:has(.sb-action-radio-input:checked) .sb-action-radio-icon { color: var(--color-warning); }
.sb-action-radio-card[data-intent="throttle"]:has(.sb-action-radio-input:checked) {
    border-color: color-mix(in srgb, var(--color-warning) 75%, var(--color-base-100));
    background: color-mix(in srgb, var(--color-warning) 7%, var(--color-base-100));
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-warning) 30%, transparent);
}
.sb-action-radio-card[data-intent="throttle"]:has(.sb-action-radio-input:checked) .sb-action-radio-icon { color: color-mix(in srgb, var(--color-warning) 80%, var(--color-base-content)); }
.sb-action-radio-card[data-intent="allow"]:has(.sb-action-radio-input:checked) {
    border-color: var(--color-success);
    background: color-mix(in srgb, var(--color-success) 8%, var(--color-base-100));
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-success) 35%, transparent);
}
.sb-action-radio-card[data-intent="allow"]:has(.sb-action-radio-input:checked) .sb-action-radio-icon { color: var(--color-success); }
.sb-action-radio-card[data-intent="observe"]:has(.sb-action-radio-input:checked) {
    border-color: var(--color-info);
    background: color-mix(in srgb, var(--color-info) 8%, var(--color-base-100));
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-info) 35%, transparent);
}
.sb-action-radio-card[data-intent="observe"]:has(.sb-action-radio-input:checked) .sb-action-radio-icon { color: var(--color-info); }
.sb-action-radio-card[data-intent="tag"]:has(.sb-action-radio-input:checked) {
    border-color: color-mix(in srgb, var(--color-base-content) 45%, transparent);
    background: color-mix(in srgb, var(--color-base-content) 5%, var(--color-base-100));
}
.sb-action-radio-card[data-intent="tag"]:has(.sb-action-radio-input:checked) .sb-action-radio-icon { color: color-mix(in srgb, var(--color-base-content) 75%, transparent); }

/* Focus-visible ring on the card when the hidden radio takes focus via
   keyboard navigation. Matches the visual weight of the selected-state
   ring above so keyboard + pointer users get equivalent feedback. */
.sb-action-radio-card:focus-within {
    outline: 2px solid color-mix(in srgb, var(--color-primary) 65%, transparent);
    outline-offset: 1px;
}
