/* ==========================================================================
   Shared page frame for the smaller v2 pages — reviews, partnerships,
   discord-bot. Built on Skynet UI (https://skynetui.com).

   One stylesheet rather than three: these pages are a header, a grid of cards
   and a footer note, and three near-identical files would drift. Every colour
   is a Skynet UI token so they follow whichever of the twelve palettes the
   reader picked.
   ========================================================================== */

body.pv2x { background: var(--sk-bg); color: var(--sk-text); }

.pv2x .hidden { display: none !important; }
.pv2x [hidden] { display: none !important; }

/* A grid or flex ITEM defaults to `min-width: auto` — its MIN-CONTENT width,
   not zero — so one long review or partner name sizes the whole track and
   `.sk-card` (overflow: hidden) clips it. `npm run audit:mobile` catches that;
   this prevents it. */
.pgv2-head > *,
.pgv2-grid > *,
.pgv2-stats > *,
.pgv2-stat > *,
.pgv2-acts > *,
.pgv2-card > *,
.pgv2-feature > * {
  min-width: 0;
}

.pgv2-main {
  max-width: 1200px;
  margin: 0 auto;
  padding: 1.5rem 1rem 4rem;
}

.pgv2-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- header -------------------------------------------------------- */

.pgv2-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.25rem;
}
.pgv2-head-text { flex: 1 1 22rem; }
.pgv2-head h1 {
  margin: 0 0 0.4rem;
  font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.1rem);
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--sk-text);
}
.pgv2-head p { margin: 0; max-width: 62ch; color: var(--sk-text-2); line-height: 1.6; }
.pgv2-head .sk-btn { flex: 0 0 auto; }
@media (pointer: coarse) {
  .pgv2-head .sk-btn, .pgv2-acts .sk-btn { min-height: 44px; }
}

/* ---------- figures ------------------------------------------------------- */

.pgv2-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
  gap: 0.6rem;
  margin: 0 0 1.5rem;
}
.pgv2-stat {
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--sk-border-2);
  border-radius: 12px;
  background: var(--sk-surface);
}
.pgv2-stat dt { margin: 0 0 0.15rem; color: var(--sk-muted); font-size: 0.82rem; }
.pgv2-stat dd {
  margin: 0;
  font-size: 1.4rem;
  font-weight: 800;
  color: var(--sk-text);
  /* Never `overflow-wrap` on a numeral: the browser breaks inside it. */
  overflow-wrap: normal;
}
.pgv2-stat dd span { font-size: 0.85rem; font-weight: 500; color: var(--sk-muted); }

/* ---------- the empty / failed states ------------------------------------- */

.pgv2-gate { max-width: 44rem; }
.pgv2-gate .sk-card-body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.7rem;
  padding: 1.75rem;
}
.pgv2-gate h2 { margin: 0; font-size: 1.2rem; font-weight: 700; color: var(--sk-text); }
.pgv2-gate p { margin: 0; max-width: 58ch; color: var(--sk-text-2); line-height: 1.6; }

.pgv2-gate-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  /* A tint of the accent with the glyph on its READABLE half — --sk-primary is
     a fill token and is thin as text on a card. */
  background: color-mix(in srgb, var(--sk-primary) 16%, transparent);
  color: var(--sk-primary-text);
  font-size: 1.1rem;
}
.pgv2-gate-icon.is-warning {
  background: color-mix(in srgb, var(--sk-warning) 18%, transparent);
  color: var(--sk-warning-text);
}

.pgv2-acts { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 0.3rem; }

/* ---------- card grids ---------------------------------------------------- */

.pgv2-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 20rem), 1fr));
  gap: 1rem;
}

.pgv2-card .sk-card-body { display: flex; flex-direction: column; gap: 0.5rem; height: 100%; }
.pgv2-card-title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--sk-text);
  /* Titles and names are other people's text. */
  overflow-wrap: anywhere;
}
.pgv2-card-text { margin: 0; color: var(--sk-text-2); line-height: 1.6; overflow-wrap: anywhere; }
.pgv2-card-by { margin: auto 0 0; padding-top: 0.5rem; color: var(--sk-muted); font-size: 0.88rem; overflow-wrap: anywhere; }

/* ---------- review stars -------------------------------------------------- */

