/* Policy UI chrome — context bar, focus rings, and brand sweep helpers.

   This stylesheet supports the look-and-feel recovery (chunk 1b).  It is
   loaded globally from ``base.html`` so HTMX sidebar swaps that drop
   into ``policies`` partials keep the chrome styling.  Tokens are
   declared in ``design-system.css`` (``--color-brand-green*``,
   ``--color-tenant-banner-gradient-*``).
*/

/* =============================================================================
   Policy-surface design tokens.

   Values the canonical policy-2 mockups use that have no exact match in the
   global token set (design-tokens.css). Named once here and referenced below
   rather than inlined as raw hex, so the mockup-alignment decision lives in a
   single, greppable place and stays fenced to the Policy surface. Globally
   tokenized neutrals (``--fg-4``, ``--border-base``, ``--border-medium``,
   ``--status-neutral-bg``) are referenced directly and are NOT re-aliased here.

     - ``--policy-title-fg`` / ``--policy-header-fg``: Tailwind gray-900 / gray-600
       from the mockup ``<h1>`` + ``<th>``. Deliberately distinct from the near
       neighbours ``--fg-1`` (#101828) / ``--fg-3`` (#4a5565) to hold the exact
       mockup pixel value.
     - ``--color-policy-banner-start`` / ``--color-policy-banner-end``: emerald
       gradient stops the policy-2/11 tenant-scope banner uses, overriding the
       global brand-green ``--color-tenant-banner-gradient-*`` on Policy only.
   ============================================================================= */
.policy-page-shell,
body.policy-surface {
    --policy-title-fg: #111827; /* Tailwind gray-900 (mockup <h1>) */
    --policy-header-fg: #4b5563; /* Tailwind gray-600 (mockup <th>) */
    --color-policy-banner-start: #10b981; /* Tailwind emerald-500 */
    --color-policy-banner-end: #059669; /* Tailwind emerald-600 */
}

/* =============================================================================
   Policy page shell — width to match the canonical mockups (policy-2/10,12,13).

   Canonical mockup (policy-2/10) fills the main column beside the 250px
   sidebar — ``max-width: calc(100vw - 250px)`` — not a centred 1280px box.
   Templates use ``policy-page-shell``; this block stretches to the full
   main-column width (``--page-max-width``) with symmetric gutter padding.
   ============================================================================= */
.policy-page-shell {
    /* Match gateways / alerts / cluster-integrity page chrome — full main-column
       width up to --page-max-width, left-aligned (not the legacy 1280px box). */
    max-width: var(--page-max-width);
    margin: 0;
    padding: var(--page-padding);
    width: 100%;
    box-sizing: border-box;
}

/* Bold table column headers + gray-600 text, matching the canonical mockups
   (policy-2/10,12,13 use semibold gray-600 ``<th>``). The template markup
   already sets ``font-semibold text-gray-600``, but the global table reset in
   section-improvements.css
   (``table thead th:not(.table-header-cell) { font-weight: 400 !important;
   color: #6b7280 !important }``) overrides BOTH the weight and the colour —
   forcing weight 400 and gray-500 (#6b7280). Scope a ``600`` weight + gray-600
   (#4b5563) colour override to policy-shell tables only — same "policies.css
   owns its table chrome and out-specifies the global reset" pattern used for the
   row separators below; the ``!important`` is required to beat the
   equally-!important global reset, and stays confined to ``.policy-page-shell``
   so no other surface is affected. */
.policy-page-shell table thead th {
    font-weight: 600 !important;
    color: var(--policy-header-fg) !important;
}

