/* Shadcn UI CSS Variables
 * Provides the design token foundation for shadcn-style components.
 * Per architecture.md Section 3: Component library
 */

:root {
  --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;

  /* Light mode colors - copied from original app's index.css */
  /* Core theme colors */
  /* #fcf8f5 - the reviewed warm canvas the connector prototypes are drawn on */
  --background: 25.71 53.85% 97.45%;
  --foreground: 24.71 68% 9.8%;
  --border: 26.67 22.5% 84.31%;

  /* Button elevate effects */
  --elevate-1: rgba(0,0,0, .03);
  --elevate-2: rgba(0,0,0, .08);
  --button-outline: rgba(0,0,0, .10);
  --opaque-button-border-intensity: -8;

  /* Computed border colors for buttons */
  --primary-border: hsl(from hsl(var(--primary)) h s calc(l + var(--opaque-button-border-intensity)));
  --secondary-border: hsl(from hsl(var(--secondary)) h s calc(l + var(--opaque-button-border-intensity)));
  --destructive-border: hsl(from hsl(var(--destructive)) h s calc(l + var(--opaque-button-border-intensity)));
  --accent-border: hsl(from hsl(var(--accent)) h s calc(l + var(--opaque-button-border-intensity)));
  --muted-border: hsl(from hsl(var(--muted)) h s calc(l + var(--opaque-button-border-intensity)));

  /* Card - elevated surfaces */
  --card: 0 0% 100%;
  --card-foreground: 26.67 77.14% 6.86%;
  --card-border: 0 0% 95%;

  /* Popover */
  --popover: 0 0% 100%;
  --popover-foreground: 26.67 77.14% 6.86%;

  /* Button/Action colors */
  --primary: 26.67 77.14% 6.86%;
  --primary-foreground: 0 0% 100%;

  --secondary: 0 0% 100%;
  --secondary-foreground: 26.67 77.14% 6.86%;

  --muted: 24 33.33% 91.18%;
  --muted-foreground: 23.48 10.41% 43.33%;

  --accent: 334.19 56.58% 29.8%;
  --accent-foreground: 0 0% 100%;

  --destructive: 0 72.16% 61.96%;
  --destructive-foreground: 0 0% 100%;
  --destructive-text: 0 74% 42%; /* Darker red for text on light backgrounds - WCAG AA compliant */

  /* Form input colors */
  --input: 0 0% 71%;
  --input-background: 0 0% 100%;
  --ring: var(--primary); /* Brand consistency: focus ring = primary */
  --radius: 1rem;

  /* Hover state for cards and list items */
  --hover: 28 31% 88%;

  /* Semantic status colors */
  --success: 142 71% 35%;
  --success-foreground: 0 0% 100%;
  --info: 217 91% 60%;
  --info-foreground: 0 0% 100%;
  --warning: 48 96% 89%;
  --warning-foreground: 32 95% 30%;

  /* RAG semantic palette for percentage/risk bars */
  --rag-red: 0 72.16% 61.96%;
  --rag-red-foreground: 0 0% 100%;
  --rag-red-text: 0 74% 42%;
  --rag-amber: 38 92% 50%;
  --rag-amber-foreground: 0 0% 100%;
  --rag-amber-text: 32 95% 30%;
  --rag-green: 142 71% 35%;
  --rag-green-foreground: 0 0% 100%;
  --rag-green-text: 142 72% 28%;

  /* Sidebar colors - matches original Replit design (warm beige/cream) */
  --sidebar: 30 33% 95%;
  --sidebar-foreground: 20 14% 17%;
  --sidebar-border: 45 15% 80%;
  --sidebar-primary: 9 82% 50%; /* #E23C1E - red logo background */
  --sidebar-primary-foreground: 0 0% 100%;
  --sidebar-accent: 30 30% 88%;
  --sidebar-accent-foreground: 20 14% 17%;
  --sidebar-ring: 9 82% 50%;
  --sidebar-brand: 342 56% 30%; /* #77223c - dark maroon for brand text */

  /* Marketing Ember palette — used by pillar page layouts only */
  --marketing-primary: 9 80% 40%;
  --marketing-accent: 20 90% 38%;
  --marketing-brand: 9 70% 32%;
  --marketing-bg: 20 15% 97%;
  --marketing-muted: 20 12% 93%;
  --marketing-muted-fg: 0 0% 42%;
  --marketing-border: 20 10% 87%;
}

