/* ============================================================
   AEGIS app and composed surfaces.
   Ported from aegis-dashboard.html: the app shell, views, stat
   cards, rule cards, settings panel, audit table, reaction-role
   and command cards, placeholder, toasts, and the responsive
   layer. Class names are kept identical to the dashboard so this
   stays a faithful mirror.
   ============================================================ */

/* ---------- app shell ---------- */
.app { display: flex; flex-direction: column; min-height: 100vh; width: 100%; }
.mobile-bar { display: flex; align-items: center; justify-content: space-between; padding: 1.25rem; background: var(--base); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); position: relative; z-index: 30; }
.mobile-bar__brand { display: flex; align-items: center; gap: 0.75rem; }
.mobile-bar .brand-mark { width: 40px; height: 40px; border-radius: 12px; font-size: 18px; color: var(--accent); }
.mobile-bar h1 { font-size: 20px; }
.menu-btn { width: 48px; height: 48px; border-radius: 12px; font-size: 18px; }

.overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5); backdrop-filter: blur(4px); z-index: 40; opacity: 0; visibility: hidden; transition: opacity 0.3s ease, visibility 0.3s ease; }
.overlay.is-visible { opacity: 1; visibility: visible; }

/* One merged icon sidebar (041): the picked server at the top, icon-only nav, the user at the foot. It is
   icon-only by default; the hamburger expands it to a labelled bar (.app.nav-expanded). */
/* Content is left-anchored in both states so collapsing just contracts the bar from the right, without
   shifting the icons and avatar toward the (still-wide) center and back (042 feedback). */
.sidebar { position: relative; z-index: 2; width: 88px; flex-shrink: 0; height: 100vh; display: flex; flex-direction: column; align-items: flex-start; gap: 0.75rem; padding: 1.25rem 1rem; background: var(--base); box-shadow: 4px 0 24px rgba(0, 0, 0, 0.12); }
.sidebar__toggle { width: 44px; height: 44px; border-radius: 14px; border: none; background: transparent; color: var(--text-muted); cursor: pointer; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.sidebar__toggle:hover { color: var(--text-main); }
.sidebar__server { display: flex; flex-direction: column; align-items: flex-start; gap: 0.4rem; width: 100%; flex-shrink: 0; overflow: hidden; }
/* The name is hidden when collapsed (icon only) and shown when expanded or on phones. Never selectable. */
.sidebar__server-name { display: none; -webkit-user-select: none; user-select: none; font-size: 14px; line-height: 1.2; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidebar__divider { width: 44px; height: 4px; border-radius: 2px; background: rgba(0, 0, 0, 0.2); box-shadow: var(--pressed-sm); flex-shrink: 0; }
.sidebar__nav { display: flex; flex-direction: column; align-items: flex-start; gap: 0.5rem; overflow-y: auto; overflow-x: hidden; min-height: 0; }
.sidebar__item { width: 100%; display: flex; justify-content: flex-start; }
.sidebar__foot { margin-top: auto; width: 100%; display: flex; flex-direction: column; align-items: flex-start; gap: 0.5rem; justify-content: flex-start; padding-top: 0.75rem; flex-shrink: 0; }
/* The persistent sign-out icon below the avatar. It clips (so its "Sign out" label is revealed by the bar's
   width animation instead of popping in ahead of the others); the shared gutter rule below keeps its hover
   shadow from being sliced. */
.sidebar__signout { display: flex; overflow: hidden; }
/* Icon nav button: icon-only on desktop (the label is a hover tooltip), full row with the label on phones. */
/* The icon is placed by a fixed left padding (not by centering-in-the-button), so its x never depends on the
   button or bar width, and it stays put while the bar expands/collapses. padding-left ~= (56-22)/2 centers it. */
.nav-icon-btn { position: relative; width: 56px; height: 56px; flex-shrink: 0; border-radius: 18px; display: flex; align-items: center; justify-content: flex-start; padding-left: 17px; color: var(--text-muted); text-decoration: none; border: none; background: transparent; cursor: pointer; transition: color 0.2s ease, box-shadow 0.2s ease; }
.nav-icon-btn:hover { color: var(--text-main); box-shadow: var(--raised-sm); }
.nav-icon-btn.active { color: var(--accent); box-shadow: var(--pressed-key); }
/* The icon never shrinks and the label never wraps, so the bar width can animate without resizing the icon
   or reflowing the label onto extra lines (the label just clips as the bar narrows). */
.nav-icon-btn .nav-icon { width: 22px; height: 22px; flex-shrink: 0; }
.nav-icon-btn__label { display: none; white-space: nowrap; }
.nav-icon-btn.is-locked { opacity: 0.45; cursor: not-allowed; }
.nav-icon-btn.is-locked:hover { color: var(--text-muted); box-shadow: none; }
.nav-icon-btn .nav-item__lock { position: absolute; top: 6px; right: 6px; width: 12px; height: 12px; }
/* The user chip at the foot. Collapsed: avatar only, hovering reveals the card (name + sign out) to the
   right. Expanded and on phones: the card sits inline next to the avatar. */
/* The user chip stays inside the bar and clips as it narrows (like the nav labels), instead of the name card
   jumping outside the bar on collapse. */
.user-chip { position: relative; display: flex; justify-content: flex-start; align-items: center; gap: 0.6rem; width: 100%; overflow: hidden; }
.user-chip__avatar { width: 44px; height: 44px; border-radius: 22px; object-fit: cover; box-shadow: var(--raised-sm); cursor: pointer; flex-shrink: 0; }
.user-chip__avatar--mono { display: flex; align-items: center; justify-content: center; background: var(--accent-deep); color: #fff; font-weight: 700; }
/* The name card is hidden when the bar is collapsed (like the nav labels and server name) rather than relying
   on the chip's clip, so the shadow gutter can give the avatar room on the right without exposing a sliver of
   the name. Shown when the bar is expanded or on phones. */
.user-chip__card { display: none; align-items: center; gap: 0.6rem; min-width: 0; flex: 1; }
.user-chip__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-main); font-weight: 500; -webkit-user-select: none; user-select: none; background: var(--base); box-shadow: var(--raised-sm); border-radius: 10px; padding: 0.3rem 0.65rem; }
/* Style-wide shadow safe-area: every sidebar container that clips its overflow (to reveal labels or the name
   as the bar collapses) widens its clip box by --shadow-gutter on all sides. The negative margin cancels the
   padding for layout, so occupied size, icon/avatar positions, gaps, and header/foot pinning are unchanged,
   only the clip region grows into the surrounding transparent space, so no child's raised shadow is ever cut
   (the nav buttons, the sign-out, the server icon, and the name card all get the same breathing room). */
.sidebar__server, .sidebar__nav, .sidebar__signout, .user-chip {
    width: calc(100% + var(--shadow-gutter) * 2);
    margin: calc(var(--shadow-gutter) * -1);
    padding: var(--shadow-gutter);
}
/* A username rendered as a raised clay chip (elevated like a button), used inline in prose too. */
.name-chip { display: inline-block; background: var(--base); box-shadow: var(--raised-sm); border-radius: 10px; padding: 0.15rem 0.6rem; color: var(--text-main); font-weight: 600; -webkit-user-select: none; user-select: none; }
/* Action-log time: shown in the viewer's timezone, click to copy a Discord timestamp. */
.log-time { background: transparent; border: none; padding: 0; font: inherit; color: inherit; cursor: pointer; -webkit-user-select: none; user-select: none; }
.log-time:hover { color: var(--text-main); text-decoration: underline dotted; }
/* A failed moderation action (028): shown with a small red badge next to the action type in the log. */
.badge-failed { margin-left: 0.5rem; padding: 0.05rem 0.4rem; border-radius: 6px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; color: var(--red); box-shadow: var(--pressed-sm); }
/* Action-log Target/Moderator: a readable display name (043) with a small copy-id marker that copies the
   exact numeric id. The name truncates with the full value on hover; the marker is clearly a control. */
.id-cell { display: inline-flex; align-items: center; gap: 0.4rem; max-width: 100%; min-width: 0; }
.id-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 14rem; }
.id-copy { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; padding: 0; border: none; border-radius: 8px; background: transparent; color: var(--text-darker); cursor: pointer; transition: color 0.15s ease, box-shadow 0.15s ease; }
.id-copy .ic { width: 14px; height: 14px; }
.id-copy:hover { color: var(--accent); box-shadow: var(--raised-sm); }
.id-copy:active { box-shadow: var(--pressed-key); }
/* The "Copied timestamp!" confirmation: a small clay bubble that floats up and fades, shown over the clicked
   time so the time column never changes width. Fixed to the viewport, non-interactive, short-lived. */
