/* ==========================================================================
   IsItOpn?  —  admin styles

   Loads on top of main.css and reuses its tokens, so light/dark and the
   contrast work already done there carry straight over.
   ========================================================================== */

body.admin {
    background: var(--page);
}

.admin-main {
    max-width: 1100px;
    margin: 0 auto;
    padding: 1rem 0.8rem 4rem;
}

/* --------------------------------------------------------------------------
   Top bar
   -------------------------------------------------------------------------- */
.admin-bar {
    background: var(--surface);
    border-bottom: 1px solid var(--rule);
    position: sticky;
    top: 0;
    z-index: 5;
}
.admin-bar-inner {
    max-width: 1100px;
    margin: 0 auto;
    padding: 0.6rem 0.8rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem 1rem;
}
.admin-brand {
    font-weight: 700;
    font-size: 1.1rem;
    text-decoration: none;
    color: var(--ink);
}
.admin-tag {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ink-muted);
    font-weight: 600;
}
.admin-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 0.15rem 0.9rem;
    flex: 1 1 auto;
}
.admin-nav a {
    text-decoration: none;
    padding: 0.35em 0;
    font-size: 0.95rem;
}
.admin-nav a:hover { text-decoration: underline; }
.admin-nav a[aria-current="page"] {
    font-weight: 700;
    color: var(--ink);
    border-bottom: 2px solid var(--link);
}
.admin-user {
    display: flex;
    align-items: center;
    gap: 0.8rem;
    font-size: 0.85rem;
    color: var(--ink-muted);
}
.admin-link { text-decoration: none; }
.admin-link:hover { text-decoration: underline; }
.role-tag {
    display: inline-block;
    font-size: 0.72rem;
    background: var(--surface-alt);
    border: 1px solid var(--rule);
    border-radius: 999px;
    padding: 0.05em 0.55em;
    margin-left: 0.2em;
}

/* --------------------------------------------------------------------------
   Panels
   -------------------------------------------------------------------------- */
.panel {
    background: var(--surface);
    border: 1px solid var(--rule);
    border-radius: 8px;
    padding: 1rem;
    margin-bottom: 1rem;
}
.panel h1 { font-size: 1.3rem; }
.panel h2 { font-size: 1.05rem; margin-top: 0; }
.panel h3 { font-size: 0.95rem; }

.panel-head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.6rem;
    margin-bottom: 0.6rem;
}
.panel-head h1, .panel-head h2 { margin: 0; }

.panel.danger { border-color: var(--closed); }
.danger-button {
    background: var(--closed);
    color: #fff;
}
.danger-button:hover { background: var(--closed); opacity: 0.85; color: #fff; }

.help {
    font-size: 0.85rem;
    color: var(--ink-muted);
    margin: 0.3em 0 0.8em;
    max-width: 70ch;
}

.sticky-actions {
    position: sticky;
    bottom: 0.5rem;
    display: flex;
    gap: 0.6rem;
    box-shadow: 0 4px 18px rgb(0 0 0 / 0.14);
}

/* --------------------------------------------------------------------------
   Stats
   -------------------------------------------------------------------------- */
.stat-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 0.7rem;
    margin: 0.8rem 0;
}
.stat {
    background: var(--surface-alt);
    border-radius: 6px;
    padding: 0.7rem;
}
.stat-n { display: block; font-size: 1.6rem; font-weight: 700; line-height: 1.1; }
.stat-l { display: block; font-size: 0.8rem; color: var(--ink-muted); }
.stat-alert { background: var(--notice-bg); }
.stat-alert .stat-n, .stat-alert .stat-l { color: var(--notice-ink); }

/* --------------------------------------------------------------------------
   Tables
   -------------------------------------------------------------------------- */
.admin-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.92rem;
}
.admin-table th, .admin-table td {
    text-align: left;
    padding: 0.55em 0.5em;
    border-bottom: 1px solid var(--rule);
    vertical-align: top;
}
.admin-table thead th {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--ink-muted);
    border-bottom-width: 2px;
}
.admin-table tbody th { font-weight: 600; }
.admin-table.compact th, .admin-table.compact td { padding: 0.35em 0.5em; }
.admin-table .is-today th, .admin-table .is-today td { font-weight: 700; }
.admin-table td a + a { margin-left: 0.7em; }
.nowrap { white-space: nowrap; }

