/* ============================================================
   Swiftpoint Hub — the forum and the thread page (/forum,
   /forum/t/:id).

   Tokens, the reset, the header and the shared controls (buttons,
   fields, cards, modals, toasts) live in the shared layers and are
   loaded before this file. Only forum layout belongs here.

   Two things this sheet has an opinion about:

   1. A status has to be readable without reading the words. "Closed"
      and "On hold" are both greys if you let them be, and a ticket
      board of greys tells you nothing at a glance. So each state owns
      a colour, and the badge is the same badge everywhere a status
      appears — a thread row, the ticket panel, the sidebar.

   2. A ticket is a thread. There is no separate "support" page and
      no separate post style: a reply in a ticket looks exactly like a
      reply anywhere else, because it is one.
   ============================================================ */

.fr-wrap {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 24px 72px;
}

/* ============ Page head ============ */

.fr-head {
  padding: 40px 0 8px;
}
.fr-eyebrow {
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-3);
  margin: 0 0 10px;
}
.fr-head h1 {
  font-family: var(--font-display);
  font-size: clamp(26px, 4.2vw, 36px);
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 0 0 12px;
  max-width: 22ch;
}
.fr-lede {
  font-size: 15.5px;
  line-height: 1.65;
  color: var(--text-2);
  max-width: 64ch;
  margin: 0;
}
.fr-lede strong {
  color: var(--text);
  font-weight: 600;
}

.fr-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
  margin: 26px 0 0;
  padding: 0;
}
.fr-stats > div {
  padding: 14px 18px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
.fr-stats dt {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 6px;
}
.fr-stats dd {
  margin: 0;
  font-size: 26px;
  font-weight: 700;
  line-height: 1;
  color: var(--text);
}

/* ============ Two columns ============ */

.fr-cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 312px;
  gap: 28px;
  align-items: start;
  margin-top: 28px;
}
.fr-main { min-width: 0; }
.fr-side {
  position: sticky;
  top: calc(var(--hdr-total-h) + var(--sp-4));
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}

@media (max-width: 980px) {
  .fr-cols { grid-template-columns: minmax(0, 1fr); }
  .fr-side { position: static; }
}

/* ============ Sidebar cards ============ */

.fr-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 16px 18px 18px;
}
.fr-card-h {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  margin: 0 0 4px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.fr-card-sub {
  margin: 0 0 12px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-3);
}
.fr-card-more {
  margin: 12px 0 0;
  font-size: 12.5px;
}
.fr-card-more a { color: var(--lime-hi); text-decoration: none; }
.fr-card-more a:hover { text-decoration: underline; }

.fr-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.fr-list > li + li {
  border-top: 1px solid var(--line);
}
.fr-list a {
  display: block;
  padding: 9px 0;
  color: var(--text-2);
  text-decoration: none;
}
.fr-list a:hover { color: var(--text); }
.fr-list-n {
  display: block;
  font-size: 13.5px;
  line-height: 1.4;
  color: var(--text);
}
.fr-list-m {
  display: block;
  font-size: 11.5px;
  color: var(--text-3);
  margin-top: 3px;
}
.fr-empty {
  font-size: 13px;
  color: var(--text-3);
  padding: 8px 0;
  margin: 0;
}
.fr-cat > .fr-empty { padding: 14px 20px; }
.fr-list > .fr-empty { display: block; padding: 8px 0; }

/* ============ Categories and thread rows ============ */

.fr-cat {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  margin-bottom: 18px;
  overflow: hidden;
}
.fr-cat-h {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
  padding: 15px 20px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-raise);
}
.fr-cat-name {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  margin: 0;
  color: var(--text);
}
.fr-cat-desc {
  flex: 1 1 100%;
  margin: 2px 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-3);
}
.fr-cat-n {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text-3);
  white-space: nowrap;
}
.fr-cat.is-support { border-color: color-mix(in srgb, var(--teal) 34%, var(--line)); }
.fr-cat.is-support .fr-cat-h { border-bottom-color: color-mix(in srgb, var(--teal) 26%, var(--line)); }

