/* ============================================================================
   12 · PICKERS & ENHANCED INPUTS

   Shared searchable combobox (`js/combo.js` — Giveaways' role/channel/member
   pickers and Auto Moderation's Trusted-roles / ignored-channels exception
   pickers, the `.ga-*` rules), the channel picker Existing|New
   fork (`cn-*`), the global custom select (`cs-*`), the date/time picker and
   the shared emoji picker.

   Part of the dashboard stylesheet, split out of the former single style.css.
   LOAD ORDER IS LOAD-BEARING (later parts intentionally override earlier
   ones) — the canonical order is dashboard/views/partials/_app_styles.ejs.
   ========================================================================== */

/* ===== GIVEAWAY COMBOBOX / MEMBER TOKEN PICKER ===== */
/* Multi-select "bar": chips + an inline search input, styled to read as one field. */
.ga-tokenbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  width: 100%;
  min-height: 42px;
  padding: 0.3rem 0.45rem;
  background: var(--bg-sidebar);
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: text;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.ga-tokenbar:focus-within {
  border-color: var(--blue);
  box-shadow: var(--ring-blue);
}
.ga-tokenbar-input {
  flex: 1 1 120px;
  min-width: 120px;
  border: none;
  outline: none;
  background: transparent;
  color: var(--text);
  font-size: 0.875rem;
  font-family: var(--font);
  padding: 0.2rem 0.15rem;
}
.ga-tokenbar-input::placeholder { color: var(--text-muted); }

/* Selected-member chip */
.ga-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  max-width: 100%;
  padding: 0.22rem 0.25rem 0.22rem 0.55rem;
  background: rgba(var(--blue-rgb), 0.16);
  border: 1px solid rgba(var(--blue-rgb), 0.4);
  border-radius: 999px;
  font-size: 0.8125rem;
  color: var(--text);
  line-height: 1.2;
}
.ga-chip-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 220px;
}
.ga-chip-x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border: none;
  border-radius: 50%;
  background: rgba(var(--blue-rgb), 0.25);
  color: var(--text);
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
  flex-shrink: 0;
  transition: background 0.15s ease;
}
.ga-chip-x:hover { background: var(--red); color: #fff; }

/* Single-select combo clear (×) button — e.g. the giveaway channel picker */
.ga-combo-clear {
  position: absolute;
  top: 0;
  right: 0;
  height: 100%;
  width: 2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--text-muted);
  font-size: 1.15rem;
  line-height: 1;
  cursor: pointer;
  transition: color 0.15s ease;
}
.ga-combo-clear:hover { color: var(--red); }

/* Dropdown menu (shared by single + multi combos) */
.ga-combo-menu {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  z-index: 60;
  margin-top: 4px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  max-height: 240px;
  overflow-y: auto;
  display: none;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
}
.ga-combo-empty {
  padding: 0.6rem 0.7rem;
  color: var(--text-muted);
  font-size: 0.8125rem;
}
.ga-combo-row {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.45rem 0.7rem;
  cursor: pointer;
  font-size: 0.8125rem;
  color: var(--text);
}
.ga-combo-row:hover { background: var(--surface-hover); }
.ga-combo-avatar { border-radius: 50%; flex-shrink: 0; }
.ga-combo-roledot {
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 50%;
  flex-shrink: 0;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25);
}
.ga-combo-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ===== CHANNEL PICKER — EXISTING | NEW FORK =====
   js/channelCreate.js forks every opted-in channel <select> (data-channel-new) into
   a two-segment mode control over two panes: the picker itself, and an inline create
   row. Mirrors the Reaction Roles panel modal's setup-method fork.
   `.cn-field` TAKES OVER the picker's layout box (the JS moves the inline
   width/flex/grid props onto it), so it must behave like the select did: full-width
   by default, with the picker filling it. */
.cn-field { display: block; width: 100%; min-width: 0; }
.cn-field [hidden] { display: none !important; }

/* The fork. Deliberately small — it sits above 27 pickers, including the Logging
   page's dense event-card grid, so it must read as a control and not as a toolbar. */