/* Tables scroll rather than forcing the page sideways on a phone. */
@media (max-width: 640px) {
    .panel { overflow-x: auto; }
}

.pill {
    display: inline-block;
    font-size: 0.72rem;
    font-weight: 600;
    border-radius: 999px;
    padding: 0.1em 0.6em;
    background: var(--surface-alt);
    border: 1px solid var(--rule);
    color: var(--ink-muted);
}
.pill-ok   { background: var(--ok-bg);     color: var(--ok-ink);     border-color: transparent; }
.pill-warn { background: var(--notice-bg); color: var(--notice-ink); border-color: transparent; }
.pill-off  { background: var(--err-bg);    color: var(--err-ink);    border-color: transparent; }

.report-details {
    margin: 0.3em 0 0;
    font-size: 0.9rem;
}

.tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.2rem 1rem;
    margin-bottom: 0.8rem;
    border-bottom: 1px solid var(--rule);
}
.tabs a {
    text-decoration: none;
    padding: 0.4em 0;
    font-size: 0.9rem;
}
.tabs a[aria-current="page"] {
    font-weight: 700;
    color: var(--ink);
    border-bottom: 2px solid var(--link);
}

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */
.stacked fieldset, .hours-form fieldset {
    border: 1px solid var(--rule);
    border-radius: 6px;
    padding: 0.8rem;
    margin: 0 0 1rem;
}
legend {
    font-weight: 600;
    font-size: 0.9rem;
    padding: 0 0.4em;
}

.field { margin-bottom: 0.8rem; }
.field label, .label-like {
    display: block;
    font-size: 0.85rem;
    font-weight: 600;
    margin-bottom: 0.25em;
}
.field input, .field select, .field textarea { width: 100%; }
.field .help { margin: 0.3em 0 0; }

.field-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.7rem;
    align-items: flex-end;
}
.field-row .field { flex: 1 1 10rem; margin-bottom: 0.8rem; }
.field-row .field-narrow { flex: 0 1 7rem; }

.inline-form {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    align-items: center;
    margin-bottom: 0.8rem;
}

.checkbox {
    display: inline-flex;
    align-items: baseline;
    gap: 0.4em;
    font-size: 0.92rem;
    font-weight: 400;
    margin-bottom: 0.4em;
    cursor: pointer;
}
.checkbox input { width: auto; min-height: 0; }
.checkbox.tight { margin-bottom: 0; font-size: 0.85rem; }

.checkbox-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: 0.2rem 0.8rem;
}

.form-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin-top: 0.5rem;
}

/* Front-door map in the location editor. .map-frame comes from main.css — the
   frame is reused so the editor and the public page show the same thing at the
   same aspect ratio; only the height is trimmed to suit a form. */
.admin-map { margin-bottom: 0.8rem; }
.admin-map .map-frame { max-height: 22rem; }

/* Expanded by the ⤢ control, because 22rem of map is not much to pick one side
   of a building in. The whole block goes over the page rather than just the
   frame, so the status line and the off-site links come with it; the frame then
   takes whatever height is left instead of its own aspect ratio. */
.admin-map.is-expanded {
    position: fixed;
    inset: 0;
    z-index: 20;
    display: flex;
    flex-direction: column;
    margin: 0;
    padding: 0.8rem;
    background: var(--surface);
}
.admin-map.is-expanded .map-frame {
    flex: 1 1 auto;
    min-height: 0;
    max-height: none;
    aspect-ratio: auto;
}
body.map-expanded { overflow: hidden; }
.map-empty {
    margin: 0;
    padding: 3rem 1rem;
    text-align: center;
    font-size: 0.9rem;
    color: var(--ink-muted);
}
.map-tools {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
    margin: 0.5rem 0 0;
    font-size: 0.85rem;
}

/* The draggable map admin-map.js builds in place of the frame above. Tiles are
   absolutely positioned <img>s; everything else floats over them. */
.map-surface {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
    background: var(--surface-alt);
    cursor: grab;
    /* Panning is a drag, not a scroll — without this a touch drag scrolls the
       form out from under the map. */
    touch-action: none;
}
.map-surface.is-dragging { cursor: grabbing; }

.map-layer {
    position: absolute;
    inset: 0;
}
.map-tile {
    position: absolute;
    width: 256px;
    height: 256px;
    user-select: none;
    -webkit-user-drag: none;
}

