/* filesReviewr
 *
 * The visual language is document control, not dashboard: bond paper, archival
 * ink, hairline rules, and a rubber stamp for the verdict. That is the world
 * this tool actually lives in — plan checks, invoice sign-offs, copy desks —
 * and it gives the interface a vocabulary that a generic admin panel does not
 * have.
 *
 * The boldness is spent in exactly one place: .stamp, in the detail drawer.
 * Everything around it is deliberately quiet so that landing a verdict reads as
 * an event. In the list, status is only a 3px ink rule down the left edge of a
 * row — scanning the column tells you the state of the whole queue without a
 * single badge shouting.
 */

/* ── Tokens ───────────────────────────────────────────────────────────────── */

:root {
    /* Cool bond paper under office light — not the warm cream that every
       document-flavoured design reaches for. */
    --paper:        #F4F6FA;
    --paper-raised: #FFFFFF;
    --paper-sunken: #E7ECF3;

    --ink:       #141A24;   /* blue-black, the colour of archival ink */
    --ink-soft:  #4E5969;
    --ink-faint: #8792A4;

    --rule:        #D6DCE6;
    --rule-strong: #BAC3D0;

    --accent:      #2F4C86;
    --accent-wash: #E5EBF7;

    /* Stamp-pad inks. Muted, because a real stamp pad is never neon. */
    --st-pending:  #8F6410;
    --st-approved: #1B7048;
    --st-changes:  #A34A08;
    --st-rejected: #A61F19;

    --st-pending-wash:  #F6EBD4;
    --st-approved-wash: #DDF0E6;
    --st-changes-wash:  #FAE7D8;
    --st-rejected-wash: #F8E1DF;

    --font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;

    --shadow-drawer: -24px 0 60px rgba(20, 26, 36, .16);
    --shadow-lift: 0 1px 2px rgba(20, 26, 36, .06), 0 8px 24px rgba(20, 26, 36, .06);

    --drawer-w: min(680px, 100vw);
}

@media (prefers-color-scheme: dark) {
    :root {
        --paper:        #0D1219;
        --paper-raised: #151C26;
        --paper-sunken: #090D13;

        --ink:       #E3E9F1;
        --ink-soft:  #97A3B5;
        --ink-faint: #6A7688;

        --rule:        #242E3C;
        --rule-strong: #35414F;

        --accent:      #7FA3E8;
        --accent-wash: #1A2436;

        --st-pending:  #D5A034;
        --st-approved: #48B685;
        --st-changes:  #E08040;
        --st-rejected: #E4695F;

        --st-pending-wash:  #2A2313;
        --st-approved-wash: #10281F;
        --st-changes-wash:  #2B1C11;
        --st-rejected-wash: #2C1614;

        --shadow-drawer: -24px 0 60px rgba(0, 0, 0, .55);
        --shadow-lift: 0 1px 2px rgba(0, 0, 0, .4), 0 8px 24px rgba(0, 0, 0, .3);
    }
}

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

/* The `hidden` attribute is only a UA rule of `display: none`, so ANY class that
   sets display — .drawer is display:flex, .empty is a block — outranks it and
   the element stays on screen. Everything in this app that toggles visibility
   does it with .hidden, so this rule has to win outright. */
[hidden] { display: none !important; }

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

body {
    margin: 0;
    background: var(--paper);
    color: var(--ink);
    font-family: var(--font-ui);
    font-size: 15px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

/* The one type device carried everywhere: letterspaced uppercase micro-labels,
   the register of a form field on official paperwork. */
.label {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin: 0;
}

.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 2px;
}

/* ── Masthead ─────────────────────────────────────────────────────────────── */

.masthead {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 0 24px;
    height: 56px;
    background: var(--paper-raised);
    border-bottom: 1px solid var(--rule);
}

.mark {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    text-decoration: none;
    color: inherit;
}

/* A stamp impression, reduced to its outline. */
.mark__box {
    width: 15px; height: 15px;
    border: 2px solid var(--accent);
    border-radius: 2px;
    transform: rotate(-8deg);
}