/* Dark mode - copied from original app's index.css */
.dark {
  --background: 20 14% 4%;
  --foreground: 45 25% 91%;
  --border: 20 14% 15%;

  /* Button elevate effects (dark mode) */
  --elevate-1: rgba(255,255,255, .04);
  --elevate-2: rgba(255,255,255, .09);
  --button-outline: rgba(255,255,255, .10);
  --opaque-button-border-intensity: 9;

  /* Computed border colors for buttons (dark mode) */
  --primary-border: hsl(from hsl(var(--primary)) h s calc(l + var(--opaque-button-border-intensity)));
  --secondary-border: hsl(from hsl(var(--secondary)) h s calc(l + var(--opaque-button-border-intensity)));
  --destructive-border: hsl(from hsl(var(--destructive)) h s calc(l + var(--opaque-button-border-intensity)));
  --accent-border: hsl(from hsl(var(--accent)) h s calc(l + var(--opaque-button-border-intensity)));
  --muted-border: hsl(from hsl(var(--muted)) h s calc(l + var(--opaque-button-border-intensity)));

  --card: 20 14% 8%;
  --card-foreground: 45 25% 85%;
  --card-border: 20 14% 12%;

  --popover: 20 14% 4%;
  --popover-foreground: 45 25% 91%;

  --primary: 9 75% 61%;
  --primary-foreground: 0 0% 100%;

  --secondary: 30 15% 52%;
  --secondary-foreground: 0 0% 100%;

  --muted: 20 14% 15%;
  --muted-foreground: 45 15% 46%;

  --accent: 25 45% 20%;
  --accent-foreground: 45 25% 85%;

  --destructive: 356 91% 54%;
  --destructive-foreground: 0 0% 100%;
  --destructive-text: 0 70% 55%; /* Lighter for dark backgrounds - WCAG AA compliant */

  --input: 20 14% 18%;
  --ring: 9 75% 61%;

  --success: 142 71% 45%;
  --success-foreground: 0 0% 100%;
  --info: 217 91% 65%;
  --info-foreground: 0 0% 100%;
  --warning: 45 93% 47%;
  --warning-foreground: 0 0% 0%;

  /* RAG semantic palette for percentage/risk bars */
  --rag-red: 356 91% 54%;
  --rag-red-foreground: 0 0% 100%;
  --rag-red-text: 0 70% 55%;
  --rag-amber: 45 93% 47%;
  --rag-amber-foreground: 0 0% 0%;
  --rag-amber-text: 45 100% 65%;
  --rag-green: 142 71% 45%;
  --rag-green-foreground: 0 0% 100%;
  --rag-green-text: 142 65% 58%;

  /* Sidebar colors (dark mode) */
  --sidebar: 20 14% 8%;
  --sidebar-foreground: 45 25% 85%;
  --sidebar-border: 20 14% 15%;
  --sidebar-primary: 9 75% 61%;
  --sidebar-primary-foreground: 0 0% 100%;
  --sidebar-accent: 25 45% 20%;
  --sidebar-accent-foreground: 45 25% 85%;
  --sidebar-ring: 9 75% 61%;
  --sidebar-brand: 9 75% 61%;
}

/* Utility classes */
/* Note: .hidden is provided by Tailwind - don't override with !important
   as it breaks responsive variants like lg:block */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}

/* Base styles */
* {
  border-color: hsl(var(--border));
}

/* Remove default focus ring for mouse clicks, keep for keyboard navigation (accessibility) */
*:focus {
  outline: none;
}

*:focus-visible {
  outline: 2px solid hsl(var(--ring));
  outline-offset: 2px;
}

body {
  background-color: hsl(var(--background));
  color: hsl(var(--foreground));
  font-family: var(--font-sans);
  font-feature-settings: "rlig" 1, "calt" 1;
}

/* Focus ring utility */
.focus-ring {
  outline: 2px solid transparent;
  outline-offset: 2px;
}

.focus-ring:focus-visible {
  outline: 2px solid hsl(var(--ring));
  outline-offset: 2px;
}

/* Error states for form inputs */
input.error,
textarea.error,
select.error {
  border-color: hsl(var(--destructive));
}

input.error:focus-visible,
textarea.error:focus-visible,
select.error:focus-visible {
  outline-color: hsl(var(--destructive));
}

label.error {
  color: hsl(var(--destructive));
}

/* Accordion animations */
@keyframes accordion-down {
  from {
    height: 0;
    opacity: 0;
  }
  to {
    height: var(--accordion-content-height, auto);
    opacity: 1;
  }
}

@keyframes accordion-up {
  from {
    height: var(--accordion-content-height, auto);
    opacity: 1;
  }
  to {
    height: 0;
    opacity: 0;
  }
}

.animate-accordion-down {
  animation: accordion-down 0.2s ease-out forwards;
}

.animate-accordion-up {
  animation: accordion-up 0.2s ease-out forwards;
}

/* Hover elevate effects for buttons and interactive elements */
.btn-primary,
.btn-secondary,
.btn-destructive,
.btn-outline,
.btn-ghost,
.hover-elevate,
.active-elevate,
.hover-elevate-2,
.active-elevate-2 {
  position: relative;
  z-index: 0;
}

