/* Sonic Titan Staffing Portal — stylesheet.
 *
 * Shell: a fixed dark sidebar (brand, nav, account) beside a scrolling
 * content column. The sidebar is dark in both themes; only the content
 * column switches. Everything is driven by the tokens in :root. Dark is the
 * default set; the light set is applied three ways so the choice survives a
 * reload before JS has run:
 *
 *   [data-theme="light"]                  explicit choice
 *   [data-theme="system"] + prefers light follow the OS
 *   no attribute + prefers light          before JS has set the attribute
 *
 * Nothing below the token blocks hard-codes a colour, so a theme is only ever
 * a token change. Status colours (dots, chips, the donut) live in app.js as
 * literal hex because they are also used as SVG presentation attributes.
 *
 * Inter is self-hosted from static/fonts (SIL OFL, licence alongside). No CDN:
 * the site must work with nothing but this box, and a third-party font host
 * would sit in front of candidate PII.
 */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("/static/fonts/inter-latin-wght-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
                 U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
                 U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* content column */
  --bg:            #0f1318;
  --surface:       #151a21;
  --surface-2:     #1a2029;
  --surface-hover: #1e252f;
  --rule:          #242b36;
  --rule-strong:   #333d4b;
  --rule-input:    #465162;

  --text:          #e8ebf0;
  --text-dim:      #9ea8b5;
  --text-faint:    #6b7584;

  --accent:        #5aa9e6;
  --accent-strong: #7cbcf0;
  --accent-ink:    #06111c;
  --accent-soft:   rgba(90,169,230,.14);
  --focus:         rgba(90,169,230,.45);
  --brand:         #d8434f;   /* the crimson of the central helmet */
  --brand-soft:    rgba(216,67,79,.16);

  --ok:            #3fc46a;   --ok-soft:   rgba(63,196,106,.14);
  --warn:          #e0a63a;   --warn-soft: rgba(224,166,58,.15);
  --err:           #f07171;   --err-soft:  rgba(240,113,113,.14);
  --info:          #7fb0d8;   --info-soft: rgba(127,176,216,.15);

  --chip-bg:       rgba(255,255,255,.06);
  --shadow:        0 1px 2px rgba(0,0,0,.4), 0 16px 40px rgba(0,0,0,.45);
  --shadow-sm:     0 1px 2px rgba(0,0,0,.3);
  --ini-bg-l:      22%;   /* initials avatar lightness (bg / text) */
  --ini-fg-l:      78%;

  /* sidebar — dark in both themes */
  --side-bg:       #0a0d12;
  --side-rule:     rgba(255,255,255,.07);
  --side-text:     #c5ccd6;
  --side-muted:    #7a8492;
  --side-hover:    rgba(255,255,255,.05);
  --side-active:   rgba(255,255,255,.08);
  --side-w:        248px;

  --radius:        8px;
  --radius-sm:     6px;
  --radius-lg:     12px;
  --font: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
  color-scheme: dark;
}

:root[data-theme="light"] {
  --bg:            #f3f4f6;
  --surface:       #ffffff;
  --surface-2:     #f7f8fa;
  --surface-hover: #f1f3f6;
  --rule:          #e4e7ec;
  --rule-strong:   #cfd4dc;
  --rule-input:    #b9c0ca;

  --text:          #111827;
  --text-dim:      #4b5563;
  --text-faint:    #8b93a1;

  --accent:        #2374ab;
  --accent-strong: #1b5f8f;
  --accent-ink:    #ffffff;
  --accent-soft:   rgba(35,116,171,.10);
  --focus:         rgba(35,116,171,.30);
  --brand:         #c0323e;
  --brand-soft:    rgba(192,50,62,.10);

  --ok:            #1f8a44;   --ok-soft:   rgba(31,138,68,.10);
  --warn:          #955f0c;   --warn-soft: rgba(196,144,42,.14);
  --err:           #b83232;   --err-soft:  rgba(184,50,50,.09);
  --info:          #2a5a86;   --info-soft: rgba(42,90,134,.10);

  --chip-bg:       rgba(17,24,39,.05);
  --shadow:        0 1px 2px rgba(16,24,40,.06), 0 16px 40px rgba(16,24,40,.14);
  --shadow-sm:     0 1px 2px rgba(16,24,40,.05);
  --ini-bg-l:      91%;
  --ini-fg-l:      30%;
  color-scheme: light;
}

@media (prefers-color-scheme: light) {
  :root[data-theme="system"],
  :root:not([data-theme]) {
    --bg:            #f3f4f6;
    --surface:       #ffffff;
    --surface-2:     #f7f8fa;
    --surface-hover: #f1f3f6;
    --rule:          #e4e7ec;
    --rule-strong:   #cfd4dc;
    --rule-input:    #b9c0ca;

    --text:          #111827;
    --text-dim:      #4b5563;
    --text-faint:    #8b93a1;

    --accent:        #2374ab;
    --accent-strong: #1b5f8f;
    --accent-ink:    #ffffff;
    --accent-soft:   rgba(35,116,171,.10);
    --focus:         rgba(35,116,171,.30);
    --brand:         #c0323e;
    --brand-soft:    rgba(192,50,62,.10);

    --ok:            #1f8a44;   --ok-soft:   rgba(31,138,68,.10);
    --warn:          #955f0c;   --warn-soft: rgba(196,144,42,.14);
    --err:           #b83232;   --err-soft:  rgba(184,50,50,.09);
    --info:          #2a5a86;   --info-soft: rgba(42,90,134,.10);

    --chip-bg:       rgba(17,24,39,.05);
    --shadow:        0 1px 2px rgba(16,24,40,.06), 0 16px 40px rgba(16,24,40,.14);
    --shadow-sm:     0 1px 2px rgba(16,24,40,.05);
    --ini-bg-l:      91%;
    --ini-fg-l:      30%;
    color-scheme: light;
  }
}

/* ---------- base ---------- */

