/*
 * skillvault.css — semantic layer with design tokens + dark mode.
 *
 * DESIGN TOKENS
 * =============
 * Colors are exposed as CSS custom properties using space-separated RGB
 * triplets so they can feed both `rgb(var(--sv-x))` here and Tailwind's
 * `rgb(var(--sv-x) / <alpha-value>)` utilities via the inline tailwind.config.
 *
 *   --sv-bg             page background
 *   --sv-surface        card / panel background
 *   --sv-border         hairline borders (tables, list dividers)
 *   --sv-border-strong  card borders
 *   --sv-text           default foreground
 *   --sv-muted          secondary text
 *   --sv-primary        brand / header & active accents (slate)
 *   --sv-accent         links / info accents (blue)
 *   --sv-verified-*     verified badge colours
 *   --sv-user-*         user badge colours
 *   --sv-public-*       public badge colours
 *
 * Typography: system font stack with optional Inter webfont (loaded in
 * base.html). Spacing: --space (1rem) base rhythm. Radius: --radius (8px)
 * cards, --radius-full for pills/badges.
 *
 * Dark mode: the `dark` class (sets <html data-theme="dark">) swaps the
 * palette above. The header stays near-black in both modes.
 */
:root {
  --sv-font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI",
    Roboto, "Helvetica Neue", Arial, sans-serif;
  --sv-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
    "Liberation Mono", "Courier New", monospace;

  /* light palette */
  --sv-bg: 248 250 252; /* slate-50  #f8fafc */
  --sv-surface: 255 255 255; /* white       */
  --sv-border: 229 231 235; /* gray-200   #e5e7eb */
  --sv-border-strong: 226 232 240; /* slate-200 #e2e8f0 */
  --sv-text: 17 24 39; /* gray-900   #111827 */
  --sv-muted: 107 114 128; /* gray-500   #6b7280 */
  --sv-primary: 15 23 42; /* slate-900  #0f172a */
  --sv-accent: 37 99 235; /* blue-600   #2563eb */

  --sv-verified-bg: 209 250 229; /* emerald-100 */
  --sv-verified-fg: 6 95 70; /* emerald-800 */
  --sv-user-bg: 219 234 254; /* blue-100    */
  --sv-user-fg: 30 58 138; /* blue-900    */
  --sv-public-bg: 229 231 235; /* gray-200    */
  --sv-public-fg: 55 65 81; /* gray-700    */

  --radius: 8px;
  --radius-full: 999px;
  --space: 1rem;
  --header-bg: #0f172a;
}

[data-theme="dark"] {
  --sv-bg: 15 23 42; /* slate-900  #0f172a */
  --sv-surface: 30 41 59; /* slate-800  #1e293b */
  --sv-border: 51 65 85; /* slate-700  #334155 */
  --sv-border-strong: 51 65 85; /* slate-700        */
  --sv-text: 226 232 240; /* slate-200  #e2e8f0 */
  --sv-muted: 148 163 184; /* slate-400  #94a3b8 */
  --sv-primary: 15 23 42; /* slate-900        */
  --sv-accent: 96 165 250; /* blue-400   #60a5fa */

  --sv-verified-bg: 6 78 59; /* emerald-900      */
  --sv-verified-fg: 110 231 183; /* emerald-300      */
  --sv-user-bg: 30 58 138; /* blue-900         */
  --sv-user-fg: 147 197 253; /* blue-300         */
  --sv-public-bg: 51 65 85; /* slate-700        */
  --sv-public-fg: 226 232 240; /* slate-200        */

  --header-bg: #020617;
}

body {
  margin: 0;
  font-family: var(--sv-font-sans);
  background: rgb(var(--sv-bg));
  color: rgb(var(--sv-text));
}

.container {
  max-width: 960px;
  margin: 0 auto;
  padding: 1rem;
}

.page-header {
  background: var(--header-bg);
  color: #ffffff;
}

.page-header a {
  color: #ffffff;
  text-decoration: none;
  margin-right: 1rem;
}

