/* =========================================================================
   osTicket client portal theme — Global Pathways Academy
   =========================================================================

   PRESENTATION LAYER. This stylesheet carries the client-portal redesign;
   the only template edits made alongside it are wrapper/markup changes in
   footer.inc.php and login.inc.php, verified attribute-identical with
   tools/attr-inventory.sh. No PHP logic, form attribute, or JS hook changed.

   Scope: loaded only by include/client/header.inc.php (via ASSETS_PATH,
   defined in client.inc.php). The agent and admin panels load
   scp/css/scp.css instead and are unaffected.

   Design source — gp.academy
   --------------------------
   This portal runs in direct conjunction with https://gp.academy, so the
   design system is copied from that site's compiled stylesheet
   (assets/styles-*.css), not invented:

     cream       #fbfaf6   page background
     cream-soft  #f4efe7   warm panels, footer band
     warm-beige  #ece7dd   deeper warm surface
     ink         #1b2230   text            (15.3:1 on cream)
     sage        #4f6b5c   primary actions (5.6:1 on cream, 5.9:1 under #fff text)
     sage-deep   #3e5649   hover/strong    (7.6:1 on cream)
     blue-deep   #2a4275   staff/secondary (9.4:1 on cream)
     gold        #b89348   DECORATIVE ONLY — 2.9:1 on white, never text
     line        rgba(27,34,48,.1)  hairlines
     radius      10px controls, 14px cards, pills for buttons
     type        General Sans (Fontshare) — headlines LIGHT (300) with
                 negative tracking; buttons 500; eyebrows tracked uppercase

   General Sans is self-hosted from assets/default/font/ (Fontshare permits
   self-hosting; the files are the latin woff2 subsets Fontshare serves).
   Self-hosting keeps the GDPR posture from docs/PROJECT-CONTEXT.md intact:
   no visitor IP is sent to a font CDN.

   Load order matters. These files load AFTER this one and win ties, so some
   rules below are raised to #content specificity (and keep !important where
   upstream used it):
     css/thread.css       .thread-body typography and link colour
     css/redactor.css     .redactor-box editor chrome
     css/filedrop.css     .filedrop upload widget (injected as field media)
     css/font-awesome.min.css

   Other invariants preserved from the first pass (see git history):
   colour is semantic-only outside the brand hue; reference numbers, dates
   and file sizes are tabular mono; section labels share one uppercase
   micro-label voice; alert bars auto-height (upstream clipped at 16px);
   the ticket-form 50/50 table-layout bug and the subject-cell descender
   clipping stay fixed; responsive from 320px up with no horizontal
   overflow (asserted by tools/preview/check.mjs).

   Re-branding: the palette lives in the custom properties below.
   ========================================================================= */

/* --- Brand face --------------------------------------------------------- */

@font-face {
  font-family: 'General Sans';
  src: url('../font/GeneralSans-300.woff2') format('woff2');
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'General Sans';
  src: url('../font/GeneralSans-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'General Sans';
  src: url('../font/GeneralSans-400-Italic.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: 'General Sans';
  src: url('../font/GeneralSans-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'General Sans';
  src: url('../font/GeneralSans-600.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Brand (gp.academy) -------------------------------------------------- */
  --gp-brand:        #4f6b5c;   /* sage */
  --gp-brand-strong: #3e5649;   /* sage-deep */
  --gp-brand-tint:   #eef3f0;   /* sage over white, ~8% */
  --gp-brand-edge:   #cfdcd4;
  --gp-brand-ring:   rgba(79, 107, 92, 0.28);
  --gp-navy:         #2a4275;   /* blue-deep — staff-facing accents */
  --gp-navy-strong:  #1f3259;
  --gp-gold-soft:    rgba(184, 147, 72, 0.18);  /* gold, decorative only */

  /* Ink and surfaces ----------------------------------------------------- */
  --gp-ink:       #1b2230;
  --gp-ink-2:     #4d5563;     /* 8.0:1 on cream */
  --gp-ink-3:     #6a7080;     /* 4.7:1 on cream — floor for small labels */
  --gp-line:      rgba(27, 34, 48, 0.12);
  --gp-line-soft: rgba(27, 34, 48, 0.07);
  --gp-page:      #fbfaf6;     /* cream */
  --gp-surface:   #ffffff;     /* cards */
  --gp-surface-2: #f4efe7;     /* cream-soft */
  --gp-beige:     #ece7dd;

  /* Semantic — meaning only, never decoration ---------------------------- */
  --gp-ok:        #3e5649;
  --gp-ok-bg:     #edf3ee;
  --gp-ok-edge:   #cfdcd3;
  --gp-warn:      #8a5300;
  --gp-warn-bg:   #faf3e2;
  --gp-warn-edge: #e7d3a8;
  --gp-err:       #a52121;
  --gp-err-bg:    #fbf0ef;
  --gp-err-edge:  #ecc9c9;
  --gp-info:      #2a4275;
  --gp-info-bg:   #eef2f9;
  --gp-info-edge: #c9d6ea;

  /* Type ------------------------------------------------------------------ */
  --gp-sans: "General Sans", ui-sans-serif, -apple-system, BlinkMacSystemFont,
             "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --gp-mono: ui-monospace, SFMono-Regular, "SF Mono", "Cascadia Mono",
             Menlo, Consolas, monospace;

  /* Metrics ---------------------------------------------------------------- */
  --gp-width:  71rem;
  --gp-pad:    24px;
  --gp-gutter: 56px;    /* thread avatar gutter */
  --gp-r:      14px;    /* cards */
  --gp-r-sm:   10px;    /* controls */
  --gp-r-pill: 999px;

  /* Motion — colours fast, transforms slightly slower, both ease-out ------- */
  --gp-t-color: 120ms ease-out;
  --gp-t-move:  160ms cubic-bezier(0.23, 1, 0.32, 1);

  /* Optical correction for Font Awesome 3.2.1 glyphs set beside text.
     FA's em box has ascent 1536 / descent 0, so a glyph's box centre does not
     coincide with its ink centre, and align-items:center lines up boxes, not
     ink — leaving the glyph visibly low against the text's cap band. Measured
     against General Sans by decoding rendered pixels: the text's cap band runs
     18.00-29.13px inside a 40px pill (centre 23.60) while the glyph ink centre
     landed at 22.69 — about 1px high. Nudging down by 1px at 15px text lands
     the plus, magnifier, house, book, and document glyphs on the cap-band
     centre. Expressed in em so it tracks font-size. */
  --gp-icon-nudge: 0.065em;
}

/* =========================================================================
   1. Reset  (upstream reset.less, kept intact except where noted)
   ========================================================================= */

html {
  font-size: 100%;
  overflow-y: scroll;
  -webkit-text-size-adjust: 100%;
  -ms-text-size-adjust: 100%;
}
body {
  margin: 0;
  padding: 0;
  font-size: 16px;
  line-height: 1.55;
}
body, input, select, textarea, button {
  font-family: var(--gp-sans);
  color: var(--gp-ink);
}
b, strong { font-weight: 600; }
blockquote {
  margin: 1em 0;
  padding: 2px 0 2px 16px;
  border-left: 3px solid var(--gp-line);
  color: var(--gp-ink-2);
}
hr {
  display: block;
  height: 1px;
  border: 0;
  border-top: 1px solid var(--gp-line);
  margin: 1.5em 0;
  padding: 0;
}
small { font-size: 85%; }
ul, ol { margin: 1em 0; padding: 0 0 0 24px; }
img { border: 0; vertical-align: middle; max-width: 100%; }
form { margin: 0; }
fieldset { border: 0; margin: 0; padding: 0; }
label { cursor: pointer; }
input, select, textarea {
  font-size: 100%;
  margin: 0;
  vertical-align: baseline;
}
input { line-height: normal; }
input[type="button"], input[type="reset"], input[type="submit"], button {
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
input[type="checkbox"], input[type="radio"] {
  box-sizing: border-box;
  width: 17px;
  height: 17px;
  accent-color: var(--gp-brand);
  vertical-align: -3px;
}
textarea { overflow: auto; vertical-align: top; resize: vertical; }
table { border-collapse: collapse; border-spacing: 0; }
th, td { vertical-align: top; }
th { text-align: left; font-weight: normal; }
h1, h2, h3, h4, h5, h6, form, fieldset { margin: 0; padding: 0; }
code, kbd, samp, pre { font-family: var(--gp-mono); font-size: 0.9em; }

/* Every element that reports a size should measure it the same way. */
*, *::before, *::after { box-sizing: border-box; }

/* =========================================================================
   2. Typography
   ========================================================================= */

/* gp.academy sets headlines LIGHT with negative tracking — the single most
   recognisable trait of the brand's type. Bold belongs to inline emphasis,
   not to headings. */
h1, h2, h3, h4 {
  color: var(--gp-ink);
  font-weight: 400;
  letter-spacing: -0.011em;
  text-wrap: balance;
}
h1 {
  font-size: 2.1rem;
  line-height: 1.15;
  font-weight: 300;
  letter-spacing: -0.025em;
  margin-bottom: 0.45em;
}
h2, .subject { font-size: 1.35rem; line-height: 1.25; letter-spacing: -0.015em; }
h3 { font-size: 1.1rem; line-height: 1.35; font-weight: 500; }
h4 { font-size: 1rem; font-weight: 500; }

/* Headings that open a new section need air above them. Scoped to direct
   children and article bodies so #reply h2 and .headline keep their own
   spacing. */
#content > h2,
#content > h3,
#content .faq-content .thread-body h2,
#content .faq-content .thread-body h3 { margin-top: 1.5em; }
#content .faq-content .thread-body h2 { font-size: 1.35rem; }
#content .faq-content .thread-body h3 { font-size: 1.1rem; }
#content .thread-body h1 { font-weight: 300; letter-spacing: -0.025em; }

/* Prose measure. Long lines are the other half of the legibility problem. */
#content > p,
.thread-body p,
.faq-content p,
#landing_page .thread-body li { max-width: 68ch; }

#content > p { color: var(--gp-ink-2); margin: 0 0 1em; }

/* Reference numbers, dates, sizes: tabular mono. Ticket numbers read as
   record locators; digits align down a column. */
#ticketTable tbody td:first-child a,
#ticketInfo h1 small,
#clientLogin #ticketno,
.filesize,
.thread-entry .header time {
  font-family: var(--gp-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* One voice for every micro-label, tuned to gp.academy's eyebrow style. */
#ticketTable thead th,
#ticketTable caption,
.headline,
.sidebar section .header,
.freetext-files .title,
#reply h2 {
  font-size: 0.6875rem;   /* 11px */
  line-height: 1.4;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gp-ink-3);
}

/* --- Links ------------------------------------------------------------ */
a, .link {
  color: var(--gp-brand);
  text-decoration: none;
  text-decoration-color: var(--gp-brand-edge);
  text-underline-offset: 0.18em;
  text-decoration-thickness: from-font;
  transition: color var(--gp-t-color);
}
a:hover, .link:hover {
  color: var(--gp-brand-strong);
  text-decoration: underline;
  text-decoration-color: currentColor;
  cursor: pointer;
}
a:focus-visible,
.link:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[contenteditable]:focus-visible {
  outline: 2px solid var(--gp-brand);
  outline-offset: 2px;
  border-radius: 3px;
}

/* =========================================================================
   3. Helpers  (names are markup contracts — keep all of them)
   ========================================================================= */

.centered     { text-align: center; }
.clear        { clear: both; height: 1px; visibility: hidden; }
.hidden       { display: none; }
.faded        { color: var(--gp-ink-3); }
.flush-right  { text-align: right; }
.flush-left   { text-align: left; }
.bleed        { margin: 0 !important; padding: 0 !important; }
.valign-helper { height: 100%; display: inline-block; vertical-align: middle; }
.truncate {
  display: inline-block;
  width: auto;
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: bottom;
}
.row { }
.span4, .span8 { display: inline-block; vertical-align: top; margin: 0 1%; }
.span4 { width: 29.5%; }
.span8 { width: 66%; }

/* =========================================================================
   4. Page frame
   ========================================================================= */

body { background: var(--gp-page); }

/* Pin the footer to the viewport bottom on short pages. The body's flow
   children are #container then #footer (#overlay/#loading are fixed and
   scripts render nothing), so a flex column with the container growing
   keeps the footer at the bottom edge of every screen instead of floating
   mid-page after short content. */
body {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}
#container { flex: 1 0 auto; }
#footer { flex-shrink: 0; }

#container {
  width: 100%;
  max-width: var(--gp-width);
  margin: 0 auto;
  padding: 0 var(--gp-pad);
  background: transparent;
  box-shadow: none;
}

/* --- Site bar: logo + navigation + account, one capsule ----------------- */
/* gp.academy's header is a single rounded capsule holding the logo at the
   left, the nav in the middle, and one pill CTA at the right. The portal
   copies that: header.inc.php wraps #header and #nav in .site-bar, and
   #header is dissolved with display:contents so the logo and the account
   cluster become flex items of the bar alongside #nav — no DOM reordering,
   so every conditional in the template still emits exactly what it did. */
.site-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 20px;
  margin: 18px 0 0;
  padding: 7px 10px 7px 20px;
  background: var(--gp-surface);
  border: 1px solid var(--gp-line);
  border-radius: var(--gp-r-pill);
}
/* The template emits an <hr> in place of #nav when there is no nav, and a
   float-clearing div that the flex row makes redundant. */
.site-bar > hr,
.site-bar > .clear { display: none; }

#header {
  display: contents;
  position: static;
  height: auto;
  padding: 0;
}
#header #logo {
  order: 1;
  height: auto;
  /* Zero basis so both end zones resolve to the SAME width and the nav lands
     on the bar's true centre; min-width keeps either end from being squashed
     below its content (whereupon centring degrades rather than breaking). */
  flex: 1 1 0;
  min-width: max-content;
  display: inline-flex;
  align-items: center;
}
#header #logo:hover { text-decoration: none; }
#header #logo img {
  max-height: 40px;
  max-width: 240px;
  width: auto;
  height: auto;
  vertical-align: middle;
}
/* Account cluster / sign-in, anchored right. */
#header .pull-right {
  order: 3;
  float: none;
  flex: 1 1 0;
  min-width: max-content;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 4px 14px;
}
#header p {
  width: auto;
  margin: 0;
  padding: 0;
  font-size: 0.8125rem;
  color: var(--gp-ink-3);
}
#header p:empty { display: none; }
/* The template always emits a second <p> for the language flags, holding only
   whitespace when the desk runs one language — so :empty never matches it.
   Keying on "has no element children" collapses it, and still shows it when
   flags are actually rendered. */