.mark__word { font-weight: 650; letter-spacing: -.012em; }

.masthead__right { display: flex; align-items: center; gap: 18px; }

.whoami { display: flex; align-items: baseline; gap: 8px; }
.whoami__name { font-weight: 550; }
.whoami__role { color: var(--ink-faint); }

.linkbtn {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    color: var(--ink-soft);
    cursor: pointer;
    text-decoration: underline;
    text-decoration-color: var(--rule-strong);
    text-underline-offset: 3px;
}
.linkbtn:hover { color: var(--accent); text-decoration-color: currentColor; }
.linkbtn--strong { color: var(--accent); font-weight: 550; }

.iconbtn {
    background: none;
    border: 0;
    font-size: 26px;
    line-height: 1;
    color: var(--ink-faint);
    cursor: pointer;
    padding: 4px 8px;
}
.iconbtn:hover { color: var(--ink); }

/* ── Sheet ────────────────────────────────────────────────────────────────── */

.sheet {
    max-width: 1100px;
    margin: 0 auto;
    padding: 28px 24px 72px;
}

/* ── Queue rule ───────────────────────────────────────────────────────────── */
/* Proportion is the point. Four stat boxes would report the same numbers while
   hiding the only thing a reviewer wants to know: how much of this is unread. */

.queue { margin-bottom: 26px; }
.queue > .label { margin-bottom: 8px; }

.queue__bar {
    display: flex;
    height: 10px;
    border-radius: 2px;
    overflow: hidden;
    background: var(--paper-sunken);
    border: 1px solid var(--rule);
}

.qseg {
    border: 0;
    padding: 0;
    cursor: pointer;
    transition: flex-grow .45s cubic-bezier(.2, .7, .3, 1), opacity .15s;
    min-width: 2px;
}
.qseg:hover { opacity: .75; }
.qseg--pending   { background: var(--st-pending); }
.qseg--approved  { background: var(--st-approved); }
.qseg--needs_changes { background: var(--st-changes); }
.qseg--rejected  { background: var(--st-rejected); }

.queue__legend {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 20px;
    margin-top: 12px;
}

.qleg {
    display: flex;
    align-items: baseline;
    gap: 7px;
    background: none;
    border: 0;
    padding: 3px 0;
    font: inherit;
    color: var(--ink-soft);
    cursor: pointer;
    border-bottom: 2px solid transparent;
}
.qleg:hover { color: var(--ink); }
.qleg[aria-pressed="true"] { color: var(--ink); border-bottom-color: currentColor; }
.qleg__n { font-family: var(--font-mono); font-weight: 650; font-size: 16px; color: var(--ink); }
.qleg__tick { width: 8px; height: 8px; border-radius: 1px; }

/* ── Intake ───────────────────────────────────────────────────────────────── */

.intake {
    position: relative;
    border: 1px dashed var(--rule-strong);
    border-radius: 4px;
    background: var(--paper-raised);
    padding: 17px 24px;
    text-align: center;
    transition: border-color .12s, background .12s;
    margin-bottom: 26px;
}
.intake.is-hot {
    border-color: var(--accent);
    border-style: solid;
    background: var(--accent-wash);
}

.intake__lead { margin: 0; font-size: 15px; font-weight: 550; }
.intake__sub { margin: 5px 0 0; color: var(--ink-faint); font-size: 13px; }
.intake__limit { margin-left: 10px; font-family: var(--font-mono); font-size: 12px; }

/* :not(:empty) so an idle dropzone does not carry the progress list's margin as
   dead space under the prompt. */
