/*
 * The admin. Utilitarian, but built for a thumb first.
 *
 * The published site does not use any of this — it has its own hand-written CSS
 * under assets/site/, copied and content-hashed by site:build. Keeping them apart
 * means the admin can change without republishing anything.
 */

:root {
    /* Muted and earthy, a quiet relative of the published site's palette rather
       than a copy of it — this is the workshop, not the room. */
    --ground: #16181a;
    --raised: #1e2124;
    --raised-high: #272b2f;
    --rule: #343a3f;
    --ink: #e8e6e1;
    --ink-dim: #9aa0a2;
    --leaf: #7a8b5a;
    --leaf-bright: #9db071;
    --bark: #8a6a4a;
    --alarm: #c9553d;

    --radius: 6px;
    --gap: 1rem;
    /* Below this, nothing is reliably hittable with a thumb. Apple and Google
       both land on ~44px; this is that, in rem so it scales with text size. */
    --tap: 2.75rem;

    --font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --mono: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, monospace;
}

@media (prefers-color-scheme: light) {
    :root {
        --ground: #f4f2ec;
        --raised: #fffefa;
        --raised-high: #ebe8df;
        --rule: #d3cec1;
        --ink: #22201c;
        --ink-dim: #62605a;
        --leaf: #5d7040;
        --leaf-bright: #46592c;
        --bark: #6e5236;
    }
}

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

body {
    margin: 0;
    /* Room for the fixed bottom nav plus the home-indicator strip on a modern
       phone, so the last row of a list is never trapped underneath it. */
    padding-bottom: calc(var(--tap) + env(safe-area-inset-bottom) + 1rem);
    background: var(--ground);
    color: var(--ink);
    font-family: var(--font);
    font-size: 1rem;
    line-height: 1.5;
    -webkit-text-size-adjust: 100%;
}

/* ---- app bar ---- */

.app-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gap);
    padding: 0.75rem 1rem;
    padding-top: calc(0.75rem + env(safe-area-inset-top));
    background: var(--raised);
    border-bottom: 1px solid var(--rule);
    position: sticky;
    top: 0;
    z-index: 10;
}

.app-bar__brand {
    color: var(--leaf-bright);
    font-weight: 700;
    letter-spacing: 0.02em;
    text-decoration: none;
}

.app-main {
    max-width: 46rem;
    margin: 0 auto;
    padding: var(--gap);
}

/* ---- bottom navigation ---- */

.app-nav {
    position: fixed;
    inset: auto 0 0 0;
    display: flex;
    background: var(--raised);
    border-top: 1px solid var(--rule);
    padding-bottom: env(safe-area-inset-bottom);
    z-index: 10;
}

.app-nav__item {
    flex: 1;
    min-height: var(--tap);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--ink-dim);
    text-decoration: none;
    font-size: 0.875rem;
}

.app-nav__item.is-current {
    color: var(--leaf-bright);
    box-shadow: inset 0 2px 0 var(--leaf);
}

@media (min-width: 48rem) {
    body { padding-bottom: 0; }

    .app-nav {
        position: static;
        border-top: 0;
        border-bottom: 1px solid var(--rule);
        justify-content: center;
        gap: 1rem;
    }

    .app-nav__item { flex: 0 0 auto; padding: 0 1rem; }
}

/* ---- forms ---- */

.field { display: block; margin-bottom: 1.25rem; }

.field__label {
    display: block;
    margin-bottom: 0.375rem;
    font-size: 0.8125rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-dim);
}

.field__hint {
    margin: 0.375rem 0 0;
    font-size: 0.8125rem;
    color: var(--ink-dim);
}

input[type="text"],
input[type="password"],
input[type="date"],
input[type="datetime-local"],
input[type="number"],
input[type="search"],
select,
textarea {
    width: 100%;
    min-height: var(--tap);
    padding: 0.625rem 0.75rem;
    background: var(--raised);
    color: var(--ink);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    /* Never below 16px. iOS Safari zooms the viewport on focus for anything
       smaller, and then leaves you scrolled sideways in the middle of a sentence. */
    font-size: 1rem;
    font-family: inherit;
}

textarea { min-height: 12rem; resize: vertical; line-height: 1.6; }

