/*
 * The officer console's one stylesheet.
 *
 * Every page here ends in two people doing something irreversible to a real customer's account:
 * a maker acts, a checker countersigns, and the record keeps both names. So the dual-signature
 * block is the one loud thing on the page — a tinted counterfoil, ruled down the middle, the way
 * the paper slip it replaces was signed twice. Everything else stays quiet and dense, because an
 * officer works down these forms all day on a 1366-wide branch machine.
 *
 * Irreversible verbs (freeze, reject) are the only things wearing brick. Nothing decorative is
 * allowed that colour, so it never has to compete for meaning.
 *
 * No web fonts: this runs on a bank intranet behind a strict content policy, where a fetch to a
 * font CDN is a page that renders in Times while somebody is mid-vouch.
 */

:root {
    --ink: #14202a;
    --ink-soft: #4a5b68;
    --paper: #ffffff;
    --field: #f3f6f8;
    --rule: #cbd5dc;
    --primary: #10527c;
    --primary-dark: #0c3f60;
    --consequence: #8a2b1c;
    --consequence-dark: #6d2115;
    --affirm: #1f6b4a;
    --shell: #eef2f5;

    --step: 0.5rem;
    --radius: 3px;
}

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

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

body {
    margin: 0;
    background: var(--shell);
    color: var(--ink);
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    font-size: 15px;
    line-height: 1.5;
}

/* Numbers an officer reads back to a customer down the phone: client ids, dates, amounts. */
td, th, .tabular, input, select { font-variant-numeric: tabular-nums; }

/* ── The bar: who you are, and which system you are about to change ─────────────── */

.bar {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: calc(var(--step) * 2);
    padding: calc(var(--step) * 1.5) calc(var(--step) * 3);
    background: var(--ink);
    color: #dce6ed;
}

.bar__mark {
    font-weight: 600;
    letter-spacing: 0.01em;
    color: #ffffff;
}