.copied-bubble { position: fixed; z-index: 100; pointer-events: none; background: var(--base); color: var(--accent); box-shadow: var(--raised-sm); border-radius: 10px; padding: 0.3rem 0.6rem; font-size: 13px; font-weight: 600; white-space: nowrap; opacity: 0; transform: translate(-50%, -100%) translateY(6px); transition: opacity 0.18s ease, transform 0.26s ease; }
.copied-bubble.is-shown { opacity: 1; transform: translate(-50%, -100%) translateY(-4px); }
/* Expanded desktop bar: wider, labelled, with the server name and user card shown inline. The width slide
   is gated (.nav-ready) and lives in the desktop media block, so it never governs the phone menu. */
.app.nav-expanded .sidebar { width: 240px; align-items: stretch; }
.app.nav-expanded .sidebar__toggle { align-self: flex-start; }
/* The shared gutter keeps the server icon at the same x in both states (the negative margin cancels the
   padding), so expanding only needs to switch the layout to a row, no padding override. */
.app.nav-expanded .sidebar__server { flex-direction: row; align-items: center; gap: 0.6rem; }
.sidebar__server .server-icon { flex-shrink: 0; }
.app.nav-expanded .sidebar__server-name { display: block; text-align: left; }
.app.nav-expanded .sidebar__nav { align-items: stretch; }
.app.nav-expanded .sidebar__item { justify-content: stretch; }
.app.nav-expanded .nav-icon-btn { width: 100%; height: 56px; justify-content: flex-start; gap: 1rem; padding: 0 1rem 0 17px; }
.app.nav-expanded .nav-icon-btn__label { display: inline; font-size: 14px; }
.app.nav-expanded .nav-icon-btn .nav-item__lock { position: static; margin-left: auto; }
/* No element (button, link, icon, avatar) is draggable, so pressing one never starts a ghost drag. */
.aegis button, .aegis a, .aegis img, .aegis [role="button"], .aegis .nav-icon-btn, .aegis .btn,
.aegis .server-icon, .aegis .server-card, .aegis .user-chip__avatar, .aegis .nav-icon { -webkit-user-drag: none; }
.app.nav-expanded .user-chip { justify-content: flex-start; gap: 0.6rem; overflow: hidden; }
.app.nav-expanded .user-chip__card { display: flex; min-width: 0; }
.avatar { width: 48px; height: 48px; border-radius: 50%; padding: 4px; background: var(--base); box-shadow: var(--raised-sm); cursor: pointer; }
.avatar img { width: 100%; height: 100%; border-radius: 50%; display: block; }