.btn-primary::after,
.btn-secondary::after,
.btn-destructive::after,
.btn-outline::after,
.btn-ghost::after,
.hover-elevate::after,
.active-elevate::after,
.hover-elevate-2::after,
.active-elevate-2::after {
  content: "";
  pointer-events: none;
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  z-index: 999;
}

.btn-primary:hover::after,
.btn-secondary:hover::after,
.btn-destructive:hover::after,
.btn-outline:hover::after,
.btn-ghost:hover::after,
.hover-elevate:hover::after,
.active-elevate:active::after {
  background-color: var(--elevate-1);
}

.btn-primary:active::after,
.btn-secondary:active::after,
.btn-destructive:active::after,
.btn-outline:active::after,
.btn-ghost:active::after,
.hover-elevate-2:hover::after,
.active-elevate-2:active::after {
  background-color: var(--elevate-2);
}

/* Disabled button states - no hover effects */
.btn-primary:disabled,
.btn-secondary:disabled,
.btn-destructive:disabled,
.btn-outline:disabled,
.btn-ghost:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

.btn-primary:disabled::after,
.btn-secondary:disabled::after,
.btn-destructive:disabled::after,
.btn-outline:disabled::after,
.btn-ghost:disabled::after {
  display: none;
}

/* ============================================================================
 * Modal / Dialog styles
 * ShadCN-style modal dialogs
 * ============================================================================ */

dialog.modal {
  position: fixed;
  inset: 0;
  margin: auto;
  padding: 0;
  border: none;
  background: transparent;
  max-width: 100vw;
  max-height: 100vh;
  overflow: visible;
}

dialog.modal::backdrop {
  background-color: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(2px);
}

dialog.modal[open] {
  display: flex;
  align-items: center;
  justify-content: center;
}

.modal-box {
  background-color: hsl(var(--card));
  color: hsl(var(--card-foreground));
  border-radius: var(--radius);
  border: 1px solid hsl(var(--border));
  box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
  padding: 1.5rem;
  max-width: 32rem;
  width: calc(100vw - 2rem);
  max-height: calc(100vh - 4rem);
  overflow-y: auto;
  animation: modal-fade-in 0.15s ease-out;
  position: relative;
  z-index: 10;
}

/* The shared helper owns header/body/footer padding and hands scrolling to the
 * body, which is always `min-h-0 overflow-y-auto`. Keep the legacy modal-box
 * defaults for older call sites, but never double-pad a component dialog — and
 * never let its panel scroll too. The panel already asks for `overflow-hidden`,
 * but this rule is unlayered and so outranks that utility on the y axis, and a
 * clipped list inside the body still swells the panel's scrollable area, so a
 * wheel anywhere over the dialog slid the title out of the top and opened dead
 * space under the footer. */
.modal-box.modal-component-panel {
  padding: 0;
  overflow-y: hidden;
}

/* Near-fullscreen modal for media preview */
.modal-box.modal-box-fullscreen {
  width: 90vw !important;
  max-width: 90vw !important;
  height: 90vh !important;
  max-height: 90vh !important;
}

/* Shared details drawer (architecture.md §§3 and 6). The semantic classes
 * live beside the base modal rules so component geometry cannot be weakened
 * by stylesheet layer or source-order differences. */
dialog.modal.modal-drawer {
  inset: 0;
  width: 100vw;
  height: 100dvh;
  max-width: 100vw;
  max-height: 100dvh;
  margin: 0;
  overflow: hidden;
}

dialog.modal.modal-drawer[open] {
  display: flex;
  align-items: stretch;
  justify-content: flex-end;
}

.modal-box.modal-box-drawer {
  width: 100vw;
  max-width: 100vw;
  height: 100dvh;
  max-height: 100dvh;
  padding: 0;
  overflow: hidden;
  border: 0;
  border-radius: 0;
  animation: drawer-slide-in 0.15s ease-out;
}

.modal-box.modal-box-drawer > .min-h-0,
.modal-box.modal-box-drawer > form > .min-h-0 {
  flex: 1 1 0%;
}

.modal-box.modal-box-drawer > form {
  min-height: 0;
  flex: 1 1 0%;
}

/* Drawer content follows the connector-detail prototypes: one continuous
 * surface with divider-led sections, never a stack of cards. */
.drawer-header-mark {
  display: inline-flex;
  width: 2.125rem;
  height: 2.125rem;
  flex: 0 0 2.125rem;
  align-items: center;
  justify-content: center;
  /* A literal radius, not var(--radius): at 1rem the mark rounds into a circle
   * and loses the squared-off silhouette the prototypes give it. */
  border-radius: 0.5rem;
  background: hsl(var(--muted));
  color: hsl(var(--muted-foreground));
}

.drawer-compact-header {
  min-height: 4.5rem;
  align-items: center;
  padding: 0.75rem 1.375rem;
}

.drawer-compact-header > div {
  min-width: 0;
  align-items: center;
}

