@import url('https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600&family=Inter:wght@400;500;600&display=swap');

:root{
  /* --muted darkened from #7a8698: at the old value secondary copy (stat labels, the
     lede, spec labels) sat at ~3.5:1 on white, under the 4.5:1 minimum. */
  --navy:#0f1b2d; --navy2:#16263c; --ink:#1b2431; --muted:#646f80; --line:#e7e9ee;
  --gold:#c8a44d; --gold-d:#a8863a; --bg:#f6f7f9; --panel:#fff; --green:#2f9e6d; --red:#c0563f;
  --panel2:#fafbfc;          /* table headers, row hover */
  --skel:#dde2e9;            /* image placeholder before a photo loads */
  --chip:#eef0f4; --chip-ink:#5b6675;
  /* TEXT tokens. Kept separate from --navy, which is a BACKGROUND (the sidebar):
     using a background colour as a text colour is what made the stat numbers
     unreadable in dark mode. */
  --heading:#0f1b2d;         /* stat numbers, prices, property titles */
  --body:#4a5666;            /* descriptions and long copy */
  --side-dim:#8a99b0;        /* small print inside the navy sidebar (light text on navy) */
  --shadow:0 1px 3px rgba(16,27,45,.06),0 8px 24px rgba(16,27,45,.06);
}

/* Dark mode. Only the palette changes — every surface already reads these tokens, so
   there is no second set of rules to keep in sync. Driven by [data-theme] on <html>,
   which app.js sets from his saved choice (and from the OS preference the first time). */
:root[data-theme="dark"]{
  --navy:#0b1422; --navy2:#16263c; --ink:#e6ebf2; --muted:#8d9aad; --line:#243247;
  --bg:#0f1725; --panel:#161f30; --panel2:#1b2536;
  --skel:#243247; --chip:#22304a; --chip-ink:#a9b7cb;
  /* Text has to INVERT, not just shift: headings near-white for the stat numbers and
     prices, body copy a light grey that still reads as secondary. */
  --heading:#f2f6fb; --body:#c3ccd9; --side-dim:#8896ab;
  /* lift the accents so they stay legible on a dark surface */
  --gold:#d4b46a; --gold-d:#d8b86a; --green:#46b98a; --red:#e07a62;
  --shadow:0 1px 3px rgba(0,0,0,.4),0 8px 24px rgba(0,0,0,.35);
}
/* Inputs keep the browser's dark form styling in step with the theme. */
:root[data-theme="dark"]{ color-scheme: dark; }

/* A few rules bake in a light-mode assumption that a token can't express. */
:root[data-theme="dark"] .pill.live{
  /* the tint was a near-transparent dark navy — invisible on a dark panel */
  background:rgba(255,255,255,.10);
}
:root[data-theme="dark"] .btn-primary{
  /* --navy is now almost the page background, so the button would disappear */
  background:var(--gold); color:#1a1300;
}
:root[data-theme="dark"] .btn-primary:hover{ background:var(--gold-d); }
:root[data-theme="dark"] .stat-l em{ background:rgba(212,180,106,.16); }
:root[data-theme="dark"] .swipe-src{ background:rgba(70,185,138,.16); }
:root[data-theme="dark"] .drive-row{ background:rgba(212,180,106,.07); border-color:rgba(212,180,106,.25); }
:root[data-theme="dark"] .drive-row .dr-sub{ color:var(--muted); }
:root[data-theme="dark"] .drive-row .dr-open{
  background:var(--panel2); border-color:rgba(212,180,106,.25); color:var(--gold);
}
:root[data-theme="dark"] .owner-box{ background:var(--panel2); }
*{box-sizing:border-box}
body{margin:0;font-family:Inter,system-ui,sans-serif;color:var(--ink);background:var(--bg);-webkit-font-smoothing:antialiased}
.serif{font-family:Fraunces,Georgia,serif;font-weight:500;letter-spacing:-.01em}
.hidden{display:none!important}
.muted{color:var(--muted)}
.link{color:var(--gold-d);text-decoration:none;font-weight:500;font-size:13px;cursor:pointer}
.link:hover{text-decoration:underline}

#app{display:flex;min-height:100vh}