/* Server icons are circles, like profile pictures (not the squircle-morph). */
.server-icon { width: 48px; height: 48px; border-radius: 50%; background: var(--base); box-shadow: var(--raised-sm); display: flex; align-items: center; justify-content: center; color: var(--text-muted); font-weight: 400; cursor: pointer; border: none; font-family: inherit; transition: color 0.3s ease, box-shadow 0.3s ease; }
.server-icon:hover { color: var(--text-main); box-shadow: var(--raised); }
.server-icon:active { box-shadow: var(--pressed-key); }
/* Elevated (clay) like a button, not pressed, so the picked server icon feels raised off the plane. */
.server-icon.is-active { border-radius: 50%; box-shadow: var(--raised); color: var(--accent); }
.server-icon--add { color: var(--accent); margin-top: 0.5rem; }
.server-icon--muted { color: var(--text-darker); }
/* 037: the picked server's real icon fills the rail marker, monogram fallback. */
.server-icon__img { width: 100%; height: 100%; border-radius: inherit; object-fit: cover; }
.server-icon__mono { font-weight: 600; font-size: 18px; }

/* 037: the signed-in user panel, pinned to the bottom of the nav sidebar (Discord's user-panel spot). */
.user-panel { margin-top: auto; display: flex; align-items: center; gap: 0.75rem; padding: 0.6rem 0.75rem; border-radius: 14px; background: var(--base); box-shadow: var(--raised-sm); }
.user-panel__avatar { width: 40px; height: 40px; border-radius: 20px; object-fit: cover; flex-shrink: 0; box-shadow: var(--raised-sm); }
.user-panel__avatar--mono { display: flex; align-items: center; justify-content: center; background: var(--accent-deep); color: #fff; font-weight: 700; }
.user-panel__name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-main); font-weight: 500; }
.user-panel__signout { margin: 0; flex-shrink: 0; }
.user-panel__signout-btn { display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0; border: none; border-radius: 10px; background: transparent; color: var(--text-darker); cursor: pointer; transition: color 0.2s ease, box-shadow 0.2s ease; }
.user-panel__signout-btn:hover { color: var(--accent); box-shadow: var(--raised-sm); }
.user-panel__signout-btn:active { box-shadow: var(--pressed-key); }

/* Phone top app bar (hidden on desktop): holds the menu button in its own space so it never overlaps content. */
.topbar { display: none; }
.topbar__menu { width: 44px; height: 44px; border: none; border-radius: 12px; background: transparent; color: var(--text-main); cursor: pointer; display: flex; align-items: center; justify-content: center; }
.topbar__menu:hover { color: var(--accent); }
.topbar__brand { font-size: 18px; font-weight: 500; }
/* Back-to-top: fades in when scrolling up (away from the top), fades out on scroll-down or at the top. */
.to-top { position: fixed; right: 20px; bottom: 20px; z-index: 90; width: 48px; height: 48px; border: none; border-radius: 50%; background: var(--base); box-shadow: var(--raised-sm), 0 8px 20px rgba(0, 0, 0, 0.28); color: var(--accent); cursor: pointer; display: flex; align-items: center; justify-content: center; opacity: 0; visibility: hidden; transform: translateY(10px); transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s; }
.to-top.is-visible { opacity: 1; visibility: visible; transform: translateY(0); }
.to-top:hover { color: var(--text-main); }
/* Interactive, non-input elements do not select their text on click or drag (inputs keep selection). */
.aegis button, .aegis .btn, .aegis label, .aegis [role="button"],
.aegis .nav-icon-btn, .aegis .topbar__menu, .aegis .server-icon, .aegis .server-icon__mono,
.aegis .server-card, .aegis .reference__toc a, .aegis .add-row, .aegis .picker__link, .aegis .picker__opt,
.aegis .dismiss, .aegis .user-panel__signout-btn, .aegis .stepper button {
    -webkit-user-select: none; user-select: none;
}
/* Lock down the chrome: labels, headings, eyebrows, and instructional/summary text are not selectable, so
   only real content (field values, message text, ids in the log) can be selected and copied. */
