/* Throbstar — dark theme */
:root {
  --bg: #0e1113;
  --panel: #14181b;
  --panel2: #1b2125;
  --line: #2a3238;
  --ink: #e6e9e8;
  --mut: #8a979b;
  --acc: #d9413a;
  --acc2: #7c2620;
  --ok: #4caf7d;
  --warn: #d6a53c;
  --bad: #d65c5c;
  /* Chat attachment cell size (desktop). Mobile overrides below. */
  --chat-cell: 128px;
}
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--ink);
  font: 15px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif;
}
a { color: var(--acc); text-decoration: none; }
a:hover { text-decoration: underline; }
code { background: var(--panel2); padding: 0.1em 0.4em; border-radius: 4px; }

.topbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.7rem 1.3rem;
  padding: 0.7rem 1.4rem;
  background: linear-gradient(180deg, var(--panel2), var(--panel));
  border-bottom: 1px solid var(--line);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.5);
  position: sticky;
  top: 0;
  z-index: 10;
}
.brand { display: inline-flex; align-items: center; gap: 0.55em; font-weight: 700; letter-spacing: 0.05em; font-size: 1.05rem; color: var(--ink); }
.brand::before { content: ""; width: 1em; height: 2.4em; background: url(/images/fork.svg) center / contain no-repeat; filter: drop-shadow(0 0 5px rgba(217, 65, 58, 0.7)); }
.brand:hover { text-decoration: none; color: var(--acc); }
.nav { margin-left: auto; display: flex; gap: 0.3rem; padding: 0.25rem; background: var(--panel2); border: 1px solid var(--line); border-radius: 999px; }
.nav a {
  color: var(--mut);
  font-size: 0.9rem;
  padding: 0.35em 0.95em;
  border: 1px solid transparent;
  border-radius: 999px;
  transition: color 0.15s, border-color 0.15s, background-color 0.15s;
}
.nav a:hover { color: var(--ink); border-color: var(--line); background: var(--panel); text-decoration: none; }
.nav a.on { color: var(--ink); background: var(--acc2); border-color: var(--acc); text-decoration: none; }
@media (max-width: 640px) {
  /* Compact the strip so brand and menu share one line on narrow screens. */
  .topbar { flex-wrap: nowrap; gap: 0.5rem 0.8rem; padding: 0.6rem 0.9rem; }
  .brand { font-size: 0.95rem; }
  .nav { gap: 0.15rem; padding: 0.2rem; }
  .nav a { font-size: 0.78rem; padding: 0.3em 0.7em; }
}
.who { margin-left: auto; display: flex; align-items: center; gap: 0.7rem; }
.who-chip { display: inline-flex; align-items: center; background: var(--panel2); border: 1px solid var(--line); border-radius: 999px; padding: 0.25em 0.9em; }
.who-id { color: var(--ink); font-size: 0.8rem; }

.wrap { max-width: 1080px; margin: 0 auto; padding: 1.4rem 1.2rem 4rem; }
h1 { font-size: 1.5rem; margin: 0.2rem 0 1rem; }
h2 { font-size: 1.05rem; margin: 0 0 0.7rem; color: var(--mut); text-transform: uppercase; letter-spacing: 0.08em; }
.mut { color: var(--mut); }
.inline { display: inline-flex; align-items: center; gap: 0.4rem; margin: 0.2rem 0; }
.wdetails-actions { display: flex; align-items: center; justify-content: center; gap: 0.5rem; margin-top: 0.9rem; }
.wdetails-actions form.inline { margin: 0; }
.inline[hidden] { display: none; }
.wrel-add { display: flex; gap: 0.5rem; margin: 0.9rem 0; }
.wrel-grid form.inline { margin: 0; }
/* Relations section header: title left, Add button right on the same row. */
.relsec-head { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; margin-bottom: 0.5rem; }
.relsec-head h2 { margin: 0; }
/* Search section stacks: every input and the Search button span the full width. */
.relsearch { display: flex; flex-direction: column; gap: 0.5rem; margin: 0.9rem 0; }
.relsearch input, .relsearch button { width: 100%; }
.relsearch-results { max-height: 40vh; overflow-y: auto; margin: 0.9rem 0; }
/* Full-width so the select's percentage width resolves against the fixed column, not its own intrinsic size. */
.relsearch-results form.inline { margin: 0; width: 100%; }
/* Fixed layout: the Relation column takes an explicit width that fits the
   longest label at the reduced type; the Add column is fixed too, so the
   name column takes the remaining slack. */