/* =============================================================================
   Policy page title — bold, near-black, 24px, matching the canonical mockups
   (policy-2/10,11,12 set ``patitur-main-page-title text-2xl font-bold
   text-gray-900`` on the ``<h1>``).

   The global house style (design-tokens.css ``h1, .h1, .patitur-main-page-title``
   and patitur-auth.css ``.patitur-main-page-title``) renders titles
   brand-green / weight-500 / 30px — the app-wide standard used by Dashboard,
   compliance, device-detail, etc. The mockup deliberately overrides that on the
   Policy surfaces. Per the 2026-05-25 alignment decision, match the mockup on
   Policy ONLY: scope the override under ``.policy-page-shell`` so no other
   surface changes. Two-class specificity (0,2,0) beats both single-class global
   rules (0,1,0) cleanly — no ``!important`` needed. Values mirror Tailwind
   ``text-2xl`` (24px / line-height 2rem) + ``font-bold`` (700) +
   ``text-gray-900`` (#111827). */
.policy-page-shell .patitur-main-page-title {
    color: var(--policy-title-fg);
    font-weight: 700;
    font-size: 24px;
    line-height: 2rem;
}

/* =============================================================================
   Policy tab bar — active-state colours (E1 chrome).

   The active tab reads green: green label, green icon, and a 2px green
   underline, with a soft-green count pill (light-green bg, deep-green text) —
   matching the canonical mockup (mockup-common.css .tab-item.active /
   .tab-item.active .count, policy-2/10).

   These colours MUST live here, not as inline Tailwind ``text-[var(...)]``
   utilities: arbitrary-value classes referencing CSS variables are not emitted
   by the build, so an inline ``text-[var(--color-brand-green)]`` produces no
   rule and the global ``a { color: inherit }`` (current_user_main.css) wins,
   painting the active tab slate-gray.  A real ``.policy-tab`` rule (class
   specificity, loaded after current_user_main.css) wins cleanly with no
   ``!important``.  Neutral tokens (``--fg-4``, ``--border-medium``,
   ``--status-neutral-bg``) come from design-tokens.css; the hover-text
   ``--policy-title-fg`` is the Policy gray-900 declared at the top of this file.
   ============================================================================= */
.policy-tab {
    color: var(--fg-4);
    border-bottom-color: transparent;
    text-decoration: none;
}

.policy-tab:hover {
    color: var(--policy-title-fg);
    border-bottom-color: var(--border-medium);
}

.policy-tab--active,
.policy-tab--active:hover {
    color: var(--color-brand-green);
    border-bottom-color: var(--color-brand-green);
}

.policy-tab--active i {
    color: var(--color-brand-green);
}

.policy-tab-count {
    background: var(--status-neutral-bg);
    color: var(--fg-4);
}

.policy-tab-count--active {
    background: var(--color-brand-green-light);
    color: var(--color-brand-green-deep);
}

/* =============================================================================
   C7 — Org context bar.  Dark gradient strip rendered above the tab nav on
   org-scoped policy pages.  Uses the same gradient family as the tenant
   scope banner so the two bars read as a system; the org variant is the
   inverse-gradient (brand-green → deep-green) so it never collides with
   the tenant banner above it.
   ============================================================================= */
.policies-context-bar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
    padding: 0.5rem 1rem;
    margin-bottom: 1rem;
    border-radius: 6px;
    color: #ffffff;
    font-size: 0.8125rem;
    font-weight: 500;
    /* Dark navy gradient matching the canonical org-admin mockup (10-org-admin-view.html) —
       distinct from the brand-green tenant-scope-banner that appears on tenant-scoped pages. */
    background: linear-gradient(135deg, #1e2939 0%, #2d3d50 100%);
    border: 1px solid rgba(255, 255, 255, 0.08);
}

.policies-context-bar-name {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    font-weight: 600;
}

/* Pill-style chip for tenant count (and future: industry). Mirrors the
   .context-pill used in the mockup shell. */
.policies-context-bar-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.12);
    padding: 0.25rem 0.625rem;
    border-radius: 9999px;
    font-size: 0.75rem;
    font-weight: 500;
}

/* "Viewing as Org Admin" — right-aligned label. Uses margin-left: auto to push
   it to the end of the flex row without absolute positioning. */
.policies-context-bar-role {
    margin-left: auto;
    font-size: 0.6875rem;
    opacity: 0.6;
}