.pgv2-rating { margin: 0; display: flex; align-items: center; gap: 0.4rem; }
.pgv2-stars { display: inline-flex; gap: 0.1rem; color: var(--sk-warning-text); }
/* A star that was not given is drawn, not omitted: five positions make the
   rating readable at a glance, and the spelled-out value beside it is what a
   screen reader gets rather than a count of glyphs. */
.pgv2-stars .is-off { color: var(--sk-faint); }

/* ---------- partner cards ------------------------------------------------- */

.pgv2-banner {
  height: 6.5rem;
  background-color: var(--sk-surface-2);
  background-size: cover;
  background-position: center;
}
.pgv2-logo {
  width: 46px;
  height: 46px;
  border-radius: 11px;
  object-fit: cover;
  background: var(--sk-surface-2);
  flex: 0 0 auto;
}
.pgv2-logo-none {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 11px;
  background: color-mix(in srgb, var(--sk-primary) 16%, transparent);
  color: var(--sk-primary-text);
  flex: 0 0 auto;
}
.pgv2-card-head { display: flex; align-items: center; gap: 0.7rem; }
.pgv2-no-desc { color: var(--sk-muted); font-style: italic; }

/* ---------- feature rows (the bot landing page) --------------------------- */

.pgv2-features {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: 1rem;
  margin-bottom: 1.5rem;
}
.pgv2-feature .sk-card-body { display: flex; flex-direction: column; gap: 0.4rem; }
.pgv2-feature h2 { margin: 0.5rem 0 0; font-size: 1.05rem; font-weight: 700; color: var(--sk-text); }
.pgv2-feature p { margin: 0; color: var(--sk-text-2); line-height: 1.6; }
.pgv2-feature-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border-radius: 11px;
  background: color-mix(in srgb, var(--sk-primary) 16%, transparent);
  color: var(--sk-primary-text);
}

/* /download: the visitor's own phone is listed first and says so in words. */
.pgv2-install .pgv2-feature p.pgv2-install-yours { color: var(--sk-primary-text); font-weight: 600; }

/* /account/delete: what is in the way, and the confirm form. */
.pgv2-blockers { margin: 0; padding-left: 1.2rem; display: flex; flex-direction: column; gap: 0.6rem; color: var(--sk-text-2); line-height: 1.6; overflow-wrap: anywhere; }
.pgv2-blockers strong { color: var(--sk-text); }
.pgv2-delete-form { display: flex; flex-direction: column; align-items: flex-start; gap: 0.6rem; width: 100%; max-width: 28rem; }
.pgv2-delete-form label { color: var(--sk-text-2); }
.pgv2-delete-form .sk-input { width: 100%; }
@media (pointer: coarse) { .pgv2-delete-form .sk-input { min-height: 44px; font-size: 16px; } }

/* /help: support tickets (supportTicketRoutes.js). */
.pgv2-section-title { margin: 2rem 0 0.75rem; font-size: 1.15rem; font-weight: 700; color: var(--sk-text); }
.pgv2-tabs { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1rem; }
.pgv2-tickets { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.6rem; }
.pgv2-ticket-top { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; overflow-wrap: anywhere; }
.pgv2-ticket-meta { color: var(--sk-muted); font-size: 0.875rem; overflow-wrap: anywhere; }
.pgv2-ticket-meta a:not(.sk-btn) { color: var(--sk-primary-text); }
.pgv2-ticket-preview { color: var(--sk-text-2); font-size: 0.9rem; overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.pgv2-ticket-form { display: flex; flex-direction: column; gap: 0.5rem; width: 100%; }
.pgv2-ticket-form label { color: var(--sk-text-2); font-weight: 600; }
.pgv2-ticket-form .sk-input, .pgv2-ticket-form .sk-select, .pgv2-ticket-form .sk-textarea { width: 100%; }
.pgv2-ticket-hint { margin: 0; color: var(--sk-muted); font-size: 0.85rem; }
.pgv2-check { display: inline-flex; align-items: center; gap: 0.5rem; font-weight: 400 !important; min-height: 44px; }
.pgv2-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.pgv2-ticket-actions { margin-top: 1rem; }
.pgv2-ticket-actions form { margin: 0; }
@media (pointer: coarse) { .pgv2-ticket-form .sk-input, .pgv2-ticket-form .sk-select, .pgv2-ticket-form .sk-textarea { min-height: 44px; font-size: 16px; } }

/* Ticket screenshots (views/help-ticket.ejs). A picture never sizes the card: it shrinks to the column. */
.pgv2-shots { margin-top: 1.5rem; }
.pgv2-shots .sk-card-body { display: flex; flex-direction: column; gap: 0.75rem; }
.pgv2-shot-list { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr)); gap: 0.75rem; }
.pgv2-shot { min-width: 0; display: flex; flex-direction: column; gap: 0.25rem; }
.pgv2-shot a { display: block; border: 1px solid var(--sk-border); border-radius: 0.5rem; overflow: hidden; background: var(--sk-surface-2); }
.pgv2-shot img { display: block; width: 100%; height: 8rem; object-fit: cover; }
.pgv2-shot form { margin: 0; }
.pgv2-ticket-form input[type="file"] { max-width: 100%; min-height: 44px; }