.aegis .label, .aegis .eyebrow, .aegis .crumb-current, .aegis .view-title, .aegis .view-sub,
.aegis .section-title, .aegis .nav-group__label, .aegis th, .aegis .segmented, .aegis .segmented__opt,
.aegis .rule__state, .aegis .meta-line, .aegis .placeholder-icon, .aegis .toggle,
.aegis h1, .aegis h2, .aegis h3, .aegis h4 {
    -webkit-user-select: none; user-select: none;
}
/* The picker search gets a clear button; the blocked enable button shows it is not clickable. */
.picker__filter-wrap { position: relative; flex: 1; display: flex; }
.picker__filter-wrap .picker__filter { flex: 1; padding-right: 2rem; }
.picker__filter-clear { position: absolute; right: 0.5rem; top: 50%; transform: translateY(-50%); width: 20px; height: 20px; padding: 0; border: none; background: transparent; color: var(--text-darker); cursor: pointer; display: flex; align-items: center; justify-content: center; -webkit-user-select: none; user-select: none; }
.picker__filter-clear:hover { color: var(--text-main); }
.btn.is-blocked { cursor: not-allowed; }
/* Phone: the sidebar becomes a full-screen menu (with labels) opened from the top bar, self-closing on pick. */
@media (max-width: 767.98px) {
    .topbar { display: flex; align-items: center; gap: 0.5rem; position: fixed; top: 0; left: 0; right: 0; height: 56px; padding: 0 0.75rem; background: var(--base); box-shadow: 0 2px 12px rgba(0, 0, 0, 0.2); z-index: 50; }
    /* The phone menu is hidden by default (off-screen left) and shown by adding .nav-open. Its own always-on
       transition is not gated by .nav-ready, so an enhanced-navigation class wipe can never make it instant. */
    .sidebar { position: fixed; inset: 0; width: 100vw; height: 100%; flex-direction: column; align-items: stretch; gap: 0.5rem; padding: 4.5rem 1.25rem 1.25rem; z-index: 56; transform: translateX(-100%); opacity: 0; pointer-events: none; transition: transform 0.42s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.38s ease; }
    .sidebar__toggle { display: none; }
    .sidebar__server { flex-direction: row; align-items: center; gap: 0.75rem; }
    .sidebar__server-name { display: block; font-size: 16px; text-align: left; }
    .sidebar__nav { align-items: stretch; }
    .sidebar__item { justify-content: stretch; }
    .nav-icon-btn { width: 100%; height: auto; justify-content: flex-start; gap: 1rem; padding: 0.85rem 1rem; border-radius: 12px; }
    .nav-icon-btn__label { display: inline; font-size: 15px; }
    .nav-icon-btn .nav-item__lock { position: static; margin-left: auto; }
    .user-chip { justify-content: flex-start; gap: 0.6rem; }
    .user-chip__card { display: flex; min-width: 0; }
    /* Open slides in a touch quicker; the base (closed) transition above is slightly slower so the menu
       slides away gently while the new page paints behind it (picking a page removes nav-open). */
    .app.nav-open .sidebar { transform: translateX(0); opacity: 1; pointer-events: auto; transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.25s ease; }
    .main { width: 100%; overflow-x: hidden; }
    /* Higher specificity than the base .view-body padding so the fixed top bar never overlaps the page. */
    .main .view-body { padding-top: calc(56px + 1rem); }
    /* Phone: the wide tables stack into labelled rows instead of scrolling sideways (the page never slides). */
    .audit-wrap { overflow-x: visible; }
    .audit-table { min-width: 0; }
    .audit-table thead { display: none; }
    .audit-table tbody, .audit-table tr, .audit-table td { display: block; width: 100%; }
    .audit-table tr { padding: 0.85rem 0; border-bottom: 1px solid var(--shadow-d); }
    .audit-table td { padding: 0.15rem 0; text-align: left; }
    .audit-table .cell-right { text-align: left; }
    .audit-table td[data-label]::before { content: attr(data-label) ": "; color: var(--text-darker); font-weight: 700; font-size: 12px; }
    .reference__table { display: block; overflow-x: auto; }
}

/* ---------- main and views ---------- */
.main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.view-header { padding: 1.5rem; }
.view-header__row { display: flex; flex-direction: column; gap: 1.5rem; }
.view-title { font-size: 30px; }
.view-title-row { display: flex; align-items: center; gap: 1.25rem; margin-top: 0.75rem; }
.view-sub { color: var(--text-muted); font-size: 16px; margin-top: 0.75rem; max-width: 36rem; line-height: 1.6; }
.view-body { flex: 1; padding: 1rem 1.5rem 3rem; }
.view-actions { display: flex; flex-wrap: wrap; gap: 1rem; }

.unsaved { margin-bottom: 2rem; padding: 1rem 1.5rem; display: flex; flex-direction: column; gap: 1rem; }
.unsaved__msg { display: flex; align-items: center; gap: 1rem; color: var(--accent); font-weight: 400; }
.unsaved__actions { display: flex; gap: 1rem; }

/* ---------- stats ---------- */
.stats { display: grid; grid-template-columns: 1fr; gap: 1.5rem; margin-bottom: 2.5rem; }
.stat { display: flex; align-items: center; gap: 1.25rem; padding: 1.5rem; }
.stat__icon { width: 56px; height: 56px; border-radius: 16px; font-size: 24px; color: var(--text-muted); flex-shrink: 0; }
.stat__icon, .rule__icon, .event__icon, .placeholder-icon {
    /* no container box (an inset box would read as "selected"). The glyph itself is
       engraved into the flat surface it sits on: light catches the lower-right edge,
       shadow sits on the upper-left, so the stroke looks carved softly with white. */
    display: flex; align-items: center; justify-content: center;
    background: transparent; box-shadow: none;
}
.stat__icon .ic, .rule__icon .ic, .event__icon .ic, .placeholder-icon .ic {
    filter: drop-shadow(1px 1px 0.4px rgba(255, 255, 255, 0.13)) drop-shadow(-1px -1px 0.4px rgba(0, 0, 0, 0.28));
}
.stat__value { font-size: 30px; font-weight: 700; }
.stat--meter { flex-direction: column; align-items: stretch; justify-content: center; }
.meter-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 1rem; }
.meter-row { display: flex; align-items: center; gap: 1rem; }
.cursor-help { cursor: help; color: var(--text-muted); }

