/* Staff area.
 *
 * MOBILE FIRST, like the public site: everything outside a media query is the
 * phone layout, and wider screens are additive via min-width only.
 *
 * Standalone rather than an add-on to style.css. The staff area shares none of
 * the public site's markup, and loading the public stylesheet to override two
 * thirds of it would be the slower, muddier option.
 *
 * BRANDED ON THE FRONT DOOR, PLAIN BEHIND IT.
 *
 * The signed-out screens — sign in, forgot password, reset password, setup —
 * are styled to match the public site: black bar, Fredericka wordmark, square
 * edges, monochrome. They are the only staff pages anyone meets before signing
 * in, so they should read as part of the website.
 *
 * Everything behind the sign-in stays a plain working tool. It shares the
 * site's tokens so nothing clashes, but it is not decorated: staff use it
 * daily to get something done, and a manager who works across two of these
 * should not have to learn two interfaces.
 *
 * Prefer changing the tokens below to rewriting the components.
 *
 * Bump ASSET_VERSION in includes/site.php when you change this file — assets
 * are cached for a year by .htaccess.
 */

/* The display face, declared again here because this stylesheet is loaded on
   its own — the staff area never loads style.css. Same file, so the browser
   serves it from cache and there is no second download.
   See the note in style.css: self-hosted, never linked from Google. */
@font-face {
    font-family: 'Fredericka the Great';
    src: url('../fonts/fredericka-the-great.woff2') format('woff2'),
         url('../fonts/fredericka-the-great.ttf')   format('truetype');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

/* --- Tokens (kept in step with style.css) -------------------------------- */
:root {
    --paper:      #ffffff;
    --ink:        #000000;
    --paper-lift: #f4f4f4;
    --paper-deep: #e2e2e2;
    --ink-soft:   #6a6a6a;
    --ink-line:   rgba(0, 0, 0, 0.14);
    --paper-line: rgba(255, 255, 255, 0.28);

    /* The one colour in the whole build, and it is deliberate. Reserved for
       DESTRUCTIVE actions and failures — deleting a user, a send that did not
       go. Monochrome is right for the public site, where nothing is
       irreversible; in a tool where one button removes someone's access, the
       colour is a safety signal rather than decoration. */
    --error:      #8c2f27;
    --ok:         var(--ink);

    /* Fredericka at display sizes only, exactly as on the public site. The
       staff area's headings run small, so it appears on h1 and the wordmark
       and nowhere else — see the h1/h2/h3 rules below. */
    --font-display: 'Fredericka the Great', 'Papyrus', 'Brush Script MT', cursive;
    --font-body:    system-ui, -apple-system, "Segoe UI", Roboto,
                    "Helvetica Neue", Arial, sans-serif;

    --gap:     1rem;
    --measure: 34rem;
    --shell:   64rem;
    /* Square, matching the public site's grid. */
    --radius:  0;
}

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

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

body {
    margin: 0;
    font: 400 1rem/1.6 var(--font-body);
    color: var(--ink);
    background: var(--paper);
}

h1, h2, h3 {
    line-height: 1.12;
    margin: 0 0 var(--gap);
}

/* ONLY h1 GETS THE DISPLAY FACE. Fredericka is a distressed hand-lettered
   design that stops being readable below about 1.5rem, and staff headings run
   small — h3 is 1.125rem. Putting it on h2/h3 would make a working tool hard
   to scan for the sake of brand consistency nobody is looking for while they
   are signed in. Same restraint as the public site. */
h1 {
    font-family: var(--font-display);
    font-weight: 400;
    font-size: clamp(1.875rem, 7vw, 2.75rem);
    letter-spacing: -0.005em;
    text-transform: uppercase;
}

h2 { font-family: var(--font-body); font-weight: 600; font-size: clamp(1.25rem, 5vw, 1.625rem); margin-top: 2.5rem; letter-spacing: -0.01em; }
h3 { font-family: var(--font-body); font-weight: 600; font-size: 1.0625rem; letter-spacing: 0; }

p { margin: 0 0 var(--gap); }

a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.25em; }
a:hover { text-decoration-color: var(--ink-soft); }