* { box-sizing: border-box; }
html { height: 100%; }
body {
  margin: 0; min-height: 100%;
  background: var(--bg); color: var(--text);
  font: 14px/1.5 var(--font);
  font-feature-settings: "cv11", "ss01";
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 2px; }
b, strong { font-weight: 600; }

h1, h2, h3 { margin: 0; letter-spacing: -.015em; }
h1 { font-size: 28px; font-weight: 700; line-height: 1.15; letter-spacing: -.02em; }
h2 { font-size: 15px; font-weight: 600; }

input, select, textarea, button { font: inherit; color: inherit; }
button { cursor: pointer; }
:is(input, select, textarea, button, a):focus-visible {
  outline: 2px solid var(--focus); outline-offset: 2px;
}
::placeholder { color: var(--text-faint); }
[hidden] { display: none !important; }

/* Shared control appearance. :where() keeps this at type-selector
   specificity so component rules can refine it without fighting. */
input:where(:not([type=checkbox]):not([type=radio])), select, textarea {
  background: var(--surface); color: var(--text);
  border: 1px solid var(--rule-input); border-radius: var(--radius);
  padding: 8px 12px; line-height: 1.4;
  transition: border-color .12s, box-shadow .12s;
}
input:where(:not([type=checkbox]):not([type=radio])):focus,
select:focus, textarea:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--focus);
}
select {
  padding-right: 32px; appearance: none;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238b93a1' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
  background-repeat: no-repeat; background-position: right 11px center;
}
input[type=checkbox] { width: 16px; height: 16px; accent-color: var(--accent); }
input[type=search] { appearance: none; }
input[type=search]::-webkit-search-decoration { display: none; }

/* ---------- shell: sidebar + content ---------- */