/* ---------- rule summary card ---------- */
.rules { display: grid; grid-template-columns: 1fr; gap: 2rem; }
.rules-col { display: flex; flex-direction: column; gap: 1.5rem; }
.section-title { font-size: 20px; margin-bottom: 0.5rem; }
.rule { padding: 1.5rem; }
.rule.is-disabled { opacity: 0.42; }
.rule__head { display: flex; flex-direction: column; gap: 1.5rem; }
.rule__id { display: flex; align-items: center; gap: 1.25rem; }
.rule__icon { width: 48px; height: 48px; border-radius: 16px; font-size: 20px; flex-shrink: 0; }
.rule__icon--danger { color: var(--text-muted); }
.rule__icon--muted { color: var(--text-darker); }
/* Feature 035: the in-app reference (sidebar of sections + generated content). */
.reference { display: flex; gap: 2rem; align-items: flex-start; margin-top: 1.5rem; }
.reference__nav { position: sticky; top: 2rem; flex: 0 0 12rem; display: flex; flex-direction: column; gap: 0.75rem; }
.reference__filter { width: 100%; }
.reference__toc { display: flex; flex-direction: column; gap: 2px; padding: 0.5rem; border-radius: 12px; box-shadow: var(--inset-well, var(--pressed)); }
.reference__toc a { color: var(--text-muted); text-decoration: none; padding: 6px 10px; border-radius: 8px; font-size: 14px; }
.reference__toc a:hover { color: var(--text-main); box-shadow: var(--raised-sm); }
/* 041/023: the section you are currently scrolled to is highlighted in white with a pressed look. */
.reference__toc a.is-active { color: var(--text-main); box-shadow: var(--pressed); }
.reference__content { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2.5rem; }
.reference__content section { scroll-margin-top: 2rem; }
.reference__kind { padding: 1rem 0; border-top: 2px solid var(--shadow-d); }
.reference__kind-name { font-size: 16px; margin: 0; color: var(--text-main); }
.reference__none { font-size: 13px; color: var(--text-darker); margin: 0.25rem 0; }
.reference__eg { font-size: 13px; margin: 0.25rem 0; color: var(--teal); }
.reference__eg-tag { color: var(--text-darker); text-transform: uppercase; font-size: 11px; letter-spacing: 0.06em; }
.reference__table { width: 100%; border-collapse: collapse; margin-top: 0.5rem; font-size: 14px; }
.reference__table td, .reference__table th { text-align: left; padding: 6px 10px; vertical-align: top; }
.reference__table th { color: var(--text-darker); font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; font-weight: 700; }
.reference__table td:first-child { color: var(--text-main); white-space: nowrap; }
.reference__example { color: var(--teal); white-space: nowrap; }
.reference__table tr + tr td { border-top: 1px solid var(--shadow-d); }
@media (max-width: 800px) { .reference { flex-direction: column; } .reference__nav { position: static; flex-basis: auto; width: 100%; } }
.rule__title { font-size: 18px; }
/* Button shadow guard: .btn reserves top clearance so its raised shadow never falls behind the element
   above it (the sign-in/sign-out fix, generalized). Reset it where buttons sit in a horizontal row
   beside other content, not below it, so they stay aligned with their neighbours. */