.fr-row {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 13px 20px;
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--line);
  transition: background var(--t-fast);
}
.fr-row:last-child { border-bottom: 0; }
.fr-row:hover { background: var(--surface-2); }
.fr-row-ava {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--surface-3);
  display: grid;
  place-items: center;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  color: var(--text-3);
}
.fr-row-ava img { width: 100%; height: 100%; object-fit: cover; display: block; }
.fr-row-body { min-width: 0; flex: 1 1 auto; }
.fr-row-t {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--text);
}
.fr-row:hover .fr-row-t { color: var(--lime-hi); }
.fr-row-m {
  margin-top: 3px;
  font-size: 12px;
  color: var(--text-3);
}
.fr-row-x {
  margin-top: 4px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-3);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.fr-row-n {
  flex: 0 0 auto;
  text-align: right;
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text-3);
  white-space: nowrap;
  padding-top: 2px;
}
.fr-row-n b { display: block; color: var(--text-2); font-weight: 600; }

/* ============ Badges ============ */

.fr-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 19px;
  padding: 0 8px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line-med);
  background: var(--surface-2);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-3);
  white-space: nowrap;
}
.fr-badge::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

/* The four ticket states. A status you cannot see at a glance is a
   status that has to be read, and a queue of 40 tickets is not
   something anybody reads one at a time. */
.fr-badge.st-open { color: var(--blue); background: var(--blue-dim); border-color: color-mix(in srgb, var(--blue) 34%, transparent); }
.fr-badge.st-in_progress { color: var(--lime-hi); background: var(--lime-dim); border-color: color-mix(in srgb, var(--lime) 40%, transparent); }
.fr-badge.st-on_hold { color: var(--orange); background: var(--orange-dim); border-color: color-mix(in srgb, var(--orange) 34%, transparent); }
.fr-badge.st-closed { color: var(--text-3); background: var(--surface-2); }

.fr-badge.is-pinned { color: var(--violet); background: var(--violet-dim); border-color: color-mix(in srgb, var(--violet) 34%, transparent); }
.fr-badge.is-pinned::before,
.fr-badge.is-locked::before { content: ''; }
.fr-badge.is-locked { color: var(--text-3); }

.fr-tag {
  display: inline-flex;
  align-items: center;
  height: 19px;
  padding: 0 8px;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  border: 1px solid var(--line);
  font-size: 11px;
  font-weight: 600;
  color: var(--text-3);
  white-space: nowrap;
}
.fr-tag.staff { color: var(--teal); background: var(--teal-dim); border-color: color-mix(in srgb, var(--teal) 30%, transparent); }

@media (max-width: 640px) {
  .fr-row { flex-wrap: wrap; }
  .fr-row-n { flex: 1 1 100%; text-align: left; padding-top: 0; }
  .fr-row-n b { display: inline; }
}

/* ============ Thread page ============ */

.fr-thread {
  padding: 32px 0 0;
}
.fr-crumb {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--text-3);
  margin: 0 0 10px;
}
.fr-crumb a { color: var(--text-2); text-decoration: none; }
.fr-crumb a:hover { color: var(--lime-hi); }
.fr-title {
  font-family: var(--font-display);
  font-size: clamp(22px, 3.4vw, 30px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.22;
  margin: 0 0 10px;
}
.fr-title-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.fr-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 12.5px;
  color: var(--text-3);
  margin: 0 0 20px;
}
.fr-meta a { color: var(--text-2); text-decoration: none; }
.fr-meta a:hover { color: var(--lime-hi); }

/* ============ The ticket panel ============ */