#header .pull-right > p:not(:has(*)) { display: none; }
#header p + p { margin-top: 0; }
#header p a { white-space: nowrap; color: var(--gp-brand); }
/* Signed in, the template emits "Name | Profile | Tickets (n) - Sign Out" as
   one run of text and links with literal separators. Wrapping it in a soft
   chip gives the bar a defined right end — the role gp.academy's CTA pill
   plays — without touching those separators. Excluded when the cluster holds
   the sign-in pill, which is its own terminus. */
#header .pull-right > p:has(a):not(:has(.signin-button)) {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 7px 15px;
  background: var(--gp-page);
  border: 1px solid var(--gp-line-soft);
  border-radius: var(--gp-r-pill);
  color: var(--gp-ink-2);
}
/* The template used to separate these with literal "|" and "-" text, which no
   selector can reach; they are drawn here instead, so the cluster is both
   narrower and adjustable. */
.acct-name { color: var(--gp-ink); font-weight: 500; }
.acct-link + .acct-link::before,
.acct-name + .acct-link::before {
  content: "";
  display: inline-block;
  width: 1px;
  height: 0.9em;
  margin-right: 9px;
  vertical-align: -0.1em;
  background: var(--gp-line);
}
/* Tickets is already a nav item two hundred pixels away; in the bar it only
   pushed the cluster wide enough to knock the nav off centre. It stays in the
   collapsed menu, where there is room. */
@media (min-width: 1151px) {
  #header .acct-tickets { display: none; }
}

/* The one pill CTA at the right of the bar — gp.academy's "Inquire now". */
.signin-button {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 9px 20px;
  background: var(--gp-brand);
  border: 1px solid var(--gp-brand);
  border-radius: var(--gp-r-pill);
  color: #fff !important;
  font-size: 0.9375rem;
  font-weight: 500;
  white-space: nowrap;
  transition: background-color var(--gp-t-color), border-color var(--gp-t-color),
              transform var(--gp-t-move);
}
.signin-button::after { content: "\2192"; font-size: 0.9em; }   /* → */
.signin-button:hover {
  background: var(--gp-brand-strong);
  border-color: var(--gp-brand-strong);
  color: #fff !important;
  text-decoration: none;
}
.signin-button:active { transform: scale(0.98); }

/* --- Menu toggle -------------------------------------------------------- */
/* A checkbox drives the mobile menu so it works with no JavaScript at all —
   the client portal loads no pjax, so nothing re-renders the header behind
   our back, and a nav that depends on scripts is a nav that can fail. The
   input stays 1px and focusable (not display:none) so it remains reachable
   by keyboard and the label picks up its focus ring. */
#nav-toggle {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  padding: 0;
  opacity: 0;
  appearance: none;
  -webkit-appearance: none;
  border: 0;
}
.nav-toggle-btn {
  display: none;         /* shown by the media query below */
  order: 4;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  flex: none;
  border: 1px solid var(--gp-line);
  border-radius: 50%;
  color: var(--gp-ink);
  cursor: pointer;
  transition: background-color var(--gp-t-color), border-color var(--gp-t-color);
}
.nav-toggle-btn::before {
  font-family: FontAwesome;
  font-style: normal;
  font-weight: normal;
  content: "\f0c9";      /* reorder (hamburger) */
  font-size: 15px;
  line-height: 1;
}
.nav-toggle-btn:hover {
  background: var(--gp-brand-tint);
  border-color: var(--gp-brand-edge);
}
#nav-toggle:checked ~ #header .nav-toggle-btn {
  background: var(--gp-brand);
  border-color: var(--gp-brand);
  color: #fff;
}
#nav-toggle:checked ~ #header .nav-toggle-btn::before { content: "\f00d"; }  /* × */
#nav-toggle:focus-visible ~ #header .nav-toggle-btn {
  outline: 2px solid var(--gp-brand);
  outline-offset: 2px;
}

/* --- Primary navigation ------------------------------------------------- */
/* Pills inside the bar; the active item is filled sage. Icons come from the
   Font Awesome build the page already loads. */
#nav {
  order: 2;
  flex: 0 0 auto;
  margin: 0;
  padding: 0;
  height: auto;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  white-space: normal;
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  width: auto;
  max-width: 100%;
}
#nav li { margin: 0; padding: 0; list-style: none; display: block; }
#nav li a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  width: auto;
  height: auto;
  min-height: 40px;          /* 48px with capsule padding — touch target */
  line-height: 1.3;
  text-align: left;
  padding: 9px 14px;
  margin: 0;
  color: var(--gp-ink-2);
  font-size: 0.875rem;
  font-weight: 500;
  border-radius: var(--gp-r-pill);
  background: none;
  transition: background-color var(--gp-t-color), color var(--gp-t-color);
}
#nav li a::before {
  font-family: FontAwesome;
  font-weight: normal;
  font-style: normal;
  font-size: 0.9em;
  line-height: 1;
  color: var(--gp-ink-3);
  flex: none;
  transform: translateY(var(--gp-icon-nudge));
  transition: color var(--gp-t-color);
}
#nav li a.home::before    { content: "\f015"; }  /* home        */
#nav li a.kb::before      { content: "\f02d"; }  /* book        */
#nav li a.new::before     { content: "\f067"; }  /* plus        */
#nav li a.tickets::before { content: "\f0f6"; }  /* file-text   */
#nav li a.status::before  { content: "\f002"; }  /* search      */

#nav li a:hover {
  background: var(--gp-brand-tint);
  color: var(--gp-brand-strong);
  text-decoration: none;
}
#nav li a:hover::before { color: var(--gp-brand); }
/* --- Which pill is lit --------------------------------------------------- */
/* client.inc.php builds the nav with Home already active —
   `new UserNav($thisclient, 'home')` — and several pages never override it:
   login.php's override is unreachable behind an `if (!$nav)` that is never
   true, and account.php, profile.php, kb/*.php and pages/*.php make no
   setActiveNav() call at all. The result is a lit Home pill on the sign-in,
   register, profile and knowledgebase pages, which misreports where you are.

   Corrected here rather than in PHP to keep this pass presentation-only. Each
   page is identified by markup only it renders. The real fix is four lines of
   setActiveNav() in those entry points; see this commit's message. */
