/* ===== Twingate-inspired Dark Theme — VPN Config Mini App ===== */

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

:root {
  --void: #000;
  --obsidian: #0e0f11;
  --carbon: #141617;
  --graphite: #1d2023;
  --ash: #303438;
  --steel: #3a3d40;
  /* Steel is a border colour — at #3a3d40 it is roughly 1.5:1 against the
     card background, which is unreadable as text. Anywhere the content
     carries meaning (a service label, the filename) uses smoke instead. */
  --smoke: #8d8d96;
  --silver: #cfcfd3;
  --paper: #fff;

  --violet: #b6abff;
  --livewire: #eef35f;
  --teal: #00cbaa;
  --danger: #ff9d9d;

  --inset: inset 0 0 0 0.5px rgba(255, 255, 255, 0.10);
}

html, body {
  height: 100%;
  background: var(--void);
  color: var(--silver);
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* The app fills the viewport so the mobile dock can pin to the bottom and the
   panes can scroll internally rather than moving the whole page. */
body {
  display: flex;
  flex-direction: column;
}
#app {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  width: 100%;
}

/* ---- Topbar ---- */
#topbar {
  display: flex;
  align-items: center;
  padding: 12px 20px;
  background: var(--obsidian);
  border-bottom: 1px solid var(--ash);
  box-shadow: var(--inset);
  gap: 12px;
}
#brand {
  font-weight: 600;
  font-size: 16px;
  color: var(--paper);
  letter-spacing: -0.01em;
}
#filename {
  flex: 1;
  font-size: 13px;
  color: var(--smoke);
  font-family: "JetBrains Mono", "SF Mono", "Fira Code", monospace;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#topbar-actions {
  display: flex;
  gap: 8px;
}

/* ---- Pill Buttons ---- */
.pill-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 50px;
  padding: 0 28px;
  border: none;
  border-radius: 50px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s, box-shadow 0.15s;
  white-space: nowrap;
}
.pill-btn.primary {
  background: var(--violet);
  color: var(--void);
}
.pill-btn.primary:hover {
  box-shadow: 0 0 0 2px var(--violet);
}
.pill-btn.secondary {
  background: var(--graphite);
  color: var(--silver);
  box-shadow: var(--inset);
}
.pill-btn.secondary:hover {
  background: var(--ash);
}
.pill-btn:disabled {
  opacity: 0.4;
  cursor: default;
}

/* ---- Upload View ---- */
#upload-view {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: calc(100vh - 74px);
  padding: 40px 20px;
}
#drop-zone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  padding: 60px 40px;
  border: 2px dashed var(--steel);
  border-radius: 12px;
  background: var(--carbon);
  width: 100%;
  max-width: 480px;
  text-align: center;
  transition: border-color 0.2s, background 0.2s;
}
#drop-zone.drag-over {
  border-color: var(--teal);
  background: var(--graphite);
}
#drop-icon {
  color: var(--teal);
  width: 48px;
  height: 48px;
}
#drop-zone h2 {
  font-size: 20px;
  font-weight: 600;
  color: var(--paper);
}
#drop-text {
  font-size: 14px;
  color: var(--steel);
}

/* ---- Config View Columns ---- */
#config-view {
  padding: 20px;
}
#columns {
  display: flex;
  gap: 20px;
  align-items: flex-start;
}

/* -- Routes Column -- */
#routes-column {
  width: 340px;
  flex-shrink: 0;
  /* Same reason as the diff column: the RU preset can add ~40 routes. */
  max-height: calc(100vh - 120px);
  display: flex;
  flex-direction: column;
}
#routes-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
}
#routes-header h3 {
  font-size: 14px;
  font-weight: 600;
  color: var(--silver);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
