:root{--bg:#0e1420;--bg2:#121a28;--card:#17202f;--card2:#1c2637;--border:#2a374c;--ink:#e4eaf1;--muted:#91a1b5;--head:#f5f8fb;--accent:#69a7d8;--bad:#e5645a;--ok:#4cc38a}*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font:14px/1.5 "Segoe UI",system-ui,sans-serif}h1{margin:0 0 6px;color:var(--head);font-size:24px}h2{margin:0 0 7px;font-size:16px}p{margin-top:0;color:var(--muted)}button,input,select,textarea{font:inherit}.chrome{height:66px;display:flex;align-items:center;padding:0 24px;background:var(--bg2);border-bottom:1px solid var(--border)}.brand{display:flex;gap:10px;align-items:center}.brand>span{font-size:24px}.brand small{display:block;color:var(--muted)}#app-version{margin-left:auto;color:var(--muted)}main{max-width:1380px;margin:auto;padding:24px}.screen{display:none}.screen.visible{display:block}.page-head,.card>header,.modal>header{display:flex;justify-content:space-between;align-items:flex-start;gap:18px;margin-bottom:18px}.card{background:var(--card);border:1px solid var(--border);border-radius:12px;padding:18px}.btn{background:var(--card2);color:var(--ink);border:1px solid var(--border);border-radius:8px;padding:8px 15px;cursor:pointer}.btn:hover{border-color:var(--accent)}.btn.primary{background:var(--accent);color:#0b1826;font-weight:700}.btn.small{padding:6px 10px}.actions,.checks{display:flex;gap:8px;flex-wrap:wrap}.link,.icon{border:0;background:none;color:var(--accent);cursor:pointer}.icon{font-size:24px}.matrix-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px}.matrix-card{min-height:170px;display:flex;flex-direction:column;justify-content:space-between}.tabs,.steps{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:14px}.tabs button,.steps span{padding:8px 11px;background:var(--card2);border:1px solid var(--border);color:var(--muted);border-radius:8px}.tabs button{cursor:pointer}.tabs .active{border-color:var(--accent);color:var(--head)}.panel{display:none}.panel.active{display:block}label{display:block;color:var(--muted);margin-bottom:14px}input,select,textarea{display:block;width:100%;margin-top:5px;background:var(--card2);color:var(--ink);border:1px solid var(--border);border-radius:7px;padding:8px}input[type=checkbox]{display:inline;width:auto;margin:0 5px 0 0}.two{display:grid;grid-template-columns:1fr 1fr;gap:14px}.grid-head{color:var(--muted);font-size:12px;text-transform:uppercase;padding:0 6px 6px}.parameter-grid,.parameter-row{display:grid;grid-template-columns:1.2fr 1.4fr .8fr 1fr .8fr auto;gap:8px;align-items:center}.band-grid,.band-row{display:grid;grid-template-columns:1.2fr 1.2fr .7fr .7fr .7fr auto;gap:8px;align-items:center}.parameter-row,.band-row{padding:8px 0;border-bottom:1px solid var(--border)}.parameter-row input,.parameter-row select,.band-row input,.band-row select{margin:0}.tablewrap{overflow:auto}table{width:100%;border-collapse:collapse}th,td{padding:8px;border-bottom:1px solid var(--border);text-align:left;white-space:nowrap}th{color:var(--muted);font-size:12px;text-transform:uppercase}td input,td select{margin:0;min-width:95px}.score-card,.output-card{margin-bottom:12px}.summary-grid{display:grid;grid-template-columns:1.5fr 1fr .7fr .7fr auto auto auto;gap:10px;align-items:end}.output-grid{grid-template-columns:1.5fr .8fr 1fr auto auto auto}.component-row{display:grid;grid-template-columns:1fr .45fr auto;gap:8px;margin:7px 0}.mapping-row{display:grid;grid-template-columns:250px 1fr 1fr;gap:10px;align-items:center;padding:7px 0;border-bottom:1px solid var(--border)}.spaced{margin-top:14px}.modal-bg{position:fixed;inset:0;background:rgba(5,9,15,.84);display:flex;align-items:center;justify-content:center;padding:24px;z-index:100}.modal-bg[hidden]{display:none}.modal{width:min(980px,96vw);max-height:88vh;overflow:auto;background:var(--card);border:1px solid var(--border);border-radius:14px;padding:20px}.modal.wide{width:min(1120px,96vw)}.modal footer{display:flex;justify-content:flex-end;gap:8px;margin-top:18px}.formula-row{display:grid;grid-template-columns:1fr .8fr 1fr auto;gap:8px;padding:8px 0;border-bottom:1px solid var(--border)}.operand{display:grid;grid-template-columns:.7fr 1.3fr;gap:6px}.rule-card{background:var(--card2);border:1px solid var(--border);border-radius:10px;padding:12px;margin-bottom:10px}.condition{display:grid;grid-template-columns:1fr .9fr .7fr 1fr auto;gap:8px;margin-bottom:7px}.score-chip{display:inline-block;padding:2px 8px;border-radius:6px;font-weight:700}#toasts{position:fixed;right:18px;bottom:18px;z-index:120}.toast{background:var(--card2);border:1px solid var(--border);border-radius:8px;padding:10px 15px;margin-top:8px}.toast.error{border-color:var(--bad)}.toast.success{border-color:var(--ok)}@media(max-width:900px){.two{grid-template-columns:1fr}.summary-grid,.output-grid{grid-template-columns:1fr 1fr}.mapping-row{grid-template-columns:1fr}}

.runner-step[hidden] {
  display: none;
}

.source-file-list {
  display: grid;
  gap: 10px;
  margin-top: 14px;
}

.source-file-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.join-row {
  display: grid;
  grid-template-columns: minmax(220px, 0.8fr) minmax(260px, 1.2fr);
  gap: 12px;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
}

.mapping-table,
.gap-table {
  width: 100%;
  border-collapse: collapse;
}

.mapping-table th,
.mapping-table td,
.gap-table th,
.gap-table td {
  padding: 8px;
  border-bottom: 1px solid var(--border);
  text-align: left;
  vertical-align: middle;
}

.mapping-table th,
.gap-table th {
  color: var(--muted);
  font-size: 12px;
  text-transform: uppercase;
  white-space: nowrap;
}

.mapping-table select {
  min-width: 180px;
  margin: 0;
}

.gap-table input {
  min-width: 140px;
  margin: 0;
}

.existing-value {
  color: var(--muted);
  background: rgba(255, 255, 255, 0.025);
}

.source-file-name {
  color: var(--head);
}

.source-file-meta {
  margin-top: 3px;
}

.screen-footer {
  display: flex;
  justify-content: flex-end;
  gap: 9px;
  margin-top: 16px;
}

@media (max-width: 900px) {
  .join-row {
    grid-template-columns: 1fr;
  }
}

[hidden] {
  display: none !important;
}

.account-context {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  padding-right: 18px;
  border-right: 1px solid var(--border);
}

.account-context span {
  color: var(--muted);
  font-size: 11px;
  line-height: 1.35;
}

.logout-button {
  flex-shrink: 0;
}

.home-button {
  width: 36px;
  height: 34px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.home-icon {
  width: 17px;
  height: 17px;
  fill: currentColor;
}

.auth-controls {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 18px;
}

.login-layout {
  min-height: calc(100vh - 48px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px 20px;
}

.login-card {
  width: min(440px, 100%);
  padding: 34px;
  text-align: center;
}

.login-mark {
  width: 62px;
  height: 62px;
  margin: 0 auto 18px;
  border-radius: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--card2);
  border: 1px solid var(--border);
  color: var(--accent);
  font-size: 31px;
}

.login-card h1 {
  margin-bottom: 10px;
}

.login-card > p {
  max-width: 340px;
  margin-left: auto;
  margin-right: auto;
}

.login-button {
  width: 100%;
  margin-top: 12px;
  padding: 11px 16px;
}

.login-button:disabled,
#logout-button:disabled {
  cursor: wait;
  opacity: 0.7;
}

.login-status {
  margin-top: 16px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--card2);
  color: var(--muted);
  text-align: left;
}