.policies-context-bar-role strong {
    opacity: 1;
    color: rgba(255, 255, 255, 0.85);
}

/* =============================================================================
   Tenant-scope banner — Policy-surface gradient override.

   The shared ``.tenant-scope-banner`` (navigation.css) renders on every
   tenant-scoped view with the brand-green gradient
   (``--color-tenant-banner-gradient-start/end``: deep-pine → brand-green).
   The canonical mockup (policy-2/11) uses Tailwind ``emerald`` stops
   (#10b981 → #059669) for this banner. Per the 2026-05-25 alignment decision,
   match the mockup on Policy surfaces ONLY.

   The banner renders in base.html ABOVE ``.policy-page-shell`` (flush to the top
   of ``#content``), so it is NOT a descendant of the shell — a
   ``.policy-page-shell`` selector cannot reach it. Scope instead via the
   ``policy-surface`` body class added by policies/_page_chrome.html, which IS an
   ancestor of the banner. Body-class + single-class specificity (0,2,0) beats the
   single-class global rule (0,1,0); no ``!important`` needed. */
body.policy-surface .tenant-scope-banner {
    background: linear-gradient(
        90deg,
        var(--color-policy-banner-start) 0%,
        var(--color-policy-banner-end) 100%
    );
}

/* =============================================================================
   Signal chips — small inline indicators used in the signals legend strip and
   the Divergence column on the Org Policy table.  Amber palette per the
   canonical mockup (10-org-admin-view.html); kept off-Tailwind so the regression
   guard against chrome-blue cannot mistake them for primary chrome.
   ============================================================================= */
.signal-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 10px;
    font-weight: 600;
    padding: 2px 6px;
    border-radius: 9999px;
    letter-spacing: 0.02em;
    white-space: nowrap;
}

.signal-chip i {
    font-size: 9px;
}

.chip-divergence {
    background: #fef3c7;
    color: #92400e;
    border: 1px solid #fde68a;
}

.chip-inherit {
    background: #f3f4f6;
    color: #6b7280;
    border: 1px solid #e5e7eb;
}

/* Industry chip on the Tenants tab (T5).  Neutral-gray, slightly lighter
   weight than the signal chips above — it carries a categorization, not a
   divergence/inherit signal.  Values from the chunk-2b mockup
   (memory-bank/.../policy-2/12-org-tenants-tab.html). */
.chip-inherited {
    background: var(--status-neutral-bg);
    color: var(--policy-header-fg);
    border: 1px solid var(--border-base);
    font-weight: 500;
}

.chip-inherited i {
    font-size: 8px;
    opacity: 0.6;
}

/* =============================================================================
   Rule rows on the Org Policy table.  Default rows carry a transparent left
   border to reserve the gutter; rows that have at least one diverging tenant
   light up the gutter in brand green with a faint tint behind the cells (O8).

   We own the inter-row separator here as `border-bottom` on every row
   rather than via Tailwind's `divide-y divide-gray-100` on the parent
   <tbody>.  The divide-utility selector (`.divide-gray-100 > :not([hidden])
   ~ :not([hidden])`) has higher specificity than `.rule-row.tenant-override`
   thanks to the two `:not([hidden])` attribute selectors, so its four-side
   `border-color: gray-100` shorthand previously won the cascade for our
   left side and rendered the override gutter as gray-100.  Owning the
   separator on `.rule-row` directly eliminates the foreign-specificity
   rule rather than trying to out-specify it.
   ============================================================================= */
.rule-row {
    border-left: 3px solid transparent;
    border-bottom: 1px solid rgb(243, 244, 246);
}

.rule-row:last-child {
    border-bottom: 0;
}

.rule-row.tenant-override {
    border-left-color: var(--color-brand-green);
    background: rgba(37, 175, 136, 0.05);
}