#nav li a.active,
#container:has(.searchbar) #nav li a.kb {
  color: #fff;
  background: var(--gp-brand);
  font-weight: 500;
}
#nav li a.active::before,
#container:has(.searchbar) #nav li a.kb::before { color: rgba(255, 255, 255, 0.85); }
#nav li a.active:hover,
#container:has(.searchbar) #nav li a.kb:hover {
  background: var(--gp-brand-strong);
  color: #fff;
}

/* Unlight the pill the default left lit where it is wrong: on the KB pages
   (the rule above lights the right one instead), and on the sign-in, register
   and profile pages, which no nav item leads to at all. */
#container:has(.searchbar) #nav li a.home.active,
#container:has(.login-row) #nav li a.active,
#container:has(form[action="account.php"]) #nav li a.active,
#container:has(form[action="profile.php"]) #nav li a.active {
  color: var(--gp-ink-2);
  background: none;
  font-weight: 500;
}
#container:has(.searchbar) #nav li a.home.active::before,
#container:has(.login-row) #nav li a.active::before,
#container:has(form[action="account.php"]) #nav li a.active::before,
#container:has(form[action="profile.php"]) #nav li a.active::before {
  color: var(--gp-ink-3);
}
#container:has(.searchbar) #nav li a.home.active:hover,
#container:has(.login-row) #nav li a.active:hover,
#container:has(form[action="account.php"]) #nav li a.active:hover,
#container:has(form[action="profile.php"]) #nav li a.active:hover {
  background: var(--gp-brand-tint);
  color: var(--gp-brand-strong);
}
#container:has(.searchbar) #nav li a.home.active:hover::before,
#container:has(.login-row) #nav li a.active:hover::before,
#container:has(form[action="account.php"]) #nav li a.active:hover::before,
#container:has(form[action="profile.php"]) #nav li a.active:hover::before {
  color: var(--gp-brand);
}
.rtl #nav li a { padding: 9px 14px; margin: 0; background-position: initial; }

/* --- Content column ---------------------------------------------------- */
#content {
  padding: 32px 0 56px;
  margin: 0;
  height: auto !important;
  min-height: 42vh;
}

/* --- Footer ------------------------------------------------------------ */
/* The gp.academy footer is a warm cream-soft band; it also carries the
   site's "Staff Sign In" link, which is the pattern the portal copies for
   the agent panel (footer.inc.php adds .staff-link on every page). */
#footer {
  margin-top: 8px;
  padding: 0;
  text-align: left;
  font-size: 0.875rem;
  color: var(--gp-ink-2);
  background: var(--gp-surface-2);
  border-top: 1px solid var(--gp-line);
}
#footer a { color: var(--gp-ink-2); }
#footer p { margin: 0; }
.footer-inner {
  max-width: var(--gp-width);
  margin: 0 auto;
  padding: 26px var(--gp-pad) 30px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px 28px;
}
.footer-copyright { color: var(--gp-ink-3); }
.footer-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px 22px;
}
/* Staff entrance: quiet but unmissable — a navy ghost pill with an arrow,
   present on every page of the portal. */
.staff-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 38px;
  padding: 7px 16px;
  border: 1px solid var(--gp-navy);
  border-radius: var(--gp-r-pill);
  color: var(--gp-navy) !important;
  font-weight: 500;
  transition: background-color var(--gp-t-color), color var(--gp-t-color);
}
.staff-link::after { content: "\2192"; font-size: 0.9em; }  /* → */
.staff-link:hover {
  background: var(--gp-navy);
  color: #fff !important;
  text-decoration: none;
}
#footer #poweredBy {
  display: block;
  width: 126px;
  height: 23px;
  outline: none;
  text-indent: -9999px;
  margin: 0;
  background: url('../images/poweredby.png') top left no-repeat;
  background-size: auto 20px;
  opacity: 0.45;
  transition: opacity var(--gp-t-color);
}
#footer #poweredBy:hover { opacity: 0.85; }

/* =========================================================================
   5. Buttons and form controls
   ========================================================================= */

/* --- .button family — gp.academy pills --------------------------------- */
/* .blue.button is the primary action in every template that uses it,
   .green.button the secondary; mapped to the brand's filled-sage and
   ghost-ring pills. Light sage (#7c9f86) from the marketing site fails
   contrast under white text (2.9:1), so fills use full sage. */
.button,
.button:visited {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 10px 22px;
  max-width: 100%;
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.3;
  text-align: center;
  text-decoration: none;
  text-shadow: none;
  border: 1px solid var(--gp-brand);
  border-radius: var(--gp-r-pill);
  background: var(--gp-brand);
  color: #fff;
  box-shadow: none;
  position: relative;
  cursor: pointer;
  font-family: inherit;
  transition: background-color var(--gp-t-color), border-color var(--gp-t-color),
              color var(--gp-t-color), transform var(--gp-t-move);
}
.button:hover {
  background: var(--gp-brand-strong);
  border-color: var(--gp-brand-strong);
  color: #fff;
  text-decoration: none;
}
.button:active { top: 0; box-shadow: none; transform: scale(0.98); }

.button, .button:visited,
.blue.button, .blue.button:visited {
  background: var(--gp-brand);
  border-color: var(--gp-brand);
  color: #fff;
}
.blue.button:hover {
  background: var(--gp-brand-strong);
  border-color: var(--gp-brand-strong);
}
.green.button, .green.button:visited {
  background: transparent;
  border-color: rgba(27, 34, 48, 0.35);
  color: var(--gp-ink);
}
.green.button:hover {
  background: var(--gp-surface);
  border-color: var(--gp-ink);
  color: var(--gp-ink);
}

/* --- Native buttons ----------------------------------------------------- */
input[type="submit"],
button[type="submit"],
.btn {
  min-height: 44px;
  padding: 10px 22px;
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.3;
  color: #fff;
  background: var(--gp-brand);
  border: 1px solid var(--gp-brand);
  border-radius: var(--gp-r-pill);
  transition: background-color var(--gp-t-color), border-color var(--gp-t-color),
              transform var(--gp-t-move);
}
input[type="submit"]:hover,
button[type="submit"]:hover,
.btn:hover {
  background: var(--gp-brand-strong);
  border-color: var(--gp-brand-strong);
}
input[type="reset"],
input[type="button"],
button {
  min-height: 44px;
  padding: 10px 18px;
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.3;
  color: var(--gp-ink-2);
  background: transparent;
  border: 1px solid var(--gp-line);
  border-radius: var(--gp-r-pill);
  transition: background-color var(--gp-t-color), border-color var(--gp-t-color),
              color var(--gp-t-color), transform var(--gp-t-move);
}
input[type="reset"]:hover,
input[type="button"]:hover,
button:hover {
  background: var(--gp-surface);
  border-color: rgba(27, 34, 48, 0.4);
  color: var(--gp-ink);
}
input[type="submit"]:active,
input[type="reset"]:active,
input[type="button"]:active,
button:active,
.btn:active { transform: scale(0.98); }
input[type="submit"][disabled],
input[type="button"][disabled],
input[type="reset"][disabled],
button[disabled] {
  opacity: 0.55;
  cursor: default;
}

/* js/osticket.js flags an edited form with an inline color:red on the
   submit button, and clears it on reset. Inline colour wins, so give the
   button a light ground the red can be read against and carry the signal
   in the border too. */
input[type="submit"][style*="color"] {
  background: var(--gp-surface);
  border: 2px solid var(--gp-warn);
  font-weight: 600;
}

/* Action rows */
/* Action rows. These MUST stay direct-child selectors: as descendant
   selectors they also matched the last <p> inside Redactor's contenteditable
   (which is :last-child of .redactor-in), turning the paragraph the user types
   into a centred flex container with a 20px top margin — so text centred
   itself and the caret sat below the placeholder instead of over it. */
p.buttons,
#reply > p:last-child,
#ticketForm > p:last-child {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  align-items: center;
  margin: 20px 0 0;
}

/* --- Text inputs -------------------------------------------------------- */
input[type="text"],
input[type="password"],
input[type="email"],
input[type="tel"],
input[type="url"],
input[type="number"],
input[type="search"],
input[type="date"],
input[type="time"],
select,
textarea {
  min-height: 44px;
  padding: 10px 14px;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--gp-ink);
  background: var(--gp-surface);
  border: 1px solid rgba(27, 34, 48, 0.18);
  border-radius: var(--gp-r-sm);
  max-width: 100%;
  transition: border-color var(--gp-t-color), box-shadow var(--gp-t-color);
}
textarea { min-height: 120px; padding: 12px 14px; line-height: 1.55; }
select {
  padding-right: 34px;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--gp-ink-3) 50%),
    linear-gradient(135deg, var(--gp-ink-3) 50%, transparent 50%);
  background-position: right 17px center, right 12px center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  -webkit-appearance: none;
  appearance: none;
}
.rtl select {
  padding-right: 14px;
  padding-left: 34px;
  background-position: left 12px center, left 17px center;
}
input[type="text"]:hover,
input[type="password"]:hover,
select:hover,
textarea:hover { border-color: rgba(27, 34, 48, 0.4); }

input:focus,
select:focus,
textarea:focus {
  border-color: var(--gp-brand);
  box-shadow: 0 0 0 3px var(--gp-brand-ring);
  outline: none;
}
input::placeholder, textarea::placeholder { color: var(--gp-ink-3); }
input[type="file"] { min-height: 0; padding: 0; border: 0; font-size: 0.9375rem; }

/* The contenteditable holds USER content, not form furniture — anything the
   form rules above could reach into it is reset here. Kept next to the editor
   styling so the two are read together. */
#content .redactor-in em {
  color: inherit;
  font-size: inherit;
}
/* Editor block spacing. Redactor sets no paragraph margins of its own, so a
   <p> kept the UA default 1em top margin — which at the editor's 15px font
   pushed the first line, and the caret, 15px below the placeholder. Redactor
   generates the placeholder on .redactor-in itself, so it sits at the padding
   box top and the two never lined up: you could only type under the
   placeholder, never over it. Zero the leading margin and space blocks from
   the bottom instead, the way a text editor should. */
#content .redactor-in p,
#content .redactor-in ul,
#content .redactor-in ol,
#content .redactor-in blockquote,
#content .redactor-in pre {
  margin: 0 0 0.7em;
}
#content .redactor-in > :first-child { margin-top: 0; }
#content .redactor-in > :last-child { margin-bottom: 0; }

