/* =====================================================================
   assets/app.css — MoHHS ICT Helpdesk

   Self-hosted, no CDN — the interface must not break when the island's
   link wobbles, which is exactly when tickets spike.

   Design discipline, stated plainly so it doesn't erode one component
   at a time:
     - ONE shadow, used sparingly (cards, sticky header). No hover-lift
       theatrics. Elevation marks structure, not interactivity.
     - Colour is reserved for acuity — critical/high/normal/done. Blue is
       brand and structure and never means "urgent". A page with six
       colours competing has no colour that means anything.
     - Content runs full width inside the frame. The sidebar and a
       measured page margin ARE the structure; a second, narrower column
       centred inside that is a second frame fighting the first.
   ===================================================================== */

:root {
  --ink:      #0F1D2E;
  --ink-2:    #55657A;
  --ink-3:    #8695A6;
  --ink-4:    #C2CAD3;

  --surface:  #F3F5F8;
  --card:     #FFFFFF;
  --sunken:   #F7F9FB;
  --rule:     #E4E8EE;

  --deep:     #003893;
  --deep-2:   #002B72;
  --deep-3:   #EBF1FA;

  --critical: #C0182B;
  --high:     #C56A00;
  --normal:   #0E7C86;
  --done:     #1B7F4D;
  --critical-bg: #FCEEEF;
  --high-bg:     #FCF3E7;
  --done-bg:     #EDF7F1;

  --sans: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, Menlo, Consolas, monospace;

  /* One shadow. Used on the header when stuck, and on cards. Nothing
     else gets a shadow — a screen where five things cast shadows reads
     as busy no matter how each looks alone. */
  --shadow: 0 1px 2px rgba(15,29,46,.06), 0 1px 8px rgba(15,29,46,.05);

  --rail:    248px;
  --header:  60px;
  --radius:  10px;
  --radius-sm: 7px;

  /* Page margin. This — not a centred max-width column — is what keeps
     long lines readable while everything else (lists, tables, the
     summary strip) runs the full width of the frame. */
  --gutter: 32px;
}