.pgv2-cta { margin-top: 1.5rem; }
.pgv2-cta .sk-card-body { display: flex; flex-direction: column; align-items: flex-start; gap: 0.75rem; padding: 1.75rem; }
.pgv2-cta h2 { margin: 0; font-size: 1.25rem; font-weight: 700; color: var(--sk-text); }
.pgv2-cta p { margin: 0; max-width: 60ch; color: var(--sk-text-2); line-height: 1.6; }

.pgv2-foot { margin: 1.5rem 0 0; color: var(--sk-muted); line-height: 1.6; }
/* Skynet UI paints <a> with --sk-primary, a FILL token that measures about
   2.8:1 as text. --sk-primary-text is the readable half.

   `:not(.sk-btn)` is not tidiness — without it this rule also repaints the
   label of a link styled as a button, putting the pale accent on the solid
   accent fill underneath it. `npm run audit:themes` measured "Join their
   Discord" at 1.94:1 on the crimson palette before this. A button's label is
   the framework's to colour. */
.pgv2-foot a:not(.sk-btn),
.pgv2-card a:not(.sk-btn),
.pgv2-feature a:not(.sk-btn),
.pgv2-gate a:not(.sk-btn) { color: var(--sk-primary-text); }

@media (max-width: 480px) {
  .pgv2-main { padding-left: 0.75rem; padding-right: 0.75rem; }
  .pgv2-gate .sk-card-body, .pgv2-cta .sk-card-body { padding: 1.25rem; }
  .pgv2-acts .sk-btn { width: 100%; }
}

/* ---------- /testers ------------------------------------------------------ */

.pgv2-steps { list-style: none; margin: 0; padding: 0; }
.pgv2-note { margin: 0 0 1rem; }
.pgv2-progress {
  display: block;
  width: 100%;
  height: 0.6rem;
  margin: 0 0 1.25rem;
  accent-color: var(--sk-primary);
}

/* Support tickets: the author's servers, staff view only. */
.pgv2-ticket-services h2 { margin: 0 0 .5rem; font-size: 1.05rem; }
.pgv2-ticket-services h3 { margin: 1rem 0 .4rem; font-size: .9rem; color: var(--sk-muted); text-transform: uppercase; letter-spacing: .04em; }
.pgv2-svc-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.pgv2-svc-list li { display: flex; flex-direction: column; gap: .15rem; padding: .6rem .75rem; border: 1px solid var(--sk-border); border-radius: 10px; min-width: 0; overflow-wrap: anywhere; }
.pgv2-svc-meta { font-size: .85rem; color: var(--sk-muted); }

/* A server card: name and state, the ids staff quote, the tabs an admin was
   given, and the two support tools. It lives in a 20rem sidebar on desktop, so
   everything wraps and nothing sets a width. */