/* Redactor draws its own chrome; match it to the inputs above. Raised to
   #content specificity because css/redactor.css loads after this file. */
#content .redactor-box.redactor-styles-on {
  border: 1px solid rgba(27, 34, 48, 0.18);
  border-radius: var(--gp-r-sm);
  overflow: hidden;
  background: var(--gp-surface);
}
#content .redactor-box.redactor-styles-on:focus-within {
  border-color: var(--gp-brand);
  box-shadow: 0 0 0 3px var(--gp-brand-ring);
}
#content .redactor-box.redactor-styles-on .redactor-toolbar {
  background: var(--gp-page);
  border-bottom: 1px solid var(--gp-line);
  padding: 4px 6px;
  border-radius: 0;
}
#content .redactor-box .redactor-in {
  padding: 12px 14px;
  min-height: 140px;
  font-size: 0.9375rem;
  line-height: 1.6;
}

/* Upload widget — css/filedrop.css loads after this file. */
#content .filedrop { padding-bottom: 10px; }
#content .filedrop .dropzone {
  border: 1px dashed var(--gp-brand-edge);
  border-radius: var(--gp-r-sm);
  background: var(--gp-brand-tint);
  color: var(--gp-ink-2);
  padding: 14px 16px;
  font-size: 0.875rem;
}
#content .filedrop .dropzone a { color: var(--gp-brand); font-weight: 500; }
#content .filedrop .files:not(:empty) {
  border: 1px solid var(--gp-line);
  border-radius: var(--gp-r-sm) var(--gp-r-sm) 0 0;
  padding: 6px;
}
#content .filedrop .files:not(:empty) + .dropzone {
  border-top: none;
  border-radius: 0 0 var(--gp-r-sm) var(--gp-r-sm);
}

/* Field furniture inside forms */
label.required, span.required { font-weight: 600; }
.form-header h3 { margin-bottom: 2px; }
.form-header > div { color: var(--gp-ink-2); font-size: 0.9375rem; }

.uploads { display: inline-block; padding-right: 20px; }
.uploads label { padding: 3px 10px 3px 3px; width: auto !important; }

.freetext-files {
  padding: 14px 16px;
  margin-top: 12px;
  border: 1px solid var(--gp-line);
  border-radius: var(--gp-r-sm);
  background: var(--gp-surface);
}
.freetext-files .file {
  margin-right: 10px;
  display: inline-block;
  width: 48%;
  padding-top: 0.2em;
}
.freetext-files .title { margin-bottom: 0.5em; }

/* =========================================================================
   6. Alerts, notices, and errors
   ========================================================================= */

/* Auto height (upstream clipped at 16px), Font Awesome icons, semantic
   left edge — palette harmonised with the brand: success speaks sage,
   info speaks the staff navy. */
#msg_notice, #msg_warning, #msg_error, #msg_info,
.notice_bar, .warning_bar, .error_bar, .warning-banner {
  position: relative;
  display: block;
  height: auto;
  min-height: 0;
  line-height: 1.5;
  margin: 0 0 16px;
  padding: 12px 16px 12px 42px;
  font-size: 0.9375rem;
  border: 1px solid;
  border-left-width: 3px;
  border-radius: var(--gp-r-sm);
  background-image: none;
}
#msg_notice::before, #msg_warning::before, #msg_error::before,
#msg_info::before, .notice_bar::before, .warning_bar::before,
.error_bar::before, .warning-banner::before {
  position: absolute;
  left: 15px;
  top: 13px;
  font-family: FontAwesome;
  font-style: normal;
  font-weight: normal;
  font-size: 15px;
  line-height: 1.2;
}
#msg_notice, .notice_bar {
  color: var(--gp-ok);
  background-color: var(--gp-ok-bg);
  border-color: var(--gp-ok-edge);
  border-left-color: var(--gp-ok);
}
#msg_notice::before, .notice_bar::before { content: "\f058"; }  /* ok-sign */

#msg_warning, .warning_bar, .warning-banner {
  color: var(--gp-warn);
  background-color: var(--gp-warn-bg);
  border-color: var(--gp-warn-edge);
  border-left-color: var(--gp-warn);
}
#msg_warning::before, .warning_bar::before,
.warning-banner::before { content: "\f071"; }                   /* warning */

#msg_error, .error_bar {
  color: var(--gp-err);
  background-color: var(--gp-err-bg);
  border-color: var(--gp-err-edge);
  border-left-color: var(--gp-err);
}
#msg_error::before, .error_bar::before { content: "\f06a"; }     /* excl.   */

#msg_info {
  color: var(--gp-info);
  background-color: var(--gp-info-bg);
  border-color: var(--gp-info-edge);
  border-left-color: var(--gp-info);
}
/* view.inc.php puts its own icon-compass in #msg_info; don't double up. */
#msg_info::before { content: none; }
#msg_info { padding-left: 16px; }
#msg_info .icon-2x { color: var(--gp-info); margin-right: 12px; }
#msg_notice a, #msg_warning a, #msg_error a, #msg_info a { color: inherit; }

/* The banners the header emits sit above the content column. */
.notice_bar, .warning_bar, .error_bar { margin: 16px 0 0; }

.warning {
  background: var(--gp-warn-bg);
  border: 1px solid var(--gp-warn-edge);
  border-radius: var(--gp-r-sm);
  padding: 10px 14px;
  font-style: normal;
  color: var(--gp-ink-2);
}
.warning strong {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.8125rem;
  color: var(--gp-warn);
  font-style: normal;
}

/* Inline field errors. font.error is emitted by the ticket form. */
.error, font.error { color: var(--gp-err); font-size: 0.875rem; }
.error input { border-color: var(--gp-err); }
div.error { margin-top: 4px; }

/* =========================================================================
   7. Landing page
   ========================================================================= */

/* Centered hero, gp.academy style: eyebrow, light headline, the KB search
   as the hero control, then the CTA pill pair, then a warm card holding the
   featured questions. The DOM order (sidebar first, then main-content, then
   the featured-articles block) is untouched — the sidebar's CTA conditionals
   stay in sidebar.tmpl.php — and flex `order` does the arranging. */
#landing_page {
  overflow: visible;
  display: flex;
  flex-direction: column;
}
.main-content { width: auto; }
#landing_page .main-content {
  order: 1;
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 26px 0 4px;
}
.hero-eyebrow {
  order: 1;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gp-ink-3);
  margin-bottom: 16px;
}
#landing_page .thread-body {
  order: 2;
  padding: 0;
  background: transparent;
  max-width: 62ch;
}
#landing_page .thread-body h1 {
  font-size: clamp(2rem, 4.5vw, 2.75rem);
  margin-bottom: 14px;
}
#landing_page .thread-body p { margin-left: auto; margin-right: auto; color: var(--gp-ink-2); }
#landing_page .search-form {
  order: 3;
  width: 100%;
  padding: 18px 0 2px;
  display: flex;
  justify-content: center;
}
#landing_page .search-form form { width: min(580px, 100%); }
#landing_page .search-form .search { flex: 1 1 240px; width: auto; }

/* The sidebar block becomes the hero CTA row + the featured-questions card. */
#landing_page .sidebar {
  order: 2;
  float: none !important;
  width: 100%;
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
}
#landing_page .front-page-button {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin: 14px 0 40px;
}
#landing_page .front-page-button p { margin: 0; }
/* sidebar.tmpl.php puts an inline display:block on the CTA anchors. */
#landing_page .front-page-button .button {
  display: inline-flex !important;
  width: auto;
  min-width: 220px;
}
#landing_page .sidebar .content {
  width: 100%;
  padding: 30px 34px;
  background: var(--gp-surface-2);
  border: 1px solid var(--gp-line);
  border-radius: calc(var(--gp-r) + 6px);
  display: flex;
  flex-wrap: wrap;
  gap: 22px 56px;
  text-align: left;
}
#landing_page .sidebar .content section { flex: 1 1 240px; min-width: 0; }
#landing_page .sidebar section + section {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

#landing_page > .clear { order: 3; }
/* index.php separates the featured-articles block with a .clear plus two
   <br>s; the warm card above already provides the section break. */
#landing_page > .clear + div { order: 4; border-top: 0; padding-top: 34px; margin-top: 0; }
#landing_page > .clear + div > br { display: none; }
#landing_page > .clear + div > h1 { font-size: 1.5rem; margin-bottom: 8px; }
#landing_page h1,
#landing_page h2,
#landing_page h3 { margin-bottom: 12px; }

.search-form { padding: 0 0 24px; }
.search-form form { display: flex; gap: 10px; flex-wrap: wrap; }
.searchbar .search,
.search-form .search {
  display: inline-block;
  width: 400px;
  max-width: 100%;
  flex: 1 1 240px;
  border-radius: var(--gp-r-pill);
  border: 1px solid rgba(27, 34, 48, 0.18);
  padding: 10px 18px;
  box-shadow: none;
  background: var(--gp-surface);
}
.searchbar .search {
  width: 100%;
  box-sizing: border-box;
  margin-bottom: 10px;
  flex: none;
}
.search-form .button { flex: none; }

/* Upstream #new_ticket / #check_status blocks — no current template emits
   them, but a customised landing page may; keep them harmless. */
#landing_page #new_ticket,
#landing_page #check_status {
  width: 295px;
  max-width: 100%;
  padding-left: 75px;
  margin-top: 40px;
}
#landing_page #new_ticket {
  background: url('../images/new_ticket_icon.png') top left no-repeat;
}
#landing_page #check_status {
  background: url('../images/check_status_icon.png') top left no-repeat;
}

/* --- Featured KB articles ---------------------------------------------- */
.featured-category {
  margin-top: 4px;
  margin-bottom: 20px;
  width: 49%;
  display: inline-block;
  vertical-align: top;
  padding-right: 28px;
}
.featured-category i {
  color: var(--gp-brand);
  text-shadow: none;
  display: inline-block;
  vertical-align: middle;
  font-size: 1.05em !important;
  margin-right: 8px;
}
.category-name {
  display: inline-block;
  font-weight: 500;
  font-size: 1.05rem;
  letter-spacing: -0.005em;
  color: var(--gp-ink);
}
.article-headline {
  margin-left: 0;
  padding: 13px 0;
  border-top: 1px solid var(--gp-line-soft);
}
.article-headline:first-of-type { margin-top: 10px; }
.article-title { font-weight: 500; line-height: 1.4; }
/* Upstream clipped the teaser with a hard height:3em, which cut text
   mid-word with no ellipsis. Clamp it properly instead. */
