/* ServiceKey - core shell, design tokens, dark theme.
   Shares KanKey's visual system deliberately: same palette, same spacing scale,
   same wordmark face, so the two apps read as siblings. */

@font-face {
  font-family: 'AeroviasBrasilNF';
  src: url('/font/AeroviasBrasilNF.ttf') format('truetype');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

/* ==================== VARIABLES ==================== */
:root {
  /* Colors - Dark Theme */
  --bg-primary: #1a1a1a;
  --bg-secondary: #252525;
  --bg-card: #252525;
  --bg-tertiary: #2f2f2f;
  --bg-hover: #3a3a3a;
  --text-primary: #e5e5e5;
  --text-secondary: #a3a3a3;
  --text-tertiary: #7a7a7a;
  --accent: #0093da;
  --accent-hover: #007ab8;
  --accent-light: rgba(0, 147, 218, 0.15);
  --success: #10b981;
  --warning: #f59e0b;
  --danger: #ef4444;
  --border: #3f3f3f;
  --shadow: rgba(0, 0, 0, 0.5);

  /* Document status colors. Only draft/issued/void are stored; the rest are
     derived at read time (see Invoice::deriveStatus). Each needs a text color
     and a tinted background for the badge. */
  --status-draft: #7a7a7a;
  --status-draft-bg: rgba(122, 122, 122, 0.15);
  --status-issued: #0093da;
  --status-issued-bg: rgba(0, 147, 218, 0.15);
  --status-sent: #6366f1;
  --status-sent-bg: rgba(99, 102, 241, 0.15);
  --status-viewed: #8b5cf6;
  --status-viewed-bg: rgba(139, 92, 246, 0.15);
  --status-paid: #10b981;
  --status-paid-bg: rgba(16, 185, 129, 0.15);
  --status-partial: #f59e0b;
  --status-partial-bg: rgba(245, 158, 11, 0.15);
  --status-overdue: #ef4444;
  --status-overdue-bg: rgba(239, 68, 68, 0.15);
  --status-void: #5a5a5a;
  --status-void-bg: rgba(90, 90, 90, 0.15);
  --status-signed: #10b981;
  --status-signed-bg: rgba(16, 185, 129, 0.15);

  /* Spacing */
  --space-xs: 0.25rem;
  --space-sm: 0.5rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2rem;

  /* Typography */
  --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-mono: 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, monospace;
  --font-display: 'AeroviasBrasilNF', sans-serif;
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.25rem;
  --text-2xl: 1.5rem;
  --text-3xl: 2rem;

  /* Layout */
  --radius-sm: 0.25rem;
  --radius-md: 0.5rem;
  --radius-lg: 0.75rem;
  --topbar-height: 56px;
  --content-max: 1200px;

  /* Animation */
  --transition-fast: 150ms ease;
  --transition-base: 250ms ease;
  --transition-slow: 350ms ease;
}

/* ==================== RESET & BASE ==================== */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Also on <html>, not just <body>: the root element paints the canvas before
     body has any box, so without this the page flashes white on load and
     overscroll bounce shows white past the content edge - very visible in the
     installed PWA, where there is no browser chrome to hide it. */
  background-color: var(--bg-primary);
  color-scheme: dark;
}

body {
  font-family: var(--font-sans);
  background-color: var(--bg-primary);
  color: var(--text-primary);
  line-height: 1.6;
  overflow-x: hidden;
}

/* ==================== TYPOGRAPHY ==================== */
h1, h2, h3, h4, h5, h6 {
  font-weight: 600;
  line-height: 1.2;
  margin-bottom: var(--space-md);
}

h1 { font-size: var(--text-2xl); }
h2 { font-size: var(--text-xl); }
h3 { font-size: var(--text-lg); }

a {
  color: var(--accent);
  text-decoration: none;
  transition: color var(--transition-fast);
}

a:hover { color: var(--accent-hover); }

/* Money and document numbers are tabular data: fixed-width digits so columns of
   figures line up on the decimal without hand-tuned padding. */
.mono,
.money,
.doc-number {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.money { text-align: right; white-space: nowrap; }
.money-negative { color: var(--danger); }

/* ==================== LAYOUT SHELL ==================== */
.app-topbar {
  position: sticky;
  top: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  gap: var(--space-md);
  height: var(--topbar-height);
  padding: 0 var(--space-md);
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border);
}

.app-brand {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  color: var(--text-primary);
}

.app-brand:hover { color: var(--text-primary); }
.app-brand img { width: 32px; height: 32px; display: block; }

.app-wordmark {
  font-family: var(--font-display);
  font-size: 1.6rem;
  color: var(--text-primary);
  letter-spacing: 0.02em;
  line-height: 1;
}

.app-nav {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  margin-left: var(--space-lg);
}

