/* Otto iPad shell — otto-desktop/src/styles.css with the download-tray
   rules removed (iOS owns downloads) and an iPad block appended at the very
   bottom. Everything between is byte-identical to the Windows build, so a
   diff against it stays readable. Sidebar mirrors the web Otto sidebar
   exactly (driven by postMessage state broadcast from the isaac.html
   iframe). */

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; overflow: hidden; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 13px;
  color: #1f2937;
  background: #f8fafc;
}

#app {
  display: grid;
  grid-template-columns: 240px 1fr;
  height: 100%;
}

/* ── Sidebar ─────────────────────────────────────────────────────────── */
#sidebar {
  background: #0f172a;
  color: #cbd5e1;
  display: flex;
  flex-direction: column;
  user-select: none;
  min-height: 0;
}

.sb-head {
  padding: 14px 16px 10px;
  border-bottom: 1px solid #1e293b;
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
}
.sb-logo { display: flex; align-items: center; gap: 9px; flex: 1; min-width: 0; }
.sb-collapse-btn {
  background: transparent; color: #64748b; border: 1px solid #334155;
  border-radius: 6px; padding: 2px 8px;
  font-size: 13px; line-height: 1;
  cursor: pointer; font-family: inherit;
  flex-shrink: 0;
}
.sb-collapse-btn:hover { background: #1e293b; color: #f1f5f9; }
.sb-logo-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: linear-gradient(135deg, #38bdf8, #a78bfa);
  box-shadow: 0 0 8px rgba(56,189,248,.4);
}
/* Real Essentials lockup (white variant on the dark sidebar — canonical
   asset from branding/, never CSS-inverted). */
.sb-logo-img {
  height: 34px; width: auto; display: block;
  flex-shrink: 0; user-select: none;
}
.sb-logo-text {
  font-weight: 800; font-size: 17px; color: #f8fafc; letter-spacing: -0.01em;
}
.sb-logo-dot-period { color: #38bdf8; }

/* Search box */
.sb-search { padding: 10px 12px 6px; }
.sb-search-w {
  display: flex; align-items: center; gap: 7px;
  background: #1e293b; border: 1px solid #334155;
  border-radius: 7px; padding: 6px 9px;
}
.sb-search-w:focus-within { border-color: #38bdf8; }
.sb-search-i-prefix { font-size: 11px; opacity: .7; }
.sb-search-i {
  flex: 1;
  background: transparent; border: 0; outline: 0;
  color: #f1f5f9; font-size: 12px;
  font-family: inherit;
}
.sb-search-i::placeholder { color: #64748b; }
.sb-kbd {
  font-size: 9px; color: #94a3b8;
  background: #0f172a; border: 1px solid #334155;
  padding: 2px 5px; border-radius: 4px;
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
}

/* Body — scrollable list of nodes */
.sb-body {
  flex: 1; overflow-y: auto;
  padding: 6px 8px;
  scrollbar-width: thin;
  scrollbar-color: #334155 transparent;
}
.sb-body::-webkit-scrollbar { width: 8px; }
.sb-body::-webkit-scrollbar-thumb { background: #334155; border-radius: 4px; }

/* Section labels (Pinned / Navigation) */
.sb-lbl {
  text-transform: uppercase; letter-spacing: .08em;
  font-size: 10px; font-weight: 600;
  color: #64748b;
  padding: 12px 10px 6px;
}

/* Top-level item button (Dashboard, category headers) */
.sb-item {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 7px 10px;
  background: transparent; border: 0; color: #cbd5e1;
  font-size: 13px; text-align: left; cursor: pointer;
  border-radius: 6px;
  font-family: inherit;
  margin-bottom: 1px;
}
.sb-item:hover { background: #1e293b; color: #f8fafc; }
.sb-item.act { background: #1e293b; color: #f8fafc; }
.sb-item.act .sb-ic { filter: drop-shadow(0 0 4px rgba(56,189,248,.5)); }

/* ERP space — header (Back to Otto + Live/Demo switch) + title */
.erp-hd { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 6px 4px; }
.erp-back { display: inline-flex; align-items: center; gap: 5px; background: #1e293b; color: #cbd5e1;
  border: 1px solid #334155; border-radius: 7px; padding: 5px 9px; font-size: 12px; font-weight: 600;
  cursor: pointer; font-family: inherit; }
.erp-back:hover { background: #273449; color: #f8fafc; }
.erp-envs { display: inline-flex; background: #0f172a; border: 1px solid #334155; border-radius: 7px; overflow: hidden; }
.erp-env { background: transparent; color: #94a3b8; border: 0; padding: 5px 10px; font-size: 11.5px;
  font-weight: 600; cursor: pointer; font-family: inherit; }
.erp-env:hover { color: #f8fafc; }
.erp-env.act { background: #2c4ef5; color: #fff; }
.erp-title { font-weight: 700; }
.erp-title.erp-live { color: #34d399; }
.erp-title.erp-demo { color: #fbbf24; }
.sb-ic { font-size: 14px; width: 18px; text-align: center; flex-shrink: 0; }
.sb-l  { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sb-cv {
  display: inline-flex; align-items: center; justify-content: center;
  transition: transform .15s;
  color: #64748b;
}
.sb-section.exp .sb-cv { transform: rotate(90deg); color: #cbd5e1; }
.sb-section.exp .sb-children { display: block; }

.sb-children { display: none; padding: 2px 0 4px 4px; }

/* Child row (a page inside an expanded category, or a pin) */
.sb-child {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 10px 5px 26px;
  border-radius: 5px;
  color: #94a3b8;
  font-size: 12px;
  cursor: pointer;
}
.sb-child:hover { background: #1e293b; color: #f1f5f9; }
.sb-child.act  { background: #1e293b; color: #f8fafc; font-weight: 600; }
.sb-child-dot  { font-size: 11px; opacity: .55; }
.sb-child-l    { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sb-child-pin {
  background: transparent; border: 0; cursor: pointer;
  color: #475569; padding: 2px 3px;
  display: none;
  font-family: inherit;
}
.sb-child:hover .sb-child-pin { display: inline-flex; }
.sb-child.pin  .sb-child-pin  { display: inline-flex; color: #fbbf24; }
.sb-child-pin:hover { color: #fde68a; }

.sb-empty {
  padding: 8px 12px;
  color: #475569; font-size: 11px; font-style: italic;
}

/* Drag & drop reorder for pinned rows */
.sb-child[draggable="true"] { cursor: grab; }
.sb-child[draggable="true"]:active { cursor: grabbing; }
.sb-child.dragging { opacity: .35; }
/* Use outer box-shadow so the 2px indicator doesn't shift layout while dragging. */
.sb-child.drop-before { box-shadow: 0 -3px 0 0 #38bdf8; }
.sb-child.drop-after  { box-shadow: 0  3px 0 0 #38bdf8; }

/* Utility row — Diag + Legacy Menu, just above footer */
.sb-utility {
  display: flex; gap: 6px; padding: 8px 10px;
  border-top: 1px solid #1e293b;
}
.sb-util-btn {
  flex: 1;
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  padding: 6px 8px;
  background: #1e293b; color: #cbd5e1; border: 1px solid #334155;
  border-radius: 5px; cursor: pointer;
  font-size: 11px; font-weight: 500;
  font-family: inherit;
}
.sb-util-btn:hover { background: #334155; color: #f8fafc; }
.sb-util-err {
  background: #ef4444; color: #fff;
  padding: 1px 5px; border-radius: 8px;
  font-size: 9px; font-weight: 700;
  display: none;
}
.sb-util-err.has { display: inline-flex; }

/* Dedicated "Check for updates" row, slightly emphasized so users can spot it. */
.sb-utility-update { border-top: 0; padding-top: 0; }
.sb-util-update {
  background: #0c4a6e; color: #e0f2fe; border-color: #0369a1;
  width: 100%;
}
.sb-util-update:hover { background: #075985; color: #f0f9ff; }

/* Footer — user identity + admin/gear/logout */
.sb-foot {
  display: flex; align-items: center; gap: 9px;
  padding: 10px 12px; border-top: 1px solid #1e293b;
}
.sb-av {
  width: 30px; height: 30px; border-radius: 50%;
  background: linear-gradient(135deg, #38bdf8, #a78bfa);
  color: #fff; font-weight: 700; font-size: 12px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.sb-meta { flex: 1; min-width: 0; }
.sb-name {
  color: #f1f5f9; font-size: 12px; font-weight: 600;
  display: flex; align-items: center; gap: 5px;
  min-width: 0;
}
.sb-name-text {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-width: 0;
}
.sb-name-admin {
  font-size: 8px; text-transform: uppercase; letter-spacing: .06em;
  background: #38bdf8; color: #0f172a; padding: 1px 5px; border-radius: 3px;
  font-weight: 700;
  flex-shrink: 0;
}
.sb-role {
  color: #64748b; font-size: 10px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sb-id-hit {
  display: flex; align-items: center; gap: 9px;
  flex: 1; min-width: 0;
  cursor: pointer;
  margin: -4px -6px; padding: 4px 6px;
  border-radius: 7px;
  transition: background .12s ease;
}
.sb-id-hit:hover { background: #1e293b; }
.sb-id-actions { display: flex; gap: 3px; flex-shrink: 0; }
/* Account-details popover — anchored above the footer identity area. */
.sb-id-pop {
  position: fixed; z-index: 300;
  min-width: 230px; max-width: 300px;
  background: #1e293b; border: 1px solid #334155; border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,.45);
  padding: 14px;
  color: #f1f5f9; font-size: 12px;
}
.sb-id-pop-head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.sb-id-pop-av {
  width: 38px; height: 38px; border-radius: 50%;
  background: linear-gradient(135deg, #38bdf8, #a78bfa);
  color: #fff; font-weight: 700; font-size: 14px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.sb-id-pop-name {
  font-size: 13px; font-weight: 700; color: #f8fafc;
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  word-break: break-word;
}
.sb-id-pop-row {
  display: flex; gap: 8px; padding: 4px 0;
  color: #cbd5e1;
}
.sb-id-pop-row .k { color: #64748b; flex-shrink: 0; width: 46px; font-size: 10px; text-transform: uppercase; letter-spacing: .05em; padding-top: 1px; }
.sb-id-pop-row .v { word-break: break-all; user-select: text; }
.sb-id-btn {
  background: transparent; border: 0; color: #94a3b8; cursor: pointer;
  padding: 4px 5px; border-radius: 4px; font-size: 13px;
  font-family: inherit;
}
.sb-id-btn:hover { background: #1e293b; color: #f8fafc; }
.sb-id-btn.logout:hover { color: #f87171; }

.sb-version {
  padding: 4px 14px 6px;
  color: #f1f5f9; font-size: 10px; font-weight: 600;
  border-top: 1px solid #1e293b;
  text-align: center;
  opacity: .85;
}

/* ── Main / tab bar ──────────────────────────────────────────────────── */
#main {
  display: flex; flex-direction: column; min-width: 0;
  background: #f1f5f9;
}
/* Tab strip shares the sidebar's slate palette so the whole window frame reads
   as one dark chrome wrapping the light content area. Everything that sits on
   this bar had light-surface colors before (dark text, dark hover overlays) and
   had to be re-toned — dark-on-dark is invisible, not subtle. */
#tabBar {
  display: flex; align-items: center;
  /* A touch lighter than the sidebar's #0f172a so the two dark panels read as
     separate surfaces instead of one undifferentiated block. */
  background: linear-gradient(180deg, #16213a 0%, #131d33 100%);
  border-bottom: 1px solid #0b1220;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.04);
  height: 42px;
  padding: 0 6px;
}
/* No horizontal scrollbar. Tabs stop before they'd need one; the surplus
   moves into the ▾ overflow menu instead (see layoutTabOverflow in main.js).
   A scrolling strip meant hunting sideways for a tab you could no longer
   read — the menu shows every tab's full label at once. */
#tabsScroller {
  flex: 1; min-width: 0;
  display: flex; align-items: center; gap: 4px;
  overflow: hidden;
  padding: 0 2px;
}
.tab.tab-hidden { display: none; }

/* Overflow button — sits between the strip and "+" */
#tabOverflowBtn {
  display: flex; align-items: center; gap: 3px;
  flex-shrink: 0;
  height: 30px; padding: 0 9px; margin-left: 2px;
  background: rgba(255,255,255,.07); color: #cbd5e1;
  border: none; border-radius: 8px;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.09);
  font-family: inherit; font-size: 11px; font-weight: 700;
  cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
#tabOverflowBtn:hover { background: #2b3a52; color: #f8fafc; }
#tabOverflowBtn.hidden { display: none; }
.tab-ovf-chev { font-size: 9px; opacity: .7; }

/* Vertical list of every open tab */
.tab-ovf-menu {
  position: fixed; z-index: 1000;
  background: #1c2942; border: 1px solid #334155; border-radius: 9px;
  box-shadow: 0 10px 34px rgba(0,0,0,.5);
  padding: 4px; min-width: 240px; max-width: 380px;
  max-height: 70vh; overflow-y: auto;
  scrollbar-width: thin; scrollbar-color: #475569 transparent;
}
.tab-ovf-menu::-webkit-scrollbar { width: 8px; }
.tab-ovf-menu::-webkit-scrollbar-thumb { background: #475569; border-radius: 4px; }
.tab-ovf-menu .tab-ovf-head {
  font-size: 10px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: #7b8ba3; padding: 6px 10px 4px;   /* 4.2:1 on this surface, see .ctx-zoom-head */
}
.tab-ovf-item {
  display: flex; align-items: center; gap: 8px;
  width: 100%; background: transparent; border: none; cursor: pointer;
  padding: 7px 10px; border-radius: 5px;
  font-family: inherit; font-size: 12px; color: #cbd5e1; text-align: left;
}
.tab-ovf-item:hover { background: #2b3a52; color: #f8fafc; }
.tab-ovf-item[data-active="1"] {
  background: #29384f; color: #f8fafc; font-weight: 700;
  box-shadow: inset 2px 0 0 #38bdf8;
}
.tab-ovf-item .ovf-lbl {
  flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Marks tabs currently pushed out of the strip, so the menu explains itself */
.tab-ovf-item .ovf-tag {
  font-size: 9px; font-weight: 700; color: #94a3b8;
  border: 1px solid #475569; border-radius: 999px; padding: 1px 6px;
}
.tab-ovf-item .ovf-x {
  width: 18px; height: 18px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; font-size: 10px; color: #94a3b8;
}
.tab-ovf-item .ovf-x:hover { background: rgba(255,255,255,.18); color: #f8fafc; }
.tab {
  display: flex; align-items: center; gap: 7px;
  padding: 0 8px 0 12px;
  min-width: 110px; max-width: 220px;
  height: 30px;
  /* Inactive tabs are soft chips — visible pills, just quieter than the
     active card — so the strip reads as modern even when unfocused. */
  background: rgba(255,255,255,.05); color: #94a3b8;
  border-radius: 8px;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.06);
  cursor: pointer;
  font-size: 12px; font-weight: 500;
  user-select: none;
  transition: background .12s ease, color .12s ease, box-shadow .12s ease;
}
/* Active tab = raised slate card with a sky rim, echoing .sb-item.act. */
.tab.active {
  background: linear-gradient(180deg, #29384f 0%, #223047 100%);
  color: #f8fafc; font-weight: 600;
  box-shadow: inset 0 0 0 1px rgba(56,189,248,.38),
              inset 0 1px 0 rgba(255,255,255,.08),
              0 2px 8px rgba(0,0,0,.35);
}
.tab:hover:not(.active) { background: rgba(255,255,255,.11); color: #e2e8f0; }
/* Icons are emoji, so they can't inherit color — dim the inactive ones instead
   so they don't out-shout their own label. */
.tab .tab-icon { opacity: .72; transition: opacity .12s ease; }
.tab.active .tab-icon, .tab:hover .tab-icon { opacity: 1; }

/* Auto color-coding by space: ERP Live = green, ERP Demo = amber, Otto = neutral.
   A left stripe (inset shadow) + tint groups them at a glance, no manual groups. */
/* Text flipped from dark-on-light-tint to light-on-dark-tint. The old
   #14532d / #7c2d12 were near-black and would have been unreadable against the
   dark strip; the stripe colors are brightened for the same reason. */
.tab-erp-live { background: rgba(34,197,94,.14); color: #86efac;
  box-shadow: inset 3px 0 0 #22c55e, inset 0 0 0 1px rgba(34,197,94,.22); }
.tab-erp-live:hover:not(.active) { background: rgba(34,197,94,.24); color: #bbf7d0; }
.tab-erp-live.active { background: linear-gradient(180deg, rgba(34,197,94,.32) 0%, rgba(34,197,94,.24) 100%);
  color: #dcfce7;
  box-shadow: inset 3px 0 0 #4ade80, inset 0 1px 0 rgba(255,255,255,.1),
              inset 0 0 0 1px rgba(74,222,128,.4), 0 2px 8px rgba(0,0,0,.35); }
/* Campaign Manager space — third colour so its tabs read distinctly from
   ERP Live (green) and ERP Demo (amber). */
.tab-cm { background: rgba(56,189,248,.14); color: #7dd3fc;
  box-shadow: inset 3px 0 0 #38bdf8, inset 0 0 0 1px rgba(56,189,248,.22); }
.tab-cm:hover:not(.active) { background: rgba(56,189,248,.24); color: #bae6fd; }
.tab-cm.active { background: linear-gradient(180deg, rgba(56,189,248,.3) 0%, rgba(56,189,248,.22) 100%);
  color: #e0f2fe;
  box-shadow: inset 3px 0 0 #7dd3fc, inset 0 1px 0 rgba(255,255,255,.1),
              inset 0 0 0 1px rgba(125,211,252,.4), 0 2px 8px rgba(0,0,0,.35); }
.tab-erp-demo { background: rgba(245,158,11,.14); color: #fcd34d;
  box-shadow: inset 3px 0 0 #f59e0b, inset 0 0 0 1px rgba(245,158,11,.22); }
.tab-erp-demo:hover:not(.active) { background: rgba(245,158,11,.24); color: #fde68a; }
.tab-erp-demo.active { background: linear-gradient(180deg, rgba(245,158,11,.32) 0%, rgba(245,158,11,.24) 100%);
  color: #fef3c7;
  box-shadow: inset 3px 0 0 #fbbf24, inset 0 1px 0 rgba(255,255,255,.1),
              inset 0 0 0 1px rgba(251,191,36,.4), 0 2px 8px rgba(0,0,0,.35); }

.tab-icon { font-size: 13px; }
.tab-label { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tab-close {
  background: transparent; border: none; cursor: pointer;
  width: 18px; height: 18px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; color: inherit; font-size: 10px;
  opacity: 0; flex-shrink: 0;
  font-family: inherit;
  transition: opacity .12s ease, background .12s ease;
}
.tab:hover .tab-close, .tab.active .tab-close { opacity: .6; }
/* Light overlay, not dark — a dark scrim on a dark tab is invisible. */
.tab-close:hover { background: rgba(255,255,255,.18); opacity: 1 !important; }
/* Drag-to-reorder states */
.tab.dragging { opacity: .4; }
.tab.drop-before { box-shadow: inset 3px 0 0 #38bdf8; }
.tab.drop-after  { box-shadow: inset -3px 0 0 #38bdf8; }
#newTabBtn {
  background: transparent; border: none; color: #64748b;
  padding: 0 14px; font-size: 18px; cursor: default;
  transition: color .12s ease;
}
#newTabBtn:hover { color: #e2e8f0; }

/* ── Frames ──────────────────────────────────────────────────────────── */
#frames { flex: 1; min-height: 0; position: relative; }
#frames > iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0; display: none;
}
#frames > iframe.active { display: block; }

/* ── Context menu ────────────────────────────────────────────────────── */
/* Slate to match the tab bar and sidebar it launches from. */
.ctx-menu {
  position: fixed; z-index: 1000;
  background: #1c2942; border: 1px solid #334155; border-radius: 9px;
  box-shadow: 0 10px 34px rgba(0,0,0,.5);
  padding: 4px; min-width: 190px;
}
.ctx-menu.hidden { display: none; }
.ctx-menu button {
  display: block; width: 100%;
  background: transparent; border: none; cursor: pointer;
  padding: 7px 10px; font-size: 12px; text-align: left;
  border-radius: 5px; color: #cbd5e1;
  font-family: inherit;
}
.ctx-menu button:hover { background: #2b3a52; color: #f8fafc; }
.ctx-sep { height: 1px; background: #334155; margin: 4px 6px; }
/* The × in the corner. Clicks inside a hosted webview never reach this
   document, so the click-outside dismiss can't fire from over the app area —
   this is the visible way out (window blur + Escape are the invisible ones). */
.ctx-menu .ctx-close {
  position: absolute; top: 5px; right: 5px;
  width: 20px; height: 20px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: 5px; font-size: 14px; line-height: 1;
  color: #7b8ba3;
}
.ctx-menu .ctx-close:hover { background: #2b3a52; color: #f8fafc; }

/* ── Zoom slider (tab context menu) ──────────────────────────────────── */
.ctx-zoom { padding: 4px 10px 8px; }
.ctx-zoom-head {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 10px; font-weight: 700; letter-spacing: .06em;
  /* Lighter than the sidebar's #64748b muted label: this menu surface is
     lighter than the sidebar, so the same gray drops to 3.05:1 on it. 4.2:1. */
  text-transform: uppercase; color: #7b8ba3;
  padding: 2px 0 7px;
}
.ctx-zoom-val {
  color: #38bdf8; font-variant-numeric: tabular-nums;
  letter-spacing: 0; text-transform: none; font-size: 11px;
}
.ctx-zoom-row { display: flex; align-items: center; gap: 8px; }
/* These are round steppers, so they must opt out of the full-width block
   styling `.ctx-menu button` applies to every other item in this menu. */
.ctx-menu .ctx-zoom-btn {
  width: 22px; height: 22px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  padding: 0; border-radius: 50%;
  background: rgba(255,255,255,.08); color: #e2e8f0;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.1);
  font-size: 14px; line-height: 1; text-align: center;
}
.ctx-menu .ctx-zoom-btn:hover { background: #38bdf8; color: #0b1220; }
.ctx-menu .ctx-zoom-btn:active { transform: translateY(1px); }

.ctx-zoom-range {
  flex: 1; min-width: 96px; height: 4px; margin: 0;
  -webkit-appearance: none; appearance: none;
  background: #334155; border-radius: 999px; outline: none; cursor: pointer;
}
.ctx-zoom-range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 14px; height: 14px; border-radius: 50%;
  background: #38bdf8; border: 2px solid #1c2942;
  box-shadow: 0 0 0 1px #38bdf8, 0 0 8px rgba(56,189,248,.55);
  cursor: grab;
}
.ctx-zoom-range::-webkit-slider-thumb:active { cursor: grabbing; }
.ctx-zoom-range:focus-visible { box-shadow: 0 0 0 2px rgba(56,189,248,.4); }

/* ── Command palette (Ctrl+K) ───────────────────────────────────────── */
.kp-back {
  position: fixed; inset: 0;
  background: rgba(15,23,42,.5);
  display: flex; align-items: flex-start; justify-content: center;
  padding-top: 12vh;
  z-index: 2000;
}
.kp-back.hidden { display: none; }
.kp-modal {
  width: min(600px, 90vw);
  background: #fff; border-radius: 12px;
  box-shadow: 0 20px 60px rgba(15,23,42,.4);
  overflow: hidden;
  display: flex; flex-direction: column;
  max-height: 70vh;
}
.kp-input-wrap {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid #e2e8f0;
}
.kp-input-icon { font-size: 14px; opacity: .6; }
.kp-input {
  flex: 1; border: 0; outline: 0;
  font-size: 15px; color: #0f172a;
  font-family: inherit; background: transparent;
}
.kp-esc {
  font-size: 10px; color: #64748b;
  background: #f1f5f9; padding: 3px 7px; border-radius: 4px;
  border: 1px solid #cbd5e1;
}
.kp-results { overflow-y: auto; padding: 6px; }
.kp-group-lbl {
  text-transform: uppercase; letter-spacing: .08em;
  font-size: 10px; font-weight: 700; color: #64748b;
  padding: 8px 10px 4px;
}
.kp-row {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px; border-radius: 6px; cursor: pointer;
  font-size: 13px; color: #0f172a;
}
.kp-row:hover, .kp-row.sel { background: #e0f2fe; color: #0369a1; }
.kp-row-ic { font-size: 14px; width: 18px; text-align: center; }
.kp-row-l  { flex: 1; }
.kp-row-cat { font-size: 10px; color: #64748b; text-transform: uppercase; letter-spacing: .05em; }
.kp-empty { padding: 22px; text-align: center; color: #64748b; font-size: 12px; }

/* ── Auto-updater status pill (bottom-right) ─────────────────────────── */
.up-status {
  position: fixed; right: 14px; bottom: 14px;
  z-index: 2500;
  padding: 7px 12px; border-radius: 18px;
  font-size: 11px; font-weight: 600;
  background: #0f172a; color: #f1f5f9;
  border: 1px solid #334155;
  box-shadow: 0 4px 14px rgba(15,23,42,.3);
  font-family: inherit;
}
.up-status.up-checking { color: #fbbf24; border-color: #f59e0b; }
.up-status.up-ok       { color: #6ee7b7; border-color: #10b981; }
.up-status.up-found    { color: #38bdf8; border-color: #38bdf8; }
.up-status.up-error    { color: #fca5a5; border-color: #ef4444; max-width: 420px; line-height: 1.35; }

/* ── Forced update modal (no dismiss) ────────────────────────────────── */
#updateModal {
  position: fixed; inset: 0; z-index: 4000;
  display: flex; align-items: center; justify-content: center;
}
.um-back {
  position: absolute; inset: 0;
  background: rgba(15,23,42,.75);
  backdrop-filter: blur(4px);
}
.um-card {
  position: relative;
  width: min(440px, 90vw);
  background: #0f172a; color: #f8fafc;
  border: 1px solid #38bdf8;
  border-radius: 14px;
  padding: 28px 28px 24px;
  box-shadow: 0 30px 80px rgba(15,23,42,.6);
  text-align: center;
}
.um-title {
  font-size: 13px; font-weight: 700;
  color: #38bdf8;
  text-transform: uppercase; letter-spacing: .08em;
  margin-bottom: 6px;
}
.um-version { font-size: 22px; font-weight: 800; color: #f8fafc; }
.um-from { font-size: 12px; color: #94a3b8; font-weight: 500; }
.um-notes {
  margin-top: 14px; padding: 10px 12px;
  background: #1e293b; border-radius: 8px;
  font-size: 12px; color: #cbd5e1; text-align: left;
  max-height: 140px; overflow-y: auto;
}
.um-info {
  margin: 16px 0 18px;
  font-size: 12px; color: #94a3b8;
}
.um-apply {
  display: block; width: 100%;
  padding: 11px 18px;
  background: #38bdf8; color: #0f172a;
  border: 0; border-radius: 8px;
  font-size: 14px; font-weight: 700;
  cursor: pointer;
  font-family: inherit;
}
.um-apply:hover { background: #7dd3fc; }
.um-apply:disabled { opacity: .6; cursor: progress; }
.um-progress {
  margin-top: 14px;
  font-size: 12px; color: #fbbf24; font-weight: 600;
}

/* ── Collapsed sidebar (no rail) ─────────────────────────────────────── */
/* Collapsed means GONE: the page gets the full window and the two things the
   rail was still used for — expand and search — move to the head of the tab
   strip (#tbLead). Expanded is untouched. */
/* ONE column, not "0px 1fr": with #sidebar display:none the grid auto-places
   #main into the first track, and a 0px first track squeezed the whole tab
   bar + content into a sliver at the left edge (0.1.43 blank-screen bug). */
body.sb-collapsed #app { grid-template-columns: 1fr; }
body.sb-collapsed #sidebar { display: none; }

.tb-lead { display: none; }
body.sb-collapsed .tb-lead {
  display: flex; align-items: center; gap: 4px;
  flex-shrink: 0; margin-right: 4px;
}
.tb-ib {
  height: 30px; min-width: 30px; padding: 0 8px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.07); color: #cbd5e1;
  border: none; border-radius: 8px;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.09);
  font-family: inherit; font-size: 14px; line-height: 1;
  cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.tb-ib:hover { background: #2b3a52; color: #f8fafc; }
/* The expand chevron is the only way back to the sidebar, so it gets the
   brand sky accent instead of the muted chip grey (Eddie: "give the double
   arrow a color so they show better"). */
#tbExpandBtn {
  color: #38bdf8; font-size: 18px; font-weight: 700;
  background: rgba(56,189,248,.14);
  box-shadow: inset 0 0 0 1px rgba(56,189,248,.35);
}
#tbExpandBtn:hover { background: rgba(56,189,248,.28); color: #e0f2fe; }
.tb-ib:focus-visible { outline: 2px solid #38bdf8; outline-offset: 1px; }
.tb-sep { width: 1px; height: 18px; background: rgba(255,255,255,.12); margin: 0 4px 0 2px; }

/* ── Misc ────────────────────────────────────────────────────────────── */
.hidden { display: none !important; }

/* ══ iPad ═══════════════════════════════════════════════════════════════
   Everything above this line is the Windows shell's CSS. Everything below
   exists because a finger is not a mouse and Safari is not WebView2.

   The layout viewport is pinned to 1440px (index.html), so on an iPad Air 5
   the whole shell renders at about 0.82x in landscape and pinch-zoom is the
   way you read anything small. That is deliberate — Eddie's standing rule is
   that a "mobile version" is the full desktop app seen from a distance, not
   a phone-width crop with the useful columns hidden. Consequences of pinning
   the viewport are handled here, not by media queries: once the layout
   viewport is a fixed 1440, width-based media queries no longer tell you
   anything about the device, so the touch rules below key off
   `hover: none` + `pointer: coarse` instead.
   ═══════════════════════════════════════════════════════════════════════ */

/* iOS inflates text on a page whose layout viewport is wider than the
   screen. Without this the sidebar labels come out visibly larger than the
   tab labels and the 240px rail overflows. */
html { -webkit-text-size-adjust: 100%; }
/* The shell is a fixed frame, not a document: rubber-banding it up and down
   just detaches the sidebar from the top of the screen. Scrolling belongs to
   the iframes and the sidebar body. */
html, body { overscroll-behavior: none; }

/* Safari treats an iframe as content-sized unless the containing block
   clips, which would let a tall page stretch #frames and push the tab bar
   off screen. Momentum scrolling inside the frame is the iOS default on
   modern iPadOS; the property is harmless where it is ignored. */
#frames { overflow: hidden; }
#frames > iframe { -webkit-overflow-scrolling: touch; }

@media (hover: none) and (pointer: coarse) {
  /* A long press on the chrome opens our context menus. iOS would otherwise
     answer it with the selection magnifier and the share callout, which
     eats the gesture. Text inside a tab's page is unaffected — this is only
     the shell's own furniture. */
  #sidebar, #tabBar, .ctx-menu {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
  }

  /* The keyboard hint is a lie without a keyboard. */
  .sb-kbd, .kp-esc { display: none; }

  /* Hover-reveal does not exist on touch: anything that only appears on
     :hover is simply unreachable, so the pin star and the tab ✕ are always
     on. They are low-contrast until used, so this costs little visually. */
  .sb-child-pin { opacity: .55; }
  .sb-child.pin .sb-child-pin { opacity: 1; }
  .tab-close { opacity: .7; }

  /* Touch targets. Apple's floor is 44px; the shell is a dense desktop
     layout rendered at ~0.82x, so a 28px row is ~23 physical px — too small
     to hit reliably. These bring the rows and buttons up without changing
     the grid the rest of the layout sits on. */
  .sb-item, .sb-child { min-height: 34px; }
  .sb-util-btn { min-height: 32px; }
  .tab { min-height: 34px; }
  .tab-close { padding: 6px; margin: -4px -2px -4px 0; }
  .ctx-menu button { min-height: 36px; }
  .ctx-menu { min-width: 220px; }

  /* Pinned-row reorder arrows — the touch replacement for HTML5 drag, which
     iOS reserves for its own long-press drag session (and which would fight
     the long-press context menu). Rendered only on touch; see renderChild. */
  .sb-child-move {
    background: transparent; border: 0; padding: 0 5px;
    color: #64748b; font-size: 9px; line-height: 1;
    cursor: pointer; font-family: inherit;
    flex-shrink: 0;
    -webkit-tap-highlight-color: transparent;
  }
  .sb-child-move:active { color: #f1f5f9; }

  /* The range slider's thumb is a 12px dot by default in Safari. */
  .ctx-zoom-range { height: 28px; }
  .ctx-zoom-btn { min-width: 34px; min-height: 30px; }

  /* Stop the grey flash box on every tap of shell furniture. */
  #sidebar button, #tabBar button, .ctx-menu button, .sb-child, .sb-item {
    -webkit-tap-highlight-color: transparent;
  }
}
