/* The design system's components, vendored: docs/DEPLOY.md says from where.
   Edited here since (what buttons animate, their line height), so refreshing it
   is a merge, not a copy. */
/* Component styles
   Import tokens.css first. */

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg-base);
  color: var(--fg-primary);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
}

/* ==== Buttons ==== */
/* What a button animates, named: `all` also animated layout and font changes, and
   still could not animate a gradient. The press (transform) has its own, shorter
   transition, so it eases in and out rather than snapping. */
.btn {
  position: relative; isolation: isolate;
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px; padding: 10px 16px; border-radius: var(--radius-xl);
  font-weight: var(--weight-medium); font-size: var(--text-sm);
  /* Its own line height: a link drawn as a button took the page's (1.6 on our pages)
     and a <button> the browser's, so side by side they came out different heights. */
  line-height: 1.25;
  border: 1px solid transparent; cursor: pointer;
  transition: background-color 150ms var(--ease-out), border-color 150ms var(--ease-out), color 150ms var(--ease-out),
              box-shadow 150ms var(--ease-out), opacity 150ms var(--ease-out), transform 90ms var(--ease-out);
  font-family: inherit;
}
.btn:disabled { opacity: .5; cursor: not-allowed; }
/* A gradient cannot be animated, so a gradient button's hover and press are layers
   that fade in over it, under its label: ::after the hover, ::before the press. */
.btn-primary::before, .btn-primary::after, .btn-accent::after, .btn-danger::after {
  content: ""; position: absolute; inset: -1px; border-radius: inherit; pointer-events: none;
  opacity: 0; transition: opacity 150ms var(--ease-out);
}
.btn-primary::after, .btn-accent::after, .btn-danger::after { z-index: -2; }
.btn-primary::before { z-index: -1; }
.btn:hover:not(:disabled)::after { opacity: 1; }
.btn:active:not(:disabled)::before { opacity: 1; }
.btn:focus-visible { outline: none; }

.btn-primary {
  color: #fff;
  background: linear-gradient(to bottom, var(--primary-500), var(--primary-600));
  box-shadow: 0 1px 3px var(--shadow-black-soft), inset 0 1px 0 var(--shadow-white-hairline);
}
.btn-primary::after { background: linear-gradient(to bottom, var(--primary-400), var(--primary-500)); }
.btn-primary::before { background: linear-gradient(to bottom, var(--primary-600), var(--primary-700)); }
.btn-primary:active { transform: scale(.98); }

.btn-secondary {
  color: var(--fg-primary);
  background: var(--surface-control-strong);
  border-color: var(--border-card);
}
.btn-secondary:hover { background: var(--surface-hover); }
.btn-secondary:active { transform: scale(.98); }

.btn-accent {
  color: #fff;
  background: linear-gradient(to bottom, var(--accent-500), var(--accent-600));
  box-shadow: 0 1px 3px var(--shadow-black-soft), inset 0 1px 0 var(--shadow-white-hairline);
}
.btn-accent::after { background: linear-gradient(to bottom, var(--accent-400), var(--accent-500)); }

.btn-ghost {
  background: transparent; color: var(--fg-secondary);
}
.btn-ghost:hover { color: var(--fg-primary); background: var(--surface-hover-ghost); }