/* =============================================================================
   Tenant rows on the canonical Tenants table (Tillamook, chunk 2b).  Same
   own-the-separator pattern as .rule-row above — DO NOT add `divide-y
   divide-gray-100` to the <tbody> hosting these rows; the cascade collision
   documented above also applies here.

   The left-border tint is AMBER, not brand-green.  This is intentional:
   on the Tenants tab the gutter signals "this tenant overrides at least
   one rule" — a tenant-customization signal — whereas the Org Policy
   tab's brand-green gutter on .rule-row.tenant-override signals
   "tenants diverge from this rule".  Different signal, different colour.
   ============================================================================= */
.tenant-row {
    border-left: 3px solid transparent;
    border-bottom: 1px solid rgb(243, 244, 246);
}

.tenant-row:hover {
    background: rgb(249, 250, 251);
}

.tenant-row:last-child {
    border-bottom: 0;
}

.tenant-row.has-customization {
    border-left-color: rgb(245, 158, 11);
}

/* Mini progress bar — used in the Customized Rules cell on the Tenants tab.
   Amber gradient so the bar visually matches the .tenant-row left-border. */
.mini-bar {
    height: 6px;
    border-radius: 3px;
    background: rgb(243, 244, 246);
    overflow: hidden;
}

.mini-bar-fill {
    height: 100%;
    background: linear-gradient(90deg, rgb(245, 158, 11), rgb(251, 191, 36));
    border-radius: 3px;
}

/* =============================================================================
   .btn-neutral — white-background neutral action button (Tillamook chunk 2b).
   First used on the Tenants table's Open button per canonical mockup
   12-org-tenants-tab.html; sourced from
   memory-bank/tasks/feature-v0.8.0-stage-1/policy-2/mockup-common.css.
   Lives in policies.css because it is currently policy-scoped; promote to
   design-system.css when a non-policy surface adopts it.
   ============================================================================= */
.btn-neutral {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    border-radius: 12px;
    background: rgb(255, 255, 255);
    border: 1px solid rgb(209, 213, 219);
    color: rgb(55, 65, 81);
    padding: 6px 12px;
    font-size: 12px;
    line-height: 20px;
    font-weight: 500;
    box-shadow: 0 1px 0.5px 0.05px rgba(29, 41, 61, 0.02);
    cursor: pointer;
    text-decoration: none;
    transition: background-color 0.15s ease;
}

.btn-neutral:hover {
    background: rgb(229, 231, 235);
    color: rgb(55, 65, 81);
}

.btn-neutral[aria-disabled="true"],
.btn-neutral.is-disabled {
    color: rgb(156, 163, 175);
    cursor: not-allowed;
    opacity: 0.6;
}

/* =============================================================================
   .btn-reset-amber — amber-filled Reset action button (Stannard Rock chunk 3b,
   E11). Used in the Edit modal footer when the current level carries any
   override; HTMX-GETs the existing reset-confirm route so chunk 3c can
   rebuild the modal body without coupling to this button.

   Filled amber (#d97706 → amber-600 background, white text) per the
   canonical mockup (10-org-admin-view.html / 11-tenant-admin-view.html
   "Reset" CTA) and per confirm-modals.md § R4. Distinct from the
   destructive-red CTA family because Reset is recoverable: it restores
   inheritance, not data deletion.
   ============================================================================= */
.btn-reset-amber {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    border-radius: 12px;
    background: rgb(217, 119, 6);
    border: 1px solid rgb(180, 83, 9);
    color: rgb(255, 255, 255);
    padding: 6px 12px;
    font-size: 12px;
    line-height: 20px;
    font-weight: 500;
    box-shadow: 0 1px 0.5px 0.05px rgba(29, 41, 61, 0.02);
    cursor: pointer;
    text-decoration: none;
    transition: background-color 0.15s ease;
}

.btn-reset-amber:hover {
    background: rgb(180, 83, 9);
}

.btn-reset-amber:focus-visible {
    outline: 2px solid rgb(217, 119, 6);
    outline-offset: 1px;
}