.pgv2-svc-list li.pgv2-svc-card { gap: .6rem; padding: .8rem .85rem; background: var(--sk-surface-2); }
.pgv2-svc-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .4rem .6rem; min-width: 0; }
.pgv2-svc-name { min-width: 0; font-size: .98rem; overflow-wrap: anywhere; }
.pgv2-svc-pills { display: inline-flex; flex-wrap: wrap; gap: .3rem; }
.pgv2-svc-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: .35rem .75rem; margin: 0; }
.pgv2-svc-facts > div { min-width: 0; }
.pgv2-svc-facts dt { font-size: .72rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--sk-muted); }
.pgv2-svc-facts dd { margin: 0; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: .85rem; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.pgv2-svc-chips { list-style: none; display: flex; flex-wrap: wrap; gap: .3rem; margin: 0; padding: 0; }
.pgv2-svc-chips li { padding: .1rem .5rem; border: 1px solid var(--sk-border); border-radius: 999px; font-size: .78rem; color: var(--sk-text); background: var(--sk-surface); }
.pgv2-svc-tools { display: flex; flex-direction: column; gap: .5rem; padding-top: .6rem; border-top: 1px solid var(--sk-border); }
.pgv2-svc-form { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin: 0; }
.pgv2-svc-form .sk-btn { flex: 1 1 auto; min-width: 0; white-space: normal; }
.pgv2-svc-keep { display: inline-flex; align-items: center; gap: .4rem; min-height: 44px; font-size: .82rem; color: var(--sk-muted); }
.pgv2-svc-busy { margin: 0; font-size: .82rem; color: var(--sk-primary-text); }
.pgv2-svc-busy:empty { display: none; }

/* The killfeed line: state is carried by the words first; the dot and its
   colour only agree with them. */
.pgv2-svc-fresh { display: flex; align-items: baseline; gap: .5rem; margin: 0; font-size: .88rem; }
.pgv2-svc-dot { flex: 0 0 auto; width: .6rem; height: .6rem; border-radius: 50%; background: var(--sk-muted); transform: translateY(-.05rem); }
.pgv2-svc-fresh[data-state="ok"] .pgv2-svc-dot { background: var(--sk-success); }
.pgv2-svc-fresh[data-state="warn"] .pgv2-svc-dot { background: var(--sk-warning); }
.pgv2-svc-fresh[data-state="bad"] .pgv2-svc-dot { background: var(--sk-danger); }

/* The last channel check: what is broken, a Fix per channel, and the owner's
   steps when the bot cannot fix it. The nested lists sit inside a card that
   is itself a .pgv2-svc-list item, so they undo that rule's box. */
.pgv2-svc-last { display: flex; flex-direction: column; gap: .45rem; padding-top: .6rem; border-top: 1px solid var(--sk-border); min-width: 0; }
.pgv2-svc-last > p { margin: 0; }
.pgv2-svc-list .pgv2-svc-issues { list-style: none; margin: 0; padding: 0; display: grid; gap: .35rem; }
.pgv2-svc-list .pgv2-svc-issues li { flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .4rem; padding: .45rem .6rem; background: var(--sk-surface); }
.pgv2-svc-issue-text { display: flex; flex-direction: column; min-width: 0; flex: 1 1 10rem; font-size: .9rem; }
.pgv2-svc-issues .pgv2-svc-form { flex: 0 0 auto; }
.pgv2-svc-list .pgv2-svc-steps { margin: 0; padding-left: 1.3rem; font-size: .85rem; }
.pgv2-svc-list .pgv2-svc-steps li { display: list-item; padding: .1rem 0; border: 0; border-radius: 0; }
.pgv2-svc-invite { display: flex; flex-direction: column; gap: .3rem; min-width: 0; }
.pgv2-svc-invite .sk-input { width: 100%; min-width: 0; font-size: .8rem; }
/* A report is plain text with line breaks; it is shown as typed, never as markup. */
.pgv2-svc-report { margin: .5rem 0 0; white-space: pre-wrap; overflow-wrap: anywhere; font-size: .88rem; line-height: 1.55; }

/* The server page: the last result sits above the tools, apart from them. */
#result { margin-bottom: 1rem; }

/* The staff action log. */
.pgv2-act-filters { display: flex; flex-direction: column; gap: .6rem; }
.pgv2-act-filters .sk-input, .pgv2-act-filters .sk-select { flex: 1 1 9rem; min-width: 0; width: auto; }
.pgv2-act-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.pgv2-act { padding: .65rem .8rem; border: 1px solid var(--sk-border); border-radius: 10px; background: var(--sk-surface); min-width: 0; overflow-wrap: anywhere; }
.pgv2-act[data-ok="false"] { border-left: 3px solid var(--sk-warning); }
.pgv2-act-head { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .6rem; }
.pgv2-act-summary { min-width: 0; font-weight: 600; }
.pgv2-act .pgv2-svc-meta { margin: .3rem 0 0; }
.pgv2-svc-meta a, .pgv2-act a { color: var(--sk-primary-text); }

/* Support tickets: the browser-notification switch (public/js/web-push.js). */
.pgv2-push-body { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .75rem; }
.pgv2-push-body > div { min-width: 0; flex: 1 1 14rem; }

/* ------------------------------------------------------------------ Support tickets: look and motion
 * Everything reads with motion off: the keyframes only ever move things that
 * are already visible, and all of it sits behind prefers-reduced-motion. */

/* Status pill: a tint of the state's own token, text in --sk-text so it holds
   contrast on every palette; the dot carries the colour, the words the meaning. */
.pgv2-status { display: inline-flex; align-items: center; gap: .4rem; padding: .15rem .6rem; border-radius: 999px; font-weight: 700; font-size: .8rem; color: var(--sk-text); background: var(--sk-surface-2); border: 1px solid var(--sk-border); white-space: nowrap; }
.pgv2-status-dot { width: .55rem; height: .55rem; border-radius: 50%; background: var(--sk-muted); flex: none; }
.pgv2-status[data-status="open"] { background: var(--sk-warning-soft); border-color: color-mix(in srgb, var(--sk-warning) 45%, transparent); }
.pgv2-status[data-status="open"] .pgv2-status-dot { background: var(--sk-warning); }
.pgv2-status[data-status="answered"] { background: var(--sk-success-soft); border-color: color-mix(in srgb, var(--sk-success) 45%, transparent); }
.pgv2-status[data-status="answered"] .pgv2-status-dot { background: var(--sk-success); }

/* Progress: Opened → replied → closed. */
.pgv2-track { list-style: none; display: flex; flex-wrap: wrap; gap: .25rem 0; margin: .9rem 0 0; padding: 0; counter-reset: step; }
.pgv2-track li { display: inline-flex; align-items: center; gap: .45rem; color: var(--sk-muted); font-size: .85rem; font-weight: 600; }
.pgv2-track li + li::before { content: ""; width: 2rem; height: 2px; margin: 0 .5rem; background: var(--sk-border); border-radius: 2px; }
.pgv2-track li > span { width: .7rem; height: .7rem; border-radius: 50%; border: 2px solid var(--sk-border-2, var(--sk-border)); background: var(--sk-surface); flex: none; }
.pgv2-track li[data-done] { color: var(--sk-text); }
.pgv2-track li[data-done] > span { background: var(--sk-primary); border-color: var(--sk-primary); }
.pgv2-track li[data-done] + li::before, .pgv2-track li[data-done] + li[data-done]::before { background: var(--sk-primary); }
.pgv2-track li[data-current] { color: var(--sk-text); }
.pgv2-track li[data-current] > span { border-color: var(--sk-primary); }

/* Ticket lists: a status edge, a lift on hover. */
.pgv2-ticket-card { position: relative; overflow: hidden; transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease; }
.pgv2-ticket-card::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 4px; background: var(--sk-border); }
.pgv2-ticket-card[data-status="open"]::before { background: var(--sk-warning); }
.pgv2-ticket-card[data-status="answered"]::before { background: var(--sk-success); }
.pgv2-ticket-card[data-status="closed"] { opacity: .85; }
.pgv2-ticket-card:hover, .pgv2-ticket-card:focus-within { transform: translateY(-2px); box-shadow: 0 10px 24px -14px color-mix(in srgb, var(--sk-primary) 55%, transparent); border-color: color-mix(in srgb, var(--sk-primary) 40%, var(--sk-border)); }
.pgv2-ticket { display: flex; flex-direction: column; gap: .35rem; padding: .95rem 1.1rem .95rem 1.35rem; color: var(--sk-text); text-decoration: none; min-width: 0; }
.pgv2-ticket:focus-visible { outline: 2px solid var(--sk-primary); outline-offset: -2px; }
.pgv2-ticket-top strong { font-size: 1rem; }
.pgv2-ticket-meta { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem; }