.fr-ticket {
  border: 1px solid color-mix(in srgb, var(--teal) 30%, var(--line));
  background: var(--surface);
  border-radius: var(--r-md);
  padding: 16px 18px;
  margin-bottom: 22px;
}
.fr-ticket-h {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}
.fr-ticket-h .fr-card-h { margin: 0; }
.fr-ticket-note {
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-2);
  margin: 0 0 12px;
  padding-left: 12px;
  border-left: 2px solid var(--line-strong);
}
.fr-ticket-set {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}
.fr-ticket-set .tbar-label { color: var(--text-3); }
.fr-ticket-set input {
  flex: 1 1 220px;
  min-width: 0;
}
.fr-trail {
  list-style: none;
  margin: 12px 0 0;
  padding: 12px 0 0;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.fr-trail > li {
  display: flex;
  gap: 10px;
  font-size: 12.5px;
  color: var(--text-3);
}
.fr-trail b { color: var(--text-2); font-weight: 600; }
.fr-trail .fr-badge { flex: 0 0 auto; }

/* ============ Posts ============ */

.fr-posts { display: flex; flex-direction: column; gap: 12px; }

/* The window controls. One line above the replies and, when there is
   more below, one line under — a reader has to be able to see that a
   thread continues without being told. */
.fr-pager {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 4px 0 14px;
}

.fr-post {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 16px 18px;
}
.fr-post.is-first { border-color: var(--line-med); }
.fr-post.is-deleted { opacity: 0.6; }
.fr-post-h {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}
.fr-post-who { display: flex; align-items: center; gap: 9px; min-width: 0; }
.fr-post-ava {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--surface-3);
  display: grid;
  place-items: center;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  color: var(--text-3);
  flex: 0 0 auto;
}
.fr-post-ava img { width: 100%; height: 100%; object-fit: cover; display: block; }
.fr-post-name {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text);
  text-decoration: none;
}
.fr-post-when {
  font-size: 11.5px;
  color: var(--text-3);
}
.fr-post-actions {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 6px;
}

/* ============ Rendered markdown ============ */

/* A post is markdown, rendered by the server (lib/markdown.js). The
   rules here are about type and rhythm, not about appearance: a post is
   something somebody wrote, and the one thing it must not look like is
   a system message. */
.fr-post-body {
  font-size: 14.5px;
  line-height: 1.7;
  color: var(--text-2);
  word-break: break-word;
  overflow-wrap: anywhere;
}
.fr-post-body > *:first-child { margin-top: 0; }
.fr-post-body > *:last-child { margin-bottom: 0; }
.fr-post-body p { margin: 0 0 0.85em; }
.fr-post-body h1,
.fr-post-body h2,
.fr-post-body h3,
.fr-post-body h4 {
  font-family: var(--font-display);
  color: var(--text);
  line-height: 1.3;
  margin: 1.4em 0 0.5em;
}
.fr-post-body h1 { font-size: 1.4em; }
.fr-post-body h2 { font-size: 1.22em; }
.fr-post-body h3 { font-size: 1.1em; }
.fr-post-body h4 { font-size: 1em; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-3); }
.fr-post-body ul,
.fr-post-body ol { margin: 0 0 0.85em; padding-left: 1.5em; }
.fr-post-body li { margin: 0.2em 0; }
.fr-post-body li > ul,
.fr-post-body li > ol { margin-bottom: 0.2em; }
.fr-post-body blockquote {
  margin: 0 0 0.85em;
  padding: 2px 0 2px 14px;
  border-left: 2px solid var(--line-strong);
  color: var(--text-3);
}
.fr-post-body blockquote > *:last-child { margin-bottom: 0; }
.fr-post-body a { color: var(--lime-hi); }
.fr-post-body hr {
  border: 0;
  border-top: 1px solid var(--line);
  margin: 1.4em 0;
}
.fr-post-body code {
  font-family: var(--font-mono);
  font-size: 0.88em;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 0.1em 0.36em;
  color: var(--text);
}
.fr-post-body pre {
  margin: 0 0 0.9em;
  padding: 12px 14px;
  background: var(--bg-raise);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  overflow-x: auto;
}
.fr-post-body pre code {
  background: none;
  border: 0;
  padding: 0;
  font-size: 12.5px;
  line-height: 1.6;
}
.fr-post-body table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 0.9em;
  font-size: 13.5px;
}
.fr-post-body th,
.fr-post-body td {
  border: 1px solid var(--line);
  padding: 6px 10px;
  text-align: left;
}
.fr-post-body th { background: var(--surface-2); color: var(--text); font-weight: 600; }

