/*
 * Robovue component library, organized per CUBE CSS (see docs/design-system.md):
 * Composition/Utility primitives live in base.css; this file holds Blocks
 * (the real components) and Exceptions (state/variant handling via data-*
 * attributes rather than proliferating modifier classes).
 *
 * Every value here should be a var() reference into tokens.css — no raw
 * hex/oklch literals or magic-number spacing (enforced by
 * scripts/check-design-tokens.sh).
 */

/* ---------- Site header / nav (Block: .site-header) ---------- */

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-5);
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border-subtle);
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  min-height: var(--header-height);
}

.site-header .brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: var(--font-weight-bold);
  font-size: var(--text-lg);
  color: var(--text-primary);
  text-decoration: none;
}

.nav-toggle-summary {
  display: none;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
  list-style: none;
  color: var(--text-secondary);
}

.nav-toggle-summary::-webkit-details-marker {
  display: none;
}

.nav-toggle-summary:hover {
  background: var(--bg-surface-hover);
}

/* <details> is used purely as a toggle-state holder (its [open] attribute),
   never as a container for the real nav content — putting flex content
   *inside* <details> and overriding its native content-hiding broke its
   intrinsic width/height sizing in real testing (a genuine browser quirk in
   how <details> participates in flex layout, not just a specificity issue).
   .nav-panel is a normal sibling of <details> instead; :has() reads the
   toggle's open state to control it at mobile widths (see media query
   below) — Baseline since ~2023, safe for this app's modern-browser stance. */
details.nav-toggle {
  display: contents;
}

.nav-panel {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-width: 0;
}

.primary-nav {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.primary-nav a {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  text-decoration: none;
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
}

.primary-nav a:hover {
  background: var(--bg-surface-hover);
  color: var(--text-primary);
}

.primary-nav a[aria-current="page"] {
  color: var(--accent-text);
  background: var(--status-neutral-subtle-bg);
}

.primary-nav .nav-icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

.user-menu {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  border-left: 1px solid var(--border-subtle);
  padding-left: var(--space-3);
  font-size: var(--text-xs);
  color: var(--text-tertiary);
}

/* Theme toggle (ADR 0020) — a single icon button that cycles
   System -> Light -> Dark -> System; theme-toggle.js swaps the icon and
   aria-label to reflect the current state. Same square-icon-button
   footprint as .nav-toggle-summary. */
.theme-toggle-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
}

.theme-toggle-btn:hover {
  background: var(--bg-surface-hover);
  color: var(--text-primary);
}

.theme-toggle-btn .nav-icon {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

@media (max-width: 767px) {
  .nav-toggle-summary {
    display: flex;
  }

  /* At this breakpoint <details> needs to be a normal box again — its
     [open] state (native, zero-JS) is what the .site-header:has() rule
     below reads to show/hide the sibling .nav-panel. */
  details.nav-toggle {
    display: block;
  }

  .nav-panel {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-3);
    background: var(--bg-surface);
    border-bottom: 1px solid var(--border-subtle);
    padding: var(--space-3) var(--space-5);
    box-shadow: var(--shadow-popover);
  }

  .site-header:has(details.nav-toggle[open]) .nav-panel {
    display: flex;
  }

  .primary-nav {
    flex-direction: column;
    align-items: stretch;
  }

  .user-menu {
    border-left: none;
    border-top: 1px solid var(--border-subtle);
    padding-left: 0;
    padding-top: var(--space-3);
  }
}

/* ---------- Card / Panel (Blocks) ---------- */

.card {
  max-width: 28rem;
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-card);
}

.panel {
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  margin-block-end: var(--space-4);
}

.panel[data-tone="danger"] {
  border-color: var(--status-error-border);
}

.panel[data-tone="danger"] h2,
.panel[data-tone="danger"] h3 {
  color: var(--status-error-text);
}

/* Auth shell — full-height centered layout for Login/GetStarted/AccountDeleted,
   toggled via a ViewData-driven body class rather than a second _Layout. */