.relsearch-results .grid { table-layout: fixed; }
.relsearch-results .grid th:nth-child(2), .relsearch-results .grid td:nth-child(2) { width: 11.5rem; white-space: nowrap; }
.relsearch-results .grid th:nth-child(3), .relsearch-results .grid td:nth-child(3) { width: 3.5rem; white-space: nowrap; }
.relsearch-results select { width: 100%; font-size: 0.72rem; }
/* Reduced type in the name and Add columns. */
.relsearch-results .grid td:nth-child(1) a { font-size: 0.85rem; }
.relsearch-results .grid td:nth-child(3) button { font-size: 0.7rem; padding: 0.25em 0.6em; }
@media (max-width: 640px) {
  .relsearch-results .grid th:nth-child(2), .relsearch-results .grid td:nth-child(2) { width: 8.5rem; }
  .relsearch-results select { font-size: 0.66rem; }
}

.btn {
  background: var(--acc2);
  border: 1px solid var(--acc);
  color: var(--ink);
  padding: 0.45em 1.1em;
  border-radius: 6px;
  font: inherit;
  cursor: pointer;
}
.btn:hover { background: var(--acc); }
.btn[disabled] { background: var(--panel); border-color: var(--line); color: var(--mut); cursor: not-allowed; }
.btn[disabled]:hover { background: var(--panel); }
.btn-ghost { background: transparent; border-color: var(--line); color: var(--mut); }
.btn-ghost:hover { color: var(--ink); border-color: var(--mut); background: transparent; }
.btn-danger { background: transparent; border-color: var(--bad); color: var(--bad); }
.btn-danger:hover { background: var(--bad); color: var(--ink); }
.btn-sm { padding: 0.3em 0.85em; font-size: 0.8rem; border-radius: 999px; }

.form { display: flex; flex-direction: column; gap: 0.9rem; max-width: 460px; }
label { display: flex; flex-direction: column; gap: 0.3rem; color: var(--mut); font-size: 0.85rem; }
label.check { flex-direction: row; align-items: center; gap: 0.5rem; }
.rules { margin: 0.2em 0 0; padding-left: 1.1em; font-size: 0.72rem; line-height: 1.5; color: var(--mut); }
.rules li { margin: 0.05em 0; }
input, select, textarea {
  background: var(--panel);
  border: 1px solid var(--line);
  color: var(--ink);
  border-radius: 6px;
  padding: 0.5em 0.7em;
  font: inherit;
  width: 100%;
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--acc); }
textarea { resize: vertical; }
input.narrow { width: 5rem; }

.auth { max-width: 420px; margin: 0 auto; }
.auth h1 { margin-bottom: 0.2rem; }

.flash { border: 1px solid var(--line); border-radius: 6px; padding: 0.6em 0.9em; margin: 0 0 1rem; }
.flash p { margin: 0.2em 0; }
.flash-ok { border-color: var(--ok); }
.flash-warn { border-color: var(--warn); }
.flash-info { border-color: var(--line); }

.search { display: flex; gap: 0.8rem; align-items: end; margin-bottom: 1.2rem; }
.search input[type="text"], .search input:not([type]) { flex: 1; }
.search label.check { flex-direction: row; }

.grid { width: 100%; border-collapse: collapse; }
.grid th { text-align: left; color: var(--mut); font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.08em; padding: 0.4em 0.6em; border-bottom: 1px solid var(--line); }
.grid td { padding: 0.5em 0.6em; border-bottom: 1px solid var(--line); vertical-align: middle; }
.grid tr:hover td { background: var(--panel); }