/* One focus style everywhere, and it must stay visible. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
summary:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 3px;
    border-radius: 2px;
}

/* --- Utilities ---------------------------------------------------------- */
.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.skip-link {
    position: absolute;
    left: -9999px;
    z-index: 100;
    padding: 0.75rem 1rem;
    background: var(--ink);
    color: var(--paper);
    text-decoration: none;
}
.skip-link:focus { left: 0.5rem; top: 0.5rem; }

/* Honeypot: a class, never an inline style — the CSP forbids those. Moved
 * off-screen rather than display:none, which some bots detect. */
.hp {
    position: absolute;
    left: -9999px;
    width: 1px; height: 1px;
    overflow: hidden;
}

.eyebrow {
    margin: 0 0 0.75rem;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--ink-soft);
}

.measure { max-width: var(--measure); }
.muted   { color: var(--ink-soft); }
.lede    { font-size: 1.0625rem; color: var(--ink-soft); }

code {
    padding: 0.1em 0.35em;
    font-size: 0.875em;
    background: var(--paper-deep);
    border-radius: 3px;
    word-break: break-word;
}

/* --- Top bar ------------------------------------------------------------ */
.admin-bar {
    color: var(--paper);
    background: var(--ink);
}

.admin-bar__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    max-width: var(--shell);
    margin: 0 auto;
    padding: 0.875rem 1.25rem;
}

.admin-bar__brand {
    margin: 0;
    font-family: var(--font-display);
    font-size: 1.25rem;
}
.admin-bar__brand a { text-decoration: none; }
.admin-bar__brand span {
    display: block;
    font-family: var(--font-body);
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    opacity: 0.65;
}

.admin-nav {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 1.25rem;
    width: 100%;
}

.admin-nav__list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1.25rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.admin-nav__list a {
    display: inline-block;
    /* 44px touch target, which is why the padding looks generous. */
    padding: 0.7rem 0;
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-decoration: none;
}
.admin-nav__list a:hover { text-decoration: underline; }
.admin-nav__list a[aria-current="page"] {
    text-decoration: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: 0.35em;
}

.admin-nav__out { margin-left: auto; }
.admin-nav__out .btn { margin-top: 0; width: auto; }

.admin-who {
    max-width: var(--shell);
    margin: 0 auto;
    padding: 0.75rem 1.25rem 0;
    font-size: 0.8125rem;
    color: var(--ink-soft);
}

/* --- Layout ------------------------------------------------------------- */
.admin-main {
    max-width: var(--shell);
    margin: 0 auto;
    padding: 1.75rem 1.25rem 3rem;
}

/* --- Signed-out screens: sign in, forgot password, reset password, setup ---
 *
 * These are the only staff pages anyone meets before being signed in, so they
 * are the ones that should read as part of the website rather than as a tool.
 * They borrow the public site's composition directly: black bar carrying the
 * wordmark, generous white space below it, one narrow centred column.
 *
 * Everything BEHIND the sign-in stays plain on purpose — see the note at the
 * top of this file. Brand belongs on the front door, not on the shelving.
 */
.admin--bare .admin-main {
    max-width: calc(var(--measure) + 2.5rem);
    padding-top: 3.5rem;
}

/* The bar is the full-width black block the public header inverts to, and the
   wordmark inside it is set like the site's. */
.admin--bare .admin-bar__inner {
    justify-content: center;
    padding-block: 2rem;
    text-align: center;
}

.admin--bare .admin-bar__brand {
    font-size: clamp(1.5rem, 6vw, 2.25rem);
    letter-spacing: 0.01em;
    text-transform: uppercase;
}

/* "Staff area", under the wordmark. Body face, wide tracking — the same
   eyebrow treatment the public site uses above its headings. */
.admin--bare .admin-bar__brand span {
    margin-top: 0.65rem;
    font-size: 0.6875rem;
    letter-spacing: 0.24em;
    opacity: 0.7;
}