.article-teaser {
  font-size: 0.875rem;
  line-height: 1.55;
  height: auto;
  max-height: none;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  color: var(--gp-ink-3);
  margin-top: 2px;
}
.faq-content .article-title {
  font-size: 1.6rem;
  font-weight: 300;
  line-height: 1.2;
  letter-spacing: -0.025em;
  margin-top: 4px;
}

/* =========================================================================
   8. Sidebar
   ========================================================================= */

.sidebar {
  margin-bottom: 24px;
  margin-left: 36px;
  width: 284px;
}
.front-page-button { display: grid; gap: 10px; margin-bottom: 22px; }
.front-page-button p { margin: 0; }
.front-page-button .button { width: 100%; max-width: none; }

.sidebar .content {
  padding: 20px 22px;
  border: 1px solid var(--gp-line);
  border-radius: var(--gp-r);
  background: var(--gp-surface);
}
.sidebar .content:empty { display: none; }
.sidebar section .header { margin-bottom: 8px; }
.sidebar section strong {
  display: block;
  margin-bottom: 8px;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gp-ink-3);
}
.sidebar section + section {
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid var(--gp-line-soft);
}
.sidebar section > div { padding: 4px 0; line-height: 1.45; }
.sidebar .content a { color: var(--gp-brand); }
.sidebar select { width: 100%; max-width: 100%; }

/* =========================================================================
   9. Knowledgebase
   ========================================================================= */

#breadcrumbs {
  color: var(--gp-ink-3);
  font-size: 0.875rem;
  margin-bottom: 16px;
}
#breadcrumbs a { color: var(--gp-ink-2); }

#kb { margin: 4px 0 0; padding: 0; overflow: hidden; }
#kb > li {
  position: relative;
  padding: 22px 0;
  height: auto !important;
  overflow: hidden;
  margin: 0;
  background: none;
  border-bottom: 1px solid var(--gp-line);
  display: block;
  list-style: none;
}
#kb > li h4 { margin-bottom: 2px; }
#kb > li h4 a { font-size: 1.1rem; font-weight: 500; }
#kb > li h4 span { color: var(--gp-ink-3); }
/* Was a 32px folder PNG; now the Font Awesome folder already on the page. */
#kb > li > i {
  display: block;
  width: 34px;
  height: 34px;
  float: left;
  margin-right: 6px;
  background: var(--gp-brand-tint);
  border-radius: 50%;
  color: var(--gp-brand);
  font-size: 15px;
  line-height: 34px;
  text-align: center;
}
#kb > li > i::before { font-family: FontAwesome; content: "\f07b"; }
.rtl #kb > li > i { float: right; margin-right: 0; margin-left: 6px; }
#kb > li > div { margin-left: 48px; }
#kb .faded { color: var(--gp-ink-2); font-size: 0.9375rem; }

.popular-faq { padding: 4px 0 4px 0; line-height: 1.45; }
.popular-faq i { color: var(--gp-ink-3); margin-right: 6px; }

#faq { clear: both; margin: 0; padding: 0; }
#faq ol {
  font-size: 1rem;
  margin: 12px 0 0;
  padding-left: 0;
  border-top: 1px solid var(--gp-line);
}
#faq ol li { list-style: none; margin: 0; padding: 0; color: var(--gp-ink-3); }
#faq ol li a {
  display: block;
  padding: 13px 8px 13px 26px;
  height: auto !important;
  overflow: hidden;
  margin: 0;
  border-bottom: 1px solid var(--gp-line);
  line-height: 1.45;
  background: none;
  position: relative;
  transition: background-color var(--gp-t-color);
}
#faq ol li a::before {
  font-family: FontAwesome;
  content: "\f016";               /* file-alt */
  position: absolute;
  left: 4px;
  top: 13px;
  color: var(--gp-ink-3);
  font-size: 0.9em;
}
#faq ol li a:hover { background-color: var(--gp-brand-tint); text-decoration: none; }
#faq .article-meta { padding: 8px; background: var(--gp-surface-2); }

.faq-content { margin-top: 4px; }
.faq-content .thread-body { background: transparent; }

/* Legacy KB search ids. No current template emits them; harmless to keep. */
#kb-search { padding: 10px 0; overflow: hidden; }
#kb-search div { clear: both; overflow: hidden; padding-top: 5px; }
#kb-search #query, #kb-search #cid { width: 200px; margin-right: 8px; }
#kb-search #topic-id { width: 410px; max-width: 100%; }

/* =========================================================================
   10. Ticket form  (open.inc.php, edit.inc.php, register, profile)
   ========================================================================= */

/* Centred form column, matching the sign-in page. Scoped to "#ticketForm that
   contains a table" so it hits open.inc.php and edit.inc.php but not the bare
   #ticketForm the alerts specimen uses. The fields stay left-aligned inside the
   card — only the column and the page heading are centred. */
#content:has(#ticketForm > table) > h1,
#content:has(#ticketForm > table) > p {
  display: block;
  text-align: center;
  margin-left: auto;
  margin-right: auto;
}
#content:has(#ticketForm > table) > h1 { margin-bottom: 10px; }
#content:has(#ticketForm > table) > p { max-width: 52ch; }
#ticketForm:has(> table) {
  width: 100%;
  max-width: 44rem;
  margin: 26px auto 0;
  padding: 26px 30px 28px;
  background: var(--gp-surface);
  border: 1px solid var(--gp-line);
  border-radius: var(--gp-r);
}
/* The template opens with <td colspan=2><hr>, which is now redundant against
   the card's own top edge. */
#ticketForm:has(> table) > table > tbody:first-of-type > tr:first-child hr { display: none; }
#ticketForm:has(> table) > hr:last-of-type { display: none; }

#ticketForm > table,
#clientLogin table,
table.padded {
  width: 100%;
  max-width: 100%;
}
/* Upstream set table-layout:fixed here, but the first row of every client
   form is a <td colspan="2"><hr>, so fixed layout had no column widths to
   read and split the table 50/50 — leaving a half-width label column.
   Auto layout plus a shrink-to-fit label column instead. */
#ticketForm > table { table-layout: auto; }
#ticketForm > table > tbody > tr > td { padding: 4px 0; }
#ticketForm > table > tbody > tr > td:first-child:not([colspan]) {
  width: 1%;
  white-space: nowrap;
  padding-right: 28px;
  color: var(--gp-ink-2);
}
#ticketForm > table > tbody > tr > td[colspan] { width: auto; white-space: normal; }

#ticketForm div.clear,
#clientLogin div.clear { clear: both; padding: 3px 0; overflow: hidden; }

#ticketForm div label,
#clientLogin div label { display: block; }
#ticketForm div label.required,
#clientLogin div label.required { text-align: left; }
#ticketForm div input,
#clientLogin div input,
#ticketForm div textarea,
#clientLogin div textarea { width: auto; display: block; }
#ticketForm div input[type="file"],
#clientLogin div input[type="file"] { border: 0; }
#ticketForm div select,
#clientLogin div select { display: block; float: none; }

#ticketForm td textarea,
#clientLogin td textarea,
#ticketForm div textarea,
#clientLogin div textarea { width: 100%; max-width: 640px; }

#ticketForm td em,
#clientLogin td em,
#ticketForm div em,
#clientLogin div em { color: var(--gp-ink-3); font-size: 0.875rem; }

#ticketForm label > span:first-child {
  display: inline-block;
  margin-bottom: 6px;
  font-weight: 500;
  color: var(--gp-ink);
}
#ticketForm label > span:first-child.required { font-weight: 600; }

#ticketForm div div.captchaRow,
#clientLogin div div.captchaRow { line-height: normal; }
#ticketForm div div.captchaRow input,
#clientLogin div div.captchaRow input { position: static; top: 0; }
tr.captchaRow td { padding-top: 14px; }
#ticketForm td .captcha,
#clientLogin td .captcha,
#ticketForm div .captcha,
#clientLogin div .captcha {
  width: 88px;
  height: 31px;
  background: var(--gp-ink);
  border-radius: 4px;
  overflow: hidden;
  display: inline-block;
  float: none;
  vertical-align: middle;
  margin-right: 12px;
}
#ticketForm td label.inline,
#clientLogin td label.inline,
#ticketForm div label.inline,
#clientLogin div label.inline { width: auto; padding: 0 10px; display: inline; }

#ticketForm div.error input,
#clientLogin div.error input { border-color: var(--gp-err); }
#ticketForm div.error label,
#clientLogin div.error label { color: var(--gp-err); }

/* Section dividers inside the stacked form tables. */
#ticketForm .form-header,
table.padded h3 { margin-top: 4px; }
table.padded tr > td,
table.padded tr > th { height: auto; padding: 6px 12px 6px 0; }
table.padded h3 { font-size: 1.1rem; }

/* The ticket-form variant of #ticketTable (upstream kept both). */
#ticketTable th.required,
#ticketTable td.required { font-weight: 600; text-align: left; }

/* =========================================================================
   11. Ticket list  (tickets.inc.php)
   ========================================================================= */

.search.well {
  padding: 16px 18px;
  background: var(--gp-surface);
  border: 1px solid var(--gp-line);
  border-radius: var(--gp-r);
  margin: 0 0 26px;
}
#ticketSearchForm { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; float: none; padding: 0; }
#ticketSearchForm input[type="text"] { flex: 1 1 220px; min-width: 0; border-radius: var(--gp-r-pill); padding-left: 18px; }
#ticketSearchForm .pull-right {
  float: none;
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.875rem;
  color: var(--gp-ink-2);
}
.search.well + h1 { margin-top: 0 !important; }

/* Page heading rows that carry a floated action cluster. */
#content > h1,
#ticketInfo h1 {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px 14px;
}
#content > h1 > .pull-right,
#ticketInfo h1 > .pull-right { float: none; margin-left: auto; }

.states small { font-size: 0.875rem; font-weight: 500; }
.states i { color: var(--gp-ink-3); margin-right: 2px; }
.state { color: var(--gp-ink-2); }
.active.state {
  font-weight: 600;
  color: var(--gp-brand-strong);
  text-decoration: underline;
  text-decoration-color: var(--gp-brand);
  text-decoration-thickness: 2px;
  text-underline-offset: 5px;
}
i.refresh { color: var(--gp-ink-3); font-size: 0.75em; vertical-align: middle; }
#content > h1 a:hover i.refresh { color: var(--gp-brand); }

