:root{
  /* Brand palette pulled from mycoders.in: deep navy "ink" as the dark base
     (chatapp was already a dark UI, so this is a hue-shift toward the
     brand's own navy rather than a light/dark flip), coral as the one
     accent color, DM Sans / Space Grotesk for type. */
  --bg:#0d1b2e;
  --panel:#13233a;
  --panel-alt:#1a2f4a;
  --border:#2c4560;
  --text:#eef1f4;
  --text-dim:#8fa0b3;
  --accent:#f26b4f;
  --accent-dim:#c65a41;
  --success:#3ecf8e;
  --danger:#e5484d;
  --bubble-me:#5a3226;
  --bubble-them:#1a2f4a;
  --radius:8px;
  font-size:16px;
}

*{box-sizing:border-box;}
html,body{height:100%;}
body{
  margin:0;
  background:var(--bg);
  color:var(--text);
  font-family:'DM Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
}
h1,h2,h3,.brand,.chat-header h2,.login-card h1{font-family:'Space Grotesk','DM Sans',sans-serif;}
a{color:var(--accent);}
button{
  font-family:inherit;cursor:pointer;
}
input, textarea, select{
  font-family:inherit;
  background:var(--panel-alt);
  border:1px solid var(--border);
  color:var(--text);
  border-radius:6px;
  padding:10px 12px;
}
input:focus, textarea:focus, select:focus{
  outline:2px solid var(--accent);
  outline-offset:1px;
}
::placeholder{color:var(--text-dim);}