/* Ticket bans: the notice a banned user sees, and the staff list. */
.pgv2-ban { border-color: color-mix(in srgb, var(--sk-danger) 45%, var(--sk-border)); }
.pgv2-ban h2 { color: var(--sk-danger-text); }
.pgv2-ban p { overflow-wrap: anywhere; }
.pgv2-ban-row { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; padding-right: 1rem; }
.pgv2-ban-row::before { background: var(--sk-danger); }
.pgv2-ban-row .pgv2-ticket { flex: 1 1 16rem; }
.pgv2-ban-row .pgv2-ticket-preview { overflow-wrap: anywhere; }
.pgv2-ban-lift { margin: 0 0 .75rem 1.35rem; }

.pgv2-empty { display: flex; flex-direction: column; align-items: center; gap: .5rem; padding: 2rem 1rem; text-align: center; color: var(--sk-muted); border: 1px dashed var(--sk-border); border-radius: 14px; }
.pgv2-empty p { margin: 0; max-width: 32rem; }
.pgv2-empty-icon { display: grid; place-items: center; width: 3rem; height: 3rem; border-radius: 50%; font-size: 1.4rem; color: var(--sk-primary-text); background: var(--sk-primary-soft); }

/* A ticket: the conversation, and the staff panels beside it on a wide screen. */
.pgv2-ticket-layout { display: grid; gap: 1.25rem; align-items: start; }
.pgv2-ticket-layout > * { min-width: 0; }
.pgv2-ticket-main { display: flex; flex-direction: column; }
.pgv2-ticket-side { display: flex; flex-direction: column; gap: 1rem; }
.pgv2-ticket-side > .sk-card { margin: 0; }
@media (min-width: 1024px) {
  .pgv2-ticket-layout { grid-template-columns: minmax(0, 1fr) 20rem; }
  .pgv2-ticket-side { position: sticky; top: 76px; }
}
.pgv2-ticket-services h2 { margin: 0 0 .5rem; font-size: 1.05rem; }