body.auth-shell .site-main {
  min-height: calc(100vh - 4rem);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Brand mark above the heading in _AuthCard.cshtml — reuses .brand's flex/type styling;
   .brand has no icon anywhere else today, so the icon sizing is scoped here rather than
   added to the shared .brand rule. */
.auth-brand {
  margin-block-end: var(--space-4);
}

.auth-brand svg {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

/* ---------- Status badge (Block + Exception) ---------- */

.status-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0.125rem var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  line-height: 1.4;
  border: 1px solid transparent;
  white-space: nowrap;
}

.status-badge__icon {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

.status-badge[data-status="ok"] {
  background: var(--status-ok-subtle-bg);
  color: var(--status-ok-text);
  border-color: var(--status-ok-border);
}

.status-badge[data-status="warning"] {
  background: var(--status-warning-subtle-bg);
  color: var(--status-warning-text);
  border-color: var(--status-warning-border);
}

.status-badge[data-status="error"] {
  background: var(--status-error-subtle-bg);
  color: var(--status-error-text);
  border-color: var(--status-error-border);
}

.status-badge[data-status="neutral"] {
  background: var(--status-neutral-subtle-bg);
  color: var(--status-neutral-text);
  border-color: var(--status-neutral-border);
}

/* ---------- Data table (Block + Exception) ---------- */

.table-wrapper {
  container-type: inline-size;
  margin-block-end: var(--space-4);
}

.data-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--bg-surface);
}

.data-table th,
.data-table td {
  text-align: left;
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border-subtle);
}

.data-table thead th {
  color: var(--text-tertiary);
  font-weight: var(--font-weight-medium);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* data-collapse="stack" — each row becomes a labeled card. Container query
   context lives on the wrapper div, never the table/row/cell themselves
   (table-display elements are incompatible with container-type). */
@container (max-width: 640px) {
  .table-wrapper[data-collapse="stack"] table,
  .table-wrapper[data-collapse="stack"] tbody,
  .table-wrapper[data-collapse="stack"] tr,
  .table-wrapper[data-collapse="stack"] td {
    display: block;
    width: 100%;
  }

  .table-wrapper[data-collapse="stack"] thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  .table-wrapper[data-collapse="stack"] tr {
    margin-block-end: var(--space-3);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: var(--space-2) var(--space-3);
  }

  .table-wrapper[data-collapse="stack"] td {
    border: none;
    padding: var(--space-1) 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
  }

  .table-wrapper[data-collapse="stack"] td::before {
    content: attr(data-label);
    font-weight: var(--font-weight-medium);
    color: var(--text-tertiary);
    font-size: var(--text-xs);
  }
}

/* data-collapse="scroll" — dense/timestamp-heavy tables scroll horizontally
   with the first column pinned, instead of losing at-a-glance scannability
   by collapsing into cards. */
.table-wrapper[data-collapse="scroll"] {
  overflow-x: auto;
}

@container (max-width: 640px) {
  .table-wrapper[data-collapse="scroll"] table {
    min-width: 640px;
  }

  .table-wrapper[data-collapse="scroll"] th:first-child,
  .table-wrapper[data-collapse="scroll"] td:first-child {
    position: sticky;
    left: 0;
    background: var(--bg-surface);
  }
}

/* ---------- Button (Block + Exception) ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--text-body);
  font-weight: var(--font-weight-medium);
  line-height: 1.2;
  border: 1px solid var(--border-default);
  background: var(--bg-surface);
  color: var(--text-primary);
  cursor: pointer;
  text-decoration: none;
}

.btn:hover {
  background: var(--bg-surface-hover);
}

.btn[data-variant="secondary"] {
  background: var(--bg-surface);
  border-color: var(--border-default);
  color: var(--text-primary);
}

.btn[data-variant="primary"] {
  background: var(--accent-solid);
  border-color: var(--accent-solid);
  color: var(--accent-contrast);
}

.btn[data-variant="primary"]:hover {
  background: var(--accent-solid-hover);
  border-color: var(--accent-solid-hover);
}

.btn[data-variant="danger"] {
  background: var(--status-error-solid);
  border-color: var(--status-error-solid);
  color: var(--gray-0);
}

.btn[disabled],
.btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
}

/* ---------- Form fields (Block) ---------- */

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-block-end: var(--space-3);
  max-width: 32rem;
}

.field label {
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  color: var(--text-secondary);
}

.field input,
.field select,
.field textarea {
  font: inherit;
  color: var(--text-primary);
  background: var(--bg-canvas);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
}