input:focus-visible,
select:focus-visible,
textarea:focus-visible,
button:focus-visible,
a:focus-visible {
    outline: 2px solid var(--leaf-bright);
    outline-offset: 2px;
}

.checkbox {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    min-height: var(--tap);
}

.checkbox input { width: 1.25rem; height: 1.25rem; accent-color: var(--leaf); }

/* ---- buttons ---- */

.button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: var(--tap);
    padding: 0 1.125rem;
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    background: var(--raised-high);
    color: var(--ink);
    font: inherit;
    text-decoration: none;
    cursor: pointer;
}

.button--primary {
    background: var(--leaf);
    border-color: var(--leaf);
    color: #12140f;
    font-weight: 600;
}

.button--danger { color: var(--alarm); border-color: var(--alarm); background: transparent; }

.button--block { width: 100%; }

.button-row { display: flex; flex-wrap: wrap; gap: 0.625rem; margin-top: 1.5rem; }

/* ---- flashes ---- */

.flash {
    margin: 0 0 var(--gap);
    padding: 0.75rem 1rem;
    border-radius: var(--radius);
    border-left: 3px solid var(--leaf);
    background: var(--raised);
}

.flash--error { border-left-color: var(--alarm); }

/* ---- lists and cards ---- */

.card {
    background: var(--raised);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    padding: var(--gap);
    margin-bottom: var(--gap);
}

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

.post-list__item { border-bottom: 1px solid var(--rule); }

.post-list__link {
    display: block;
    /* The whole row is the target, not just the title text. */
    padding: 0.875rem 0.25rem;
    color: inherit;
    text-decoration: none;
}

.post-list__title { display: block; font-weight: 600; }

.post-list__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.25rem;
    font-size: 0.8125rem;
    color: var(--ink-dim);
}

.pill {
    display: inline-block;
    padding: 0.0625rem 0.5rem;
    border: 1px solid var(--rule);
    border-radius: 999px;
    font-size: 0.75rem;
    letter-spacing: 0.04em;
}

.pill--published { color: var(--leaf-bright); border-color: var(--leaf); }
.pill--draft { color: var(--bark); border-color: var(--bark); }
.pill--failed { color: var(--alarm); border-color: var(--alarm); }

.empty {
    padding: 2rem 1rem;
    text-align: center;
    color: var(--ink-dim);
}

/* ---- login ---- */

.login {
    display: flex;
    min-height: 100dvh;
    align-items: center;
    justify-content: center;
    padding: var(--gap);
}

.login__card { width: 100%; max-width: 22rem; }

/* ---- build indicator ---- */

.build-status { display: flex; align-items: center; gap: 0.5rem; font-size: 0.8125rem; }

.build-status__dot {
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: var(--ink-dim);
    flex: none;
}

.build-status--running .build-status__dot { background: var(--bark); animation: pulse 1.4s ease-in-out infinite; }
.build-status--success .build-status__dot { background: var(--leaf-bright); }
.build-status--failed .build-status__dot { background: var(--alarm); }

@keyframes pulse { 50% { opacity: 0.25; } }

@media (prefers-reduced-motion: reduce) {
    .build-status--running .build-status__dot { animation: none; }
}

.field--invalid input,
.field--invalid textarea,
.field--invalid select { border-color: var(--alarm); }

.field__errors {
    margin: 0.375rem 0 0;
    padding-left: 1.1rem;
    color: var(--alarm);
    font-size: 0.8125rem;
}

details.card > summary {
    cursor: pointer;
    min-height: var(--tap);
    display: flex;
    align-items: center;
    font-size: 0.8125rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-dim);
}

.build-status__error {
    margin: 0.5rem 0 0;
    padding: 0.75rem;
    overflow-x: auto;
    background: var(--ground);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    font-size: 0.75rem;
    white-space: pre-wrap;
    word-break: break-word;
}

/* ---- poem editor ----
 *
 * Side by side on a desktop, stacked on a phone with the preview under the text.
 * Not a toggle: the whole point of this template is watching the shape appear as
 * you type, and hiding one behind the other loses that.
 */

.poem-editor { display: grid; gap: var(--gap); margin-bottom: 1.5rem; }

@media (min-width: 60rem) {
    .poem-editor { grid-template-columns: 1fr 1fr; align-items: start; }
    /* Sticks while the textarea scrolls, so the shape stays in view on a long poem. */
    .poem-editor__pane:last-child { position: sticky; top: 4.5rem; }
}