.cn-mode {
  display: inline-flex;
  gap: 2px;
  margin-bottom: 0.3rem;
  padding: 2px;
  border: 1px solid var(--border);
  border-radius: 0.5rem;
  background: rgba(255, 255, 255, 0.02);
}
.cn-mode[hidden] { display: none; }
.cn-mode-btn {
  padding: 0.15rem 0.55rem;
  border: none;
  border-radius: 0.375rem;
  background: transparent;
  color: var(--text-muted);
  font-size: 0.7rem;
  font-weight: 600;
  line-height: 1.5;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.cn-mode-btn:hover:not(.is-on) { color: var(--text); background: rgba(255, 255, 255, 0.04); }
.cn-mode-btn.is-on { background: var(--crimson); color: #fff; }
.cn-mode-btn:focus-visible { outline: none; box-shadow: var(--ring-blue); }

.cn-pick { min-width: 0; }

/* The create row. Wraps on narrow layouts so a grid cell or a modal column never
   pushes the Create button out of reach. */
.cn-make-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  min-width: 0;
}
.cn-make-name { flex: 1 1 9rem; min-width: 0; }
/* `.cn-make-catwrap` is what gets hidden when a category is being created (a category
   cannot be filed under a category) — select-enhance builds its dropdown as a SIBLING
   of the <select>, so hiding the select alone would leave that dropdown standing. */
.cn-make-catwrap { flex: 0 1 10rem; min-width: 0; display: block; }
.cn-make-typewrap { flex: 0 1 7rem; min-width: 0; display: block; }
.cn-make-go { flex: 0 0 auto; white-space: nowrap; }

/* The shared Access panel (js/channelPerms.js) sitting under the create row. It is shown
   inline rather than behind a disclosure ON PURPOSE: a new channel is read-only until the
   administrator says otherwise, and a default that surprising has to be visible BEFORE
   Create is pressed. Its own `cap-*` rules come from channelPerms.js. */
.cn-make-access { margin-top: 0.55rem; padding-top: 0.55rem; border-top: 1px solid var(--border); }

.cn-make-status { font-size: 0.75rem; margin-top: 0.3rem; min-height: 1em; color: var(--text-muted); }
.cn-make-status[data-tone="bad"] { color: var(--red); }
.cn-make-status[data-tone="good"] { color: var(--green); }
.cn-make-status:empty { display: none; }

/* ===== CUSTOM SELECT (global native <select> enhancement) =====
   Replaces the OS-rendered <select> popup with an on-brand dark dropdown that
   mirrors the searchable channel combo above. Built by js/select-enhance.js,
   which keeps the real <select> in the DOM (visually hidden) as the value source. */
.cs-wrap { position: relative; display: block; width: 100%; }
.cs-native {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; opacity: 0; pointer-events: none;
}
.cs-trigger {
  display: flex; align-items: center; gap: 0.5rem; width: 100%;
  padding: 0.625rem 0.875rem; border-radius: 0.75rem;
  background: rgba(255,255,255,.035); border: 1px solid var(--border);
  color: var(--text-primary); font-size: 0.875rem; font-family: inherit;
  text-align: left; cursor: pointer; outline: none;
  transition: border-color .15s, box-shadow .15s, background .15s;
}
.cs-trigger:hover:not(:focus):not(:disabled) { border-color: var(--border-strong); }
.cs-trigger:focus, .cs-open > .cs-trigger {
  border-color: var(--crimson);
  box-shadow: 0 0 0 3px rgba(var(--blue-rgb),0.16);
  background: rgba(220,38,38,.04);
}
.cs-trigger:disabled { opacity: .55; cursor: not-allowed; }
.cs-value { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cs-value-empty { color: var(--text-muted); }
/* Opt-in per-option icon (select-enhance.js makeIcon) — channel-type glyphs etc. The
   holder collapses when empty so the trigger keeps no stray gap for an icon-less value. */
.cs-value-icon { display: inline-flex; flex-shrink: 0; }
.cs-value-icon:empty { display: none; }
.cs-icon {
  flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
  width: 1.05rem; height: 1.05rem; font-size: 1.05rem; color: var(--text-muted);
}
.cs-icon-hash { font-weight: 700; font-size: 0.98rem; line-height: 1; }
.cs-option.cs-selected .cs-icon { color: var(--text-primary); }
.cs-arrow {
  flex-shrink: 0; width: 1rem; height: 1rem;
  background: no-repeat center / contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23949BA4' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  transition: transform .18s;
}
.cs-open .cs-arrow { transform: rotate(180deg); }
.cs-menu {
  position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 70;
  background: var(--surface); border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 12px 30px rgba(0,0,0,0.5); overflow: hidden;
  animation: csIn .12s ease;
}
/* While open, select-enhance.js portals the menu to <body> and sets left/top/width from
   the trigger's measured rect — as a child of .cs-wrap it was clipped away by any
   ancestor that scrolled or hid overflow (the welcome designer's properties panel, a
   modal body). Fixed rather than absolute so it ignores page scroll the same way the
   measurement did; above `.modal-overlay` (9000) AND above the components.js dialog shell
   (9999) — a dialog hosts pickers too (selectModal's channel picker, the channel creator's
   category picker), and at 9500 an enhanced menu opened BEHIND the dialog that owned it,
   which is why those selects had to stay native and unsearchable. Still below
   `.tooltip-portal` (100000), which explains a control and must sit over it. */
.cs-menu.cs-portal { position: fixed; z-index: 10050; }
@keyframes csIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
/* An upward menu should rise into place, not drop into it. */
.cs-menu.cs-up { animation-name: csInUp; }
@keyframes csInUp { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.cs-search { padding: 0.5rem; border-bottom: 1px solid var(--border); }
.cs-search-input {
  width: 100%; padding: 0.45rem 0.6rem; border-radius: 7px;
  background: rgba(255,255,255,.04); border: 1px solid var(--border);
  color: var(--text-primary); font-size: 0.8125rem; outline: none;
}
.cs-search-input:focus { border-color: var(--crimson); }
.cs-options { max-height: 240px; overflow-y: auto; padding: 0.25rem; }
.cs-group {
  padding: 0.5rem 0.6rem 0.25rem; font-size: 0.68rem; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; color: var(--text-muted);
}
.cs-option {
  display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0.6rem;
  border-radius: 7px; cursor: pointer; font-size: 0.8125rem; color: var(--text);
}
.cs-option-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The option's id (channel/role/user), carried on every row and revealed only while a
   numeric query is being typed — see filter() in select-enhance.js. Shown always it would
   be nineteen digits of noise beside every channel name; shown then, it is what explains a
   match the label does not contain and lets a pasted id be checked. */
.cs-option-id {
  display: none; flex-shrink: 0; margin-left: 0.4rem;
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 0.6875rem; color: var(--text-muted); letter-spacing: -0.01em;
}
.cs-menu.cs-show-ids .cs-option-id { display: inline; }
.cs-option:hover, .cs-option.cs-active { background: var(--surface-hover); }
.cs-option.cs-selected .cs-option-label { font-weight: 600; color: var(--text-primary); }
.cs-option.cs-selected::after { content: "✓"; margin-left: auto; color: var(--crimson-glow, var(--crimson)); font-weight: 700; flex-shrink: 0; }
.cs-option-disabled { opacity: .4; cursor: not-allowed; pointer-events: none; }
.cs-empty { padding: 0.6rem 0.7rem; color: var(--text-muted); font-size: 0.8125rem; }

/* ===== CUSTOM DATE / TIME PICKER (datetime-enhance.js) =====
   Replaces the unstyleable native datetime-local / date popup with an on-brand
   glass calendar + time selector. The native <input> stays as .dt-native (the
   hidden value source); the .dt-trigger reuses the field's own classes so it
   reads as one of the app's glass inputs. */
.dt-wrap { position: relative; display: block; width: 100%; }
.dt-native {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; opacity: 0; pointer-events: none;
}
.dt-trigger {
  display: flex; align-items: center; gap: 0.5rem; width: 100%;
  text-align: left; cursor: pointer; font-family: inherit;
}
.dt-trigger:hover:not(:disabled) { border-color: var(--border-strong); }
.dt-open > .dt-trigger, .dt-trigger:focus-visible {
  border-color: var(--crimson);
  box-shadow: 0 0 0 3px rgba(var(--blue-rgb),0.16);
  background: rgba(220,38,38,.04);
}
.dt-trigger:disabled { opacity: .55; cursor: not-allowed; }
.dt-value { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dt-value-empty { color: var(--text-muted); }
.dt-icon {
  flex-shrink: 0; width: 1.05rem; height: 1.05rem; opacity: .7; transition: opacity .15s, color .15s;
  background: no-repeat center / contain currentColor;
  -webkit-mask: no-repeat center / contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2'/%3E%3Cline x1='16' y1='2' x2='16' y2='6'/%3E%3Cline x1='8' y1='2' x2='8' y2='6'/%3E%3Cline x1='3' y1='10' x2='21' y2='10'/%3E%3C/svg%3E");
  mask: no-repeat center / contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2'/%3E%3Cline x1='16' y1='2' x2='16' y2='6'/%3E%3Cline x1='8' y1='2' x2='8' y2='6'/%3E%3Cline x1='3' y1='10' x2='21' y2='10'/%3E%3C/svg%3E");
  color: var(--text-secondary);
}
.dt-open .dt-icon, .dt-trigger:hover .dt-icon { opacity: 1; color: var(--crimson-glow); }

/* Popup — layered glass panel */
.dt-menu {
  position: absolute; left: 0; top: calc(100% + 8px); z-index: 80;
  background: linear-gradient(180deg, rgba(26,32,42,.98), rgba(17,22,32,.98));
  -webkit-backdrop-filter: blur(20px) saturate(150%); backdrop-filter: blur(20px) saturate(150%);
  border: 1px solid var(--border-strong); border-radius: 16px;
  box-shadow: 0 24px 60px rgba(0,0,0,.55), 0 2px 0 rgba(255,255,255,.04) inset;
  padding: 0.85rem; min-width: 17rem;
  animation: dtIn .16s var(--ease);
  transform-origin: top center;
}
.dt-wrap.dt-up .dt-menu { top: auto; bottom: calc(100% + 8px); transform-origin: bottom center; }
.dt-wrap.dt-right .dt-menu { left: auto; right: 0; }
@keyframes dtIn { from { opacity: 0; transform: translateY(-6px) scale(.98); } to { opacity: 1; transform: none; } }

.dt-panels { display: flex; gap: 0.85rem; align-items: stretch; }

/* Calendar */
.dt-cal { width: 15.5rem; }
.dt-cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.6rem; }
.dt-cal-title { font-family: var(--font-display); font-weight: 700; font-size: 0.9rem; color: var(--text-primary); letter-spacing: .01em; }
.dt-nav {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.9rem; height: 1.9rem; border-radius: 9px;
  background: rgba(255,255,255,.04); border: 1px solid var(--border);
  color: var(--text-secondary); cursor: pointer;
  transition: background .15s, color .15s, border-color .15s, transform .12s;
}
.dt-nav:hover { background: var(--surface-hover); color: var(--text-primary); border-color: var(--border-strong); }
.dt-nav:active { transform: scale(.92); }
.dt-week {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; margin-bottom: 4px;
}
.dt-week span {
  text-align: center; font-size: 0.64rem; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-muted); padding: 0.15rem 0;
}
.dt-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; animation: dtFade .18s var(--ease); }
@keyframes dtFade { from { opacity: 0; } to { opacity: 1; } }
.dt-day {
  aspect-ratio: 1 / 1; display: flex; align-items: center; justify-content: center;
  border: 1px solid transparent; border-radius: 9px; background: transparent;
  color: var(--text); font-size: 0.8rem; font-weight: 500; cursor: pointer;
  transition: background .13s var(--ease), color .13s, transform .1s, box-shadow .13s;
}
.dt-day:hover { background: var(--surface-hover); transform: translateY(-1px); }
.dt-day-out { color: var(--text-muted); opacity: .45; }
.dt-today:not(.dt-selected) { border-color: rgba(var(--green-rgb),.5); color: var(--pistachio-light); }
.dt-selected {
  background: linear-gradient(135deg, var(--crimson), var(--crimson-dark));
  color: #fff; font-weight: 700; border-color: transparent;
  box-shadow: 0 4px 14px rgba(var(--blue-rgb),.45);
}
.dt-selected:hover { background: linear-gradient(135deg, var(--crimson-glow), var(--crimson)); transform: translateY(-1px); }
.dt-disabled { color: var(--text-muted); opacity: .22; cursor: not-allowed; pointer-events: none; }

/* Time columns */
.dt-time { width: 8.5rem; display: flex; flex-direction: column; border-left: 1px solid var(--border); padding-left: 0.85rem; }
.dt-time-head { display: flex; gap: 0.4rem; margin-bottom: 0.5rem; }
.dt-time-head span {
  flex: 1; text-align: center; font-size: 0.64rem; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-muted);
}
.dt-cols { display: flex; gap: 0.4rem; flex: 1; min-height: 0; }
.dt-col {
  position: relative;
  flex: 1; overflow-y: auto; max-height: 15rem; display: flex; flex-direction: column; gap: 3px;
  padding-right: 3px; scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent;
}
.dt-col::-webkit-scrollbar { width: 6px; }
.dt-col::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 3px; }
.dt-col::-webkit-scrollbar-track { background: transparent; }
.dt-tcell {
  flex: 0 0 auto; padding: 0.4rem 0; border-radius: 8px; border: 1px solid transparent;
  background: rgba(255,255,255,.03); color: var(--text-secondary);
  font-family: var(--font-mono); font-size: 0.8rem; text-align: center; cursor: pointer;
  transition: background .13s, color .13s, border-color .13s;
}
.dt-tcell:hover { background: var(--surface-hover); color: var(--text-primary); }
.dt-tcell-sel {
  background: linear-gradient(135deg, var(--crimson), var(--crimson-dark));
  color: #fff; font-weight: 700; border-color: transparent;
  box-shadow: 0 3px 10px rgba(var(--blue-rgb),.4);
}