/* IBM Plex Sans / Mono are not self-hosted here — the actual woff2
   files were never provided, and referencing them produced a 404 on
   every single page load for nothing (browsers still rendered the
   fallback correctly; it just did so noisily).
   The stack below already falls back cleanly to each platform's own
   system UI font, which is what has been rendering the entire time.
   To use the real Plex faces later: download the .woff2 files (e.g.
   via `npm i @fontsource/ibm-plex-sans @fontsource/ibm-plex-mono` and
   copying the woff2 files out of node_modules, or from Google Fonts
   directly) into assets/fonts/, matching these filenames, then restore
   the @font-face rules that used to sit here. */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--sans); font-size: 14px; line-height: 1.55; color: var(--ink);
  background: var(--surface);
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  min-height: 100vh;
}
.mono, .n, .code, .el { font-variant-numeric: tabular-nums; }
:focus-visible { outline: 2px solid var(--deep); outline-offset: 2px; border-radius: 4px; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
svg { display: block; flex-shrink: 0; }

.testbar {
  position: fixed; inset: 0 0 auto 0; z-index: 90; height: 28px;
  display: flex; align-items: center; justify-content: center;
  background: var(--high); color: #fff; font-size: 12px; font-weight: 600;
}
body.has-testbar { --offset: 28px; }
body:not(.has-testbar) { --offset: 0px; }

/* ═════════════════════════════════════════════════════════════════
   SIDEBAR — fixed, structural, quiet. It should feel like a wall, not
   a widget: minimal ornament, one clear active state.
   ═════════════════════════════════════════════════════════════════ */
.rail {
  position: fixed; top: var(--offset); left: 0; bottom: 0; width: var(--rail); z-index: 60;
  display: flex; flex-direction: column;
  background: var(--card); border-right: 1px solid var(--rule);
}
.rail-top {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 20px 16px; flex-shrink: 0;
  border-bottom: 1px solid var(--rule);
}
.rail-top img { width: 100px; height: 100px; }

.nav { flex: 1; min-height: 0; overflow-y: auto; padding: 16px 12px; }
.nav::-webkit-scrollbar { width: 6px; }
.nav::-webkit-scrollbar-thumb { background: var(--rule); border-radius: 3px; }

.nav h3 {
  font-size: 10px; letter-spacing: .09em; text-transform: uppercase; color: var(--ink-3);
  font-weight: 600; padding: 0 10px; margin: 22px 0 8px;
}
.nav h3:first-child { margin-top: 4px; }

.nav a {
  position: relative; display: flex; align-items: center; gap: 12px;
  padding: 9px 10px; margin-bottom: 2px; border-radius: var(--radius-sm);
  font-size: 13.5px; color: var(--ink-2); font-weight: 500;
  transition: background .12s ease, color .12s ease;
}
.nav a:hover { background: var(--sunken); color: var(--ink); }
.nav a.on { background: var(--deep); color: #fff; }
.nav a.on .ico { opacity: 1; }
.nav .ico { width: 17px; height: 17px; opacity: .7; flex-shrink: 0; }
.nav a:hover .ico { opacity: 1; }

.nav .count {
  margin-left: auto; font-family: var(--mono); font-size: 10.5px; font-weight: 600;
  min-width: 20px; text-align: center; line-height: 17px;
  padding: 0 6px; border-radius: 9px; background: var(--critical-bg); color: var(--critical);
}
.nav a.on .count { background: rgba(255,255,255,.22); color: #fff; }

.rail-me {
  flex-shrink: 0; padding: 14px 16px; border-top: 1px solid var(--rule);
  display: flex; align-items: center; gap: 11px;
}
.rail-me .av {
  width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0;
  background: var(--deep); color: #fff; display: grid; place-items: center;
  font-size: 11px; font-weight: 600;
}
.rail-me .who { min-width: 0; }
.rail-me .nm { font-size: 13px; font-weight: 600; line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rail-me .rl { font-size: 11px; color: var(--ink-3); line-height: 1.3; }
.rail-me .out { margin-left: auto; padding: 6px; border-radius: 6px; color: var(--ink-3); }
.rail-me .out:hover { background: var(--critical-bg); color: var(--critical); }

/* ═════════════════════════════════════════════════════════════════
   HEADER — one clear row: where you are, on the left; what you can do
   right now, on the right. Nothing competes for the centre.
   ═════════════════════════════════════════════════════════════════ */
.main { margin-left: var(--rail); min-height: 100vh; display: flex; flex-direction: column; }

.head {
  position: sticky; top: var(--offset); z-index: 50;
  height: var(--header); flex-shrink: 0;
  display: flex; align-items: center; gap: 18px;
  padding: 0 var(--gutter);
  background: var(--card);
  border-bottom: 1px solid var(--rule);
  transition: transform .2s ease, box-shadow .2s ease;
}
.head.tucked { transform: translateY(calc(-100% - var(--offset))); }
.head.stuck { box-shadow: var(--shadow); }

.burger { display: none; padding: 8px; margin-left: -8px; border-radius: 7px; color: var(--ink-2); }
.burger:hover { background: var(--sunken); }

.head .title { min-width: 0; display: flex; align-items: baseline; gap: 9px; }
.head .title h1 {
  font-size: 16px; font-weight: 600; letter-spacing: -.012em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.head .title .crumb {
  font-size: 12px; color: var(--ink-3); white-space: nowrap;
  padding-left: 9px; border-left: 1px solid var(--rule);
}

.seek { margin-left: auto; position: relative; }
.seek input {
  width: 220px; font: inherit; font-size: 13px;
  padding: 8px 12px 8px 34px; color: var(--ink);
  background: var(--sunken); border: 1px solid var(--rule); border-radius: var(--radius-sm);
  transition: width .16s ease, background .12s, border-color .12s;
}
.seek input:focus { width: 280px; background: var(--card); border-color: var(--deep); }
.seek input::placeholder { color: var(--ink-3); }
.seek .mag { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--ink-3); pointer-events: none; }

.head .act {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 15px; border-radius: var(--radius-sm);
  font-size: 13px; font-weight: 600; background: var(--deep); color: #fff;
  transition: background .12s;
}
.head .act:hover { background: var(--deep-2); }

/* ── Content ─────────────────────────────────────────────────── */
.wrap { flex: 1; width: 100%; padding: 28px var(--gutter) 0; }

/* Long-form text (forms, prose) still gets a comfortable line length —
   opted in per page, not forced on every list and table. */
.wrap.narrow { max-width: 760px; }

/* ═════════════════════════════════════════════════════════════════
   FOOTER — a real bar, not text drifting in whitespace.
   ═════════════════════════════════════════════════════════════════ */
.foot-bar {
  margin-top: 48px; border-top: 1px solid var(--rule); background: var(--card);
}
.foot-in {
  padding: 22px var(--gutter);
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
}
.foot-brand { display: flex; align-items: center; gap: 11px; }
.foot-brand img { width: 26px; height: 26px; opacity: .85; }
.foot-brand .l1 { font-size: 12.5px; font-weight: 600; color: var(--ink); line-height: 1.4; }
.foot-brand .l2 { font-size: 11px; color: var(--ink-3); line-height: 1.4; }
.foot-meta { text-align: right; font-size: 11px; color: var(--ink-3); line-height: 1.6; }
.foot-meta .grant { color: var(--ink-2); font-weight: 500; }

/* ═════════════════════════════════════════════════════════════════
   CARDS — the one place shadow is used, at one weight.
   ═════════════════════════════════════════════════════════════════ */
.card {
  background: var(--card); border: 1px solid var(--rule); border-radius: var(--radius);
  box-shadow: var(--shadow); overflow: hidden;
}
.card + .card { margin-top: 16px; }
.card-h { display: flex; align-items: center; gap: 10px; padding: 15px 20px; border-bottom: 1px solid var(--rule); }
.card-h h2 { font-size: 11px; letter-spacing: .07em; text-transform: uppercase; color: var(--ink-2); font-weight: 600; }
.card-h .c { font-family: var(--mono); font-size: 11px; color: var(--ink-3); }
.card-pad { padding: 22px 24px; }
.card-pad h1 { font-size: 18px; font-weight: 600; letter-spacing: -.014em; margin-bottom: 4px; }
.lede { font-size: 13px; color: var(--ink-2); margin-bottom: 20px; }
.hint { font-size: 11px; letter-spacing: .03em; text-transform: uppercase; color: var(--ink-3); font-weight: 500; }

/* ── Summary strip. No hover-lift — a stat card is not a button. ─ */
.strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 1px;
         background: var(--rule); border: 1px solid var(--rule); border-radius: var(--radius);
         overflow: hidden; margin-bottom: 20px; box-shadow: var(--shadow); }
.strip .stat {
  background: var(--card); padding: 16px 18px;
  display: flex; align-items: center; gap: 13px;
  transition: background .12s;
}
.strip .stat:hover { background: var(--sunken); }
.strip .stat .ic {
  width: 34px; height: 34px; border-radius: 9px; flex-shrink: 0;
  display: grid; place-items: center;
  background: var(--deep-3); color: var(--deep);
}
.strip .stat.c .ic { background: var(--critical-bg); color: var(--critical); }
.strip .stat.h .ic { background: var(--high-bg); color: var(--high); }
.strip .stat.d .ic { background: var(--done-bg); color: var(--done); }
.strip .stat .body { min-width: 0; }
.strip .stat .n { font-family: var(--mono); font-size: 22px; font-weight: 600; line-height: 1.1; letter-spacing: -.02em; }
.strip .stat .l { font-size: 10.5px; letter-spacing: .04em; color: var(--ink-3); margin-top: 2px; font-weight: 500; white-space: nowrap; }
.strip .stat.c .n { color: var(--critical); }
.strip .stat.h .n { color: var(--high); }
.strip .stat.d .n { color: var(--done); }

/* ── Tabs ────────────────────────────────────────────────────── */
.tabs { display: flex; gap: 2px; margin-bottom: 16px; border-bottom: 1px solid var(--rule); }
.tabs a {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 13px; font-weight: 500; color: var(--ink-2);
  padding: 10px 4px; margin-right: 22px; position: relative;
}
.tabs a:hover { color: var(--ink); }
.tabs a.on { color: var(--deep); }
.tabs a.on::after { content: ''; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--deep); }
.tabs a .ico { width: 14px; height: 14px; }

/* ── List rows ───────────────────────────────────────────────── */
.tk { display: flex; align-items: center; gap: 14px; padding: 14px 20px; border-bottom: 1px solid var(--rule); transition: background .1s; }
.tk:last-child { border-bottom: 0; }
.tk:hover { background: var(--sunken); }
.tk .lead { width: 28px; display: grid; place-items: center; flex-shrink: 0; color: var(--ink-3); }
.tk .code { font-family: var(--mono); font-size: 11.5px; font-weight: 500; color: var(--ink-2); width: 126px; flex-shrink: 0; }
.tk .mid { flex: 1; min-width: 0; }
.tk .sj { font-size: 13.5px; font-weight: 500; letter-spacing: -.005em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tk .wh { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; }
.tk .rt { text-align: right; flex-shrink: 0; width: 128px; }
.tk .el { font-family: var(--mono); font-size: 11px; color: var(--ink-2); }
.tk .mtr { height: 3px; background: var(--rule); border-radius: 2px; margin-top: 6px; overflow: hidden; }
.tk .mtr i { display: block; height: 100%; border-radius: 2px; }

.pill { display: inline-flex; align-items: center; font-size: 9px; letter-spacing: .05em; text-transform: uppercase; font-weight: 600; padding: 3px 8px; border-radius: 4px; color: #fff; flex-shrink: 0; }
.tag { display: inline-flex; align-items: center; gap: 4px; font-size: 10.5px; font-weight: 500; padding: 2px 7px; border-radius: 4px; background: var(--rule); color: var(--ink-2); }

.empty { padding: 60px 24px; text-align: center; }
.empty svg { margin: 0 auto 14px; color: var(--ink-4); }
.empty .t { font-size: 14px; font-weight: 600; margin-bottom: 4px; }
.empty .s { font-size: 12.5px; color: var(--ink-3); }

/* ═════════════════════════════════════════════════════════════════
   PAGINATION
   ═════════════════════════════════════════════════════════════════ */
.pager { display: flex; align-items: center; gap: 4px; padding: 14px 20px; border-top: 1px solid var(--rule); flex-wrap: wrap; }
.pager .of { font-size: 11.5px; color: var(--ink-3); margin-right: auto; }
.pager a, .pager span.pg {
  min-width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center;
  padding: 0 8px; border-radius: 6px; font-size: 12.5px; font-family: var(--mono); color: var(--ink-2);
  border: 1px solid transparent; transition: background .1s, border-color .1s;
}
.pager a:hover { background: var(--sunken); border-color: var(--rule); }
.pager .on { background: var(--deep); color: #fff; font-weight: 500; }
.pager .off { color: var(--ink-4); }
.pager .gap { color: var(--ink-4); min-width: 16px; }

/* ── Forms ───────────────────────────────────────────────────── */
.field { margin-bottom: 16px; }
.field label { display: flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 600; letter-spacing: .02em; color: var(--ink-2); margin-bottom: 6px; }
.field label .ico, .field label svg { color: var(--ink-3); }
.field input, .field select, .field textarea {
  width: 100%; font: inherit; font-size: 13.5px; color: var(--ink);
  background: var(--card); border: 1px solid var(--rule); border-radius: var(--radius-sm); padding: 9px 11px;
  transition: border-color .12s, box-shadow .12s;
}
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--deep); box-shadow: 0 0 0 3px var(--deep-3); }
.field input[type=checkbox], .field input[type=radio] { width: auto; }
.field textarea { resize: vertical; min-height: 76px; }
.field .hint { text-transform: none; letter-spacing: 0; font-weight: 400; font-size: 11.5px; margin-top: 6px; }
.row { display: flex; gap: 12px; flex-wrap: wrap; }
.row > .field { flex: 1; min-width: 170px; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  font: inherit; font-size: 13.5px; font-weight: 600; color: #fff; background: var(--deep);
  border: 1px solid var(--deep); border-radius: var(--radius-sm); padding: 10px 18px; cursor: pointer;
  transition: background .12s;
}
.btn:hover { background: var(--deep-2); border-color: var(--deep-2); }
.btn.wide { width: 100%; }
.btn.ghost { background: var(--card); color: var(--ink); border-color: var(--rule); }
.btn.ghost:hover { background: var(--sunken); }
.btn.go { background: var(--done); border-color: var(--done); }
.btn.go:hover { background: #166B40; border-color: #166B40; }
.btn.sm { font-size: 12.5px; padding: 8px 14px; }
.link { font-size: 12.5px; color: var(--deep); font-weight: 500; }
.link:hover { text-decoration: underline; }
.quiet { font-size: 11.5px; color: var(--ink-2); text-decoration: underline; }
.quiet:hover { color: var(--ink); }

/* ── Notices ─────────────────────────────────────────────────── */
.note { display: flex; gap: 10px; font-size: 13px; line-height: 1.55; border: 1px solid; border-radius: var(--radius-sm); padding: 12px 14px; margin-bottom: 18px; }
.note svg { margin-top: 1px; }
.note.bad  { color: #7B1020; background: var(--critical-bg); border-color: #F1C7CC; }
.note.good { color: #14603A; background: var(--done-bg);     border-color: #C2E3CF; }
.note.info { color: #1F3A63; background: var(--deep-3);      border-color: #CBD9EC; }
.note.warn { color: #7A4200; background: var(--high-bg);     border-color: #F5DCBB; }

/* ── Definition grid / key-value rows ────────────────────────── */
.dl { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 16px 24px; }
.dl .k { font-size: 10.5px; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-3); margin-bottom: 3px; font-weight: 500; }
.dl .v { font-size: 13.5px; }
.dl .v.mono { font-family: var(--mono); font-size: 12.5px; }

.kv { font-size: 12.5px; }
.kv > div { display: flex; justify-content: space-between; gap: 14px; padding: 10px 20px; border-bottom: 1px solid var(--rule); }
.kv > div:last-child { border-bottom: 0; }
.kv .what { color: var(--ink-2); }
.kv .ok  { color: var(--done); }
.kv .bad { color: var(--critical); }

/* ═════════════════════════════════════════════════════════════════
   CENTRED PAGES — sign in, setup, request form, status
   ═════════════════════════════════════════════════════════════════ */
.centre {
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: 32px 20px;
  background:
    radial-gradient(circle at 0% 0%, rgba(0,56,147,.09), transparent 40%),
    radial-gradient(circle at 100% 100%, rgba(221,117,0,.08), transparent 38%),
    linear-gradient(135deg, #f8fafc 0%, #eef4fb 50%, #fdf6ee 100%);
}
.panel { width: 100%; max-width: 460px; }
.panel.wide { max-width: 900px; }

.crest { text-align: center; margin-bottom: 24px; }
.crest .seal-wrap {
  width: 84px; height: 84px; margin: 0 auto 16px; display: grid; place-items: center;
  background: var(--sunken); border-radius: 22px; border: 1px solid var(--rule);
}
.crest img { width: 62px; height: 62px; }
.crest .l1 { font-size: 12px; letter-spacing: .15em; text-transform: uppercase; color: var(--ink-3); font-weight: 700; }
.crest .l2 { font-size: 15px; font-weight: 600; color: var(--ink-2); margin-top: 5px; }
.crest .l3 {
  font-size: 17px; font-weight: 800; color: var(--ink); margin-top: 14px;
  letter-spacing: -.014em; white-space: nowrap;
}
.crest .l3 .accent { color: var(--deep); }
.foot { text-align: center; font-size: 11px; line-height: 1.7; color: var(--ink-3); margin-top: 22px; }

/* Card: rounded, elevated, faintly translucent so the gradient behind
   it still shows through at the edges — this is the one surface in the
   whole app allowed to look this dressed up, since it is also the one
   surface every single person, patient-facing staff included, sees
   before anything else. */
.panel .card {
  border-radius: 28px; border-color: var(--rule);
  background: rgba(255,255,255,.96);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 1px 2px rgba(15,29,46,.04), 0 24px 48px -16px rgba(15,29,46,.16);
}
/* Only squared on the bottom when a footer band sits flush underneath
   it (login, setup, change-password) — everywhere else on this shell
   (the public request form, the status page) the card stands alone,
   so it stays rounded on all four corners. */
.panel .card:has(+ .foot) { border-radius: 28px 28px 0 0; }
.panel .card-pad { padding: 34px 32px 30px; }
.panel .card-pad h1 { font-size: 21px; font-weight: 700; letter-spacing: -.014em; }
.panel .lede { font-size: 13.5px; }

.panel .field label { font-size: 13px; font-weight: 600; color: var(--ink-2); display: flex; align-items: center; gap: 7px; }
.panel .field label .ico, .panel .field label svg { color: var(--deep); }

.panel .field input {
  border-radius: 16px; border-color: var(--rule); padding: 13px 16px 13px 44px; font-size: 14px;
}
.panel .field input:focus { border-color: var(--deep); box-shadow: 0 0 0 4px var(--deep-3); }
.panel .field-ic .fi-icon { left: 15px; color: var(--ink-4); }
.panel .field-ic input:focus ~ .fi-icon { color: var(--deep); }
.panel .field-ic input.has-toggle { padding-right: 44px; }
.panel .field-ic .fi-toggle { right: 10px; }

.panel .btn {
  border-radius: 16px; padding: 14px 20px; font-size: 14.5px; font-weight: 700;
  box-shadow: 0 8px 20px -8px rgba(0,56,147,.4);
}
.panel .btn:hover { box-shadow: 0 10px 24px -8px rgba(0,56,147,.46); }

/* Footer band, flush against the bottom of the card. .foot sits as a
   sibling of .card (not nested inside it) — a 1px negative top margin
   is enough to remove the seam between them; no horizontal offset is
   needed since both are already the same width inside .panel. */
.panel .foot {
  margin-top: -1px; padding: 16px 28px;
  background: var(--sunken); border: 1px solid var(--rule); border-top: none;
  border-radius: 0 0 28px 28px;
}


/* ═════════════════════════════════════════════════════════════════
   RESPONSIVE
   ═════════════════════════════════════════════════════════════════ */
.scrim { display: none; position: fixed; inset: 0; z-index: 55; background: rgba(15,29,46,.4); }

@media (max-width: 1200px) {
  :root { --gutter: 24px; }
}
@media (max-width: 1080px) {
  :root { --rail: 220px; }
  .seek input { width: 170px; }
  .seek input:focus { width: 220px; }
}
@media (max-width: 860px) {
  .rail { transform: translateX(-100%); transition: transform .22s ease; box-shadow: var(--shadow); }
  body.drawer .rail { transform: none; }
  body.drawer .scrim { display: block; }
  .main { margin-left: 0; }
  .burger { display: inline-flex; }
  :root { --gutter: 18px; }
  .seek { display: none; }
  .foot-in { flex-direction: column; align-items: flex-start; }
  .foot-meta { text-align: left; }
}
@media (max-width: 560px) {
  .tk .code, .tk .rt { display: none; }
  .head .act span { display: none; }
  .head .act { padding: 9px; border-radius: 50%; }
  .strip { grid-template-columns: repeat(2, 1fr); }
  .card-pad { padding: 18px; }
  .head .title .crumb { display: none; }
}

@media print {
  .rail, .head, .tabs, .pager, .foot-bar, .testbar, .scrim, form { display: none !important; }
  .main { margin-left: 0; }
  body { background: #fff; }
  .card { box-shadow: none; border-color: #ccc; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ═════════════════════════════════════════════════════════════════
   PEOPLE / TEAM ROWS — avatar chips, role badges, icon actions.
   Generic enough to reuse anywhere a "person row" appears.
   ═════════════════════════════════════════════════════════════════ */
.person {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 20px; border-bottom: 1px solid var(--rule);
  transition: background .1s;
}
.person:last-child { border-bottom: 0; }
.person:hover { background: var(--sunken); }
.person.off { opacity: .55; }

.person .av {
  width: 38px; height: 38px; border-radius: 50%; flex-shrink: 0;
  display: grid; place-items: center;
  font-size: 12.5px; font-weight: 600; color: #fff;
  background: var(--deep);
}
.person .av.role-director  { background: var(--deep); }
.person .av.role-admin     { background: #4A3A8C; }
.person .av.role-specialist{ background: var(--normal); }
.person .av.role-viewer    { background: var(--ink-3); }

.person .body { flex: 1; min-width: 0; }
.person .name-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.person .nm { font-size: 13.5px; font-weight: 600; letter-spacing: -.005em; }
.person .meta { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; }
.person .meta .sep { margin: 0 5px; opacity: .6; }

.rolebadge {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 9.5px; letter-spacing: .04em; text-transform: uppercase; font-weight: 700;
  padding: 2px 7px; border-radius: 4px;
}
.rolebadge.director   { background: var(--deep-3); color: var(--deep); }
.rolebadge.admin      { background: #EFEAFB; color: #4A3A8C; }
.rolebadge.specialist { background: var(--done-bg); color: var(--done); }
.rolebadge.viewer     { background: var(--rule); color: var(--ink-2); }

.badge-soft {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10.5px; font-weight: 500; color: var(--ink-2);
  padding: 2px 7px; border-radius: 4px; background: var(--rule);
}
.badge-soft.warn { background: var(--high-bg); color: var(--high); }
.badge-soft.good { background: var(--done-bg); color: var(--done); }

.person .actions { display: flex; align-items: center; gap: 2px; flex-shrink: 0; }
.iconbtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: var(--radius-sm);
  color: var(--ink-3); transition: background .12s, color .12s;
}
.iconbtn:hover { background: var(--rule); color: var(--ink); }
.iconbtn.danger:hover { background: var(--critical-bg); color: var(--critical); }
.iconbtn.good:hover { background: var(--done-bg); color: var(--done); }

/* Compact form used inside a person row for a one-click action. */
.person form { display: contents; }

/* ═════════════════════════════════════════════════════════════════
   TOASTS — replaces the persistent success banner. A confirmation is
   transient information; it should announce itself and get out of
   the way, not sit at the top of the page pushing content down.
   ═════════════════════════════════════════════════════════════════ */
.toast-wrap {
  position: fixed; right: 20px; bottom: 20px; z-index: 100;
  display: flex; flex-direction: column-reverse; gap: 8px;
  width: min(360px, calc(100vw - 40px));
  pointer-events: none;
}
.toast {
  pointer-events: auto;
  display: flex; align-items: flex-start; gap: 10px;
  padding: 12px 14px; border-radius: var(--radius-sm);
  background: var(--ink); color: #fff;
  font-size: 13px; line-height: 1.5; box-shadow: var(--shadow);
  animation: toast-in .18s cubic-bezier(.2,.8,.3,1);
}
.toast.out { animation: toast-out .18s ease forwards; }
.toast .tx { flex: 1; }
.toast .x { color: rgba(255,255,255,.6); padding: 2px; flex-shrink: 0; }
.toast .x:hover { color: #fff; }
.toast.good { background: #14532D; }
.toast.bad  { background: #7B1020; }
.toast.info { background: var(--deep-2); }

@keyframes toast-in  { from { opacity: 0; transform: translateY(8px); } }
@keyframes toast-out { to   { opacity: 0; transform: translateY(4px); } }

/* ═════════════════════════════════════════════════════════════════
   MODALS — one generic backdrop + dialog, reused for confirmations
   and edit forms. A <form> inside submits normally; no page here
   needs a JavaScript request cycle to save anything.
   ═════════════════════════════════════════════════════════════════ */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 95;
  display: flex; align-items: center; justify-content: center; padding: 20px;
  background: rgba(15,29,46,.44);
  opacity: 0; transition: opacity .16s ease;
}
.modal-backdrop.show { opacity: 1; }
.modal-backdrop[hidden] { display: none; }

.modal {
  width: 100%; max-width: 420px;
  background: var(--card); border-radius: var(--radius); box-shadow: var(--shadow);
  transform: translateY(6px) scale(.98); transition: transform .16s ease;
}
.modal.wide { max-width: 560px; }
.modal-backdrop.show .modal { transform: none; }
.modal.wide { max-width: 680px; }

.modal-h { display: flex; align-items: center; gap: 12px; padding: 20px 22px 0; }
.modal-h h2 { font-size: 16px; font-weight: 600; letter-spacing: -.01em; }
.modal-icon {
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
  display: grid; place-items: center;
}
.modal-icon.bad { background: var(--critical-bg); color: var(--critical); }
.modal-icon.good { background: var(--done-bg); color: var(--done); }
.modal-icon.info { background: var(--deep-3); color: var(--deep); }

.modal-body { padding: 14px 22px 4px; }
.modal-body p { font-size: 13.5px; color: var(--ink-2); line-height: 1.6; }
.modal-body .field:first-child { margin-top: 4px; }

.modal-actions {
  display: flex; justify-content: flex-end; gap: 9px;
  padding: 18px 22px 22px;
}
.modal-close {
  position: absolute; top: 14px; right: 14px;
  width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center; color: var(--ink-3);
}
.modal-close:hover { background: var(--sunken); color: var(--ink); }
.modal { position: relative; }

/* ═════════════════════════════════════════════════════════════════
   QUEUE ROW EXTRAS — assignee avatar chip, inline quick-assign.
   ═════════════════════════════════════════════════════════════════ */
.tk .who-chip {
  display: inline-flex; align-items: center; gap: 6px;
}
.tk .who-chip .av-sm {
  width: 18px; height: 18px; border-radius: 50%; flex-shrink: 0;
  display: grid; place-items: center;
  font-size: 8.5px; font-weight: 700; color: #fff; background: var(--ink-3);
}

.tk .quick-assign {
  width: 92px; flex-shrink: 0;   /* fixed width — present or empty, every
                                    row's rightmost edge lands in the same
                                    place. Without this, a row with the
                                    button is wider than one without, and
                                    the elapsed-time column staggers
                                    left/right depending on which. */
  display: flex; justify-content: flex-end;
  opacity: 0;
  transition: opacity .12s;
}
.tk:hover .quick-assign, .tk:focus-within .quick-assign { opacity: 1; }
.tk .quick-assign button {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 600; color: var(--deep);
  background: var(--deep-3); padding: 5px 10px; border-radius: 14px;
  transition: background .12s;
}
.tk .quick-assign button:hover { background: var(--deep); color: #fff; }

/* On touch devices there's no hover — keep the action visible. */
@media (hover: none) {
  .tk .quick-assign { opacity: 1; }
}

/* ═════════════════════════════════════════════════════════════════
   TICKET DETAIL — two columns. Main content (what happened, notes,
   activity) on the left at a readable width; ticket properties and
   actions in a compact sidebar on the right. This is what actually
   fills the frame on a wide screen without making prose stretch
   edge-to-edge — a single full-width column does neither well.
   ═════════════════════════════════════════════════════════════════ */
.tdetail { display: flex; gap: 20px; align-items: flex-start; }

/* The card itself fills all remaining width — no cap here. A capped
   column left a block of dead space to its right on a wide screen, and
   the whole thing then read as "boxed in" rather than filling the
   frame. The cap belongs on the prose INSIDE the card (.prose below),
   not on the column, so the card can still occupy the full container
   while a paragraph of description text stays a comfortable width to
   read. */
.tdetail .col-main { flex: 1; min-width: 0; }
.tdetail .side { width: 420px; flex-shrink: 0; display: flex; flex-direction: column; gap: 16px; }

/* Reading-width cap for actual prose — the description, resolution
   notes, and comment bodies — applied to the text itself rather than
   its container. */
.prose { max-width: 68ch; }

@media (max-width: 900px) {
  .tdetail { flex-direction: column; }
  .tdetail .col-main { max-width: none; width: 100%; }
  .tdetail .side { width: 100%; }
}

/* ── Sidebar property list ──────────────────────────────────────── */
.props .row { padding: 13px 20px; border-bottom: 1px solid var(--rule); }
.props .row:last-child { border-bottom: 0; }
.props .k { font-size: 10px; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-3); font-weight: 600; margin-bottom: 5px; }
.props .v { font-size: 13px; line-height: 1.5; overflow-wrap: anywhere; }
.props .v.mono { font-family: var(--mono); font-size: 11.5px; overflow-wrap: anywhere; }

/* A select in the sidebar is narrower than its option text — the closed
   box would otherwise clip "Anjo Reimers — 4 open · Majuro Hospit…".
   Letting it wrap to two lines when needed reads far better than an
   ellipsis that hides which person is even selected. */
.side-action select { white-space: normal; }

/* ── Sidebar action forms ───────────────────────────────────────── */
.side-action { padding: 16px 20px; }
.side-action + .side-action { border-top: 1px solid var(--rule); }
.side-action .field { margin-bottom: 10px; }
.side-action .field:last-child { margin-bottom: 0; }

/* ── Activity timeline — icon markers on a connecting line ──────── */
.timeline { padding: 4px 20px 18px; }
.tl-ev { position: relative; display: flex; gap: 12px; padding-bottom: 20px; }
.tl-ev:last-child { padding-bottom: 0; }
.tl-ev::after {
  content: ''; position: absolute; left: 13px; top: 28px; bottom: -4px;
  width: 1.5px; background: var(--rule);
}
.tl-ev:last-child::after { display: none; }
.tl-dot {
  width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
  display: grid; place-items: center; z-index: 1;
  background: var(--sunken); color: var(--ink-3);
}
.tl-dot.blue   { background: var(--deep-3);     color: var(--deep); }
.tl-dot.green  { background: var(--done-bg);    color: var(--done); }
.tl-dot.orange { background: var(--high-bg);    color: var(--high); }
.tl-dot.red    { background: var(--critical-bg);color: var(--critical); }
.tl-body { padding-top: 3px; min-width: 0; }
.tl-when { font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); margin-bottom: 2px; }
.tl-what { font-size: 13px; line-height: 1.5; }
.tl-what b { font-weight: 600; }

/* ═════════════════════════════════════════════════════════════════
   PUBLIC REQUEST FORM — section headers, a priority preview, and a
   native-CSS file picker. No JavaScript is required for any of these
   to work correctly; the priority badge is progressive enhancement on
   top of a form that already functions without it.
   ═════════════════════════════════════════════════════════════════ */
.fsec {
  display: flex; align-items: center; gap: 12px; margin: 36px 0 18px;
  padding-bottom: 12px; border-bottom: 1px solid var(--rule);
}
.fsec:first-child { margin-top: 0; }
.fsec .ic {
  width: 34px; height: 34px; border-radius: 10px; flex-shrink: 0;
  background: linear-gradient(135deg, var(--deep), var(--deep-2));
  color: #fff; box-shadow: 0 4px 10px -3px rgba(0,56,147,.4);
  display: grid; place-items: center;
}
.fsec h3 { font-size: 14px; letter-spacing: -.006em; color: var(--ink); font-weight: 700; }
.fsec .step { font-size: 10.5px; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-3); font-weight: 600; display: block; margin-bottom: 1px; }

/* Priority preview next to the category select — shown once a category
   is chosen, hidden otherwise. Pure progressive enhancement: the form
   works identically with JavaScript off, this is informational only. */
.cat-priority {
  display: none; align-items: center; gap: 6px;
  font-size: 11.5px; color: var(--ink-2); margin-top: 8px;
}
.cat-priority.show { display: inline-flex; }
.cat-priority .dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }

/* ── File attachment: drag-and-drop, with click-to-browse always
   available underneath it ──────────────────────────────────────────
   Deliberately not drag-only. Most people filling this in are on a
   hospital ward workstation, not arranging two windows side by side —
   for them a clearly labelled click target is less friction than
   dragging. On a phone, drag-and-drop does not exist at all, and a
   photo of the screen is often the single most useful thing attached
   here. So: a real <input type=file> covers the whole box, invisible,
   which means click-to-browse works even with JavaScript off — drag
   support and the filename preview are added on top of that, not
   instead of it. */
.dropzone {
  position: relative;
  border: 1.5px dashed var(--rule); border-radius: var(--radius-sm);
  padding: 22px 16px; text-align: center;
  transition: border-color .12s, background .12s;
}
.dropzone:hover { border-color: var(--ink-4); }
.dropzone.drag { border-color: var(--deep); background: var(--deep-3); }
.dropzone.has-file { border-style: solid; border-color: var(--done); background: var(--done-bg); }

.dropzone input[type=file] {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; cursor: pointer;
}

.dz-icon { color: var(--ink-3); margin-bottom: 8px; }
.dropzone.drag .dz-icon, .dropzone.has-file .dz-icon { color: var(--deep); }
.dropzone.has-file .dz-icon { color: var(--done); }

.dz-text { font-size: 13px; color: var(--ink-2); pointer-events: none; }
.dz-text b { color: var(--deep); font-weight: 600; }
.dz-name {
  display: none; align-items: center; justify-content: center; gap: 7px;
  font-size: 13px; font-weight: 600; color: var(--done); margin-top: 2px;
  pointer-events: none;
}
.dropzone.has-file .dz-text { display: none; }
.dropzone.has-file .dz-name { display: flex; }

.helpline {
  display: flex; align-items: center; gap: 11px;
  padding: 14px 16px;
}
.helpline .ic {
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
  background: var(--deep-3); color: var(--deep); display: grid; place-items: center;
}

/* ═════════════════════════════════════════════════════════════════
   ICON-ENHANCED FIELDS — an icon inside the input (email, lock), and
   a show/hide toggle for password fields. Used on the sign-in page;
   generic enough to reuse anywhere a field benefits from one.
   ═════════════════════════════════════════════════════════════════ */
.field-ic { position: relative; }
.field-ic .fi-icon {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  color: var(--ink-3); pointer-events: none;
}
.field-ic input, .field-ic select { padding-left: 38px; }
.field-ic input[type="password"],
.field-ic input.has-toggle { padding-right: 40px; }
.field-ic .fi-toggle {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 30px; height: 30px; display: grid; place-items: center;
  color: var(--ink-3); border-radius: 6px;
}
.field-ic .fi-toggle:hover { background: var(--sunken); color: var(--ink); }

/* Button loading state — set by app.js on submit. Text stays in place
   (screen readers keep reading it); a small spinner appears beside it
   and the button stops accepting another click while the request is
   in flight. */
.btn.is-loading { opacity: .75; pointer-events: none; }
.btn .spin {
  display: none; width: 14px; height: 14px; flex-shrink: 0;
  border: 2px solid rgba(255,255,255,.4); border-top-color: #fff;
  border-radius: 50%; animation: spin .7s linear infinite;
}
.btn.ghost .spin { border-color: rgba(15,29,46,.2); border-top-color: var(--ink); }
.btn.is-loading .spin { display: inline-block; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ═════════════════════════════════════════════════════════════════
   RICH TEXT EDITOR — a toolbar over a contenteditable region, styled
   to match the rest of the field system. The hidden input it syncs
   into is what actually submits; the editable div is only ever a UI
   surface, never trusted as the source of truth server-side.
   ═════════════════════════════════════════════════════════════════ */
.rte { border: 1px solid var(--rule); border-radius: var(--radius-sm); overflow: hidden; }
.rte-bar {
  display: flex; align-items: center; gap: 2px; flex-wrap: wrap;
  padding: 6px; background: var(--sunken); border-bottom: 1px solid var(--rule);
}
.rte-bar button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 6px; color: var(--ink-2);
  transition: background .12s, color .12s;
}
.rte-bar button:hover { background: var(--rule); color: var(--ink); }
.rte-bar .sep { width: 1px; height: 20px; background: var(--rule); margin: 0 4px; flex-shrink: 0; }

.rte-editor {
  min-height: 160px; padding: 12px 14px; font-size: 13.5px; line-height: 1.65;
  color: var(--ink); outline: none;
}
.rte-editor:empty::before {
  content: attr(data-placeholder); color: var(--ink-4); pointer-events: none;
}
.rte-editor ul, .rte-editor ol { margin: 0 0 10px; padding-left: 22px; }
.rte-editor li { margin-bottom: 3px; }
.rte-editor p, .rte-editor div { margin: 0 0 10px; }
.rte-editor a { color: var(--deep); text-decoration: underline; }

/* ── Radio/checkbox "cards" — the announcement kind and audience
   pickers, as tappable blocks instead of bare radio/checkbox rows. ── */
.pick-row { display: flex; flex-wrap: wrap; gap: 8px; }
.pick-card {
  position: relative; display: flex; align-items: center; gap: 9px;
  padding: 10px 14px; border: 1.5px solid var(--rule); border-radius: var(--radius-sm);
  cursor: pointer; font-size: 13px; font-weight: 500; color: var(--ink-2);
  transition: border-color .12s, background .12s, color .12s;
}
.pick-card:hover { border-color: var(--ink-4); }
.pick-card input { position: absolute; opacity: 0; width: 0; height: 0; }
.pick-card .dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.pick-card:has(input:checked), .pick-card.is-checked {
  border-color: var(--deep); background: var(--deep-3); color: var(--ink); font-weight: 600;
}
.pick-card .mono { font-family: var(--mono); font-size: 12px; }

/* ═════════════════════════════════════════════════════════════════
   REPORTS — simple, server-rendered charts. No JS chart library:
   horizontal bars are div widths driven by inline style, and the
   volume trend is plain inline SVG built in PHP. Both degrade to
   readable numbers even with CSS or JS entirely off.
   ═════════════════════════════════════════════════════════════════ */
.bar-list { display: flex; flex-direction: column; gap: 12px; }
.bar-row { display: grid; grid-template-columns: 120px 1fr 44px; align-items: center; gap: 10px; }
.bar-row .lbl { font-size: 12.5px; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-row.wide { grid-template-columns: 190px 1fr 44px; }
.bar-row.wide .lbl { text-align: right; white-space: normal; overflow: visible; text-overflow: clip; line-height: 1.3; }
.bar-row .track { height: 8px; background: var(--sunken); border-radius: 4px; overflow: hidden; }
.bar-row .fill { height: 100%; background: var(--deep); border-radius: 4px; transition: width .3s; }
.bar-row .fill.critical { background: var(--critical); }
.bar-row .fill.high     { background: var(--high); }
.bar-row .fill.normal   { background: var(--deep); }
.bar-row .fill.low      { background: var(--ink-4); }
.bar-row .n { font-family: var(--mono); font-size: 12px; color: var(--ink-2); text-align: right; }

.trend-wrap { padding: 4px 4px 0; }
.trend-wrap svg { display: block; width: 100%; height: auto; }
.trend-wrap .grid { stroke: var(--rule); stroke-width: 1; }
.trend-wrap .area { fill: var(--deep-3); opacity: .6; stroke: none; }
.trend-wrap .line { fill: none; stroke: var(--deep); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.trend-wrap .dot { fill: var(--card); stroke: var(--deep); stroke-width: 1.6; transition: r .1s; }
.trend-wrap .dot:hover { r: 4.5; fill: var(--deep); }
.trend-axis { font-size: 9.5px; fill: var(--ink-4); font-family: inherit; }

.range-bar { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
.seg { display: flex; border: 1px solid var(--rule); border-radius: var(--radius-sm); overflow: hidden; }
.seg a {
  padding: 7px 14px; font-size: 12.5px; font-weight: 500; color: var(--ink-2);
  border-right: 1px solid var(--rule);
}
.seg a:last-child { border-right: none; }
.seg a.on { background: var(--deep); color: #fff; font-weight: 600; }
.range-bar select {
  font: inherit; font-size: 12.5px; padding: 7px 10px; border: 1px solid var(--rule);
  border-radius: var(--radius-sm); background: var(--card); color: var(--ink);
}

/* ── Donut chart — Status Breakdown. Built with stroke-dasharray
   segments around a circle (no JS charting library), with a legend
   list beside it giving the exact counts a slice alone cannot. ── */
.donut-wrap { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.donut-wrap svg { flex-shrink: 0; }
.donut-seg { transition: opacity .12s; cursor: default; }
.donut-seg:hover { opacity: .8; }
.donut-total { font-family: var(--mono); font-weight: 700; font-size: 20px; fill: var(--ink); }
.donut-total-lbl { font-size: 9.5px; fill: var(--ink-3); }
.donut-legend { display: flex; flex-direction: column; gap: 8px; flex: 1; min-width: 140px; }
.donut-legend .row { display: flex; align-items: center; gap: 8px; font-size: 12.5px; }
.donut-legend .sw { width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0; }
.donut-legend .lbl { color: var(--ink-2); flex: 1; }
.donut-legend .n { font-family: var(--mono); color: var(--ink); font-weight: 600; }

/* Fixed-height chart containers — Highcharts is told the same 220px
   both here and in its own chart.height config, but pie vs bar chart
   types render with slightly different internal spacing even at "the
   same" height, and that few-pixel difference compounds visibly once
   several paired rows stack down the page. Hard-coding the box height
   in CSS, not just in the Highcharts call, is what actually keeps
   every row's two cards the same size regardless of chart type. */
.chart-box { height: 220px; }

/* One grid for all six paired report cards, not three independent
   flex rows. CSS Grid tracks rows as a first-class concept — every
   card in the same row is stretched to the tallest one in that row
   automatically, which is a stronger guarantee than pairing flex
   containers by hand and hoping each one behaves identically. */
.chart-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px;
}
.chart-grid .card { margin-bottom: 0; }
@media (max-width: 720px) {
  .chart-grid { grid-template-columns: 1fr; }
}

/* ── Knowledge Base banner — request form ────────────────────────────
   A distinct, clickable callout, not a link buried inside a paragraph.
   Gradient background makes it read as an invitation to click rather
   than a footnote; the arrow nudges right on hover as the one motion
   cue on an otherwise static form. */
.kb-banner {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 18px; margin: 18px 0 26px; border-radius: 14px;
  background: linear-gradient(135deg, var(--deep-3), #EEF3FC);
  border: 1px solid var(--deep-3);
  text-decoration: none; transition: box-shadow .15s, border-color .15s;
}
.kb-banner:hover { box-shadow: 0 6px 18px -8px rgba(0,56,147,.3); border-color: var(--deep); }
.kb-banner-text { flex: 1; display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.kb-banner-text b { font-size: 14px; color: var(--ink); font-weight: 700; }
.kb-banner-text span { font-size: 12.5px; color: var(--ink-2); }
.kb-banner-go { color: var(--deep); flex-shrink: 0; transition: transform .15s; }
.kb-banner:hover .kb-banner-go { transform: translateX(3px); }

/* ── Signature pad — asset issue / return ────────────────────────── */
.sigpad-wrap { border: 1px solid var(--rule); border-radius: var(--radius-sm); overflow: hidden; background: #fff; }
.sigpad-wrap canvas { display: block; width: 100%; height: 140px; touch-action: none; cursor: crosshair; }
.sigpad-foot {
  display: flex; justify-content: space-between; align-items: center;
  padding: 6px 10px; border-top: 1px solid var(--rule); background: var(--sunken);
  font-size: 11px; color: var(--ink-3);
}