body { display: flex; min-height: 100vh; }
.sidebar {
  position: sticky; top: 0; align-self: flex-start;
  width: var(--side-w); flex: 0 0 var(--side-w); height: 100vh;
  display: flex; flex-direction: column;
  background: var(--side-bg); color: var(--side-text);
  border-right: 1px solid var(--side-rule);
  z-index: 40;
}
.shell { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
body.signed-out .sidebar, body.signed-out .mobilebar { display: none; }

.brand {
  display: flex; align-items: center; gap: 12px;
  padding: 18px 20px 16px; color: #fff; text-decoration: none;
  border-bottom: 1px solid var(--side-rule);
}
.brand:hover { text-decoration: none; }
.brand .mark { height: 38px; width: auto; display: block; filter: drop-shadow(0 1px 1px rgba(0,0,0,.6)); }
.brand .wordmark { display: flex; flex-direction: column; line-height: 1.15; white-space: nowrap; }
.brand strong { font-size: 14px; font-weight: 800; letter-spacing: .10em; }
.brand .wordmark span { font-size: 12px; color: var(--side-muted); font-weight: 500; letter-spacing: .01em; }

.nav { display: flex; flex-direction: column; gap: 2px; padding: 14px 12px; overflow-y: auto; flex: 1 1 auto; }
.nav a {
  position: relative; display: flex; align-items: center; gap: 12px;
  padding: 9px 12px; border-radius: var(--radius);
  color: var(--side-text); font-weight: 500; white-space: nowrap; text-decoration: none;
  transition: background .12s, color .12s;
}
.nav a svg { width: 18px; height: 18px; flex: 0 0 18px; color: var(--side-muted); transition: color .12s; }
.nav a:hover { background: var(--side-hover); color: #fff; text-decoration: none; }
.nav a:hover svg { color: var(--side-text); }
.nav a.active { background: var(--side-active); color: #fff; font-weight: 600; }
.nav a.active svg { color: var(--brand); }
.nav a.active::before {
  content: ""; position: absolute; left: -12px; top: 8px; bottom: 8px; width: 3px;
  background: var(--brand); border-radius: 0 3px 3px 0;
}
.nav .navlabel {
  padding: 14px 12px 6px; color: var(--side-muted);
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .08em;
}

.sidefoot { padding: 12px; border-top: 1px solid var(--side-rule); }

/* ---------- account menu (sidebar footer) ---------- */

.accountmenu { position: relative; }
.acct {
  display: flex; align-items: center; gap: 11px; width: 100%;
  padding: 8px 10px; background: none; border: 0; border-radius: var(--radius);
  color: var(--side-text); text-align: left; cursor: pointer;
  transition: background .12s;
}
.acct:hover { background: var(--side-hover); }
.acct .who { flex: 1 1 auto; min-width: 0; line-height: 1.25; }
.acct .who b { display: block; color: #fff; font-weight: 600; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acct .who small { display: block; color: var(--side-muted); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acct .chev { color: var(--side-muted); flex: 0 0 auto; }
.avatar {
  width: 34px; height: 34px; border-radius: 50%; flex: 0 0 34px;
  display: grid; place-items: center;
  background: var(--brand); color: #fff;
  font-size: 12px; font-weight: 700; letter-spacing: .02em;
}

.accountmenu .sheet {
  /* Sized to its contents rather than pinned to the sidebar's width, which is
     narrower than a full work email. It grows rightwards over the content
     area, never past the viewport. */
  position: absolute; left: 0; right: auto; bottom: calc(100% + 8px); z-index: 50;
  min-width: 100%; width: max-content; max-width: min(340px, calc(100vw - 32px));
  background: var(--surface); color: var(--text);
  border: 1px solid var(--rule); border-radius: var(--radius-lg); box-shadow: var(--shadow);
  padding: 14px 14px 8px;
}
.accountmenu .sheet .who { font-weight: 600; }
/* Past the max-width an address wraps rather than running out of the box. */
.accountmenu .sheet .sub { color: var(--text-dim); font-size: 12px; margin-top: 2px; overflow-wrap: anywhere; }
.accountmenu .sheet .role {
  display: inline-block; margin-top: 10px; padding: 2px 8px; border-radius: 999px;
  background: var(--brand-soft); color: var(--brand); font-size: 11px; font-weight: 600;
}
.accountmenu .sheet .menu { margin: 12px -14px 0; padding-top: 6px; border-top: 1px solid var(--rule); }
.accountmenu .sheet .menu a,
.accountmenu .sheet .menu button.item {
  display: block; width: 100%; text-align: left;
  padding: 9px 14px; background: none; border: 0;
  color: var(--text); font: inherit; text-decoration: none; cursor: pointer;
}
.accountmenu .sheet .menu a:hover,
.accountmenu .sheet .menu button.item:hover { background: var(--surface-hover); text-decoration: none; }
.accountmenu .sheet .menu .sep { border-top: 1px solid var(--rule); margin: 6px 0; }
.accountmenu .sheet .grouplabel {
  padding: 8px 14px 4px; color: var(--text-faint);
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .06em;
}

/* Segmented theme control (also used on the account settings page). */
.themerow { display: flex; padding: 4px 14px 10px; }
.themerow button {
  flex: 1; padding: 7px 0; background: var(--surface-2); color: var(--text-dim);
  border: 1px solid var(--rule-input); font-size: 12px; font-weight: 500; margin-left: -1px;
}
.themerow button:first-child { border-radius: var(--radius-sm) 0 0 var(--radius-sm); margin-left: 0; }
.themerow button:last-child  { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.themerow button:hover { color: var(--text); }
.themerow button.active {
  position: relative; z-index: 1;
  background: var(--accent-soft); border-color: var(--accent); color: var(--accent); font-weight: 600;
}

/* ---------- mobile bar (narrow screens only) ---------- */

.mobilebar {
  display: none; align-items: center; gap: 12px;
  height: 56px; padding: 0 12px 0 16px;
  background: var(--side-bg); color: #fff; border-bottom: 1px solid var(--side-rule);
  position: sticky; top: 0; z-index: 30;
}
.mobilebar .brand { padding: 0; border: 0; flex: 1 1 auto; }
.mobilebar .brand .mark { height: 30px; }
.menubtn {
  width: 40px; height: 40px; display: grid; place-items: center;
  background: none; border: 0; border-radius: var(--radius); color: #fff;
}
.menubtn:hover { background: var(--side-hover); }
.backdrop { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 39; }

/* ---------- page scaffolding ---------- */

main { width: 100%; max-width: 1400px; margin: 0 auto; padding: 32px 36px 96px; }

.pagehead {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 20px; flex-wrap: wrap; margin-bottom: 24px;
}
.pagehead .lede { margin: 6px 0 0; color: var(--text-dim); max-width: 72ch; font-size: 14.5px; }
.pagehead .actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pagehead .status { display: flex; align-items: center; gap: 8px; margin-top: 12px; flex-wrap: wrap; }

.eyebrow {
  display: inline-block; margin-bottom: 8px; color: var(--brand);
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .10em;
}
.backlink {
  display: inline-flex; align-items: center; gap: 6px; margin-bottom: 16px;
  color: var(--text-dim); font-size: 13px; font-weight: 500;
}
.backlink:hover { color: var(--text); text-decoration: none; }

/* A panel is a titled surface: a header row, then a body. Tables inside a
   panel bleed to its edges so the rules line up with the frame. */
.panel {
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  margin-bottom: 24px; overflow: hidden;
}
.panelhead {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 16px 20px; border-bottom: 1px solid var(--rule);
}
.panelhead h2 { display: flex; align-items: center; gap: 10px; font-size: 15px; }
.panelhead .sub { color: var(--text-dim); font-size: 13px; }
.panelhead .actions { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.panelbody { padding: 20px; }
.panelbody > :last-child { margin-bottom: 0; }
.count {
  display: inline-block; padding: 1px 8px; border-radius: 999px;
  background: var(--chip-bg); color: var(--text-dim);
  font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums;
}

/* KPI tiles */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 16px; margin-bottom: 24px; }
.stat {
  position: relative; display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
  background: var(--surface); border: 1px solid var(--rule); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm); padding: 18px 20px; text-decoration: none; color: inherit;
  transition: border-color .12s, transform .12s;
}
a.stat:hover { border-color: var(--rule-strong); text-decoration: none; transform: translateY(-1px); }
.stat .label { color: var(--text-dim); font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; }
.stat .value { margin-top: 6px; font-size: 30px; font-weight: 700; letter-spacing: -.03em; line-height: 1.1; font-variant-numeric: tabular-nums; }
.stat .hint { margin-top: 6px; color: var(--text-faint); font-size: 12.5px; }
.stat .ico {
  width: 40px; height: 40px; border-radius: 10px; flex: 0 0 40px;
  display: grid; place-items: center; background: var(--accent-soft); color: var(--accent);
  /* Own the box outright. Tones are prefixed (see the stat helper in app.js)
     so they cannot pick up a component rule of the same name, and these two
     hold the square square if one ever does. */
  padding: 0; border: 0;
}
.stat .ico.tone-brand { background: var(--brand-soft); color: var(--brand); }
.stat .ico.tone-ok { background: var(--ok-soft); color: var(--ok); }
.stat .ico.tone-warn { background: var(--warn-soft); color: var(--warn); }

/* ---------- buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 36px; padding: 0 14px;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--rule-input); border-radius: var(--radius);
  font-weight: 500; white-space: nowrap; text-decoration: none;
  transition: background .12s, border-color .12s, color .12s, transform .05s;
}
.btn:hover { background: var(--surface-hover); border-color: var(--rule-strong); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn svg { flex: 0 0 auto; }
.btn.primary {
  background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 600;
}
.btn.primary:hover { background: var(--accent-strong); border-color: var(--accent-strong); }
.btn.sm { height: 31px; padding: 0 11px; font-size: 13px; border-radius: var(--radius-sm); }
.btn.ghost { background: transparent; border-color: transparent; color: var(--text-dim); }
.btn.ghost:hover { background: var(--surface-hover); color: var(--text); }

/* ---------- table toolbar, table, footer ---------- */

.toolbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 20px; border-bottom: 1px solid var(--rule); background: var(--surface);
}
.search { position: relative; margin-left: auto; }
.search input {
  width: 280px; max-width: 100%; height: 34px; padding: 0 12px 0 34px;
  background: var(--surface-2); border-radius: var(--radius);
}
.search svg {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  color: var(--text-faint); pointer-events: none;
}

/* A table wider than its panel scrolls, and SAYS SO. Without the fade the
   columns past the edge are simply not there: Vacancies is eleven columns and
   the three on the right -- including Status -- ended at the panel border with
   nothing to suggest they existed. The fade is toggled by dataTable on render,
   on scroll and on resize, so it marks a real edge rather than decorating one,
   and it clears once you reach the end. */
.tablescroll { position: relative; }
.tablescroll::after {
  content: ""; position: absolute; top: 0; right: 0; bottom: 0; width: 44px;
  pointer-events: none; opacity: 0; transition: opacity .15s ease;
  background: linear-gradient(to left, var(--surface) 10%, rgba(0, 0, 0, 0));
}
.tablescroll.more::after { opacity: 1; }
.tablewrap { overflow-x: auto; }
main > .tablewrap, .panelbody > .tablewrap {
  background: var(--surface); border: 1px solid var(--rule); border-radius: var(--radius-lg);
}
table { width: 100%; border-collapse: collapse; }
th, td {
  padding: 12px 16px; text-align: left; vertical-align: middle;
  border-bottom: 1px solid var(--rule);
}
th:first-child, td:first-child { padding-left: 20px; }
th:last-child,  td:last-child  { padding-right: 20px; }
th {
  color: var(--text-faint); font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .07em;
  background: var(--surface-2); padding-top: 10px; padding-bottom: 10px;
  /* Headings wrap; cells do not. This is the other half of the column-width
     rule below, and on a wide table it is the half that buys the room. The
     heading is often the longest thing in its column -- PERCENT TELEWORK is
     130px of nowrap above a cell reading "40%", CCAS ACCEPTED is 110px above
     "Yes" -- so pinning the column to the heading spent width on the labels
     and took it from the columns with something in them. */
  white-space: normal;
}
tbody tr:last-child td { border-bottom: 0; }
tbody tr { transition: background .1s; }
tbody tr:hover td { background: var(--surface-hover); }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
td a { font-weight: 500; }
td .vacflag { display: block; }
td .vacflag.inline { display: inline; }
.sortcaret { color: var(--text-faint); margin-left: 5px; font-size: 11px; }
/* Idle means "this column can be sorted", so it is present but quiet; the
   active one is the only caret carrying a direction. */
.sortcaret.idle { opacity: 0; transition: opacity .12s ease; }
th[data-sort] { cursor: pointer; user-select: none; }
th[data-sort]:hover .sortcaret.idle,
th[data-sort]:focus-visible .sortcaret.idle { opacity: .5; }
th[data-sort]:hover { color: var(--text); }
th[data-sort]:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
th.sorted { color: var(--text); }
th.sorted .sortcaret { color: var(--brand); }

/* ---- column width ----
 *
 * A table in auto layout narrows a column toward its longest WORD as soon as
 * the columns together want more room than there is. Vacancies is eleven
 * columns wide, so that is what happened to TTO: the browser sized it to the
 * three letters in the heading and wrapped the task order underneath it, one
 * word per line. Nothing on the page chose that column; the browser did, and
 * it picks the one whose content it can break.
 *
 * So a cell does not wrap. Every column is as wide as what is in it, and when
 * they do not all fit, the table scrolls sideways inside .tablewrap -- which
 * is visible and reversible, unlike a column quietly squeezed. Columns holding
 * prose rather than a value opt back in: `wrap` for an address or a list,
 * `wide` for something that wants room and has a ceiling.
 */
td { white-space: nowrap; }
td.wrap { white-space: normal; min-width: 16ch; }
td.wide { white-space: normal; min-width: 24ch; max-width: 44ch; }
/* break-word, not anywhere: a long address breaks between words where it can
   and only splits one when a single word is wider than the column. */
td.wrap, td.wide { overflow-wrap: break-word; }
/* The one full-width cell. It is centred prose, and nowrap would push the
   whole table wide to fit a sentence nobody needs on one line. */
td.empty { white-space: normal; }

/* Two lines by design -- the opening, then its status and labour category --
   in the narrow column of a detail page. */
.subrow td.opening { white-space: normal; }

.tablefoot {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 20px; border-top: 1px solid var(--rule);
  color: var(--text-dim); font-size: 13px; background: var(--surface);
}
.tablefoot select { padding: 5px 30px 5px 10px; font-size: 13px; background-color: var(--surface-2); border-radius: var(--radius-sm); }
.tablefoot .btn { height: 30px; padding: 0 11px; font-size: 13px; }
.empty { padding: 36px 20px; color: var(--text-faint); text-align: center; }
main > .empty { text-align: left; padding: 0; }

/* Person cell: initials disc + name. The hue is set inline per name. */
.person { display: inline-flex; align-items: center; gap: 10px; font-weight: 500; }
.person .ini {
  width: 28px; height: 28px; border-radius: 50%; flex: 0 0 28px;
  display: grid; place-items: center; font-size: 11px; font-weight: 700; letter-spacing: .02em;
  background: hsl(var(--h) 45% var(--ini-bg-l)); color: hsl(var(--h) 50% var(--ini-fg-l));
}

/* ---------- tabs ---------- */

.tabs {
  display: flex; gap: 2px; padding: 0 20px;
  border-bottom: 1px solid var(--rule); background: var(--surface);
}
.tabs button {
  position: relative; display: inline-flex; align-items: center; gap: 8px;
  padding: 13px 12px; background: none; border: 0;
  color: var(--text-dim); font-weight: 500;
}
.tabs button:hover { color: var(--text); }
.tabs button.active { color: var(--text); font-weight: 600; }
.tabs button.active::after {
  content: ""; position: absolute; left: 12px; right: 12px; bottom: -1px;
  height: 2px; background: var(--accent); border-radius: 2px 2px 0 0;
}
.tabs button.active .count { background: var(--accent-soft); color: var(--accent); }
.tabhint {
  margin: 0; padding: 10px 20px; color: var(--text-dim); font-size: 13px;
  border-bottom: 1px solid var(--rule); background: var(--surface-2);
}

/* ---------- status chips & flags ---------- */

.pill {
  display: inline-flex; align-items: center; gap: 7px; white-space: nowrap;
  padding: 3px 10px 3px 8px; border-radius: 999px;
  background: var(--chip-bg); font-size: 12.5px; font-weight: 500; line-height: 1.4;
}
.pill select { padding: 2px 26px 2px 6px; font-size: 12.5px; border-color: transparent; background-color: transparent; }
.pill select:hover { border-color: var(--rule-input); }
.dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 8px; box-shadow: 0 0 0 2px rgba(0,0,0,.06); }
.none { color: var(--text-faint); }

.flag {
  display: inline-block; margin-left: 6px; padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 600; white-space: nowrap; line-height: 1.4;
  background: var(--chip-bg); color: var(--text-dim);
}
.flag.ok    { background: var(--ok-soft);   color: var(--ok); }
.flag.warn  { background: var(--warn-soft); color: var(--warn); }
.flag.multi { background: var(--info-soft); color: var(--info); }
td .flag { margin-top: 2px; }

/* ---------- donut summary ---------- */

.chartrow { display: flex; align-items: center; gap: 44px; flex-wrap: wrap; padding: 22px 24px; }
.chartrow svg { flex: 0 0 auto; }
.chartrow .track { stroke: var(--rule); }
.chartrow .total { fill: var(--text); }
.chartrow .totallabel { fill: var(--text-dim); }
.legend {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
  gap: 10px 32px; flex: 1 1 340px;
}
.legend div { display: grid; grid-template-columns: 10px 1fr 60px 28px; align-items: center; gap: 10px; color: var(--text); font-size: 13px; }
.legend .sw { width: 10px; height: 10px; border-radius: 50%; }
.legend .bar { height: 4px; background: var(--rule); border-radius: 2px; overflow: hidden; }
.legend .bar i { display: block; height: 100%; border-radius: 2px; }
.legend .n  { text-align: right; color: var(--text-dim); font-variant-numeric: tabular-nums; font-weight: 600; }

/* ---------- detail views ---------- */

.detail { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 24px; align-items: start; }
.detail > .side { position: sticky; top: 24px; }
@media (max-width: 1100px) { .detail { grid-template-columns: 1fr; } .detail > .side { position: static; } }

/* The buttons under a panel's facts. Padded like .panelbody, ruled off from
   the rows above so the actions are visibly a separate thing from the
   statements of fact they follow. */
.actionrow {
  display: flex; flex-wrap: wrap; gap: 8px;
  padding: 16px 20px; border-top: 1px solid var(--rule);
}
.facts { display: grid; gap: 0; }
.facts .row { padding: 12px 20px; border-bottom: 1px solid var(--rule); }
.facts .row:last-child { border-bottom: 0; }
.facts .k { color: var(--text-faint); font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .07em; }
.facts .v { margin-top: 3px; font-weight: 500; overflow-wrap: anywhere; }
.facts .v:empty::after { content: "—"; color: var(--text-faint); font-weight: 400; }

/* Compact field grid, used where a page has no side column. */
.detailgrid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  background: var(--surface); box-shadow: var(--shadow-sm);
  border: 1px solid var(--rule); border-radius: var(--radius-lg); overflow: hidden;
  margin-bottom: 24px;
}
.detailgrid .cell {
  padding: 14px 18px; min-width: 0; margin: 0 -1px -1px 0;
  border-right: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
}
.detailgrid .k { color: var(--text-faint); font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .07em; }
.detailgrid .v { margin-top: 5px; font-weight: 500; overflow-wrap: anywhere; }
.detailgrid .v:empty::after { content: "—"; color: var(--text-faint); font-weight: 400; }

/* Rich text out of Knack, sanitized server-side (app/richtext.py). Normal
   whitespace, not pre-wrap: the source is Word HTML wrapped mid-sentence, so
   preserving its newlines would break lines at random. */
.longtext { overflow-wrap: anywhere; color: var(--text-dim); line-height: 1.65; }
.panelbody.longtext { padding: 20px; margin: 0; }
.longtext > :first-child { margin-top: 0; }
.longtext > :last-child  { margin-bottom: 0; }
.longtext p { margin: 0 0 12px; }
.longtext ul, .longtext ol { margin: 0 0 12px; padding-left: 22px; }
.longtext li { margin: 0 0 6px; }
/* Word wraps each bullet's text in its own <p>; without this every bullet
   would carry a paragraph's trailing gap. */
.longtext li > p { margin: 0; }
.longtext li::marker { color: var(--text-faint); }
.longtext b, .longtext strong { color: var(--text); font-weight: 650; }
.longtext h3, .longtext h4 { color: var(--text); font-size: 14px; margin: 18px 0 8px; }
.longtext blockquote { margin: 0 0 12px; padding-left: 14px; border-left: 2px solid var(--rule-strong); }

.subrow select { min-width: 190px; }
.subrow input[type=text] { width: 100%; min-width: 150px; }
.subrow td.opening { min-width: 200px; }
.subrow td.opening .vacflag { display: flex; align-items: center; gap: 8px; margin-top: 6px; flex-wrap: wrap; }
.subrow td.save { width: 1%; white-space: nowrap; }
.pill.sm { padding: 1px 8px 1px 6px; font-size: 11.5px; }
.saved  { color: var(--ok);  font-size: 12px; font-weight: 600; margin-top: 4px; }
.failed { color: var(--err); font-size: 12px; font-weight: 600; margin-top: 4px; }
.vacflag { font-size: 12px; color: var(--text-faint); }

/* ---------- notices ---------- */

.formerror, .formok {
  border-radius: var(--radius); padding: 10px 13px; margin-bottom: 16px;
  font-size: 13px; line-height: 1.5;
}
.formerror { background: var(--err-soft); color: var(--err); border: 1px solid transparent; }
.formok    { background: var(--ok-soft);  color: var(--ok);  border: 1px solid transparent; }
.devlink, .readonly {
  margin-top: 14px; padding: 11px 13px; word-break: break-word;
  background: var(--surface-2); border: 1px dashed var(--rule-strong); border-radius: var(--radius);
  color: var(--text-dim); font-size: 12.5px; line-height: 1.5;
}
.readonly { margin-top: 16px; }
.devlink b { color: var(--warn); }

/* ---------- auth: split screen ---------- */

.authwrap { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); min-height: 100vh; }
.authbrand {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; justify-content: center;
  padding: 40px 48px; background: var(--side-bg); color: #fff;
}
.authbrand::before {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(60% 50% at 20% 10%, rgba(216,67,79,.22), transparent 60%),
    radial-gradient(50% 45% at 90% 90%, rgba(90,169,230,.18), transparent 60%);
}
.authbrand > * { position: relative; }
.authbrand .hero { padding: 40px 0; }
/* The wordmark is the centrepiece here rather than a corner marker, so it is
   scaled well past its sidebar size. clamp keeps it from crowding the pane on
   a narrow window. */
