/* Sentinel — shared styles beyond Tailwind CDN */

/* ───────── Theme tokens ─────────
   Single light theme. Tailwind reads these via
   rgb(var(--gray-N-rgb) / <alpha-value>) (see base.html). Every hex below
   is sourced from these variables so the app stays visually consistent. */

:root,
:root[data-theme="light"] {
    /* Inverted gray scale — low numbers are dark text on light, high numbers
       are light surfaces on dark text. Surfaces stay near-white; page bg has
       just enough tint that white cards pop on top of it. */
    --gray-50-rgb:   17  24  39;     /* near-black for primary text */
    --gray-100-rgb:  31  41  55;
    --gray-200-rgb:  55  65  81;
    --gray-300-rgb:  75  85 104;
    --gray-400-rgb: 100 116 139;     /* muted text */
    --gray-500-rgb: 148 163 184;
    --gray-600-rgb: 203 213 225;
    --gray-700-rgb: 226 232 240;     /* divider lines */
    --gray-800-rgb: 241 245 249;     /* subtle inner surfaces */
    --gray-900-rgb: 255 255 255;     /* primary surface = pure white */
    --gray-950-rgb: 246 248 251;     /* page bg = slight cool tint */

    --bg-page:    #f6f8fb;
    --bg-surface: #ffffff;
    --bg-card:    #ffffff;
    --bg-flyout:  #ffffff;
    --border:     #e4e8f0;
    --border-soft: rgba(15,23,42,.08);
    --text-primary:  #0f172a;
    --text-secondary: #334155;
    --text-muted: #64748b;
    --tooltip-bg: #0f172a;
    --row-hover: rgba(15,23,42,.04);
    --sidebar-fg: #475569;
    --sidebar-fg-active: #0f172a;
    --sidebar-hover: rgba(15,23,42,.05);
    --scrollbar-track: #eef2f7;
}

/* Light-theme polish: shadow-based elevation, sharper chrome dividers,
   crisper pills. Dark theme keeps its existing borderless flat surfaces. */
:root[data-theme="light"] .sidebar-icon-nav {
    border-right: 1px solid #e4e8f0;
}
:root[data-theme="light"] .flyout-panel {
    box-shadow: 4px 0 18px rgba(15,23,42,.06);
    border-right: 1px solid #e4e8f0;
}
:root[data-theme="light"] header[class*="border-b"] {
    border-bottom-color: #e4e8f0 !important;
    box-shadow: 0 1px 0 rgba(15,23,42,.04);
}
/* Teleport-style: cards are flat by default, hover only nudges the border
   darker — no looming drop shadow on hover. Keeps the page calm. */
:root[data-theme="light"] .card-hover:hover,
:root[data-theme="light"] .stat-card:hover {
    border-color: #cbd5e1 !important;
    box-shadow: none;
}
/* Pills: flat neutral chip (matches Teleport's `env: dev`-style labels) —
   no border, soft gray fill, mid-gray text. */