#route-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  height: 24px;
  padding: 0 6px;
  border-radius: 12px;
  background: var(--ash);
  color: var(--paper);
  font-size: 12px;
  font-weight: 600;
}
#routes-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 6px;
  overflow-y: auto;
  min-height: 0;
}
.route-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: var(--carbon);
  border-radius: 12px;
  box-shadow: var(--inset);
  animation: fadeIn 0.25s ease;
}
.route-item.new {
  border-left: 3px solid var(--teal);
}
.route-ip {
  flex: 1;
  font-family: "JetBrains Mono", "SF Mono", "Fira Code", monospace;
  font-size: 13px;
  color: var(--paper);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.route-source {
  font-size: 11px;
  color: var(--smoke);
  background: var(--graphite);
  padding: 2px 8px;
  border-radius: 4px;
  flex-shrink: 0;
}
.route-gateway {
  font-size: 11px;
  font-family: "JetBrains Mono", "SF Mono", "Fira Code", monospace;
  color: var(--teal);
  flex-shrink: 0;
}
.route-remove {
  width: 28px;
  height: 28px;
  border: none;
  background: transparent;
  color: var(--steel);
  font-size: 18px;
  cursor: pointer;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.15s, color 0.15s;
}
.route-remove:hover {
  background: var(--ash);
  color: var(--danger);
}

/* -- Chat Column -- */
#chat-column {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 400px;
}
#chat-log {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 0;
  max-height: 70vh;
}
.chat-msg {
  padding: 10px 14px;
  border-radius: 12px;
  max-width: 80%;
  font-size: 14px;
  line-height: 1.45;
  word-break: break-word;
}
.chat-msg.system {
  align-self: flex-start;
  background: var(--graphite);
  color: var(--silver);
  border-bottom-left-radius: 4px;
}
.chat-msg.user {
  align-self: flex-end;
  background: var(--ash);
  color: var(--paper);
  border-bottom-right-radius: 4px;
}
.chat-msg .mono {
  font-family: "JetBrains Mono", "SF Mono", "Fira Code", monospace;
  font-size: 12px;
}
/* "и ещё N" — the tail of a truncated route list. */
.chat-msg .more {
  color: var(--smoke);
  font-size: 12.5px;
}
#chat-input-area {
  border-top: 1px solid var(--ash);
  padding-top: 12px;
}
/* One-click preset. Visually distinct from the chips because it is a
   different kind of action: it applies a whole set, with no model involved. */
.preset-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  padding: 12px 16px;
  margin-bottom: 10px;
  border: none;
  border-radius: 10px;
  background: rgba(0, 203, 170, 0.12);
  color: var(--teal);
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  box-shadow: inset 0 0 0 0.5px rgba(0, 203, 170, 0.35);
  transition: background 0.15s;
}
.preset-btn:hover {
  background: rgba(0, 203, 170, 0.2);
}
.preset-btn:disabled {
  opacity: 0.5;
  cursor: default;
}
.preset-note {
  font-size: 11px;
  font-weight: 400;
  color: var(--steel);
}

#chat-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 10px;
}
.chip {
  display: inline-flex;
  align-items: center;
  padding: 6px 14px;
  border: 1px solid var(--ash);
  border-radius: 50px;
  background: var(--carbon);
  color: var(--silver);
  font-size: 12px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
  white-space: nowrap;
}
.chip:hover {
  border-color: var(--violet);
  background: var(--graphite);
}
#chat-input-row {
  display: flex;
  gap: 8px;
}
#chat-input {
  flex: 1;
  height: 50px;
  padding: 0 16px;
  border: 1px solid var(--ash);
  border-radius: 8px;
  background: var(--carbon);
  color: var(--paper);
  font-family: inherit;
  font-size: 14px;
  outline: none;
  transition: border-color 0.15s;
}
#chat-input::placeholder {
  color: var(--steel);
}
#chat-input:focus {
  border-color: var(--violet);
}
#chat-send {
  flex-shrink: 0;
}

