/* ---------------------------------------------------------------------------
   Datenaustausch - stylesheet
   ---------------------------------------------------------------------------
   One file, no build step, no framework. The application has about twenty
   screens and three of them matter; a toolchain would cost more than it
   saves and would put a compiled asset between the source and what runs.

   Two audiences, two moods:

     The employee screens are dense. Somebody who handles twenty handovers a
     day wants the list to fit on one screen, not to breathe.

     The public link pages are the opposite - wide margins, large type, one
     thing to do. They are read once, by somebody who did not ask to be
     there, often on a phone, sometimes under time pressure. Everything that
     is not the task is in their way.

   Colour is used for exactly three things: the primary action, a warning
   that something is irreversible, and the state of a transfer. Nothing is
   coloured for decoration, so a colour always means something.
   --------------------------------------------------------------------------- */

:root {
    --ink: #16191d;
    --ink-soft: #4a5260;
    --ink-faint: #717b8c;
    --line: #dfe3ea;
    --line-soft: #eceff4;
    --paper: #ffffff;
    --paper-soft: #f6f8fa;
    --paper-sunk: #eef1f6;

    --accent: #1f5f8b;
    --accent-dark: #174a6d;
    --accent-wash: #e8f1f8;

    --good: #1b6b4a;
    --good-wash: #e6f3ec;
    --warn: #8a5a12;
    --warn-wash: #fdf2e0;
    --bad: #99301f;
    --bad-wash: #fbeceb;

    --radius: 6px;
    --radius-lg: 10px;
    --shadow: 0 1px 2px rgba(22, 25, 29, .06), 0 4px 12px rgba(22, 25, 29, .05);

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

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

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

body {
    margin: 0;
    font-family: var(--font);
    font-size: 15px;
    line-height: 1.55;
    color: var(--ink);
    background: var(--paper-soft);
}

h1, h2, h3 { line-height: 1.25; margin: 0 0 .5rem; font-weight: 600; }
h1 { font-size: 1.5rem; }
h2 { font-size: 1.15rem; }
h3 { font-size: 1rem; }

p { margin: 0 0 .75rem; }
a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--accent-dark); }

/* Visible focus everywhere. Removing the outline is the single most common
   accessibility regression in a hand written stylesheet, so it is stated
   once, here, for every focusable thing. */
:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 3px;
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    background: var(--paper);
    padding: .6rem 1rem;
    z-index: 100;
}
.skip-link:focus { left: .5rem; top: .5rem; }

/* --- Shell ---------------------------------------------------------------- */

.shell { display: flex; min-height: 100vh; }

.sidebar {
    flex: 0 0 220px;
    background: var(--ink);
    color: #cfd6e0;
    padding: 1rem .75rem 2rem;
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}

.brand {
    display: block;
    color: var(--paper);
    font-weight: 600;
    font-size: 1.05rem;
    text-decoration: none;
    padding: .4rem .5rem .75rem;
    letter-spacing: -.01em;
}
.brand small {
    display: block;
    font-weight: 400;
    font-size: .75rem;
    color: #8b95a4;
    letter-spacing: 0;
}