.authbrand .brand { padding: 0; border: 0; gap: clamp(14px, 1.6vw, 22px); margin-bottom: 32px; }
.authbrand .brand .mark { height: clamp(56px, 6.5vw, 88px); filter: drop-shadow(0 6px 18px rgba(0,0,0,.6)); }
.authbrand .brand strong { font-size: clamp(22px, 2.4vw, 34px); letter-spacing: .09em; }
.authbrand .brand .wordmark { gap: 4px; }
.authbrand .brand .wordmark span { font-size: clamp(13px, 1.15vw, 17px); color: var(--side-text); letter-spacing: .02em; }
.authbrand .hero h2 { font-size: clamp(22px, 2.1vw, 30px); font-weight: 700; letter-spacing: -.02em; line-height: 1.2; margin: 0; max-width: 20ch; }
.authpane { display: grid; place-items: center; padding: 48px 24px; background: var(--bg); }
.authcard { width: 100%; max-width: 400px; }
.authcard h1 { font-size: 26px; margin: 0 0 8px; }
.authcard p.lede { color: var(--text-dim); margin: 0 0 26px; line-height: 1.55; }
.authcard .btn.primary { width: 100%; height: 42px; font-size: 15px; }
.authcard .alt { margin: 20px 0 0; text-align: center; font-size: 13px; }
.authcard .alt a { color: var(--text-dim); }
.authcard .alt a:hover { color: var(--text); }
.authglyph {
  width: 48px; height: 48px; margin-bottom: 18px; border-radius: 50%;
  display: grid; place-items: center; background: var(--accent-soft); color: var(--accent);
}

