/* ============================================================
   APP SURFACES — member self-edit (/me) and admin desk (/admin)
   Inherits every token from styles.css. Adds no new colour.
   Green stays structure, gold stays accent ink.
   ============================================================ */

/* [hidden] must beat any display we set ourselves. .btn is inline-block, so
   a plain [hidden] on a button does nothing — that shipped a visible
   "Sign out" on the signed-out page until a screenshot caught it. */
[hidden]{display:none!important}

.visually-hidden{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}

.app-main{padding-block:44px 72px;min-height:60vh}
.app-head{margin-bottom:26px}
.app-head h1{font-size:clamp(28px,3.6vw,38px);font-weight:800;line-height:1.14}
.app-head p{color:var(--text-2);font-size:17.5px;margin-top:10px;max-width:62ch}

/* ---------------- auth card ---------------- */
.auth{max-width:520px;margin:0 auto;background:var(--bg);border:1px solid var(--line);border-radius:14px;padding:30px}
.auth h1,.auth h2{font-size:23px;font-weight:800;margin-bottom:8px;letter-spacing:-.015em}
.auth p{color:var(--text-2);font-size:16.5px}
.auth .field{margin-top:20px}
.auth .btn{width:100%;margin-top:16px}
.auth-note{margin-top:18px;font-size:15.5px;color:var(--text-2);border-top:1px solid var(--line-soft);padding-top:16px}

/* ---------------- fields ---------------- */
.field{display:block;margin-bottom:18px}
.field > label,.lbl{display:block;font-size:15px;font-weight:800;color:var(--text);margin-bottom:6px;letter-spacing:.01em}
.hint{display:block;font-size:14.5px;color:var(--text-2);font-weight:500;margin-bottom:7px;line-height:1.5}
input[type=text],input[type=email],input[type=url],input[type=tel],input[type=search],select,textarea{
  width:100%;font-family:var(--sans);font-size:16.5px;line-height:1.5;color:var(--text);
  background:var(--bg);border:2px solid var(--line-control);border-radius:9px;padding:11px 13px;
  font-weight:400;
}
textarea{min-height:104px;resize:vertical}
input:focus-visible,select:focus-visible,textarea:focus-visible{outline:3px solid var(--focus-ring);outline-offset:1px;border-color:var(--green-ink)}
input[readonly]{background:var(--bg-alt);color:var(--text-2)}
.field-row{display:grid;grid-template-columns:1fr 1fr;gap:18px}
/* Side-by-side fields share row tracks - label, hint, control, anything
   after - so the controls line up even when only one side has a hint
   (Your name / Your title, LinkedIn / Second email). Browsers without
   subgrid keep the plain layout above. Row gaps go to 0 because each
   field already carries margin-bottom. */
@supports (grid-template-rows:subgrid){
  .field-row{row-gap:0}
  .field-row > .field{display:grid;grid-row:span 4;grid-template-rows:subgrid;align-content:start}
  .field-row > .field > label,.field-row > .field > .lbl{grid-row:1}
  .field-row > .field > .hint{grid-row:2}
  .field-row > .field > input,.field-row > .field > select,.field-row > .field > textarea{grid-row:3}
  .field-row > .field > :not(label):not(.lbl):not(.hint):not(input):not(select):not(textarea){grid-row:4}
}

.count{font-size:14px;color:var(--text-2);font-weight:600;margin-top:5px}
/* Announced copy of the character count. Visually hidden and updated on a
   settle delay so it does not narrate every keystroke (4.1.3). */