/* =============================================================================
   .btn-save-green — brand-green-filled Save CTA for the Edit-modal footer.

   The modal body is HTMX-swapped in after page load, but Tailwind ships here
   via the CDN JIT runtime (base.html: cdn.tailwindcss.com), which only scans
   the DOM present at load. Arbitrary utilities that appear ONLY inside the
   HTMX-loaded partial — e.g. ``bg-[var(--color-brand-green)]`` — never get a
   generated rule, so the Save button rendered with a transparent background +
   white text (invisible on the white card). A real precompiled class sidesteps
   the JIT-timing trap, exactly as the sibling ``.btn-reset-amber`` does.
   ============================================================================= */
.btn-save-green {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    border-radius: 8px;
    background: var(--color-brand-green);
    color: rgb(255, 255, 255);
    padding: 8px 16px;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: background-color 0.15s ease;
}

.btn-save-green:hover {
    background: var(--color-brand-green-hover);
}

.btn-save-green:focus-visible {
    outline: none;
    box-shadow:
        0 0 0 2px #fff,
        0 0 0 4px var(--color-brand-green);
}

.btn-save-green:disabled,
.btn-save-green[aria-disabled="true"] {
    opacity: 0.5;
    cursor: not-allowed;
}

/* ---------------------------------------------------------------
   Compare tab — parameter x tenant matrix (chunk 2c, Wolf Rock).

   The .cell-stricter / .cell-looser classes own a top + bottom 1px
   border *plus* a coloured background.  When the surrounding <tbody>
   uses Tailwind's `divide-y divide-gray-100` utility, the generated
   `.divide-gray-100 > :not([hidden]) ~ :not([hidden])` selector
   (specificity 0,3,0) emits a four-side `border-color` shorthand that
   clobbers our 0,1,0 cell border longhands — the same trap Fastnet
   surfaced for `.rule-row.tenant-override`.  We therefore own the
   inter-row separator on `.matrix-row` directly and DO NOT add
   `divide-y` to the matrix's <tbody>.

   Cell colours come straight from the canonical mockup (see
   `memory-bank/tasks/feature-v0.8.0-stage-1/policy-2/13-cross-tenant-compare.html`):
     stricter — green-50 bg / green-700 text / green-200 borders
     looser   — orange-50 bg / orange-700 text / orange-200 borders
     inherit  — gray-300 em-dash, no bg

   Sticky parameter column + fixed table layout mirror the mockup so
   tenant columns are uniform width regardless of cell content.
   --------------------------------------------------------------- */
.matrix-table {
    table-layout: fixed;
}
/* The global `table tbody td { background: transparent !important }` rule
   in section-improvements.css clobbers any non-!important cell background.
   We win with a more specific selector plus !important so the SYSTEM /
   ORG baseline columns render their neutral-gray / light-blue fills.
   The .cell-stricter / .cell-looser rules below would normally need the
   same treatment, but their high-saturation backgrounds win on chunk-2c
   smoke regardless — probably because the cell's data-direction selectors
   or inline span anchors visually mask the override.  Belt-and-suspenders:
   apply !important here so the baseline columns are pixel-stable across
   future CSS load-order shuffles. */
.matrix-table tbody td.matrix-baseline {
    width: 100px;
    background: #f9fafb !important;
}
.matrix-table tbody td.matrix-baseline-org {
    width: 100px;
    background: #eff6ff !important;
}
.matrix-table thead th.matrix-baseline,
.matrix-table thead th.matrix-baseline-org {
    width: 100px;
}
.matrix-table thead th.matrix-baseline {
    background: #f9fafb;
}
.matrix-table thead th.matrix-baseline-org {
    background: #eff6ff;
}
.matrix-table th.sticky-col,
.matrix-table td.sticky-col {
    position: sticky;
    left: 0;
    z-index: 5;
    background: #ffffff;
    border-right: 1px solid #e5e7eb;
    width: 230px;
}
.matrix-table thead th.sticky-col {
    background: #f9fafb;
}
.matrix-table tbody tr:hover td.matrix-baseline {
    background: #f3f4f6 !important;
}
.matrix-table tbody tr:hover td.sticky-col {
    background: #fafbfc;
}

