/*
    The polling station terminal.

    This is a single-purpose appliance, not a page in a portal: one officer, one desk, one job, for a
    whole day. So it gets its own layout - a fixed dark command bar, a fixed two column desk, and no
    scrolling chrome - rather than the portal shell the elections client uses.

    The palette is the platform's own. --ps-purple is #5f4b8b, exactly the purple behind btn-purple and
    bg-purple in the shared theme; the darks below are the same hue taken down, so the terminal reads as
    part of the same product rather than a different one.
*/

:root {
    --ps-purple: #5f4b8b;
    --ps-purple-dark: #48396a;
    --ps-purple-darker: #3d3059;
    --ps-purple-tint: #f2effa;
    --ps-purple-line: #d9d1ee;

    /* Same hue as the purple, taken right down - the command bar and the sign in panel. */
    --ps-ink: #1e1830;
    --ps-ink-2: #2a2242;
    --ps-ink-3: #3a3055;
    --ps-on-ink: #ffffff;
    --ps-on-ink-dim: #a79fc0;

    --ps-page: #eef0f4;
    --ps-surface: #ffffff;
    --ps-line: #dfe3ea;
    --ps-line-soft: #eceff4;

    --ps-text: #1c2431;
    --ps-muted: #6b7585;

    /* Verifying is the irreversible act, so it gets the one strong green on the screen. */
    --ps-green: #15653f;
    --ps-green-dark: #114f31;
    --ps-green-tint: #e4f1ea;

    --ps-amber-tint: #fdf1d6;
    --ps-amber-text: #7a5b12;
    --ps-red: #b42318;

    --ps-mono: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
}

html, body {
    height: 100%;
    margin: 0;
    background: var(--ps-page);
    color: var(--ps-text);
    font-family: "Fira Sans", "Segoe UI", system-ui, -apple-system, sans-serif;
    -webkit-text-size-adjust: 100%;
}

/* Bootstrap's container caps width; this app wants the whole desk. */
.ps-app { min-height: 100vh; display: flex; flex-direction: column; }

.ps-eyebrow {
    display: block;
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--ps-muted);
}

.ps-mono { font-family: var(--ps-mono); }

/* ============================================================
   Command bar
   ============================================================ */

.ps-bar {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    padding: .625rem 1rem;
    background: var(--ps-ink);
    color: var(--ps-on-ink);
    border-bottom: 3px solid var(--ps-purple);
}

.ps-bar-brand { display: flex; align-items: center; gap: .75rem; margin-right: auto; }

.ps-mark {
    display: grid;
    place-items: center;
    width: 34px; height: 34px;
    border-radius: 50%;
    background: var(--ps-purple);
    color: #fff;
    flex: none;
}

.ps-bar-title { font-size: 1rem; font-weight: 700; line-height: 1.2; }

.ps-bar-sub {
    display: block;
    font-size: .6875rem;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--ps-on-ink-dim);
}

.ps-chips { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }

.ps-chip {
    padding: .3rem .7rem;
    border: 1px solid var(--ps-ink-3);
    border-radius: .375rem;
    background: var(--ps-ink-2);
    line-height: 1.25;
}

.ps-chip-label {
    display: block;
    font-size: .625rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--ps-on-ink-dim);
}