.field { margin-bottom: 16px; }
.field label { display: block; margin-bottom: 6px; font-size: 13px; font-weight: 500; }
.field input, .field select, .field textarea { width: 100%; }
.field input { height: 40px; }
.field .help { margin-top: 6px; color: var(--text-faint); font-size: 12.5px; line-height: 1.5; }

/* ---------- feature requests ---------- */

.frgrid { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 24px; align-items: start; }
@media (max-width: 1100px) { .frgrid { grid-template-columns: 1fr; } }
.frform textarea { min-height: 120px; resize: vertical; }
.frtitle { font-weight: 600; }
.frdetail { color: var(--text-dim); font-size: 13px; margin-top: 3px; white-space: pre-wrap; overflow-wrap: anywhere; }

/* ---------- settings ---------- */

.settingsgrid { display: grid; gap: 24px; max-width: 860px; }
.card {
  background: var(--surface); border: 1px solid var(--rule);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); padding: 24px;
}
.card h2 { margin: 0 0 4px; font-size: 16px; }
.card .sub { color: var(--text-dim); margin: 0 0 18px; font-size: 13px; }
.card .tablewrap { border: 1px solid var(--rule); border-radius: var(--radius); }
.card .toolbar { padding-left: 0; padding-right: 0; border-bottom: 0; background: transparent; }
.card .tablefoot { background: transparent; }
.card form .btn { margin-top: 2px; }
.kv { display: grid; grid-template-columns: 200px 1fr; gap: 12px 18px; margin: 0; }
.kv dt { color: var(--text-faint); font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .07em; padding-top: 3px; }
.kv dd { margin: 0; font-weight: 500; }
.toggle { display: flex; align-items: flex-start; gap: 12px; cursor: pointer; }
.toggle input { margin-top: 2px; }
.toggle .lbl { font-weight: 600; }
.toggle .desc { display: block; color: var(--text-dim); font-size: 13px; margin-top: 3px; line-height: 1.5; }
.card .themerow { padding: 0; max-width: 320px; }