.tenant-head {
    width: 130px;
}
.tenant-head.no-override {
    opacity: 0.65;
}

.matrix-row {
    border-bottom: 1px solid rgb(243, 244, 246);
}
.matrix-row:last-child {
    border-bottom: 0;
}

/* Cell-treatment classes — same global !important wallpaper as
   .matrix-baseline above (section-improvements.css's
   `table tbody td { background: transparent !important; color: #333 !important }`
   beats raw `.cell-stricter` rules).  We win with
   `.matrix-table tbody td.cell-*` specificity (0,2,2 with the tag) plus
   !important.  Standalone `.cell-stricter` / `.cell-looser` /
   .cell-inherit rules below cover the legend swatches, which live
   outside any <table> and therefore aren't subject to the wallpaper. */
.matrix-table tbody td.cell-stricter {
    background: #f0fdf4 !important;
    color: #15803d !important;
    font-weight: 600;
    border-top: 1px solid #bbf7d0;
    border-bottom: 1px solid #bbf7d0;
}
.matrix-table tbody td.cell-looser {
    background: #fff7ed !important;
    color: #c2410c !important;
    font-weight: 600;
    border-top: 1px solid #fed7aa;
    border-bottom: 1px solid #fed7aa;
}
.matrix-table tbody td.cell-inherit {
    color: #d1d5db !important;
    font-size: 14px;
}
.cell-stricter {
    background: #f0fdf4;
    color: #15803d;
    font-weight: 600;
    border-top: 1px solid #bbf7d0;
    border-bottom: 1px solid #bbf7d0;
}
.cell-looser {
    background: #fff7ed;
    color: #c2410c;
    font-weight: 600;
    border-top: 1px solid #fed7aa;
    border-bottom: 1px solid #fed7aa;
}
.cell-inherit {
    color: #d1d5db;
    font-size: 14px;
}

/* ---------------------------------------------------------------
   Divergence-panel direction chips (Cordouan chunk 3a, V11).

   .chip-stricter / .chip-looser share their colour family verbatim
   with .cell-stricter / .cell-looser (Wolf Rock 2c) — the
   legend-as-preview-of-the-matrix contract.  They differ only in
   shape: pill, smaller padding, optional icon slot.

   Cross-surface canonical pair:
       Looser  = orange
       Stricter = green

   Established by Wolf Rock 2c (Compare-tab cells) and confirmed by
   Cordouan 3a (View modal divergence panel + per-tenant pills).
   Future divergence-rendering surfaces follow this pair.

   No `!important` doubled-selector needed — these chips never
   render inside a `<td>`, so the `section-improvements.css:222`
   global `table tbody td { background: transparent !important; }`
   rule cannot reach them.
   --------------------------------------------------------------- */
.chip-stricter {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: 9999px;
    background: #dcfce7;
    color: #15803d;
    border: 1px solid #bbf7d0;
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
}

.chip-looser {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: 9999px;
    background: #ffedd5;
    color: #c2410c;
    border: 1px solid #fed7aa;
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
}

/* ---------------------------------------------------------------
   View modal — source-badge family (Cordouan chunk 3a, V4).

   The canonical mockup (11-tenant-admin-view.html view-504) uses
   .source-badge .source-{system|org|tenant} for the
   "Currently: {source}" header pill.  Colour family matches the
   3-source provenance pills (gray / blue / green per Ar-Men 2d's
   100-shade lift) so the modal header reads as the same semantic
   surface as the cascade table's effective-source labels below.
   Pill shape — wider letter-spacing per mockup-common.css:73-76
   (10px font, 0.03em tracking) — distinguishes it visually from
   the per-row provenance pills.
   --------------------------------------------------------------- */