.btn-danger {
  color: #fff;
  background: linear-gradient(to bottom, #dc2626, #b91c1c);
  box-shadow: 0 1px 3px var(--shadow-black-soft), inset 0 1px 0 var(--shadow-white-hairline);
}
.btn-danger::after { background: linear-gradient(to bottom, #ef4444, #dc2626); }

.btn-sm { padding: 6px 12px; font-size: var(--text-sm); border-radius: var(--radius-lg); }
.btn-lg { padding: 12px 24px; font-size: var(--text-base); border-radius: var(--radius-xl); }

/* ==== Inputs ==== */
.input {
  width: 100%; padding: 10px 16px;
  background: var(--surface-well);
  border: 1px solid var(--border-card);
  border-radius: var(--radius-xl);
  color: var(--fg-primary);
  font-size: var(--text-sm);
  font-family: inherit;
  transition: border-color var(--duration) var(--ease-out), background var(--duration) var(--ease-out);
}
.input::placeholder { color: var(--fg-placeholder); }
.input:focus { outline: none; border-color: var(--primary-500); background: var(--surface-well-focus); }

.label {
  display: block;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--fg-label);
  margin-bottom: 10px;
}

/* ==== Cards ==== */
.card {
  background: var(--bg-card);
  backdrop-filter: blur(4px);
  border: 1px solid var(--border-card);
  border-radius: var(--radius-xl);
  padding: var(--space-6);
}
.card-hover {
  cursor: pointer;
  transition: border-color var(--duration) var(--ease-out), background-color var(--duration) var(--ease-out),
              transform var(--duration) var(--ease-out), box-shadow var(--duration) var(--ease-out);
}
.card-hover:hover {
  border-color: var(--border-card-hover);
  background: var(--bg-card-hover);
  transform: translateY(-1px);
  box-shadow: var(--shadow-lg);
}
.card-elevated {
  background: var(--bg-elevated);
  border: 1px solid var(--border-card);
  border-radius: var(--radius-2xl);
  box-shadow: var(--shadow-modal);
}

/* ==== Badges ====
   Background is a translucent hue tint (works over either theme's page
   color); the text is the theme's "-ink" variant for that hue, which is
   what keeps the badge readable in both — a pale mint chip needs a dark
   green ink, not the light green that reads fine on a dark card. */
.badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 10px; border-radius: var(--radius-lg);
  font-size: var(--text-xs); font-weight: var(--weight-semibold);
  letter-spacing: .025em; border: 1px solid transparent;
}
.badge-primary { background: var(--primary-bg); color: var(--primary-ink); border-color: var(--primary-bg-strong); }
.badge-success { background: var(--success-bg); color: var(--role-success); border-color: rgba(16,185,129,.2); }
.badge-warning { background: var(--warning-bg); color: var(--role-warning); border-color: rgba(245,158,11,.2); }
.badge-danger  { background: var(--danger-bg);  color: var(--role-danger);  border-color: rgba(239,68,68,.2); }
.badge-info    { background: var(--info-bg);    color: var(--role-running); border-color: var(--primary-bg-strong); }
.badge-gray    { background: var(--role-neutral-bg); color: var(--role-neutral); border-color: var(--role-neutral-border); }
.badge-teal    { background: var(--teal-bg);    color: var(--teal-ink);    border-color: rgba(20,184,166,.2); }
.pill-beta {
  padding: 2px 6px; font-size: 10px; font-weight: var(--weight-semibold);
  letter-spacing: .05em; text-transform: uppercase;
  background: rgba(6,182,212,.2); color: var(--accent-ink);
  border-radius: var(--radius-sm);
}

/* ==== Status dots ====
   Fill and glow stay the dark-theme hue on purpose — a filled dot isn't
   read as text, and the same saturated dot reads as a slightly softer
   (not broken) pop of color against a light card. Only .badge/.alert/
   text-adjacent uses need the ink swap above. */
.status-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.status-dot-success { background: var(--success-400); box-shadow: 0 0 12px rgba(52,211,153,.5); }
.status-dot-warning { background: var(--warning-400); box-shadow: 0 0 12px rgba(251,191,36,.5); }
.status-dot-danger  { background: var(--danger-400);  box-shadow: 0 0 12px rgba(248,113,113,.5); }
.status-dot-info    { background: var(--info-400);    box-shadow: 0 0 12px rgba(96,165,250,.5); }

/* ==== Icon button ==== */
.icon-btn {
  min-width: 44px; min-height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius-lg); background: transparent; border: none;
  color: var(--fg-secondary); cursor: pointer;
  transition: color var(--duration) var(--ease-out), background var(--duration) var(--ease-out);
}
.icon-btn:hover { color: var(--fg-primary); background: var(--surface-hover); }

/* ==== Segmented control ==== */
.segmented { display: inline-flex; gap: 4px; padding: 4px; background: var(--surface-control); border-radius: var(--radius-lg); }
.segmented button {
  height: 36px; padding: 0 16px;
  font-size: var(--text-sm); font-weight: var(--weight-medium);
  border: 1px solid var(--border-card); background: var(--surface-control);
  color: var(--fg-secondary); border-radius: 6px; cursor: pointer;
  transition: color 150ms var(--ease-out), background-color 150ms var(--ease-out), border-color 150ms var(--ease-out), box-shadow 150ms var(--ease-out);
  font-family: inherit;
}
.segmented button:hover { background: var(--surface-control-strong); color: var(--fg-primary); }
.segmented button[aria-selected="true"] {
  background: var(--primary-bg); color: var(--primary-ink);
  border-color: var(--primary-border-strong);
}

/* ==== Scrollbar ==== */
* { scrollbar-width: thin; scrollbar-color: transparent transparent; }
*:hover { scrollbar-color: var(--surface-hover) transparent; }
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: transparent; border-radius: 3px; transition: background .2s; }
*:hover::-webkit-scrollbar-thumb { background: var(--surface-hover); }

/* ==== Page container ====
   Canonical rule for every routed page.
   - Stretches to fill the main column after the sidebar.
   - Centers at a generous 1600px cap so wide monitors don't leave the
     content glued to the sidebar. This replaces the old 1280px cap
     which made routes like Dashboard look left-weighted on >1600px screens.
   - Narrow variant (880px) for form-heavy pages (Settings, Account).
   - Wide variant (no cap) for tables/dashboards that should edge-to-edge.
   Usage: <main class="main"><div class="page-container"> … </div></main> */
.page-container {
  width: 100%;
  max-width: 1600px;
  margin: 0 auto;
  padding: 32px;
  /* Kill the left-weighted feel by ensuring content never hugs the sidebar
     on ultra-wide viewports — the auto margins absorb the overflow. */
}
.page-container--narrow { max-width: 880px; }
.page-container--wide   { max-width: none; }