/* Grid children default to min-width:auto, which means they refuse to shrink below
   their content — and a poem line does not wrap, so one long line pushed the whole
   admin sideways and put a scrollbar on the page. The pane scrolls instead. */
.poem-editor__pane { min-width: 0; }

.poem-editor__input {
    /* Monospace is not a preference here — it is what makes lining anything up
       possible, and it is the geometry the renderer reproduces. */
    font-family: var(--mono);
    font-size: 1rem;
    line-height: 1.6;
    /* No wrapping: a wrapped line hides the fact that it is one line, and the
       leading spaces of the next visual row are not real. */
    white-space: pre;
    overflow-x: auto;
    tab-size: 4;
    min-height: 20rem;
}

.poem-preview {
    /* The preview scrolls on its own rather than stretching the page. */
    overflow-x: auto;
    padding: var(--gap);
    background: var(--ground);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    min-height: 20rem;
}

/* The preview is showing older text than the textarea. Better to look wrong than
   to look current. */
.poem-preview.is-stale { opacity: 0.5; }

.poem-preview__paper img { max-width: 100%; height: auto; }

.poem-preview__paper {
    /* Approximates the published page rather than matching it exactly. Matching
       would mean loading the site's stylesheet into the admin and keeping two
       cascades from fighting; the shape is what is being checked here. */
    font-family: var(--serif, Iowan Old Style, Palatino, Georgia, serif);
    line-height: 1.9;
    font-variant-numeric: tabular-nums lining-nums;
}

.poem-preview__paper .poem__line { margin: 0; padding-left: var(--indent, 0); white-space: nowrap; transform: translateX(var(--drift, 0)); }
.poem-preview__paper .poem__line--blank { height: 1.9em; }
.poem-preview__paper .poem__gap { display: inline-block; width: calc(var(--columns) * 1ch); }
.poem-preview__paper .poem__rot, .poem-preview__paper .poem__scale { display: inline-block; }
.poem-preview__paper .poem__rot { transform: rotate(var(--rot)); }
.poem-preview__paper .poem__scale { transform: scale(var(--scale)); }
.poem-preview__paper .poem__rot.poem__scale { transform: rotate(var(--rot)) scale(var(--scale)); }
.poem-preview__paper .poem__fade { opacity: 0.55; }
.poem-preview__paper .poem__space { width: 100%; }
.poem-preview__paper .poem__slot {
    margin: 1rem 0;
    padding: 1rem;
    border: 1px dashed var(--rule);
    border-radius: var(--radius);
    color: var(--ink-dim);
    font-family: var(--font);
    font-size: 0.8125rem;
    text-align: center;
}

/* Notes, not alarms: an unclosed {fade} is what "{fade}" looks like one second
   after you type it. */
.poem-preview__notes {
    margin: 0 0 var(--gap);
    padding-left: 1.1rem;
    font-size: 0.8125rem;
    color: var(--ink-dim);
}

.poem-preview__line { color: var(--bark); font-variant-numeric: tabular-nums; }
.poem-preview__error { color: var(--alarm); font-size: 0.8125rem; }

.poem-help { margin: 0; font-size: 0.875rem; }
.poem-help dt { margin-top: 0.75rem; }
.poem-help dt code { color: var(--leaf-bright); font-family: var(--mono); font-size: 0.8125rem; }
.poem-help dd { margin: 0.125rem 0 0; color: var(--ink-dim); }

/* ---- travelogue editor ---- */

.stops { list-style: none; margin: 1rem 0; padding: 0; }

.stop {
    display: flex;
    gap: 0.75rem;
    padding: 0.75rem 0;
    border-top: 1px solid var(--rule);
}

.stop__thumb {
    width: 72px;
    height: 72px;
    object-fit: cover;
    border-radius: var(--radius);
    flex: none;
    background: var(--raised-high);
}

.stop__body { flex: 1; min-width: 0; }

.stop__unlocated {
    margin: 0 0 0.5rem;
    font-size: 0.8125rem;
    color: var(--bark);
}

.stop__label, .stop__note { margin-bottom: 0.5rem; }