/* Footer */
.dt-foot { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.85rem; padding-top: 0.7rem; border-top: 1px solid var(--border); }
.dt-foot-gap { flex: 1; }
.dt-btn {
  padding: 0.4rem 0.85rem; border-radius: 9px; font-size: 0.8rem; font-weight: 600;
  cursor: pointer; border: 1px solid var(--border); font-family: inherit;
  transition: background .15s, color .15s, border-color .15s, box-shadow .15s, transform .1s;
}
.dt-btn:active { transform: scale(.96); }
.dt-btn-ghost { background: transparent; color: var(--text-secondary); }
.dt-btn-ghost:hover { background: var(--surface-hover); color: var(--text-primary); border-color: var(--border-strong); }
.dt-btn-primary {
  background: linear-gradient(135deg, var(--crimson), var(--crimson-dark)); color: #fff; border-color: transparent;
  box-shadow: 0 4px 14px rgba(var(--blue-rgb),.4);
}
.dt-btn-primary:hover { background: linear-gradient(135deg, var(--crimson-glow), var(--crimson)); box-shadow: 0 6px 18px rgba(var(--blue-rgb),.5); }

@media (max-width: 520px) {
  .dt-panels { flex-direction: column; }
  .dt-time { width: auto; border-left: 0; padding-left: 0; border-top: 1px solid var(--border); padding-top: 0.7rem; }
  .dt-cols { max-height: 9rem; }
  .dt-col { max-height: 9rem; flex-direction: row; flex-wrap: wrap; }
}

