/* Gala section — ticket board + research panel.
 *
 * Lives under Internal, so it follows the dashboard's own language (blue
 * palette, glossy crystal, red reserved for errors) rather than Apollo's
 * gold-on-black, which is scoped to the Apollo view alone.
 *
 * Every status colour here is a blue step or a neutral. Nothing is amber or
 * green. "Blocked" is the only red, because blocked is an error state.
 */

#view-gala {
  /* Apollo's own accent. This section sits inside the Apollo dashboard, so it
     borrows the dashboard's gold rather than introducing a second accent. */
  --gold: #c8a54a;
  --gold-bright: #e6c977;
  --gold-deep: #a8862f;
  --gold-line: rgba(200, 165, 74, 0.28);
  --gold-wash: rgba(200, 165, 74, 0.12);
  --gala-gap: 14px;
  --gala-card-radius: 10px;
  /* Dense dashboard scale: 8 / 12 / 16 / 24 / 32. */
  --gala-s1: 8px;
  --gala-s2: 12px;
  --gala-s3: 16px;
  --gala-s4: 24px;
}

/* ------------------------------------------------------------- status bar -- */

.gala-status {
  display: flex;
  align-items: center;
  gap: var(--gala-s2);
  flex-wrap: wrap;
  padding: var(--gala-s2) var(--gala-s3);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-subtle);
  margin-bottom: var(--gala-s3);
}