:root[data-theme="light"] .pill {
    background: #f1f5f9;
    color: #475569;
    border: 1px solid transparent;
    font-weight: 500;
}
:root[data-theme="light"] .data-table tbody tr {
    border-bottom-color: #eef2f7;
}
:root[data-theme="light"] .data-table thead th {
    background: #f9fbfd;
    border-bottom-color: #e4e8f0;
}
:root[data-theme="light"] .breadcrumb a { color: #64748b; }
:root[data-theme="light"] .breadcrumb a:hover { color: #0f172a; }
:root[data-theme="light"] .breadcrumb .current { color: #0f172a; }
:root[data-theme="light"] .sidebar-item.active {
    background: #eef2ff;
    color: #4f46e5;
}
:root[data-theme="light"] .sidebar-item.active::before {
    background: #4f46e5;
}
:root[data-theme="light"] .flyout-link.active {
    background: #eef2ff;
    color: #4f46e5;
}
:root[data-theme="light"] .section-tab.active {
    color: #4f46e5;
    border-bottom-color: #4f46e5;
}
/* Tailwind class overrides we can't easily override at the variable level —
   inputs and code blocks default to dark `bg-gray-800/50` etc. styles that
   need a light alternative. */
:root[data-theme="light"] input,
:root[data-theme="light"] select,
:root[data-theme="light"] textarea {
    background-color: #ffffff !important;
    border-color: #e4e8f0 !important;
    color: #0f172a !important;
}
:root[data-theme="light"] input::placeholder,
:root[data-theme="light"] textarea::placeholder {
    color: #94a3b8;
}
:root[data-theme="light"] code,
:root[data-theme="light"] pre {
    background-color: #f1f5f9 !important;
    color: #0f172a !important;
    border-color: #e4e8f0 !important;
}

/* Teleport-style search inputs: pill-shaped with light gray border, soft
   focus ring. Targets the search bars on Resources / Users / Audit pages.
   Only the radius is forced — the template keeps its own pl-11 padding
   (or similar) so the absolute-positioned magnifying-glass icon doesn't
   overlap the placeholder text. */
:root[data-theme="light"] input[type="search"],
:root[data-theme="light"] input[type="text"][placeholder*="earch" i],
:root[data-theme="light"] input[type="text"][placeholder*="ilter" i] {
    border-radius: 9999px;
}
:root[data-theme="light"] input:focus,
:root[data-theme="light"] select:focus,
:root[data-theme="light"] textarea:focus {
    outline: none;
    border-color: #818cf8 !important;
    box-shadow: 0 0 0 3px rgba(99,102,241,.12);
}

/* Teleport-style primary buttons: solid indigo, soft hover, subtle press.
   Outlined secondary buttons get white bg + indigo border + indigo text. */
:root[data-theme="light"] button.btn-outline,
:root[data-theme="light"] a.btn-outline {
    background: #ffffff !important;
    color: #4f46e5 !important;
    border: 1px solid #c7d2fe !important;
    transition: all 150ms;
}
:root[data-theme="light"] button.btn-outline:hover,
:root[data-theme="light"] a.btn-outline:hover {
    background: #eef2ff !important;
    border-color: #818cf8 !important;
}

/* Soften the page header — drop the box-shadow Teleport doesn't use,
   keep only the 1px divider. */
:root[data-theme="light"] header[class*="border-b"] {
    box-shadow: none;
}

/* Stat cards keep the 3px colored accent stripe — that's our brand mark.
   But the surrounding card should be the same flat white as Teleport. */
:root[data-theme="light"] .stat-card {
    background: #ffffff !important;
}
:root[data-theme="light"] .stat-card .text-2xl {
    font-weight: 600;
    color: var(--text-primary);
}

/* Data table — Teleport uses subtle row dividers and a faint header tint;
   no zebra striping. Already partly applied; tighten the header spacing. */
:root[data-theme="light"] .data-table thead th {
    color: #64748b;
    background: #f8fafc;
}
:root[data-theme="light"] .data-table tbody tr:hover {
    background: #f8fafc;
}

/* Modal panels — light-theme overlay should be a softer slate, not pitch
   black — pitch black on a light page reads aggressive. */
:root[data-theme="light"] [class*="bg-black/60"],
:root[data-theme="light"] [class*="bg-black/50"] {
    background-color: rgba(15,23,42,.40) !important;
}

/* Sidebar: Teleport's active state is light indigo bg with a 3px indigo
   accent on the left. The accent is already correct — bump the active bg
   slightly for more presence on white. */
:root[data-theme="light"] .sidebar-item.active {
    background: #eef2ff;
    color: #4338ca;
}
:root[data-theme="light"] .sidebar-icon-nav {
    background: #ffffff !important;
}
:root[data-theme="light"] .flyout-panel {
    background: #ffffff !important;
}

/* Teleport-style cards: flat — no resting drop shadow. Templates that already
   have `border` Tailwind classes get the themed border color via the
   `[class*="border-gray-800"]` rule above; we don't force a border here so
   nested chips (e.g. `bg-gray-800/40` rows inside a card) stay borderless. */
:root[data-theme="light"] .card,
:root[data-theme="light"] .stat-card,
:root[data-theme="light"] .resource-card,
:root[data-theme="light"] .ssh-card,
:root[data-theme="light"] .aws-card,
:root[data-theme="light"] .role-row,
:root[data-theme="light"] [class*="bg-gray-900"],
:root[data-theme="light"] [class*="bg-gray-800"] {
    box-shadow: none;
}
/* Top-level card containers get the 12px Teleport-style radius — apply only
   to the .card class (which marks an outer card), not anything that happens
   to use `bg-gray-800` for a nested surface. */
:root[data-theme="light"] .card,
:root[data-theme="light"] .stat-card,
:root[data-theme="light"] .resource-card {
    border-radius: 12px;
}
:root[data-theme="light"] [class*="border-gray-800"],
:root[data-theme="light"] [class*="border-gray-700"] {
    border-color: #e4e8f0 !important;
}
:root[data-theme="light"] body { color: var(--text-primary); }

/* Tailwind's `text-white` is a hardcoded `rgb(255 255 255)` and ignores the
   CSS-variable palette swap, so it renders white-on-white on light cards.
   Remap to themed dark text everywhere first... */
:root[data-theme="light"] .text-white { color: var(--text-primary) !important; }
:root[data-theme="light"] .hover\:text-white:hover { color: var(--text-primary) !important; }

/* ...then force white text back on solid colored buttons themselves AND on
   any text-white descendants of those buttons. Covers both
   `<button class="bg-indigo-600 text-white">` and
   `<a class="bg-indigo-600"><span class="text-white">...`. The trailing
   selectors with no space are matches on the button itself; the descendant
   selectors catch nested labels. */
:root[data-theme="light"] .bg-indigo-500.text-white,
:root[data-theme="light"] .bg-indigo-600.text-white,
:root[data-theme="light"] .bg-indigo-700.text-white,
:root[data-theme="light"] .bg-purple-500.text-white,
:root[data-theme="light"] .bg-purple-600.text-white,
:root[data-theme="light"] .bg-purple-700.text-white,
:root[data-theme="light"] .bg-red-500.text-white,
:root[data-theme="light"] .bg-red-600.text-white,
:root[data-theme="light"] .bg-red-700.text-white,
:root[data-theme="light"] .bg-green-500.text-white,
:root[data-theme="light"] .bg-green-600.text-white,
:root[data-theme="light"] .bg-green-700.text-white,
:root[data-theme="light"] .bg-blue-500.text-white,
:root[data-theme="light"] .bg-blue-600.text-white,
:root[data-theme="light"] .bg-blue-700.text-white,
:root[data-theme="light"] .bg-indigo-500 .text-white,
:root[data-theme="light"] .bg-indigo-600 .text-white,
:root[data-theme="light"] .bg-indigo-700 .text-white,
:root[data-theme="light"] .bg-purple-500 .text-white,
:root[data-theme="light"] .bg-purple-600 .text-white,
:root[data-theme="light"] .bg-purple-700 .text-white,
:root[data-theme="light"] .bg-red-500 .text-white,
:root[data-theme="light"] .bg-red-600 .text-white,
:root[data-theme="light"] .bg-red-700 .text-white,
:root[data-theme="light"] .bg-green-500 .text-white,
:root[data-theme="light"] .bg-green-600 .text-white,
:root[data-theme="light"] .bg-green-700 .text-white,
:root[data-theme="light"] .bg-blue-500 .text-white,
:root[data-theme="light"] .bg-blue-600 .text-white,
:root[data-theme="light"] .bg-blue-700 .text-white { color: #ffffff !important; }

/* Same problem for the two near-white grays Tailwind ships as fixed colors;
   our palette already inverts these, but a few templates still reach for the
   literal Tailwind ones. */
:root[data-theme="light"] .text-gray-50  { color: var(--text-primary) !important; }
:root[data-theme="light"] .text-gray-100 { color: var(--text-primary) !important; }
:root[data-theme="light"] .text-gray-200 { color: var(--text-secondary) !important; }
:root[data-theme="light"] .text-gray-300 { color: var(--text-secondary) !important; }
:root[data-theme="light"] .text-gray-400 { color: var(--text-muted) !important; }
:root[data-theme="light"] .text-gray-500 { color: var(--text-muted) !important; }
:root[data-theme="light"] .text-gray-600 { color: var(--text-muted) !important; }

/* Status / accent colors stay vivid but need a touch more saturation against
   white surfaces — the dark-theme tints (e.g. text-indigo-400) wash out. */
:root[data-theme="light"] .text-indigo-400 { color: #4f46e5 !important; }
:root[data-theme="light"] .text-indigo-300 { color: #4f46e5 !important; }
:root[data-theme="light"] .text-green-400  { color: #16a34a !important; }
:root[data-theme="light"] .text-red-400    { color: #dc2626 !important; }
:root[data-theme="light"] .text-yellow-400 { color: #ca8a04 !important; }
:root[data-theme="light"] .text-purple-400 { color: #7c3aed !important; }
:root[data-theme="light"] .text-blue-400   { color: #2563eb !important; }

/* The colored Tailwind backgrounds used for badges (`bg-indigo-500/10`, etc.)
   produce a near-invisible 10%-alpha tint over white. Bump them so badges
   read as actual chips. */
:root[data-theme="light"] [class*="bg-indigo-500/10"],
:root[data-theme="light"] [class*="bg-indigo-500/15"] { background-color: rgba(79,70,229,.10) !important; }
:root[data-theme="light"] [class*="bg-green-500/10"],
:root[data-theme="light"] [class*="bg-green-500/15"]  { background-color: rgba(22,163,74,.12) !important; }
:root[data-theme="light"] [class*="bg-red-500/10"],
:root[data-theme="light"] [class*="bg-red-500/15"]    { background-color: rgba(220,38,38,.10) !important; }
:root[data-theme="light"] [class*="bg-yellow-500/10"],
:root[data-theme="light"] [class*="bg-yellow-500/15"] { background-color: rgba(202,138,4,.12) !important; }
:root[data-theme="light"] [class*="bg-purple-500/10"],
:root[data-theme="light"] [class*="bg-purple-500/15"] { background-color: rgba(124,58,237,.10) !important; }

/* Pill backgrounds built on bg-{color}-900/N (intentionally muted on dark)
   collapse to near-white on light. Promote them to readable saturated tints
   and pair them with darker text + a visible border. Used by role badges,
   SSO group counts, mode badges, etc. */
:root[data-theme="light"] [class*="bg-purple-900"] {
    background-color: rgba(124,58,237,.10) !important;
    border-color: rgba(124,58,237,.25) !important;
}
:root[data-theme="light"] [class*="bg-yellow-900"],
:root[data-theme="light"] [class*="bg-amber-900"] {
    background-color: rgba(202,138,4,.12) !important;
    border-color: rgba(202,138,4,.30) !important;
}
:root[data-theme="light"] [class*="bg-indigo-900"] {
    background-color: rgba(79,70,229,.10) !important;
    border-color: rgba(79,70,229,.25) !important;
}
:root[data-theme="light"] [class*="bg-green-900"],
:root[data-theme="light"] [class*="bg-emerald-900"] {
    background-color: rgba(22,163,74,.12) !important;
    border-color: rgba(22,163,74,.28) !important;
}
:root[data-theme="light"] [class*="bg-red-900"],
:root[data-theme="light"] [class*="bg-rose-900"] {
    background-color: rgba(220,38,38,.10) !important;
    border-color: rgba(220,38,38,.28) !important;
}
:root[data-theme="light"] [class*="bg-blue-900"] {
    background-color: rgba(37,99,235,.10) !important;
    border-color: rgba(37,99,235,.25) !important;
}

/* Same idea for the colored *text* shipped alongside those pills — yellow-300
   and purple-400 over a near-white pill aren't legible, push them darker. */
:root[data-theme="light"] .text-purple-400,
:root[data-theme="light"] .text-purple-300 { color: #6d28d9 !important; }
:root[data-theme="light"] .text-yellow-300,
:root[data-theme="light"] .text-yellow-400,
:root[data-theme="light"] .text-amber-300,
:root[data-theme="light"] .text-amber-400 { color: #a16207 !important; }
:root[data-theme="light"] .text-emerald-400,
:root[data-theme="light"] .text-emerald-300 { color: #15803d !important; }
:root[data-theme="light"] .text-rose-400,
:root[data-theme="light"] .text-rose-300 { color: #be123c !important; }

::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: var(--scrollbar-track); }
::-webkit-scrollbar-thumb { background: rgb(var(--gray-700-rgb)); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: rgb(var(--gray-600-rgb)); }

/* Status dot indicators */
.status-dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    display: inline-block;
    flex-shrink: 0;
}
.status-dot-online  { background: #22c55e; box-shadow: 0 0 6px rgba(34,197,94,.4); }
.status-dot-offline { background: #ef4444; box-shadow: 0 0 6px rgba(239,68,68,.4); }
.status-dot-unknown { background: #eab308; box-shadow: 0 0 6px rgba(234,179,8,.4); }

/* Sidebar — Teleport-style icon nav */
.sidebar-icon-nav {
    width: 72px;
    background: var(--bg-surface);
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    border-right: 1px solid var(--border-soft);
    z-index: 35;
}
.sidebar-logo {
    display: none;
}
.sidebar-items {
    flex: 1;
    overflow-y: auto;
    padding: 12px 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.sidebar-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 12px 4px 8px;
    margin: 0 6px;
    border-radius: 8px;
    color: var(--sidebar-fg);
    text-decoration: none;
    transition: all 150ms;
    cursor: pointer;
    position: relative;
}
.sidebar-item svg {
    width: 22px;
    height: 22px;
    flex-shrink: 0;
}
.sidebar-item span {
    font-size: 0.6rem;
    font-weight: 500;
    margin-top: 3px;
    text-align: center;
    line-height: 1.1;
    letter-spacing: 0.01em;
}
.sidebar-item:hover {
    background: var(--sidebar-hover);
    color: var(--sidebar-fg-active);
}
.sidebar-item.active {
    background: rgba(0,199,174,.12);
    color: #00C7AE;
}
.sidebar-item.active::before {
    content: '';
    position: absolute;
    left: -7px;
    top: 8px;
    bottom: 8px;
    width: 3px;
    background: #00C7AE;
    border-radius: 0 2px 2px 0;
}
.sidebar-bottom {
    border-top: 1px solid var(--border-soft);
    padding: 8px 0;
    flex-shrink: 0;
}

/* Build identity. The rail is 72px, the string is one unbreakable token
   (2.0.0-dev.1376.g8a45b67) and the default break-after-hyphen left the
   tail wider than the rail, so it bled out the side. */
.sidebar-version {
    padding: 6px 2px;
    opacity: 0.5;
}
.sidebar-version span {
    max-width: 100%;
    margin-top: 0;
    font-size: 0.55rem;
    line-height: 1.25;
    overflow-wrap: anywhere;
}
.sidebar-version .sidebar-version-build {
    opacity: 0.85;
}
.sidebar-user {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 8px 4px;
    margin: 0 6px;
    border-radius: 8px;
    color: var(--sidebar-fg);
    cursor: pointer;
    transition: all 150ms;
}
.sidebar-user:hover {
    background: var(--sidebar-hover);
    color: var(--sidebar-fg-active);
}
.sidebar-user .avatar {
    width: 28px;
    height: 28px;
    font-size: 0.6rem;
}
.sidebar-user span {
    font-size: 0.55rem;
    margin-top: 3px;
    max-width: 60px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Flyout panel — slides out from icon sidebar */
.flyout-panel {
    position: fixed;
    left: 72px;
    top: 3.5rem;
    bottom: 0;
    width: 256px;
    background: var(--bg-flyout);
    border-right: 1px solid var(--border-soft);
    z-index: 32;
    display: flex;
    flex-direction: column;
    box-shadow: 4px 0 24px rgba(0,0,0,.4);
    animation: flyoutSlideIn 120ms ease;
}
/* Tailwind's `.hidden { display: none }` has equal specificity to
   `.flyout-panel` (one class each), and app.css loads AFTER Tailwind, so
   the .flyout-panel rule's `display: flex` was winning the cascade for
   the resting state `<div class="flyout-panel hidden">`. The panel stayed
   rendered (invisible-but-pointer-events-active) over a 256-px-wide strip
   to the right of the sidebar — covering the leftmost dashboard tile and
   eating its click. Re-declare display:none with the combined-class
   selector so the cascade resolves correctly. */
.flyout-panel.hidden {
    display: none;
}
@keyframes flyoutSlideIn {
    from { transform: translateX(-8px); opacity: 0; }
    to   { transform: translateX(0); opacity: 1; }
}
.flyout-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 16px 12px;
    border-bottom: 1px solid var(--border-soft);
}
.flyout-header h3 {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--sidebar-fg-active);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.flyout-close {
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
    color: var(--sidebar-fg);
    background: none;
    border: none;
    cursor: pointer;
    transition: all 150ms;
}
.flyout-close:hover {
    background: var(--sidebar-hover);
    color: var(--sidebar-fg-active);
}
.flyout-close svg {
    width: 14px;
    height: 14px;
}
.flyout-items {
    flex: 1;
    padding: 8px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.flyout-link {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    border-radius: 6px;
    color: var(--sidebar-fg);
    font-size: 0.8125rem;
    font-weight: 500;
    text-decoration: none;
    transition: all 150ms;
}
.flyout-link svg {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}
.flyout-link:hover {
    background: var(--sidebar-hover);
    color: var(--sidebar-fg-active);
}
.flyout-link.active {
    background: rgba(0,199,174,.1);
    color: #00C7AE;
}

/* Flyout pinned — stays visible, pushes content */
.flyout-panel.pinned {
    position: fixed;
    box-shadow: none;
    animation: none;
}

.flyout-section-label {
    font-size: 0.6875rem;
    font-weight: 600;
    color: var(--sidebar-fg);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 12px 12px 4px;
}

/* Hard horizontal separator between grouped sections inside the
   flyout — pairs with .flyout-section-label to give the Teleport-style
   segregation ("All / Pinned" | "Filtered Views" | "Tools"). */
.flyout-divider {
    height: 1px;
    background: var(--border);
    margin: 10px 12px 4px;
    opacity: 0.6;
}

/* Horizontal separator inside the main icon-rail sidebar — sets
   "Add New" apart from the primary nav items above (Dashboard /
   Resources / Access / Audit / Downloads) so it reads as a
   distinct action, matching Teleport's rail layout. */
.sidebar-separator {
    height: 1px;
    background: var(--border);
    margin: 12px 12px;
    opacity: 0.5;
}

/* Dashboard tiles + mini-cards. Tiles are the top-row hero metrics
   (Active Sessions / Events 24h / Denials / Pending Access + admin
   identity strip). Mini-cards are the smaller resource-summary row.
   Both are anchor tags so the whole card is clickable — hover lifts
   with an indigo-tinted shadow to match .res-card. */
.dash-tile {
    position: relative;
    display: block;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    border-radius: 0.75rem;
    padding: 1.1rem 1.25rem;
    min-height: 6.5rem;
    transition: transform 120ms ease, box-shadow 200ms ease, border-color 200ms ease;
    overflow: hidden;
}
.dash-tile:hover {
    transform: translateY(-2px);
    border-color: rgba(99,102,241,.35);
    box-shadow: 0 8px 20px -8px rgba(99,102,241,.35);
}
.dash-tile-label {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--text-secondary);
    font-weight: 600;
}
.dash-tile-value {
    font-size: 1.75rem;
    font-weight: 700;
    line-height: 1.1;
    margin-top: 0.35rem;
}
.dash-tile-hint {
    font-size: 0.7rem;
    color: var(--text-tertiary, #6b7280);
    margin-top: 0.35rem;
}
.dash-tile-icon {
    position: absolute;
    top: 1.1rem;
    right: 1.1rem;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 0.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
}
.dash-tile-icon svg {
    width: 1.15rem;
    height: 1.15rem;
}
/* Alert / warn variants — subtle inset ring so the eye lands on the
   tile without being screamed at. */
.dash-tile-alert { box-shadow: inset 0 0 0 1px rgba(239,68,68,.35); }
.dash-tile-alert:hover { box-shadow: inset 0 0 0 1px rgba(239,68,68,.5), 0 8px 20px -8px rgba(239,68,68,.35); border-color: rgba(239,68,68,.4); }
.dash-tile-warn  { box-shadow: inset 0 0 0 1px rgba(245,158,11,.30); }
.dash-tile-warn:hover { box-shadow: inset 0 0 0 1px rgba(245,158,11,.45), 0 8px 20px -8px rgba(245,158,11,.35); border-color: rgba(245,158,11,.4); }

.dash-mini {
    display: block;
    background: rgba(15,23,42,.35);
    border: 1px solid var(--border-soft);
    border-radius: 0.6rem;
    padding: 0.9rem 1rem;
    transition: border-color 150ms ease, background 150ms ease;
}
.dash-mini:hover { border-color: rgba(99,102,241,.4); background: rgba(15,23,42,.55); }
.dash-mini-value { font-size: 1.5rem; font-weight: 700; line-height: 1; }
.dash-mini-label { font-size: 0.75rem; color: var(--text-secondary); margin-top: 0.35rem; }
.dash-mini-sub   { font-size: 0.65rem; color: var(--text-tertiary, #6b7280); margin-top: 0.15rem; }
:root[data-theme="light"] .dash-mini { background: rgba(241,245,249,.7); }
:root[data-theme="light"] .dash-mini:hover { background: rgba(241,245,249,1); }

.flyout-backdrop {
    position: fixed;
    inset: 0;
    z-index: 25;
}

.section-tabs {
    display: flex;
    gap: 0;
    border-bottom: 1px solid var(--border);
    margin-bottom: 1.25rem;
}
.section-tab {
    padding: 0.625rem 1rem;
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--text-muted);
    border-bottom: 2px solid transparent;
    transition: all 150ms;
    text-decoration: none;
}
.section-tab:hover {
    color: var(--text-secondary);
}
.section-tab.active {
    color: #00C7AE;
    border-bottom-color: #00C7AE;
}

.breadcrumb { display: flex; align-items: center; gap: 0.375rem; font-size: 0.8125rem; }
.breadcrumb a { color: var(--text-muted); transition: color 150ms; }
.breadcrumb a:hover { color: var(--text-secondary); }
.breadcrumb .sep { color: var(--text-muted); }
.breadcrumb .current { color: var(--text-secondary); font-weight: 500; }

.card-hover { transition: border-color 200ms, box-shadow 200ms; }
.card-hover:hover {
    border-color: var(--border);
    box-shadow: 0 4px 12px rgba(0,0,0,.35);
}

.data-table { width: 100%; }
.data-table thead th {
    font-size: 0.6875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    padding: 0.625rem 1rem;
    border-bottom: 1px solid var(--border);
    text-align: left;
}
.data-table tbody td { padding: 0.75rem 1rem; font-size: 0.8125rem; }
.data-table tbody tr { border-bottom: 1px solid var(--border-soft); transition: background 150ms; }
.data-table tbody tr:hover { background: var(--row-hover); }
.data-table tbody tr:last-child { border-bottom: none; }

.verb-badge {
    display: inline-flex; align-items: center;
    font-size: 0.6875rem; font-weight: 600; font-family: ui-monospace, monospace;
    padding: 0.1rem 0.45rem; border-radius: 0.25rem;
}
.verb-get    { background: rgba(34,197,94,.15); color: #4ade80; }
.verb-list   { background: rgba(34,197,94,.15); color: #4ade80; }
.verb-post   { background: rgba(59,130,246,.15); color: #60a5fa; }
.verb-put    { background: rgba(234,179,8,.15); color: #facc15; }
.verb-patch  { background: rgba(234,179,8,.15); color: #facc15; }
.verb-delete { background: rgba(239,68,68,.15); color: #f87171; }

.pill {
    display: inline-flex; align-items: center;
    font-size: 0.6875rem;
    padding: 0.15rem 0.5rem;
    border-radius: 9999px;
    background: rgba(15,40,71,.6);
    color: rgb(var(--gray-200-rgb));
    border: 1px solid var(--border-soft);
}
:root[data-theme="light"] .pill {
    background: rgba(80,106,145,.10);
    color: var(--text-secondary);
}

/* Access-request chips — richer variant used on the /web/access-requests
   table. Structure: [kind badge] name [·] detail — the kind badge is a
   small colored token (AWS / SSH / KUBE / APP / ROLE), the separator is
   a hairline dot, the detail (login / trailing ARN segment) is muted so
   the resource name reads first. All colors come from named tailwind
   scales (amber/sky/indigo/emerald/purple) so they render correctly on
   both dark and light themes — no gray-N vars that get inverted. */
.ar-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.7rem;
    padding: 0.28rem 0.55rem 0.28rem 0.32rem;
    border-radius: 0.5rem;
    background: rgba(148,163,184,.08);
    border: 1px solid rgba(148,163,184,.18);
    line-height: 1;
    max-width: 100%;
}
:root[data-theme="light"] .ar-chip {
    background: #ffffff;
    border-color: #e4e8f0;
    box-shadow: 0 1px 0 rgba(15,23,42,.02);
}
.ar-chip-tag {
    display: inline-flex;
    align-items: center;
    font-size: 0.5625rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    padding: 0.22rem 0.42rem;
    border-radius: 0.3rem;
    line-height: 1;
    text-transform: uppercase;
}
.ar-chip-name {
    font-weight: 600;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 14rem;
}
.ar-chip-sep {
    color: rgba(148,163,184,.55);
    font-weight: 400;
    padding: 0 0.02rem;
}
.ar-chip-detail {
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
    font-size: 0.65rem;
    color: var(--text-tertiary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 12rem;
}
.ar-chip-role  .ar-chip-tag { background: #eef2ff; color: #4338ca; }
.ar-chip-aws   .ar-chip-tag { background: #fff3e3; color: #b45309; }
.ar-chip-ssh   .ar-chip-tag { background: #ecfeff; color: #0369a1; }
.ar-chip-kube  .ar-chip-tag { background: #eef2ff; color: #3730a3; }
.ar-chip-app   .ar-chip-tag { background: #ecfdf5; color: #047857; }
/* On dark theme the pale backgrounds wash out — use tinted-alpha instead
   so the badge still reads against the dark chip body. */
:root:not([data-theme="light"]) .ar-chip-role .ar-chip-tag { background: rgba(99,102,241,.18);  color: #a5b4fc; }
:root:not([data-theme="light"]) .ar-chip-aws  .ar-chip-tag { background: rgba(255,153,0,.16);   color: #fbbf24; }
:root:not([data-theme="light"]) .ar-chip-ssh  .ar-chip-tag { background: rgba(14,165,233,.16);  color: #7dd3fc; }
:root:not([data-theme="light"]) .ar-chip-kube .ar-chip-tag { background: rgba(99,102,241,.16);  color: #a5b4fc; }
:root:not([data-theme="light"]) .ar-chip-app  .ar-chip-tag { background: rgba(16,185,129,.16);  color: #6ee7b7; }

/* Resource card hover lift — subtle translate + indigo-tinted shadow.
   Feels tactile without shouting. Paired with min-height so the card
   grid keeps a uniform baseline regardless of label count. */
.res-card {
    min-height: 8.25rem;
    transition: transform 120ms ease, box-shadow 200ms ease, border-color 200ms ease;
}
.res-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 8px 20px -8px rgba(99,102,241,.35);
    border-color: rgba(99,102,241,.35);
}

.stat-card { position: relative; overflow: hidden; }
.stat-card::before {
    content: '';
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 3px;
    border-radius: 0 2px 2px 0;
}
.stat-card-indigo::before  { background: #818cf8; }
.stat-card-green::before   { background: #22c55e; }
.stat-card-yellow::before  { background: #eab308; }
.stat-card-purple::before  { background: #a78bfa; }
.stat-card-orange::before  { background: #fb923c; }
.stat-card-emerald::before { background: #34d399; }

.avatar {
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 50%;
    font-size: 0.6875rem; font-weight: 600;
    text-transform: uppercase;
    flex-shrink: 0;
}
.avatar-sm { width: 1.75rem; height: 1.75rem; }
.avatar-md { width: 2rem; height: 2rem; }

.rbac-bar {
    height: 0.5rem; border-radius: 0.25rem;
    transition: width 600ms ease;
}

.page-header { margin-bottom: 1.5rem; }
.page-header h2 { font-size: 1.375rem; font-weight: 700; color: var(--text-primary); }
.page-header p { font-size: 0.8125rem; color: var(--text-muted); margin-top: 0.25rem; }

[data-tooltip] { position: relative; cursor: default; }
[data-tooltip]:hover::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: 100%; left: 50%;
    transform: translateX(-50%);
    padding: 0.25rem 0.5rem;
    background: var(--tooltip-bg);
    color: rgb(var(--gray-100-rgb));
    font-size: 0.6875rem;
    border-radius: 0.375rem;
    white-space: nowrap;
    z-index: 10;
    border: 1px solid var(--border);
    margin-bottom: 0.25rem;
}

.mode-badge {
    font-size: 0.6875rem;
    padding: 0.15rem 0.5rem;
    border-radius: 0.375rem;
    font-weight: 500;
}
.mode-agent  { background: rgba(139,92,246,.15); color: #a78bfa; }
.mode-direct { background: rgba(59,130,246,.15); color: #60a5fa; }

.login-card {
    position: relative;
    background: var(--bg-surface);
    border-radius: 1rem;
    border: 1px solid var(--border);
}
.login-card::before {
    content: '';
    position: absolute;
    inset: -1px;
    border-radius: 1rem;
    background: linear-gradient(135deg, rgba(99,102,241,.3), rgba(139,92,246,.2), transparent, transparent);
    z-index: -1;
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask-composite: exclude;
    -webkit-mask-composite: xor;
    padding: 1px;
}

.fade-in { animation: fadeIn 200ms ease; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

/* Header logo — defensive override. The link uses text-white which the
   global remap should already catch, but tagging the dashboard-link
   element explicitly guarantees the ZSentinel wordmark and shield icon
   stay visible against the white header surface in light theme. */
:root[data-theme="light"] header a[href="/web/dashboard"],
:root[data-theme="light"] header a[href="/web/dashboard"] svg,
:root[data-theme="light"] header a[href="/web/dashboard"] span {
    color: var(--text-primary) !important;
}

/* ───────── Session playback layout ─────────
   The player page is a flex column that fills the viewport so the recording
   does not trigger page scrolling. The recording is framed as a terminal
   window (title bar + dark surface) that looks polished and, crucially,
   reserves its space up front so the asciinema player mounting does not
   shift the layout. */
/* Terminal-window colors follow the active site theme. --player-term-bg /
   --player-term-fg drive both the surface (no-flash background) and the
   custom asciinema 'zsentinel' theme below, so the recording matches the
   app's light/dark look. */
:root {
    --player-term-bg: rgb(var(--gray-900-rgb));
    --player-term-fg: #c8d3f5;
    --player-titlebar: linear-gradient(180deg, rgba(255,255,255,.05) 0%, rgba(255,255,255,.02) 100%);
    --player-title-color: var(--text-muted);
}
:root[data-theme="light"] {
    --player-term-bg: #ffffff;
    --player-term-fg: #1e293b;
    --player-titlebar: linear-gradient(180deg, #f9fbfd 0%, #f1f5f9 100%);
    --player-title-color: #64748b;
}
.player-shell {
    background: var(--bg-surface);
    border: 1px solid var(--border-soft);
    border-radius: 0.75rem;
    overflow: hidden;
    box-shadow: 0 18px 40px -20px rgba(0,0,0,.35);
}
.player-titlebar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0.85rem;
    background: var(--player-titlebar);
    border-bottom: 1px solid var(--border-soft);
    flex-shrink: 0;
}
.player-dots { display: inline-flex; gap: 0.4rem; flex-shrink: 0; }
.player-dots .dot { width: 0.72rem; height: 0.72rem; border-radius: 9999px; display: inline-block; }
.player-dots .dot-red   { background: #ff5f57; }
.player-dots .dot-amber { background: #febc2e; }
.player-dots .dot-green { background: #28c840; }
.player-title {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    flex: 1 1 auto;
    min-width: 0;
    justify-content: center;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.75rem;
    color: var(--player-title-color);
}
.player-title span { max-width: 60%; }
.player-speed {
    background: rgba(127,127,127,.10);
    border: 1px solid var(--border-soft);
    border-radius: 0.375rem;
    padding: 0.1rem 0.25rem;
    flex-shrink: 0;
}
.player-speed .speed-btn {
    padding: 0.2rem 0.45rem;
    font-size: 0.7rem;
    color: var(--text-secondary);
    border-radius: 0.25rem;
    transition: background 120ms ease, color 120ms ease;
}
.player-speed .speed-btn:hover { background: rgba(127,127,127,.14); }
.player-speed .speed-btn.is-active {
    background: rgba(99,102,241,.28);
    color: #6366f1;
}
/* Terminal surface behind the player — matches the terminal background so
   there is no flash or reflow before/while the recording mounts. The player
   uses fit:'both' (see recording_player.html), which scales the WHOLE
   terminal to fit inside this box while preserving aspect ratio — so it
   never overflows or scrolls, regardless of the recording's column count
   (kube sessions are 80 cols, SSH uses the real browser size). Leftover
   space is centered gutter; the player's own fullscreen button gives a
   larger view when needed. */
.player-surface {
    background: var(--player-term-bg);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
}
#player {
    width: 100%;
    height: 100%;
    min-height: 0;
    position: relative;
}
#player .ap-player { background: transparent; }

/* Custom asciinema theme tied to the app palette. Background + foreground
   track the active site theme; the ANSI palette swaps to darker, legible
   colors in light mode. */
.asciinema-player-theme-zsentinel {
    --term-color-foreground: var(--player-term-fg);
    --term-color-background: var(--player-term-bg);
    --term-color-0:  #414868;
    --term-color-1:  #f7768e;
    --term-color-2:  #9ece6a;
    --term-color-3:  #e0af68;
    --term-color-4:  #7aa2f7;
    --term-color-5:  #bb9af7;
    --term-color-6:  #7dcfff;
    --term-color-7:  #a9b1d6;
    --term-color-8:  #565f89;
    --term-color-9:  #ff899d;
    --term-color-10: #b9f27c;
    --term-color-11: #ff9e64;
    --term-color-12: #8db0ff;
    --term-color-13: #c7a9ff;
    --term-color-14: #a4daff;
    --term-color-15: #c0caf5;
}
:root[data-theme="light"] .asciinema-player-theme-zsentinel {
    --term-color-0:  #0f172a;
    --term-color-1:  #b91c1c;
    --term-color-2:  #15803d;
    --term-color-3:  #b45309;
    --term-color-4:  #1d4ed8;
    --term-color-5:  #7c3aed;
    --term-color-6:  #0e7490;
    --term-color-7:  #334155;
    --term-color-8:  #475569;
    --term-color-9:  #dc2626;
    --term-color-10: #16a34a;
    --term-color-11: #d97706;
    --term-color-12: #2563eb;
    --term-color-13: #9333ea;
    --term-color-14: #0891b2;
    --term-color-15: #0f172a;
}