.stop__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0 0 0.5rem;
    font-size: 0.75rem;
    color: var(--ink-dim);
}

.stop__coords { font-variant-numeric: tabular-nums; }

.stop-add { margin-top: 1.5rem; }
.stop-add__coords { display: flex; gap: 0.5rem; margin-bottom: 0.75rem; }

/* The capture screen's main action. Deliberately large: it gets pressed with a
   thumb, outdoors, often while walking. */
.capture__add { font-size: 1.125rem; min-height: 3.5rem; margin-bottom: 1rem; }

.stops--compact .stop__form, .stops--compact .stop__note { display: none; }
.stops--compact .stop { padding: 0.5rem 0; }

[data-photo-queue-target="status"].is-error { color: var(--alarm); }


/* The shared map stylesheet asks for its colours through --map-* tokens rather
   than reaching into either palette, because the admin and the site name their
   colours differently. This is the admin's answer. */
.route-map {
    --map-context: var(--rule);
    --map-route: var(--leaf);
    --map-here: var(--bark);
    --map-paper: var(--ground);
    --map-ink: var(--ink-dim);
    --map-font: var(--font);

    margin: 1rem 0 0;
}

/* ---- place search ---- */

.stop-add { margin-top: 1.5rem; padding-top: 1.5rem; border-top: 1px solid var(--rule); }
.stop-add__heading { margin: 0 0 1rem; font-size: 1rem; }

.stop-add__coords { margin-bottom: 1.25rem; }
.stop-add__coords > summary {
    cursor: pointer;
    min-height: var(--tap);
    display: flex;
    align-items: center;
    font-size: 0.8125rem;
    color: var(--ink-dim);
}
.stop-add__pair { display: flex; gap: 0.75rem; }
.stop-add__pair .field { flex: 1; }

.place__status { margin: 0 0 0.5rem; font-size: 0.8125rem; color: var(--ink-dim); min-height: 1.2em; }

.place__results { list-style: none; margin: 0 0 1rem; padding: 0; }

.place__result {
    display: block;
    width: 100%;
    /* A whole row, hittable with a thumb — these are chosen from on a phone. */
    min-height: var(--tap);
    padding: 0.625rem 0.75rem;
    text-align: left;
    background: var(--raised-high);
    color: var(--ink);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    margin-bottom: 0.375rem;
    font: inherit;
    font-size: 0.875rem;
    cursor: pointer;
}

.place__result:hover { border-color: var(--leaf); }

/* ---- poem cheat sheet ----
 *
 * Sits under the textarea, always visible. Quiet enough not to compete with the
 * writing, close enough that remembering a directive is a glance rather than a
 * click.
 */

.cheatsheet {
    margin-top: 0.75rem;
    padding: 0.875rem 1rem;
    background: var(--ground);
    border: 1px solid var(--rule);
    border-radius: var(--radius);
    font-size: 0.8125rem;
    color: var(--ink-dim);
}

.cheatsheet__lead { margin: 0 0 0.75rem; }

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

.cheatsheet__list li {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: baseline;
    margin-bottom: 0.375rem;
}

.cheatsheet code {
    font-family: var(--mono);
    font-size: 0.75rem;
    color: var(--leaf-bright);
    white-space: nowrap;
}

.cheatsheet__note { margin: 0.75rem 0 0; }

@media (min-width: 60rem) {
    /* Two columns once there is room, so it stays one glance rather than a list
       that pushes the preview down the page. */
    .cheatsheet__list { columns: 2; column-gap: 1.5rem; }
    .cheatsheet__list li { break-inside: avoid; }
}

/* ---- poem image slots ---- */

.slots { list-style: none; margin: 0 0 1rem; padding: 0; }

.slot {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0;
    border-top: 1px solid var(--rule);
}

.slot__thumb {
    width: 56px;
    height: 56px;
    object-fit: cover;
    border-radius: var(--radius);
    flex: none;
    background: var(--raised-high);
}

.slot__body { flex: 1; min-width: 0; }

/* The markup you would type, because that is the thing you need from this list. */
.slot__ref {
    display: block;
    font-family: var(--mono);
    font-size: 0.8125rem;
    color: var(--leaf-bright);
}

.slot__name {
    display: block;
    font-size: 0.75rem;
    color: var(--ink-dim);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.slot-add { margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--rule); }
