/* Finance Service Portal — hand-written CSS, no build step.
   Palette approximates the old Next.js shell's Azure-portal look. */

:root {
  --accent: #0078d4;
  --accent-dark: #005a9e;
  --accent-light: #deecf9;
  --topbar-bg: #1b1a19;
  --topbar-fg: #f3f2f1;
  --page-bg: #faf9f8;
  --card-bg: #ffffff;
  --border: #edebe9;
  --border-strong: #d2d0ce;
  --text: #201f1e;
  --text-muted: #605e5c;
  --danger: #a4262c;
  --danger-bg: #fde7e9;
  --success: #107c10;
  --success-bg: #dff6dd;
  --radius: 4px;
  --shadow: 0 1.6px 3.6px rgba(0, 0, 0, 0.09), 0 0.3px 0.9px rgba(0, 0, 0, 0.1);
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  background: var(--page-bg);
  color: var(--text);
  font-family: "Segoe UI", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  font-size: 14px;
  line-height: 1.45;
}

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

a:hover {
  text-decoration: underline;
}

/* --- Shell: top bar + left nav + content -------------------------------- */

.shell {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--topbar-bg);
  color: var(--topbar-fg);
  padding: 0 20px;
  height: 48px;
  flex: 0 0 48px;
}

.topbar .brand {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.2px;
}

.topbar .user-menu {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 13px;
}

.topbar .user-menu .user-name {
  color: var(--topbar-fg);
}

.topbar .user-menu .user-email {
  color: #c8c6c4;
}

.topbar form {
  margin: 0;
}

.btn-signout {
  background: transparent;
  border: 1px solid #484644;
  color: var(--topbar-fg);
  border-radius: var(--radius);
  padding: 5px 12px;
  font-size: 13px;
  cursor: pointer;
}

.btn-signout:hover {
  background: #313030;
}

.body {
  display: flex;
  flex: 1 1 auto;
}

.sidenav {
  flex: 0 0 220px;
  background: var(--card-bg);
  border-right: 1px solid var(--border);
  padding: 16px 0;
}

.sidenav .nav-section-title {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--text-muted);
  padding: 4px 20px;
  margin-top: 8px;
}

.sidenav a {
  display: block;
  padding: 8px 20px;
  color: var(--text);
  border-left: 3px solid transparent;
  font-size: 13px;
}

.sidenav a:hover {
  background: var(--accent-light);
  text-decoration: none;
}

.sidenav a.active {
  background: var(--accent-light);
  border-left-color: var(--accent);
  color: var(--accent-dark);
  font-weight: 600;
}

.content {
  flex: 1 1 auto;
  /* Without this, a flex item's default min-width is its content's
     min-content size — a wide table inside would force the whole page to
     scroll horizontally instead of just .table-scroll scrolling itself. */
  min-width: 0;
  padding: 24px 32px;
  max-width: 1500px;
}

.page-title {
  font-size: 22px;
  font-weight: 600;
  margin: 0 0 6px;
}

.page-subtitle {
  color: var(--text-muted);
  margin: 0 0 20px;
}

/* --- Cards / dashboard --------------------------------------------------- */

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 16px;
}

.card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 18px;
}

.card h3 {
  margin: 0 0 6px;
  font-size: 16px;
}

.card p {
  margin: 0 0 14px;
  color: var(--text-muted);
}

/* --- Forms ---------------------------------------------------------------*/

.panel {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 20px;
  margin-bottom: 20px;
}

.panel h2 {
  margin-top: 0;
  font-size: 16px;
}

.panel-summary {
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
}

/* Collapsed by default (no [open] attr) — only add breathing room below the
   summary once it's expanded, so the panel doesn't carry dead space
   while collapsed. */
details[open] .panel-summary {
  margin-bottom: 12px;
}

.field {
  margin-bottom: 14px;
}

.field label {
  display: block;
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 4px;
}

input[type="text"],
input[type="password"],
input[type="file"],
select {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  font-size: 14px;
  background: #fff;
  color: var(--text);
}

input[type="text"]:focus,
input[type="password"]:focus,
select:focus {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
  border-color: var(--accent);
}

.btn {
  display: inline-block;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: var(--radius);
  padding: 7px 16px;
  font-size: 14px;
  cursor: pointer;
}

.btn:hover {
  background: var(--accent-dark);
}

.btn.secondary {
  background: transparent;
  color: var(--accent);
  border: 1px solid var(--accent);
}

.btn.secondary:hover {
  background: var(--accent-light);
}

.alert {
  border-radius: var(--radius);
  padding: 10px 14px;
  margin-bottom: 14px;
  font-size: 13px;
}

.alert.error {
  background: var(--danger-bg);
  color: var(--danger);
  border: 1px solid var(--danger);
}

.alert.success {
  background: var(--success-bg);
  color: var(--success);
  border: 1px solid var(--success);
}

/* --- Tables --------------------------------------------------------------*/

/* Wide tables (fixed-width columns whose sum can exceed the panel) scroll
   within their own box instead of overflowing the panel's white background
   or the page itself. */