.rule__controls .btn,
.audit-foot .btn,
.log-filter .btn { margin-top: 0; }
.rule__state { font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; padding: 2px 8px; border-radius: 6px; margin-left: 8px; vertical-align: middle; font-family: var(--mono, monospace); }
.rule__state--enabled { color: var(--teal); background: color-mix(in srgb, var(--teal) 14%, transparent); }
.rule__state--off { color: var(--text-darker); background: var(--shadow-d); }
.rule__state--draft { color: #d9a441; background: color-mix(in srgb, #d9a441 14%, transparent); }

/* Feature 030: the searchable entity picker. */
.picker { display: flex; flex-direction: column; gap: 0.5rem; width: 100%; }
.picker__bar { display: flex; align-items: center; gap: 0.5rem; }
.picker__filter { flex: 1; }
.picker__refresh { margin-top: 0; padding: 0.6rem 1.1rem; font-size: 13px; flex-shrink: 0; }
.picker__textarea { width: 100%; min-height: 4.5rem; resize: vertical; line-height: 1.5; }
.picker__textarea::-webkit-resizer { background: transparent; }
.picker__note { font-size: 12px; color: var(--text-muted); }
.picker__actions { display: flex; align-items: center; gap: 1rem; }
.picker__link { background: none; border: none; padding: 0; margin: 0; color: var(--teal); font-family: inherit; font-size: 12px; cursor: pointer; }
.picker__link:hover { text-decoration: underline; }
/* A fixed height so filtering the list never resizes the card. */
.picker__list { height: 12rem; overflow-y: auto; display: flex; flex-direction: column; gap: 4px; padding: 0.5rem; border-radius: 10px; box-shadow: var(--pressed); }
.picker__opt { display: flex; align-items: center; gap: 0.6rem; padding: 5px 8px; border-radius: 8px; cursor: pointer; font-size: 14px; color: var(--text-darker); }
/* A picked row reads slightly brighter than an unpicked one. */
.picker__opt.is-picked { color: var(--text-main); }
.picker__empty { font-size: 13px; color: var(--text-darker); padding: 0.5rem; }
/* Checkboxes in the Aegis language: a raised key that presses IN (inset) and shows a teal check when
   ticked, so a picked item is pushed in and an unpicked one stands proud (the depth law). */
.picker__opt input[type="checkbox"] { appearance: none; -webkit-appearance: none; width: 20px; height: 20px; border-radius: 6px; background: var(--base); box-shadow: var(--raised-sm); cursor: pointer; position: relative; flex-shrink: 0; margin: 0; transition: box-shadow 0.15s ease; }
.picker__opt input[type="checkbox"]:checked { box-shadow: var(--pressed-sm); }
.picker__opt input[type="checkbox"]:checked::after { content: ""; position: absolute; left: 7px; top: 3px; width: 5px; height: 10px; border: solid var(--teal); border-width: 0 2px 2px 0; transform: rotate(45deg); }
.rule__controls { display: flex; align-items: center; gap: 1.5rem; align-self: flex-end; }
.rule__channels { margin-top: 1.5rem; padding-top: 1.5rem; border-top: 2px solid var(--shadow-d); }

.meta-line { display: flex; flex-wrap: wrap; align-items: center; gap: 0.55rem; font-size: 14px; color: var(--text-muted); margin-top: 0.5rem; }
.meta-line .sep { color: var(--shadow-l); user-select: none; }
.meta-line .k { color: var(--text-darker); }
.meta-line .danger { color: var(--red); }
.meta-line .warn { color: var(--yellow); }
.add-inline { background: none; border: none; font-family: inherit; font-size: 14px; color: var(--accent); font-weight: 700; cursor: pointer; display: inline-flex; align-items: center; gap: 0.4rem; padding: 0; }
.add-inline:hover { text-decoration: underline; }

.channels { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: 1rem; }
.channel { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 1rem; border-radius: 12px; background: var(--flat); font-size: 14px; font-weight: 400; }
.channel .channel-hash { color: var(--text-darker); }
.channel .channel-remove { margin-left: 0.5rem; color: var(--text-darker); cursor: pointer; transition: color 0.2s ease; display: inline-flex; }
.channel .channel-remove:hover { color: var(--red); }
.channel--add { background: var(--base); box-shadow: var(--raised-sm); color: var(--text-muted); border: none; cursor: pointer; font-family: inherit; transition: color 0.2s ease, box-shadow 0.2s ease; }
.channel--add:hover { color: var(--text-main); box-shadow: var(--raised); }
.channel--add:active { color: var(--text-main); box-shadow: var(--pressed-key); }

.add-rule { margin-top: 1rem; width: 100%; padding: 1.25rem; border: none; border-radius: 12px; background: var(--base); box-shadow: var(--raised-sm); color: var(--text-muted); font-family: inherit; font-size: 15px; font-weight: 400; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 0.75rem; transition: color 0.2s ease, box-shadow 0.2s ease; }
.add-rule:hover { color: var(--text-main); box-shadow: var(--raised); }
.add-rule:active { color: var(--text-main); box-shadow: var(--pressed-key); }

/* ---------- settings panel ---------- */
.panel { padding: 1.5rem; }
.panel__title { font-size: 18px; margin-bottom: 1.5rem; padding-bottom: 1rem; border-bottom: 2px solid var(--shadow-d); }
.fields { display: flex; flex-direction: column; gap: 2rem; }
.field-label { margin-bottom: 0.75rem; }
.setting-row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.setting-row__title { font-size: 16px; font-weight: 700; }
.setting-row__desc { font-size: 14px; color: var(--text-darker); margin-top: 0.25rem; }

/* ---------- audit log ---------- */
.audit-wrap { overflow-x: auto; }
.audit-table { width: 100%; min-width: 700px; border-collapse: collapse; text-align: left; }
.audit-table th { padding: 1.25rem 2rem; font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-darker); border-bottom: 2px solid var(--shadow-d); }
.audit-table th.is-right { text-align: right; }
.audit-table td { padding: 1.25rem 2rem; vertical-align: middle; }
.audit-table tbody tr { border-top: 2px solid var(--shadow-d); transition: background 0.2s ease; }
.audit-table tbody tr:hover { background: rgba(255, 255, 255, 0.02); }
.event { display: flex; align-items: center; gap: 1.25rem; }
.event__icon { width: 48px; height: 48px; border-radius: 12px; font-size: 18px; color: var(--text-muted); flex-shrink: 0; }
.event__title { font-weight: 700; font-size: 16px; }
.event__desc { font-size: 14px; color: var(--text-muted); margin-top: 0.25rem; display: flex; align-items: center; gap: 0.5rem; }
.cell-strong { color: var(--text-main); font-weight: 700; font-size: 16px; }
.cell-muted { color: var(--text-muted); font-weight: 400; font-size: 16px; }
.cell-right { text-align: right; }
.mod-link { color: var(--accent); font-weight: 700; font-size: 16px; }
.id-pill { font-family: var(--font-mono); font-size: 12px; color: var(--text-darker); background: var(--flat); padding: 2px 8px; border-radius: 6px; margin-left: 0.5rem; }
.channel-pill { color: var(--accent); font-weight: 700; background: var(--flat); padding: 2px 8px; border-radius: 6px; }
.audit-foot { padding: 1.5rem 2rem; border-top: 2px solid var(--shadow-d); display: flex; justify-content: center; background: rgba(0, 0, 0, 0.1); border-radius: 0 0 20px 20px; }