.btn{
  background:var(--accent);
  color:#0b1220;
  border:none;
  font-weight:600;
  padding:10px 18px;
  border-radius:6px;
  transition:background .15s ease;
}
.btn:hover{background:#729bf1;}
.btn:disabled{opacity:.5;cursor:not-allowed;}
.btn-ghost{
  background:transparent;
  border:1px solid var(--border);
  color:var(--text);
}
.btn-ghost:hover{border-color:var(--accent);color:var(--accent);}
.btn-danger{background:var(--danger);color:#fff;}
.btn-danger:hover{background:#f16368;}
.btn-sm{padding:6px 12px;font-size:13px;}

/* ---------- Login page ---------- */
.login-wrap{
  min-height:100vh;
  display:flex;align-items:center;justify-content:center;
  padding:20px;
}
.login-card{
  width:100%;max-width:380px;
  background:var(--panel);
  border:1px solid var(--border);
  border-radius:var(--radius);
  padding:36px;
}
.login-card h1{
  font-size:22px;margin:0 0 4px;
}
.login-card .sub{color:var(--text-dim);font-size:14px;margin-bottom:28px;}
.field-group{margin-bottom:16px;}
.field-group label{display:block;font-size:13px;color:var(--text-dim);margin-bottom:6px;}
.field-group input{width:100%;}
.error-msg{
  background:rgba(229,72,77,0.12);
  border:1px solid rgba(229,72,77,0.35);
  color:#ff9a9d;
  padding:10px 12px;border-radius:6px;
  font-size:13px;margin-bottom:16px;
  display:none;
}
.error-msg.show{display:block;}
.success-msg{
  background:rgba(34,197,94,0.12);
  border:1px solid rgba(34,197,94,0.35);
  color:#7ee2a8;
  padding:10px 12px;border-radius:6px;
  font-size:13px;margin-bottom:16px;
  display:none;
}
.success-msg.show{display:block;}
.text-link{
  background:none;border:none;padding:0;
  color:var(--accent);font-size:13px;cursor:pointer;
}
.text-link:hover{text-decoration:underline;}
.hint{
  margin-top:20px;font-size:12px;color:var(--text-dim);
  border-top:1px solid var(--border);padding-top:16px;
}

/* ---------- App shell ---------- */
.app-shell{
  display:grid;
  /* minmax(0, 1fr), not bare 1fr — a bare 1fr track still grows to fit a
     descendant's content-based minimum width (e.g. an unbreakable pasted
     link, or the reply-quote preview's intentional white-space:nowrap for
     its ellipsis), which was stretching .chat-main itself past the actual
     viewport width and taking the composer's Send button off-screen with
     it. minmax(0, ...) caps the track at the space actually available. */
  grid-template-columns:280px minmax(0, 1fr);
  /* 100vh on mobile browsers is the height with the address bar hidden —
     the actually-visible viewport is shorter while it's showing, so the
     layout was taller than the screen and the whole page scrolled as a
     unit, dragging the "sticky" header along with it. 100dvh tracks the
     real visible height; overflow:hidden stops the whole-page scroll so
     only .sidebar-scroll and .messages (each scrollable on their own)
     move, keeping header/composer genuinely fixed in place. */
  height:100vh;
  height:100dvh;
  overflow:hidden;
}
.sidebar{
  background:var(--panel);
  border-right:1px solid var(--border);
  display:flex;flex-direction:column;
  overflow:hidden;
}
.sidebar-header{
  padding:18px 20px;
  border-bottom:1px solid var(--border);
  display:flex;align-items:center;justify-content:space-between;
  /* Same status-bar overlap as .chat-header — this doubles as the mobile
     drawer's own top edge, which is position:fixed to the very top of the
     screen. */
  padding-top:calc(18px + env(safe-area-inset-top));
}
.brand{font-weight:700;font-size:16px;display:flex;align-items:center;gap:8px;}
.brand .dot{width:8px;height:8px;background:var(--success);border-radius:50%;}
.me-row{
  padding:14px 20px;
  display:flex;align-items:center;gap:10px;
  border-bottom:1px solid var(--border);
}
.avatar{
  width:34px;height:34px;border-radius:50%;
  background:var(--accent-dim);
  display:flex;align-items:center;justify-content:center;
  font-weight:700;font-size:14px;color:#fff;
  flex-shrink:0;
}
.me-info{overflow:hidden;}
.me-name{font-size:14px;font-weight:600;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}
.me-role{font-size:12px;color:var(--text-dim);}
.sidebar-actions{padding:10px 16px;display:flex;gap:8px;border-bottom:1px solid var(--border);}
.sidebar-search-row{padding:10px 16px;border-bottom:1px solid var(--border);}
.sidebar-search{
  width:100%;padding:8px 12px;font-size:13px;
  background:var(--panel-alt);border:1px solid var(--border);border-radius:6px;color:var(--text);
}
.sidebar-search:focus{outline:2px solid var(--accent);outline-offset:1px;}
.sidebar-scroll{flex:1;overflow-y:auto;padding:10px 0;}
.nav-section-title{
  padding:14px 20px 6px;font-size:11px;text-transform:uppercase;
  letter-spacing:.06em;color:var(--text-dim);font-weight:700;
}
.nav-item{
  display:flex;align-items:center;gap:10px;
  padding:9px 20px;font-size:14px;color:var(--text);
  cursor:pointer;position:relative;
}
.nav-item:hover{background:var(--panel-alt);}
.nav-item.active{background:var(--panel-alt);border-left:3px solid var(--accent);padding-left:17px;}
.nav-item .presence-dot{width:8px;height:8px;border-radius:50%;background:var(--text-dim);flex-shrink:0;}
.nav-item .presence-dot.online{background:var(--success);}
.nav-item .name{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.nav-item .last-active{font-size:11px;color:var(--text-dim);flex-shrink:0;}
.unread-badge{min-width:18px;height:18px;padding:0 5px;border-radius:10px;background:var(--accent);color:#fff;font-size:11px;font-weight:700;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;}
.hash{color:var(--text-dim);}
.nav-empty{padding:9px 20px;font-size:13px;color:var(--text-dim);}
.nav-load-more{
  display:block;width:calc(100% - 32px);margin:4px 16px 10px;
  padding:7px;font-size:12px;font-weight:600;text-align:center;
  background:transparent;border:1px dashed var(--border);border-radius:6px;
  color:var(--text-dim);cursor:pointer;
}
.nav-load-more:hover{color:var(--accent);border-color:var(--accent);}

/* ---------- Chat main area ---------- */
.chat-main{display:flex;flex-direction:column;height:100vh;height:100dvh;min-height:0;}
.chat-header{
  padding:16px 24px;border-bottom:1px solid var(--border);
  display:flex;align-items:center;justify-content:space-between;
  background:var(--panel);
  /* Installed on the iPhone home screen, the status bar is translucent
     (see apple-mobile-web-app-status-bar-style in chat.html) and web
     content draws underneath it — without this the header sits behind the
     clock/notch instead of below it. env() is 0 everywhere else. */
  padding-top:calc(16px + env(safe-area-inset-top));
}
.chat-header h2{margin:0;font-size:16px;display:flex;align-items:center;gap:8px;}
.chat-header .desc{font-size:13px;color:var(--text-dim);margin-top:2px;}
.chat-header-left{display:flex;align-items:center;min-width:0;}
.menu-btn{display:none;font-size:18px;margin-right:6px;}
.chat-search-toggle{font-size:17px;flex-shrink:0;}
.sidebar-backdrop{display:none;}

/* ---------- In-chat search ---------- */
.chat-search-bar{
  position:relative;
  display:flex;align-items:center;gap:8px;
  padding:10px 24px;background:var(--panel);
  border-bottom:1px solid var(--border);
}
.chat-search-icon{color:var(--text-dim);font-size:13px;flex-shrink:0;}
.chat-search-input{
  flex:1;min-width:0;font-size:13px;
  background:var(--panel-alt);border:1px solid var(--border);
  border-radius:6px;padding:8px 12px;color:var(--text);
}
.chat-search-count{
  font-size:12px;color:var(--text-dim);white-space:nowrap;
  min-width:56px;text-align:center;flex-shrink:0;
}
.chat-search-nav{
  font-size:11px;padding:5px 8px;flex-shrink:0;
  border:1px solid var(--border);border-radius:6px;background:var(--panel-alt);
}
.chat-search-nav:disabled{opacity:.35;cursor:not-allowed;}
.chat-search-nav:not(:disabled):hover{border-color:var(--accent);color:var(--accent);}
.chat-search-dropdown{
  display:none;position:absolute;top:100%;left:24px;right:24px;
  background:var(--panel);border:1px solid var(--border);border-top:none;
  border-radius:0 0 var(--radius) var(--radius);
  box-shadow:0 14px 32px rgba(0,0,0,.35);
  max-height:360px;overflow-y:auto;z-index:20;
}
.chat-search-dropdown.show{display:block;}
.search-result-item{padding:10px 16px;cursor:pointer;border-bottom:1px solid var(--border);}
.search-result-item:last-child{border-bottom:none;}
.search-result-item:hover,.search-result-item.active{background:var(--panel-alt);}
.search-result-meta{
  display:flex;justify-content:space-between;gap:10px;
  font-size:11px;color:var(--text-dim);margin-bottom:3px;
}
.search-result-meta span:first-child{font-weight:600;color:var(--text);}
.search-result-snippet{font-size:13px;color:var(--text-dim);line-height:1.4;}
.search-result-snippet mark{
  background:rgba(242,107,79,.32);color:var(--text);
  border-radius:3px;padding:0 2px;
}
.search-empty{padding:16px;text-align:center;color:var(--text-dim);font-size:13px;}

.messages-wrap{position:relative;flex:1;min-height:0;display:flex;flex-direction:column;}
.messages{
  flex:1;overflow-y:auto;padding:24px;
  display:flex;flex-direction:column;gap:14px;
  min-height:0;
}
.empty-state{
  margin:auto;text-align:center;color:var(--text-dim);
}
.drop-overlay{
  display:none;position:absolute;inset:8px;z-index:5;
  align-items:center;justify-content:center;
  border:2px dashed var(--accent);border-radius:var(--radius);
  background:rgba(242,107,79,.08);
  color:var(--accent);font-weight:600;font-size:15px;
  pointer-events:none;
}
.messages-wrap.dragging .drop-overlay{display:flex;}
.jump-latest-btn{
  position:absolute;bottom:16px;left:50%;transform:translateX(-50%);
  background:var(--accent);color:#0b1220;font-weight:600;font-size:12.5px;
  padding:8px 16px;border:none;border-radius:20px;
  box-shadow:0 6px 18px rgba(0,0,0,.35);cursor:pointer;z-index:6;
}
.jump-latest-btn:hover{background:#729bf1;}
.date-separator{align-self:center;display:flex;}
.date-separator span{
  background:var(--panel-alt);border:1px solid var(--border);
  color:var(--text-dim);font-size:12px;font-weight:600;
  padding:4px 14px;border-radius:14px;
}
.msg-row{display:flex;gap:10px;max-width:70%;position:relative;}
.msg-row.me{align-self:flex-end;flex-direction:row-reverse;}
/* Flex items default to min-width:auto, which lets them refuse to shrink
   below their unwrapped content width — so a long message pushed the whole
   row past its container instead of wrapping, and text ran off the edge of
   the screen with no way to scroll and see it. min-width:0 lets this item
   shrink to the space actually available so word-wrap can do its job. */
.msg-group{position:relative;min-width:0;}
.msg-bubble{
  background:var(--bubble-them);
  padding:10px 14px;border-radius:var(--radius);
  font-size:14px;line-height:1.5;
  /* word-wrap:break-word only stops overflow inside a box that's already
     been sized — it does NOT shrink the box's own intrinsic minimum width,
     which browsers compute as if the text couldn't break at all. A pasted
     link with no spaces (e.g. a raw Google Docs URL) was therefore still
     counted at its full unbroken pixel width when sizing the flex/grid
     ancestors above it, stretching the whole chat column (composer
     included) far past the viewport on any device narrow enough that the
     link alone exceeds its width. overflow-wrap:anywhere is the one that
     actually counts toward that intrinsic-size calculation. */
  word-wrap:break-word;
  overflow-wrap:anywhere;
}
.msg-row.me .msg-bubble{background:var(--bubble-me);}
/* Brief ring pulse when a search result is jumped to — a box-shadow (not a
   background-color swap) so it works identically over both the "me" and
   "them" bubble colors without needing to know which one applies. */
.msg-row.highlight-flash .msg-bubble{animation:searchFlash 1.8s ease;border-radius:var(--radius);}
@keyframes searchFlash{
  0%,55%{box-shadow:0 0 0 3px var(--accent);}
  100%{box-shadow:0 0 0 0 rgba(242,107,79,0);}
}
.msg-meta{font-size:11px;color:var(--text-dim);margin-bottom:4px;}
.msg-row.me .msg-meta{text-align:right;}
.msg-edited-tag{opacity:.7;font-style:italic;}
.msg-status{display:block;text-align:right;margin-top:2px;font-size:12px;line-height:1;color:var(--text-dim);letter-spacing:-2px;}
.msg-status.read{color:#48b8f0;}

.msg-quote{
  border-left:3px solid var(--accent);
  background:rgba(255,255,255,.06);
  padding:4px 10px;margin-bottom:6px;
  border-radius:4px;font-size:12.5px;
  max-width:100%;overflow:hidden;
}
.msg-quote-name{color:var(--accent);font-weight:600;margin-bottom:1px;}
.msg-quote-text{color:var(--text-dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}

.msg-actions{
  display:none;align-items:center;gap:2px;
  align-self:center;
}
/* :hover never reliably fires on a touchscreen — without this split, Reply
   and Edit are effectively unreachable on mobile, since there's no hover
   state to reveal them. Real pointer devices still get the hover reveal
   (keeps message rows uncluttered); touch devices just show them always. */
@media (hover: hover) {
  .msg-row:hover .msg-actions{display:flex;}
}
@media (hover: none) {
  .msg-actions{display:flex;}
  /* Bigger tap target on touch — the hover-only 12px icon + 4-7px padding
     is fine for a mouse cursor but too small to comfortably tap reliably. */
  .msg-action-btn{padding:9px 12px;font-size:15px;}
  /* On a mouse the actions only ever appear on hover, so they cost the row
     nothing by default; on touch they're always there, permanently eating
     into the same 70% budget, which left very little room for the bubble
     itself on a narrow phone. Give the row more width to compensate. */
  .msg-row{max-width:88%;}
}
.msg-action-btn{
  background:var(--panel-alt);border:1px solid var(--border);color:var(--text-dim);
  border-radius:6px;padding:4px 7px;font-size:12px;line-height:1;
}
.msg-action-btn:hover{color:var(--text);border-color:var(--accent);}
.msg-delete-btn:hover{color:#e05555;border-color:#e05555;}

.msg-edit-form{display:flex;gap:6px;align-items:flex-end;min-width:220px;}
.msg-edit-form textarea{flex:1;min-height:36px;resize:vertical;font-size:14px;}

.reply-preview{
  display:flex;align-items:center;gap:10px;
  padding:8px 24px;background:var(--panel);
  border-top:1px solid var(--border);
}
.reply-preview-body{flex:1;border-left:3px solid var(--accent);padding:2px 10px;overflow:hidden;}
.reply-preview-name{font-size:12px;font-weight:600;color:var(--accent);}
.reply-preview-text{font-size:13px;color:var(--text-dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}

.attachment-preview{
  display:flex;align-items:center;gap:10px;
  padding:8px 24px;background:var(--panel);
  border-top:1px solid var(--border);
}
.attachment-preview-body{
  flex:1;display:flex;align-items:center;gap:10px;overflow:hidden;
  font-size:13px;color:var(--text);
}
.attachment-preview-thumb{
  position:relative;width:36px;height:36px;flex-shrink:0;
  display:flex;align-items:center;justify-content:center;
  border-radius:4px;overflow:hidden;background:var(--panel-alt);font-size:16px;
}
.attachment-preview-thumb img{width:100%;height:100%;object-fit:cover;display:block;}
.attachment-preview-info{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px;justify-content:center;}
.attachment-preview-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.attachment-preview-size{color:var(--text-dim);flex-shrink:0;}

/* Uploading state: a translucent scrim + spinner over the thumbnail, and a
   progress bar in place of the file size, so the user has clear, continuous
   feedback that something is happening instead of a frozen composer. */
.attachment-preview-body.uploading .attachment-preview-thumb::after{
  content:'';position:absolute;inset:0;background:rgba(13,27,46,.45);
}
.attachment-spinner{
  position:absolute;z-index:1;width:18px;height:18px;
  border:2px solid rgba(238,241,244,.35);border-top-color:var(--accent);
  border-radius:50%;animation:attachmentSpin .7s linear infinite;
}
@keyframes attachmentSpin{to{transform:rotate(360deg);}}
.attachment-progress-row{display:flex;align-items:center;gap:8px;}
.attachment-progress-track{
  flex:1;height:5px;border-radius:3px;background:var(--panel-alt);
  overflow:hidden;
}
.attachment-progress-bar{
  display:block;height:100%;border-radius:3px;background:var(--accent);
  transition:width .15s ease;
}
.attachment-progress-pct{color:var(--text-dim);font-size:11px;flex-shrink:0;min-width:32px;text-align:right;}

.typing-indicator{
  padding:0 24px 8px;font-size:12px;color:var(--text-dim);min-height:18px;
}
.composer{
  padding:16px 24px;border-top:1px solid var(--border);
  display:flex;gap:10px;align-items:flex-end;background:var(--panel);
  /* Keeps the composer clear of the home indicator on notched iPhones when
     installed to the home screen — see the matching note on .chat-header. */
  padding-bottom:calc(16px + env(safe-area-inset-bottom));
}
.composer-attach-btn{
  align-self:center;font-size:19px;padding:8px;flex-shrink:0;
}
.composer .btn{flex-shrink:0;}
.message-input{
  /* min-width:0 overrides a flex item's default "auto" minimum, which is
     otherwise based on its content's intrinsic width — without it, a long
     placeholder (or a long unbroken paste) refuses to shrink and pushes
     the Send button off the right edge of the screen on narrow viewports
     instead of wrapping. overflow-x:hidden backs that up by clipping any
     content that still doesn't wrap (Safari/WebKit doesn't reliably wrap
     the placeholder's ::before content the way Chromium does), so the box
     itself can never grow past its flex-assigned width either way.
     white-space/overflow-wrap force real wrapping in both engines instead
     of relying on the browser's contenteditable default. */
  flex:1;min-width:0;resize:none;min-height:44px;max-height:160px;
  overflow-y:auto;overflow-x:hidden;padding:10px 12px;line-height:1.5;
  white-space:normal;overflow-wrap:anywhere;
  background:var(--panel-alt);border:1px solid var(--border);border-radius:6px;
  font-size:14px;color:var(--text);
}
.message-input:empty:before{white-space:normal;}
.message-input:focus{outline:2px solid var(--accent);outline-offset:1px;}
.message-input:empty:before{content:attr(data-placeholder);color:var(--text-dim);}
/* Anything pasted keeps its own inline color/weight from the source page —
   these two make sure it isn't unreadable against the composer's own dark
   background, without stripping the formatting itself. */
.message-input b, .message-input strong{font-weight:700;}
.message-input a{color:var(--accent);text-decoration:underline;}

/* ---------- Message attachments (images/video/files in a bubble) ---------- */
.msg-attachment{margin-top:6px;}
.msg-attachment img, .msg-attachment video{
  max-width:280px;max-height:280px;border-radius:6px;display:block;cursor:pointer;
}
.msg-attachment audio{max-width:260px;}
.msg-file-chip{
  display:flex;align-items:center;gap:10px;
  background:rgba(255,255,255,.06);border:1px solid var(--border);
  border-radius:6px;padding:8px 12px;text-decoration:none;color:var(--text);
  max-width:260px;
}
.msg-file-chip .file-icon{font-size:20px;flex-shrink:0;}
.msg-file-chip .file-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px;}
.msg-file-chip .file-size{font-size:11px;color:var(--text-dim);}
/* A message that's only an attachment (no caption) shouldn't render an
   empty bubble above it. */
.msg-bubble:empty{padding:0;background:transparent;}

/* ---------- Admin page ---------- */
.admin-shell{max-width:1100px;margin:0 auto;padding:32px 24px 80px;}
.admin-top{display:flex;justify-content:space-between;align-items:center;margin-bottom:28px;}
.admin-top h1{margin:0;font-size:22px;}
.tabs{display:flex;gap:6px;border-bottom:1px solid var(--border);margin-bottom:24px;}
.tab{
  padding:10px 18px;font-size:14px;color:var(--text-dim);
  cursor:pointer;border-bottom:2px solid transparent;
}
.tab.active{color:var(--text);border-bottom-color:var(--accent);}
.panel{background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);padding:24px;}
.panel h3{margin-top:0;}
table{width:100%;border-collapse:collapse;font-size:14px;}
th,td{text-align:left;padding:10px 12px;border-bottom:1px solid var(--border);}
th{color:var(--text-dim);font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:.04em;}
th.sortable{cursor:pointer;user-select:none;}
th.sortable:hover{color:var(--text);}
th.sortable .sort-arrow{margin-left:4px;color:var(--accent);}
tr:last-child td{border-bottom:none;}
.badge{
  display:inline-block;padding:2px 8px;border-radius:20px;font-size:11px;font-weight:600;
}
.badge.admin{background:rgba(242,107,79,0.18);color:var(--accent);}
.badge.user{background:rgba(154,161,178,0.18);color:var(--text-dim);}
.badge.active{background:rgba(62,207,142,0.15);color:var(--success);}
.badge.inactive{background:rgba(229,72,77,0.15);color:#ff9a9d;}
.row-actions{display:flex;gap:6px;}
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:18px;}
.form-grid .full{grid-column:1/-1;}
.modal-overlay{
  position:fixed;inset:0;background:rgba(0,0,0,0.55);
  display:none;align-items:center;justify-content:center;z-index:50;
}
.modal-overlay.show{display:flex;}
.modal{
  background:var(--panel);border:1px solid var(--border);border-radius:var(--radius);
  padding:28px;width:100%;max-width:440px;max-height:85vh;overflow-y:auto;
}
.modal h3{margin-top:0;}
.modal-actions{display:flex;justify-content:flex-end;gap:10px;margin-top:20px;}
.member-list{max-height:180px;overflow-y:auto;border:1px solid var(--border);border-radius:6px;padding:8px;}
.member-list label{display:flex;align-items:center;gap:8px;padding:6px 4px;font-size:14px;cursor:pointer;}
.member-list input{width:auto;}
.toast{
  position:fixed;bottom:24px;right:24px;
  background:var(--panel-alt);border:1px solid var(--border);
  padding:12px 18px;border-radius:6px;font-size:14px;
  box-shadow:0 8px 24px rgba(0,0,0,.3);
  opacity:0;transform:translateY(8px);
  transition:opacity .2s ease, transform .2s ease;
  pointer-events:none;z-index:100;
}
.toast.show{opacity:1;transform:translateY(0);}
.toast.error{border-color:rgba(229,72,77,0.5);color:#ff9a9d;}

/* ---------- "Enable notifications" banner (needs a real tap on iOS Safari) ---------- */
.notif-banner{
  display:none;align-items:center;gap:10px;
  position:fixed;top:0;left:0;right:0;z-index:150;
  background:var(--panel-alt);border-bottom:1px solid var(--border);
  padding:10px 16px;font-size:14px;
  padding-top:calc(10px + env(safe-area-inset-top));
}
.notif-banner.show{display:flex;}
.notif-banner span{flex:1;}

/* ---------- Image lightbox (click an attached image to enlarge) ---------- */
.lightbox{
  display:none;position:fixed;inset:0;z-index:200;
  align-items:center;justify-content:center;
  background:rgba(0,0,0,.88);
  cursor:zoom-out;
}
.lightbox.show{display:flex;}
.lightbox img{
  max-width:92vw;max-height:88vh;border-radius:6px;
  box-shadow:0 12px 48px rgba(0,0,0,.5);
  cursor:default;
}
.lightbox-toolbar{
  position:absolute;top:18px;right:20px;display:flex;gap:10px;z-index:1;
}
.lightbox-btn{
  display:flex;align-items:center;justify-content:center;
  width:40px;height:40px;border-radius:50%;
  background:rgba(255,255,255,.12);border:none;color:#fff;
  font-size:18px;text-decoration:none;cursor:pointer;
}
.lightbox-btn:hover{background:rgba(255,255,255,.22);}
.toast.success{border-color:rgba(62,207,142,0.5);color:var(--success);}
.icon-btn{
  background:transparent;border:none;color:var(--text-dim);font-size:16px;padding:4px;
}
.icon-btn:hover{color:var(--text);}

@media (max-width:800px){
  .app-shell{grid-template-columns:minmax(0, 1fr);}
  .sidebar{position:fixed;inset:0 auto 0 0;z-index:40;transform:translateX(-100%);transition:transform .2s ease;width:280px;max-width:85vw;}
  .sidebar.open{transform:translateX(0);}
  .menu-btn{display:inline-flex;align-items:center;justify-content:center;}
  .sidebar-backdrop.show{
    display:block;position:fixed;inset:0;z-index:39;
    background:rgba(0,0,0,.5);
  }
  .form-grid{grid-template-columns:1fr;}
}