.table-scroll {
  overflow-x: auto;
}

table.data {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

table.data th,
table.data td {
  text-align: left;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
}

table.data th {
  color: var(--text-muted);
  font-weight: 600;
  background: var(--page-bg);
}

.converter-history .history-status {
  width: 100px;
}

.converter-history .history-status .page-subtitle {
  max-width: 180px;
  overflow-wrap: anywhere;
}

.converter-history .history-files {
  width: 1%;
  white-space: nowrap;
}

.status-pill {
  display: inline-block;
  border-radius: 10px;
  padding: 2px 10px;
  font-size: 12px;
  font-weight: 600;
}

.status-pill.success {
  background: var(--success-bg);
  color: var(--success);
}

.status-pill.failed {
  background: var(--danger-bg);
  color: var(--danger);
}

/* --- Template mapping page (io_payment_converter/config.html) ------------
   ~20% denser than the shared defaults above: this page's table can run to
   60+ rows (one per output column), so cutting padding/font-size here earns
   back a lot of scroll without touching those defaults for every other page
   that reuses .panel/table.data/.field. */

.mapping-page .panel {
  padding: 16px;
  margin-bottom: 16px;
}

.mapping-page .field {
  margin-bottom: 11px;
}

.mapping-page .field label {
  font-size: 12px;
  margin-bottom: 3px;
}

.mapping-page input[type="text"],
.mapping-page select {
  padding: 5px 6px;
  font-size: 12px;
}

/* The shared table.data is width:100% — with auto table-layout, that extra
   width beyond what the fixed-size inputs/selects need gets spread into each
   column as blank space rather than being absorbed anywhere else. Sizing to
   content instead lets columns hug their inputs, with only the cell padding
   below as breathing room. */
.mapping-page table.data {
  width: auto;
  font-size: 14px;
}

.mapping-page table.data th,
.mapping-page table.data td {
  padding: 6px 8px;
}

/* Column-name cell: cap its width and let long names wrap onto a 2nd line,
   rather than growing to fit the longest single-line name (that's what was
   pushing the whole table wider than the viewport). 3rd child: #, Actions,
   then Column. */
.mapping-page table.data th:nth-child(3),
.mapping-page table.data td:nth-child(3) {
  max-width: 130px;
  word-break: break-word;
}

/* # column never needs more than 2 digits. */
.mapping-page table.data th:nth-child(1),
.mapping-page table.data td:nth-child(1) {
  width: 24px;
}

.mapping-page .config-field-prompt {
  font-size: 12px;
}

.mapping-page .btn {
  padding: 6px 13px;
  font-size: 14px;
}

.mapping-type-dropdown {
  position: relative;
}

/* Matches .mapping-page select's own border/padding/font-size exactly, so the
   closed control is indistinguishable from "Filter by" next to it. */
.mapping-type-dropdown summary {
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  width: 100%;
  box-sizing: border-box;
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 5px 6px;
  font-size: 12px;
  cursor: pointer;
  background: var(--card-bg);
  outline: none;
}

/* Chrome/Edge/Safari's own disclosure-triangle hook, plus the standard
   ::marker (Firefox) — both need hiding, since our own arrow is the
   summary's ::after below. */
.mapping-type-dropdown summary::-webkit-details-marker {
  display: none;
}

.mapping-type-dropdown summary::marker {
  content: "";
}

.mapping-type-dropdown[open] summary,
.mapping-type-dropdown summary:focus-visible {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}

/* A native <select>'s own arrow, redrawn here since this is a <summary>. */
.mapping-type-dropdown summary::after {
  content: "";
  flex: none;
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid var(--text-muted, #666);
}

/* Flat and square against the box below it, like a browser's own option
   list — no card radius/shadow, so it still reads as part of the same
   control rather than a floating popover. */
.mapping-type-dropdown-panel {
  position: absolute;
  top: 100%;
  left: -1px;
  right: -1px;
  z-index: 20;
  background: var(--card-bg);
  border: 1px solid var(--accent);
  border-top: 1px solid var(--border);
}

.mapping-type-dropdown-panel label {
  display: block;
  padding: 4px 6px;
  font-size: 12px;
  cursor: pointer;
}

.mapping-type-dropdown-panel label:has(input:checked) {
  background: var(--accent);
  color: #fff;
}

.mapping-type-dropdown-panel label:not(:has(input:checked)):hover {
  background: var(--accent-light);
}

.mapping-type-select-all {
  border-bottom: 1px solid var(--border);
}

/* Compact row actions; explicit margins replace inline whitespace. */
.mapping-page .config-row-actions {
  white-space: nowrap;
  width: 1%;
  font-size: 0;
}

.mapping-page .config-row-actions .btn {
  padding: 3px 5px;
  font-size: 8px;
  line-height: 1.25;
  white-space: nowrap;
}

.mapping-page .config-row-actions .btn + .btn {
  margin-left: 3px;
}

/* --- Review popup (modal) -------------------------------------------------*/

.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 1000;
}

.modal-panel {
  background: var(--card-bg);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  width: 100%;
  max-width: 960px;
  max-height: 85vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
}

.modal-header h2 {
  margin: 0;
  font-size: 16px;
}

.modal-tabs {
  display: flex;
  gap: 4px;
  padding: 10px 20px 0;
  border-bottom: 1px solid var(--border);
}

.modal-tabs .tab-btn {
  background: transparent;
  border: 1px solid var(--border-strong);
  border-bottom: none;
  border-radius: var(--radius) var(--radius) 0 0;
  padding: 6px 14px;
  font-size: 13px;
  cursor: pointer;
  color: var(--text-muted);
  margin-bottom: -1px;
}

.modal-tabs .tab-btn.active {
  background: var(--accent-light);
  color: var(--accent-dark);
  font-weight: 600;
  border-color: var(--border-strong);
}

.modal-body {
  padding: 16px 20px;
  overflow: auto;
}

/* Lock the page only while an actual popup is present and visible. HTMX
   replaces these containers with empty placeholders when a popup closes. */
:is(html, body):has(:is(#selection-modal, #review-modal, #validation-error-modal):not([hidden]) > .modal-backdrop) {
  overflow: hidden;
}

#review-modal .modal-panel,
#selection-modal .modal-panel {
  display: block;
  max-height: min(85vh, calc(100dvh - 48px));
  overflow: auto;
  overscroll-behavior: contain;
}

#review-modal .modal-body,
#selection-modal .modal-body {
  overflow: visible;
}