/* ===== SHARED EMOJI PICKER (giveaways + reaction roles + tickets) ===== */

/* A text input with the picker trigger sitting beside it. The tickets editors show
   BOTH — the box so a stored `<:name:id>` stays visible and pasteable, the trigger
   so nobody has to know that syntax in the first place. The picker mounts itself
   `afterend` of the input, so this only has to lay the two out on one line. */
.tk-emoji-field { display: flex; align-items: center; gap: 0.4rem; }
.tk-emoji-field > .input { flex: 1; min-width: 0; }

.emoji-trigger {
  width: 2.5rem;
  height: 2.375rem;
  padding: 0;
  font-size: 1.125rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  background: var(--bg-sidebar);
  border-radius: 0.5rem;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.emoji-trigger:hover { border-color: var(--blurple); background: var(--surface-hover); }
.emoji-trigger img { width: 1.375rem; height: 1.375rem; object-fit: contain; }

/* Portalled to <body> so it escapes the giveaway panel's backdrop-filter/3D
   layer; its own frosted glass matches the app's modals. */
.emoji-popup {
  width: 288px;
  background: var(--glass-strong);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  backdrop-filter: blur(20px) saturate(140%);
  border: 1px solid var(--border-strong);
  border-radius: 14px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(var(--blue-rgb), 0.06);
  overflow: hidden;
}
.emoji-popup-tabs {
  display: flex;
  gap: 2px;
  padding: 6px;
  border-bottom: 1px solid var(--border);
  background: rgba(0, 0, 0, 0.18);
}
.emoji-popup-tab {
  flex: 1;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  border: none;
  background: none;
  border-radius: 8px;
  cursor: pointer;
  opacity: 0.65;
  filter: grayscale(35%);
  transition: background 0.12s, opacity 0.12s, filter 0.12s;
}
.emoji-popup-tab:hover { background: var(--surface-hover); opacity: 1; filter: none; }
.emoji-popup-tab.active {
  background: var(--blurple);
  opacity: 1;
  filter: none;
  box-shadow: 0 2px 10px rgba(var(--blue-rgb), 0.4);
}
.emoji-popup-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
  padding: 8px;
  max-height: 204px;
  overflow-y: auto;
}
.emoji-popup-grid button {
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.15rem;
  line-height: 1;
  border: none;
  background: none;
  border-radius: 8px;
  cursor: pointer;
  padding: 0;
  transition: background 0.1s, transform 0.1s;
}
.emoji-popup-grid button:hover { background: var(--surface-hover); transform: scale(1.12); }
.emoji-popup-grid img { width: 1.4rem; height: 1.4rem; object-fit: contain; }
.emoji-popup-grid::-webkit-scrollbar { width: 8px; }
.emoji-popup-grid::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 4px; }
.emoji-popup-grid::-webkit-scrollbar-thumb:hover { background: rgba(var(--blue-rgb), 0.5); }
.emoji-popup-grid::-webkit-scrollbar-track { background: transparent; }