/* Label + control on one line, used for the dashboard company picker. */
.inlinefield { display: inline-flex; align-items: center; gap: 8px; color: var(--text-dim); font-size: 13px; }
.inlinefield select { min-width: 220px; height: 36px; padding-top: 0; padding-bottom: 0; }

/* ---------- responsive ---------- */

@media (max-width: 900px) {
  body { display: block; }
  .mobilebar { display: flex; }
  body.signed-out .mobilebar { display: none; }
  .sidebar {
    position: fixed; top: 0; left: 0; height: 100vh;
    transform: translateX(-100%); transition: transform .18s ease;
    box-shadow: var(--shadow);
  }
  body.nav-open .sidebar { transform: none; }
  body.nav-open .backdrop { display: block; }
  main { padding: 20px 16px 80px; }
  h1 { font-size: 24px; }
  .search { margin-left: 0; flex: 1 1 100%; }
  .search input { width: 100%; }
  .kv { grid-template-columns: 1fr; gap: 2px 0; }
  .kv dd { margin-bottom: 10px; }
  /* Stacked, the brand pane is a header strip: keep the wordmark, drop the
     line under it and shrink the lockup back to its sidebar size. The rows
     are sized so the strip stays its own height instead of splitting the
     viewport with the form. */
  .authwrap { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .authbrand { padding: 20px 24px; }
  .authbrand .hero { padding: 0; }
  .authbrand .hero h2 { display: none; }
  .authbrand .brand { margin-bottom: 0; gap: 12px; }
  .authbrand .brand .mark { height: 38px; }
  .authbrand .brand strong { font-size: 14px; letter-spacing: .10em; }
  .authbrand .brand .wordmark span { font-size: 12px; color: var(--side-muted); }
  .authpane { align-items: start; padding-top: 36px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; }
}

/* Signed out, the auth split screen owns the whole content column. */
body.signed-out main { max-width: none; padding: 0; }

/* ---------- modal dialog ---------- */

dialog.modal {
  width: min(520px, calc(100vw - 32px)); padding: 0; margin: auto;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--rule); border-radius: var(--radius-lg); box-shadow: var(--shadow);
  /* Two stacked pickers make the tallest dialog here about 790px. On a short
     laptop that put the footer off the bottom of the screen with no way to
     reach Submit, so the body scrolls and the head and foot stay put. */
  max-height: calc(100vh - 32px);
}
dialog.modal > form, dialog.modal.confirm {
  display: flex; flex-direction: column; max-height: calc(100vh - 34px);
}
dialog.modal .modalbody { overflow-y: auto; }
dialog.modal .modalhead, dialog.modal .modalfoot { flex: none; }
dialog.modal::backdrop { background: rgba(6, 9, 14, .55); backdrop-filter: blur(2px); }
.modalhead {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px; border-bottom: 1px solid var(--rule);
}
.modalhead h2 { font-size: 16px; }
.modalbody { padding: 20px; }
.modalbody .help { margin: -6px 0 16px; color: var(--text-faint); font-size: 12.5px; line-height: 1.5; }
.modalbody .toggle { margin-top: 4px; }
/* `.modalbody .help` above is the lede under a dialog's TITLE, pulled up to
   sit against it. A help line under a FIELD is a different thing and belongs
   below its control -- inheriting the negative margin landed it on top of the
   select above it, which the candidate form made obvious by having three. */