/* --- The table ----------------------------------------------------------- */
/* Hairline rules only where they separate data — matches the flat list
   treatment gp.academy uses on its beige sections. */
#ticketTable {
  width: 100%;
  border: 0;
  border-top: 1px solid var(--gp-line);
  margin-top: 4px;
}
#ticketTable caption {
  padding: 0 0 10px;
  text-align: left;
  color: var(--gp-ink-3);
  background: none;
  border: 0;
  caption-side: top;
}
#ticketTable thead th {
  height: auto;
  line-height: 1.4;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--gp-line);
  padding: 11px 12px 11px 0;
  white-space: normal;
  vertical-align: bottom;
}
#ticketTable thead th a { color: var(--gp-ink-3); }
#ticketTable thead th a:hover { color: var(--gp-brand); text-decoration: none; }
#ticketTable thead th i { opacity: 0.5; font-size: 0.9em; }
#ticketTable thead th a:hover i { opacity: 1; }

#ticketTable td {
  padding: 13px 12px 13px 0;
  border: 0;
  border-bottom: 1px solid var(--gp-line-soft);
  vertical-align: middle;
}
#ticketTable tbody tr:hover td { background: var(--gp-brand-tint); }
#ticketTable tr.alt td { background: transparent; }

/* Column voices. The five columns are fixed in the template. */
#ticketTable tbody td:first-child a { font-weight: 500; letter-spacing: -0.01em; }
#ticketTable tbody td:nth-child(2) {
  font-family: var(--gp-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.8125rem;
  color: var(--gp-ink-3);
  white-space: nowrap;
}
#ticketTable tbody td:nth-child(3) {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gp-ink-2);
}
#ticketTable tbody td:nth-child(4) { color: var(--gp-ink); }
#ticketTable tbody td:nth-child(4) .link { color: var(--gp-brand); }
/* tickets.inc.php pins the subject cell to an inline max-height:1.2em, which
   clips descenders at any line-height above 1.2. .truncate already keeps it
   to one line, so the cap is redundant — and it needs !important to beat the
   inline style. */
#ticketTable tbody td .truncate {
  max-height: none !important;
  line-height: 1.45;
}
#ticketTable tbody td:nth-child(5) { color: var(--gp-ink-3); font-size: 0.875rem; }
/* The "no records" row spans all five, so keep it plain. */
#ticketTable tbody td[colspan] {
  font: inherit;
  letter-spacing: normal;
  text-transform: none;
  color: var(--gp-ink-3);
  padding: 28px 0;
}

/* --- Source-type and file icons ------------------------------------------ */
.Icon {
  width: auto;
  padding-left: 0;
  background-image: none !important;
  color: var(--gp-brand);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
.Icon::before {
  font-family: FontAwesome;
  font-style: normal;
  font-weight: normal;
  font-size: 0.9em;
  line-height: 1;
  color: var(--gp-ink-3);
  flex: none;
  transform: translateY(var(--gp-icon-nudge));
}
.Icon.Ticket::before,
.Icon.webTicket::before   { content: "\f0ac"; }   /* globe     */
.Icon.emailTicket::before { content: "\f003"; }   /* envelope  */
.Icon.phoneTicket::before { content: "\f095"; }   /* phone     */
.Icon.otherTicket::before,
.Icon.apiTicket::before    { content: "\f013"; }  /* cog       */
.Icon.attachment::before,
.Icon.file::before         { content: "\f0c6"; }  /* paperclip */
.Icon.refresh::before      { content: "\f021"; }  /* refresh   */
.Icon.thread::before       { content: "\f0e5"; }  /* comment   */
.Icon.thread { font-weight: 600; font-size: 1em; }
.Icon:hover { text-decoration: underline; }
.Icon:hover::before { color: var(--gp-brand); }
.rtl .Icon { padding-left: 0; padding-right: 0; }

/* =========================================================================
   12. Ticket view  (view.inc.php)
   ========================================================================= */

#ticketInfo { width: 100%; }
#ticketInfo h1 {
  padding-bottom: 16px;
  margin-bottom: 20px;
  border-bottom: 1px solid var(--gp-line);
}
#ticketInfo h1 b { font-weight: 500; letter-spacing: -0.02em; }
#ticketInfo h1 small {
  font-weight: 400;
  font-size: 1rem;
  color: var(--gp-ink-3);
  letter-spacing: 0.02em;
}
#ticketInfo > tbody > tr > td { padding-right: 28px; }
#ticketInfo > tbody > tr > td:last-child { padding-right: 0; }

.infoTable,
table.custom-data {
  background: none;
  width: 100%;
  margin-top: 0;
}
table.custom-data { margin-top: 20px; }
.infoTable th,
table.custom-data th {
  text-align: left;
  padding: 7px 14px 7px 0;
  width: 34%;
  background: none;
  color: var(--gp-ink-3);
  font-weight: 400;
  font-size: 0.875rem;
  white-space: nowrap;
}
table.custom-data th { width: 30%; }
.infoTable td,
table.custom-data td { padding: 7px 0; color: var(--gp-ink); }
.infoTable tr + tr th,
.infoTable tr + tr td,
table.custom-data tr + tr th,
table.custom-data tr + tr td { border-top: 1px solid var(--gp-line-soft); }

table .headline,
table.custom-data .headline {
  border-bottom: 1px solid var(--gp-line);
  background: none;
  padding: 0 0 8px;
}
.infoTable thead .headline,
table.custom-data thead .headline,
table.custom-data tr:first-child .headline { border-top: 0; }

/* --- Thread --------------------------------------------------------------- */
/* Each entry is a white card on the cream page; the agent's replies carry
   a sage-tinted header so the two voices stay distinguishable without
   shouting. */
#ticketThread {
  z-index: 0;
  position: relative;
  border-bottom: 0;
}
#ticketThread::before { content: none; }

.thread-entry { margin-bottom: 18px; }
.thread-entry::before,
.thread-entry::after { content: none; }      /* old timeline masks */

.thread-entry.avatar { margin-left: var(--gp-gutter); }
.thread-entry.response.avatar { margin-right: var(--gp-gutter); margin-left: 0; }
.thread-entry > .avatar {
  margin-left: calc(-1 * var(--gp-gutter));
  display: inline-block;
  width: 40px;
  height: auto;
  border-radius: 50%;
  overflow: hidden;
}
.thread-entry.response > .avatar {
  margin-left: initial;
  margin-right: calc(-1 * var(--gp-gutter));
}
img.avatar { border-radius: inherit; }
.avatar > img.avatar { width: 100%; height: auto; }

.thread-entry .header {
  position: relative;
  padding: 11px 16px;
  border: 1px solid var(--gp-line);
  border-radius: var(--gp-r) var(--gp-r) 0 0;
  background: var(--gp-surface-2);
  font-size: 0.875rem;
  color: var(--gp-ink-2);
  line-height: 1.5;
}
.thread-entry .header b { color: var(--gp-ink); font-weight: 600; }
.thread-entry .header time { font-size: 0.8125rem; color: var(--gp-ink-3); }
/* Retire the CSS-triangle speech tails. */
.thread-entry.avatar .header::before,
.thread-entry.avatar .header::after,
.thread-entry.avatar.message .header::before,
.thread-entry.avatar.message .header::after,
.thread-entry.avatar.response .header::after { content: none; border: 0; }

.thread-entry.message .header { background: var(--gp-surface-2); }
.thread-entry.response .header {
  background: var(--gp-brand-tint);
  border-color: var(--gp-brand-edge);
}
.thread-entry.response .header b { color: var(--gp-brand-strong); }
.thread-entry .header .title {
  max-width: 500px;
  vertical-align: bottom;
  display: inline-block;
  margin-left: 12px;
  font-size: 0.8125rem;
}
.rtl .thread-entry .header .title { margin-left: 0; margin-right: 12px; }

/* css/thread.css loads after this file and pins font-size with !important. */
#content .thread-entry .thread-body,
#content .faq-content .thread-body,
#content #landing_page .thread-body {
  font-size: 1rem !important;
  line-height: 1.62;
  color: var(--gp-ink);
  font-family: var(--gp-sans);
}
#content .thread-body a:not(.button) {
  color: var(--gp-brand) !important;
  text-decoration: underline;
  text-decoration-color: var(--gp-brand-edge);
  text-underline-offset: 0.18em;
}
#content .thread-body a:not(.button):hover {
  color: var(--gp-brand-strong) !important;
  text-decoration-color: currentColor;
}
.thread-entry .thread-body {
  padding: 16px 18px;
  border: 1px solid var(--gp-line);
  border-top: none;
  border-radius: 0 0 var(--gp-r) var(--gp-r);
  background: var(--gp-surface);
}
.thread-entry.response .thread-body { border-color: var(--gp-brand-edge); }

/* Attachment strip pinned to the bottom of the card interior. */
.thread-body .attachments {
  background: var(--gp-page);
  margin: 16px -18px -16px;
  position: static;
  top: 0;
  padding: 10px 18px;
  border-top: 1px solid var(--gp-line);
  border-radius: 0 0 var(--gp-r) var(--gp-r);
  font-size: 0.875rem;
}
.thread-body .attachments .filesize { margin-left: 0.6em; font-size: 0.75rem; }
.thread-body .attachments i { color: var(--gp-ink-3); margin-right: 4px; }
.thread-body .attachments a,
.thread-body .attachments a:hover { text-decoration: none; }
.thread-body .attachments a:hover { text-decoration: underline; }
.thread-body .attachment-info {
  margin-right: 10px;
  display: inline-block;
  width: 48%;
  padding: 2px 0;
}
.thread-body .attachment-info .filename { max-width: calc(100% - 80px); }