/* Icon picker variant — giveaway entry-method button icons */
.emoji-icon-picker {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  border: 1px solid var(--border);
  background: var(--bg-sidebar);
  border-radius: 0.5rem;
  padding: 0.3rem 0.55rem 0.3rem 0.35rem;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
  min-height: 2.625rem;
}
.emoji-icon-picker:hover {
  border-color: var(--border-strong);
  background: var(--surface-hover);
}
/* The trigger inside the row blends in — the row is the visible affordance */
.emoji-icon-picker .emoji-trigger {
  width: 2.1rem;
  height: 2.1rem;
  font-size: 1.25rem;
  border: none;
  background: none;
  border-radius: 0.35rem;
  flex-shrink: 0;
  pointer-events: none;   /* row's click handler delegates to trigger via .click() */
}
.emoji-icon-picker .emoji-trigger:hover { border: none; background: none; }
.eip-status {
  font-size: 0.8125rem;
  color: var(--text-muted);
  font-style: italic;
  flex: 1;
  line-height: 1.2;
  user-select: none;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.eip-status.eip-custom {
  color: var(--text);
  font-style: normal;
  font-weight: 500;
}
.eip-clear {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.4rem;
  height: 1.4rem;
  padding: 0;
  font-size: 1rem;
  color: var(--text-muted);
  background: none;
  border: none;
  cursor: pointer;
  border-radius: 50%;
  flex-shrink: 0;
  transition: color 0.12s, background 0.12s;
}
.eip-clear:hover { color: var(--red); background: rgba(var(--red-rgb), 0.12); }
.eip-chevron {
  font-size: 0.8rem;
  color: var(--text-muted);
  opacity: 0.6;
  flex-shrink: 0;
  pointer-events: none;
}