/* The sign-in panel sits flat on the page rather than in a raised card. The
   public site has no cards anywhere, and one here would look borrowed. */
.admin--bare .panel {
    background: transparent;
    border: 0;
    border-top: 1px solid var(--ink-line);
    padding: 1.75rem 0 0;
}

.admin--bare .page-head h1 { margin-bottom: 0.75rem; }

/* Full-width primary action, which is the convention people expect on a
   sign-in form and reads correctly at phone width. */
.admin--bare form .btn { width: 100%; }

.page-head { margin-bottom: 1.5rem; }
.page-head h1 { margin-bottom: 0.5rem; }

.panel {
    padding: 1.25rem;
    background: var(--paper-lift);
    border: 1px solid var(--ink-line);
    border-radius: var(--radius);
}
.panel + .panel { margin-top: 1.25rem; }
.panel > :last-child { margin-bottom: 0; }

.stack > * + * { margin-top: 1.25rem; }

/* --- Buttons ------------------------------------------------------------ */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 48px;
    padding: 0.7rem 1.5rem;
    font-family: var(--font-body);
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--paper);
    background: var(--ink);
    border: 1px solid var(--ink);
    /* Square, like the public site's buttons. Was a pill. */
    border-radius: var(--radius);
    cursor: pointer;
    transition: background 0.2s ease, color 0.2s ease;
}
.btn:hover { background: transparent; color: var(--ink); }

.btn--ghost {
    color: var(--paper);
    background: transparent;
    border-color: var(--paper-line);
}
.btn--ghost:hover { background: var(--paper); color: var(--ink); border-color: var(--paper); }

.btn--quiet {
    color: var(--ink);
    background: transparent;
    border-color: var(--ink-line);
}
.btn--quiet:hover { background: var(--paper-deep); border-color: var(--paper-deep); color: var(--ink); }

.btn--danger { background: var(--error); border-color: var(--error); color: #fff; }
.btn--danger:hover { background: transparent; color: var(--error); }

.btn--small {
    min-height: 44px;
    padding: 0.5rem 1rem;
    font-size: 0.75rem;
}

.btn-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 1.75rem;
}
.btn-row .btn { margin-top: 0; width: auto; }

/* --- Forms -------------------------------------------------------------- */
label {
    display: block;
    margin: 1.5rem 0 0.4rem;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
}

.hint {
    display: block;
    margin: 0.35rem 0 0;
    font-size: 0.8125rem;
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
    color: var(--ink-soft);
}

input, select {
    width: 100%;
    padding: 0.85rem;
    font: inherit;
    color: inherit;
    background: var(--paper-lift);
    border: 1px solid var(--ink-line);
    border-radius: var(--radius);
    /* 16px minimum stops iOS Safari zooming on focus. */
    font-size: max(1rem, 16px);
}
.panel input, .panel select { background: #fff; }
input:hover, select:hover { border-color: var(--ink); }
input:disabled, select:disabled {
    color: var(--ink-soft);
    background: var(--paper-deep);
    cursor: not-allowed;
}

/* Tick boxes are not text fields — the 100% width above would stretch one into
 * a stripe across the page. The label sits beside it, in sentence case, and the
 * whole pair is at least 44px tall so it is a comfortable touch target. */
input[type="checkbox"], input[type="radio"] {
    width: auto;
    min-width: 1.375rem;
    min-height: 1.375rem;
    margin: 0;
    accent-color: var(--ink);
}

.checkline {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-height: 44px;
    margin-top: 1.5rem;
}
.checkline label {
    margin: 0;
    font-size: 0.9375rem;
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
}

form .btn { margin-top: 1.75rem; width: 100%; }

.form-aside {
    margin-top: 1.5rem;
    font-size: 0.875rem;
}

.privacy {
    margin-top: 1.5rem;
    font-size: 0.8125rem;
    color: var(--ink-soft);
}

/* Search / filter row above the user list. */
.filters {
    display: grid;
    gap: 0.75rem;
    margin-bottom: 1.5rem;
}
.filters label { margin-top: 0; }
.filters .btn { margin-top: 0; width: 100%; }

/* --- Notices ------------------------------------------------------------ */
.notice {
    margin: var(--gap) 0;
    padding: var(--gap);
    border-left: 3px solid;
    background: var(--paper-lift);
}
.notice ul { margin: 0; padding-left: 1.25rem; }
.notice li + li { margin-top: 0.35rem; }
.notice > :last-child { margin-bottom: 0; }
.notice--error { border-color: var(--error); }
.notice--ok    { border-color: var(--ok); }
.notice--warn  { border-color: var(--paper-deep); }

/* --- The user list ------------------------------------------------------
 * A real table, because it is real tabular data and a screen reader should be
 * told so. On a phone it scrolls sideways inside its own box rather than
 * squeezing the page — tabbable and labelled so that is discoverable.
 */
.table-wrap {
    overflow-x: auto;
    border: 1px solid var(--ink-line);
    border-radius: var(--radius);
    background: var(--paper-lift);
}

table {
    width: 100%;
    min-width: 40rem;
    border-collapse: collapse;
    font-size: 0.9375rem;
}

caption {
    padding: 0.75rem 1rem;
    text-align: left;
    font-size: 0.8125rem;
    color: var(--ink-soft);
    border-bottom: 1px solid var(--ink-line);
}

th, td {
    padding: 0.75rem 1rem;
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--ink-line);
}