/* --- Thread events --------------------------------------------------------- */
.thread-event {
  padding: 0 0 18px;
  margin-left: var(--gp-gutter);
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.875rem;
}
.rtl .thread-event { margin-left: 0; margin-right: var(--gp-gutter); }
.type-icon {
  border-radius: 50%;
  background: var(--gp-surface-2);
  border: 1px solid var(--gp-line);
  width: 26px;
  height: 26px;
  padding: 0;
  margin: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  flex: none;
  vertical-align: middle;
}
.type-icon i { color: var(--gp-ink-3); }
.type-icon.dark { border-color: var(--gp-ink-2); background: var(--gp-ink-2); }
.type-icon.dark i { color: #fff; }
.type-icon::after { content: none; }         /* old timeline mask */
.thread-event img.avatar {
  vertical-align: middle;
  border-radius: 4px;
  width: auto;
  max-height: 22px;
  margin: -2px 3px 0;
}
.thread-event .description {
  margin-left: 0;
  padding: 0;
  display: block;
  width: auto;
  line-height: 1.5;
  color: var(--gp-ink-2);
}

/* --- Reply form -------------------------------------------------------------- */
#reply {
  margin-top: 28px;
  padding: 22px;
  background: var(--gp-surface-2);
  border: 1px solid var(--gp-line);
  border-radius: var(--gp-r);
}
#reply h2 {
  margin-bottom: 14px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--gp-line);
}
#reply > table { width: auto; max-width: 100%; }
#reply table td { vertical-align: top; }
#reply textarea { width: 100% !important; }
#reply input[type="text"],
#reply #response_options textarea {
  border: 1px solid rgba(27, 34, 48, 0.18);
  background: var(--gp-surface);
}
#reply > div > p:first-child { margin-top: 0; }
#reply em { color: var(--gp-ink-2); }
#reply .attachments .uploads div { display: inline-block; padding-right: 20px; }
#reply .file {
  display: inline-block;
  padding-left: 20px;
  margin-right: 20px;
  background: url('../images/icons/file.gif') 0 50% no-repeat;
}
#reply .warning-banner { margin-top: 14px; }

/* =========================================================================
   13. Sign in / access link  (login.inc.php, accesslink.inc.php, pwreset)
   ========================================================================= */

/* Focused single column. Both templates that use #clientLogin — login.inc.php
   (.login-row/.login-aside) and accesslink.inc.php (an inline display:table-row
   with .login-box/.instructions) — become one narrow centred card with the form
   on top and the secondary routes stacked beneath a hairline. The old
   side-by-side split gave the weaker column equal visual weight and doubled the
   page's width for no gain. */
#content:has(#clientLogin) > .hero-eyebrow,
#content:has(#clientLogin) > h1,
#content:has(#clientLogin) > p {
  /* display:block undoes the flex heading rule used by the ticket pages;
     a flex container ignores text-align for its items. */
  display: block;
  text-align: center;
  margin-left: auto;
  margin-right: auto;
}
#content:has(#clientLogin) > .hero-eyebrow { margin-bottom: 12px; }
#content:has(#clientLogin) > h1 { margin-bottom: 10px; }
#content:has(#clientLogin) > p { max-width: 46ch; }

#clientLogin {
  display: block;
  width: 100%;
  max-width: 27rem;
  margin: 26px auto 0;
  padding: 0;
  background: var(--gp-surface);
  border: 1px solid var(--gp-line);
  border-radius: var(--gp-r);
  box-shadow: none;
  overflow: hidden;
}
.rtl #clientLogin { background-position: 5% 50%; }

/* The row wrappers stack. accesslink sets display:table-row inline. */
.login-row,
#clientLogin > div[style] {
  display: block !important;
  gap: 0;
}

.login-box {
  display: block;
  width: auto;
  flex: none;
  box-shadow: none;
  padding: 24px 26px;
  background: none;
  border: 0;
  border-radius: 0;
  vertical-align: top;
}
.rtl .login-box { box-shadow: none; }
.login-box > div { margin-bottom: 14px; }
.login-box > div:last-of-type { margin-bottom: 0; }
.login-box label { display: block; font-weight: 500; font-size: 0.875rem; }
.login-box label input { margin-top: 6px; }
/* Submit fills the card; the password link sits centred beneath it. */
.login-box p {
  margin: 20px 0 0;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 12px;
}
#clientLogin input[type="submit"],
#clientLogin .btn { width: 100%; padding: 11px 22px; }
.pwreset-link { display: block; text-align: center; font-size: 0.875rem; }

/* Secondary routes: external auth, then the register prompt. */
.login-aside,
#clientLogin .instructions {
  display: block;
  width: auto;
  flex: none;
  padding: 20px 26px 22px;
  border-top: 1px solid var(--gp-line-soft);
  background: var(--gp-page);
  color: var(--gp-ink-2);
  font-size: 0.9375rem;
  text-align: center;
  vertical-align: top;
}
.rtl #clientLogin .instructions { padding: 20px 26px 22px; }
.login-aside hr {
  width: 100% !important;
  margin: 16px 0;
  border-top-color: var(--gp-line);
}
.register-prompt { margin: 0; }

/* Full-width provider button so it reads as a peer of Sign In, not an afterthought. */
.login-aside .external-auth { display: block; }
.login-aside .external-auth + .external-auth { margin-top: 8px; }
.login-aside a.external-sign-in { display: block; }
.login-aside .external-auth-box { display: flex; width: 100%; }
.login-aside .external-auth-name { flex: 1; justify-content: center; min-width: 0; }

#clientLogin p { clear: both; }
#clientLogin strong {
  display: block;
  margin-bottom: 12px;
  padding: 9px 12px;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--gp-err);
  background: var(--gp-err-bg);
  border: 1px solid var(--gp-err-edge);
  border-radius: var(--gp-r-sm);
  text-align: left;
}
#clientLogin strong:empty { display: none; }
#clientLogin #username,
#clientLogin #passwd,
#clientLogin #email,
#clientLogin #ticketno { width: 100%; margin-right: 0; }
#clientLogin input[type="text"],
#clientLogin input[type="password"] { margin-bottom: 0; }
#clientLogin hr { margin: 16px 0; border-top-color: var(--gp-line); }

/* The trailing "first time contacting us" line stays a quiet centred row. */
#content:has(#clientLogin) > p:last-of-type {
  text-align: center;
  max-width: 46ch;
  margin: 20px auto 0;
  font-size: 0.9375rem;
}
/* Staff route: its own card, same width and shape as the client card above it,
   so the two audiences read as two parallel doors rather than a form with an
   afterthought stuck to the bottom. */
.agent-signin {
  width: 100%;
  max-width: 27rem;
  margin: 16px auto 0;
  padding: 20px 26px;
  background: var(--gp-surface);
  border: 1px solid var(--gp-line);
  border-radius: var(--gp-r);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  text-align: center;
}
.agent-signin-label {
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gp-ink-3);
}
/* A navy ghost pill, matching the footer's Staff Sign In: quiet enough not to
   compete with the client card, but still unmistakably a control — agents land
   on this page more than any other. */
.agent-signin-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 38px;
  padding: 7px 16px;
  background: transparent;
  border: 1px solid var(--gp-navy);
  border-radius: var(--gp-r-pill);
  color: var(--gp-navy) !important;
  font-weight: 500;
  transition: background-color var(--gp-t-color), color var(--gp-t-color);
}
.agent-signin-link::after { content: "\2192"; font-size: 0.9em; }   /* → */
.agent-signin-link:hover {
  background: var(--gp-navy);
  color: #fff !important;
  text-decoration: none;
}
.agent-signin-link:active { transform: scale(0.98); }

.external-auth + .external-auth { margin-top: 8px; }
a.external-sign-in { text-decoration: none; }
a.external-sign-in:hover { text-decoration: none; }
.external-auth-box {
  display: inline-flex;
  align-items: stretch;
  vertical-align: middle;
  border-radius: var(--gp-r-pill);
  border: 1px solid rgba(27, 34, 48, 0.25);
  background: var(--gp-surface);
  overflow: hidden;
  transition: border-color var(--gp-t-color);
}
a.external-sign-in:hover .external-auth-box { border-color: var(--gp-ink); }
.external-auth-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--gp-ink-2);
  width: 42px;
  padding: 0;
  border-right: 1px solid var(--gp-line);
  background: var(--gp-page);
}
.external-auth-name {
  display: inline-flex;
  align-items: center;
  color: var(--gp-ink);
  width: auto;
  min-width: 110px;
  padding: 9px 16px;
  line-height: 1.3;
  font-size: 0.9375rem;
  font-weight: 500;
}
img.sign-in-image {
  border: none;
  max-height: 40px;
  max-width: 200px;
  width: auto;
  height: auto;
}

/* =========================================================================
   14. Odds and ends
   ========================================================================= */

/* Print / Edit chips on the ticket view. */
.action-button {
  border-radius: var(--gp-r-pill);
  -webkit-background-clip: padding-box;
  background-clip: padding-box;
  color: var(--gp-ink-2) !important;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--gp-line);
  cursor: pointer;
  font-size: 0.8125rem;
  font-weight: 500;
  overflow: hidden;
  background: var(--gp-surface);
  background-image: none;
  padding: 7px 14px;
  text-decoration: none;
  line-height: 1.3;
  margin-left: 6px;
  transition: background-color var(--gp-t-color), border-color var(--gp-t-color);
}
.action-button:hover {
  background: var(--gp-brand-tint);
  border-color: var(--gp-brand-edge);
  color: var(--gp-brand-strong) !important;
  text-decoration: none;
}
.action-button i { color: var(--gp-ink-3); }
.action-button:hover i { color: var(--gp-brand); }
.action-button span,
.action-button a { color: var(--gp-ink-2) !important; display: inline-block; float: none; }
.action-button a { text-decoration: none; }
.image-hover a.action-button:hover,
.image-hover a.action-button { color: initial !important; text-decoration: none; }

.label {
  font-size: 0.6875rem;
  padding: 2px 8px;
  border-radius: var(--gp-r-pill);
  font-weight: 600;
  letter-spacing: 0.03em;
  line-height: 1.5;
  color: #fff;
  vertical-align: baseline;
  white-space: nowrap;
  text-shadow: none;
  background: var(--gp-ink-3);
  display: inline-block;
}
/* The one place gold appears: quiet metadata chips ("Edited"). */
.label-bare {
  background: var(--gp-gold-soft);
  border: 1px solid transparent;
  color: #6d5526;
  text-shadow: none;
}

/* Pagination: the client templates emit bare <a><b>n</b></a>, so there is
   no hook for a proper pager without a markup change. Kept for the
   #pagination markup other surfaces use. */
#pagination { border: 0; margin: 0 0 32px; padding: 0; }
#pagination li { border: 0; margin: 0; padding: 0; font-size: 0.75rem; list-style: none; display: inline; }
#pagination li a { margin-right: 2px; display: block; float: left; padding: 5px 10px; border-radius: var(--gp-r-pill); text-decoration: none; }
#pagination li a:hover { color: var(--gp-brand-strong); background: var(--gp-brand-tint); }
#pagination .previousOff, #pagination .nextOff { color: var(--gp-ink-3); display: block; float: left; font-weight: 600; padding: 5px 8px; }
#pagination .next a, #pagination .previous a { font-weight: 600; }
#pagination .active { color: var(--gp-ink); font-weight: 600; margin-right: 2px; display: block; float: left; padding: 5px 10px; text-decoration: none; }