.bar__who { margin-left: auto; color: #b7c7d3; }

.bar__who span { color: #ffffff; }

.bar a { color: #cfe0ec; }

.bar form { margin: 0; }

.bar button {
    background: none;
    border: 1px solid #3c5062;
    color: #dce6ed;
    padding: 4px 10px;
    border-radius: var(--radius);
    font: inherit;
    cursor: pointer;
}

.bar button:hover { border-color: #7d95a7; color: #ffffff; }

/* ── Page frame ─────────────────────────────────────────────────────────────────── */

.page {
    max-width: 1100px;
    margin: 0 auto;
    padding: calc(var(--step) * 4) calc(var(--step) * 3) calc(var(--step) * 8);
}

.page--narrow { max-width: 30rem; }

h1 {
    font-size: 1.6rem;
    line-height: 1.25;
    margin: 0 0 calc(var(--step) * 2);
    letter-spacing: -0.01em;
}

h2 {
    font-size: 1.05rem;
    margin: 0 0 calc(var(--step) * 2);
}

p { margin: 0 0 calc(var(--step) * 2); max-width: 66ch; }

.note { color: var(--ink-soft); }

/* A warning an officer must read before acting, not a decorative callout. */
.warning {
    border-left: 3px solid var(--consequence);
    background: #fbf3f1;
    padding: calc(var(--step) * 1.5) calc(var(--step) * 2);
    max-width: 66ch;
}

/* ── Panels: steps of one task, separated by rule and space rather than cards ───── */

.panel {
    background: var(--paper);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    padding: calc(var(--step) * 3);
    margin-bottom: calc(var(--step) * 3);
}

.panel > h2 {
    padding-bottom: var(--step);
    border-bottom: 1px solid var(--rule);
}

/* ── Fields ─────────────────────────────────────────────────────────────────────── */

label {
    display: block;
    margin-bottom: calc(var(--step) * 2);
    color: var(--ink-soft);
}

input[type="text"], input[type="password"], input:not([type]), select {
    display: block;
    width: 100%;
    max-width: 22rem;
    margin-top: 4px;
    padding: 9px 10px;
    background: var(--field);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    color: var(--ink);
    font: inherit;
}

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

input[type="checkbox"] { margin-right: 6px; accent-color: var(--primary); }

label:has(> input[type="checkbox"]) { color: var(--ink); margin-bottom: var(--step); }

fieldset {
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    padding: calc(var(--step) * 2);
    margin: 0 0 calc(var(--step) * 3);
    max-width: 34rem;
}

legend { color: var(--ink-soft); padding: 0 6px; }

.row {
    display: flex;
    flex-wrap: wrap;
    gap: calc(var(--step) * 3);
}

.row > label { flex: 1 1 14rem; }

/* ── The dual signature: the one loud thing here ────────────────────────────────── */

.countersign {
    border: 1px solid #b9c9d4;
    border-top: 3px solid var(--primary);
    border-radius: var(--radius);
    background: #f7fafc;
    padding: calc(var(--step) * 3);
    margin-bottom: calc(var(--step) * 3);
}

.countersign > h2 { border: 0; padding: 0; }

.countersign__pair {
    display: grid;
    grid-template-columns: 1fr 1px 1fr;
    gap: calc(var(--step) * 3);
    align-items: start;
}

.countersign__rule { background: var(--rule); align-self: stretch; }

.countersign__role {
    font-weight: 600;
    color: var(--ink);
    margin-bottom: var(--step);
}

.countersign__hint {
    color: var(--ink-soft);
    margin: 0 0 calc(var(--step) * 2);
    max-width: 60ch;
}

@media (max-width: 40rem) {
    .countersign__pair { grid-template-columns: 1fr; }
    .countersign__rule { height: 1px; }
}

/* ── Buttons ────────────────────────────────────────────────────────────────────── */

button {
    font: inherit;
    padding: 9px 16px;
    border-radius: var(--radius);
    border: 1px solid var(--rule);
    background: var(--paper);
    color: var(--ink);
    cursor: pointer;
}

button:hover { border-color: #9fb0bc; }

button.primary {
    background: var(--primary);
    border-color: var(--primary);
    color: #ffffff;
    font-weight: 600;
}

button.primary:hover { background: var(--primary-dark); border-color: var(--primary-dark); }

/* Freeze and reject: an act with no undo from here. */
button.consequence {
    background: var(--consequence);
    border-color: var(--consequence);
    color: #ffffff;
    font-weight: 600;
}

button.consequence:hover { background: var(--consequence-dark); border-color: var(--consequence-dark); }

/* ── Navigation from the home page ──────────────────────────────────────────────── */

.tasks { display: grid; gap: 1px; background: var(--rule); border: 1px solid var(--rule); border-radius: var(--radius); }

.tasks a {
    display: block;
    padding: calc(var(--step) * 2) calc(var(--step) * 3);
    background: var(--paper);
    color: var(--primary);
    text-decoration: none;
    font-weight: 600;
}

.tasks a:hover { background: #f0f5f9; text-decoration: underline; }

/* ── Tables ─────────────────────────────────────────────────────────────────────── */

table { border-collapse: collapse; width: 100%; background: var(--paper); }

th, td {
    text-align: left;
    padding: 10px 12px;
    border-bottom: 1px solid var(--rule);
    vertical-align: top;
}

thead th {
    border-bottom: 2px solid var(--ink);
    font-size: 0.85rem;
    color: var(--ink-soft);
    font-weight: 600;
}

tbody tr:hover { background: #f5f9fb; }

/* ── Results and lists the pages fill in with script ────────────────────────────── */

#sessions, #queue { list-style: none; margin: 0; padding: 0; }

#sessions li, #queue li {
    padding: calc(var(--step) * 1.5) 0;
    border-bottom: 1px solid var(--rule);
}

#vouchResult, #freezeResult, #rulingResult, #reviewResult {
    margin-top: calc(var(--step) * 2);
    color: var(--ink-soft);
}

/*
 * Where the challenge is shown. No surround of its own: a QR needs a white quiet zone to scan,
 * so the code's own white card is the frame, sitting left with the rest of the form rather than
 * centred in a band of colour.
 */
#screen {
    margin: calc(var(--step) * 2) 0;
    display: flex;
    justify-content: flex-start;
}

#screen:empty { display: none; }

/*
 * The challenge itself. Big enough to scan across a counter from a customer's own phone, capped
 * so it does not swallow the page on a wide branch monitor — and on white, always, because a
 * scanner needs the quiet zone around it whatever the surrounding chrome is doing.
 */
#screen canvas, #screen img, #screen svg, #screen table {
    width: 15rem;
    height: auto;
    background: #ffffff;
    padding: calc(var(--step) * 1.5);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
}

#state { color: var(--ink-soft); }

/* ── A remote submission's captures ─────────────────────────────────────────────── */

/*
 * The only page here whose work is looking rather than typing: nobody has met this customer, and
 * the ruling rests on holding a photograph of an ID against a photograph of a face.
 *
 * So the captures are laid out as one set — a grid, every tile the same size — rather than at
 * whatever size each phone produced. Natural size made an ID and a selfie two unrelated objects
 * a screen apart, which is a comparison done from memory between scrolls.
 */
#media {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
    gap: calc(var(--step) * 3);
    margin: calc(var(--step) * 2) 0;
}

#media:empty { display: none; }

#media figure { margin: 0; }

/*
 * The code, beside its own capture. An officer checks it against the one printed in the
 * photograph itself, so it is a label on that tile and not a note somewhere above the set.
 */
#media figcaption {
    font-size: 0.85rem;
    color: var(--ink-soft);
    margin-bottom: var(--step);
}

#media .capture {
    display: block;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    /* Light, not dark. These arrive underexposed often enough that a dark surround would let an
       ID merge into its own frame. */
    background: var(--field);
}

#media .capture:hover, #media .capture:focus-visible {
    border-color: var(--primary);
}

/*
 * Uniform tiles, contained rather than cropped: a cropped ID can lose the very corner the officer
 * is reading, and a cropped face is not the face.
 */
#media img, #media video {
    display: block;
    width: 100%;
    height: 11rem;
    object-fit: contain;
}

/* The video is the one capture with a duration, and it is watched rather than compared. */
#media figure:has(video) {
    grid-column: 1 / -1;
}

#media video {
    height: auto;
    max-height: 22rem;
    background: #000000;
}

/* ── Sign-in ────────────────────────────────────────────────────────────────────── */

.signin {
    background: var(--paper);
    border: 1px solid var(--rule);
    border-top: 3px solid var(--primary);
    border-radius: var(--radius);
    padding: calc(var(--step) * 4);
    margin-top: calc(var(--step) * 8);
}

.signin h1 { font-size: 1.35rem; }

.signin button { width: 100%; margin-top: var(--step); }

.signin input { max-width: none; }

#sign-in-error {
    border-left: 3px solid var(--consequence);
    background: #fbf3f1;
    padding: var(--step) calc(var(--step) * 1.5);
    color: var(--consequence-dark);
}

a { color: var(--primary); }

@media (prefers-reduced-motion: reduce) {
    * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}