.login-status.error {
  border-color: var(--bad);
  color: var(--ink);
}

.login-note {
  margin-top: 18px;
  margin-bottom: 8px;
  font-size: 12px;
}

.login-version {
  color: var(--muted);
  font-size: 12px;
}

@media (max-width: 700px) {
  .chrome {
    height: auto;
    min-height: 66px;
    padding-top: 10px;
    padding-bottom: 10px;
  }

  .auth-controls {
    gap: 10px;
  }

  .account-context {
    min-width: 0;
    padding-right: 10px;
  }


  .login-card {
    padding: 25px 20px;
  }
}

.btn:disabled {
  cursor: not-allowed;
  opacity: 0.45;
  border-color: var(--border);
}

.btn:disabled:hover {
  border-color: var(--border);
}

/* ------------------------------------------------------------- progress / busy state */
.upload-progress {
  margin-top: 16px;
  max-width: 560px;
}
.upload-progress[hidden] { display: none; }
.upload-progress-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 7px;
  color: var(--muted);
  font-size: 12.5px;
}
#upload-progress-count {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
.upload-progress-track {
  width: 100%;
  height: 7px;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg2);
}
.upload-progress-fill {
  width: 0%;
  height: 100%;
  border-radius: inherit;
  background: var(--accent);
  transition: width .18s ease;
}
.overlay {
  position: fixed;
  inset: 0;
  z-index: 250;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(14, 20, 32, .78);
  backdrop-filter: blur(2px);
}
.overlay[hidden] { display: none; }
.overlay-box {
  min-width: 180px;
  padding: 22px 28px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--card);
  color: var(--head);
  text-align: center;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .28);
}
.spinner {
  width: 34px;
  height: 34px;
  margin: 0 auto 13px;
  border: 3px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin .75s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
body.busy { cursor: wait; }
body.busy button { cursor: wait; }
@media (prefers-reduced-motion: reduce) {
  .spinner { animation-duration: 2.5s; }
  .upload-progress-fill { transition: none; }
}

/* ------------------------------------------------------------- mobile layout */
/* These rules are intentionally scoped to phone-sized viewports so the desktop
   layout above remains unchanged. */
@media (max-width: 700px) {
  html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
  }

  body {
    font-size: 16px;
    line-height: 1.55;
  }

  h1 {
    font-size: 26px;
    line-height: 1.18;
    margin-bottom: 8px;
  }

  h2 {
    font-size: 19px;
    line-height: 1.25;
  }

  p {
    line-height: 1.55;
  }

  .chrome {
    min-height: 64px;
    padding: 10px 14px;
    gap: 10px;
  }

  .brand {
    min-width: 0;
    gap: 8px;
  }

  .brand > span {
    font-size: 22px;
  }

  .brand b {
    font-size: 14px;
    white-space: nowrap;
  }

  .brand small {
    font-size: 11px;
    white-space: nowrap;
  }

  .auth-controls {
    gap: 8px;
  }

  /* The role label competes with the brand + Home + Log out for the very
     limited phone header width. Keep it on desktop, but hide it on phones so
     the primary navigation never overlaps. */
  .account-context {
    display: none;
  }

  .home-button {
    width: 42px;
    height: 42px;
  }

  .home-icon {
    width: 19px;
    height: 19px;
  }

  .logout-button {
    min-height: 42px;
    padding: 8px 12px;
  }

  main {
    width: 100%;
    max-width: none;
    padding: 18px 14px 28px;
  }

  .page-head,
  .card > header,
  .modal > header {
    gap: 12px;
    margin-bottom: 16px;
  }

  .page-head {
    flex-direction: column;
    align-items: stretch;
  }

  .page-head > .actions {
    width: 100%;
  }

  #dashboard .page-head {
    flex-direction: row;
    align-items: flex-start;
  }

  #dashboard .page-head > div {
    min-width: 0;
    flex: 1;
  }

  #new-matrix {
    flex-shrink: 0;
  }

  .card {
    border-radius: 11px;
    padding: 16px;
  }

  .btn {
    min-height: 44px;
    padding: 10px 14px;
    font-size: 15px;
    touch-action: manipulation;
  }

  .btn.small {
    min-height: 40px;
    padding: 8px 12px;
  }

  input,
  select,
  textarea {
    min-height: 44px;
    padding: 10px 11px;
    font-size: 16px; /* prevents iOS form-control zoom */
  }

  textarea {
    min-height: 110px;
  }

  .matrix-grid {
    grid-template-columns: 1fr;
    gap: 12px;
  }

  .matrix-card {
    min-height: 0;
    padding: 17px;
  }

  .matrix-card h2 {
    font-size: 19px;
  }

  .matrix-card p {
    font-size: 15px;
  }

  .matrix-card .actions {
    margin-top: 12px;
  }

  .tabs,
  .steps {
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    margin: 0 -14px 16px;
    padding: 0 14px 2px;
  }

  .tabs::-webkit-scrollbar,
  .steps::-webkit-scrollbar {
    display: none;
  }

  .tabs button,
  .steps span {
    flex: 0 0 auto;
    min-height: 42px;
    display: inline-flex;
    align-items: center;
    padding: 9px 12px;
    font-size: 14px;
    white-space: nowrap;
  }

  .two,
  .summary-grid,
  .output-grid,
  .component-row,
  .formula-row,
  .condition {
    grid-template-columns: 1fr;
  }

  .grid-head {
    display: none;
  }

  .parameter-row,
  .band-row {
    grid-template-columns: 1fr;
    gap: 6px;
    padding: 12px 0;
  }

  .join-row {
    grid-template-columns: 1fr;
    gap: 8px;
    padding: 12px 0;
  }

  .join-row strong,
  .source-file-name {
    overflow-wrap: anywhere;
    word-break: break-word;
  }

  .source-file-list {
    gap: 10px;
  }

  .source-file-card {
    align-items: flex-start;
    gap: 12px;
  }

  .source-file-card > div {
    min-width: 0;
    flex: 1;
  }

  .source-file-meta {
    font-size: 14px;
    color: var(--muted);
  }

  /* Preserve every table column on phones. The table becomes an intentional
     horizontal scroller rather than shrinking text/controls until unreadable. */
  .tablewrap {
    width: 100%;
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    -webkit-overflow-scrolling: touch;
    border-radius: 8px;
  }

  .mapping-table {
    min-width: 760px;
  }

  .gap-table {
    min-width: 720px;
  }

  #report-table {
    min-width: 720px;
  }

  th,
  td,
  .mapping-table th,
  .mapping-table td,
  .gap-table th,
  .gap-table td {
    padding: 10px 9px;
  }

  th,
  .mapping-table th,
  .gap-table th {
    font-size: 11px;
  }

  td {
    font-size: 14px;
  }

  .mapping-table select,
  .gap-table input,
  td input,
  td select {
    min-width: 150px;
  }

  .screen-footer {
    gap: 8px;
    margin-top: 18px;
  }

  .screen-footer .btn {
    flex: 1 1 0;
  }

  #report-step .page-head {
    gap: 10px;
  }

  #report-step .page-head .actions {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
  }

  #report-step .page-head .actions .btn {
    width: 100%;
  }

  #report-meta {
    font-size: 14px;
  }

  .score-chip {
    padding: 4px 8px;
  }

  .modal-bg {
    padding: 10px;
    align-items: flex-end;
  }

  .modal,
  .modal.wide {
    width: 100%;
    max-height: 92vh;
    border-radius: 16px 16px 0 0;
    padding: 18px 16px calc(18px + env(safe-area-inset-bottom));
  }

  .modal footer {
    position: sticky;
    bottom: 0;
    padding-top: 10px;
    background: var(--card);
  }

  #toasts {
    left: 12px;
    right: 12px;
    bottom: calc(12px + env(safe-area-inset-bottom));
  }

  .toast {
    width: 100%;
    margin-top: 6px;
  }

  .upload-progress {
    max-width: none;
  }

  .overlay-box {
    width: min(280px, calc(100vw - 40px));
    min-width: 0;
    padding: 22px 20px;
  }

  .login-layout {
    min-height: calc(100dvh - 36px);
    padding: 20px 0;
  }

  .login-card {
    padding: 26px 20px;
  }
}

@media (max-width: 430px) {
  .brand small {
    display: none;
  }

  #dashboard .page-head {
    flex-direction: column;
  }

  #new-matrix {
    width: 100%;
  }

  .source-file-card {
    flex-direction: column;
  }

  .source-file-card .remove-source-file {
    width: 100%;
  }
}