/* Inline Font Awesome <i> elements set beside text get the same optical
   correction as the ::before glyphs above. Grouped here so the nudge lives in
   one place; .type-icon is excluded because it centres a glyph inside its own
   round chip, where the box centre is the right reference. */
.states i,
.popular-faq i,
.featured-category i,
.action-button i,
.thread-body .attachments i,
#msg_info .icon-2x,
i.refresh {
  position: relative;
  top: var(--gp-icon-nudge);
}

/* =========================================================================
   15. Responsive
   -------------------------------------------------------------------------
   The templates carry width="800"/width="320" table attributes, but
   presentational attributes lose to author CSS — which is what makes a
   fluid layout reachable without markup changes.
   ========================================================================= */

@media (max-width: 1000px) {
  .main-content { margin-right: 0; }
  .sidebar { float: none !important; width: auto; margin-left: 0; }
  .front-page-button { grid-template-columns: 1fr 1fr; }
}

/* --- Nav collapses to a menu ------------------------------------------- */
/* Above this width the bar holds the nav inline; below it, the nav becomes a
   panel that drops out of the bar and the toggle appears.
   
   1150px is measured, not guessed: it is the narrowest viewport where the
   widest bar the templates can emit — logo, four nav pills, and the signed-in
   account cluster — still fits on one row. Below it the row wrapped, which
   left an awkward two-line bar. One breakpoint for both auth states means the
   nav never changes mode just because someone signed in, and there is never
   an in-between state with the inline nav and the toggle both visible. */
@media (max-width: 1150px) {
  .site-bar {
    border-radius: 26px;
    padding: 8px 10px 8px 16px;
    gap: 6px 12px;
  }
  /* Centring is a desktop concern; in the collapsed bar a max-content floor
     would force the account cluster wider than the viewport. */
  #header #logo,
  #header .pull-right { flex: 0 1 auto; min-width: 0; }
  #header .pull-right { margin-left: auto; }
  .nav-toggle-btn { display: inline-flex; }

  #nav {
    order: 5;
    flex-basis: 100%;
    width: 100%;
    display: none;
    flex-direction: column;
    gap: 2px;
    margin: 4px 0 2px;
    padding-top: 8px;
    border-top: 1px solid var(--gp-line);
  }
  #nav-toggle:checked ~ #nav { display: flex; }
  #nav li { width: 100%; }
  #nav li a {
    width: 100%;
    justify-content: flex-start;
    min-height: 46px;
    padding: 11px 14px;
    border-radius: var(--gp-r-sm);
  }
  #nav li a::before { width: 1.1em; text-align: center; }
}

/* Below this width the account cluster is too wide for the bar, so it joins
   the menu panel underneath the nav instead of crowding the logo. */
@media (max-width: 700px) {
  /* With the account cluster out of the bar, the toggle takes over as the
     right-hand anchor — otherwise it sits flush against the logo. */
  .nav-toggle-btn { margin-left: auto; }

  #header .pull-right {
    display: none;
    order: 6;
    flex-basis: 100%;
    width: 100%;
    margin: 0;
    padding-top: 10px;
    border-top: 1px solid var(--gp-line);
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }
  #nav-toggle:checked ~ #header .pull-right { display: flex; }
  #nav-toggle:checked ~ #nav { border-top: 0; padding-top: 4px; }
  #header .pull-right > p { width: 100%; }
  /* Match the full-width nav rows above it. */
  .signin-button { width: 100%; justify-content: center; }
  #header .pull-right > p:has(a):not(:has(.signin-button)) {
    justify-content: center;
    flex-wrap: wrap;
  }
}

@media (max-width: 780px) {
  :root { --gp-pad: 18px; --gp-gutter: 44px; }

  .span4, .span8 { display: block; width: auto; margin: 0; }
  .span4 { margin-top: 28px; }
  .featured-category { width: auto; display: block; padding-right: 0; }

  #ticketInfo > tbody > tr > td {
    display: block;
    width: auto !important;
    padding: 0 0 20px;
  }
  #ticketInfo h1 { display: block; }
  #ticketInfo h1 > .pull-right { display: block; margin: 12px 0 0; }
  .action-button { margin: 0 6px 0 0; }

  .thread-body .attachment-info { width: 100%; margin-right: 0; }
  .freetext-files .file { width: 100%; }

  .footer-inner { flex-direction: column; align-items: flex-start; }
}

@media (max-width: 640px) {
  h1 { font-size: 1.65rem; }
  #content { padding: 22px 0 36px; }

  /* Header */
  #header #logo img { max-height: 34px; max-width: 190px; }
  #header .pull-right,
  #header p { text-align: left; }

  /* Stacked label/value form tables. The rows become plain blocks: with any
     table box left in the chain, an <input size="40">'s intrinsic width
     (~330px) sets the table's min-content and overflows a small phone —
     percentage caps can't shrink a table's min-content, blocks can. */
  #ticketForm > table,
  #ticketForm > table > tbody,
  #ticketForm > table > tbody > tr,
  table.padded,
  table.padded tbody,
  table.padded tr { display: block; width: 100%; table-layout: auto; }
  #ticketForm input[type="text"],
  #ticketForm input[type="password"],
  #ticketForm select { max-width: 100%; }
  #ticketForm > table > tbody > tr > td,
  table.padded tr > td,
  table.padded tr > th {
    display: block;
    width: auto;
    padding: 2px 0;
  }
  #ticketForm > table > tbody > tr > td:first-child:not([colspan]) {
    padding-top: 10px;
    color: var(--gp-ink-3);
    font-size: 0.875rem;
  }
  #ticketForm div textarea,
  #ticketForm td textarea { max-width: none; }

  /* Sign-in panels: login.inc.php uses .login-row (flex, wraps on its own);
     accesslink.inc.php still sets display:table-row/-cell inline. */
  #clientLogin > div > div[style] { display: block !important; }
  #clientLogin > div[style] { display: block !important; }
  .login-box,
  #clientLogin .instructions { display: block; width: auto; }
  .login-box { flex-basis: auto; }
  #clientLogin .instructions { padding: 18px 2px !important; }

  /* Ticket list: five columns will not fit, so let cells wrap and shrink
     rather than hiding a column or forcing a horizontal scroll. */
  /* Auto layout, and drop the template's width="120"/width="320" hints. The
     first three columns hold short atomic values, so pin them to nowrap and
     let auto layout hand the remaining width to subject and department —
     which are the two that can usefully wrap. */
  #ticketTable { font-size: 0.8125rem; table-layout: auto; }
  #ticketTable thead th,
  #ticketTable td { padding: 10px 6px 10px 0; width: auto !important; }
  #ticketTable thead th {
    font-size: 0.625rem;
    letter-spacing: 0.06em;
    white-space: normal !important;
  }
  #ticketTable tbody td:nth-child(1),
  #ticketTable tbody td:nth-child(2),
  #ticketTable tbody td:nth-child(3) { white-space: nowrap; }
  #ticketTable tbody td:nth-child(2) { font-size: 0.6875rem; }
  #ticketTable tbody td:nth-child(4),
  #ticketTable tbody td:nth-child(5) { white-space: normal; overflow-wrap: break-word; }
  /* The subject/department cells hold .truncate divs whose nowrap (plus the
     template's inline max-width:320px) sets the column's min-content to the
     full one-line width — let them wrap here instead. */
  #ticketTable tbody td:nth-child(4) .link,
  #ticketTable tbody td:nth-child(4) .truncate,
  #ticketTable tbody td:nth-child(5) .truncate {
    white-space: normal;
    max-width: none !important;
    display: block;
  }

  /* Search / filter rows go full width */
  #ticketSearchForm .pull-right { margin-left: 0; width: 100%; }
  #ticketSearchForm .pull-right select { flex: 1 1 auto; min-width: 0; }

  /* select2 is initialised with an inline width:350px in class.forms.php */
  .select2-container { width: 100% !important; max-width: 100% !important; }

  #reply { padding: 16px; }
  /* Cards give back some padding at phone widths so the fields keep their room. */
  #ticketForm:has(> table) { padding: 18px 16px 20px; }
  .login-box { padding: 20px 18px; }
  .login-aside,
  #clientLogin .instructions { padding: 18px 18px 20px; }
  .agent-signin { padding: 18px 18px; }
  .thread-entry .header .title { display: none; }   /* duplicates the subject */

  /* CAPTCHA image, field, and hint will not sit on one line at this width. */
  tr.captchaRow td em,
  #ticketForm div .captcha + * { display: block; }
  tr.captchaRow td em { margin-top: 8px; }
  #ticketForm td .captcha { margin-bottom: 8px; }
}

@media (max-width: 420px) {
  .front-page-button { grid-template-columns: 1fr; }
  /* Five columns at 320px: the date wraps, the source-type glyph goes, and
     the whole table steps down a size — the alternative is a horizontal
     scroll, which is worse than a smaller-but-complete row. */
  #ticketTable { font-size: 0.75rem; }
  #ticketTable tbody td:nth-child(2) {
    white-space: normal;
    overflow-wrap: anywhere;
  }
  #ticketTable .Icon { gap: 0; }
  #ticketTable .Icon::before { display: none; }
  #ticketTable thead th,
  #ticketTable td { padding-right: 5px; }
  #ticketTable thead th { letter-spacing: 0.03em; }
  #ticketTable tbody td:nth-child(3) { letter-spacing: 0.04em; font-size: 0.6875rem; }
  /* In the dropped-down menu the glyphs are a useful column, so they stay —
     it is the bar itself that has to shed width at 320px. */
  .site-bar { padding: 8px 8px 8px 12px; gap: 6px 8px; }
  #header #logo img { max-height: 30px; max-width: 150px; }
  .thread-entry.avatar,
  .thread-entry.response.avatar { margin-left: 0; margin-right: 0; }
  .thread-entry > .avatar,
  .thread-entry.response > .avatar { display: none; }
  .thread-event { margin-left: 0; }
  .thread-event, .rtl .thread-event { margin-right: 0; }
  .agent-signin { border-radius: var(--gp-r-sm); }
}

/* Honour a reduced-motion preference. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}