.app-nav a {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  color: var(--text-secondary);
  font-size: var(--text-sm);
  /* 44px minimum tap target, per the mobile convention. */
  min-height: 44px;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.app-nav a:hover { background: var(--bg-tertiary); color: var(--text-primary); }
.app-nav a.active { background: var(--accent-light); color: var(--accent); }

.app-topbar-spacer { flex: 1; }

.app-main {
  max-width: var(--content-max);
  margin: 0 auto;
  padding: var(--space-lg) var(--space-md);
}

.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  margin-bottom: var(--space-lg);
  flex-wrap: wrap;
}

.page-header h1 { margin-bottom: 0; }

/* ==================== BUTTONS ==================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  min-height: 44px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-tertiary);
  color: var(--text-primary);
  font-family: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
  transition: background var(--transition-fast), border-color var(--transition-fast),
              color var(--transition-fast);
}

/* EVERY :hover here must restate `color`, even where it repeats the resting
   value. A button is written as <button class="btn"> in some places and
   <a class="btn"> in others, and `a:hover { color: var(--accent-hover) }` above
   is (0,2,0) - it outweighs `.btn-primary` at (0,1,0). Without the restatement
   an anchor button's label turns accent-blue on hover: on btn-primary that is
   blue text on a blue fill, so the button reads as blank, while the identical
   <button> next to it behaves. That was the reported bug, and it is invisible
   until someone hovers the one variant that happens to be an anchor.
   `color: inherit` is not a fix - it resolves to the container's color, not the
   variant's own, so each variant states its contract explicitly. */
.btn:hover { background: var(--bg-hover); color: var(--text-primary); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }

.btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: #fff; }

.btn-danger { background: transparent; border-color: var(--danger); color: var(--danger); }
/* Used for "Remind" on an overdue invoice: it draws the eye without reading as
   destructive the way btn-danger would. */
.btn-warning { background: transparent; border-color: var(--warning); color: var(--warning); }
.btn-danger:hover { background: rgba(239, 68, 68, 0.12); color: var(--danger); }
.btn-warning:hover { background: rgba(245, 158, 11, 0.12); color: var(--warning); }

.btn-ghost { background: transparent; border-color: transparent; color: var(--text-secondary); }
.btn-ghost:hover { background: var(--bg-tertiary); color: var(--text-primary); }

.btn-sm { min-height: 32px; padding: var(--space-xs) var(--space-sm); font-size: var(--text-xs); }

/* ==================== FORMS ==================== */
.form-group { margin-bottom: var(--space-md); }

.form-group label {
  display: block;
  margin-bottom: var(--space-xs);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

input[type="text"],
input[type="email"],
input[type="number"],
input[type="date"],
input[type="url"],
input[type="password"],
select,
textarea {
  width: 100%;
  padding: var(--space-sm) var(--space-md);
  min-height: 44px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-primary);
  color: var(--text-primary);
  font-family: inherit;
  font-size: var(--text-base);
  transition: border-color var(--transition-fast);
}

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
}

textarea { min-height: 100px; resize: vertical; line-height: 1.5; }

.form-hint { font-size: var(--text-xs); color: var(--text-tertiary); margin-top: var(--space-xs); }
.form-row { display: flex; gap: var(--space-md); flex-wrap: wrap; }
.form-row > * { flex: 1; min-width: 200px; }

/* ==================== CARDS & TABLES ==================== */
.card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-lg);
  margin-bottom: var(--space-md);
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  margin-bottom: var(--space-md);
}

.data-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }

.data-table th {
  text-align: left;
  padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--border);
  color: var(--text-secondary);
  font-weight: 600;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.data-table td {
  padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}

.data-table tbody tr:hover { background: var(--bg-tertiary); }
.data-table tbody tr:last-child td { border-bottom: none; }

/* Wide tables scroll inside their own container so the page body never scrolls
   horizontally. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ==================== STATUS BADGES ==================== */
.status-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  padding: 2px var(--space-sm);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  white-space: nowrap;
}

.status-draft   { color: var(--status-draft);   background: var(--status-draft-bg); }
.status-issued  { color: var(--status-issued);  background: var(--status-issued-bg); }
.status-sent    { color: var(--status-sent);    background: var(--status-sent-bg); }
.status-viewed  { color: var(--status-viewed);  background: var(--status-viewed-bg); }
.status-paid    { color: var(--status-paid);    background: var(--status-paid-bg); }
.status-partially_paid { color: var(--status-partial); background: var(--status-partial-bg); }
.status-overdue { color: var(--status-overdue); background: var(--status-overdue-bg); }
.status-void    { color: var(--status-void);    background: var(--status-void-bg); text-decoration: line-through; }
.status-signed  { color: var(--status-signed);  background: var(--status-signed-bg); }