.count-live{position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.count.over{color:var(--accent-ink);font-weight:800}

/* ---------------- consent block ---------------- */
.consents{border:1px solid var(--line);border-radius:12px;padding:20px;background:var(--bg-alt);margin-bottom:22px}
.consents > h3{font-size:18.5px;font-weight:800;margin-bottom:6px}
.consents > p{font-size:15.5px;color:var(--text-2);margin-bottom:16px}
.check{display:flex;gap:12px;align-items:flex-start;padding:13px 0;border-top:1px solid var(--line-soft)}
.check:first-of-type{border-top:0}
.check input[type=checkbox]{width:21px;height:21px;margin:2px 0 0;flex:0 0 auto;accent-color:#16351F}
.check .lbl{margin-bottom:3px}
.check .hint{margin-bottom:0}

/* ---------------- listing cards on /me ---------------- */
.listing{border:1px solid var(--line);border-radius:14px;background:var(--bg);padding:26px;margin-bottom:26px}
.listing-head{display:flex;gap:16px;align-items:flex-start;justify-content:space-between;flex-wrap:wrap;margin-bottom:20px;padding-bottom:16px;border-bottom:1px solid var(--line-soft)}
.listing-head h2{font-size:23px;font-weight:800;line-height:1.2}
.listing-head .sub{font-size:15.5px;color:var(--text-2);margin-top:3px;font-weight:500}

.status{font-size:13.5px;font-weight:800;padding:4px 12px;border-radius:99px;border:1px solid transparent;white-space:nowrap}
.s-responded{background:var(--green-tint);color:var(--green-ink);border-color:var(--green-ink)}
.s-sent{background:var(--gold-tint);color:var(--accent-ink);border-color:var(--accent-ink)}
.s-declined,.s-bounced{background:var(--bg-alt);color:var(--text-2);border-color:var(--text-3)}

/* ---------------- locked / read-only panel ---------------- */
.locked{background:var(--green-tint);border-radius:10px;padding:16px 18px;margin-bottom:22px}
.locked h3{font-size:16px;font-weight:800;color:var(--green-ink);margin-bottom:8px}
.locked dl{display:grid;grid-template-columns:auto 1fr;gap:5px 16px;margin:0;font-size:16px}
.locked dt{font-weight:700;color:var(--green-ink)}
.locked dd{margin:0;color:var(--text)}
.locked .why{font-size:14.5px;color:var(--text-2);margin-top:12px;font-weight:500}

/* ---------------- logo ---------------- */
.logo-row{display:flex;gap:18px;align-items:center;flex-wrap:wrap}
.logo-box{width:104px;height:104px;flex:0 0 auto;border:2px dashed var(--line);border-radius:12px;display:grid;place-items:center;background:var(--bg-alt);overflow:hidden}
.logo-box img{max-width:100%;max-height:100%;object-fit:contain}
.logo-box span{font-size:13px;color:var(--text-2);font-weight:700;text-align:center;padding:6px}

/* Banner preview shows the 3:1 shape the listing will crop to, so what the
   member sees here is what the directory renders. */
.banner-row{display:flex;flex-direction:column;gap:12px;align-items:flex-start}
.banner-box{width:100%;max-width:360px;aspect-ratio:3/1;border:2px dashed var(--line);border-radius:12px;
  display:grid;place-items:center;background:var(--bg-alt);overflow:hidden}
.banner-box img{width:100%;height:100%;object-fit:cover;display:block}
.banner-box span{font-size:13px;color:var(--text-2);font-weight:700;text-align:center;padding:6px}
.banner-ctl{display:flex;flex-direction:column;gap:8px;align-items:flex-start}
.btn-link{appearance:none;background:none;border:0;padding:0;font:inherit;font-size:14.5px;font-weight:700;
  color:var(--green-ink);text-decoration:underline;cursor:pointer}
.btn-link:hover{color:var(--text)}
.btn-link[hidden]{display:none}

/* ---------------- actions / messages ---------------- */
.actions{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin-top:8px}
.msg{border-radius:9px;padding:13px 16px;font-size:16px;font-weight:600;margin-bottom:18px}
.msg-ok{background:var(--green-tint);color:var(--green-ink);border-left:5px solid var(--green-ink)}
.msg-err{background:var(--gold-tint);color:var(--accent-ink);border-left:5px solid var(--accent-ink)}
.msg[hidden]{display:none}
.muted{color:var(--text-2);font-size:16px}

/* ---------------- admin table ---------------- */
.admin-bar{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin-bottom:20px}
.admin-bar input[type=search]{max-width:320px}
.admin-bar select{max-width:210px}
.stat-row{display:grid;grid-template-columns:repeat(5,1fr);gap:14px;margin-bottom:26px}
.stat{border:1px solid var(--line);border-radius:12px;padding:16px 18px;background:var(--bg)}
.stat b{display:block;font-size:28px;font-weight:800;line-height:1.1;font-variant-numeric:tabular-nums}
.stat span{display:block;font-size:14.5px;color:var(--text-2);font-weight:600;margin-top:3px}

.tbl-wrap{border:1px solid var(--line);border-radius:14px;overflow:auto;background:var(--bg)}
table{border-collapse:collapse;width:100%;min-width:880px}
th,td{text-align:left;padding:13px 16px;border-bottom:1px solid var(--line-soft);font-size:16px;vertical-align:top}
th{background:var(--green-surface);color:var(--on-green);font-size:14px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;position:sticky;top:0;z-index:1}
tbody tr:hover{background:var(--bg-alt)}
tbody tr:last-child td{border-bottom:0}
td .who{font-weight:700}
td .sub{display:block;font-size:14.5px;color:var(--text-2);font-weight:500}
.flags{display:flex;gap:6px;flex-wrap:wrap}
/* Granted consent is a filled chip; withheld is an outline. It used to be
   --green-tint (#E4EDE7) against --bg-alt (#F3F6F4) — two pale greys four
   points apart, which asked the eye to read a swatch instead of a state.
   The weight difference now survives a glance, a projector and a photocopy,
   and it does not rely on hue, so it still reads without colour vision. */
.flag{font-size:12.5px;font-weight:800;line-height:1.5;padding:2px 10px;border-radius:99px;
  border:1px solid var(--green-surface);background:var(--green-surface);color:var(--on-green)}
.flag-off{border-color:var(--line-control);background:transparent;color:var(--text-3);font-weight:600}
/* In dark mode --green-surface sits almost on top of the row, so the chip
   loses its shape even though the white label still carries. A lighter fill
   and a lighter border put the boundary back over 3:1 (1.4.11).
   The :not() is load-bearing: .flag-off is a single class and would lose to
   any bare .flag rule written here, which filled every chip green. */
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .flag:not(.flag-off){background:#2E6B41;border-color:#3E8354;color:#FFFFFF}
}
:root[data-theme="dark"] .flag:not(.flag-off){background:#2E6B41;border-color:#3E8354;color:#FFFFFF}

/* ---------------- row controls ----------------
   Edit / Logo / Remove were .btn-sm: 15.5px type in a ~42px control. That is
   a form button, and next to a table row it swamps the record it acts on.
   At this size they read as part of the row. 14px x 1.35 + 12px padding +
   2px border = 35px tall, so the target still clears 24x24 (2.5.8).         */
#rows td:last-child .btn,
#mtg-rows td:last-child .btn,
.rowacts .btn{
  font-size:14px;font-weight:700;padding:6px 12px;border-radius:7px;line-height:1.35;
}
/* The actions column hugs its content, so Edit lands in the same place on
   every row whether or not that business has a website to give it a Logo
   button beside it — and middle alignment stops the pair riding up when the
   consent or data-issue cell wraps to a second line. That drift was the
   misalignment; the buttons were never the thing out of place. */
#rows td:last-child,
#mtg-rows td:last-child,
td.col-actions,
th.col-actions{width:1%;white-space:nowrap;vertical-align:middle}

/* The three consent chips hold one line. Stacked three high they doubled the
   height of every row for a fixed, three-item vocabulary. Category is left to
   wrap on purpose — "Real Estate, Finance & Insurance" on one line would take
   thirty characters of width away from the data issue, and a floor on the
   issue column pushed the table past the page and hid the Logo button behind
   a horizontal scroll. Width here is zero-sum; the chips are the cheapest
   place to buy it back. */
#rows td:nth-child(4){white-space:nowrap}
#rows td:nth-child(4) .flags{flex-wrap:nowrap;gap:5px}
#rows td:nth-child(4) .flag{font-size:12px;padding:2px 8px}
.issue{font-size:14.5px;color:var(--text-2);max-width:44ch;font-weight:500}

/* ---------------- admin desk width ----------------
   The member table's unbreakable parts - the longest email (39 characters),
   three consent chips and the Edit/Logo pair - need 1,178px. Inside the site's
   1,160px .wrap that left 1,114px, so the table scrolled sideways on every
   screen, a MacBook's 1,512px included. The admin desk is a working tool, not
   a reading page, so it runs wider than the public site. :has(#rows) scopes
   that to the admin desk alone - #rows exists on no other page - and a browser
   without :has() keeps the old width and the scroll, nothing worse.

   Column widths are set on purpose rather than left to auto layout. Left
   alone, the long data-issue notes took the spare width and business names
   wrapped onto three lines. Measured against the live rows, 2026-09-27: at
   1,512px 46 of 48 names and 42 of 47 categories sit on one line, and nothing
   scrolls sideways at 1,440, 1,366, 1,280 or 1,024px either. */
body:has(#rows) .wrap{max-width:1400px}
table:has(#rows) thead th:nth-child(1){width:27%}
table:has(#rows) thead th:nth-child(2){width:14%}
table:has(#rows) thead th:nth-child(5){width:24%}
/* Below 1,100px there is no spare width left to give out, so the cells tighten
   and a long email may break mid-address rather than push the table sideways.
   Above it, emails never break: overflow-wrap:anywhere also shrinks a column's
   minimum width, which is what let the notes column starve the member column. */
@media (max-width:1100px){
  table:has(#rows) th,#rows td{padding-inline:11px}
  #rows td .sub{overflow-wrap:anywhere}
}

dialog{border:1px solid var(--line);border-radius:14px;padding:0;background:var(--bg);color:var(--text);max-width:640px;width:calc(100% - 32px)}
dialog::backdrop{background:rgba(9,14,11,.6)}
.dlg-in{padding:26px}
.dlg-in h2{font-size:22px;font-weight:800;margin-bottom:18px}

@media (max-width:980px){
  .stat-row{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:640px){
  .field-row{grid-template-columns:1fr;gap:0}
  .listing{padding:20px}
  .stat-row{grid-template-columns:1fr 1fr}
  .locked dl{grid-template-columns:1fr;gap:2px}
  .locked dt{margin-top:8px}
}