/* Sidebar */
.sidebar{width:236px;background:var(--navy);color:#cdd6e4;display:flex;flex-direction:column;position:sticky;top:0;height:100vh;flex-shrink:0}
.brand{display:flex;align-items:center;gap:10px;padding:22px 20px 26px}
.brand-mark{width:30px;height:30px;border-radius:7px;background:linear-gradient(135deg,var(--gold),var(--gold-d));color:#1a1300;display:grid;place-items:center;font-family:Fraunces,serif;font-weight:600;font-size:18px}
.brand-name{font-weight:600;letter-spacing:.02em;color:#fff}
.nav{display:flex;flex-direction:column;gap:2px;padding:0 12px;flex:1}
.nav-item{display:flex;align-items:center;gap:11px;padding:10px 12px;border-radius:8px;color:#aab6c8;font-size:14px;font-weight:500;cursor:pointer;text-decoration:none}
.nav-item .ic{width:16px;text-align:center;opacity:.8;font-size:13px}
.nav-item:hover{background:var(--navy2);color:#e7ecf3}
.nav-item.active{background:var(--navy2);color:#fff}
.nav-item.active .ic{color:var(--gold)}
.badge{margin-left:auto;background:rgba(200,164,77,.16);color:var(--gold);font-size:11px;font-weight:600;padding:1px 7px;border-radius:20px;min-width:20px;text-align:center}
.nav-sep{font-size:10.5px;letter-spacing:.12em;color:var(--side-dim);padding:16px 14px 6px;font-weight:600}
.sidebar-foot{padding:16px 18px;border-top:1px solid rgba(255,255,255,.06)}
.drive-chip{display:flex;align-items:center;gap:8px;font-size:12.5px;color:#c2ccd9}
.drive-chip .dot{width:7px;height:7px;border-radius:50%;background:var(--gold)}
.foot-note{font-size:11px;color:var(--side-dim);margin-top:6px}

/* Main */
.main{flex:1;min-width:0;display:flex;flex-direction:column}
.topbar{display:grid;grid-template-columns:repeat(5,1fr);gap:1px;background:var(--line);border-bottom:1px solid var(--line)}
.stat{background:var(--panel);padding:16px 20px}
.stat-n{font-family:Fraunces,serif;font-size:30px;font-weight:500;line-height:1;color:var(--heading)}
.stat-l{font-size:11.5px;color:var(--muted);margin-top:6px;text-transform:uppercase;letter-spacing:.05em}
.stat-l em{font-style:normal;color:var(--gold-d);font-size:9.5px;background:rgba(200,164,77,.12);padding:1px 5px;border-radius:4px;margin-left:4px;letter-spacing:.03em}

.view{padding:30px 36px;max-width:1180px;width:100%}
/* The property database is the one view that wants the whole window: he has 60+
   columns available and every pixel of width is one less sideways scroll. */
#view-database{max-width:none}
.view-head{display:flex;justify-content:space-between;align-items:flex-start;gap:24px;margin-bottom:24px}
.view-head h1{font-size:32px;margin:0 0 8px}
.lede{color:var(--muted);font-size:14.5px;line-height:1.55;max-width:640px;margin:0}
.btn-primary{background:var(--navy);color:#fff;border:0;padding:11px 18px;border-radius:9px;font-weight:600;font-size:13.5px;cursor:pointer;white-space:nowrap;font-family:inherit}
.btn-primary:hover{background:var(--navy2)}
.btn-ghost{background:var(--panel);border:1px solid var(--line);color:var(--ink);padding:9px 14px;border-radius:8px;font-weight:500;font-size:13px;cursor:pointer;font-family:inherit}
.btn-ghost:hover{border-color:var(--gold);color:var(--gold-d)}

/* Dashboard grid */
.dash-grid{display:grid;grid-template-columns:1fr 320px;gap:20px}
.panel{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:18px;box-shadow:var(--shadow)}
.panel-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:14px}
.panel-head h3{margin:0;font-size:14px;font-weight:600}
.queue-preview{display:flex;flex-direction:column;gap:10px}
.qp-card{display:flex;gap:12px;padding:10px;border:1px solid var(--line);border-radius:10px;align-items:center;cursor:pointer;transition:.12s}
.qp-card:hover{border-color:var(--gold);transform:translateX(2px)}
.qp-thumb{width:74px;height:56px;border-radius:7px;object-fit:cover;background:var(--skel);flex-shrink:0}
.qp-body{min-width:0;flex:1}
.qp-addr{font-weight:600;font-size:13.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.qp-meta{font-size:12px;color:var(--muted);margin-top:2px}
.qp-price{font-family:Fraunces,serif;font-size:15px;color:var(--heading);font-weight:500}
.qp-tag{font-size:10px;background:var(--chip);color:var(--chip-ink);padding:2px 7px;border-radius:20px;text-transform:capitalize}

/* Sources */
.sources .src-list{display:flex;flex-direction:column;gap:9px;margin-bottom:14px}
.src-row{display:flex;align-items:center;gap:10px;padding:8px 0;border-bottom:1px solid var(--line)}
.src-row:last-child{border-bottom:0}
.src-name{font-size:13px;font-weight:500}
.src-sub{font-size:11px;color:var(--muted)}
.src-count{margin-left:auto;font-size:12px;color:var(--green);font-weight:600}
.src-count.off{color:var(--muted)}
.sources .btn-ghost{width:100%;margin-bottom:10px}
.src-note{font-size:11.5px;color:var(--muted);line-height:1.5}

/* Review swipe */
.review-wrap{max-width:900px;margin:0 auto}
.swipe-card{background:var(--panel);border:1px solid var(--line);border-radius:18px;overflow:hidden;box-shadow:var(--shadow)}
.swipe-top{display:flex;justify-content:space-between;align-items:center;padding:14px 20px;border-bottom:1px solid var(--line)}
.swipe-count{font-size:13px;color:var(--muted)}
.swipe-src{font-size:11px;background:rgba(47,158,109,.1);color:var(--green);padding:3px 10px;border-radius:20px;font-weight:600}
.swipe-body{display:grid;grid-template-columns:1.15fr 1fr;gap:0}
.swipe-photo{position:relative;background:#20293a;min-height:420px}
.swipe-photo img{width:100%;height:100%;object-fit:cover;position:absolute;inset:0}
.swipe-photo .photo-tag{position:absolute;left:14px;bottom:14px;background:rgba(15,27,45,.8);color:#fff;font-size:11px;padding:4px 10px;border-radius:6px;z-index:2}
.swipe-strip{position:absolute;left:14px;right:14px;bottom:44px;display:flex;gap:6px;z-index:2}
.swipe-strip img{position:relative;width:52px;height:40px;border-radius:5px;border:2px solid rgba(255,255,255,.7);object-fit:cover}
.swipe-info{padding:26px 28px;display:flex;flex-direction:column}
.si-area{font-size:11px;letter-spacing:.08em;color:var(--gold-d);text-transform:uppercase;font-weight:600}
.si-addr{font-family:Fraunces,serif;font-size:27px;font-weight:500;margin:6px 0 2px;color:var(--heading)}
.si-price{font-family:Fraunces,serif;font-size:22px;color:var(--ink)}
.si-specs{display:flex;gap:18px;margin:16px 0;padding:14px 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.si-spec b{font-family:Fraunces,serif;font-size:19px;font-weight:500;display:block;color:var(--heading)}
.si-spec span{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.04em}
.si-desc{font-size:13px;color:var(--body);line-height:1.55;flex:1;overflow:hidden;display:-webkit-box;-webkit-line-clamp:4;-webkit-box-orient:vertical}
.si-tags{display:flex;flex-wrap:wrap;gap:6px;margin:14px 0}
.si-tags .t{font-size:11px;background:var(--chip);color:var(--chip-ink);padding:4px 10px;border-radius:20px}
.swipe-actions{display:flex;gap:12px;margin-top:18px}
.act{flex:1;padding:14px;border-radius:11px;font-weight:600;font-size:15px;cursor:pointer;border:1px solid var(--line);background:var(--panel);display:flex;align-items:center;justify-content:center;gap:8px;font-family:inherit}
.act.pass:hover{border-color:var(--red);color:var(--red)}
.act.like{background:var(--gold);border-color:var(--gold);color:#231a00}
.act.like:hover{background:var(--gold-d)}
.review-empty{text-align:center;padding:80px 20px;color:var(--muted)}
.review-empty .serif{font-size:24px;color:var(--ink);display:block;margin-bottom:8px}

/* Tables */
/* overflow-x:auto is what lets him scroll sideways to the columns he added. It only
   works if the cells stop shrinking to fit — hence white-space:nowrap on .tbl td
   below. Without that the browser compresses 20 columns into the panel width and
   there is never anything to scroll, which is exactly what he was seeing. */
.table-wrap{background:var(--panel);border:1px solid var(--line);border-radius:14px;box-shadow:var(--shadow);overflow-x:auto;overflow-y:hidden}
.tbl{width:100%;border-collapse:collapse;font-size:13px;min-width:760px}
.tbl th{text-align:left;padding:12px 14px;font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);border-bottom:1px solid var(--line);font-weight:600;background:var(--panel2);white-space:nowrap}

/* ---- the property database, scrolled comfortably -------------------------------
   He said: scroll down, move sideways, then scroll back up to see which column you
   are in — "불편하다". Two fixes, both here:
     · the header row sticks to the top of the window, so it is always readable
       however far down the list he is;
     · the thumbnail and the property name freeze to the left, so a row is still
       identifiable however far right he scrolls.
   The wrapper scrolls the page rather than an inner box (overflow-y:visible), which
   is what lets position:sticky work against the window instead of a clipped div. */
#db-table-wrap{overflow-y:visible;border-radius:14px}
/* The table still scrolls sideways, but its own scrollbar is hidden: it sits at the
   foot of every row where he cannot reach it, and drawn under the pinned one below it
   just looked like two bars stacked on top of each other. */
/* While a property is being fetched, so a click has a visible effect straight away. */
#db-table-wrap .tbl tr.row-loading{opacity:.55}
#db-table-wrap{scrollbar-width:none;-ms-overflow-style:none}
#db-table-wrap::-webkit-scrollbar{height:0;width:0;display:none}
/* A sideways scrollbar he can actually reach. The table's own one is at the foot of
   all its rows, thousands of pixels below the fold, so there was nothing on screen to
   drag: "i dont see a scale on the bottom to swipe to the right". This is pinned to
   the bottom of the window and scrolls the table from wherever he happens to be.
   It is shown only when the table really is wider than the panel. */
.hscroll{position:sticky;bottom:0;z-index:5;overflow-x:auto;overflow-y:hidden;height:16px;
  background:var(--panel);border-top:1px solid var(--line);border-radius:0 0 14px 14px}
.hscroll>div{height:1px}
/* Always drawn, never the thin overlay bar that fades out. He has to see the handle. */
.hscroll::-webkit-scrollbar{height:12px}
.hscroll::-webkit-scrollbar-track{background:var(--panel2);border-radius:6px}
.hscroll::-webkit-scrollbar-thumb{background:#b9c2d0;border-radius:6px;border:2px solid var(--panel2)}
.hscroll::-webkit-scrollbar-thumb:hover{background:#96a2b4}
.hscroll{scrollbar-width:auto;scrollbar-color:#b9c2d0 var(--panel2)}
#db-table-wrap .tbl thead th{position:sticky;top:0;z-index:3}
/* col 1 = photo, col 2 = property name. Both pinned; the name carries the shadow
   that shows the rest of the table has slid underneath it. */
#db-table-wrap .tbl th:nth-child(1),
#db-table-wrap .tbl td:nth-child(1){position:sticky;left:0;z-index:2;background:var(--panel)}
#db-table-wrap .tbl th:nth-child(2),
#db-table-wrap .tbl td:nth-child(2){position:sticky;left:76px;z-index:2;background:var(--panel);
  box-shadow:6px 0 8px -6px rgba(15,27,45,.18)}
#db-table-wrap .tbl thead th:nth-child(1),
#db-table-wrap .tbl thead th:nth-child(2){z-index:4;background:var(--panel2)}
/* Hover must repaint the frozen cells too, or they stay pale while the row lights up. */
#db-table-wrap .tbl tbody tr:hover td:nth-child(1),
#db-table-wrap .tbl tbody tr:hover td:nth-child(2){background:var(--panel2)}
.tbl td{padding:11px 14px;border-bottom:1px solid var(--line);vertical-align:middle;white-space:nowrap;max-width:320px;overflow:hidden;text-overflow:ellipsis}
.tbl tr:last-child td{border-bottom:0}
.tbl tr{cursor:pointer}
.tbl tbody tr:hover{background:var(--panel2)}
.tbl .t-thumb{width:52px;height:40px;border-radius:6px;object-fit:cover;background:var(--skel)}
.t-price{font-family:Fraunces,serif;font-weight:500;color:var(--heading)}
.t-tags{display:flex;gap:4px;flex-wrap:wrap}
.t-tags .t{font-size:10px;background:var(--chip);color:var(--chip-ink);padding:1px 7px;border-radius:20px}
/* Where a listing came from, readable at a glance in the table: the MLS badge, the
   platform that found it, and the brokerage that listed it. */
.src-tag{font-size:10px;font-weight:600;padding:2px 7px;border-radius:5px;letter-spacing:.02em}
.src-tag.mls{background:rgba(47,158,109,.13);color:var(--green)}
.src-tag.broker{background:var(--chip);color:var(--chip-ink)}
.src-plat{font-size:12px;color:var(--body)}
:root[data-theme="dark"] .src-tag.mls{background:rgba(70,185,138,.16)}
.pill{font-size:11px;font-weight:600;padding:3px 10px;border-radius:20px}
.pill.ready{background:rgba(47,158,109,.12);color:var(--green)}
.pill.processing{background:rgba(200,164,77,.14);color:var(--gold-d)}
.pill.live{background:rgba(15,27,45,.08);color:var(--heading)}
.drive-link{color:var(--gold-d);font-size:12px;text-decoration:none;font-weight:500}
.drive-link:hover{text-decoration:underline}
.drive-link.na{color:var(--muted);font-weight:400}

/* Which search a property came from — for sale / sold / for rent, told apart by
   colour so a rental never reads as a sale. */
.pill.spec-for-sale{background:rgba(47,158,109,.12);color:var(--green)}
.pill.spec-sold{background:rgba(15,27,45,.09);color:var(--heading)}
.pill.spec-for-rent{background:rgba(74,124,214,.14);color:#2f5fb0}

/* Links carried over from his sheet (Airbnb, Drive, the property's own site). */
.ext-link{color:var(--gold-d);font-size:12px;text-decoration:none;font-weight:500}
.ext-link:hover{text-decoration:underline}

/* Sideways scrolling is only useful if he can still tell which row he is on, so the
   thumbnail and the first data column stay pinned to the left. */
.tbl th:nth-child(1),.tbl td:nth-child(1){position:sticky;left:0;z-index:2;background:var(--panel)}
.tbl th:nth-child(2),.tbl td:nth-child(2){position:sticky;left:66px;z-index:2;background:var(--panel)}
.tbl th:nth-child(1),.tbl th:nth-child(2){z-index:3;background:var(--panel2)}
.tbl tbody tr:hover td:nth-child(1),.tbl tbody tr:hover td:nth-child(2){background:var(--panel2)}

/* Detail overlay */
.detail-overlay{position:fixed;inset:0;background:rgba(15,27,45,.5);display:flex;justify-content:center;align-items:flex-start;padding:40px 20px;z-index:50;overflow-y:auto}
.detail-card{background:var(--panel);border-radius:18px;max-width:1140px;width:100%;overflow:hidden;box-shadow:0 20px 60px rgba(0,0,0,.3)}

/* Image left, headline facts right. Below 820px it stacks back to vertical, since
   side-by-side stops being readable on a narrow screen. */
/* ---- the gallery, laid out like essentialyfe.com --------------------------------
   One large photo with a strip of smaller ones beside it, and a "View all" button.
   The last thumbnail carries a "+N" badge so the count is visible without opening. */
.dt-gal{display:grid;grid-template-columns:1fr 232px;gap:8px;padding:8px 8px 0;position:relative;background:var(--panel)}
.dt-gal-main,.dt-gal-thumb{padding:0;border:0;cursor:pointer;background:#20293a;overflow:hidden;position:relative;display:block}
.dt-gal-main{height:380px;border-radius:12px}
.dt-gal-main img,.dt-gal-thumb img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .25s}
.dt-gal-main:hover img,.dt-gal-thumb:hover img{transform:scale(1.03)}
.dt-gal-side{display:grid;grid-template-rows:repeat(2,1fr);grid-template-columns:repeat(2,1fr);gap:8px;height:380px}
.dt-gal-thumb{border-radius:10px}
.dt-gal-more{position:absolute;inset:0;background:rgba(15,27,45,.55);color:#fff;display:flex;
  align-items:center;justify-content:center;font-size:22px;font-weight:600;font-family:Fraunces,serif}
/* Sits over the big photo, bottom-left, so it never covers a thumbnail. */
.dt-gal-all{position:absolute;left:24px;bottom:20px;background:var(--panel);color:var(--heading);
  border:1px solid var(--line);border-radius:9px;padding:8px 14px;font-size:12.5px;font-weight:600;
  cursor:pointer;box-shadow:0 2px 10px rgba(15,27,45,.18);z-index:2}
.dt-gal-all:hover{background:var(--panel2)}
.dt-gal .dt-status{position:absolute;top:14px;left:14px;background:rgba(47,158,109,.92);color:#fff;
  font-size:11px;font-weight:600;padding:4px 12px;border-radius:20px}
/* Says the photo is the raw listing image — the MLS corner logo is still on it, and
   will be until he likes the property and the cleaning pipeline runs. Sits top-left,
   away from the bottom-right corner where that logo actually is. */
.dt-gal .dt-gal-raw{position:absolute;top:14px;left:14px;background:rgba(15,27,45,.72);color:#fff;
  font-size:11px;font-weight:500;padding:4px 12px;border-radius:20px;backdrop-filter:blur(4px)}
/* Stronger than the "not cleaned yet" note: these images are not the property at all. */
.dt-gal .dt-gal-raw.stand-in{background:rgba(176,58,46,.88);font-weight:600}
/* His own photographs, out of his own folder — a fact worth stating, not a warning. */
.dt-gal .dt-gal-raw.own{background:rgba(47,158,109,.9);font-weight:600}
/* Nothing to approve on a property that is already his, so the bar carries the link
   to his folder where Like and Pass would otherwise be. */
.dt-decide.own{display:flex;align-items:center;justify-content:space-between;gap:16px}
.dt-decide.own .act.own-folder{background:var(--panel);border:1px solid var(--line);
  color:var(--gold-d);text-decoration:none;font-weight:600;white-space:nowrap}
.dt-decide.own .act.own-folder:hover{background:var(--gold);color:#231a00;border-color:var(--gold)}
/* Destructive action — visually distinct from every other button in Settings so it
   cannot be clicked by momentum while working down the page. */
.btn-ghost.danger{color:#b03a2e;border-color:#e3b5ae}
.btn-ghost.danger:hover{background:#b03a2e;color:#fff;border-color:#b03a2e}
:root[data-theme="dark"] .btn-ghost.danger{color:#e08b7f;border-color:rgba(224,139,127,.4)}
/* Photo backfill sits under the import, separated because it is a second step he
   takes after the spreadsheet is in, not part of the upload itself. */
.imp-errors{margin-top:12px;background:rgba(176,58,46,.06);border:1px solid rgba(176,58,46,.25);
  border-radius:10px;padding:12px 14px;max-height:220px;overflow-y:auto}
.imp-errors .imp-err-t{font-size:12.5px;font-weight:600;color:#b03a2e;margin-bottom:6px}
.imp-errors .imp-err-row{font-size:12px;color:var(--body);line-height:1.6;word-break:break-word}
.imp-photos{margin-top:18px;padding-top:16px;border-top:1px solid var(--line)}
.imp-photos-t{font-size:13px;font-weight:600;color:var(--heading)}
/* Photos arrive over a minute or two on a big file, so the bar gives the wait a
   visible end rather than leaving him wondering whether anything is happening. */
.imp-photos-bar{height:6px;border-radius:3px;background:var(--line);overflow:hidden;margin:10px 0 8px}
.imp-photos-fill{height:100%;width:0;border-radius:3px;background:var(--gold);transition:width .4s ease}
/* The causes behind the failures, one line each. */
.imp-why{margin-top:10px;border:1px solid var(--line);border-radius:8px;padding:10px 12px;background:var(--panel2)}
.imp-why-t{font-size:12px;font-weight:600;color:var(--heading);margin-bottom:6px}
.imp-why-row{display:flex;gap:10px;align-items:baseline;padding:5px 0;font-size:12px;line-height:1.45}
.imp-why-row+.imp-why-row{border-top:1px solid var(--line)}
.imp-why-n{min-width:52px;text-align:right;font-weight:600;color:var(--heading)}
.warn{color:#b03a2e;font-weight:600}
:root[data-theme="dark"] .warn{color:#e08b7f}
.dt-gal .dt-status ~ .dt-gal-raw{top:46px}
@media(max-width:760px){
  .dt-gal{grid-template-columns:1fr}
  .dt-gal-main{height:240px}
  .dt-gal-side{grid-template-rows:1fr;height:88px}
}

/* ---- full-screen photo viewer ---- */
.lightbox{position:fixed;inset:0;background:rgba(8,13,22,.94);z-index:80;display:flex;
  align-items:center;justify-content:center}
.lb-img{max-width:82vw;max-height:74vh;object-fit:contain;border-radius:8px;box-shadow:0 20px 60px rgba(0,0,0,.5)}
.lb-close{position:absolute;top:18px;right:22px;width:40px;height:40px;border-radius:50%;border:0;
  background:rgba(255,255,255,.14);color:#fff;font-size:22px;cursor:pointer}
.lb-close:hover{background:rgba(255,255,255,.24)}
.lb-nav{position:absolute;top:50%;transform:translateY(-50%);width:48px;height:48px;border-radius:50%;
  border:0;background:rgba(255,255,255,.14);color:#fff;font-size:30px;line-height:1;cursor:pointer}
.lb-nav:hover{background:rgba(255,255,255,.26)}
.lb-nav.prev{left:24px}
.lb-nav.next{right:24px}
.lb-count{position:absolute;top:24px;left:50%;transform:translateX(-50%);color:#fff;font-size:12.5px;
  background:rgba(0,0,0,.4);padding:5px 14px;border-radius:20px}
.lb-strip{position:absolute;bottom:18px;left:50%;transform:translateX(-50%);display:flex;gap:7px;
  max-width:86vw;overflow-x:auto;padding:6px}
.lb-strip img{width:74px;height:54px;object-fit:cover;border-radius:6px;cursor:pointer;opacity:.5;
  border:2px solid transparent;flex:0 0 auto}
.lb-strip img.on{opacity:1;border-color:var(--gold)}

.dt-top{display:grid;grid-template-columns:380px 1fr;gap:0;background:var(--panel2);border-bottom:1px solid var(--line)}
/* The hero is superseded by .dt-gal above; kept for the review-queue card. */
.dt-top:has(.dt-hero.hidden){grid-template-columns:1fr}
.dt-hero.hidden{display:none}
.dt-hero{position:relative;min-height:280px;background:#20293a}
.dt-hero img{width:100%;height:100%;object-fit:cover;display:block;position:absolute;inset:0}
.dt-status{position:absolute;top:14px;left:14px;background:rgba(47,158,109,.92);color:#fff;font-size:10px;font-weight:600;padding:4px 10px;border-radius:20px;letter-spacing:.04em}
.dt-headline{position:relative;padding:26px 28px 22px}
/* The close button lives in the gallery now (the gallery is the top of the card), so
   it pins to the card's top-right corner over the photo. */
.dt-close{position:absolute;top:18px;right:18px;width:36px;height:36px;border-radius:50%;
  background:rgba(255,255,255,.92);color:var(--heading);border:0;cursor:pointer;font-size:19px;line-height:1;
  z-index:5;box-shadow:0 2px 10px rgba(15,27,45,.25)}
.dt-close:hover{background:#fff}
.dt-headline h2{font-family:Fraunces,serif;font-weight:500;font-size:26px;margin:0 34px 2px 0;color:var(--heading);line-height:1.2}
.dt-headline .sub{font-size:13px;color:var(--muted)}
.dt-quick{display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin:14px 0 18px}
.dt-quick .t{font-size:11px;background:var(--chip);color:var(--chip-ink);padding:3px 10px;border-radius:20px;font-weight:600}
/* ---- the headline, two columns ------------------------------------------------
   The address and its four facts never came close to filling the card, and the space
   to their right was empty on every property. The month a home is free is the thing
   worth seeing first, so the calendar sits there. It keeps its own column rather than
   floating, so the facts do not reflow as the month changes width. */
.dt-headline{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:14px 30px;align-items:start}
.dt-headline-main{min-width:0}
/* The description reads better against the calendar than as a full-card-width slab. */
.dt-headline-desc{margin-top:18px;max-width:560px}
.dt-headline-desc .dt-section-t{margin:0 0 6px}
.dt-headline-cal{min-width:0}
/* Inside a 300px column the month has to give up the wide-screen margins. */
.dt-headline-cal .cal-head{margin:0 0 8px}
.dt-headline-cal .cal-grid{max-width:none}
.dt-headline-cal .cal-key{margin-left:0;flex-basis:100%;order:3}
.dt-headline-cal .cal-cell{font-size:10.5px;border-radius:4px}
/* Holds the height while the month loads, so the facts beside it do not jump. */
.cal-skel{height:232px;border-radius:10px;background:var(--panel);border:1px solid var(--line)}
.dt-headline-facts{display:grid;grid-template-columns:repeat(4,auto);gap:22px;justify-content:start}
.dt-headline-facts div{display:flex;flex-direction:column}
.dt-headline-facts b{font-family:Fraunces,serif;font-weight:500;font-size:19px;color:var(--heading);line-height:1.2}
.dt-headline-facts span{font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin-top:2px}
@media (max-width:900px){
  .dt-top{grid-template-columns:1fr}
  .dt-hero{height:220px}
  /* Not enough width for a column beside the facts: the month drops underneath them,
     still above everything else on the card. */
  .dt-headline{grid-template-columns:1fr}
  .dt-headline-cal{margin-top:4px}
  .cal-skel{height:210px}
}
@media (max-width:820px){
  .dt-headline-facts{grid-template-columns:repeat(2,auto);gap:14px 22px}
}
.dt-body{padding:24px 28px}
.dt-cols{display:grid;grid-template-columns:1fr 1fr;gap:24px 40px}
.dt-field{display:flex;justify-content:space-between;gap:12px;padding:8px 0;border-bottom:1px solid var(--line);font-size:13px}
.dt-field .k{color:var(--muted)}
.dt-field .v{font-weight:500;text-align:right}
.dt-section-t{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--gold-d);font-weight:600;margin:22px 0 10px}
.palette{display:flex;gap:6px}
.palette span{width:34px;height:34px;border-radius:7px;border:1px solid var(--line)}
.dt-desc{font-size:13.5px;line-height:1.6;color:var(--body);margin:8px 0 0}
/* The per-room photo grid is gone — the gallery at the top of the card shows every
   photo, and the room name rides each one in the viewer. What is left is the summary
   of which rooms the set covers, which is what the tagged filenames in Drive reflect. */
/* One line, not a panel. The 46 filenames and the folder path that used to be printed
   here are already in Drive itself — the link goes there, and the path rides its
   tooltip. What stays visible is the coverage: how many photos, and which rooms. */
.drive-row{display:flex;align-items:center;gap:12px;background:#faf8f2;border:1px solid #eadfc4;
  border-radius:10px;padding:11px 14px;margin-top:20px}
.drive-row .dr-ic{font-size:15px;line-height:1}
.drive-row .dr-text{min-width:0;flex:1}
.drive-row .dr-text b{display:block;font-size:13px;color:var(--gold-d);font-weight:600}
.drive-row .dr-sub{display:block;font-size:12px;color:#7a6a3f;line-height:1.5;margin-top:2px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.drive-row .dr-open{flex:0 0 auto;font-size:12.5px;font-weight:600;color:var(--gold-d);text-decoration:none;
  border:1px solid #eadfc4;background:#fff;border-radius:7px;padding:6px 11px}
.drive-row .dr-open:hover{background:var(--gold);color:#231a00;border-color:var(--gold)}
.drive-row .dr-pending{flex:0 0 auto;font-size:11.5px;color:var(--muted)}
.owner-box{background:#f7f8fa;border:1px dashed var(--line);border-radius:10px;padding:12px 14px;margin-top:14px;font-size:12.5px;color:var(--muted);display:flex;align-items:center;gap:8px}
.owner-box b{color:var(--ink)}
.mini-note{font-size:11px;color:var(--muted);margin-top:6px}

@media(max-width:920px){
  .dash-grid{grid-template-columns:1fr}
  .swipe-body{grid-template-columns:1fr}
  .dt-cols{grid-template-columns:1fr}
}

/* ---------- auth (login / first-run) overlay ---------- */
#auth-overlay{position:fixed;inset:0;z-index:1000;background:var(--navy);display:grid;place-items:center;padding:24px}
.auth-card{background:var(--panel);border-radius:14px;box-shadow:var(--shadow);width:100%;max-width:360px;padding:34px 30px;display:flex;flex-direction:column;gap:13px}
.auth-brand{font-family:Fraunces,Georgia,serif;font-weight:600;font-size:22px;color:var(--heading);letter-spacing:-.01em}
.auth-title{color:var(--muted);font-size:14px;margin-bottom:6px}
/* The form carries the card's own column layout, so wrapping the inputs in a real
   <form> (which is what a password manager looks for) does not collapse the spacing. */
#auth-form{display:flex;flex-direction:column;gap:13px}
.auth-input{border:1px solid var(--line);border-radius:9px;padding:11px 13px;font-size:14px;font-family:inherit;color:var(--ink);outline:none;transition:border-color .15s}
.auth-input:focus{border-color:var(--gold)}
.auth-btn{margin-top:4px;background:linear-gradient(135deg,var(--gold),var(--gold-d));color:#1a1300;border:none;border-radius:9px;padding:12px;font-size:14px;font-weight:600;font-family:inherit;cursor:pointer;transition:opacity .15s}
.auth-btn:hover{opacity:.92}
.auth-btn:disabled{opacity:.5;cursor:default}
.auth-err{color:var(--red);font-size:13px;min-height:0}
.auth-err:empty{display:none}

/* ---------- account block in sidebar ---------- */
.acct{padding:10px 12px;margin-bottom:8px;background:var(--navy2);border-radius:9px}
.acct-name{color:#e7ecf3;font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.acct-role{color:var(--gold);font-size:11px;font-weight:600;margin-top:1px}
.acct-actions{display:flex;gap:12px;margin-top:8px}
.acct-link{color:#9fb0c4;font-size:12px;cursor:pointer;text-decoration:none}
.acct-link:hover{color:#fff}
/* password dialog reuses the auth overlay look */
#pw-overlay{position:fixed;inset:0;z-index:1001;background:rgba(15,27,45,.55);display:grid;place-items:center;padding:24px}
.auth-link{color:var(--muted);font-size:13px;text-align:center;cursor:pointer;text-decoration:none}
.auth-link:hover{color:var(--ink)}
/* explanatory line inside the auth card (forgot / reset flows) */
.auth-note{color:var(--muted);font-size:13px;line-height:1.5}

/* ---- "Edit fields" button in the property table ---- */
.row-edit{font:inherit;font-size:12px;font-weight:500;padding:5px 11px;border-radius:7px;
  border:1px solid var(--line);background:var(--panel);color:var(--ink);cursor:pointer;white-space:nowrap}
.row-edit:hover{border-color:var(--gold);color:var(--gold-d)}

/* ---- Pass / Like inside the property detail ---- */
.dt-decide{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;
  padding:12px 14px;margin-bottom:18px;border:1px solid var(--line);border-radius:11px;background:var(--panel2)}
.dt-decide-now{font-size:13px;color:var(--muted)}
.dt-decide-acts{display:flex;gap:10px}
.dt-decide .act{flex:0 0 auto;padding:9px 20px;font-size:13.5px}
/* the decision he's already on */
.dt-decide .act.chosen{opacity:.55}
.dt-decide .act:disabled{opacity:.5;cursor:default}

/* ---- column picker ---- */
.col-picker{border:1px solid var(--line);border-radius:12px;background:var(--panel);
  box-shadow:var(--shadow);padding:14px 16px;margin-bottom:14px}
.col-picker-head{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding-bottom:10px;margin-bottom:12px;border-bottom:1px solid var(--line)}
.col-picker-head > div{display:flex;gap:8px}
.col-picker-body{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:16px 22px;
  max-height:340px;overflow-y:auto}
.col-group-t{font-size:11px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--muted);margin-bottom:7px}
.col-opt{display:flex;align-items:center;gap:7px;font-size:13px;color:var(--ink);
  padding:3px 0;cursor:pointer}
.col-opt input{width:14px;height:14px;accent-color:var(--gold-d);cursor:pointer}
.col-tag{font-style:normal;font-size:9.5px;letter-spacing:.04em;text-transform:uppercase;
  color:var(--gold-d);background:rgba(200,164,77,.14);padding:1px 5px;border-radius:4px}

/* ---- creating a field of his own ---- */
.col-new{border-top:1px solid var(--line);margin-top:14px;padding-top:14px}
.col-new-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.col-del{border:0;background:none;color:var(--muted);cursor:pointer;font-size:15px;
  line-height:1;padding:0 2px;margin-left:auto}
.col-del:hover{color:var(--red)}
/* Switching a built-in field off. Same affordance as deleting a custom one, but it is
   reversible, so it fades in on hover rather than sitting there inviting a click. */
.col-hide{border:0;background:none;color:transparent;cursor:pointer;font-size:15px;
  line-height:1;padding:0 2px;margin-left:auto}
.col-opt:hover .col-hide{color:var(--muted)}
.col-hide:hover{color:var(--red)}
.col-hidden{border-top:1px solid var(--line);margin-top:14px;padding-top:12px}
.col-unhide{display:inline-flex;align-items:center;gap:6px;background:var(--panel2);
  border:1px solid var(--line);border-radius:20px;padding:4px 11px;margin:4px 6px 0 0;
  font-size:12px;color:var(--body);cursor:pointer}
.col-unhide span{color:var(--gold-d);font-weight:600}
.col-unhide:hover{border-color:var(--gold);background:var(--panel)}

/* ---- table filters + sortable headers ---- */
.tbl-controls{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:14px}
.tbl th.sortable{cursor:pointer;user-select:none;white-space:nowrap}
.tbl th.sortable:hover{color:var(--ink)}
.tbl th.sortable::after{content:'';margin-left:5px;opacity:.35;font-size:9px}
.tbl th.sortable.sorted{color:var(--gold-d)}
.tbl th.sortable.sorted[data-dir="asc"]::after{content:'▲';opacity:.9}
.tbl th.sortable.sorted[data-dir="desc"]::after{content:'▼';opacity:.9}

/* ---- dragging a column left or right ----
   The header is both a sort button and a drag handle, so the cursor has to say the
   second one is possible; the title attribute says both. */
.tbl th.sortable{cursor:grab}
.tbl th.sortable:active{cursor:grabbing}
.tbl th.col-dragging{opacity:.4}
/* Where it will land. Drawn inside the cell rather than as a floating line, so it
   cannot be thrown off by the table's sideways scroll or the frozen columns. */
.tbl th.col-drop-before{box-shadow:inset 3px 0 0 var(--gold)}
.tbl th.col-drop-after{box-shadow:inset -3px 0 0 var(--gold)}
/* A pinned header keeps its own shadow; make sure the drop mark wins over it. */
#db-table-wrap .tbl thead th.col-drop-before{box-shadow:inset 3px 0 0 var(--gold)}
#db-table-wrap .tbl thead th.col-drop-after{box-shadow:inset -3px 0 0 var(--gold)}

/* ---- table pagination ---- */
.pager{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-top:14px}
.pager-left,.pager-right{display:flex;align-items:center;gap:9px}
.pager-count{font-size:12.5px;color:var(--muted)}
.pager-page{font-size:12.5px;color:var(--ink);min-width:96px;text-align:center}
.pager .row-edit:disabled{opacity:.45;cursor:default;border-color:var(--line);color:var(--muted)}

/* ---- price changes ---- */
.price-filters{display:flex;align-items:center;gap:14px}
.delta{font-weight:600;font-size:13px;white-space:nowrap}
.delta.down{color:var(--green)}
.delta.up{color:var(--red)}

/* ---- daily email box (dashboard sidebar panel) ---- */
.digest-box{margin-top:16px;padding-top:14px;border-top:1px solid var(--line)}
.digest-sum{font-size:12px;color:var(--muted);line-height:1.5;margin-bottom:10px}
.digest-sum b{color:var(--ink)}
.digest-msg{font-size:12px;margin-top:8px;color:var(--muted)}
.digest-msg.ok{color:var(--green)}
.digest-msg.err{color:var(--red)}

/* ---- automation panel ---- */
.auto-row{display:flex;align-items:center;justify-content:space-between;gap:10px}
.auto-state{font-size:11px;font-weight:600;padding:2px 8px;border-radius:20px;text-transform:uppercase;letter-spacing:.04em}
.auto-state.on{background:rgba(47,158,109,.14);color:var(--green)}
.auto-state.off{background:rgba(122,134,152,.16);color:var(--muted)}
.auto-sub{font-size:11.5px;color:var(--muted);line-height:1.5;margin:5px 0 8px}
.auto-inline{display:flex;align-items:center;gap:8px;margin-bottom:4px}
.auto-inline .fld-input{font-size:12px;padding:5px 8px}

/* ---- theme toggle (sidebar foot) ---- */
.theme-toggle{display:flex;align-items:center;gap:8px;width:100%;margin-top:10px;padding:8px 10px;
  background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.10);border-radius:8px;
  color:#cdd6e4;font:inherit;font-size:12px;cursor:pointer;text-align:left}
.theme-toggle:hover{background:rgba(255,255,255,.11);color:#fff}
.theme-toggle span:first-child{font-size:13px;line-height:1}

/* ---- his editable fields, inside the property detail card ---- */
.fld-lock{font-size:10px;letter-spacing:.02em;text-transform:none;color:var(--gold-d);font-weight:500}

/* ---- availability ---------------------------------------------------------------
   Calendars are read in and merged: a home listed on Airbnb and Vrbo at once shows one
   answer per day. The four states are colour-coded because the whole point is telling
   them apart at a glance, and two of them (On Hold, Maintenance) exist only here. */
.cal-feeds{margin:4px 0 14px}
.cal-feed{display:flex;align-items:center;gap:10px;padding:7px 0;font-size:12px;border-bottom:1px solid var(--line)}
.cal-feed-name{font-weight:600;color:var(--heading);min-width:110px}
.cal-feed-sub{color:var(--muted);flex:1}
.cal-err{color:var(--red)}
.cal-add{display:flex;gap:8px;align-items:center;margin-top:10px;flex-wrap:wrap}
.cal-add #cal-url{flex:1;min-width:260px}

.cal-head{display:flex;align-items:center;gap:10px;margin:6px 0 8px;font-size:13px;flex-wrap:wrap}
.cal-key{margin-left:auto;display:flex;align-items:center;gap:8px;font-size:11px;color:var(--muted);flex-wrap:wrap}
.cal-key i{width:11px;height:11px;border-radius:3px;display:inline-block;margin-right:3px;vertical-align:-1px;border:1px solid var(--line)}
.k-free{background:var(--panel)}
.k-booked{background:#c0563f;border-color:#c0563f}
.k-blocked{background:#d8a08f;border-color:#d8a08f}
.k-hold{background:#c8a44d;border-color:#c8a44d}
.k-maint{background:#6b7a8f;border-color:#6b7a8f}

.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:3px;max-width:430px}
.cal-dow{font-size:10px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);text-align:center;padding:2px 0}
.cal-cell{aspect-ratio:1;display:flex;align-items:center;justify-content:center;border:1px solid var(--line);
  border-radius:5px;font-size:11px;color:var(--body);background:var(--panel)}
.cal-cell.empty{border:none;background:none}
/* White text on the filled states, or the date number disappears into the colour. */
.cal-cell.booked{background:#c0563f;border-color:#c0563f;color:#fff}
.cal-cell.blocked{background:#d8a08f;border-color:#d8a08f;color:#42200f}
.cal-cell.hold{background:#c8a44d;border-color:#c8a44d;color:#2b2100}
.cal-cell.maint{background:#6b7a8f;border-color:#6b7a8f;color:#fff}

.cal-manual{margin-top:14px;padding-top:12px;border-top:1px solid var(--line)}
.cal-manual-row{display:flex;gap:8px;align-items:center;margin-top:7px;flex-wrap:wrap}
/* .fld-input is full width by default, which made the two date boxes take a line each
   and pushed the rest of the row apart. */
.cal-manual-row input[type=date]{width:auto;min-width:140px;flex:0 0 auto}
.cal-manual-row #blk-note{flex:1;min-width:150px;width:auto}
.cal-block{display:flex;align-items:center;gap:10px;font-size:12px;padding:6px 0;border-bottom:1px solid var(--line)}
.pill.hold{background:#f6ecd2;color:#6b5310}
.pill.maint{background:#e4e8ee;color:#3d4756}
.fld-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:10px 14px}
/* Sections as tabs. Ten groups stacked vertically meant scrolling past sixty fields
   to reach one value; this keeps every section one click from the top. The row wraps
   rather than scrolling sideways, so no tab is ever hidden off the edge. */
.fld-tabs{display:flex;flex-wrap:wrap;gap:6px;margin:14px 0 12px;border-bottom:1px solid var(--line);padding-bottom:10px}
.fld-tab{background:transparent;border:1px solid var(--line);border-radius:999px;padding:6px 13px;
  font-size:12px;font-family:inherit;font-weight:500;color:var(--muted);cursor:pointer;
  white-space:nowrap;transition:background .15s,color .15s,border-color .15s}
.fld-tab:hover{color:var(--heading);border-color:var(--muted)}
.fld-tab.on{background:var(--navy);border-color:var(--navy);color:#fff;font-weight:600}
.fld-lock-s{font-size:10px}
.fld-pane-note{font-size:11px;color:var(--gold-d);margin-bottom:9px}
.fld{display:flex;flex-direction:column;gap:4px}
.fld-l{font-size:12px;color:var(--muted)}
.fld-input{font:inherit;font-size:13px;color:var(--ink);background:var(--panel);border:1px solid var(--line);border-radius:8px;padding:8px 10px;width:100%}
.fld-input:focus{outline:none;border-color:var(--gold);box-shadow:0 0 0 3px rgba(200,164,77,.15)}
textarea.fld-input{resize:vertical;min-height:38px}
/* A link field: the box stays editable, the arrow opens what is in it. */
.fld-url{display:flex;align-items:center;gap:6px}
.fld-open{flex:0 0 auto;color:var(--gold-d);text-decoration:none;font-size:14px;padding:0 2px}
.fld-open:hover{color:var(--ink)}
.fld-actions{display:flex;align-items:center;gap:12px;margin:18px 0 4px}
.fld-status{font-size:12px;color:var(--muted)}
.fld-status.ok{color:var(--green)}
.fld-status.err{color:var(--red)}
.fld-note{font-size:12px;color:var(--muted);background:var(--bg);border-radius:8px;padding:9px 11px;margin-top:12px}

/* ---- settings view ---- */
.set-block{padding:14px 0;border-bottom:1px solid var(--line)}
.set-block:last-of-type{border-bottom:0}
.settings-hint{margin-top:10px}

/* ---- import your database ---- */
.imp-drop{border:1.5px dashed var(--line);border-radius:12px;padding:26px 20px;text-align:center;cursor:pointer;transition:border-color .15s,background .15s;background:var(--bg)}
.imp-drop:hover,.imp-drop.over{border-color:var(--gold);background:var(--panel2)}
.imp-drop-in{display:flex;flex-direction:column;align-items:center;gap:6px;color:var(--body);font-size:13.5px}
.imp-ic{font-size:22px;color:var(--gold-d)}
.imp-panel{margin-top:16px;border:1px solid var(--line);border-radius:12px;padding:16px;background:var(--bg)}
.imp-stat{display:flex;gap:26px;flex-wrap:wrap;margin-bottom:14px}
.imp-stat div{display:flex;flex-direction:column}
.imp-stat b{font-family:Fraunces,serif;font-size:21px;color:var(--heading);font-weight:500}
.imp-stat span{font-size:10.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin-top:2px}
.imp-map{max-height:260px;overflow-y:auto;border:1px solid var(--line);border-radius:8px;background:var(--panel)}
.imp-map table{width:100%;border-collapse:collapse;font-size:12.5px}
.imp-map td{padding:6px 10px;border-bottom:1px solid var(--line)}
.imp-map tr:last-child td{border-bottom:0}
.imp-map .src{color:var(--muted)}
.imp-map .arr{color:var(--gold-d);width:22px;text-align:center}
.imp-map .dst{font-weight:500}
.imp-map .skip{color:var(--muted);font-style:italic}
.imp-acts{display:flex;align-items:center;gap:12px;margin-top:14px}

/* ---- team / permissions view ---- */
.team-tbl .role-sel{font:inherit;font-size:12px;padding:5px 8px;border:1px solid var(--line);border-radius:7px;background:var(--panel);color:var(--ink)}
.team-chk{display:inline-flex;align-items:center;gap:7px;font-size:13px;color:var(--ink);cursor:pointer}
.team-chk input{width:15px;height:15px;accent-color:var(--gold-d);cursor:pointer}
.team-you{font-size:11px;color:var(--muted);margin-left:6px}
.act-danger{color:var(--red);cursor:pointer;font-size:12px;text-decoration:none;background:none;border:0;font-family:inherit;padding:0}
.act-danger:hover{text-decoration:underline}
.act-danger:disabled{color:var(--muted);cursor:default;text-decoration:none}
.team-add{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;align-items:end;margin-top:6px}
.team-msg{font-size:12px;margin-top:10px}
.team-msg.ok{color:var(--green)}
.team-msg.err{color:var(--red)}
.team-link-box{font-size:12px;background:var(--bg);border-radius:8px;padding:10px 12px;margin-top:10px;word-break:break-all;color:var(--ink)}

/* =================================================================================
   PHONE AND TABLET
   =================================================================================
   The layout is a fixed 236px menu beside a five-across statistics row, which is
   about 900px of furniture before a single property is drawn. On a phone that put
   the menu on top of the page and pushed everything else off the right edge.

   Two things change and nothing else has to:
     · the menu becomes a drawer that slides in over the page, opened from a bar
       pinned to the top of the screen;
     · every row that was laid out side by side (statistics, page heading and its
       button, form fields, the property card) stacks.

   The tables keep scrolling sideways, which is right on a phone — sixty columns
   cannot be made to fit — but only one column stays frozen instead of two, because
   two of them left barely any of a 360px screen to scroll into.
   ================================================================================= */

/* Off on a desktop screen. Both elements exist in the markup at every width so the
   drawer can animate rather than appear. */
.mobile-bar{display:none}
.side-scrim{display:none}
.side-close{display:none}

@media (max-width:900px){
  /* ---- the top bar that opens the drawer ---- */
  .mobile-bar{display:flex;align-items:center;gap:12px;padding:9px 12px;
    background:var(--navy);color:#fff;position:sticky;top:0;z-index:40}
  .mob-menu{width:40px;height:40px;flex:0 0 auto;display:grid;place-items:center;
    background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.12);
    border-radius:9px;cursor:pointer;padding:0}
  .mob-menu:active{background:rgba(255,255,255,.18)}
  /* Three bars drawn from one element, so the same element can become the ✕ when the
     drawer is open without a second icon to keep in step. */
  .mob-bars,.mob-bars::before,.mob-bars::after{content:'';display:block;width:18px;height:2px;
    border-radius:2px;background:#e7ecf3;transition:transform .2s ease,top .2s ease,background .2s ease}
  .mob-bars{position:relative}
  .mob-bars::before{position:absolute;top:-6px}
  .mob-bars::after{position:absolute;top:6px}
  #app.nav-open .mob-bars{background:transparent}
  #app.nav-open .mob-bars::before{top:0;transform:rotate(45deg)}
  #app.nav-open .mob-bars::after{top:0;transform:rotate(-45deg)}
  .mob-brand{display:flex;align-items:center;gap:9px;min-width:0}
  .mob-brand .brand-mark{width:26px;height:26px;font-size:16px;flex:0 0 auto}
  .mob-brand .brand-name{font-size:15px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

  /* ---- the menu itself, as a drawer ----
     position:fixed takes it out of the flex row, so the page below is full width
     whether the drawer is open or shut. */
  .sidebar{position:fixed;top:0;left:0;bottom:0;height:100dvh;width:min(82vw,272px);
    z-index:70;transform:translateX(-100%);transition:transform .22s ease;
    overflow-y:auto;overscroll-behavior:contain;box-shadow:0 0 40px rgba(0,0,0,.45)}
  #app.nav-open .sidebar{transform:none}
  .side-scrim{display:block;position:fixed;inset:0;z-index:65;background:rgba(8,13,22,.55);
    opacity:0;pointer-events:none;transition:opacity .22s ease}
  #app.nav-open .side-scrim{opacity:1;pointer-events:auto}
  /* A finger needs a bigger target than a mouse does. */
  .nav-item{padding:12px 12px;font-size:14.5px}
  .side-close{display:grid;place-items:center;margin-left:auto;width:32px;height:32px;
    border-radius:8px;border:1px solid rgba(255,255,255,.14);background:transparent;
    color:#cdd6e4;font-size:15px;line-height:1;cursor:pointer;font-family:inherit}
  .side-close:hover{background:rgba(255,255,255,.10);color:#fff}
  /* The page must not scroll behind an open drawer. */
  body.nav-locked{overflow:hidden}

  /* ---- everything else ---- */
  /* Five tiles over three columns leaves an empty cell on the second row, which reads
     as a sixth statistic that failed to load. The last one widens to fill it. */
  .topbar{grid-template-columns:repeat(3,1fr)}
  .topbar .stat:last-child{grid-column:2/-1}
  .view{padding:22px 20px}
  .review-wrap{max-width:none}
}

/* Reduced motion: the drawer still opens and closes, it just does not slide. */
@media (prefers-reduced-motion:reduce){
  .sidebar,.side-scrim,.mob-bars,.mob-bars::before,.mob-bars::after{transition:none}
}

@media (max-width:700px){
  /* ---- statistics row ----
     Five tiles never fit. Number and label go on one line so all five are readable in
     three short rows instead of scrolling sideways to a count he cannot see. */
  .topbar{grid-template-columns:1fr 1fr}
  .stat{display:flex;align-items:baseline;gap:9px;padding:11px 14px}
  .stat-n{font-size:21px}
  .stat-l{margin-top:0;font-size:10px;line-height:1.35;letter-spacing:.04em}
  .stat-l em{font-size:9px;margin-left:3px}
  /* Same specificity as the three-column rule above, and later, so it wins here. */
  .topbar .stat:last-child{grid-column:1/-1}

  /* ---- page heading and its action ---- */
  .view{padding:18px 14px}
  .view-head{flex-direction:column;align-items:stretch;gap:14px;margin-bottom:18px}
  .view-head h1{font-size:24px}
  .lede{font-size:13.5px}
  .view-head>.btn-primary,.view-head>.btn-ghost{width:100%}
  .price-filters{flex-wrap:wrap}
  .panel{padding:14px;border-radius:12px}

  /* ---- tables ----
     Only the property name stays frozen. The thumbnail column scrolls away with the
     rest: on a 360px screen a pinned photo plus a pinned name left about 150px of
     visible table, and the sideways scroll had nowhere to go. */
  .tbl{min-width:620px;font-size:12.5px}
  .tbl th,.tbl td{padding:9px 10px}
  .tbl td{max-width:200px}
  .tbl .t-thumb{width:40px;height:32px}
  .tbl th:nth-child(1),.tbl td:nth-child(1),
  #db-table-wrap .tbl th:nth-child(1),#db-table-wrap .tbl td:nth-child(1){position:static}
  .tbl th:nth-child(2),.tbl td:nth-child(2),
  #db-table-wrap .tbl th:nth-child(2),#db-table-wrap .tbl td:nth-child(2){left:0}

  /* Filters: the search box takes its own line, the dropdowns pair up. */
  .tbl-controls{gap:8px}
  .tbl-controls #db-search{max-width:none;flex:1 1 100%}
  .tbl-controls select.fld-input{flex:1 1 calc(50% - 4px);min-width:0}
  .pager-left,.pager-right{flex-wrap:wrap}

  /* ---- the property card, full screen ----
     A card inset by 40px on a phone wastes a fifth of the screen on a dark border.
     The card must keep align-items:flex-start from the base rule. The overlay is the
     scroller and the card itself is overflow:hidden, so stretching the card to the
     height of the screen clips everything past the fold with no way to reach it —
     on a real property that is 2,300px of the page gone. min-height covers the other
     case, a short card that would otherwise float in a full-screen backdrop. */
  .detail-overlay{padding:0}
  .detail-card{border-radius:0;max-width:none;min-height:100dvh}
  .dt-headline{padding:18px 16px 16px}
  .dt-headline h2{font-size:21px;margin-right:44px}
  .dt-body{padding:18px 16px}
  .dt-close{top:12px;right:12px}
  .dt-field{font-size:12.5px}
  .fld-grid{grid-template-columns:1fr}
  .dt-decide,.dt-decide.own{flex-direction:column;align-items:stretch}
  .dt-decide-acts{display:flex}
  .dt-decide .act{flex:1 1 auto}
  .drive-row{flex-wrap:wrap}

  /* ---- review queue ---- */
  .swipe-top{padding:11px 14px}
  .swipe-photo{min-height:230px}
  .swipe-strip img{width:44px;height:34px}
  .swipe-info{padding:18px 16px}
  .si-addr{font-size:21px}
  .si-price{font-size:18px}
  .si-specs{gap:12px;flex-wrap:wrap}
  .swipe-actions{gap:9px}
  .act{padding:13px 10px;font-size:14px}
  .review-empty{padding:50px 16px}
  .qp-thumb{width:62px;height:48px}

  /* ---- photo viewer ---- */
  .lb-img{max-width:94vw;max-height:62vh}
  .lb-close{top:10px;right:12px;width:36px;height:36px;font-size:19px}
  .lb-nav{width:38px;height:38px;font-size:24px}
  .lb-nav.prev{left:8px}
  .lb-nav.next{right:8px}
  .lb-strip{bottom:10px;max-width:96vw}
  .lb-strip img{width:54px;height:40px}

  /* ---- forms ----
     iOS zooms the whole page in on any field under 16px and does not zoom back out,
     which left him scrolled sideways after every tap. Every field the app renders is
     named here, including the ones with their own smaller size. */
  .fld-input,.auth-input,.auto-inline .fld-input,.team-tbl .role-sel,
  .tbl-controls .fld-input,.cal-manual-row .fld-input{font-size:16px}
  .team-add{grid-template-columns:1fr}
  .auth-card{padding:26px 20px}
  .cal-add #cal-url{min-width:0}
  .cal-manual-row #blk-note{min-width:0}
  .cal-manual-row input[type=date]{min-width:0;flex:1 1 auto}
  .cal-grid{max-width:none}
  .col-picker-body{max-height:260px}
  .imp-stat{gap:14px}
  .fld-tabs{gap:5px}
  .fld-tab{padding:5px 11px;font-size:11.5px}
}

/* The narrowest phones still in use (iPhone SE, 320px). */
@media (max-width:380px){
  .topbar{grid-template-columns:1fr}
  .topbar .stat:last-child{grid-column:auto}
  .view{padding:16px 12px}
  .view-head h1{font-size:22px}
  .tbl-controls select.fld-input{flex:1 1 100%}
}