.nav-group { display: flex; flex-direction: column; gap: 1px; }
.nav-label {
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: #727c8b;
    padding: .5rem .5rem .25rem;
}
.nav-group a {
    color: #cfd6e0;
    text-decoration: none;
    padding: .45rem .6rem;
    border-radius: var(--radius);
    font-size: .92rem;
}
.nav-group a:hover { background: #262b33; color: var(--paper); }
.nav-group a[aria-current="page"] { background: #303742; color: var(--paper); font-weight: 500; }

.sidebar-foot { margin-top: auto; font-size: .82rem; color: #8b95a4; padding: 0 .6rem; }
.sidebar-foot a { color: #cfd6e0; }

.main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }

.topbar {
    background: var(--paper);
    border-bottom: 1px solid var(--line);
    padding: .75rem 1.5rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
}
.topbar h1 { margin: 0; font-size: 1.2rem; }
.topbar .spacer { flex: 1 1 auto; }

.content { padding: 1.5rem; max-width: 1180px; width: 100%; }
.content.narrow { max-width: 760px; }

/* --- Public pages --------------------------------------------------------- */

.public-body { background: var(--paper-sunk); }

.public-wrap {
    max-width: 640px;
    margin: 0 auto;
    padding: 2.5rem 1.25rem 4rem;
}

.public-card {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    padding: 1.75rem;
}

.public-sender {
    font-size: .8rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: var(--ink-faint);
    margin-bottom: .35rem;
}

.public-wrap h1 { font-size: 1.6rem; margin-bottom: .75rem; }
.public-lead { font-size: 1.05rem; color: var(--ink-soft); }

.public-foot {
    margin-top: 1.5rem;
    font-size: .85rem;
    color: var(--ink-faint);
}
.public-foot ul { margin: .5rem 0 0; padding-left: 1.1rem; }
.public-foot li { margin-bottom: .2rem; }

/* --- Auth ---------------------------------------------------------------- */

.auth-body {
    background: var(--ink);
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.5rem;
}
.auth-card {
    background: var(--paper);
    border-radius: var(--radius-lg);
    box-shadow: 0 10px 40px rgba(0, 0, 0, .3);
    padding: 2rem;
    width: 100%;
    max-width: 400px;
}
.auth-card h1 { font-size: 1.3rem; margin-bottom: 1.25rem; }
.auth-brand {
    font-size: .8rem;
    text-transform: uppercase;
    letter-spacing: .09em;
    color: var(--ink-faint);
    margin-bottom: .25rem;
}

/* --- Cards and sections -------------------------------------------------- */

.card {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    padding: 1.25rem;
    margin-bottom: 1.25rem;
}
.card > h2:first-child, .card > h3:first-child { margin-top: 0; }
.card-tight { padding: 1rem; }

.grid { display: grid; gap: 1.25rem; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }

.row { display: flex; gap: .75rem; flex-wrap: wrap; align-items: center; }
.row-end { justify-content: flex-end; }

/* --- Forms ---------------------------------------------------------------- */

.field { margin-bottom: 1rem; }
.field > label, .field-label {
    display: block;
    font-weight: 500;
    font-size: .9rem;
    margin-bottom: .3rem;
}
.hint { display: block; font-size: .82rem; color: var(--ink-faint); margin-top: .25rem; }

input[type="text"], input[type="email"], input[type="password"],
input[type="tel"], input[type="number"], select, textarea {
    width: 100%;
    font: inherit;
    color: inherit;
    padding: .5rem .65rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--paper);
}
input:focus, select:focus, textarea:focus { border-color: var(--accent); }
textarea { min-height: 5.5rem; resize: vertical; }

input[type="text"].code-input {
    font-family: var(--mono);
    font-size: 1.4rem;
    letter-spacing: .25em;
    text-align: center;
    padding: .6rem;
}

fieldset { border: 0; padding: 0; margin: 0 0 1rem; }
legend { font-weight: 600; font-size: .95rem; padding: 0; margin-bottom: .5rem; }

/* A choice between two whole approaches, not a checkbox: the direction of a
   transfer changes what every field below it means, so it is presented as two
   cards rather than a dropdown nobody reads. */
.choice { display: grid; gap: .6rem; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.choice label {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: .85rem;
    cursor: pointer;
    display: block;
    background: var(--paper);
}
.choice label:hover { border-color: var(--accent); }
.choice input { margin-right: .4rem; }
.choice label:has(input:checked) {
    border-color: var(--accent);
    background: var(--accent-wash);
    box-shadow: inset 0 0 0 1px var(--accent);
}
.choice strong { display: block; font-size: .98rem; }
.choice .hint { margin-top: .2rem; }

.check { display: flex; gap: .5rem; align-items: flex-start; margin-bottom: .6rem; }
.check input { margin-top: .3rem; flex: 0 0 auto; }
.check label { font-weight: 500; font-size: .92rem; }
.check .hint { margin-top: .1rem; }

/* --- Buttons -------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    font: inherit;
    font-weight: 500;
    padding: .5rem .9rem;
    border-radius: var(--radius);
    border: 1px solid var(--line);
    background: var(--paper);
    color: var(--ink);
    cursor: pointer;
    text-decoration: none;
}
.btn:hover { background: var(--paper-soft); }
.btn-primary {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}
.btn-primary:hover { background: var(--accent-dark); border-color: var(--accent-dark); }
.btn-danger { color: var(--bad); border-color: #e8c9c4; }
.btn-danger:hover { background: var(--bad-wash); }
.btn-small { padding: .3rem .6rem; font-size: .85rem; }
.btn-block { width: 100%; justify-content: center; }
.btn:disabled { opacity: .5; cursor: not-allowed; }

.btn-link {
    background: none;
    border: 0;
    padding: 0;
    color: var(--accent);
    font: inherit;
    cursor: pointer;
    text-decoration: underline;
}

/* --- Tables --------------------------------------------------------------- */

.table-wrap { overflow-x: auto; margin: 0 -1.25rem; padding: 0 1.25rem; }
table.list td.mono, table.list td .mono { white-space: nowrap; }

table.list {
    width: 100%;
    border-collapse: collapse;
    font-size: .9rem;
}
table.list th, table.list td {
    text-align: left;
    padding: .55rem .6rem;
    border-bottom: 1px solid var(--line-soft);
    vertical-align: top;
}
table.list th {
    font-size: .75rem;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--ink-faint);
    border-bottom: 1px solid var(--line);
    white-space: nowrap;
}
table.list tbody tr:hover { background: var(--paper-soft); }
table.list td.numeric, table.list th.numeric { text-align: right; font-variant-numeric: tabular-nums; }
table.list .muted { color: var(--ink-faint); font-size: .85rem; }

.dl { display: grid; grid-template-columns: max-content 1fr; gap: .3rem 1rem; font-size: .92rem; margin: 0; }
.dl dt { color: var(--ink-faint); }
.dl dd { margin: 0; }

/* --- State pills ---------------------------------------------------------- */

.pill {
    display: inline-block;
    font-size: .74rem;
    font-weight: 600;
    letter-spacing: .02em;
    padding: .13rem .45rem;
    border-radius: 99px;
    white-space: nowrap;
}
.pill-active { background: var(--good-wash); color: var(--good); }
.pill-completed { background: var(--accent-wash); color: var(--accent-dark); }
.pill-expired { background: var(--paper-sunk); color: var(--ink-soft); }
.pill-revoked { background: var(--bad-wash); color: var(--bad); }
.pill-warn { background: var(--warn-wash); color: var(--warn); }
.pill-neutral { background: var(--paper-sunk); color: var(--ink-soft); }

.dir {
    display: inline-block;
    font-size: .78rem;
    font-weight: 600;
    padding: .1rem .4rem;
    border-radius: var(--radius);
    border: 1px solid var(--line);
    color: var(--ink-soft);
    white-space: nowrap;
}
.dir-inbound { border-color: #c5dcea; background: #eff7fc; color: var(--accent-dark); }
.dir-outbound { border-color: #d6d2c0; background: #faf7ec; color: #6b5a1f; }

/* --- Messages ------------------------------------------------------------- */

.msg {
    border-radius: var(--radius);
    padding: .7rem .9rem;
    margin-bottom: 1rem;
    font-size: .92rem;
    border: 1px solid transparent;
}
.msg-success { background: var(--good-wash); border-color: #bfdfcd; color: #12553a; }
.msg-error { background: var(--bad-wash); border-color: #eac6c1; color: #7d2718; }
.msg-notice { background: var(--warn-wash); border-color: #e8d2a8; color: #6f4810; }
.msg-info { background: var(--accent-wash); border-color: #c5dcea; color: var(--accent-dark); }

/* The support banner is never dismissible and never subtle. Guest access that
   is not visible is not auditable, and that is the whole basis on which it is
   allowed at all. */
.support-banner {
    background: #6b2d12;
    color: #ffe9d8;
    padding: .55rem 1.5rem;
    font-size: .88rem;
    display: flex;
    gap: 1rem;
    align-items: center;
    flex-wrap: wrap;
}
.support-banner form { margin: 0; }
.support-banner .btn { background: #ffe9d8; border-color: #ffe9d8; color: #6b2d12; }

/* --- The link box --------------------------------------------------------- */

.linkbox {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 1.25rem;
    align-items: start;
}
@media (max-width: 620px) { .linkbox { grid-template-columns: 1fr; } }

.link-url {
    font-family: var(--mono);
    font-size: .82rem;
    background: var(--paper-sunk);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: .55rem .65rem;
    word-break: break-all;
    margin-bottom: .6rem;
}

.qr { background: #fff; border: 1px solid var(--line); border-radius: var(--radius); padding: .4rem; }
.qr img, .qr svg { display: block; width: 150px; height: 150px; }

.code-display {
    font-family: var(--mono);
    font-size: 1.8rem;
    letter-spacing: .3em;
    font-weight: 600;
    background: var(--warn-wash);
    border: 1px dashed #d9b574;
    border-radius: var(--radius);
    padding: .6rem 1rem;
    display: inline-block;
}

.codes { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: .4rem; }
.codes code {
    font-family: var(--mono);
    background: var(--paper-sunk);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: .3rem .5rem;
    text-align: center;
    font-size: .95rem;
}

/* --- Upload -------------------------------------------------------------- */

.dropzone {
    border: 2px dashed var(--line);
    border-radius: var(--radius-lg);
    background: var(--paper-soft);
    padding: 1.75rem 1.25rem;
    text-align: center;
    transition: border-color .12s, background .12s;
}
.dropzone.is-over { border-color: var(--accent); background: var(--accent-wash); }
.dropzone p { margin: .35rem 0; }
.dropzone input[type="file"] { position: absolute; width: 1px; height: 1px; opacity: 0; }

.upload-list { list-style: none; margin: 1rem 0 0; padding: 0; }
.upload-list li {
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: .6rem .75rem;
    margin-bottom: .5rem;
    background: var(--paper);
}
.upload-row { display: flex; gap: .75rem; align-items: baseline; }
.upload-name { font-weight: 500; word-break: break-all; flex: 1 1 auto; }
.upload-state { font-size: .85rem; color: var(--ink-faint); white-space: nowrap; }
.upload-state.is-done { color: var(--good); }
.upload-state.is-failed { color: var(--bad); }

.bar {
    height: 5px;
    background: var(--paper-sunk);
    border-radius: 99px;
    overflow: hidden;
    margin-top: .45rem;
}
.bar > span { display: block; height: 100%; background: var(--accent); width: 0; transition: width .15s; }
.bar.is-done > span { background: var(--good); }
.bar.is-failed > span { background: var(--bad); }

.meter {
    height: 7px;
    background: var(--paper-sunk);
    border-radius: 99px;
    overflow: hidden;
    margin-top: .35rem;
}
.meter > span { display: block; height: 100%; background: var(--accent); }
.meter.is-high > span { background: var(--warn); }
.meter.is-full > span { background: var(--bad); }

/* --- Events -------------------------------------------------------------- */

.events { list-style: none; margin: 0; padding: 0; font-size: .89rem; }
.events li {
    display: grid;
    grid-template-columns: 11rem 1fr;
    gap: .75rem;
    padding: .4rem 0;
    border-bottom: 1px solid var(--line-soft);
}
.events time { color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.events .who { color: var(--ink-faint); }
@media (max-width: 560px) {
    .events li { grid-template-columns: 1fr; gap: .1rem; }
}

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

.muted { color: var(--ink-faint); }
.small { font-size: .85rem; }
.mono { font-family: var(--mono); font-size: .85rem; }
/* break-all belongs to .link-url alone. On .mono it also hit the e-mail
   column of the user table, which then wrapped one character per line -
   "anna. berge r@dem o.inv alid". A table that is too wide scrolls; a
   table whose cells shatter is unreadable. */
.nowrap { white-space: nowrap; }
.stack > * + * { margin-top: 1rem; }
.sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

.stat { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius); padding: .8rem; }
.stat .n { font-size: 1.5rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.stat .l { font-size: .8rem; color: var(--ink-faint); }

/* --- Narrow screens ------------------------------------------------------ */

@media (max-width: 860px) {
    .shell { flex-direction: column; }
    .sidebar {
        flex: 0 0 auto;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
        gap: .5rem;
        padding: .6rem .75rem;
    }
    .brand { padding: 0 .5rem 0 0; }
    .brand small { display: none; }
    .nav-label { display: none; }
    .nav-group { flex-direction: row; flex-wrap: wrap; }
    .sidebar-foot { margin: 0; }
    .content { padding: 1rem; }
    .table-wrap { margin: 0 -1rem; padding: 0 1rem; }
}

@media print {
    .sidebar, .topbar, .support-banner, .btn { display: none !important; }
    body { background: #fff; }
    .card { border: 0; padding: 0; }
}