.badge { display: inline-block; padding: 0.05em 0.55em; border-radius: 999px; font-size: 0.72rem; border: 1px solid var(--line); color: var(--mut); }
.badge-wife { border-color: var(--acc); color: var(--acc); }
.badge-girlfriend { border-color: var(--ok); color: var(--ok); }
.badge-friend { border-color: var(--mut); color: var(--mut); }
.badge-ex-girlfriend, .badge-ex-wife { border-color: var(--warn); color: var(--warn); }

.panel { background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: 1rem 1.2rem; margin: 1rem 0; }
.details { white-space: normal; }

.gal { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 0.7rem; }
.gal figure, .vids figure { margin: 0; }
.gal img { width: 100%; aspect-ratio: 1; object-fit: contain; border: 1px solid #4a0c0a; border-radius: 6px; display: block; background: var(--panel); }
.gal figcaption, .vids figcaption { font-size: 0.75rem; margin-top: 0.3em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dpick-item { display: block; width: 100%; padding: 0; border: 2px solid var(--line); border-radius: 6px; background: none; cursor: pointer; }
.dpick-item img { width: 100%; height: 150px; object-fit: cover; border-radius: 4px; display: block; }
.dpick-item:hover, .dpick-item.on { border-color: var(--acc); }
.vids { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 0.9rem; }
.vids video { width: 100%; object-fit: contain; border: 1px solid #4a0c0a; border-radius: 6px; display: block; background: #000; }
.gal figure:hover img { border-color: var(--acc); box-shadow: 0 0 18px 2px rgba(217, 65, 58, 0.75); }
.vids figure:hover video { border-color: var(--acc); box-shadow: 0 0 18px 2px rgba(217, 65, 58, 0.75); }
/* Mobile: the images-tab gallery packs three tiles per row (the square
   tile geometry follows the narrower columns); dpick keeps its own layout. */
@media (max-width: 640px) {
  .wmedia-panel[data-tabpanel="images"] .gal { grid-template-columns: repeat(3, 1fr); }
}

.codes li { margin: 0.15em 0; }

.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; letter-spacing: 0.06em; }
.idbig { font-size: 1.6rem; word-break: break-all; margin: 1rem 0; }

/* Chat — full-bleed: header strip above, chat filling the viewport.
   Mobile browsers overlay their UI (and the virtual keyboard) on the
   bottom of the layout viewport, so the fixed layout must track the
   DYNAMIC viewport height or the composer lands behind the chrome and
   becomes unreachable (body overflow is hidden). Older browsers ignore
   the dvh declaration and keep the vh fallback. */
body:has(main.wrap > .chatwrap) { height: 100vh; height: 100dvh; overflow: hidden; display: flex; flex-direction: column; }
main.wrap:has(> .chatwrap) { flex: 1; min-height: 0; max-width: none; margin: 0; padding: 0.8rem 1.1rem 1rem; display: flex; flex-direction: column; }
.chatwrap { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 0.6rem; }
.chat-surface { flex: 1; min-height: 0; display: flex; flex-direction: row; gap: 1rem; }
/* Padding insets every entry from the scrollport edge by more than the
   hover-glow extent (~13px) so the full glow renders inside the rail. */
.chat-rail { flex: 0 0 15rem; overflow-y: auto; display: flex; flex-direction: column; gap: 0.3rem; border-right: 1px solid var(--line); padding: 0.9rem; }
.chat-room { display: block; padding: 0.45rem 0.7rem; border-radius: 6px; border: 1px solid transparent; color: var(--mut); text-decoration: none; font-size: 0.9rem; overflow-wrap: anywhere; }
.chat-room:hover { color: var(--ink); background: var(--panel); text-decoration: none; box-shadow: 0 0 12px 1px rgba(217, 65, 58, 0.4); }
/* Popup-context entries: styled exactly like the desktop rail entries. */
.dm-pop-list { display: flex; flex-direction: column; gap: 0.3rem; }
/* Group entry: a real button, pinned above the separator at all times. */
.chat-rail .chat-room-group { text-align: center; border: 1px solid var(--line); background: var(--panel); }
/* Info entry (desktop rail): a real button wearing the room-entry styling —
   the same bordered, panel-backed look as the pinned Group entry. */
.chat-room-info { text-align: center; border: 1px solid var(--line); background: var(--panel); font-family: inherit; cursor: pointer; }
.chat-sep { border-top: 1px solid var(--line); }
.chat-rooms { display: contents; }
.chat-room.on { color: var(--acc); border-color: transparent; background: color-mix(in srgb, var(--acc) 14%, transparent); }
.chat-room.unread { font-weight: 700; color: var(--ink); }
.chat-room.unread::before { content: ""; display: inline-block; width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--acc); margin-right: 0.5em; }
.chat-head { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--mut); text-align: center; margin-bottom: 0.6rem; }
.chat-col { position: relative; flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.chat-col[hidden] { display: none; }
.chat-bar { display: flex; gap: 0.5rem; padding-bottom: 0.6rem; border-bottom: 1px solid var(--line); }
.chat-bar-btn { flex: 1; display: block; text-align: center; padding: 0.3rem 0.4rem; border: 1px solid var(--line); border-radius: 6px; color: var(--mut); text-decoration: none; font-size: 0.72rem; background: none; cursor: pointer; }
.chat-bar-btn:hover { text-decoration: none; box-shadow: 0 0 12px 1px rgba(217, 65, 58, 0.4); }
.chat-bar-btn.on { color: var(--acc); border-color: transparent; background: color-mix(in srgb, var(--acc) 14%, transparent); }
/* Info content: its own contained box — height driven by its content on
   every viewport, inset from the surface edges, never a full-bleed section. */
.chat-info { flex: 0 1 auto; margin: 0.5rem; max-height: calc(100% - 1rem); min-height: 0; overflow-y: auto; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: 1.1rem 1.3rem; }
.chat-info h2 { margin: 0 0 0.6rem; font-size: 1rem; }
.chat-info h3 { margin: 1.1rem 0 0.4rem; font-size: 0.72rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; color: var(--mut); }
.chat-info p { margin: 0 0 0.4rem; font-size: 0.8rem; }
.chat-info p + p { margin-top: 0.8rem; }
.chat-info ul { margin: 0.3rem 0 0; padding-left: 1.2rem; }
.chat-info li { margin: 0.25rem 0; font-size: 0.9rem; }
/* Fullscreen override — higher specificity than the shared .modal/.modal-card
   rules so the cascade can't claw back the centred-card geometry. */
.modal.dm-pop { padding: 0; }
.dm-pop .modal-card { max-width: 100%; width: 100%; height: 100%; max-height: none; border: 0; border-radius: 0; padding: 1.2rem 1.2rem 1.4rem; }
@media (max-width: 640px) {
  .chat-surface { flex-direction: column; gap: 0.6rem; }
  .chat-rail { display: none; }
  /* Small enough that at least three cells fit every realistic mobile width. */
  :root { --chat-cell: 80px; }
}
/* Desktop: the rail carries the Info entry, so the tab strip retires; the
   info box caps at half the surface width and centres in the area beside
   the rail, content-heighted. */
@media (min-width: 641px) {
  .chat-bar { display: none; }
  .chat-info { flex: 0 1 50%; margin-left: auto; margin-right: auto; align-self: flex-start; }
}
.chat {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.9rem 1.1rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.chat-empty { margin: auto; }
/* One box per message: name far left inside the box, text below it, media
   below the text. The box hugs its content — short messages stay narrow,
   long ones grow to the available width and wrap (break-word) instead of
   stretching past the surface. */
.chat-msg {
  align-self: flex-start;
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.45rem 0.65rem;
  max-width: 100%;
}
.chat-msg > * + * { margin-top: 0.25rem; }
.chat-user { font-weight: 700; color: var(--acc); font-size: 0.85rem; }
/* Username buttons: reset the native button chrome only — size, weight and
   colour come from .chat-user, exactly as the original span styling. Hover
   underlines instead of glowing. */
.chat-who { background: none; border: 0; padding: 0; margin: 0; font-family: inherit; cursor: pointer; }
.chat-who:hover { text-decoration: underline; }
.who-pop-actions { display: flex; gap: 0.6rem; margin-top: 1rem; }
.chat-body { overflow-wrap: break-word; font-size: 0.85rem; }
/* Attachments: one single-line row per message. Fixed-size square cells
   (letterboxed, never cropped) so the client can compute exactly how many
   fit the line; overflow cells are hidden and the last visible one carries
   a "+N more" overlay. */
.chat-media-row { display: flex; gap: 4px; overflow: hidden; }
.chat-media-cell {
  position: relative;
  flex: 0 0 auto;
  width: var(--chat-cell);
  height: var(--chat-cell);
  padding: 0;
  border: 0;
  border-radius: 6px;
  overflow: hidden;
  background: none;
  cursor: zoom-in;
}
.chat-media-cell[hidden] { display: none; }
.chat-media-cell img { display: block; width: 100%; height: 100%; object-fit: contain; }
/* "+N more" overlay centred on the last visible cell of an overflowing row. */
.chat-media-more {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-weight: 700;
  font-size: 0.8rem;
  pointer-events: none;
}
.chat-media-cell[data-kind="video"]::after {
  content: "\25B6";
  position: absolute;
  inset: 0;
  z-index: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.6rem;
  color: rgba(255, 255, 255, 0.85);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.8);
  background: rgba(0, 0, 0, 0.18);
  border-radius: 6px;
  pointer-events: none;
}
.chat-jump {
  position: absolute;
  right: 1.4rem;
  bottom: 4.6rem;
  z-index: 5;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 50%;
  background: var(--acc2);
  border: 1px solid var(--acc);
  color: var(--ink);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);
}
.chat-jump:hover { background: var(--acc); }
.chat-jump[hidden] { display: none; }
.chat-compose { display: flex; gap: 0.6rem; margin-top: 0.8rem; align-items: center; }
.chat-compose input[name="body"] { flex: 1; }
.chat-attach { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; width: 2.2rem; height: 2.2rem; border-radius: 6px; border: 1px solid var(--line); background: transparent; padding: 0; color: var(--mut); cursor: pointer; }
.chat-attach:hover { color: var(--acc); border-color: var(--acc); }
.chat-attach-count { font-size: 0.75rem; color: var(--mut); margin-top: 0.4rem; }
.chat-attach-count[hidden] { display: none; }
.up-head { display: flex; gap: 0.5rem; margin-bottom: 0.7rem; }
.up-list { display: flex; flex-direction: column; gap: 0.5rem; max-height: 50vh; overflow-y: auto; margin: 0 0 0.5rem; }
.up-empty { margin: 0.5rem 0; }
.up-row { display: flex; align-items: center; gap: 0.6rem; }
.up-prev { flex: 0 0 auto; width: 2.5rem; height: 2.5rem; object-fit: contain; border-radius: 4px; background: rgba(0, 0, 0, 0.4); }
.up-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.2rem; }
.up-name { font-size: 0.75rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.up-bar { height: 4px; border-radius: 2px; background: rgba(255, 255, 255, 0.12); overflow: hidden; }
.up-bar i { display: block; height: 100%; width: 0; background: var(--acc); transition: width 0.15s ease; }
.up-pct { font-size: 0.7rem; color: var(--mut); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.up-row.error .up-bar i { background: var(--bad); }
.up-row.error .up-pct { color: var(--bad); }
.up-x { flex: 0 0 auto; background: none; border: 0; padding: 0; color: var(--mut); font-size: 1.1rem; line-height: 1; cursor: pointer; }
.up-x:hover { color: var(--acc); }
.up-err { color: var(--bad); font-size: 0.8rem; margin: 0.5rem 0 0; }
.chat-senderr { color: var(--bad); font-size: 0.8rem; margin: 0 0 0.4rem; }

/* Index rows: whole-row clickable, default-image cell left of the name */
.grid tr[data-href] { cursor: pointer; transition: box-shadow 0.15s ease, background-color 0.15s ease; }
.grid tr[data-href]:hover { box-shadow: 0 0 12px 1px rgba(217, 65, 58, 0.4); background-color: var(--panel); }
.grid tr[data-href]:active { box-shadow: 0 0 20px 3px rgba(217, 65, 58, 0.75); background-color: var(--panel2); }
/* Search tab: primary row + collapsible advanced filters */
.ss-search { display: block; }
.ss-search-primary { display: grid; grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr)); gap: 0.45rem 0.5rem; }
.ss-search-primary label { display: flex; flex-direction: column; gap: 0.15rem; font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--mut); }
.ss-search-primary input { width: 100%; box-sizing: border-box; }
/* Advanced filters: native details/summary expandable (settings-dropdown pattern) */
.ss-search-adv { margin: 0.5rem 0 0; overflow: hidden; }
.ss-search-adv summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.5rem 0.7rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--mut);
  cursor: pointer;
  list-style: none;
  user-select: none;
  transition: color 0.15s ease, background-color 0.15s ease;
}
.ss-search-adv summary::-webkit-details-marker { display: none; }
.ss-search-adv summary:hover,
.ss-search-adv summary:focus-visible { color: var(--ink); background-color: var(--panel2); outline: none; }
.ss-search-adv .chevron {
  flex-shrink: 0;
  width: 7px;
  height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform 0.2s ease;
}
.ss-search-adv[open] .chevron { transform: rotate(-135deg); }
.ss-search-adv .ss-search-fields { padding: 0.4rem 0.7rem 0.6rem; }
.ss-search-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr)); gap: 0.45rem 0.5rem; }
.ss-search-fields label { display: flex; flex-direction: column; gap: 0.15rem; font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--mut); }
.ss-search-fields input { width: 100%; box-sizing: border-box; }
.ss-search-actions { display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 0.6rem; }
@media (max-width: 640px) {
  .ss-search-primary { grid-template-columns: 1fr; }
  .ss-search-fields { grid-template-columns: 1fr; }
}
.grid td.rowimg { padding: 0.4em 0.6em; }
.grid td.rowimg img { width: 72px; height: 72px; object-fit: contain; border: 1px solid #4a0c0a; border-radius: 4px; display: block; background: var(--panel); }
@media (max-width: 640px) {
  .wlist tr:first-of-type { display: none; }
  .wlist tr[data-href] {
    display: grid;
    grid-template-columns: auto 1fr;
    /* 24px floor per track: with the spanning cell's padding zeroed below,
       its grid contribution is exactly the 72px image, so each track floors
       at 24px, the area equals the image height, the image fills the row
       without overflowing into neighbouring rows, and the stacked text —
       centred within its own track — stays inside the image's vertical
       extent by construction. */
    grid-template-rows: repeat(3, minmax(24px, auto));
    align-items: center;
    border-bottom: 1px solid var(--line);
  }
  .wlist tr[data-href] td { display: block; border-bottom: 0; }
  .wlist tr[data-href] td.rowimg { grid-column: 1; grid-row: 1 / span 3; padding: 0; }
  .wlist tr[data-href] td:not(.rowimg) {
    padding: 0.1em 0.6em;
    line-height: 1.05;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* Woman-page tabs + reduced type across the detail page */
.tabbar { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.5rem 0; }
.tabbar .btn { font-size: 0.72rem; padding: 0.25em 0.6em; }
.tabbar .btn.on { color: var(--acc); border-color: var(--acc); }
.wdetails-panel, .tabbar, [data-tabpanel] { font-size: 0.85rem; }
.wmedia-compose { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.8rem; }
/* Media-tab edit mode: the composer and per-item removal exist only while the panel is editing */
.wmedia-panel [data-wme] { display: inline-block; margin-bottom: 0.8rem; }
.wmedia-panel .wmedia-compose { display: none; }
.wmedia-panel.editing .wmedia-compose { display: flex; }
.wmedia-panel form[data-wme-remove] { display: none; }
.wmedia-panel.editing form[data-wme-remove] { display: inline-flex; }
.dflt.on { color: var(--acc); border-color: var(--acc); }
.wdefault { margin: 0 auto 0.9rem; text-align: center; }
.wdefault img { width: 240px; max-width: 100%; aspect-ratio: 1; object-fit: contain; border-radius: 6px; display: block; margin: 0 auto; background: var(--panel); }
.wdefault-frame { position: relative; display: inline-block; border: 1px solid #4a0c0a; }
.wdefault-pick { display: none; position: absolute; top: -0.45rem; right: -0.45rem; z-index: 2; width: 1.9rem; height: 1.9rem; padding: 0; border: 1px solid var(--line); border-radius: 50%; background: var(--panel); color: var(--mut); font-size: 0.95rem; line-height: 1; cursor: pointer; }
.wdefault-pick:hover { color: var(--acc); border-color: var(--acc); }
.wdetails-panel.editing .wdefault-pick { display: block; }
/* Woman detail: stacked fields at every breakpoint — the former mobile
   edit-mode treatment, promoted: small label top-left above a full-width
   value or input, in both view and edit modes. */
.winfo { display: block; width: 100%; margin: 0 0 0.9rem; }
.winfo tbody, .winfo tr, .winfo th, .winfo td { display: block; width: auto; }
/* text-align: left overrides the UA stylesheet's th centreing */
.winfo th { color: var(--mut); font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.08em; padding: 0.35em 0.6em 0.1em; text-align: left; }
.winfo td { padding: 0.1em 0.6em 0.35em; border-bottom: 1px solid var(--line); }
.winfo input.we { display: none; width: 100%; box-sizing: border-box; }
.wdetails-panel .winfo tr[data-unset] { display: none; }
.wdetails-panel.editing .winfo tr[data-unset] { display: block; }
.wdetails-panel.editing .winfo .wv { display: none; }
.wdetails-panel.editing .winfo input.we { display: block; }
/* Location split: composed view row vs the labeled edit rows */
.wdetails-panel .winfo tr.wloc-edit { display: none; }
.wdetails-panel.editing .winfo tr.wloc-edit { display: block; }
.wdetails-panel.editing .winfo tr.wloc-view { display: none; }
/* Detail name: top-left of the panel, reduced type */
.wdetails-name { font-size: 1.05rem; font-weight: 600; margin: 0 0 0.9rem; text-align: left; }
/* Handles: platform-tagged list; controls gated to the details panel's edit mode */
.whandles { margin: 0 0 0.9rem; border-top: 1px solid var(--line); padding-top: 0.8rem; }
.whandles-head h3 { font-size: 0.66rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; color: var(--mut); margin: 0 0 0.5rem; }
.whandle-list { display: flex; flex-direction: column; gap: 0.35rem; margin-bottom: 0.6rem; }
.whandle { display: flex; align-items: center; gap: 0.5rem; background: var(--panel2); border: 1px solid var(--line); border-radius: 6px; padding: 0.35rem 0.6rem; }
.whandle-id { flex: 1; min-width: 0; }
.whandle-plat { color: var(--mut); font-size: 0.72rem; }
.whandle-val { font-weight: 600; }
.whandle form.inline { margin: 0; }
.whandle .whandle-editform { display: none; }
.whandle.editing .whandle-id, .whandle.editing [data-hedit], .whandle.editing [data-hcopy] { display: none; }
.whandle.editing .whandle-editform { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; flex: 1; min-width: 0; }
.whandle-editform select, .whandle-editform input[type=text] { font-size: 0.8rem; }
.whandle-add { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; }
.whandle-add select, .whandle-add input[type=text] { font-size: 0.8rem; }
.whandle-add input[type=text] { width: 14rem; max-width: 100%; }
/* View mode lists handles read-only; controls appear only while the panel is in edit mode */
.whandle [data-hedit], .whandle form[data-confirm] { display: none; }
.wdetails-panel .whandle-add { display: none; }
.wdetails-panel.editing .whandle [data-hedit] { display: inline-block; }
.wdetails-panel.editing .whandle [data-hcopy] { display: none; }
.wdetails-panel.editing .whandle form[data-confirm] { display: inline; }
.wdetails-panel.editing .whandle-add { display: flex; }
/* Tabs hidden while the details panel is in edit mode */
.wdetails-panel.editing ~ .tabbar { display: none; }
.wdetails-panel.editing ~ [data-tabpanel] { display: none; }

/* Woman-page comments */
.wcomment-compose { display: flex; gap: 0.5rem; margin-bottom: 0.9rem; }
.wcomment-compose input { flex: 1; }
.wcomments { display: flex; flex-direction: column; gap: 0.7rem; }
.wcomment { background: var(--panel2); border: 1px solid var(--line); border-radius: 6px; padding: 0.6rem 0.9rem; }
.wcomment-user { font-weight: 700; color: var(--acc); font-size: 0.85rem; }
.wcomment-when { font-size: 0.72rem; margin-left: 0.5rem; }
.wcomment-body { margin: 0.3rem 0 0; overflow-wrap: break-word; }

/* Chat lightbox — full-size popup for chat attachments (mavora.net pattern) */
.chat-lightbox {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  background: rgba(0, 0, 0, 0.85);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
.chat-lightbox[hidden] { display: none; }
.chat-lightbox-topbar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 16px;
  background: rgba(26, 26, 35, 0.94);
  border-bottom: 1px solid var(--line);
}
.chat-lightbox-count { color: var(--mut); font-size: 0.85rem; white-space: nowrap; }
.chat-lightbox-close {
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.chat-lightbox-close:hover { background: var(--acc); border-color: var(--acc); }
.chat-lightbox-body {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px 76px;
  overflow: hidden;
}
.chat-lightbox-stage {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  max-width: 100%;
  max-height: 100%;
  min-width: 240px;
  min-height: 160px;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 4px;
  box-shadow: 0 0 40px 6px rgba(0, 0, 0, 0.6);
}
.chat-lightbox-stage img,
.chat-lightbox-stage video {
  max-width: 100%;
  max-height: calc(100vh - 120px);
  object-fit: contain;
  display: block;
  background: #000;
}
/* Load transformation: once the stage is explicitly sized, the blurred
   thumbnail and the full file both fill the box edge-to-edge; the loaded
   state flips the swap. */
.chat-lightbox-stage.sized { min-width: 0; min-height: 0; }
.chat-lightbox-stage .chat-lightbox-thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: cover;
  filter: blur(3px);
  transform: scale(1.03);
  background: #000;
}
.chat-lightbox-stage .chat-lightbox-full {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  object-fit: contain;
  display: none;
  background: #000;
}
.chat-lightbox-stage.loaded .chat-lightbox-full { display: block; }
.chat-lightbox-stage.loaded .chat-lightbox-thumb { display: none; }
.chat-lightbox-spinner {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  width: 42px;
  height: 42px;
  border: 3px solid rgba(255, 255, 255, 0.2);
  border-top-color: var(--acc);
  border-radius: 50%;
  animation: chat-lb-spin 0.8s linear infinite;
}
@keyframes chat-lb-spin { to { transform: rotate(360deg); } }
.chat-lightbox-nav {
  position: absolute;
  top: 20px;
  bottom: 20px;
  width: 52px;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.chat-lightbox-nav-prev { left: 16px; }
.chat-lightbox-nav-next { right: 16px; }
.chat-lightbox-nav:hover:not(:disabled) { background: var(--acc); border-color: var(--acc); }
.chat-lightbox-nav:disabled { opacity: 0.3; cursor: not-allowed; }
/* Mobile: no side bars (swipe to navigate); tighter body padding */
@media (max-width: 640px) {
  .chat-lightbox-nav { display: none; }
  .chat-lightbox-body { padding: 12px; }
}

/* Popup modals */
.modal { position: fixed; inset: 0; z-index: 50; display: flex; align-items: center; justify-content: center; background: rgba(0, 0, 0, 0.72); padding: 1rem; }
.modal[hidden] { display: none; }
.modal-card { position: relative; background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 1.4rem; width: 100%; max-width: 480px; max-height: 90vh; overflow-y: auto; }
.modal-card h2 { margin-top: 0; }
.modal-x { position: absolute; top: 0.5rem; right: 0.7rem; background: none; border: none; color: var(--mut); font-size: 1.3rem; line-height: 1; cursor: pointer; }
.modal-x:hover { color: var(--ink); }
#invites-modal .btn { font-size: 0.72rem; padding: 0.25em 0.6em; }
#invites-modal code.mono { font-size: 0.78rem; }
#invites-modal .mut { font-size: 0.78rem; }

/* Directory header row: title left, Add right */
.idxhead { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 0.6rem; }
.idxhead h1 { margin: 0; }