.source-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
    border-radius: 9999px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.03em;
    white-space: nowrap;
    text-transform: none;
    border: 1px solid transparent;
}

.source-badge.source-system {
    background: #f3f4f6;
    color: #1f2937;
    border-color: #e5e7eb;
}

.source-badge.source-org {
    background: #dbeafe;
    color: #1e40af;
    border-color: #bfdbfe;
}

.source-badge.source-tenant {
    background: #dcfce7;
    color: #14532d;
    border-color: #bbf7d0;
}

/* ---------------------------------------------------------------
   View modal — cascade table cell treatments (Cordouan chunk 3a,
   V5/V6/V7).

   The `.cascade-table` class hosts the doubled-selector pattern
   Wolf Rock 2c established for the Compare matrix.  `section-
   improvements.css:222` declares a global

       table tbody td { background: transparent !important; }

   which would otherwise clobber `.diff-changed` and `.effective-cell`
   backgrounds applied directly to a `<td>`.  We win by being more
   specific AND carrying `!important` ourselves — `.cascade-table
   tbody td.diff-changed { ... !important }`.  Standalone `.diff-
   changed` / `.effective-cell` rules (no `!important`) cover legend
   swatches or any non-table consumer that may emerge later.

   Colour values come straight from `mockup-common.css:95-96` —
   `.diff-changed = #fefce8` (yellow-50, NOT amber) and
   `.effective-cell = #f0fdf4` (green-50).  The plan doc named amber-50;
   the mockup is the source of truth per the orchestrator's tie-breaker
   (Wolf Rock / Ar-Men precedent), so we follow the mockup.
   --------------------------------------------------------------- */
.cascade-table tbody td.diff-changed {
    background: #fefce8 !important;
}

.cascade-table tbody td.effective-cell {
    background: #f0fdf4 !important;
}

.diff-changed {
    background: #fefce8;
}

.effective-cell {
    background: #f0fdf4;
}

/* =============================================================================
   Edit-modal per-card chrome (Stannard Rock chunk 3b, E2-E5).

   The four editor-field templates (input, toggle, slider, readonly) wrap
   their content in `.editor-card` so the override-customized variants
   (`.editor-card--customized-org`, `.editor-card--customized-tenant`)
   can paint the canonical blue/green border + light tint without the
   templates each owning their own border rule. The base `.editor-card`
   carries the gutter-reserving transparent border so toggling between
   states does not reflow the card (same own-the-state lesson as
   `.tenant-row` / Tillamook's Trap-4).

   The `.advanced-pill`, `.sensitivity-chip`, and `.override-chip` family
   are the per-card metadata chips rendered by `_editor_field_header.html`.
   They sit next to the label, not inside `<td>` elements, so no
   doubled-selector / !important plumbing is needed.
   ============================================================================= */
.editor-card,
.editor-card.field-group {
    border: 1px solid rgb(229, 231, 235);
    border-radius: 8px;
    padding: 16px;
    transition:
        background-color 0.15s ease,
        border-color 0.15s ease;
}

.editor-card--customized-org {
    border-width: 2px;
    border-color: rgb(147, 197, 253);
    background: rgba(239, 246, 255, 0.5);
}

.editor-card--customized-tenant {
    border-width: 2px;
    border-color: rgb(134, 239, 172);
    background: rgba(240, 253, 244, 0.6);
}

/* =============================================================================
   Policy modals — shell tightening + self-contained chrome.

   The global modal shell (base.html) pads the card (p-6) and caps width at
   max-w-5xl. Policy Edit/View templates ship their own breadcrumb, title,
   close X, and footer — so we strip the shell header, zero the card padding,
   and size the outer wrapper per variant. Content templates own px-6 py-5.

   Browser compatibility: the :has() pseudo-class is used to detect which
   modal variant is open.  Baseline support: Chrome 105+, Safari 15.4+,
   Firefox 121+.  This is an authenticated internal tool with a documented
   minimum browser requirement (see docs/configuration/configuration-reference.md).
   On older browsers the modal header remains visible and padding is not
   adjusted — degraded but not broken UX.  The @supports guard below
   keeps the layout intact on unsupported browsers rather than silently
   misapplying partial styles.
   ============================================================================= */