.panel {
  background: rgb(var(--sv-surface));
  border: 1px solid rgb(var(--sv-border-strong));
  border-radius: var(--radius);
  padding: 1rem;
  margin-bottom: 1rem;
}

.stack > * {
  display: block;
  margin-bottom: 0.75rem;
}

input,
textarea,
button {
  font: inherit;
  padding: 0.5rem;
}

input,
textarea {
  color: rgb(var(--sv-text));
  background: rgb(var(--sv-surface));
  border: 1px solid rgb(var(--sv-border-strong));
  border-radius: calc(var(--radius) - 2px);
}

button {
  cursor: pointer;
}

.badge {
  display: inline-block;
  border-radius: var(--radius-full);
  padding: 0.1rem 0.5rem;
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: lowercase;
}

.badge-verified {
  background: rgb(var(--sv-verified-bg));
  color: rgb(var(--sv-verified-fg));
}

.badge-user {
  background: rgb(var(--sv-user-bg));
  color: rgb(var(--sv-user-fg));
}

.badge-public {
  background: rgb(var(--sv-public-bg));
  color: rgb(var(--sv-public-fg));
}

.muted {
  color: rgb(var(--sv-muted));
  font-size: 0.9rem;
}

.warning {
  color: #991b1b;
  font-weight: 700;
}

.copy-row {
  display: flex;
  gap: 0.5rem;
}

.copy-row input {
  flex: 1;
}

.list {
  list-style: none;
  padding: 0;
}

.list li {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem;
  border-top: 1px solid rgb(var(--sv-border));
  padding: 0.75rem 0;
}

.list li > :first-child {
  flex: 1 1 15rem;
  min-width: 0;
}

.actions,
.inline {
  display: inline-flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  align-items: center;
}

.tabs {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

.tab-button {
  border: 1px solid #94a3b8;
  background: rgb(var(--sv-bg));
}

.tab-button.is-active {
  background: var(--header-bg);
  color: #ffffff;
}

.tab-panel {
  display: none;
}

.tab-panel.is-active {
  display: block;
}

.pager {
  display: flex;
  gap: 1rem;
  margin-top: 0.75rem;
  align-items: center;
}

.pager a {
  display: inline-block;
  background: rgb(var(--sv-surface));
  border: 1px solid rgb(var(--sv-border-strong));
  border-radius: var(--radius);
  padding: 0.4rem 0.75rem;
  color: rgb(var(--sv-accent));
  text-decoration: none;
}

table {
  width: 100%;
  border-collapse: collapse;
  background: rgb(var(--sv-surface));
}

th,
td {
  border-top: 1px solid rgb(var(--sv-border));
  padding: 0.4rem;
  text-align: left;
}

th code,
td code {
  word-break: break-all;
}

/* Wrappable horizontal-scroll container for wide tables (e.g. agent API
   keys). Keeps tables at natural column widths but lets narrow screens
   scroll the table instead of forcing horizontal page overflow. */
.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.public-header {
  border-bottom: 1px solid #1e293b;
}

.public-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.public-nav .brand {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 700;
}

/* Make the header nav a wrapping flex row so links + email + actions never
   overflow the viewport on narrow screens (they wrap onto their own lines). */
.public-nav nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.75rem;
  min-width: 0;
}

/* Long user emails in the header: truncate on desktop, stack full-width and
   break cleanly on mobile instead of blowing past the header edge. */
.public-nav nav .muted {
  display: inline-block;
  max-width: min(44vw, 16rem);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: middle;
}

/* Keep nav buttons (e.g. Logout) the same height/appearance as the nav
   links so they don't inflate the header bar or look like form buttons. */
.public-nav nav .inline button {
  background: none;
  border: none;
  padding: 0;
  margin-right: 1rem;
  color: #ffffff;
  font: inherit;
  text-decoration: none;
}

/* Dark-mode toggle button in the header, styled like a nav link. */
.theme-toggle {
  background: none;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: var(--radius-full);
  color: #ffffff;
  padding: 0.15rem 0.5rem;
  line-height: 1.4;
  cursor: pointer;
  font-size: 0.9rem;
}