/* -- Diff Column -- */
#diff-column {
  width: 340px;
  flex-shrink: 0;
  /* Applying the RU preset adds ~40 routes at once; without a bounded height
     the column stretches the page instead of scrolling inside it. */
  max-height: calc(100vh - 120px);
  display: flex;
  flex-direction: column;
}
#diff-column h3 {
  font-size: 14px;
  font-weight: 600;
  color: var(--silver);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 12px;
}
#diff-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  overflow-y: auto;
  min-height: 0;
}
.diff-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border-radius: 6px;
  font-size: 13px;
  font-family: "JetBrains Mono", "SF Mono", "Fira Code", monospace;
}
.diff-item.add {
  background: rgba(0, 203, 170, 0.10);
  color: var(--teal);
}
.diff-item.del {
  background: rgba(255, 157, 157, 0.10);
  color: var(--danger);
}
.diff-sign {
  font-weight: 700;
  width: 16px;
  text-align: center;
  flex-shrink: 0;
}
.diff-cidr {
  flex: 1;
}

/* ---- Toast ---- */
#toast {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  padding: 12px 24px;
  border-radius: 50px;
  background: var(--graphite);
  color: var(--silver);
  font-size: 14px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
  border: 1px solid var(--ash);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
  z-index: 1000;
  white-space: nowrap;
}
#toast.show {
  opacity: 1;
  pointer-events: auto;
}
#toast.bad {
  background: rgba(255, 157, 157, 0.15);
  border-color: var(--danger);
  color: var(--danger);
}

/* ---- Animations ---- */
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ---- Bottom dock (mobile only) ---- */
#dock {
  display: none;
}

/* ---- Mobile ----
   Stacking the three panes and scrolling between them was the original
   design, and it meant scrolling past the route list to reach the chat, then
   further still to download. Tabs show one pane at a time and the dock keeps
   the primary action under the thumb. */
@media (max-width: 900px) {
  #app {
    height: 100vh;
    height: 100dvh;
    overflow: hidden;
  }
  #topbar {
    padding: 8px 14px;
    padding-top: calc(8px + env(safe-area-inset-top));
  }
  #brand {
    font-size: 15px;
  }
  /* The actions live in the dock now; keeping them here would force the
     header to wrap on a narrow screen. */
  #topbar-actions {
    display: none !important;
  }

  #config-view {
    padding: 0;
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
  }
  #columns {
    flex: 1;
    min-height: 0;
    gap: 0;
    align-items: stretch;
  }
  /* One pane at a time, chosen by the active tab. */
  #columns > [data-pane] {
    display: none;
    width: 100%;
    max-height: none;
    flex: 1;
    min-height: 0;
  }
  #columns > [data-pane].is-active {
    display: flex;
    flex-direction: column;
  }

  #routes-column,
  #diff-column {
    border: none;
    padding: 0 14px;
  }
  #routes-list,
  #diff-list {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding-bottom: 8px;
  }
  #chat-column {
    min-height: 0;
  }
  #chat-log {
    flex: 1;
    min-height: 0;
    max-height: none;
    padding: 12px 14px;
  }
  #chat-input-area {
    padding: 8px 14px calc(8px + env(safe-area-inset-bottom));
  }
  #chat-input {
    height: 44px;
  }
  /* 16px prevents iOS Safari from zooming the whole page on focus. */
  #chat-input,
  #chat-input::placeholder {
    font-size: 16px;
  }
  #btn-ru-bypass {
    padding: 11px 14px;
    font-size: 13px;
  }
  .preset-note {
    display: none;
  }

  #dock {
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
    background: var(--obsidian);
    border-top: 1px solid var(--ash);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .dock-cta {
    margin: 10px 14px;
    height: 46px;
    justify-content: center;
  }
  #tabbar {
    display: flex;
    border-top: 1px solid var(--ash);
  }
  .tab {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 8px 4px 10px;
    border: none;
    background: none;
    color: var(--smoke);
    font-family: inherit;
    font-size: 11px;
    cursor: pointer;
    position: relative;
  }
  .tab svg {
    width: 19px;
    height: 19px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  .tab.is-active {
    color: var(--livewire);
  }
  .tab-badge {
    position: absolute;
    top: 4px;
    right: 50%;
    transform: translateX(22px);
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 8px;
    background: var(--graphite);
    color: var(--silver);
    font-size: 10px;
    line-height: 16px;
    text-align: center;
  }
  .tab-badge:empty,
  .tab-badge[data-zero="1"] {
    display: none;
  }

  #drop-zone {
    padding: 40px 20px;
  }
}