/* ---------- reaction roles ---------- */
.rr-grid { display: grid; grid-template-columns: 1fr; gap: 2rem; }
.rr-card { padding: 2rem; display: flex; flex-direction: column; }
.rr-card__head { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 1.5rem; }
.rr-card__title { font-size: 20px; margin-bottom: 0.5rem; }
.rr-meta { display: flex; align-items: center; gap: 0.75rem; font-size: 14px; color: var(--text-muted); font-weight: 400; }
.rr-channel { display: flex; align-items: center; gap: 0.5rem; background: var(--flat); padding: 0.4rem 0.75rem; border-radius: 8px; }
.rr-channel .ic { color: var(--text-darker); }
.rr-jump { color: var(--accent); cursor: pointer; display: inline-flex; align-items: center; gap: 0.35rem; }
.rr-card__actions { display: flex; gap: 1rem; }
/* flat on the card it already sits on: no panel, no grey fill, no inset */
.rr-preview { margin-bottom: 1.75rem; }
.rr-preview__row { display: flex; gap: 1.25rem; }
.rr-avatar { width: 48px; height: 48px; border-radius: 50%; background: var(--accent-deep); display: flex; align-items: center; justify-content: center; color: #fff; font-weight: 700; flex-shrink: 0; }
.rr-byline { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.5rem; }
.rr-byline__name { color: var(--text-main); font-weight: 700; font-size: 16px; }
.bot-tag { display: inline-flex; align-items: center; gap: 0.25rem; background: var(--accent-deep); color: #fff; font-size: 10px; font-weight: 700; text-transform: uppercase; padding: 2px 8px; border-radius: 4px; }
.rr-preview__body { color: var(--text-muted); font-size: 16px; }
.rr-list { margin-top: auto; padding-top: 1rem; display: flex; flex-direction: column; gap: 1rem; }
.rr-row { display: flex; align-items: center; gap: 1.25rem; background: var(--flat); padding: 1rem; border-radius: 12px; font-size: 16px; }
.swatch { width: 24px; height: 24px; border-radius: 50%; flex-shrink: 0; box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.4); }
.rr-row__assigns { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-darker); }
.rr-row__role { font-weight: 700; }

/* ---------- custom commands ---------- */
.cmd-grid { display: grid; grid-template-columns: 1fr; gap: 2rem; }
.cmd { padding: 1.5rem; cursor: pointer; }
.cmd__head { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 1.5rem; }
.cmd__tag { background: var(--flat); color: var(--accent); padding: 0.5rem 1rem; border-radius: 8px; font-family: var(--font-mono); font-size: 16px; font-weight: 700; }
.cmd__title { font-size: 20px; margin-bottom: 0.75rem; }
.cmd__desc { font-size: 14px; color: var(--text-muted); display: flex; align-items: center; gap: 0.75rem; }
.cmd__desc .ic { color: var(--text-darker); }

/* ---------- placeholder ---------- */
.placeholder-card { padding: 2.5rem; text-align: center; max-width: 32rem; width: 100%; margin: 0 auto; }
.placeholder-icon { width: 96px; height: 96px; border-radius: 50%; font-size: 36px; color: var(--text-darker); margin: 0 auto 2rem; }
.placeholder-card h2 { font-size: 24px; margin-bottom: 1rem; }
.placeholder-card p { color: var(--text-muted); font-size: 16px; margin-bottom: 2.5rem; line-height: 1.6; }

/* ---------- toast stack ---------- */
.toast-stack { position: fixed; bottom: 24px; right: 24px; display: flex; flex-direction: column; gap: 12px; z-index: 100; }

/* ---------- server picker grid ---------- */
/* Cards stay a sensible size and pack more columns as the screen widens, centered so wide screens do not
   stretch a few huge cards across all that empty space. min(100%, ...) keeps one column from overflowing a phone. */