.field .field-error {
  color: var(--status-error-text);
  font-size: var(--text-xs);
}

/* ---------- Code block (Block, wraps Prism's own toolbar markup) ---------- */

.code-block {
  margin-block: var(--space-3);
  border-radius: var(--radius-lg);
  overflow: hidden;
  border: 1px solid var(--border-subtle);
}

.code-block pre[class*="language-"] {
  margin: 0;
  border-radius: 0;
}

div.code-toolbar > .toolbar {
  opacity: 1;
}

div.code-toolbar > .toolbar .toolbar-item > button {
  background: var(--bg-surface-hover);
  color: var(--text-secondary);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  padding: var(--space-1) var(--space-2);
}

div.code-toolbar > .toolbar .toolbar-item > button:hover {
  background: var(--bg-surface);
  color: var(--text-primary);
}

/* Prism token color overrides — maps prism-tomorrow.min.css's hardcoded
   hex literals onto this app's semantic tokens so code blocks adapt to
   light/dark mode instead of staying a fixed dark box. */

/* prism-tomorrow.min.css sets a hardcoded light-grey text color directly on
   BOTH the <pre> and the nested <code> (its selector list is
   `code[class*=language-], pre[class*=language-] { color: <that grey> }`) —
   a direct declaration on the <code> element itself, which a parent <pre>
   override can't beat via inheritance. The previous override only
   re-targeted `pre` and standalone (`:not(pre) > code`) elements, leaving
   `pre > code`'s own direct color intact. That measured 1.39:1 contrast
   against light mode's near-white --bg-surface (axe-core color-contrast,
   docs/design-system.md's recipe) — the concrete cause of code reading as
   grey/washed out in light mode. Background is fine left un-duplicated
   here: the vendor's own background rule already excludes `pre > code`
   (transparent, so the pre's own background paints through), only color
   needed this fix. */
pre[class*="language-"],
code[class*="language-"],
:not(pre) > code[class*="language-"] {
  color: var(--text-primary);
}

pre[class*="language-"],
:not(pre) > code[class*="language-"] {
  background: var(--bg-surface);
}

.token.block-comment,
.token.cdata,
.token.comment,
.token.doctype,
.token.prolog {
  color: var(--code-comment-text);
}

.token.punctuation,
.token.entity,
.token.operator,
.token.url {
  color: var(--code-punctuation-text);
}

.token.attr-name,
.token.deleted,
.token.namespace,
.token.tag {
  color: var(--code-tag-text);
}

.token.class-name,
.token.constant,
.token.property,
.token.symbol,
.token.function-name {
  color: var(--code-class-text);
}

.token.boolean,
.token.function,
.token.number {
  color: var(--code-number-text);
}

.token.atrule,
.token.builtin,
.token.important,
.token.keyword,
.token.selector {
  color: var(--code-keyword-text);
  font-weight: var(--font-weight-medium);
}

.token.attr-value,
.token.char,
.token.inserted,
.token.regex,
.token.string,
.token.variable {
  color: var(--code-string-text);
}

.token.bold,
.token.important {
  font-weight: var(--font-weight-bold);
}

.code-block[data-lang]::before {
  content: attr(data-lang);
  display: block;
  padding: var(--space-1) var(--space-3);
  background: var(--bg-surface-hover);
  color: var(--text-tertiary);
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--border-subtle);
}

/* ---------- Empty state (Block) ---------- */

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-3);
  padding: var(--space-8) var(--space-4);
  color: var(--text-secondary);
}

.empty-state__icon {
  width: 2.5rem;
  height: 2.5rem;
  color: var(--text-tertiary);
}

.empty-state h3 {
  margin: 0;
}

.empty-state p {
  max-width: 40ch;
  margin: 0;
}

/* ---------- Inline alert / toast (Block + Exception) ---------- */

.inline-alert {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid;
  font-size: var(--text-body);
  margin-block: var(--space-3);
}

.inline-alert[data-tone="error"] {
  background: var(--status-error-subtle-bg);
  border-color: var(--status-error-border);
  color: var(--status-error-text);
}

.inline-alert[data-tone="warning"] {
  background: var(--status-warning-subtle-bg);
  border-color: var(--status-warning-border);
  color: var(--status-warning-text);
}

