/* Pincite — "Record" design system: the application shell.
   Requires tokens.css, loaded first.

   Serves the five operator/counsel pages that are not the transcript itself:
   `templates/authorize.html`, `connect.html`, `upload.html`, `clio_pull.html`, `login.html`.
   Before this file each of those carried its own inline <style> block with its own
   greys, blues, and radii — four private design systems on one origin. The blocks are
   gone; every value here is a token.

   Why the <style> blocks had to go rather than merely be re-coloured: the marketing
   site's CSP forbids inline styles, and the app should not be the surface where that
   discipline lapses. An external sheet is also the only version a firm's own CSP can
   allow without `'unsafe-inline'`.

   Same rule as everywhere: anything the machine produced — an id, a URL, a digest, a
   filename, a timestamp, an enum — is set in --font-mono. */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background-color: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

main {
  max-width: var(--page);
  margin: 0 auto;
  padding: var(--space-5) 1.5rem var(--space-6);
}

main.wide { max-width: var(--page-wide); }

p { margin: 0 0 var(--space-3); max-width: var(--measure); }
p:last-child { margin-bottom: 0; }

h1, h2, h3 { color: var(--ink); text-wrap: balance; }

h1 {
  font-size: var(--step-3);
  font-weight: 650;
  line-height: 1.2;
  letter-spacing: -0.018em;
  margin: 0 0 var(--space-3);
}

h2 {
  font-size: var(--step-1);
  font-weight: 640;
  line-height: 1.3;
  letter-spacing: -0.008em;
  margin: var(--space-4) 0 var(--space-1);
}

code {
  font-family: var(--font-mono);
  font-size: 0.875em;
  background-color: var(--code-bg);
  padding: 0.12em 0.36em;
  border-radius: var(--radius-chip);
  word-break: break-word;
}

ol, ul { padding-left: 1.2rem; max-width: var(--measure); }
li { margin: 0.4rem 0; }

/* ---- links: the four states, and no others -------------------------- */

a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 0.18em; }
a:hover { color: var(--accent-lift); text-decoration-thickness: 2px; }
a:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 2px; }

/* ---- brand ---------------------------------------------------------- */
/* Two marks, one per theme, swapped by media query — the swap is CSS because there is
   no script on these pages that may decide what renders. The mark is a pincite:
   brackets around a single point in the record.

   Note the coupling, and why NO page currently ships the lockup: `TRANSCRIBE_BRAND_NAME`
   renames the brand TEXT on in-product surfaces (config.py:47) and does not repaint
   `static/brand/*.svg`. A page that pairs the mark with a hard-coded "Pincite" would go
   silently wrong the day that variable is set. So the pages carry the mark only as a
   favicon, and this is the reviewed shape for a lockup on a surface that is
   unambiguously ours — the certificate head below is its one live consumer. */

.brand { display: flex; align-items: center; gap: 0.7rem; }
.brand img { width: 22px; height: 22px; display: block; }
.brand-name { font-weight: 700; font-size: var(--step-0); letter-spacing: -0.02em; color: var(--ink); }

/* The brand name set INSIDE a heading — it inherits the heading's size and only gains
   weight. Distinct from .brand-name, which is the lockup's own 17px label. */
.brand-inline { font-weight: 700; letter-spacing: -0.02em; }

.brand .mark-dark { display: none; }
@media (prefers-color-scheme: dark) {
  .brand .mark-light { display: none; }
  .brand .mark-dark { display: block; }
}

.app-head {
  border-bottom: 1px solid var(--rule);
  padding: var(--space-3) 1.5rem;
}

.app-head-inner {
  max-width: var(--page);
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.app-head.wide .app-head-inner { max-width: var(--page-wide); }

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

.card {
  background-color: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius-card);
  padding: var(--space-3);
  margin: var(--space-3) 0;
  max-width: var(--measure);
}

.card p { margin-bottom: var(--space-2); }
.card p:last-child { margin-bottom: 0; }

/* The one accent-edged block: an advisory the reader must not skim past. Same shape as
   the marketing site's status callout, on purpose — the product and the page that
   describes it should not disagree about what a warning looks like. */
.callout {
  background-color: var(--surface);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius-card) var(--radius-card) 0;
  padding: var(--space-3);
  margin: var(--space-3) 0;
  max-width: var(--measure);
  font-size: 1rem;
  color: var(--ink-muted);
}

.callout strong { color: var(--ink); }
.callout p:last-child { margin-bottom: 0; }

/* `.warning` is the same shape: `oauth.py::_warning_block` emits it around a registered
   disclaimer, and the consent screen is the one place a reader must not skim. Its ink is
   full strength, not muted — a warning set in support-grey is a warning nobody read. */
.warning {
  background-color: var(--surface);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius-card) var(--radius-card) 0;
  padding: var(--space-3);
  margin: var(--space-3) 0;
  max-width: var(--measure);
  font-size: 1rem;
  color: var(--ink);
}