/* Overdue is orthogonal to the main status - a partially paid invoice can also
   be late - so it rides alongside the badge rather than replacing it. */
.overdue-flag { color: var(--status-overdue); font-size: var(--text-xs); font-weight: 600; }

/* ==================== EMPTY STATES ==================== */
.empty-state {
  text-align: center;
  padding: var(--space-xl) var(--space-md);
  color: var(--text-secondary);
}

.empty-state i { font-size: 2.5rem; color: var(--text-tertiary); margin-bottom: var(--space-md); display: block; }
.empty-state h3 { color: var(--text-primary); }

/* ==================== TOASTS ==================== */
.toast-container {
  position: fixed;
  bottom: var(--space-lg);
  right: var(--space-lg);
  z-index: 1000;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  max-width: 380px;
}

.toast {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-md);
  border-radius: var(--radius-md);
  background: var(--bg-tertiary);
  border-left: 3px solid var(--accent);
  box-shadow: 0 4px 16px var(--shadow);
  font-size: var(--text-sm);
  cursor: pointer;
  animation: toast-in var(--transition-base);
}

.toast-success { border-left-color: var(--success); }
.toast-error   { border-left-color: var(--danger); }
.toast-warning { border-left-color: var(--warning); }

@keyframes toast-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ==================== LOGIN ==================== */
.login-page {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: var(--space-md);
}

.login-card {
  width: 100%;
  max-width: 400px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-xl);
}

.login-header { text-align: center; margin-bottom: var(--space-lg); }
.login-header img { width: 64px; height: 64px; margin-bottom: var(--space-md); }

.login-wordmark {
  display: block;
  font-family: var(--font-display);
  font-size: var(--text-3xl);
  color: var(--text-primary);
  letter-spacing: 0.02em;
  line-height: 1;
  margin-bottom: var(--space-xs);
}

.login-header p { color: var(--text-secondary); font-size: var(--text-sm); }
.login-footer { margin-top: var(--space-lg); text-align: center; font-size: var(--text-xs); color: var(--text-tertiary); }

/* ==================== UTILITIES ==================== */
.text-secondary { color: var(--text-secondary); }
.text-tertiary  { color: var(--text-tertiary); }
.text-danger    { color: var(--danger); }
/* Was used by admin.js and doc-editor.js before it existed, so both rendered
   their warning in the surrounding colour. A missing utility class is silent:
   the text is still there, it just does not read as a warning. */
.text-warning   { color: var(--warning); }
.text-success   { color: var(--success); }
.text-sm        { font-size: var(--text-sm); }
.text-xs        { font-size: var(--text-xs); }
.text-right     { text-align: right; }
.nowrap         { white-space: nowrap; }
.hidden         { display: none !important; }
.flex           { display: flex; }
.flex-gap       { gap: var(--space-sm); }
.items-center   { align-items: center; }
.mt-md          { margin-top: var(--space-md); }
.mb-md          { margin-bottom: var(--space-md); }

/* ==================== ADMIN: BACKUPS + AUDIT ==================== */
/* auto-fit rather than a fixed column count: the same markup carries three
   retention tiers plus a last-run cell on a desktop and stacks on a phone
   without a second breakpoint. */
.backup-summary {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--space-sm);
}

.backup-summary-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: var(--space-sm);
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
}

.backup-summary-label {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.backup-status-ok    { color: var(--success); font-weight: 600; }
.backup-status-error { color: var(--danger);  font-weight: 600; }

/* The cron line is meant to be selected and pasted, so it wraps instead of
   scrolling - a horizontally scrolled command is easy to copy incompletely. */
.backup-cron-command {
  padding: var(--space-sm);
  background: var(--bg-tertiary);
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  white-space: pre-wrap;
  word-break: break-all;
  user-select: all;
}

.audit-timestamp { white-space: nowrap; font-variant-numeric: tabular-nums; }
.audit-action    { font-family: var(--font-mono, monospace); font-size: var(--text-xs); }

/* Details is free text of unbounded length; capping it keeps every row one
   line tall, with the full value in the title attribute. */
.audit-details {
  max-width: 42ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ==================== RESPONSIVE ==================== */
@media (max-width: 768px) {
  .app-topbar { padding: 0 var(--space-sm); gap: var(--space-sm); }
  .app-wordmark { font-size: 1.3rem; }
  .app-nav { margin-left: var(--space-sm); }
  .app-nav a span { display: none; }  /* icons only on narrow screens */
  .app-main { padding: var(--space-md) var(--space-sm); }
  .page-header { flex-direction: column; align-items: stretch; }
  .card { padding: var(--space-md); }
  .toast-container { left: var(--space-sm); right: var(--space-sm); bottom: var(--space-sm); max-width: none; }
}