thead th {
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    white-space: nowrap;
}

tbody tr:last-child th,
tbody tr:last-child td { border-bottom: 0; }

td .row-actions {
    display: flex;
    gap: 0.5rem;
    white-space: nowrap;
}

.row-name { font-weight: 600; }
.row-email { font-size: 0.875rem; color: var(--ink-soft); word-break: break-word; }

/* --- Small labels ------------------------------------------------------- */
.pill {
    display: inline-block;
    padding: 0.2rem 0.6rem;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    white-space: nowrap;
    border: 1px solid var(--ink-line);
    border-radius: 999px;
}
.pill--admin      { color: var(--paper); background: var(--ink); border-color: var(--ink); }
.pill--management { background: var(--paper-deep); }
.pill--suspended  { color: #fff; background: var(--error); border-color: var(--error); }

/* --- Definition pairs on the dashboard ---------------------------------- */
.facts { margin: 0; }
.facts dt {
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--ink-soft);
}
.facts dd {
    margin: 0.25rem 0 1rem;
    font-family: var(--font-display);
    font-size: 1.25rem;
}
.facts dd:last-child { margin-bottom: 0; }

/* --- Metrics: headline figures ------------------------------------------
 * Four tiles. On a phone they are two by two rather than a single column —
 * these are numbers to compare at a glance, and a column makes that a scroll.
 */
.stats {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.75rem;
    margin: 0 0 0.75rem;
}

.stat {
    padding: 1rem;
    background: var(--paper-lift);
    border: 1px solid var(--ink-line);
    border-radius: var(--radius);
}

.stat dt {
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-soft);
}

.stat dd {
    margin: 0.35rem 0 0;
    font-family: var(--font-display);
    font-size: clamp(1.75rem, 8vw, 2.5rem);
    line-height: 1.05;
    /* Tabular figures so the four tiles line up rather than shuffling about. */
    font-variant-numeric: tabular-nums;
}

.stats__note {
    max-width: var(--measure);
    margin-bottom: 2rem;
    font-size: 0.8125rem;
    color: var(--ink-soft);
}

/* --- Metrics: date range ------------------------------------------------- */
.range-presets {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1rem;
}
.range-presets .btn { width: auto; }
.range-presets [aria-current="true"] {
    color: var(--paper);
    background: var(--ink);
    border-color: var(--ink);
}

.range-said {
    margin-bottom: 1.5rem;
    font-size: 0.9375rem;
}

/* --- Metrics: charts -----------------------------------------------------
 * The drawings are inline SVG with percentage geometry and no viewBox, so they
 * fill whatever box these rules give them while their rounded corners stay in
 * real pixels. See includes/chart.php. Nothing here may become an inline style:
 * the CSP forbids those, which is the whole reason the geometry lives in SVG
 * attributes in the first place.
 */