/* Fallback (no :has() support): keep modal shell intact — header stays
   visible, card padding unchanged.  No explicit rule needed; the default
   Flowbite shell already applies correct padding. */

@supports selector(:has(*)) {
    #modal-placeholder:has(#main-modal-content .policy-editor-modal)
        #modal-header-bar,
    #modal-placeholder:has(#main-modal-content .policy-view-modal)
        #modal-header-bar {
        display: none;
    }

    #modal-placeholder:has(#main-modal-content .policy-editor-modal)
        > .relative.p-4,
    #modal-placeholder:has(#main-modal-content .policy-view-modal)
        > .relative.p-4 {
        max-width: none;
        padding: 1rem;
    }

    #modal-placeholder:has(#main-modal-content .policy-editor-modal)
        > .relative.p-4 {
        width: 100%;
        max-width: 42rem; /* Tailwind max-w-2xl — edit mockup width */
    }

    #modal-placeholder:has(#main-modal-content .policy-view-modal)
        > .relative.p-4 {
        width: 100%;
        max-width: 64rem; /* Tailwind max-w-5xl — org view mockup width */
    }

    #modal-placeholder:has(#main-modal-content .policy-view-modal--tenant)
        > .relative.p-4 {
        max-width: 56rem; /* Tailwind max-w-4xl — tenant view mockup width */
    }

    #modal-placeholder:has(#main-modal-content .policy-editor-modal)
        > .relative.p-4
        > .relative.bg-white,
    #modal-placeholder:has(#main-modal-content .policy-view-modal)
        > .relative.p-4
        > .relative.bg-white {
        padding: 0;
        gap: 0;
        align-items: stretch;
        max-width: none;
        width: 100%;
    }
}

.policy-editor-modal,
.policy-view-modal {
    width: 100%;
}

/* HTMX save spinner — hidden until the Save POST is in flight. */
.policy-editor-modal #editor-save-spinner {
    display: none;
}

.policy-editor-modal #editor-save-spinner.htmx-request {
    display: inline-flex;
}

.advanced-pill {
    display: inline-flex;
    align-items: center;
    padding: 1px 6px;
    border-radius: 9999px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: rgb(75, 85, 99);
    background: rgb(243, 244, 246);
    border: 1px solid rgb(229, 231, 235);
}

.sensitivity-chip {
    display: inline-flex;
    align-items: center;
    padding: 1px 6px;
    border-radius: 9999px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: rgb(180, 83, 9);
    background: rgb(254, 243, 199);
    border: 1px solid rgb(253, 230, 138);
    white-space: nowrap;
}

.override-chip {
    display: inline-flex;
    align-items: center;
    padding: 1px 6px;
    border-radius: 9999px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.02em;
    white-space: nowrap;
}

.override-chip--org {
    color: rgb(30, 64, 175);
    background: rgb(219, 234, 254);
    border: 1px solid rgb(191, 219, 254);
}

.override-chip--tenant {
    color: rgb(22, 101, 52);
    background: rgb(220, 252, 231);
    border: 1px solid rgb(187, 247, 208);
}

/* =============================================================================
   .hard-bound-violation — red border on editor inputs that hold a value
   outside the schema's hard bound (Stannard Rock chunk 3b, E8). Toggled
   by the per-field Alpine scope's ``hardBoundViolation`` getter. Save is
   simultaneously disabled at the modal-wide level so the violating value
   can never reach the server.
   ============================================================================= */
.hard-bound-violation {
    border-color: rgb(220, 38, 38);
    background: rgb(254, 242, 242);
}

.hard-bound-violation:focus {
    border-color: rgb(220, 38, 38);
    box-shadow: 0 0 0 2px rgba(220, 38, 38, 0.3);
}