.ps-chip-value { display: block; font-size: .8125rem; font-weight: 600; color: #fff; white-space: nowrap; }

.ps-chip-value.ps-clock { font-family: var(--ps-mono); letter-spacing: .02em; }

.ps-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: .35rem; }
.ps-dot-on { background: #34d399; }
.ps-dot-off { background: #f87171; }

.ps-bar-signout {
    display: inline-flex; align-items: center; gap: .4rem;
    padding: .45rem .8rem;
    border: 1px solid var(--ps-ink-3);
    border-radius: .375rem;
    background: transparent;
    color: #fff;
    font-size: .8125rem; font-weight: 600;
}

.ps-bar-signout:hover { background: var(--ps-ink-2); color: #fff; }

/* ============================================================
   Toolbar
   ============================================================ */

.ps-toolbar {
    display: flex;
    align-items: center;
    gap: .75rem;
    flex-wrap: wrap;
    padding: .75rem 1rem;
    background: var(--ps-surface);
    border-bottom: 1px solid var(--ps-line);
}

.ps-toolbar-meta {
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--ps-muted);
}

.ps-toolbar-end { margin-left: auto; position: relative; }

/* ---- station menu ---- */

.ps-menu-btn {
    display: inline-flex; align-items: center; gap: .5rem;
    padding: .45rem .7rem;
    border: 1px solid transparent;
    border-radius: .375rem;
    background: transparent;
    color: var(--ps-text);
    font-size: .875rem; font-weight: 600;
}

.ps-menu-btn:hover { background: var(--ps-line-soft); }

.ps-menu {
    position: absolute;
    top: calc(100% + .35rem);
    right: 0;
    z-index: 50;
    min-width: 240px;
    padding: .35rem 0;
    background: var(--ps-surface);
    border: 1px solid var(--ps-line);
    border-radius: .5rem;
    box-shadow: 0 12px 28px rgba(20, 24, 33, .16);
}

.ps-menu-item {
    display: block; width: 100%;
    padding: .55rem 1rem;
    border: 0;
    background: none;
    text-align: left;
    font-size: .9375rem;
    color: var(--ps-text);
}

.ps-menu-item:hover:not(:disabled) { background: var(--ps-purple-tint); }
.ps-menu-item:disabled { color: var(--ps-muted); }
.ps-menu-item.is-danger { color: var(--ps-red); }
.ps-menu-sep { height: 1px; margin: .35rem 0; background: var(--ps-line); }

.ps-backdrop { position: fixed; inset: 0; z-index: 40; }

/* ============================================================
   Desk
   ============================================================ */

.ps-desk {
    flex: 1;
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
    padding: 1rem;
}

@media (max-width: 991.98px) {
    .ps-desk { grid-template-columns: minmax(0, 1fr); }
}

.ps-card {
    background: var(--ps-surface);
    border: 1px solid var(--ps-line);
    border-radius: .5rem;
}

.ps-card-body { padding: 1.25rem; }

/* ---- search ---- */

.ps-search { display: flex; gap: .75rem; }

.ps-search-input {
    flex: 1; min-width: 0;
    height: 62px;
    padding: 0 1rem;
    font-family: var(--ps-mono);
    font-size: 1.6rem;
    letter-spacing: .12em;
    color: var(--ps-text);
    border: 2px solid var(--ps-text);
    border-radius: .375rem;
    background: #fff;
}

.ps-search-input::placeholder { color: #c3c9d4; }

.ps-search-input:focus {
    outline: none;
    border-color: var(--ps-purple);
    box-shadow: 0 0 0 .2rem rgba(95, 75, 139, .25);
}

.ps-find {
    flex: none;
    min-width: 130px;
    border: 0;
    border-radius: .375rem;
    background: var(--ps-purple);
    color: #fff;
    font-size: 1rem; font-weight: 700;
}

.ps-find:hover:not(:disabled) { background: var(--ps-purple-dark); }
.ps-find:disabled { opacity: .6; }

/* Shortcuts are the difference between a desk that keeps up with a queue and one that does not. */
.ps-keys { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: .6rem; font-size: .8125rem; color: var(--ps-muted); }
.ps-keys kbd {
    padding: .1rem .4rem;
    border: 1px solid var(--ps-line);
    border-bottom-width: 2px;
    border-radius: .25rem;
    background: #f6f7f9;
    color: var(--ps-text);
    font-family: var(--ps-mono);
    font-size: .75rem;
}

.ps-empty {
    margin-top: 1rem;
    padding: 3rem 1rem;
    border: 1px dashed var(--ps-line);
    border-radius: .375rem;
    text-align: center;
    color: var(--ps-muted);
}

.ps-empty i { font-size: 1.75rem; color: #c3c9d4; }

/* ---- voter record ---- */

.ps-record { display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: 1.25rem; }

@media (max-width: 575.98px) {
    .ps-record { grid-template-columns: minmax(0, 1fr); }
}

/*
    Corner brackets, not a border. They frame the photograph the way a document does and make it read
    as evidence to compare against a face, rather than decoration.
*/
.ps-photo-frame { position: relative; padding: 10px; }

.ps-photo-frame::before,
.ps-photo-frame::after {
    content: "";
    position: absolute;
    width: 18px; height: 18px;
    border: 2px solid var(--ps-muted);
}

.ps-photo-frame::before { top: 0; left: 0; border-right: 0; border-bottom: 0; }
.ps-photo-frame::after { bottom: 0; right: 0; border-left: 0; border-top: 0; }

.ps-photo {
    display: block; width: 100%;
    aspect-ratio: 3 / 4;
    object-fit: cover;
    background: var(--ps-line-soft);
}

.ps-photo-missing {
    display: grid; place-content: center; text-align: center; gap: .25rem;
    width: 100%; aspect-ratio: 3 / 4;
    padding: 1rem;
    background: var(--ps-line-soft);
    color: var(--ps-muted);
    font-size: .8125rem;
}

.ps-photo-caption { margin-top: .35rem; text-align: center; }

.ps-verdict {
    display: flex; gap: .65rem;
    padding: .8rem 1rem;
    border-radius: .375rem;
    background: var(--ps-purple-tint);
    border: 1px solid var(--ps-purple-line);
    margin-bottom: 1.1rem;
}

.ps-verdict-title { font-weight: 700; color: var(--ps-purple-darker); }
.ps-verdict-note { font-size: .875rem; color: var(--ps-purple-darker); opacity: .85; }

.ps-verdict.is-done { background: var(--ps-amber-tint); border-color: #e8d4a0; }
.ps-verdict.is-done .ps-verdict-title,
.ps-verdict.is-done .ps-verdict-note { color: var(--ps-amber-text); }

.ps-name { font-size: 1.65rem; font-weight: 700; line-height: 1.15; margin: .15rem 0 .15rem; }

.ps-index { font-family: var(--ps-mono); font-size: 1.05rem; letter-spacing: .06em; color: var(--ps-purple); }

.ps-facts { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1.5rem; margin: 1.1rem 0; }

.ps-fact { padding: .6rem 0; border-bottom: 1px solid var(--ps-line); }
.ps-fact-value { display: block; font-size: 1rem; font-weight: 600; }

.ps-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem; margin-top: .35rem; }

.ps-verify {
    padding: .85rem 1.5rem;
    border: 0; border-radius: .375rem;
    background: var(--ps-green);
    color: #fff;
    font-size: 1.0625rem; font-weight: 700;
}

.ps-verify:hover:not(:disabled) { background: var(--ps-green-dark); }
.ps-verify:disabled { opacity: .65; }

.ps-cancel { border: 0; background: none; color: var(--ps-text); font-weight: 600; padding: .5rem 0; }

/* ============================================================
   Right column
   ============================================================ */

.ps-stats { display: grid; grid-template-columns: repeat(3, 1fr); }

.ps-stat { padding: .9rem 1rem; border-right: 1px solid var(--ps-line); }
.ps-stat:last-child { border-right: 0; }
.ps-stat-value { display: block; font-size: 1.5rem; font-weight: 700; line-height: 1.2; }
.ps-stat-value.is-verified { color: var(--ps-green); }

.ps-turnout { padding: .75rem 1rem; border-top: 1px solid var(--ps-line); }
.ps-turnout-head { display: flex; justify-content: space-between; font-weight: 700; font-size: .9375rem; }

.ps-progress { height: 8px; border-radius: 999px; background: var(--ps-line-soft); overflow: hidden; margin-top: .5rem; }
.ps-progress-bar { height: 100%; background: var(--ps-green); transition: width .3s ease; }

.ps-tabs { display: flex; border-top: 1px solid var(--ps-line); }

.ps-tab {
    flex: 1;
    padding: .8rem .5rem;
    border: 0;
    border-bottom: 3px solid transparent;
    background: #f7f8fa;
    color: var(--ps-muted);
    font-weight: 600;
}

.ps-tab.is-active { background: var(--ps-surface); color: var(--ps-text); border-bottom-color: var(--ps-purple); }

.ps-filter-wrap { padding: .75rem 1rem; }

.ps-list { max-height: 26rem; overflow-y: auto; }

.ps-row {
    display: flex; align-items: center; gap: .75rem;
    padding: .7rem 1rem;
    border-top: 1px solid var(--ps-line-soft);
}

.ps-row:first-child { border-top: 0; }

.ps-avatar {
    display: grid; place-items: center;
    flex: none;
    width: 34px; height: 34px;
    border-radius: 50%;
    background: var(--ps-purple-tint);
    color: var(--ps-purple-darker);
    font-size: .75rem; font-weight: 700;
}

.ps-row-main { min-width: 0; flex: 1; }
.ps-row-name { font-weight: 600; line-height: 1.25; }
.ps-row-meta { font-family: var(--ps-mono); font-size: .8125rem; color: var(--ps-muted); }
.ps-row-end { flex: none; text-align: right; font-size: .8125rem; color: var(--ps-muted); }

.ps-tag {
    display: inline-block;
    padding: .1rem .45rem;
    border-radius: .25rem;
    font-size: .6875rem; font-weight: 700; letter-spacing: .04em;
}

.ps-tag-voted { background: var(--ps-green-tint); color: var(--ps-green); }

/* ============================================================
   Sign in
   ============================================================ */

.ps-signin { min-height: 100vh; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }

@media (max-width: 991.98px) {
    .ps-signin { grid-template-columns: minmax(0, 1fr); }
    .ps-signin-brand { min-height: auto; }
}

.ps-signin-brand {
    position: relative;
    overflow: hidden;
    display: flex; flex-direction: column;
    padding: 2.5rem;
    color: var(--ps-on-ink);

    /* The cover photo is bright, so an ink wash sits over it - lighter at the top where the photo
       shows through, darkest behind the title and station facts. The service worker precaches .jpeg,
       so the cover is there offline too. */
    background:
        linear-gradient(180deg, rgba(30, 24, 48, .55) 0%, rgba(30, 24, 48, .72) 45%, rgba(30, 24, 48, .94) 100%),
        url("../cover.jpeg") center top / cover no-repeat,
        var(--ps-ink);
}

.ps-signin-brand > * { position: relative; z-index: 1; }

.ps-signin-head { display: flex; align-items: center; gap: .75rem; }
.ps-signin-org { font-weight: 700; }

.ps-signin-body { margin-top: auto; padding-top: 3rem; }

.ps-signin-title { font-size: 2.35rem; font-weight: 700; line-height: 1.1; margin: .35rem 0 1rem; }
.ps-signin-text { max-width: 26rem; color: #ded9ec; }

.ps-signin-grid {
    display: grid; grid-template-columns: 1fr 1fr;
    margin-top: 1.75rem;
    max-width: 28rem;
    border: 1px solid var(--ps-ink-3);
}

.ps-signin-cell { padding: .8rem 1rem; border-right: 1px solid var(--ps-ink-3); border-bottom: 1px solid var(--ps-ink-3); }
.ps-signin-cell:nth-child(2n) { border-right: 0; }
.ps-signin-cell:nth-last-child(-n+2) { border-bottom: 0; }
.ps-signin-cell .ps-eyebrow { color: var(--ps-on-ink-dim); }
.ps-signin-value { font-weight: 700; }

.ps-signin-foot { margin-top: auto; padding-top: 2.5rem; font-size: .8125rem; color: #7d7597; }

/* Grey behind the panel so the card below reads as a card rather than as the page itself. */
.ps-signin-form { display: flex; align-items: center; justify-content: center; padding: 2.5rem 1.5rem; background: var(--ps-page); }

.ps-signin-card {
    width: 100%;
    max-width: 26rem;
    padding: 2rem;
    background: var(--ps-surface);
    border: 1px solid var(--ps-line);
    border-radius: .5rem;
    box-shadow: 0 10px 30px rgba(30, 24, 48, .07);
}

.ps-signin-heading { font-size: 1.7rem; font-weight: 700; margin: .35rem 0 .4rem; }

.ps-field { margin-bottom: 1rem; }
.ps-field label { display: block; margin-bottom: .3rem; }

.ps-input {
    width: 100%;
    height: 52px;
    padding: 0 .9rem;
    border: 1px solid var(--ps-line);
    border-radius: .375rem;
    font-size: 1rem;
    color: var(--ps-text);
    background: #fff;
}

.ps-input.ps-mono { font-family: var(--ps-mono); letter-spacing: .12em; }

.ps-input:focus {
    outline: none;
    border-color: var(--ps-purple);
    box-shadow: 0 0 0 .2rem rgba(95, 75, 139, .25);
}

.ps-input-wrap { position: relative; }

.ps-reveal {
    position: absolute; top: 0; right: .75rem; height: 52px;
    border: 0; background: none;
    color: var(--ps-purple);
    font-size: .875rem; font-weight: 600;
}

.ps-submit {
    width: 100%;
    padding: .9rem 1rem;
    border: 0; border-radius: .375rem;
    background: var(--ps-purple);
    color: #fff;
    font-size: 1.0625rem; font-weight: 700;
}

.ps-submit:hover:not(:disabled) { background: var(--ps-purple-dark); }
.ps-submit:disabled { opacity: .65; }

.ps-note { margin-top: 1.25rem; font-size: .875rem; color: var(--ps-muted); }

.ps-alert { padding: .8rem 1rem; border-radius: .375rem; font-size: .9375rem; margin-bottom: 1rem; }
.ps-alert-error { background: #fdecec; border: 1px solid #f5c2c0; color: #8f2320; }
.ps-alert-ok { background: var(--ps-green-tint); border: 1px solid #b9dcc9; color: var(--ps-green); }
.ps-alert-warn { background: var(--ps-amber-tint); border: 1px solid #e8d4a0; color: var(--ps-amber-text); }

/* ============================================================
   Panels (setup, sync) and boot
   ============================================================ */

.ps-panel { max-width: 60rem; margin: 0 auto; padding: 1.5rem 1rem 3rem; }
.ps-panel h1 { font-size: 1.5rem; font-weight: 700; }

.ps-btn {
    display: inline-flex; align-items: center; gap: .45rem;
    padding: .55rem 1rem;
    border: 1px solid var(--ps-line);
    border-radius: .375rem;
    background: var(--ps-surface);
    color: var(--ps-text);
    font-size: .9375rem; font-weight: 600;
}

.ps-btn:hover:not(:disabled) { background: var(--ps-line-soft); color: var(--ps-text); }
.ps-btn:disabled { opacity: .6; }

.ps-btn-primary { background: var(--ps-purple); border-color: var(--ps-purple); color: #fff; }
.ps-btn-primary:hover:not(:disabled) { background: var(--ps-purple-dark); border-color: var(--ps-purple-dark); color: #fff; }

.ps-btn-danger { background: var(--ps-red); border-color: var(--ps-red); color: #fff; }
.ps-btn-danger:hover:not(:disabled) { background: #8f1c14; border-color: #8f1c14; color: #fff; }

.ps-option {
    display: block; width: 100%; text-align: left;
    padding: .85rem 1rem;
    border: 1px solid var(--ps-line);
    border-radius: .375rem;
    background: var(--ps-surface);
    margin-bottom: .5rem;
}

.ps-option.is-selected { border-color: var(--ps-purple); box-shadow: 0 0 0 .15rem rgba(95, 75, 139, .18); }

.ps-boot {
    display: grid; place-content: center; gap: .75rem;
    min-height: 100vh; text-align: center;
    color: var(--ps-muted);
}

.ps-spinner {
    width: 34px; height: 34px; margin: 0 auto;
    border: 3px solid var(--ps-purple-line);
    border-top-color: var(--ps-purple);
    border-radius: 50%;
    animation: ps-spin .8s linear infinite;
}

.ps-spinner-sm { width: 15px; height: 15px; border-width: 2px; display: inline-block; vertical-align: -2px; margin-right: .4rem; }

@keyframes ps-spin { to { transform: rotate(360deg); } }

/* ---- skeletons ----

   Loading a register off the device is a layout the officer will see again a second later, so the
   waiting state is that layout in grey rather than a spinner: nothing moves, and nothing has to be
   re-read once the real values land. Placeholders carry no text, so they cannot be mistaken for data.
*/

.ps-skel {
    display: block;
    background: linear-gradient(90deg, #e6e9ef 25%, #eff1f5 37%, #e6e9ef 63%);
    background-size: 400% 100%;
    border-radius: .25rem;
    animation: ps-skel-shimmer 1.4s ease-in-out infinite;
}

.ps-skel-line { height: .75rem; }
.ps-skel-text { height: 1rem; }
.ps-skel-title { height: 1.35rem; width: 45%; }
.ps-skel-input { height: 2.75rem; border-radius: .375rem; }
.ps-skel-btn { height: 2.75rem; width: 8.5rem; border-radius: .375rem; }
.ps-skel-avatar { width: 34px; height: 34px; border-radius: 50%; flex: none; }
.ps-skel-block { height: 6.5rem; border-radius: .375rem; }

/* On the dark command bar the light grey would glare, so placeholders there are the bar itself, lifted. */
.ps-skel-ink {
    background: linear-gradient(90deg, var(--ps-ink-2) 25%, var(--ps-ink-3) 37%, var(--ps-ink-2) 63%);
    background-size: 400% 100%;
}

@keyframes ps-skel-shimmer { to { background-position: -135% 0; } }

.ps-skel-stack > * + * { margin-top: .6rem; }

@media (prefers-reduced-motion: reduce) {
    .ps-skel { animation: none; }
}

@media (prefers-reduced-motion: reduce) {
    .ps-spinner { animation-duration: 3s; }
    .ps-progress-bar { transition: none; }
}

#blazor-error-ui {
    display: none;
    position: fixed; bottom: 0; left: 0; right: 0; z-index: 1000;
    padding: .85rem 1.25rem;
    background: var(--ps-amber-tint);
    color: var(--ps-amber-text);
    box-shadow: 0 -1px 6px rgba(0, 0, 0, .15);
}

#blazor-error-ui .dismiss { position: absolute; top: .5rem; right: .9rem; cursor: pointer; font-size: 1.2rem; }