.public-main {
  padding-top: 1.5rem;
  padding-bottom: 2rem;
}

.hero {
  background: linear-gradient(180deg, rgb(var(--sv-surface)) 0%, rgb(var(--sv-bg)) 100%);
}

.eyebrow {
  margin: 0;
  color: rgb(var(--sv-accent));
  font-size: 0.9rem;
  font-weight: 700;
}

.hero h1 {
  margin-bottom: 0.75rem;
}

/* Hero headline for the redesigned landing page: larger type with a gradient
   accent on the emphasized phrase. Falls back to the accent colour if gradient
   text isn't supported. */
.hero-headline {
  font-size: clamp(1.8rem, 2.5vw + 1rem, 2.4rem);
  line-height: 1.15;
  letter-spacing: -0.01em;
  font-weight: 700;
  margin-bottom: 0.75rem;
}

.hero-accent {
  background: linear-gradient(120deg, rgb(var(--sv-accent)), #7c3aed);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero-copy {
  font-size: 1.05rem;
  line-height: 1.5;
  max-width: 60ch;
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 1rem;
}

.button-link {
  display: inline-block;
  background: var(--header-bg);
  color: #ffffff;
  border-radius: var(--radius);
  text-decoration: none;
  padding: 0.55rem 0.8rem;
  font-weight: 700;
}

.button-link-muted {
  background: rgb(var(--sv-border-strong));
  color: rgb(var(--sv-text));
}

.feature-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 0.75rem;
}

.feature-card {
  border: 1px solid rgb(var(--sv-border-strong));
  border-radius: var(--radius);
  padding: 0.85rem;
  background: rgb(var(--sv-surface));
}

.feature-card h3 {
  margin-top: 0;
  margin-bottom: 0.5rem;
}

.endpoint-banner {
  border-left: 4px solid rgb(var(--sv-accent));
}

.endpoint-value {
  margin-top: 0.25rem;
}

.endpoint-value code {
  font-size: 0.95rem;
}

.public-footer {
  padding-bottom: 2rem;
}

.snippet-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 0.75rem;
}

.code-card {
  border: 1px solid rgb(var(--sv-border-strong));
  border-radius: var(--radius);
  padding: 0.75rem;
  background: rgb(var(--sv-surface));
}

.code-card h3 {
  margin-top: 0;
  margin-bottom: 0.5rem;
}

.code-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.code-toolbar button {
  border: 1px solid #94a3b8;
  border-radius: calc(var(--radius) - 2px);
  background: rgb(var(--sv-bg));
}

.code-block {
  margin: 0;
  padding: 0.75rem;
  border-radius: calc(var(--radius) - 2px);
  border: 1px solid rgb(var(--sv-border));
  background: #0f172a;
  color: #e2e8f0;
  font-family: var(--sv-font-mono);
  font-size: 0.82rem;
  line-height: 1.4;
  overflow-x: auto;
  white-space: pre;
}

/* --- Skill detail page ---------------------------------------------------- */
.detail-header {
  padding-top: 1.25rem;
  padding-bottom: 1.25rem;
}

.detail-title-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.detail-name {
  margin: 0;
}

.detail-id {
  margin: 0.25rem 0 0.75rem;
}

.detail-id code {
  word-break: break-all;
  display: inline-block;
  max-width: 100%;
}

.meta-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.75rem 1.5rem;
  margin: 0;
}

.meta-item {
  border-bottom: 1px solid rgb(var(--sv-border));
  padding-bottom: 0.5rem;
}

.meta-item dt {
  color: rgb(var(--sv-muted));
  font-size: 0.75rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin-bottom: 0.15rem;
}

.meta-item dd {
  margin: 0;
}

.meta-item dd code {
  word-break: break-all;
}

.tag-chip {
  display: inline-block;
  background: rgb(var(--sv-public-bg));
  color: rgb(var(--sv-public-fg));
  border-radius: var(--radius-full);
  padding: 0.05rem 0.5rem;
  font-size: 0.75rem;
  font-weight: 600;
  margin-right: 0.25rem;
  margin-bottom: 0.25rem;
}

.skill-body {
  line-height: 1.55;
}