.fr-post-body.is-editing {
  width: 100%;
  min-height: 120px;
  font-family: var(--font-mono);
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text);
  background: var(--bg-raise);
  border: 1px solid var(--accent);
  border-radius: var(--r-sm);
  padding: 12px 14px;
  resize: vertical;
}
.fr-post-edit-actions {
  display: flex;
  gap: 8px;
  margin-top: 10px;
}
.fr-post-deleted {
  font-size: 13.5px;
  font-style: italic;
  color: var(--text-4);
}

/* ============ Reply composer ============ */

.fr-reply {
  margin-top: 20px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 16px 18px;
}
.fr-reply-h {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.fr-reply-h .fr-card-h { margin: 0; }
.fr-reply textarea {
  width: 100%;
  min-height: 130px;
  font-family: var(--font-body);
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--text);
  background: var(--bg-raise);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 12px 14px;
  resize: vertical;
}
.fr-reply textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-dim);
}
.fr-reply-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 12px;
}
.fr-reply-foot .btn { flex: 0 0 auto; }
.fr-hint { font-size: 12.5px; color: var(--text-3); }
.fr-locked-note {
  margin-top: 20px;
  padding: 14px 16px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-md);
  font-size: 13.5px;
  color: var(--text-3);
}

/* ============ New thread: category cards ============ */

/* The size and the behaviour of this modal are ui.css’s business now —
   see `.modal--form` and `.modal--wide`. */

.fr-cats {
  border: 0;
  padding: 0;
  margin: 0 0 18px;
}
.fr-legend {
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-3);
  padding: 0;
  margin-bottom: 8px;
}
.fr-legend-note { margin: 6px 0 0; font-size: 12.5px; color: var(--text-3); }
.fr-cats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 8px;
}
.fr-cat-card {
  position: relative;
  display: block;
  padding: 11px 13px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--surface);
  cursor: pointer;
  transition: border-color var(--t-fast), background var(--t-fast);
}
.fr-cat-card:hover { border-color: var(--line-strong); background: var(--surface-2); }
.fr-cat-card input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.fr-cat-card:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-dim);
}
.fr-cat-card:has(input:focus-visible) {
  box-shadow: 0 0 0 3px var(--accent-dim);
}
.fr-cat-card-n {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--text);
}
.fr-cat-card:has(input:checked) .fr-cat-card-n { color: var(--lime-hi); }
.fr-cat-card-d {
  display: block;
  margin-top: 4px;
  font-size: 12px;
  line-height: 1.45;
  color: var(--text-3);
}
.fr-modal-foot { flex: 1 1 auto; font-size: 12px; color: var(--text-3); }

/* ============ Reply composer (thread page) ============ */

.fr-reply .md-area { min-height: 120px; }
.fr-reply-hint {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 10px;
  font-size: 12px;
  color: var(--text-3);
}
.fr-reply-hint .md-help { font-weight: 600; }

/* The container the in-place post editor is built into. It holds the
   markdown editor and the save/cancel row, and nothing else needs to
   know it is there. */
.fr-post-edit { margin-top: 4px; }
.fr-post-edit .md { margin-bottom: 10px; }

/* ============ Small bits ============ */

.field--row { display: flex; align-items: center; gap: 12px; }

.fr-queue-filters {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.fr-queue-filters button {
  height: 26px;
  padding: 0 10px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--text-3);
  font-size: 11.5px;
  font-weight: 600;
  cursor: pointer;
}
.fr-queue-filters button[aria-pressed='true'] {
  background: var(--accent-dim);
  border-color: var(--accent);
  color: var(--accent);
}
.modal--wide .fr-list { margin-bottom: 4px; }