.chart-block { margin-bottom: 2.5rem; }
.chart-block h2 { margin-bottom: 0.35rem; }

.chart__note {
    max-width: var(--measure);
    margin: 0 0 1rem;
    font-size: 0.8125rem;
    color: var(--ink-soft);
}

/* The rule the columns stand on, so a day with no traffic reads as a zero
   rather than as a missing bar. */
.chart {
    height: 9rem;
    padding-bottom: 1px;
    border-bottom: 1px solid var(--ink-line);
}
.chart--short { height: 6rem; }

.chart__svg {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
}

.chart__col { fill: var(--ink); }

.chart__axis {
    display: flex;
    justify-content: space-between;
    margin: 0.4rem 0 1rem;
    font-size: 0.75rem;
    color: var(--ink-soft);
}

.chart__bar {
    display: block;
    width: 100%;
    height: 0.625rem;
}
.chart__track { fill: var(--paper-deep); }
.chart__fill  { fill: var(--ink); }
/* Machines, in the one chart that shows them beside people. The label carries
   the meaning; this only stops the eye reading four identical bars as one
   quantity. Never colour alone. */
.chart__fill--muted { fill: var(--ink-soft); }

.chart__data {
    margin-top: 1rem;
    font-size: 0.875rem;
}
.chart__data summary {
    padding: 0.5rem 0;
    cursor: pointer;
    font-weight: 600;
}
.chart__data .table-wrap { margin-top: 0.5rem; }

.cell-bar { width: 40%; min-width: 6rem; vertical-align: middle; }

/* --- Metrics: labelled bars ---------------------------------------------
 * Label, bar, value. The bar is aria-hidden — the number is right there as
 * text, so announcing the drawing would read the row twice.
 */
.meters {
    margin: 0 0 1rem;
    padding: 0;
    list-style: none;
}

.meter {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 0.25rem 0.75rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--ink-line);
}
.meter:last-child { border-bottom: 0; }

.meter__label { font-size: 0.9375rem; }

.meter__value {
    font-size: 0.9375rem;
    font-variant-numeric: tabular-nums;
    text-align: right;
    white-space: nowrap;
}

/* The bar drops to its own full-width row on a phone, where a three-column
   layout would leave it a few millimetres wide and useless. */
.meter__track { grid-column: 1 / -1; }

.plain-list {
    margin: 0.5rem 0;
    padding-left: 1.25rem;
}
.plain-list--split { columns: 2; }

/* --- Footer ------------------------------------------------------------- */
.admin-foot {
    max-width: var(--shell);
    margin: 0 auto;
    padding: 1.5rem 1.25rem 2.5rem;
    border-top: 1px solid var(--ink-line);
    font-size: 0.8125rem;
    color: var(--ink-soft);
}
.admin-foot p { margin: 0 0 0.5rem; }
.admin-foot__note { max-width: var(--measure); }

/* --- Wider screens ------------------------------------------------------ */
@media (min-width: 40rem) {
    form .btn { width: auto; }

    .filters {
        grid-template-columns: 2fr 1fr 1fr auto;
        align-items: end;
    }
    .filters .btn { width: auto; }

    /* Two dates and a button, not the user list's four columns. */
    .filters--range { grid-template-columns: 1fr 1fr auto; }

    .panel { padding: 1.75rem; }

    .stats { grid-template-columns: repeat(4, 1fr); }

    /* Enough width for the bar to sit between the label and the value. */
    .meter {
        grid-template-columns: 10rem 1fr 8rem;
        gap: 0.75rem 1rem;
    }
    .meter__track { grid-column: auto; }
}

@media (min-width: 52rem) {
    .admin-bar__inner { flex-wrap: nowrap; padding-block: 1rem; }
    .admin-nav { width: auto; flex-wrap: nowrap; }
    .admin-nav__out { margin-left: 1rem; }

    .facts--grid {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        gap: 0 1.5rem;
    }
}

/* --- Respect user preferences ------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}