.inline-alert[data-tone="info"] {
  background: var(--status-neutral-subtle-bg);
  border-color: var(--status-neutral-border);
  color: var(--text-secondary);
}

.toast-region {
  position: fixed;
  bottom: var(--space-4);
  right: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  z-index: 1000;
}

.toast {
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  box-shadow: var(--shadow-popover);
  color: var(--text-primary);
  font-size: var(--text-xs);
  max-width: 320px;
}

.toast[data-tone="warning"] {
  border-color: var(--status-warning-border);
}

.toast[data-tone="error"] {
  border-color: var(--status-error-border);
}

/* ---------- Plan card (Block, Billing) ---------- */

.plans-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-4);
  margin-block: var(--space-4);
}

.plan-card {
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.plan-card[data-current="true"] {
  border-color: var(--accent-solid);
  box-shadow: 0 0 0 1px var(--accent-solid);
}

.plan-card h3 {
  margin-block-end: 0;
}

.plan-card__price {
  font-size: var(--text-xl);
  font-weight: var(--font-weight-bold);
  color: var(--text-primary);
}

.plan-card ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  color: var(--text-secondary);
  font-size: var(--text-xs);
}

.plan-card ul li {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.plan-card p {
  margin: 0;
  font-size: var(--text-xs);
}

/* ---------- Identity strip + disclosure (Blocks, Runs/Details) ---------- */

.identity-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  background: var(--bg-surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  margin-block-end: var(--space-4);
}

.identity-strip > div {
  min-width: 0;
}

.identity-strip dt {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  margin-block-end: var(--space-1);
}

.identity-strip dd {
  margin: 0;
  color: var(--text-primary);
  font-size: var(--text-body);
}

.disclosure > summary {
  cursor: pointer;
  font-weight: var(--font-weight-medium);
  color: var(--text-secondary);
  padding: var(--space-2) 0;
}

.disclosure > summary:hover {
  color: var(--text-primary);
}

/* ---------- Connect page-in-page nav + check-in widget (Blocks, Connect) ---------- */

.connect-toc {
  position: sticky;
  top: var(--header-height);
  z-index: var(--z-sticky-subnav);
  display: flex;
  gap: var(--space-2);
  padding: var(--space-3) 0;
  background: var(--bg-canvas);
  border-bottom: 1px solid var(--border-subtle);
  margin-block-end: var(--space-4);
  overflow-x: auto;
}

.connect-toc a {
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  text-decoration: none;
  font-size: var(--text-xs);
  font-weight: var(--font-weight-medium);
  white-space: nowrap;
}

.connect-toc a:hover {
  background: var(--bg-surface-hover);
  color: var(--text-primary);
}

.connect-toc-select {
  display: none;
  font: inherit;
  color: var(--text-primary);
  background: var(--bg-canvas);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
}

/* Keeps a jump-nav target's heading clear of the sticky .connect-toc above it.
   Only needed at widths where .connect-toc is actually sticky (see the
   640px collapse to .connect-toc-select below) — a non-sticky nav needs no
   scroll offset, and adding one would just leave dead space above the
   heading on mobile. */
@media (min-width: 641px) {
  #setup,
  #dotnet-sdk,
  #other-languages,
  #uipath {
    scroll-margin-top: calc(var(--header-height) + var(--space-8));
  }
}

@media (max-width: 640px) {
  .connect-toc {
    display: none;
  }

  .connect-toc-select {
    display: block;
    width: 100%;
    margin-block-end: var(--space-4);
  }
}

.check-in-widget {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-lg);
  border: 1px solid var(--border-subtle);
  background: var(--bg-surface);
  margin-block-end: var(--space-4);
  color: var(--text-secondary);
}

.check-in-widget[data-state="success"] {
  border-color: var(--status-ok-border);
  background: var(--status-ok-subtle-bg);
  color: var(--status-ok-text);
}

.check-in-widget .pulse-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent-solid);
  flex-shrink: 0;
  animation: pulse-dot 1.5s ease-in-out infinite;
}

@keyframes pulse-dot {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

@media (prefers-reduced-motion: reduce) {
  .check-in-widget .pulse-dot {
    animation: none;
  }
}