/* The scope line and the tier prompt: supporting text under a claim, not the claim.
   `.note` is the same weight — the connect page's standing statement about what the
   connector delivers. */
.scope,
.note { color: var(--ink-muted); font-size: 1rem; }

/* ---- machine strings -------------------------------------------------- */

.mono,
.tx-meta,
.tx-file-name,
.url {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.tx-meta { color: var(--ink-muted); font-size: var(--step-mono); }

/* Prose, not machine output — so it stays sans. A hint set in mono would read as
   something the system produced, which is the one distinction this system enforces. */
.tx-hint { color: var(--gutter); font-size: var(--step-mono); }

/* The FAILURE state on the matter pages. Deliberately NOT `.tx-hint`: it sits in the same slot as
   "No matters yet", so if the two rendered alike a reader could not tell "you have no matters" from
   "we could not load them" — which is the finding (F5), not the fix.
   Both ARE muted greys; what separates them is the accent rule and the absence of `.tx-hint`'s mono
   size — so the border is load-bearing, not decoration, and the guard asserts it. Same shape as
   `.login-error`, built only from tokens already in the contrast inventory
   (`tests/guards/test_design_tokens.py`). */
.tx-error {
  border-left: 2px solid var(--accent);
  padding-left: var(--space-2);
  color: var(--ink-muted);
}

/* The connector URL. It is the one string on that page a reader must copy exactly, so
   it is set as an artifact: mono, full width, breaking rather than truncating. */
.url {
  display: block;
  background-color: var(--code-bg);
  color: var(--ink);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius-card) var(--radius-card) 0;
  padding: 0.8rem 1rem;
  margin: var(--space-3) 0;
  font-size: var(--step-mono);
  line-height: 1.6;
  word-break: break-all;
}

/* ---- forms ------------------------------------------------------------ */

fieldset {
  border: 1px solid var(--rule);
  border-radius: var(--radius-card);
  background-color: var(--surface);
  padding: var(--space-3);
  margin: var(--space-3) 0;
  max-width: var(--measure);
}

legend { font-weight: 650; padding: 0 0.4rem; color: var(--ink); }

label { display: block; margin: 0.4rem 0; }

input[type="text"],
input[type="search"],
input[type="email"],
input[type="password"],
select {
  font: inherit;
  font-size: 1rem;
  color: var(--ink);
  background-color: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius-chip);
  padding: 0.4rem 0.6rem;
}

input:focus-visible,
select:focus-visible,
button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

button {
  font: inherit;
  font-size: 1rem;
  font-weight: 650;
  padding: 0.55rem 1.1rem;
  border-radius: var(--radius-chip);
  border: 1px solid var(--rule);
  background-color: var(--surface);
  color: var(--ink);
  cursor: pointer;
}

button:hover:not(:disabled) { border-color: var(--accent); color: var(--accent-lift); }
button:disabled { color: var(--gutter); cursor: not-allowed; }

/* The accent fills exactly one button per page — the one that commits the action. */
button.approve,
button.tx-cta {
  background-color: var(--accent);
  border-color: var(--accent);
  color: var(--bg);
}

button.approve:hover:not(:disabled),
button.tx-cta:hover:not(:disabled) {
  background-color: var(--accent-lift);
  border-color: var(--accent-lift);
  color: var(--bg);
}

button.tx-cta:disabled {
  background-color: var(--surface);
  border-color: var(--rule);
  color: var(--gutter);
}

button.deny { margin-left: 0.5rem; }

/* ---- row: a labelled control ------------------------------------------ */

.tx-row {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  margin: var(--space-2) 0;
  flex-wrap: wrap;
}

.tx-row label {
  min-width: 8rem;
  margin: 0;
  font-size: var(--step-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gutter);
}

/* ---- lists of files: the queue and the Clio pickers -------------------- */

.tx-list,
.tx-queue {
  list-style: none;
  padding: 0;
  margin: var(--space-3) 0;
  border: 1px solid var(--rule);
  border-radius: var(--radius-card);
  background-color: var(--surface);
  max-width: none;
  overflow: hidden;
}

.tx-list { max-height: 300px; overflow-y: auto; }

.tx-list li,
.tx-queue li {
  display: flex;
  gap: 0.6rem;
  align-items: center;
  padding: 0.45rem 0.75rem;
  border-bottom: 1px solid var(--rule-soft);
  font-size: var(--step-mono);
  margin: 0;
}

.tx-list li:last-child,
.tx-queue li:last-child { border-bottom: none; }

.tx-list li { cursor: pointer; }
.tx-list li:hover { background-color: var(--code-bg); }
#tx-results li { cursor: default; }
#tx-results li:hover { background-color: var(--surface); }

.tx-file-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--step-mono);
}

progress { width: 130px; }

/* Outcome is carried by a word as well as a colour: the row reads the same in
   greyscale, on paper, and to a colour-blind reader. */