.gala-status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: none;
  background: #94a3b8;
}
.gala-status.is-live .gala-status-dot { background: #2563eb; }
.gala-status.is-down .gala-status-dot { background: var(--danger); }

.gala-status-text { font-size: 13px; color: var(--text); font-weight: 600; }
.gala-status-sub { font-size: 12px; color: var(--muted); }
.gala-status-spacer { flex: 1 1 auto; }

.gala-btn {
  appearance: none;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  /* 44px min touch target: 10px padding + 13px text + border clears it with
     the 24px line box below. */
  padding: 10px 14px;
  min-height: 44px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.gala-btn:hover { background: var(--bg-subtle); border-color: var(--blue-400); }
.gala-btn:focus-visible { outline: 2px solid #2563eb; outline-offset: 2px; }
.gala-btn[disabled] { opacity: 0.5; cursor: not-allowed; }
/* Gold glass, matching the dock and the header button. The lit top edge is in
   pale gold rather than white: a white rim on a gold bead reads as plastic. */
.gala-btn-primary {
  background: linear-gradient(180deg, #e6c977 0%, #c8a54a 55%, #a8862f 100%);
  border-color: #a8862f;
  color: #1a1408;
  font-weight: 600;
  box-shadow: inset 0 1px 0 rgba(255, 240, 200, 0.55), 0 1px 2px rgba(0, 0, 0, 0.3);
}
.gala-btn-primary:hover {
  background: linear-gradient(180deg, #f0d68e 0%, #d4b25c 55%, #b8933a 100%);
  border-color: #c8a54a;
}
.gala-btn-primary:focus-visible { outline-color: #e6c977; }

/* The secondary sits beside it, so it echoes the gold without competing. */
.gala-actions .gala-btn:not(.gala-btn-primary) {
  border-color: var(--gold-line);
  color: var(--gold);
  background: transparent;
  text-decoration: none;
}
.gala-actions .gala-btn:not(.gala-btn-primary):hover {
  background: var(--gold-wash);
  border-color: var(--gold);
  color: var(--gold-bright);
}

/* ------------------------------------------------------------ two columns -- */

/* Holds the panel and gives it something to be absolute against. Carries no
   height of its own, so the grid row is sized by the board. */
.gala-panel-slot { position: relative; min-height: 0; }

.gala-layout {
  display: grid;
  /* The board is a flex row of fixed 250px columns, so a fractional track left a
     band of dead space between the last column and the panel. fit-content lets
     the board take exactly what its columns need, capped so a long pipeline
     scrolls sideways instead of squeezing the panel out. The panel then starts
     immediately after the last column and takes everything remaining. */
  grid-template-columns: fit-content(62%) minmax(340px, 1fr);
  gap: var(--gala-s3);
  align-items: stretch;
}
@media (max-width: 1100px) {
  .gala-layout { grid-template-columns: minmax(0, 1fr); }
  /* Stacked, there is no board beside it to borrow a height from, so the panel
     goes back into normal flow and grows with its content. */
  .gala-panel-slot { position: static; }
  .gala-panel { position: static; max-height: none; }
}

/* ------------------------------------------------------------------ board -- */

.gala-board {
  display: flex;
  gap: var(--gala-s2);
  overflow-x: auto;
  padding-bottom: var(--gala-s1);
  /* Auto-hide, per house rule. .is-scrolling is added by JS. */
  scrollbar-width: thin;
  scrollbar-color: transparent transparent;
}
.gala-board::-webkit-scrollbar { height: 8px; }
.gala-board::-webkit-scrollbar-track { background: transparent; }
.gala-board::-webkit-scrollbar-thumb { background: transparent; border-radius: 4px; }
.gala-board.is-scrolling { scrollbar-color: #cbd5e1 transparent; }
.gala-board.is-scrolling::-webkit-scrollbar-thumb { background: #cbd5e1; }
html.theme-dark .gala-board.is-scrolling { scrollbar-color: #1a1a1a transparent; }
html.theme-dark .gala-board.is-scrolling::-webkit-scrollbar-thumb { background: #1a1a1a; }

.gala-col {
  flex: 0 0 250px;
  min-width: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-subtle);
  padding: var(--gala-s2);
}
.gala-col-head {
  display: flex;
  align-items: center;
  gap: var(--gala-s1);
  margin-bottom: var(--gala-s2);
}
.gala-col-name {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.gala-col-count {
  font-size: 11px;
  font-weight: 700;
  color: var(--muted);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 1px 7px;
  flex: none;
}
.gala-col-body { display: flex; flex-direction: column; gap: var(--gala-s1); }
.gala-col-empty { font-size: 12px; color: var(--muted); padding: var(--gala-s2) 0; }

/* ------------------------------------------------------------------- card -- */

.gala-card {
  width: 100%;
  text-align: left;
  appearance: none;
  font: inherit;
  border: 1px solid var(--border);
  border-radius: var(--gala-card-radius);
  background: var(--bg);
  padding: var(--gala-s2);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 6px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.gala-card:hover { border-color: var(--gold-line); box-shadow: var(--shadow); }
.gala-card:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.gala-card.is-active {
  border-color: var(--gold);
  box-shadow: 0 0 0 1px var(--gold) inset, var(--shadow);
}

.gala-card-title {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--text);
  /* Two lines then ellipsis: keeps every card the same scan height. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.gala-card-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  font-size: 11px;
  color: var(--muted);
}

.gala-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  font-weight: 600;
  border-radius: 999px;
  padding: 2px 8px;
  border: 1px solid var(--border);
  background: var(--bg-subtle);
  color: var(--muted);
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.gala-chip-client { border-color: var(--gold-line); background: var(--gold-wash); color: var(--gold); }
.gala-chip-unmatched { border-color: var(--border); background: var(--bg-subtle); color: var(--muted); }
.gala-chip-urgent { border-color: #fecaca; background: #fef2f2; color: #b91c1c; }

html.theme-dark .gala-chip-client { border-color: var(--gold-line); background: var(--gold-wash); color: var(--gold-bright); }
html.theme-dark .gala-chip-urgent { border-color: #7f1d1d; background: rgba(239, 68, 68, 0.14); color: #fca5a5; }

/* Research state pip on the card. Shape carries the meaning as well as the
   colour, so it does not rely on colour alone. */
.gala-pip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
}
.gala-pip::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #cbd5e1;
  flex: none;
}
/* Every state is gold now, so the SHAPE has to carry the meaning on its own:
   filled circle = ready, hollow ring = needs a call, square = blocked. Blocked
   also runs brighter and bolder, because it is the one that needs to be found
   in a full column. */
.gala-pip.is-ready { color: var(--gold); }
.gala-pip.is-ready::before { background: var(--gold); }
.gala-pip.is-running::before {
  background: var(--gold-bright);
  animation: gala-pulse 1.4s ease-in-out infinite;
}
.gala-pip.is-blocked { color: var(--gold-bright); font-weight: 700; }
.gala-pip.is-blocked::before {
  background: var(--gold-bright);
  border-radius: 2px;
  box-shadow: 0 0 0 2px var(--gold-wash);
}

@keyframes gala-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}
@media (prefers-reduced-motion: reduce) {
  .gala-pip.is-running::before { animation: none; }
  .gala-card { transition: none; }
}

/* ------------------------------------------------------------------ panel -- */

.gala-panel {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  padding: var(--gala-s3);
  /* Pinned to fill its slot exactly. Absolute positioning is what makes this
     work: a normal-flow panel contributes its own content height to the grid
     row, so a long piece of research stretched the row and the board ended up
     shorter than the panel. Out of flow, the row is sized by the board alone and
     the panel matches it, scrolling inside for anything longer.
     Sticky went with the same change: an element as tall as the thing beside it
     never detaches, so it only made scrolling unpredictable. */
  position: absolute;
  inset: 0;
  overflow-y: auto;
  /* The dock is fixed over the bottom of the viewport, so the last lines of a
     long panel were sitting underneath it and reading as cut off. Clear it. */
  padding-bottom: 96px;
  scrollbar-width: thin;
  scrollbar-color: transparent transparent;
}
.gala-panel::-webkit-scrollbar { width: 8px; }
.gala-panel::-webkit-scrollbar-track { background: transparent; }
.gala-panel::-webkit-scrollbar-thumb { background: transparent; border-radius: 4px; }
.gala-panel.is-scrolling { scrollbar-color: #cbd5e1 transparent; }
.gala-panel.is-scrolling::-webkit-scrollbar-thumb { background: #cbd5e1; }
html.theme-dark .gala-panel.is-scrolling { scrollbar-color: #1a1a1a transparent; }
html.theme-dark .gala-panel.is-scrolling::-webkit-scrollbar-thumb { background: #1a1a1a; }

.gala-panel-empty {
  color: var(--muted);
  font-size: 13px;
  text-align: center;
  padding: var(--gala-s4) var(--gala-s2);
}

.gala-panel-title {
  font-size: 16px;
  font-weight: 700;
  line-height: 1.35;
  color: var(--text);
  margin: 0 0 var(--gala-s1);
}
.gala-panel-meta {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: var(--gala-s3);
}

/* Sections are separated by a gold rule, not by whitespace alone. A long piece
   of research is a wall of text otherwise, and the eye needs a place to land. */
.gala-sec { margin-bottom: var(--gala-s3); }
.gala-sec + .gala-sec {
  border-top: 1px solid var(--gold-line);
  padding-top: var(--gala-s3);
}
.gala-sec-head {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 6px;
}
.gala-sec-body {
  font-size: 13px;
  line-height: 1.6;
  color: var(--text);
  white-space: pre-wrap;
  word-break: break-word;
}
.gala-sec-body.is-muted { color: var(--muted); }

.gala-reply {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-subtle);
  padding: var(--gala-s2);
  font-size: 13px;
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--text);
}

.gala-note {
  border-left: 3px solid var(--danger);
  background: #fef2f2;
  color: #991b1b;
  padding: var(--gala-s1) var(--gala-s2);
  border-radius: 0 8px 8px 0;
  font-size: 13px;
  line-height: 1.55;
}
html.theme-dark .gala-note { background: rgba(239, 68, 68, 0.1); color: #fca5a5; }

.gala-actions { display: flex; gap: var(--gala-s1); flex-wrap: wrap; }

/* Match confidence readout. Never let the board imply a certainty the matcher
   does not have. */
.gala-match {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 12px;
  color: var(--muted);
}
.gala-match-id {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  color: var(--text);
}

/* --------------------------------------------------------------- skeleton -- */

.gala-skel {
  height: 58px;
  border-radius: var(--gala-card-radius);
  background: linear-gradient(90deg, var(--bg-subtle) 25%, var(--blue-100) 50%, var(--bg-subtle) 75%);
  background-size: 200% 100%;
  animation: gala-shimmer 1.3s linear infinite;
}
@keyframes gala-shimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .gala-skel { animation: none; }
}

/* "Needs a call" is not a research result and must not look like one. Hollow
   pip: the shape says there is nothing to read here, only something to do. */
.gala-pip.is-call { color: var(--gold); }
.gala-pip.is-call::before {
  background: transparent;
  box-shadow: inset 0 0 0 2px var(--gold);
}
html.theme-dark .gala-pip.is-call::before { box-shadow: inset 0 0 0 2px var(--gold-bright); }

/* The GoHighLevel thread behind a ticket. Capped and scrollable: it is context,
   not the answer, and must never push the reply off the panel. */
.gala-thread {
  max-height: 260px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: var(--gala-s2);
  background: var(--bg-subtle);
  display: flex;
  flex-direction: column;
  gap: 10px;
  scrollbar-width: thin;
  scrollbar-color: transparent transparent;
}
.gala-thread::-webkit-scrollbar { width: 8px; }
.gala-thread::-webkit-scrollbar-track { background: transparent; }
.gala-thread::-webkit-scrollbar-thumb { background: transparent; border-radius: 4px; }
.gala-thread.is-scrolling { scrollbar-color: #cbd5e1 transparent; }
.gala-thread.is-scrolling::-webkit-scrollbar-thumb { background: #cbd5e1; }
html.theme-dark .gala-thread.is-scrolling { scrollbar-color: #1a1a1a transparent; }
html.theme-dark .gala-thread.is-scrolling::-webkit-scrollbar-thumb { background: #1a1a1a; }

/* Who spoke has to be readable at a glance, so it carries a left rule as well
   as a label. Colour alone would not survive a mono-vision reader. */
.gala-msg { padding-left: 10px; border-left: 2px solid var(--border); }
.gala-msg.is-client { border-left-color: #2563eb; }
.gala-msg-who {
  font-size: 11px; font-weight: 700; letter-spacing: 0.03em;
  text-transform: uppercase; color: var(--muted); margin-right: 6px;
}
.gala-msg.is-client .gala-msg-who { color: #1d4ed8; }
html.theme-dark .gala-msg.is-client .gala-msg-who { color: #93c5fd; }
.gala-msg-when { font-size: 11px; color: var(--muted); }
.gala-msg-body { font-size: 13px; line-height: 1.55; color: var(--text); white-space: pre-wrap; margin-top: 2px; }

/* ---------------------------------------------------- header, Gala only -- */

/* The shared header carries a date range and a Refresh that reloads Meta
   clients. On a ticket board neither means anything, and two buttons reading
   Refresh a few pixels apart did different things. So on this view only, both
   are swapped for the board's own control. Every rule here is gated on
   body.gala-active and touches nothing anywhere else. */
/* Gold, not the app's blue primary. This button sits in the shared header,
   outside #view-gala, so the gold values are written out rather than taken from
   the tokens scoped to the view. Dark text: the gold is light enough that white
   on it fails contrast. */
#gala-refresh-btn { display: none; }
body.gala-active #gala-refresh-btn {
  display: inline-flex;
  align-items: center;
  background: linear-gradient(180deg, #e6c977 0%, #c8a54a 55%, #a8862f 100%);
  border: 1px solid #a8862f;
  color: #1a1408;
  font-weight: 600;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35);
}
body.gala-active #gala-refresh-btn:hover {
  background: linear-gradient(180deg, #f0d68e 0%, #d4b25c 55%, #b8933a 100%);
}
body.gala-active #gala-refresh-btn:focus-visible {
  outline: 2px solid #e6c977;
  outline-offset: 2px;
}
body.gala-active #gala-refresh-btn[disabled] { opacity: 0.55; }

/* Start Scan sits to the left of Refresh tickets and wears the same solid gold.
   It was the outlined version of the pair first, on the reasoning that one button
   re-reads the board and the other starts work on the PC. Overruled: in this
   header gold means gold, and two half-matching golds looked worse than two
   matching ones. Dark text for the same reason as its neighbour, white on this
   gold fails contrast. */
#gala-scan-btn { display: none; }
body.gala-active #gala-scan-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: linear-gradient(180deg, #e6c977 0%, #c8a54a 55%, #a8862f 100%);
  border: 1px solid #a8862f;
  color: #1a1408;
  font-weight: 600;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35);
}
body.gala-active #gala-scan-btn:hover {
  background: linear-gradient(180deg, #f0d68e 0%, #d4b25c 55%, #b8933a 100%);
}
body.gala-active #gala-scan-btn:focus-visible {
  outline: 2px solid #e6c977;
  outline-offset: 2px;
}
/* While the launcher is being called the button says so and stops taking clicks,
   so nobody fires three scans at the same tickets. */
body.gala-active #gala-scan-btn[disabled] { opacity: 0.55; cursor: default; }
body.gala-active .header-actions .dr-wrap,
body.gala-active .header-actions #refresh-btn { display: none; }

/* Same clearance for the board: its last card sat under the dock too. */
.gala-col-body { padding-bottom: 72px; }