/* Shown by htmx (hx-indicator, toggling .htmx-request automatically) or by a
   plain (non-htmx) form's own submit handler (toggling .is-loading manually
   — see e.g. config.html/review_config.html) while a save/convert is in
   flight: a small centered card with its own dimmed backdrop, above
   everything else (including a popup's own .modal-backdrop underneath it). */
.popup-loading {
  display: none;
}

.popup-loading.htmx-request,
.popup-loading.is-loading {
  display: flex;
  position: fixed;
  inset: 0;
  z-index: 1100;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.4);
}

.popup-loading-box {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--card-bg);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 14px 22px;
}

:is(#selection-modal, #review-modal) button:disabled {
  opacity: 0.6;
  cursor: wait;
}

.spinner {
  display: inline-block;
  width: 16px;
  height: 16px;
  border: 2px solid var(--border-strong);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

.selection-step {
  padding: 16px 20px;
}

.selection-confirm-actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}

.selection-step .modal-body {
  padding: 0;
}

.to-review {
  background: #fff4ce; /* amber */
}

.to-review .review-input {
  width: 100%;
  min-width: 90px;
  padding: 3px 6px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  font-size: 13px;
  background: #fff;
  color: var(--text);
}

.to-review .review-input:focus {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
  border-color: var(--accent);
}

/* Vendor API reference cell: "label : value" per line (see
   app/web/router.py's _vendor_reference_columns) — preserve the \n's as line
   breaks instead of collapsing them into one line. */
.reference-cell {
  white-space: pre-line;
}

/* --- Review-config admin page ---------------------------------------------*/

.review-tab {
  margin-bottom: 16px;
}

.review-tab h3 {
  font-size: 13px;
  margin: 16px 0 8px;
}

.review-field-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 8px;
}

.review-field-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.review-field-row select {
  max-width: 360px;
}

.field-combo {
  max-width: 360px;
}

/* --- Login page ----------------------------------------------------------*/

.login-page {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background: var(--page-bg);
}

.login-card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  width: 340px;
  padding: 28px 28px 24px;
}

.login-card h1 {
  font-size: 18px;
  margin: 0 0 4px;
}

.login-card .login-subtitle {
  color: var(--text-muted);
  margin: 0 0 20px;
  font-size: 13px;
}

.sso-panel {
  background: var(--accent-light);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  padding: 14px;
  margin-bottom: 4px;
}

.sso-btn {
  display: block;
  width: 100%;
  text-align: center;
  background: var(--accent);
  color: #fff;
  border-radius: var(--radius);
  padding: 12px 0;
  font-size: 15px;
  font-weight: 600;
  box-shadow: 0 2px 6px rgba(0, 120, 212, 0.35);
}

.sso-btn:hover {
  background: var(--accent-dark);
  text-decoration: none;
}

.sso-btn.disabled {
  pointer-events: none;
  opacity: 0.6;
}

.divider {
  display: flex;
  align-items: center;
  color: var(--text-muted);
  font-size: 12px;
  margin: 14px 0;
}

.divider::before,
.divider::after {
  content: "";
  flex: 1;
  border-bottom: 1px solid var(--border);
}

.divider span {
  padding: 0 8px;
}

/* De-emphasized on purpose — SSO above is the guided path; this is the
   fallback, collapsed by default so it doesn't compete for attention. */
.local-login summary {
  color: var(--text-muted);
  font-size: 13px;
  cursor: pointer;
  margin-bottom: 12px;
}