.tx-status-ok { color: var(--ink-muted); font-family: var(--font-mono); font-size: var(--step-mono); }
.tx-status-err { color: var(--accent); font-weight: 650; font-family: var(--font-mono); font-size: var(--step-mono); }

/* ---- upload drop zone -------------------------------------------------- */

.tx-drop {
  border: 1px dashed var(--rule);
  border-radius: var(--radius-card);
  background-color: var(--surface);
  padding: var(--space-5) var(--space-3);
  text-align: center;
  color: var(--ink-muted);
  margin: var(--space-3) 0;
}

.tx-drop.tx-over { border-color: var(--accent); border-style: solid; color: var(--accent); }

/* ---- evidence artifacts ------------------------------------------------
   The coverage strip and the chain-of-custody certificate are the product's own
   artifacts, sharing their vocabulary with the marketing site's transcript figure.
   Kept here as the reviewed shapes; the surfaces that render them are wired
   separately. On any marketing surface the coverage figure ships BLANK — a published
   coverage number is a docs/MARKETING_SITE_SPEC.md §4 claim. */

.coverage {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0.7rem 1.25rem;
  border-top: 1px solid var(--rule);
  font-size: 0.75rem;
  color: var(--ink-muted);
}

.coverage-label { letter-spacing: 0.08em; text-transform: uppercase; }
.coverage-track { flex: 1; height: 6px; background-color: var(--code-bg); border-radius: 3px; overflow: hidden; display: block; }
.coverage-fill { display: block; height: 100%; background-color: var(--accent); }
.coverage-value { font-variant-numeric: tabular-nums; font-family: var(--font-mono); }

.cert {
  background-color: var(--surface);
  border: 1px solid var(--rule);
  border-top: 3px solid var(--accent);
  border-radius: 0 0 var(--radius-card) var(--radius-card);
  padding: var(--space-3) var(--space-3) var(--space-4);
  max-width: 44rem;
}

.cert-head {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--rule-soft);
  font-weight: 650;
  letter-spacing: -0.008em;
}

.cert-head img { width: 18px; height: 18px; display: block; }

.cert-fields {
  display: grid;
  grid-template-columns: 9.5rem 1fr;
  row-gap: 0.75rem;
  column-gap: var(--space-3);
  padding-top: var(--space-3);
  font-family: var(--font-mono);
  font-size: 0.78125rem;
  line-height: 1.55;
}

.cert-fields dt { color: var(--gutter); text-transform: uppercase; letter-spacing: 0.08em; font-size: var(--step-label); }
.cert-fields dd { margin: 0; word-break: break-all; }
.cert-fields dd.num { font-variant-numeric: tabular-nums; word-break: normal; }

/* ---- small screens ----------------------------------------------------- */

@media (max-width: 40rem) {
  .tx-row label { min-width: 0; flex-basis: 100%; }
  .cert-fields { grid-template-columns: 1fr; row-gap: 0.35rem; }
  .cert-fields dd { margin-bottom: 0.5rem; }
}

@media (max-width: 30rem) {
  main { padding-left: 1.25rem; padding-right: 1.25rem; }
  .app-head { padding-left: 1.25rem; padding-right: 1.25rem; }
}

/* ---- print -------------------------------------------------------------- */

@media print {
  body { font-size: 11pt; line-height: 1.45; }
  main { max-width: none; padding: 0; }
  button, .tx-drop, .coverage-track { display: none; }
  .card, .callout, .cert { break-inside: avoid; }
  h1, h2, h3 { break-after: avoid; }
}

/* ---- index rows ----------------------------------------------------------
   The nav itself now lives in shell.css, shared with the transcript surfaces that
   cannot link this file. */

/* An index row: name first, machine facts trailing. `.tx-list li` supplies the
   hairline rule and the flex row; these only govern what sits inside it. */
.tx-list li > .tx-meta { flex: 0 0 auto; }
.tx-list li > .coverage { flex: 0 0 auto; padding: 0; border-top: none; min-width: 9rem; }

/* A quarantined recording. The row states that the recording exists and carries
   nothing else — no filename, no coverage, no link. It is set in the accent so it
   reads as a disclosure rather than as a row someone forgot to fill in. */
.tx-privileged-row {
  color: var(--accent);
  font-weight: 650;
}

.tx-privileged-row .tx-file-name { font-family: var(--font-sans); }
/* ---- login (templates/login.html) ------------------------------------ */
/* The one credential surface. Tokens only — test_design_tokens.py forbids a colour literal
   anywhere in this file outside a :root declaration. */

main.login-card {
  max-width: var(--measure);
}

.login-card form {
  margin-top: var(--space-3);
}

.login-card input {
  width: 100%;
}

.login-card button {
  margin-top: var(--space-3);
}

.login-notice,
.login-error {
  border-left: 2px solid var(--accent);
  padding-left: var(--space-2);
  color: var(--ink-muted);
}