/* The box's bottom centre is the coordinate; the teardrop is drawn to end
   there, so what the pin points at is what gets saved. */
.map-pin {
    position: absolute;
    width: 24px;
    height: 25px;
    margin: -25px 0 0 -12px;
    padding: 0;
    border: 0;
    min-height: 0;
    background: none;
    cursor: grab;
}
.map-pin:hover { background: none; }
.map-pin::before {
    content: "";
    position: absolute;
    left: 2px;
    top: 0;
    width: 20px;
    height: 20px;
    background: var(--closed);
    border: 2px solid #fff;
    border-radius: 50% 50% 50% 0;
    transform: rotate(-45deg);
    box-shadow: 0 1px 4px rgb(0 0 0 / 0.45);
}
.map-pin::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: 0;
    width: 4px;
    height: 4px;
    margin-left: -2px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 0 0 1px rgb(0 0 0 / 0.55);
}
.map-pin:focus-visible { outline: 3px solid var(--link); outline-offset: 3px; }

.map-zoom {
    position: absolute;
    top: 0.4rem;
    right: 0.4rem;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}
.map-zoom button {
    width: 2rem;
    min-height: 2rem;
    padding: 0;
    font-size: 1rem;
    line-height: 1;
    background: var(--surface);
    color: var(--ink);
    border: 1px solid var(--rule);
}
.map-zoom button:hover { background: var(--surface-alt); color: var(--ink); }

.map-credit {
    position: absolute;
    right: 0;
    bottom: 0;
    padding: 0 0.35em;
    font-size: 0.68rem;
    background: var(--surface);
    border-top-left-radius: 4px;
}

/* Reaching the weekly rota on a page that reads widest-layer-first. */
.jump-links {
    display: flex;
    flex-wrap: wrap;
    gap: 0.9rem;
    margin: 0;
    font-size: 0.85rem;
    color: var(--ink-muted);
}

.link-button {
    background: none;
    border: 0;
    color: var(--link);
    font: inherit;
    font-size: 0.85rem;
    padding: 0.2em 0;
    min-height: 0;
    cursor: pointer;
    text-decoration: underline;
}
.link-button:hover { background: none; color: var(--link-hover); }
.danger-link { color: var(--closed); }
.danger-link:hover { color: var(--closed); opacity: 0.8; }

@media (prefers-color-scheme: dark) {
    .link-button, .link-button:hover { color: var(--link); }
    .danger-link, .danger-link:hover { color: var(--closed); }
}

/* --------------------------------------------------------------------------
   Hours editor
   -------------------------------------------------------------------------- */
.days {
    display: grid;
    gap: 0.7rem;
}
@media (min-width: 780px) {
    .days { grid-template-columns: 1fr 1fr; }
}

.day-panel {
    border: 1px solid var(--rule);
    border-radius: 6px;
    padding: 0.7rem;
    background: var(--surface-alt);
}
.day-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.4rem;
    margin-bottom: 0.4rem;
}
.day-head h3 { margin: 0; }
.day-actions { display: flex; gap: 0.8rem; }

.hours-rows { display: grid; gap: 0.4rem; }
.hours-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    background: var(--surface);
    border: 1px solid var(--rule);
    border-radius: 4px;
    padding: 0.4rem;
}
.hours-row input[type="time"] {
    min-height: 38px;
    padding: 0.3em 0.4em;
    flex: 0 1 auto;
    width: auto;
}
.hours-row .to { color: var(--ink-muted); font-size: 0.85rem; }

.closed-note {
    color: var(--ink-muted);
    font-size: 0.9rem;
    font-style: italic;
    margin: 0.2em 0;
}

.copy-panel { margin-top: 0.6rem; }
.copy-panel fieldset { margin-bottom: 0; background: var(--surface); }
.copy-days {
    display: flex;
    flex-wrap: wrap;
    gap: 0.2rem 0.7rem;
    margin-bottom: 0.5rem;
}
.copy-shortcuts {
    display: flex;
    flex-wrap: wrap;
    gap: 0.8rem;
    margin-bottom: 0.6rem;
}
.copy-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
}
.copy-status {
    font-size: 0.82rem;
    color: var(--ok-ink);
}