.skill-body pre {
  background: #0f172a;
  color: #e2e8f0;
  border-radius: calc(var(--radius) - 2px);
  padding: 0.75rem;
  overflow-x: auto;
}

/* --- Buttons (unified actions across dashboard / agents / forms) ----------- */
.btn {
  display: inline-block;
  border: 1px solid rgb(var(--sv-border-strong));
  border-radius: calc(var(--radius) - 2px);
  background: rgb(var(--sv-bg));
  color: rgb(var(--sv-text));
  padding: 0.4rem 0.7rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

.btn-primary {
  background: var(--header-bg);
  color: #ffffff;
  border-color: var(--header-bg);
}

.btn-secondary {
  background: rgb(var(--sv-bg));
  color: rgb(var(--sv-text));
}

.btn-danger {
  background: rgb(var(--sv-bg));
  color: #b91c1c;
  border-color: #b91c1c;
}

/* Alpine x-cloak: hide Alpine-controlled panels until initialised (prevents
   a flash of all tab panels before Alpine has applied x-show). */
[x-cloak] {
  display: none !important;
}

/* --- Auth + form pages (login / signup / onboard / skill form) ------------- */
.panel-auth {
  max-width: 440px;
  margin: 1.5rem auto;
}

.form-field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  margin-bottom: 0.85rem;
}

.form-field label {
  font-size: 0.9rem;
  font-weight: 600;
}

.form-field .hint {
  color: rgb(var(--sv-muted));
  font-size: 0.8rem;
}

.form-actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 0.25rem;
}

.form-note {
  color: rgb(var(--sv-muted));
  font-size: 0.85rem;
  margin-top: 1rem;
}

.visibility-options {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: 0.25rem;
}

.visibility-options label {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-weight: 500;
}