/* Chat: whoever is reading is on the right. */
.pgv2-thread { list-style: none; margin: 0 0 1.25rem; padding: 0; display: flex; flex-direction: column; gap: .9rem; }
.pgv2-msg-row { display: flex; align-items: flex-end; gap: .6rem; max-width: 100%; }
.pgv2-msg-row[data-side="mine"] { flex-direction: row-reverse; }
.pgv2-avatar { display: grid; place-items: center; flex: none; width: 2.25rem; height: 2.25rem; border-radius: 50%; font-weight: 800; font-size: .95rem; color: var(--sk-text); background: var(--sk-surface-2); border: 1px solid var(--sk-border); }
.pgv2-avatar[data-kind="staff"] { color: #fff; background: var(--sk-primary); border-color: var(--sk-primary); }
.pgv2-avatar[data-kind="note"] { background: var(--sk-warning-soft); border-color: var(--sk-warning); }
.pgv2-msg { position: relative; min-width: 0; max-width: min(40rem, 100%); padding: .75rem 1rem; border-radius: 16px 16px 16px 4px; background: var(--sk-surface); border: 1px solid var(--sk-border); box-shadow: 0 1px 2px color-mix(in srgb, #000 12%, transparent); }
.pgv2-msg-row[data-side="mine"] .pgv2-msg { border-radius: 16px 16px 4px 16px; background: var(--sk-primary-soft); border-color: color-mix(in srgb, var(--sk-primary) 35%, var(--sk-border)); }
/* SKYNET AI answers (the Discord bot): visible to the user, labelled, and set apart from staff. */
.pgv2-avatar[data-kind="ai"] { font-size: .7rem; color: var(--sk-info-text); background: var(--sk-info-soft); border-color: var(--sk-info); }
.pgv2-msg[data-kind="ai"] { background: var(--sk-info-soft); border-color: color-mix(in srgb, var(--sk-info) 45%, var(--sk-border)); }
/* Where a ticket was opened. Words carry it; the colour only agrees. */
.pgv2-source { font-weight: 600; color: var(--sk-text); }
.pgv2-source[data-source="discord"] { color: var(--sk-primary-text); }
.pgv2-source-tabs { margin-top: -.25rem; }
.pgv2-discord-id { font-size: .85em; overflow-wrap: anywhere; }
.pgv2-msg[data-kind="note"] { background: var(--sk-warning-soft); border-style: dashed; border-color: var(--sk-warning); }
.pgv2-msg-head { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; margin-bottom: .3rem; color: var(--sk-text); overflow-wrap: anywhere; font-size: .9rem; }
.pgv2-msg-when { color: var(--sk-muted); font-size: .78rem; }
.pgv2-msg-body { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; color: var(--sk-text); line-height: 1.6; }
.pgv2-msg-system { display: flex; align-items: center; gap: .75rem; color: var(--sk-muted); font-size: .8rem; text-align: center; }
.pgv2-msg-system::before, .pgv2-msg-system::after { content: ""; flex: 1; height: 1px; background: var(--sk-border); }
.pgv2-msg-system > span { flex: 0 1 auto; overflow-wrap: anywhere; }
#latest .pgv2-msg { outline: 2px solid transparent; }

/* The browser-notification switch: a small card in the side column. */
.pgv2-push { margin: 0 0 1rem; }
.pgv2-ticket-side .pgv2-push { margin: 0; }

@media (prefers-reduced-motion: no-preference) {
  @keyframes pgv2-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
  @keyframes pgv2-in-left { from { opacity: 0; transform: translateX(-10px) scale(.98); } to { opacity: 1; transform: none; } }
  @keyframes pgv2-in-right { from { opacity: 0; transform: translateX(10px) scale(.98); } to { opacity: 1; transform: none; } }
  @keyframes pgv2-pulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--sk-warning) 60%, transparent); } 70%, 100% { box-shadow: 0 0 0 .45rem transparent; } }
  @keyframes pgv2-glow { 0%, 100% { box-shadow: 0 1px 2px color-mix(in srgb, #000 12%, transparent); } 40% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--sk-primary) 45%, transparent); } }
  @keyframes pgv2-pop { 0% { transform: scale(.6); } 60% { transform: scale(1.12); } 100% { transform: scale(1); } }

  .pgv2-ticket-card { animation: pgv2-rise .35s ease both; animation-delay: calc(var(--i, 0) * 45ms); }
  .pgv2-msg-row[data-side="theirs"] { animation: pgv2-in-left .35s ease both; animation-delay: calc(var(--i, 0) * 40ms); }
  .pgv2-msg-row[data-side="mine"] { animation: pgv2-in-right .35s ease both; animation-delay: calc(var(--i, 0) * 40ms); }
  .pgv2-msg-system { animation: pgv2-rise .35s ease both; animation-delay: calc(var(--i, 0) * 40ms); }
  #latest .pgv2-msg { animation: pgv2-glow 1.6s ease .6s 1; }
  .pgv2-status[data-status="open"] .pgv2-status-dot { animation: pgv2-pulse 2s ease-out infinite; }
  .pgv2-new { animation: pgv2-pop .4s ease both .3s; }
  .pgv2-ticket-side > * { animation: pgv2-rise .4s ease both .1s; }
  .pgv2-track li > span { transition: background-color .3s ease, border-color .3s ease; }
}

/* The support pages' own nav (views/partials/help-nav.ejs): home, then the help
   pages. Wraps on a phone rather than scrolling; the divider drops out there. */
.pgv2-help-nav { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin: 0 0 1.25rem; padding: .5rem; border: 1px solid var(--sk-border); border-radius: var(--sk-radius, .75rem); background: var(--sk-surface); min-width: 0; }
.pgv2-help-nav-sep { width: 1px; align-self: stretch; background: var(--sk-border); margin: 0 .2rem; }
@media (max-width: 520px) { .pgv2-help-nav-sep { display: none; } .pgv2-help-home { flex-basis: 100%; justify-content: flex-start; } }

/* Deleting tickets (staff only): a closed <details>, so it takes a deliberate
   click to even see the form; the typed word is checked again on the server. */
.pgv2-danger { margin: 1.25rem 0 0; border-color: var(--sk-danger); }
.pgv2-danger-summary { cursor: pointer; padding: .85rem 1.1rem; color: var(--sk-danger-text, var(--sk-text)); font-weight: 600; min-height: 44px; display: flex; align-items: center; }
.pgv2-danger[open] .pgv2-danger-summary { border-bottom: 1px solid var(--sk-border); }