.intake__progress { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.intake__progress:not(:empty) { margin-top: 16px; }

.uprow { display: grid; grid-template-columns: 1fr auto; gap: 4px 12px; text-align: left; }
.uprow__name { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.uprow__pct { font-family: var(--font-mono); font-size: 12px; color: var(--ink-faint); }
.uprow__track { grid-column: 1 / -1; height: 3px; background: var(--paper-sunken); border-radius: 2px; overflow: hidden; }
.uprow__fill { height: 100%; background: var(--accent); width: 0; transition: width .18s linear; }
.uprow--failed .uprow__fill { background: var(--st-rejected); }
.uprow--failed .uprow__pct { color: var(--st-rejected); }

/* ── Controls ─────────────────────────────────────────────────────────────── */

.controls {
    display: flex;
    align-items: flex-end;
    gap: 20px;
    margin-bottom: 14px;
}

.field { display: grid; gap: 5px; }
.field > .label { margin: 0; }

/* Matched by exclusion rather than by listing types. `input[type="text"]` does
   NOT match `<input id="x">` — an input with no type attribute defaults to text
   behaviourally but has no attribute for the selector to match, so it kept the
   browser's white default and stood out in dark mode. */
input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
select, textarea {
    font: inherit;
    color: var(--ink);
    background: var(--paper-raised);
    border: 1px solid var(--rule-strong);
    border-radius: 3px;
    padding: 7px 10px;
    min-width: 240px;
}
textarea { width: 100%; resize: vertical; min-height: 68px; font-size: 14px; }
input:focus, select:focus, textarea:focus { border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px var(--accent-wash); }

.toggle { display: inline-flex; align-items: center; gap: 7px; font-size: 14px; color: var(--ink-soft); cursor: pointer; padding-bottom: 7px; }
.controls__count { margin-left: auto; padding-bottom: 9px; }

/* ── Ledger ───────────────────────────────────────────────────────────────── */

.ledger {
    background: var(--paper-raised);
    border: 1px solid var(--rule);
    border-radius: 4px;
    overflow: hidden;
}

.ledger__head,
.frow {
    display: grid;
    grid-template-columns: 3px 44px minmax(0, 1fr) 130px 84px 92px 72px;
    align-items: center;
    gap: 14px;
}

.ledger__head {
    padding: 9px 18px 9px 0;
    border-bottom: 1px solid var(--rule);
    background: var(--paper-sunken);
}
.ledger__h {
    font-size: 10px; font-weight: 700; letter-spacing: .14em;
    text-transform: uppercase; color: var(--ink-faint);
}
/* The head has no thumbnail or ink-rule cell of its own, so its first label
   starts in the third column, above the filename. */
.ledger__h--file { grid-column: 3; }
.ledger__h--num { text-align: right; }

.ledger__rows { list-style: none; margin: 0; padding: 0; }

.frow {
    width: 100%;
    padding: 0 18px 0 0;
    border: 0;
    border-bottom: 1px solid var(--rule);
    background: none;
    font: inherit;
    /* An <a>, so a queue can be worked through in background tabs with
       cmd-click. Both resets are for that: links come with their own colour and
       underline. */
    color: inherit;
    text-decoration: none;
    text-align: left;
    cursor: pointer;
    min-height: 58px;
}
/* The button is wrapped in an <li>, so :last-child on .frow would always match.
   The last ROW is what should lose its rule. */
.ledger__rows > li:last-child .frow { border-bottom: 0; }
.frow:hover { background: var(--paper-sunken); }
.frow[aria-current="true"] { background: var(--accent-wash); }

/* The status signal: an ink rule down the row's leading edge. Reading the
   column vertically gives the shape of the queue with no badges at all. */
.frow__ink { height: 100%; min-height: 58px; align-self: stretch; }
.frow--pending       .frow__ink { background: var(--st-pending); }
.frow--approved      .frow__ink { background: var(--st-approved); }
.frow--needs_changes .frow__ink { background: var(--st-changes); }
.frow--rejected      .frow__ink { background: var(--st-rejected); }

.frow__thumb {
    width: 40px; height: 40px;
    border-radius: 2px;
    border: 1px solid var(--rule);
    background: var(--paper-sunken) center/cover no-repeat;
    display: grid; place-items: center;
    font-family: var(--font-mono);
    font-size: 9px; font-weight: 700;
    color: var(--ink-faint);
    overflow: hidden;
}

.frow__main { min-width: 0; }
.frow__name {
    display: block;
    font-weight: 550;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.frow__status {
    font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
}
.frow--pending       .frow__status { color: var(--st-pending); }
.frow--approved      .frow__status { color: var(--st-approved); }
.frow--needs_changes .frow__status { color: var(--st-changes); }
.frow--rejected      .frow__status { color: var(--st-rejected); }

/* Sits inside .frow__status, which is uppercase and letterspaced. This is prose,
   not a status token, so it opts back out of both. */
.frow__dupe {
    color: var(--ink-faint);
    font-size: 11px;
    margin-left: 8px;
    text-transform: none;
    letter-spacing: 0;
    font-weight: 400;
}

.frow__who { font-size: 13px; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.frow__num { font-family: var(--font-mono); font-size: 12px; color: var(--ink-soft); text-align: right; font-variant-numeric: tabular-nums; }
.frow__remarks { text-align: right; font-family: var(--font-mono); font-size: 12px; }
.frow__remarks[data-has="true"] { color: var(--ink); font-weight: 650; }
.frow__remarks[data-has="false"] { color: var(--ink-faint); }

.empty { padding: 56px 24px; text-align: center; color: var(--ink-faint); }
.empty strong { display: block; color: var(--ink); font-size: 16px; margin-bottom: 6px; font-weight: 550; }

.pager { display: flex; align-items: center; justify-content: center; gap: 14px; margin-top: 18px; }
.pager__at { font-family: var(--font-mono); font-size: 12px; color: var(--ink-faint); }

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

.btn {
    font: inherit;
    font-size: 14px;
    font-weight: 550;
    padding: 8px 15px;
    border-radius: 3px;
    border: 1px solid var(--accent);
    background: var(--accent);
    color: #fff;
    cursor: pointer;
    text-decoration: none;
    display: inline-block;
}
.btn:hover { filter: brightness(1.08); }
.btn:disabled { opacity: .5; cursor: default; filter: none; }

.btn--quiet { background: var(--paper-raised); color: var(--ink); border-color: var(--rule-strong); }
.btn--quiet:hover { border-color: var(--ink-faint); filter: none; }

.btn--danger { background: none; color: var(--st-rejected); border-color: currentColor; }
.btn--danger:hover { background: var(--st-rejected-wash); filter: none; }

/* ── Drawer ───────────────────────────────────────────────────────────────── */

.scrim {
    position: fixed; inset: 0; z-index: 30;
    background: rgba(20, 26, 36, .38);
    backdrop-filter: blur(1.5px);
    animation: fade .16s ease-out;
}
@keyframes fade { from { opacity: 0; } }

.drawer {
    position: fixed;
    top: 0; right: 0; bottom: 0;
    z-index: 31;
    width: var(--drawer-w);
    display: flex;
    flex-direction: column;
    background: var(--paper-raised);
    border-left: 1px solid var(--rule);
    box-shadow: var(--shadow-drawer);
    animation: slide .22s cubic-bezier(.2, .8, .3, 1);
}
@keyframes slide { from { transform: translateX(24px); opacity: .4; } }

.drawer__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    padding: 18px 20px 16px;
    border-bottom: 1px solid var(--rule);
}
.drawer__title { min-width: 0; }
.drawer__title h2 {
    margin: 4px 0 0;
    font-size: 19px;
    font-weight: 600;
    letter-spacing: -.015em;
    overflow-wrap: anywhere;
}
.drawer__scroll { overflow-y: auto; padding: 20px; display: grid; gap: 26px; align-content: start; }

/* ── Review page ──────────────────────────────────────────────────────────── */
/* Two columns filling the viewport: the document gets the room, and everything
   said about it rides alongside. Each column scrolls independently, so reading
   the thread never scrolls the page you are looking at out of view. */

.body--review { overflow: hidden; }

.review {
    height: calc(100vh - 56px);      /* the masthead */
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
}

.reviewbar {
    display: flex;
    align-items: center;
    gap: 22px;
    padding: 11px 24px;
    background: var(--paper-raised);
    border-bottom: 1px solid var(--rule);
}

.backlink {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    color: var(--ink-soft);
    text-decoration: none;
    font-size: 13px;
    white-space: nowrap;
}
.backlink:hover { color: var(--accent); }

.reviewbar__id { flex: 1; min-width: 0; }
.reviewbar__id h1 {
    margin: 0;
    font-size: 17px;
    font-weight: 600;
    letter-spacing: -.015em;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.reviewbar__meta { margin: 2px 0 0; font-size: 11.5px; color: var(--ink-faint); }
.reviewbar__actions { display: flex; gap: 10px; flex-shrink: 0; }

/* minmax(0, 1fr) rather than 1fr: a bare 1fr track floors at min-content, so a
   wide PDF would push the rail off-screen instead of scrolling inside its own
   column. */
.review__body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 420px;
    min-height: 0;
}

.review__doc {
    position: relative;
    display: flex;
    min-height: 0;
    overflow: hidden;
    background: var(--paper-sunken);
}

.review__stage {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 0;
    overflow: auto;
}

/* A PDF gets the frame edge to edge — it brings its own toolbar and margins.
   An image is a picture on a wall and wants a mount around it. */
.doc--pdf { width: 100%; height: 100%; border: 0; background: #fff; }
.doc--img {
    max-width: calc(100% - 56px);
    max-height: calc(100% - 56px);
    object-fit: contain;
    display: block;
    box-shadow: var(--shadow-lift);
}

.review__rail {
    border-left: 1px solid var(--rule);
    background: var(--paper-raised);
    overflow-y: auto;
    min-height: 0;
    padding: 22px 22px 44px;
    display: grid;
    gap: 26px;
    align-content: start;
}

.review__missing {
    min-height: 70vh;
    display: grid;
    place-content: center;
    justify-items: center;
    gap: 11px;
    text-align: center;
    padding: 40px;
}
.review__missing strong { font-size: 18px; font-weight: 600; }
.review__missing span { color: var(--ink-faint); max-width: 42ch; }
.review__missing .btn { margin-top: 10px; }

.noview { padding: 44px 20px; text-align: center; }
.noview__badge {
    display: inline-grid; place-items: center;
    width: 62px; height: 62px;
    border: 1px solid var(--rule-strong);
    border-radius: 3px;
    background: var(--paper-raised);
    font-family: var(--font-mono);
    font-size: 12px; font-weight: 700;
    color: var(--ink-soft);
    margin-bottom: 12px;
}
.noview p { margin: 0; color: var(--ink-faint); font-size: 13px; }

/* THE signature element. A verdict is a physical act in this domain, so it
   reads as one: double-ruled, letterspaced, rotated off-axis, sitting on top of
   the document rather than beside it. */
/* Bottom-right, not top-right: the PDF viewer puts its own toolbar across the
   top, and a stamp landing there covers the download and print buttons and
   reads as browser chrome instead of a mark on the document. */
.stamp {
    position: absolute;
    bottom: 24px; right: 26px;
    z-index: 2;
    padding: 9px 19px;
    border: 3px double currentColor;
    border-radius: 3px;
    font-size: 16px;
    font-weight: 800;
    letter-spacing: .16em;
    text-transform: uppercase;
    transform: rotate(-7deg);
    opacity: .9;
    pointer-events: none;
    background: color-mix(in srgb, var(--paper-raised) 72%, transparent);
}
.stamp--pending       { color: var(--st-pending); }
.stamp--approved      { color: var(--st-approved); }
.stamp--needs_changes { color: var(--st-changes); }
.stamp--rejected      { color: var(--st-rejected); }

/* The press: down fast, settle slow, like a stamp hitting paper. */
.stamp.is-fresh { animation: press .34s cubic-bezier(.2, 1.5, .4, 1); }
@keyframes press {
    0%   { transform: rotate(-14deg) scale(1.7); opacity: 0; }
    55%  { transform: rotate(-5deg)  scale(.94); opacity: 1; }
    100% { transform: rotate(-7deg)  scale(1); }
}

/* A 2×2 grid rather than a wrapping row. Four buttons will not fit across a
   420px rail, and letting them break 3-then-1 looks like an accident. */
.verdict__row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
    margin-top: 9px;
}

.vbtn {
    font: inherit;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    padding: 7px 12px;
    border-radius: 3px;
    border: 1px solid var(--rule-strong);
    background: var(--paper-raised);
    color: var(--ink-soft);
    cursor: pointer;
}
.vbtn:hover { border-color: currentColor; }
.vbtn[aria-pressed="true"] { border-color: currentColor; }
.vbtn--pending[aria-pressed="true"]       { color: var(--st-pending);  background: var(--st-pending-wash); }
.vbtn--approved[aria-pressed="true"]      { color: var(--st-approved); background: var(--st-approved-wash); }
.vbtn--needs_changes[aria-pressed="true"] { color: var(--st-changes);  background: var(--st-changes-wash); }
.vbtn--rejected[aria-pressed="true"]      { color: var(--st-rejected); background: var(--st-rejected-wash); }

/* ── Thread ───────────────────────────────────────────────────────────────── */

.thread__list { list-style: none; margin: 10px 0 16px; padding: 0; display: grid; gap: 2px; }

.remark {
    display: grid;
    gap: 3px;
    padding: 11px 0 12px 14px;
    border-left: 2px solid var(--rule);
}
.remark:hover { border-left-color: var(--rule-strong); }
.remark__head { display: flex; align-items: baseline; gap: 9px; }
.remark__who { font-weight: 600; font-size: 13px; }
.remark__when { font-family: var(--font-mono); font-size: 11px; color: var(--ink-faint); }
.remark__body { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; font-size: 14px; }
.remark__del {
    background: none; border: 0; padding: 0; cursor: pointer;
    font-size: 11px; color: var(--ink-faint); margin-left: auto; text-decoration: underline;
}
.remark__del:hover { color: var(--st-rejected); }

.thread__none { color: var(--ink-faint); font-size: 13px; margin: 10px 0 16px; }

.composer { display: grid; gap: 8px; }
.composer__foot { display: flex; align-items: center; justify-content: space-between; }
.composer__count { font-size: 11px; color: var(--ink-faint); }

/* ── History ──────────────────────────────────────────────────────────────── */

.history__list { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 9px; }
.hev { display: grid; grid-template-columns: 7px 1fr; gap: 10px; align-items: start; font-size: 13px; }
.hev__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--rule-strong); margin-top: 6px; }
.hev--status_changed .hev__dot { background: var(--accent); }
.hev--deleted .hev__dot { background: var(--st-rejected); }
.hev__text { color: var(--ink-soft); }
.hev__text b { color: var(--ink); font-weight: 600; }
.hev__when { font-family: var(--font-mono); font-size: 11px; color: var(--ink-faint); }

/* ── Users ────────────────────────────────────────────────────────────────── */

.newuser { display: grid; gap: 12px; justify-items: start; }
.newuser__grid { display: grid; gap: 12px; width: 100%; }
.newuser__grid .field { width: 100%; }
.newuser__grid input, .newuser__grid select { width: 100%; min-width: 0; }

.userlist { list-style: none; margin: 26px 0 0; padding: 22px 0 0; border-top: 1px solid var(--rule); display: grid; gap: 2px; }

.urow { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 6px 14px; align-items: center; padding: 11px 0; border-bottom: 1px solid var(--rule); }
.urow:last-child { border-bottom: 0; }
.urow__name { font-weight: 550; }
.urow__meta { font-family: var(--font-mono); font-size: 11px; color: var(--ink-faint); }
.urow__controls { display: flex; align-items: center; gap: 8px; }
.urow__controls select { min-width: 0; padding: 4px 7px; font-size: 12px; }
.urow--off .urow__name { color: var(--ink-faint); text-decoration: line-through; }

/* ── Toasts ───────────────────────────────────────────────────────────────── */

.toaster { position: fixed; bottom: 20px; left: 20px; z-index: 60; display: grid; gap: 8px; max-width: 400px; }

.toast {
    padding: 11px 15px;
    border-radius: 3px;
    border: 1px solid var(--rule-strong);
    border-left-width: 3px;
    background: var(--paper-raised);
    box-shadow: var(--shadow-lift);
    font-size: 14px;
    animation: rise .18s ease-out;
}
@keyframes rise { from { transform: translateY(8px); opacity: 0; } }
.toast--error { border-left-color: var(--st-rejected); }
.toast--ok    { border-left-color: var(--st-approved); }
.toast--info  { border-left-color: var(--accent); }

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

.signin { min-height: 100vh; display: grid; place-items: center; padding: 24px; }

.signin__card {
    width: 100%;
    max-width: 370px;
    background: var(--paper-raised);
    border: 1px solid var(--rule);
    border-radius: 4px;
    padding: 32px;
    box-shadow: var(--shadow-lift);
}
.signin__mark { display: flex; align-items: center; gap: 10px; margin-bottom: 26px; }
.signin__mark .mark__word { font-size: 17px; }
.signin__form { display: grid; gap: 15px; }
.signin__form .field { width: 100%; }
.signin__form input { width: 100%; min-width: 0; }
.signin__form .btn { width: 100%; padding: 10px; }
.signin__error { margin: 0; color: var(--st-rejected); font-size: 13px; min-height: 19px; }

/* ── Responsive ───────────────────────────────────────────────────────────── */

/* Below this the two columns stop fitting side by side: the document would be
   too narrow to read and the rail too narrow to write in. Stack them, and let
   the page scroll normally instead of each column scrolling itself. */
@media (max-width: 900px) {
    .body--review { overflow: auto; }
    .review { height: auto; }
    .review__body { grid-template-columns: 1fr; }
    .review__doc { height: 58vh; }
    .review__rail {
        border-left: 0;
        border-top: 1px solid var(--rule);
        overflow: visible;
        padding: 20px 16px 44px;
    }
    .reviewbar { flex-wrap: wrap; gap: 10px 18px; padding: 11px 16px; }
    /* The filename drops to its own line; the back link and the actions share
       the one above, pushed to opposite edges rather than bunched together. */
    .reviewbar__id { flex-basis: 100%; order: 3; }
    .reviewbar__actions { margin-left: auto; }
    .doc--img { max-width: calc(100% - 28px); max-height: calc(100% - 28px); }
}

@media (max-width: 860px) {
    .ledger__head { display: none; }

    /* The ledger stops being a table and becomes a stack: filename and status on
       one line, everything else demoted to a metadata line underneath. */
    .frow {
        grid-template-columns: 3px 40px minmax(0, 1fr);
        grid-template-areas: "ink thumb main";
        padding: 12px 14px 12px 0;
        gap: 12px;
    }
    .frow__ink   { grid-area: ink; }
    .frow__thumb { grid-area: thumb; }
    .frow__main  { grid-area: main; }
    .frow__who, .frow__num, .frow__remarks { display: none; }
    .frow__mobile { display: block; font-family: var(--font-mono); font-size: 11px; color: var(--ink-faint); margin-top: 3px; }

    .controls { flex-wrap: wrap; gap: 12px; }
    .controls__count { margin-left: 0; }
    input[type="search"] { min-width: 0; width: 100%; }
    .field { width: 100%; }
    .sheet { padding: 20px 14px 56px; }
    .masthead { padding: 0 14px; }
    .whoami__role { display: none; }
}

@media (min-width: 861px) {
    .frow__mobile { display: none; }
}

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