.drawer-title {
  overflow: hidden;
  font-size: 0.9375rem;
  line-height: 1.25rem;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.drawer-subtitle {
  overflow: hidden;
  margin-top: 0;
  font-size: 0.75rem;
  line-height: 1rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.drawer-header-mark-text {
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 500;
}

.drawer-section {
  border-bottom: 1px solid hsl(var(--border));
}

.drawer-section-trigger {
  display: grid;
  width: 100%;
  min-height: 2.75rem;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 0.625rem;
  padding: 0.625rem 1.375rem;
  text-align: left;
}

.drawer-section-trigger:hover {
  background: hsl(var(--muted) / 0.28);
}

.drawer-section-trigger:focus-visible {
  outline: 2px solid hsl(var(--ring));
  outline-offset: -2px;
}

.drawer-section-title {
  overflow: hidden;
  color: hsl(var(--muted-foreground));
  font-size: 0.6875rem;
  line-height: 1rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-overflow: ellipsis;
  text-transform: uppercase;
  white-space: nowrap;
}

.drawer-section-summary {
  color: hsl(var(--muted-foreground));
  font-size: 0.75rem;
  line-height: 1rem;
  white-space: nowrap;
}

.drawer-section-chevron {
  color: hsl(var(--muted-foreground));
  transition: transform 0.15s ease-out;
}

.drawer-section-content {
  padding: 0 1.375rem 1rem;
}

/* The drawer opens with its search field focused, so the field wears its focus
 * indicator most of the time. The app-wide input ring plus the global
 * :focus-visible outline together draw a slab the prototype does not have —
 * and at `ring-offset-2` it swallows the search icon — so tint the existing
 * border and add a soft halo instead: focus stays obvious, and the field keeps
 * its one-pixel silhouette. */
.drawer-search-input:focus-visible {
  outline: none;
  border-color: hsl(var(--ring));
  box-shadow: 0 0 0 3px hsl(var(--ring) / 0.15);
}

.drawer-account-list {
  display: grid;
  gap: 0.375rem;
  max-height: 20rem;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.drawer-account-row {
  min-height: 2.5rem;
}

.drawer-tool-row {
  min-height: 1.5625rem;
}

.drawer-disconnect {
  padding: 1rem 1.375rem;
}

/* The unlayered `* { border-color }` reset above outranks every layered
   Tailwind border utility, so the failure surface declares its tint here.
   Values are Tailwind red-200 / red-900, inlined so the rule does not depend
   on those palette variables surviving the theme's tree shaking. */
.drawer-verification-failure {
  border-color: oklch(88.5% 0.062 18.334);
}

.dark .drawer-verification-failure {
  border-color: oklch(39.6% 0.141 25.723);
}

.grant-access-dialog-header,
.grant-access-dialog-body,
.grant-access-dialog-footer,
.connection-dialog-header,
.connection-dialog-body,
.connection-dialog-footer {
  padding-right: 1.375rem;
  padding-left: 1.375rem;
}

.accounts-empty-surface {
  min-height: 19.5rem;
  padding: 1.5rem;
}

.accounts-filter-bar {
  min-height: 4rem;
  padding: 0.75rem 1rem;
}

.accounts-search-control {
  width: 100%;
}

/* Fixed table columns, sized from measured content rather than eyeballed shares.
 * The four trailing columns have hard floors — the dotted status chip is 117px,
 * "Calls · 7 days" is a 95px header, and Reconnect plus the chevron is a 147px
 * group — so below the desktop tier the account column yields width instead of
 * letting a right-aligned button ride up over the calls figure. */
.accounts-col-account {
  width: 24%;
}

.accounts-col-status {
  width: 22%;
}

.accounts-col-check {
  width: 18%;
}

.accounts-col-calls {
  width: 19%;
}

.accounts-col-actions {
  width: 17%;
}

/* Stacked connector tiles overlap (-space-x-2), so their fill must be opaque
 * or the tile behind ghosts through the one in front. These flatten the
 * standalone tiles' translucent washes — muted/40 and primary/10 — onto the
 * card they sit on, keeping the same rendered color. */
.connector-tile-opaque-muted {
  background-color: color-mix(in srgb, hsl(var(--muted)) 40%, hsl(var(--card)));
}

.connector-tile-opaque-primary {
  background-color: color-mix(in srgb, hsl(var(--primary)) 10%, hsl(var(--card)));
}

/* Row-end controls — the drilldown chevron and the row-remove ✕. Hover paints
 * the muted wash the drawer's close button and the connected-accounts table
 * already use (WLS-1558 review), so the icon reads as a button before it is
 * clicked; focus stays inside the hit area rather than boxing it. */
.row-chevron {
  display: inline-flex;
  min-width: 2.25rem;
  min-height: 2.25rem;
  align-items: center;
  justify-content: center;
  border-radius: 0.375rem;
  color: hsl(var(--muted-foreground));
}

.row-chevron:hover {
  background-color: hsl(var(--muted));
  color: hsl(var(--foreground));
}

.row-chevron:focus-visible {
  outline: 2px solid hsl(var(--ring));
  outline-offset: -2px;
}

/* Whole-row drill-down, for tables whose rows carry no other controls (Groups).
 * The visible link keeps the text and the accessible name; a stretched
 * pseudo-element hands the rest of the row the same target, so the row hovers
 * and clicks as one thing instead of growing a second, redundant link beside
 * the chevron. Rows with embedded controls keep the `.row-chevron` link. */
.row-link-surface {
  position: relative;
}

.row-link::after {
  content: "";
  position: absolute;
  inset: 0;
}

.api-key-empty-surface {
  min-height: 11rem;
  padding: 1.5rem;
}

.tools-empty-surface {
  min-height: 19.5rem;
}

.tools-search-control {
  width: 100%;
}

.tool-matrix-trigger {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem 1rem;
  padding-right: 2.75rem;
}

.tool-matrix-trigger > :first-child,
.tool-matrix-unavailable {
  grid-column: 1 / -1;
}

.tool-matrix-field {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 0.25rem;
}

.tool-matrix-mobile-label {
  color: hsl(var(--muted-foreground));
  font-size: 0.6875rem;
  line-height: 1rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.tool-matrix-unavailable {
  display: inline-flex;
  min-width: 0;
  align-items: center;
  gap: 0.375rem;
  color: hsl(var(--warning-foreground));
  font-size: 0.75rem;
  line-height: 1rem;
}

.tool-matrix-chevron {
  position: absolute;
  top: 1rem;
  right: 1rem;
}

.tool-classification-card {
  min-height: 4.625rem;
  border: 1px solid hsl(var(--border));
  border-radius: 0.625rem;
  background: hsl(var(--card));
  padding: 0.625rem 0.75rem;
}

/* Alpha is tuned so the band sits ~10/255 below the card surface, matching the
   tint strength sampled from prototype 24. */
.tool-matrix-row-destructive {
  background: hsl(var(--destructive) / 0.06);
}

.dark .tool-matrix-row-destructive {
  background: hsl(var(--destructive) / 0.08);
}

@media (min-width: 80rem) {
  /* Minimums are budgeted against the narrowest desktop viewport (1280px, which
     leaves 910px inside the card): 16rem + 5.5rem + 6 x 4.5rem + 2rem + 8 x
     0.75rem gaps = 904px. The tool minimum clears the longest tool name
     (~252px) so names stay on one line instead of breaking mid-identifier. */
  .tool-matrix-grid {
    grid-template-columns:
      minmax(16rem, 2.5fr)
      5.5rem
      repeat(6, minmax(4.5rem, 1fr))
      2rem;
    column-gap: 0.75rem;
    align-items: center;
  }

  .tool-matrix-grid-basic {
    grid-template-columns: minmax(16rem, 1fr) 8rem 2rem;
  }

  .tool-matrix-trigger {
    padding-right: 1rem;
  }

  .tool-matrix-trigger > :first-child,
  .tool-matrix-unavailable {
    grid-column: auto;
  }

  .tool-matrix-field {
    display: block;
  }

  /* Hidden visually — the column headers carry the labels at this width — but
     kept in the accessible name so a row reads "tool, tier: read, effect:
     informational" rather than a run-on list of bare values. */
  .tool-matrix-mobile-label {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border-width: 0;
  }

  .tool-matrix-chevron {
    position: static;
  }

  .tool-detail-classification-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .tools-classification-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 40rem) {
  .tools-search-control {
    width: 16rem;
  }
}

.grant-access-dialog-body {
  padding-top: 1rem;
  padding-bottom: 1rem;
}

.grant-access-dialog-footer {
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
}

.connection-dialog-body {
  padding-top: 1rem;
  padding-bottom: 1rem;
}

.connection-dialog-footer {
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
}

/* Subtitles wrap: a nowrap line one word longer than the dialog overflows it
 * (the "Grant key access" copy did exactly that at md width). */
.grant-access-dialog-subtitle {
  font-size: 0.8125rem;
  line-height: 1.125rem;
}

.grant-access-dialog-preview {
  padding: 0.625rem 0.75rem;
  font-size: 0.8125rem;
  line-height: 1.125rem;
}

.connection-dialog-subtitle {
  font-size: 0.8125rem;
  line-height: 1.125rem;
}

.access-filter-bar {
  min-height: 4rem;
  padding: 0.75rem 1rem;
}

/* Access identity table columns.
 *
 * Every column except identity is a constant, because every one of them holds
 * an indivisible group: three tier controls and their gaps, a "Aug 14, 2026"
 * date, and — on a dirty row — Save beside the chevron. Identity is the only
 * column that degrades gracefully (it truncates), so it takes `auto` and
 * absorbs whatever the viewport leaves. That is the prototype's own behaviour:
 * between its 1465 and 1280 frames the trailing columns hold their widths to
 * the pixel and identity alone gives up the 185px.
 *
 * Percentages were tried first and are wrong here — a share of the table starves
 * the tier group on a narrower desktop, wrapping the controls onto a second line
 * and growing the row from 55px to 93px. */
.access-col-select {
  width: 2.5rem;
}

.access-col-identity {
  width: auto;
}

.access-col-level {
  width: 16.75rem;
}

.access-col-granted {
  width: 7.75rem;
}

/* The acting admin behind the grant (avatar + truncating name). It is the one
 * column the table can do without, so between `md` and `xl` — where the reviewed
 * widths already leave identity nothing to spare — the cell is hidden outright
 * rather than allowed to starve identity or overflow the card. Below `md` the
 * row is a labelled card and it comes back as its own band. */
.access-col-granted-by {
  width: 11rem;
}

.access-col-actions {
  width: 7rem;
}

/* The API-keys table trades the people table's leading select column (keys have
 * no bulk operations) for the key's connection scope — "All" or "1 of 8". Every
 * other column keeps the reviewed width so the two tables line up down the page.
 * 8rem is what the uppercase CONNECTIONS head needs before its padding — at
 * 6.5rem the head filled the column and visually collided with GRANTED. */
.access-col-connections {
  width: 8rem;
}

/* The reviewed widths, measured off prototypes 14 and 18: 54 / 311 / 175 / 111.
 * They apply from 1280 — the narrower of the two prototype frames — up. Below
 * that a sidebar layout cannot afford them (at 1024 the table is 686px and they
 * would leave identity 35px), so the content minimums above take over. */
@media (min-width: 80rem) {
  .access-col-select {
    width: 3.375rem;
  }

  .access-col-level {
    width: 19.4375rem;
  }

  /* The date column gives up 43px so the acting admin fits beside it: "Aug 14,
   * 2026" needs ~90px of the reviewed 175px, and identity should not pay for
   * the whole new column on its own. */
  .access-col-granted {
    width: 8.25rem;
  }
}

/* Below the table tier the row becomes a labelled card. Selection, identity and
 * the drilldown share the first line — stacked as their own full-width bands,
 * the checkbox and the chevron each floated in an empty strip — and the tier
 * controls and grant date follow as labelled lines. These grid properties are
 * inert from `md` up, where the row is a table-row again. */
.access-row {
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas:
    "select identity actions"
    "level level level"
    "granted granted granted"
    "granted-by granted-by granted-by";
}

.access-cell-select {
  grid-area: select;
}

.access-cell-identity {
  grid-area: identity;
}

.access-cell-level {
  grid-area: level;
}

.access-cell-granted {
  grid-area: granted;
}

.access-cell-granted-by {
  grid-area: granted-by;
}

.access-cell-actions {
  grid-area: actions;
}

.access-cell-connections {
  grid-area: connections;
}

/* The same table read the other way round — one subject's connectors, on that
 * subject's own page (group, member, key). There is no bulk selection here, so
 * below the table tier the connector opens the card and the revoke control
 * closes it; the member page's Source band sits between the connector and the
 * tiers it qualifies. */
.access-row-subject {
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "identity actions"
    "level level"
    "granted granted"
    "granted-by granted-by";
}

.access-row-subject-source {
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "identity actions"
    "source source"
    "level level"
    "granted granted"
    "granted-by granted-by";
}

.access-cell-source {
  grid-area: source;
}

/* A row filtered out by `searchable-list` must actually disappear. The `hidden`
 * attribute alone cannot do it here: the UA rule lands in `:where()` at zero
 * specificity, so the row's own `md:table-row` display utility outranks it and
 * the row would keep rendering from the table tier up. */
.access-row[hidden],
.keys-row[hidden] {
  display: none;
}

/* Source names a group ("via Apprentices") and may stack the Overridden pill
 * beneath it — the date column's width truncates real group names, so the
 * column gets its own reviewed width. Identity remains the elastic column. */
.access-col-source {
  width: 10.5rem;
}

/* At the 1280 desktop breakpoint, Granted by returns and leaves the member
 * table's elastic Connector column only wide enough for its logo. Keep the
 * semantic heading for assistive technology, but wait until the column has
 * room again before showing the duplicate visual label. */
.access-source-connector-heading {
  display: none;
}

@media (min-width: 90rem) {
  .access-source-connector-heading {
    display: inline;
  }
}

/* A key row carries no select checkbox, so below the table tier the name and the
 * drilldown open the card between them and the scope band follows the tiers. */
.access-row-key {
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "identity actions"
    "level level"
    "connections connections"
    "granted granted"
    "granted-by granted-by";
}

/* The Team table (WLS-1567). It answers a different question from the grant
 * tables — a member's standing, their groups, and everything they can reach —
 * so it gets its own columns rather than borrowing `.access-col-*` labels that
 * would have to lie about what they hold. The member is the elastic column, as
 * identity is over there; below the table tier the row collapses to the same
 * labelled card, with the member and the drilldown sharing the first line. */
.team-col-member {
  width: auto;
}

.team-col-role {
  width: 6.5rem;
}

.team-col-groups {
  width: 11rem;
}

.team-col-access {
  width: 10rem;
}

.team-col-joined {
  width: 7.75rem;
}

.team-col-actions {
  width: 3.5rem;
}

.team-row {
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "member actions"
    "role role"
    "groups groups"
    "access access"
    "joined joined";
}

.team-row-no-groups {
  grid-template-areas:
    "member actions"
    "role role"
    "access access"
    "joined joined";
}

.team-cell-member {
  grid-area: member;
}

.team-cell-role {
  grid-area: role;
}

.team-cell-groups {
  grid-area: groups;
}

.team-cell-access {
  grid-area: access;
}

.team-cell-joined {
  grid-area: joined;
}

.team-cell-actions {
  grid-area: actions;
}

/* The Groups table asks the Team table's question of a group — its staffing,
 * its reach, its age — so it takes the same dedicated-column treatment. The
 * group is the elastic column; members and access each hold an indivisible
 * stack, and below the table tier the row collapses to the same labelled card
 * with the group and the drilldown sharing the first line. */
.groups-col-group {
  width: auto;
}

.groups-col-members {
  width: 11.5rem;
}

.groups-col-access {
  width: 10rem;
}

.groups-col-created {
  width: 7.75rem;
}

.groups-col-actions {
  width: 3.5rem;
}

.groups-row {
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "group actions"
    "members members"
    "access access"
    "created created";
}

.groups-cell-group {
  grid-area: group;
}

.groups-cell-members {
  grid-area: members;
}

.groups-cell-access {
  grid-area: access;
}

.groups-cell-created {
  grid-area: created;
}

.groups-cell-actions {
  grid-area: actions;
}

/* The API keys table (WLS-1570). Like the Team table it answers its own
 * question — every key in the workspace, what it can reach and who made it —
 * so it gets its own columns rather than borrowing `.access-col-*` labels that
 * hold different things here. The key is the elastic column: it stacks a name
 * over a monospace client id and truncates, while every other column holds an
 * indivisible group (a pill, a logo stack, a date, an avatar + name).
 *
 * It is the only grant-area table with a leading select column, because bulk
 * revoke lives here and nowhere else. */
.keys-col-select {
  width: 2.5rem;
}

.keys-col-key {
  width: auto;
}

.keys-col-status {
  width: 6.5rem;
}

.keys-col-connectors {
  width: 8.5rem;
}

.keys-col-used {
  width: 8rem;
}

.keys-col-created {
  width: 7.75rem;
}

.keys-col-created-by {
  width: 11rem;
}

.keys-col-actions {
  width: 3.5rem;
}

@media (min-width: 80rem) {
  .keys-col-select {
    width: 3.375rem;
  }
}

.keys-row {
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas:
    "select key actions"
    "status status status"
    "connectors connectors connectors"
    "used used used"
    "created created created"
    "created-by created-by created-by";
}

.keys-cell-select {
  grid-area: select;
}

.keys-cell-key {
  grid-area: key;
}

.keys-cell-status {
  grid-area: status;
}

.keys-cell-connectors {
  grid-area: connectors;
}

.keys-cell-used {
  grid-area: used;
}

.keys-cell-created {
  grid-area: created;
}

.keys-cell-created-by {
  grid-area: created-by;
}

.keys-cell-actions {
  grid-area: actions;
}

/* A selected row reads as picked rather than merely hovered, and holds that
 * reading while the pointer is elsewhere in the table. */
.keys-row[data-state="selected"] {
  background: hsl(var(--muted) / 0.5);
}

/* The reviewed 55px row. Tier controls hold a 36px hit target, which on its own
 * leaves a 53px row; this restores the prototype's rhythm without shrinking the
 * target, and taller identity rows still grow past it. The keys row stacks a
 * client id under the name, so it sets a minimum instead of a fixed height. */
@media (min-width: 48rem) {
  .access-row,
  .team-row,
  .groups-row {
    height: 3.375rem;
  }

  .keys-row {
    height: 3.75rem;
  }

  /* The 32px header band. Stated outright because otherwise it is the tallest
   * thing the header happens to contain, and a viewer — who gets no select-all
   * checkbox — would read a 28px band where an owner reads 32px. */
  .access-head-row {
    height: 2rem;
  }
}

.access-empty-surface {
  min-height: 19.5rem;
  padding: 1.5rem;
}

.activity-empty-surface {
  min-height: 18.25rem;
}

@media (min-width: 64rem) {
  .activity-filter-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .activity-filter-summary {
    grid-column: 1 / -1;
  }
}

@media (min-width: 40rem) {
  .accounts-search-control {
    width: 16rem;
  }

  .activity-event-row {
    min-height: 5.5rem;
  }
}

/* Prototypes 08/12 are drawn at desktop, where the account column carries the
 * reviewed weight and the trailing columns relax back toward their content. */
@media (min-width: 80rem) {
  .accounts-col-account {
    width: 39%;
  }

  .accounts-col-status {
    width: 16%;
  }

  .accounts-col-check {
    width: 13%;
  }

  .accounts-col-calls {
    width: 14%;
  }

  .accounts-col-actions {
    width: 18%;
  }
}

.overview-warning {
  border-color: hsl(var(--warning-foreground) / 0.25);
  background: hsl(var(--warning));
  color: hsl(var(--warning-foreground));
}

.overview-warning-action {
  border-color: hsl(var(--warning-foreground) / 0.3);
  background: hsl(var(--background));
  color: hsl(var(--foreground));
}

.overview-warning-dismiss:hover {
  background: hsl(var(--warning-foreground) / 0.08);
}

/* Overview summary cards. The prototype's mock face is ~10% narrower than Inter, so
   the supporting lines run at 13px to keep the prototype's one-line meta rhythm, and
   the footer seats meta and action on a single ink baseline. Touch keeps the full
   36px target; from sm up the action pads back to 28px with a matching negative
   margin, so the prototype's tight footer costs no height. */
.overview-card-meta,
.overview-card-footer {
  font-size: 0.8125rem;
  line-height: 1.25rem;
}

.overview-card-action {
  min-height: 2.25rem;
}

@media (min-width: 640px) {
  .overview-card-action {
    min-height: 0;
    padding-top: 0.25rem;
    padding-bottom: 0.25rem;
    margin-top: -0.25rem;
    margin-bottom: -0.25rem;
  }
}

.overview-spark-bar {
  flex: 1 1 0%;
  min-height: 2px;
  border-start-start-radius: 3px;
  border-start-end-radius: 3px;
}

/* The kind chip sits on the identity line and never wraps below the name: the
 * name truncates instead, so a narrow identity column costs characters rather
 * than a second line and the row keeps its 55px rhythm. */
.access-kind-badge {
  flex-shrink: 0;
  padding: 0.0625rem 0.375rem;
  font-size: 0.6875rem;
  line-height: 0.875rem;
}

dialog.modal.modal-drawer .modal-backdrop {
  display: none;
}

@media (min-width: 640px) {
  .modal-box.modal-box-drawer {
    width: 452px;
    max-width: 452px;
    border-left: 1px solid hsl(var(--border));
    border-radius: 0;
  }

  dialog.modal.modal-drawer .modal-backdrop {
    display: block;
    right: 452px;
  }
}

@media (max-width: 639px) {
  .drawer-compact-header,
  .drawer-section-trigger,
  .drawer-disconnect,
  .grant-access-dialog-header,
  .grant-access-dialog-body,
  .grant-access-dialog-footer,
  .connection-dialog-header,
  .connection-dialog-body,
  .connection-dialog-footer {
    padding-right: 1rem;
    padding-left: 1rem;
  }

  .drawer-section-content {
    padding-right: 1rem;
    padding-bottom: 1rem;
    padding-left: 1rem;
  }
}

@keyframes drawer-slide-in {
  from {
    opacity: 0;
    transform: translateX(1rem);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-delay: 0s !important;
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-delay: 0s !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

@media (min-width: 640px) {
  .overview-activity-row {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1.2fr) minmax(0, 1.2fr) auto auto;
    align-items: center;
  }
}

@keyframes modal-fade-in {
  from {
    opacity: 0;
    transform: scale(0.95);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

.modal-header {
  margin-bottom: 1rem;
}

.modal-footer {
  margin-top: 1.5rem;
  border-top: 1px solid hsl(var(--border));
  padding-top: 1rem;
}

.modal-backdrop {
  position: fixed;
  inset: 0;
  cursor: default;
  /* z-index -1 to stay behind modal-box content */
  z-index: -1;
}

.modal-backdrop button {
  opacity: 0;
  position: absolute;
  inset: 0;
  cursor: default;
}

/* Section accordion icon rotation
 * Section accordion UI
 * Uses data-state attribute instead of inline styles */
[data-section-accordion-target="icon"][data-state="open"] {
  transform: rotate(180deg);
}

/* ============================================================================
 * Settings modal responsive styles
 * Mobile full-screen modal
 * ============================================================================ */

/* Mobile full-screen for settings modal */
@media (max-width: 639px) {
  dialog#settings-modal .modal-box {
    max-width: 100vw !important;
    max-height: 100vh !important;
    width: 100vw !important;
    height: 100vh !important;
    border-radius: 0;
    margin: 0;
  }
}