.modalbody .field .help { margin: 6px 0 0; }
/* A checkbox is not a text box. `.field input` gives inputs a 40px height and
   a full width because that is what nearly every field here is; applied to a
   checkbox it produced a panel-wide 40px square floating above its label. */
.field input[type=checkbox] { width: auto; height: auto; }
.modalfoot {
  display: flex; justify-content: flex-end; gap: 10px;
  padding: 14px 20px; border-top: 1px solid var(--rule); background: var(--surface-2);
}
.field2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
@media (max-width: 520px) { .field2 { grid-template-columns: 1fr; } }

/* ---------- choose-one list (picker() in app.js) ----------

   Replaces a native <select size="8">, whose failure was that it clips a row
   at the right edge: the detail line that tells two openings apart was the
   part you could not read. Here the detail sits under the label and wraps. */
dialog.modal.wide { width: min(580px, calc(100vw - 32px)); }
.picker { margin-bottom: 2px; }
.pickersearch { width: 100%; height: 36px; margin-bottom: 8px; }
.pickerrows {
  max-height: 290px; overflow-y: auto;
  border: 1px solid var(--rule-input); border-radius: var(--radius);
  background: var(--surface-2);
}
/* Two stacked in one dialog (the dashboard's pair form) have to share the
   height, or the second one is below the fold on a laptop. */
.picker.short .pickerrows { max-height: 176px; }
.pickerrows:focus-visible { outline: 2px solid var(--brand); outline-offset: 1px; }
.pickerrow {
  display: flex; flex-direction: column; gap: 2px;
  padding: 9px 12px; cursor: pointer; border-bottom: 1px solid var(--rule);
}
.pickerrow:last-of-type { border-bottom: 0; }
.pickerrow:hover { background: var(--surface); }
/* The bar, not just the tint: the tint alone is easy to miss against
   --surface-2 on a dim screen, and this is the only thing on the dialog
   saying which row the Submit button will act on. */
.pickerrow.on { background: var(--brand-soft); box-shadow: inset 3px 0 0 var(--brand); }
.pickerrow .pl { font-size: 13.5px; font-weight: 500; }
.pickerrow .ps { font-size: 12px; color: var(--text-faint); line-height: 1.45; }
.pickerempty { padding: 14px 12px; color: var(--text-faint); font-size: 13px; }
.pickercount { margin-top: 7px; font-size: 12px; color: var(--text-faint); }

/* ---------- the resume panel on a candidate ---------- */
/* The file itself, when there is one: a target big enough to be the obvious
 * thing on the panel, because reading the resume is what the page is for. */
.resumebox .resumehave {
  display: flex; align-items: center; gap: 12px; margin-bottom: 10px;
  padding: 12px 14px; border-radius: var(--radius); text-decoration: none;
  border: 1px solid var(--rule); background: var(--surface-2); color: var(--text);
}
.resumebox .resumehave:hover { border-color: var(--accent); background: var(--accent-soft); }
.resumebox .resumehave svg { flex: 0 0 22px; color: var(--accent); }
.resumebox .resumehave .rh { display: flex; flex-direction: column; min-width: 0; }
.resumebox .resumehave .rn {
  font-size: 13.5px; font-weight: 600; overflow-wrap: anywhere; line-height: 1.35;
}
.resumebox .resumehave .rs { font-size: 11.5px; color: var(--text-faint); margin-top: 2px; }

/* And when there is not. Stated rather than whispered: a blank space here
 * reads as "nothing to do", and the whole point is that there is. */
.resumebox .resumenone {
  margin-bottom: 12px; padding: 12px 14px; border-radius: var(--radius);
  border: 1px dashed var(--rule-input); background: var(--surface-2);
}
.resumebox .resumenone.warn { border-color: var(--warn); background: var(--warn-soft); }
.resumebox .resumenone b { display: block; font-size: 13px; margin-bottom: 3px; }
.resumebox .resumenone span { display: block; font-size: 12.5px; color: var(--text-dim); line-height: 1.5; }