/* A wide screen has room for a whole day on one line — day name, the hours
   themselves, then the day's actions — so the week reads as seven rows rather
   than two columns of stacked panels. `display: contents` promotes the head's
   two children into the panel's own flex row, which is what lets the day name
   sit before the hours and the actions after them without moving any markup.
   It has to come after the rules it overrides: a media query adds no
   specificity, so a plain `.day-head` further down the file would win. */
@media (min-width: 1000px) {
    .days { grid-template-columns: 1fr; gap: 0.45rem; }

    .day-panel {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 0.5rem 0.9rem;
        padding: 0.45rem 0.7rem;
    }
    .day-head {
        display: contents;
        margin-bottom: 0;
    }
    .day-head h3 {
        order: 1;
        flex: 0 0 7rem;
        margin: 0;
    }
    .day-panel .hours-rows {
        order: 2;
        flex: 1 1 auto;
    }
    .day-panel .hours-row {
        border: 0;
        background: none;
        padding: 0;
        flex-wrap: nowrap;
    }
    .day-panel .closed-note { margin: 0; }
    .day-actions {
        order: 3;
        flex: 0 0 auto;
        margin-left: auto;
    }
    .copy-panel {
        order: 4;
        flex: 1 0 100%;
        margin-top: 0.2rem;
    }
}

.repeat-list { display: grid; gap: 0.7rem; margin-bottom: 0.7rem; }
.repeat-item {
    border: 1px solid var(--rule);
    border-radius: 6px;
    padding: 0.7rem;
    background: var(--surface-alt);
}
.repeat-item .field-row:last-child { margin-bottom: 0; }
.repeat-item .field-row .field { margin-bottom: 0.5rem; }

.inline-fieldset {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.2rem 0.7rem;
    margin-bottom: 0.6rem !important;
    padding: 0.5rem 0.7rem !important;
    background: var(--surface);
}
.inline-fieldset legend { font-size: 0.82rem; }

.ex-hours { margin: 0.5rem 0; }

.repeat-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-bottom: 0.4rem;
    align-items: center;
}
.repeat-row select { flex: 0 1 9rem; }
.repeat-row input { flex: 1 1 12rem; }

/* --------------------------------------------------------------------------
   Bulk editor
   -------------------------------------------------------------------------- */
.bulk-search { align-items: flex-end; }
.bulk-search .field { margin-bottom: 0; }

.tick-col { width: 2.2rem; }
.tick-col .checkbox { margin: 0; }

/* Two or three fields abreast on a wide screen, one on a phone: each is a
   checkbox that arms the control beneath it, so they have to stay paired. */
.bulk-fields {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: 0.7rem 1rem;
}
.bulk-field {
    border: 1px solid var(--rule);
    border-radius: 6px;
    padding: 0.6rem;
    background: var(--surface-alt);
}
.bulk-field .checkbox { font-weight: 600; margin-bottom: 0.35em; }
.bulk-field .bulk-control input,
.bulk-field .bulk-control select,
.bulk-field .bulk-control textarea { width: 100%; }
.bulk-field .help { margin: 0.4em 0 0; }

/* --------------------------------------------------------------------------
   Activity log
   -------------------------------------------------------------------------- */
.audit-filter {
    align-items: flex-end;
    margin-bottom: 1rem;
}
.audit-filter .field { margin-bottom: 0; }

/* A date input carries its own picker and placeholder, so it will not shrink
   to the width .field-narrow allows without clipping them. */
.audit-filter .field-date { flex: 0 1 10.5rem; }

.audit-filter .filter-actions {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 0.7rem;
}

/* The linked record and the free-text detail are two separate facts about an
   entry — stacked, they stay legible where a bulk edit lists eighty ids. */
.audit-target { display: block; }
.audit-detail { display: block; }
.audit-target + .audit-detail { margin-top: 0.15em; }

/* The id qualifies the name beside it rather than competing with it: quieter
   than the name, and outside the link so what is clickable stays the record. */
.record-id {
    color: var(--ink-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* --------------------------------------------------------------------------
   Login
   -------------------------------------------------------------------------- */
body.admin-plain {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: 1rem;
}
.login-card {
    background: var(--surface);
    border: 1px solid var(--rule);
    border-radius: 10px;
    padding: 1.6rem;
    width: 100%;
    max-width: 22rem;
}
.login-card h1 { margin-bottom: 0.1em; }
.login-card .field { margin-bottom: 1rem; }
.login-card button { width: 100%; }
.login-card .back { margin-top: 1rem; font-size: 0.85rem; }