/* Search-as-you-type (browse) helpers */
.search-row {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.search-row input[type="search"] {
  flex: 1;
}

/* Loading indicator for HTMX requests */
.htmx-indicator {
  opacity: 0;
  transition: opacity 0.2s ease-in-out;
  color: rgb(var(--sv-muted));
  font-size: 0.85rem;
}

.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator {
  opacity: 1;
}

/* Screen-reader-only utilities (used by the dark-mode toggle label) */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* --- Responsive breakpoints ----------------------------------------------- */

/* Tablet / small-laptop edge cases (e.g. 768px): let form/nav rows wrap so
   they don't crowd at mid widths. */
@media (max-width: 768px) {
  .form-actions,
  .pager {
    flex-wrap: wrap;
  }

  .panel-auth {
    margin: 1rem auto;
  }
}

@media (max-width: 640px) {
  .container {
    padding: 0.8rem;
  }

  /* Header: keep brand on a row, drop the nav to its own full-width wrapped
     row so links + email + actions never overflow the viewport. */
  .public-nav {
    align-items: flex-start;
  }

  .public-nav nav {
    width: 100%;
  }

  /* Long user email: break onto its own full-width row on mobile. */
  .public-nav nav .muted {
    flex-basis: 100%;
    max-width: 100%;
  }

  .page-header a {
    margin-right: 0.6rem;
  }

  /* Enlarge touch targets on small screens (>= Apple's 44px guideline). */
  .public-nav nav a,
  .theme-toggle,
  .btn,
  .button-link,
  .pager a,
  .tab-button {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /* List rows stack title + actions vertically; action buttons become
     equal-width grid cells so they align and fill the row on mobile. */
  .list li {
    flex-direction: column;
    align-items: stretch;
  }

  /* The generic `.list li > :first-child` rule uses `flex: 1 1 15rem` as a
     WIDTH basis for the desktop row layout. Once the list is a column, that
     same basis is applied to HEIGHT and forces each item (e.g. an agent) to
     be at least 15rem tall no matter how little content it has. Reset it. */
  .list li > :first-child {
    flex-basis: auto;
  }

  .actions {
    width: 100%;
    /* Grid (instead of flex) so a button wrapped in a form.inline gets the
       same sized cell as a plain .btn anchor — they stay aligned. */
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  }

  .actions > * {
    min-width: 0;
  }

  .actions .btn,
  .actions button {
    width: 100%;
  }

  /* Buttons nested inside a form.inline don't stretch to the grid cell on
     their own — make the form a flex container so its child fills it. */
  .actions .inline {
    display: flex;
    width: 100%;
  }

  .actions .inline button {
    flex: 1 1 auto;
    width: 100%;
  }

  .code-toolbar {
    flex-wrap: wrap;
  }

  .search-row {
    flex-wrap: wrap;
  }

  /* Copy rows (e.g. onboarding raw key) stack the field above the button. */
  .copy-row {
    flex-direction: column;
    align-items: stretch;
  }

  .copy-row button {
    width: 100%;
  }

  .meta-list {
    grid-template-columns: 1fr;
  }

  .detail-title-row {
    /* Vertically center the heading and any action button. The mobile
       touch-target rule bumps .btn up to min-height:44px, so top-aligning
       the row makes the taller button overhang below the heading text.
       Centering keeps them on a shared midline (matches desktop). */
    align-items: center;
  }

  /* Section heading reads a touch larger on small screens for clearer
     hierarchy above the list. */
  .detail-name {
    font-size: 1.25rem;
    line-height: 1.35;
  }

  /* Primary action beside a section heading (e.g. "Onboard a new agent")
     becomes a full-width, high-presence CTA on mobile instead of a small
     chip tucked next to the title. flex-basis:100% drops it onto its own
     line because the row already wraps (does not affect agent-detail's
     title row, which holds a badge — not a .btn — so that stays inline). */
  .detail-title-row .btn {
    flex-basis: 100%;
    justify-content: center;
    font-weight: 700;
    padding: 0.7rem 1rem;
  }

  /* More breathing room between stacked list rows and a wider gap between
     the equal-width action buttons for easier tapping on mobile. */
  .list li {
    padding: 1rem 0;
  }

  .actions {
    gap: 0.6rem;
  }

  /* Agent-detail header: the two actions ("Publish new skill" primary and
     "Delete Agent" danger) used mismatched widths/heights. Stack them as
     full-width equal rows on mobile so the primary reads clearly first. */
  .detail-header .button-link {
    display: block;
    width: 100%;
    text-align: center;
  }

  .detail-header .stack button {
    width: 100%;
  }

  /* Tabs (Personal / Global) become equal-width full-row segments so the
     control reads as one unit instead of two loosely-sized buttons. */
  .tabs .tab-button {
    flex: 1 1 0;
  }

  /* API-keys view: a 5-column table is wider than a phone, so instead of
     forcing sideways scroll to reach Status / Actions, break it into stacked
     key "cards". Each cell shows its data-label above the value, the header
     row is hidden, and Actions gets its own card row with full-width buttons. */
  .table-scroll {
    overflow-x: visible;
    -webkit-overflow-scrolling: auto;
  }

  .table-scroll thead {
    display: none;
  }

  .table-scroll table,
  .table-scroll tbody,
  .table-scroll tr,
  .table-scroll td {
    display: block;
    width: 100%;
    box-sizing: border-box;
  }

  /* Each key becomes its own card: hairline separators between cells. */
  .table-scroll tbody tr {
    border: 1px solid rgb(var(--sv-border));
    border-radius: var(--radius);
    margin-bottom: 0.75rem;
    padding: 0.4rem 0.75rem;
  }

  .table-scroll td {
    border-top: 1px solid rgb(var(--sv-border));
    padding: 0.5rem 0;
  }

  .table-scroll td:first-child {
    border-top: none;
  }

  /* Show the column label above each value, muted so the value leads. */
  .table-scroll td::before {
    content: attr(data-label);
    display: block;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: rgb(var(--sv-muted));
    margin-bottom: 0.15rem;
  }

  /* Long key id can still wrap; avoid page overflow. */
  .table-scroll td code {
    word-break: break-all;
  }

  /* Actions sit on their own line as full-width equal buttons. */
  .table-scroll td[data-label="Actions"] .actions {
    margin-top: 0.25rem;
  }
}