.server-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 300px)); gap: 1.5rem; margin-top: 1.25rem; justify-content: center; }
.server-card { padding: 1.75rem; display: flex; flex-direction: column; align-items: flex-start; gap: 1rem; }
.server-card.is-unavailable { opacity: 0.6; }
.server-card__icon { width: 56px; height: 56px; border-radius: 50%; background: var(--accent-deep); color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 20px; overflow: hidden; box-shadow: var(--raised-sm); }
/* 037: the server's real Discord icon fills the card slot, the monogram stays the fallback. */
.server-card__icon-img { width: 100%; height: 100%; object-fit: cover; }
.server-card__name { font-size: 18px; font-weight: 700; }
.server-card__note { font-size: 14px; color: var(--text-muted); display: flex; align-items: center; gap: 0.5rem; }
/* 010: a server the bot is not in yet reads dimmer, with its icon greyed, so it is clearly an invite card. */
.server-card--absent { opacity: 0.72; }
.server-card--absent .server-card__icon { background: var(--base); color: var(--text-darker); box-shadow: var(--raised-sm); }
/* 010: the card action (Manage / Selected / Add to server) is the same size and aligned to the card foot. */
.server-card .btn { width: 100%; justify-content: center; margin-top: auto; }
/* 010: after clicking Add to server, the follow-up tells the user how to return and confirm. */
.invite-followup { font-size: 13px; color: var(--text-muted); margin: 0; }

/* 041: the access gate. The page body renders as a dimmed, inert teaser behind an overlay that names the
   missing step. `inert` on the teaser makes the whole subtree non-interactive, the dim is only cosmetic. */
.gate { position: relative; }
.gate-teaser { opacity: 0.45; filter: grayscale(0.35); user-select: none; }
.gate-overlay { position: absolute; inset: 0; display: flex; align-items: flex-start; justify-content: center; padding-top: 2.5rem; }
.gate-overlay__panel { padding: 2.5rem; text-align: center; max-width: 30rem; display: flex; flex-direction: column; align-items: center; gap: 0.25rem; }
.gate-overlay__panel .placeholder-icon { margin-bottom: 1rem; }
.gate-overlay__msg { color: var(--text-muted); margin: 0 0 1.5rem; }
/* 041: a nav entry whose prerequisite is unmet is locked, dimmed and not clickable, with a reason on hover. */
.nav-item.is-locked { opacity: 0.5; cursor: not-allowed; }
.nav-item.is-locked:hover { box-shadow: none; color: inherit; }
.nav-item__lock { margin-left: auto; width: 14px; height: 14px; opacity: 0.8; }

/* 041: the signed-out landing (a short info screen for the bot with the sign-in call to action). */
.landing { max-width: 40rem; margin-top: 1.5rem; }
.landing__lead { font-size: 18px; color: var(--text-muted); margin: 0 0 2rem; line-height: 1.6; }
.landing__highlights { list-style: none; padding: 0; margin: 0 0 2.5rem; display: flex; flex-direction: column; gap: 1rem; }
.landing__highlight { display: flex; align-items: center; gap: 0.85rem; }
.landing__highlight .ic { width: 22px; height: 22px; color: var(--accent); flex-shrink: 0; }
.landing__cta { display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; }
.landing__note { font-size: 14px; color: var(--text-muted); margin: 1.5rem 0 0; }
/* 010: the server name filter and its no-results line. */
.server-search { width: 100%; max-width: 28rem; margin-top: 1.25rem; padding: 0.75rem 1rem; border: none; border-radius: 14px; background: var(--base); box-shadow: var(--pressed); color: var(--text-main); font-size: 15px; }
.server-search:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.server-noresults { margin-top: 1.5rem; color: var(--text-muted); }

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (min-width: 640px) {
    .stats { grid-template-columns: repeat(2, 1fr); }
    .rule__head { flex-direction: row; align-items: flex-start; justify-content: space-between; }
    .rule__controls { align-self: flex-start; }
    .unsaved { flex-direction: row; align-items: center; justify-content: space-between; }
}
@media (min-width: 768px) {
    .app { flex-direction: row; }
    /* Desktop only: the icon<->labelled width slides, gated so page load/navigation does not animate it. */
    .app.nav-ready .sidebar { transition: width 0.28s cubic-bezier(0.4, 0, 0.2, 1); }
    .mobile-bar { display: none; }
    .view-header { padding: 2.5rem 3rem 1.5rem; }
    .view-body { padding: 1rem 3rem 3rem; }
    .view-title { font-size: 36px; }
    .view-header__row { flex-direction: row; align-items: center; justify-content: space-between; }
    .rule, .panel, .rr-card, .cmd, .placeholder-card { padding: 2rem; }
}
@media (min-width: 1024px) {
    .stats { grid-template-columns: repeat(4, 1fr); }
    .rules { grid-template-columns: repeat(3, 1fr); gap: 2.5rem; }
    .rules-col { grid-column: span 2; }
    .cmd-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1280px) {
    .rr-grid { grid-template-columns: repeat(2, 1fr); }
    .cmd-grid { grid-template-columns: repeat(3, 1fr); }
}

/* ---------- portal glue (Blazor-isms over the Aegis kit) ---------- */
/* Blazor NavLink applies "active"; alias it to the Aegis selected-nav look */
.nav-item { text-decoration: none; }
.nav-item.active { box-shadow: var(--pressed-sm); color: var(--text-main); }
.nav-item.active .nav-icon { color: var(--accent); }
/* the main content column scrolls within the shell, the rail and nav stay fixed on desktop */
.app { min-height: 100vh; }
@media (min-width: 768px) {
    .app { height: 100vh; overflow: hidden; }
    .main { min-height: 0; overflow-y: auto; }
}
a { color: inherit; }
/* anchors styled as buttons must not underline (the kit's buttons were <button>) */
.btn, .add-row { text-decoration: none; }