/* Responsive padding — tighten on smaller viewports. */
@media (max-width: 1024px) {
  .page-container { padding: 24px; }
}
@media (max-width: 640px) {
  .page-container { padding: 16px; }
}

/* ==== Selection ==== */
::selection { background: var(--primary-border); color: #fff; }

/* ==== Focus visible ====
   No external focus rings anywhere. Components that need to indicate focus
   change their own border-color (see .input:focus, .listbox-trigger:focus). */
*:focus,
*:focus-visible,
*:focus-within {
  outline: none !important;
  box-shadow: none;
}
button:focus,
input:focus,
textarea:focus,
select:focus,
[role="button"]:focus,
[tabindex]:focus {
  outline: none !important;
}

/* ==== Keyframes ==== */
@keyframes fadeIn { from { opacity: 0 } to { opacity: 1 } }
@keyframes slideUp { from { opacity: 0; transform: translateY(8px) } to { opacity: 1; transform: translateY(0) } }
@keyframes shimmer { 0% { transform: translateX(-100%) } 100% { transform: translateX(100%) } }

/* ==== Compact density ====
   Activated by setting data-density="compact" on <html> (or any ancestor).
   Shrinks vertical rhythm by ~25% — useful for Jobs / TM / Glossary tables
   when an op needs to see >25 rows at once. Implementation:
   • Re-defines the density tokens declared in tokens.css.
   • Tightens .btn, .input, .card paddings.
   • Tables / lists pick up via row-h / row-py vars (read in JSX).
*/
[data-density="compact"] {
  --row-h:        36px;
  --row-py:       8px;
  --card-p:       16px;
  --section-gap:  16px;
  --input-h:      32px;
}
[data-density="compact"] .btn      { padding: 6px 12px; }
[data-density="compact"] .btn-sm   { padding: 4px 10px; }
[data-density="compact"] .btn-lg   { padding: 8px 18px; font-size: var(--text-sm); }
[data-density="compact"] .input    { padding: 6px 12px; }
[data-density="compact"] .card     { padding: 16px; }
[data-density="compact"] .icon-btn { min-width: 32px; min-height: 32px; }
[data-density="compact"] .segmented button { height: 28px; padding: 0 12px; }
[data-density="compact"] .page-container   { padding: 20px; }

/* ==== Print styles ====
   Optimised for invoice / receipt / audit-log export.
   Strips chrome (sidebar, banners, action buttons), forces light surfaces,
   keeps text and tables. Trigger by visiting the route and Cmd-P / Ctrl-P,
   OR by adding `class="print-mode"` to <body> for a screen preview.
   Deliberately hardcoded to paper-white regardless of the active on-screen
   theme — a printed page is its own "theme" and always renders light.
*/
@media print {
  @page { size: A4; margin: 18mm 14mm; }
  body  { background: #fff !important; color: #111 !important; }
  /* Hide chrome */
  .sidebar, .topbar, .trial-banner, .tweaks-panel,
  [data-print-hide], .icon-btn, .btn, .modal-overlay { display: none !important; }
  /* Flatten cards / tables to ink-on-paper */
  .card, .card-elevated {
    background: #fff !important; border: 1px solid #d0d0d0 !important;
    box-shadow: none !important; backdrop-filter: none !important;
    break-inside: avoid;
  }
  table { border-collapse: collapse; width: 100%; }
  table th, table td { border: 1px solid #d0d0d0; padding: 6px 10px; color: #111; }
  table thead th    { background: #f4f4f4 !important; font-weight: 600; }
  /* Page container goes edge-to-edge in print */
  .page-container, .page-container--narrow, .page-container--wide {
    max-width: none !important; padding: 0 !important;
  }
  /* Force readable text */
  body, body * {
    color-adjust: exact; -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  /* Color hints kept (status badges) but de-saturated */
  .badge { border-color: #ccc !important; }
  .badge-success { background: #e8f5e9 !important; color: #1b5e20 !important; }
  .badge-warning { background: #fff8e1 !important; color: #8d6708 !important; }
  .badge-danger  { background: #ffebee !important; color: #b71c1c !important; }
  .badge-primary, .badge-info { background: #e3f2fd !important; color: #0d47a1 !important; }
  .badge-gray    { background: #f5f5f5 !important; color: #555 !important; }
  /* Avoid awkward breaks */
  h1, h2, h3 { break-after: avoid; }
  tr, li     { break-inside: avoid; }
}

/* Class-based preview that mirrors @media print so we can demo the look
   without invoking the OS print dialog. */
.print-preview {
  background: #fff; color: #111; padding: 32px;
}
.print-preview .card,
.print-preview .card-elevated {
  background: #fff; border: 1px solid #d0d0d0; box-shadow: none;
}
.print-preview table { border-collapse: collapse; width: 100%; }
.print-preview table th,
.print-preview table td { border: 1px solid #d0d0d0; padding: 8px 12px; color: #111; }
.print-preview table thead th { background: #f4f4f4; font-weight: 600; }