.resumebox .resumefile { margin: 0 0 6px; font-size: 13.5px; word-break: break-word; }
.resumebox .help { margin: 0 0 14px; color: var(--text-faint); font-size: 12.5px;
  line-height: 1.5; }
.resumebox .field { margin-bottom: 12px; }
.resumebox input[type=file] {
  width: 100%; font-size: 12.5px; padding: 7px 10px;
  border: 1px dashed var(--rule-input); border-radius: var(--radius);
  background: var(--surface-2); cursor: pointer;
}
.resumebox input[type=file]::file-selector-button {
  font: inherit; margin-right: 10px; padding: 4px 10px; cursor: pointer;
  color: var(--text); background: var(--surface);
  border: 1px solid var(--rule-input); border-radius: var(--radius-sm);
}
.resumebox .actionrow { display: flex; gap: 8px; }

/* The roster column. Reaching the document from the list is one click, and
 * the icon is what makes the column scannable at a glance. */
.resumelink {
  display: inline-flex; align-items: center; gap: 5px; text-decoration: none;
  color: var(--accent); font-size: 12.5px; font-weight: 600; white-space: nowrap;
}
.resumelink svg { width: 15px; height: 15px; flex: 0 0 15px; }
.resumelink:hover { text-decoration: underline; }

/* The resume question inside the add form, raised out of the run of fields
 * so it does not read as one more optional box at the bottom. */
.modalbody .field.resumeask {
  padding: 12px 14px; border-radius: var(--radius);
  border: 1px solid var(--rule); background: var(--surface-2);
}
.modalbody .field.resumeask input[type=file] {
  width: 100%; height: auto; font-size: 12.5px; padding: 7px 10px; cursor: pointer;
  border: 1px dashed var(--rule-input); border-radius: var(--radius);
  background: var(--surface);
}
.modalbody .field.resumeask input[type=file]::file-selector-button {
  font: inherit; margin-right: 10px; padding: 4px 10px; cursor: pointer;
  color: var(--text); background: var(--surface);
  border: 1px solid var(--rule-input); border-radius: var(--radius-sm);
}

/* Destructive actions: quiet until hovered, then unmistakably red. */
.btn.danger { background: var(--err); border-color: var(--err); color: #fff; font-weight: 600; }
.btn.danger:hover { filter: brightness(1.08); background: var(--err); border-color: var(--err); }
.btn.ghost.danger { background: transparent; border-color: transparent; color: var(--text-faint); }
.btn.ghost.danger:hover { background: var(--err-soft); color: var(--err); filter: none; }
td.actions { text-align: right; }
td.actions .btn + .btn { margin-left: 6px; }
dialog.modal.confirm .modalbody p { margin: 0 0 10px; color: var(--text-dim); line-height: 1.55; }
dialog.modal.confirm .modalbody p:last-child { margin-bottom: 0; }

/* The "waking up" notice. Fixed to the bottom so it never moves the page
   under a cursor that is already heading somewhere, and out of the flow so it
   cannot reflow a table mid-render. See api() in app.js for why it exists. */
#waking {
  position: fixed; left: 50%; bottom: 20px; transform: translate(-50%, 12px);
  max-width: min(520px, calc(100vw - 32px));
  padding: 10px 16px; border-radius: 8px;
  background: var(--surface); color: var(--text-dim);
  border: 1px solid var(--rule); box-shadow: 0 6px 24px rgba(0,0,0,.18);
  font-size: 13px; line-height: 1.45; text-align: center;
  opacity: 0; pointer-events: none;
  transition: opacity .18s ease, transform .18s ease;
  z-index: 60;
}
#waking.on { opacity: 1; transform: translate(-50%, 0); }
@media (prefers-reduced-motion: reduce) {
  #waking { transition: none; }
}

/* ---------- two-step verification ---------- */

/* The QR always sits on white, in both themes. A dark-mode inversion of a QR
 * code is still scannable by most readers and reliably scannable by none, and
 * the one thing this square must do is scan on the first try. */
.qrbox {
  display: grid; place-items: center;
  background: #fff; border-radius: 10px; border: 1px solid var(--rule);
  padding: 14px; margin: 0 0 18px;
}
/* 340px, not 260. The authcard is 400 wide and .qrbox eats 30 of it, so this
 * is very nearly all there is. The number matters: a version-8 code is 49
 * modules plus an 8-module quiet zone, and at 260px that was 4.5 pixels per
 * module -- around the floor at which a phone camera stops resolving one
 * module from the next, and below it on any narrower viewport. crispEdges
 * makes it worse, because it snaps each module edge independently, so a
 * fractional scale renders neighbouring modules at different widths. */
.qrbox svg { display: block; width: 100%; max-width: 340px; height: auto; }

.steps { margin: 0 0 20px 0; padding-left: 20px; color: var(--text-dim); line-height: 1.6; }
.steps li { margin-bottom: 6px; }

.manualkey { margin: 0 0 18px; font-size: 13px; }
.manualkey summary { cursor: pointer; color: var(--text-dim); }
.manualkey summary:hover { color: var(--text); }
.manualkey p { color: var(--text-dim); line-height: 1.5; margin: 10px 0; }
.manualkey .help { margin-bottom: 0; }

/* Grouped in fours and spaced out, because this is read aloud or retyped
 * character by character off a screen. */
.secret {
  display: block; padding: 10px 12px; border-radius: 8px;
  background: var(--surface-2); border: 1px solid var(--rule);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 15px; letter-spacing: .08em; word-break: break-all; user-select: all;
}

.codelist {
  list-style: none; margin: 0 0 16px; padding: 14px;
  border-radius: 10px; background: var(--surface-2); border: 1px solid var(--rule);
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px 16px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 14px; letter-spacing: .04em;
}
.codelist li { user-select: all; }
@media (max-width: 420px) { .codelist { grid-template-columns: 1fr; } }
