/*
 * Admin surface. Same tokens as the public site, denser.
 *
 * Forms, buttons, panels, and flashes are NOT here. They live in app.css,
 * because the public contact form uses the same primitives and this sheet is
 * only loaded by layout-admin. Keeping them here rendered the contact page as
 * bare user-agent widgets. Only rules that are genuinely admin-specific
 * belong in this file.
 */

.admin { font-size: 16px; }

.admin-bar { border-bottom: 1px solid var(--hairline); background: var(--sunken); }
.admin-bar .bar {
  display: flex; align-items: center; gap: var(--s-3) var(--s-4);
  min-height: 56px; flex-wrap: wrap;
}
.admin-bar .wordmark { font-family: var(--f-display); font-weight: var(--w-strong); letter-spacing: .04em; font-size: .9rem; }

/*
 * The admin bar carries eight links plus a sign out button, which is more than
 * a phone can fit on one row. Same treatment as the public header: the nav
 * takes its own full width row and the brand keeps the row above it.
 */
@media (max-width: 860px) {
  .admin-bar .bar { padding-block: var(--s-2); }
  .admin-bar .nav { order: 3; flex: 1 0 100%; }
  .admin-bar .signout { margin-left: auto; }
}

/* Denser than the public field rhythm, because an admin form is a work
   surface rather than something to read. Both the field and the row it may sit
   in, or the two rhythms disagree wherever a .row2 appears. */
.admin .field { margin-bottom: var(--s-3); }
.admin .row2 { margin-bottom: var(--s-3); }

/*
 * Columns, because the page is the window now.
 *
 * These forms were written when .wrap capped the page at 1180px, and each
 * carried an inline max-width of about 44rem so it did not become a single
 * absurd column. With the page running the window that cap turned into the
 * opposite problem: a 700px form pinned to the left of a 1600px screen with
 * half the window empty beside it, which is what "left-bound" means.
 *
 * Removing the cap alone would not have helped — the fields are capped at 38rem
 * individually, so a full width panel would still be one narrow column of
 * controls hugging the left edge. The fix is to lay the fields out ACROSS the
 * panel instead of down it.
 *
 * auto-fit, so the column count comes from the window rather than from a
 * breakpoint: one column on a phone, two on a laptop, three or four on a wide
 * monitor, with no number written down anywhere that has to be revisited.
 */
.panel.cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));
  gap: var(--s-3) var(--s-4);
  align-items: start;
}
/*
 * Things that belong to the whole form rather than to one column: the submit
 * row, a note about the form, and any field holding a textarea. Selected here
 * rather than marked up child by child, so adding a field to one of these forms
 * later needs no thought about which class it wants.
 */
.panel.cols > .full,
.panel.cols > .btn-row,
.panel.cols > .hint,
.panel.cols > p,
.panel.cols > .field:has(textarea) { grid-column: 1 / -1; }

/*
 * Two columns, fixed, for a panel whose items are long enough that auto-fit
 * would make four of them and none readable. Settings is four switches, each
 * with a paragraph explaining what it costs to turn on.
 */
.panel.cols-2 { display: grid; gap: var(--s-3) var(--s-4); align-items: start; grid-template-columns: 1fr; }
@media (min-width: 60rem) { .panel.cols-2 { grid-template-columns: 1fr 1fr; } }
.panel.cols-2 > .btn-row,
.panel.cols-2 > .field:has(textarea) { grid-column: 1 / -1; }

/*
 * A bare submit button as a direct child of either grid.
 *
 * Grid items stretch to their cell by default, which is right for an input and
 * absurd for a button: Save Settings rendered 720px wide across half the panel.
 * Its own row, sized to its own text.
 */
.panel.cols > .btn,
.panel.cols-2 > .btn { grid-column: 1 / -1; justify-self: start; }

/*
 * A submit that belongs beside the field next to it rather than on a row of its
 * own. The spacer reproduces the height of a field's label, so the button lines
 * up with the INPUT it sits next to instead of with that input's label.
 */
.field.save-inline { align-items: flex-start; margin-bottom: 0; }
.field.save-inline .field-spacer {
  /* Every property a .field > label carries that contributes height, and no
     line-height of its own: setting one made the spacer 6px shorter than the
     label it stands in for, and the button sat 6px above the input. */
  display: block;
  font-family: var(--f-mono);
  font-size: .6rem;
  font-stretch: 80%;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.field.save-inline .field-spacer::before { content: "\200B"; }
.panel.cols-2 > .field { margin-bottom: 0; }
/* A field's own margin fights the grid gap and doubles it. */
.panel.cols > .field { margin-bottom: 0; }

/*
 * The same idea one level up, for a page that is a stack of panels rather than
 * a panel of fields. The content editor is forty short strings, and forty
 * panels down the left of a wide screen is a lot of scrolling to change one
 * word.
 */
.admin-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(24rem, 100%), 1fr));
  gap: var(--s-3) var(--s-4);
  align-items: start;
}
/*
 * A slot being edited as prose gets two columns' worth, because a paragraph
 * typed into an 18rem box is miserable. Guarded by a width where at least two
 * columns are certain to exist: spanning two in a one-column grid would create
 * an implicit second column and push the page sideways.
 */
@media (min-width: 64rem) {
  .admin-cols > .panel:has(textarea) { grid-column: span 2; }
}

/*
 * table-layout: fixed is not cosmetic here.
 *
 * With automatic layout the table sizes to its widest content, and a table
 * inside an overflow:auto wrapper that does this pushes the DOCUMENT sideways
 * as well as its own scroll box: the page gained several hundred pixels of
 * empty scrollable canvas that no element's bounding box accounted for, which
 * is the least debuggable form the bug takes. Fixed layout resolves the columns
 * from the header row and keeps the table at its declared width, so the wrapper
 * is the only thing that ever scrolls.
 */
.admin-table { width: 100%; table-layout: fixed; border-collapse: collapse; font-size: .9rem; }
.admin-table td, .admin-table th { overflow-wrap: break-word; }

/*
 * A header and its values sit on the same axis.
 *
 * Every column was left aligned, which was fine when the page stopped at
 * 1180px. Full width, a table spreads its columns to the window, and a
 * three-character value like a unit count or a term left aligned in a 240px
 * column drifts to the far left of a header it is supposed to belong to. The
 * header and the value stop reading as one column.
 *
 * So: the identifying column keeps its left edge, the actions keep their right
 * edge, and everything between is centred, header and cell together. A column
 * of prose opts back out with .wide, because centring a wrapped sentence is
 * worse than the problem this fixes.
 */
.admin-table th:not(.wide):not(:first-child):not(:last-child),
.admin-table td:not(.wide):not(:first-child):not(:last-child) { text-align: center; }
.admin-table th {
  text-align: left; font-family: var(--f-mono); font-size: .58rem; font-stretch: 80%;
  letter-spacing: .13em; text-transform: uppercase; color: var(--text-muted);
  font-weight: var(--w-body); padding: 8px 10px; border-bottom: 1px solid var(--rule); white-space: nowrap;
}
.admin-table td { padding: 9px 10px; border-bottom: 1px solid var(--hairline); vertical-align: middle; }
.admin-table tr:last-child td { border-bottom: 0; }
.admin-table .actions { display: flex; gap: 5px; align-items: center; justify-content: flex-end; flex-wrap: wrap; }

/*
 * A select sizes itself to its longest option. In a table cell that means one
 * album called "Sport And The Outdoors" sets the width of the whole column, the
 * table grows past its scroll container, and the page acquires a horizontal
 * scrollbar that no element's bounding box explains. The popup still shows the
 * full text, so nothing is lost by capping the closed control.
 */
.admin-table select {
  max-width: 11rem;
  min-width: 0;
  font-size: .75rem;
  padding: 4px 6px;
  border-radius: var(--r-control);
  border: 1px solid var(--hairline);
  background: var(--surface);
  color: var(--text-body);
  font-family: var(--f-body);
}
/*
 * A form in a cell is a flex container, not a block.
 *
 * As a block it gets a line box, and the baseline descender space under an
 * inline-flex .btn made every form-wrapped button 26.13px tall against 23.13px
 * for the plain anchors beside it. align-items: center on .actions then centred
 * the taller boxes and left their buttons sitting 1.5px lower than Edit and
 * Delete in every row of every table.
 */
.admin-table td form { min-width: 0; display: flex; }

/*
 * A table of eight columns cannot reflow into 320px, and squeezing it produces
 * one word per line. It scrolls inside .table-wrap instead. min-width keeps the
 * columns legible while scrolling rather than collapsing them to fit the box.
 */
/* Wide enough that seven columns stay readable while scrolling, rather than
   collapsing into one word per line. */
.table-wrap .admin-table { min-width: 46rem; }

.stat-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(110px, 100%), 1fr)); gap: 1px;
  background: var(--hairline); border: 1px solid var(--hairline); border-radius: var(--r-card); overflow: hidden; }
/* Centred, for the same reason .metric is on the public side: a stat is a
   number and its name read as one object, and a row of them left aligned in
   cells of different widths reads as a table that lost its columns. Full width
   makes twelve of them wide enough for that to be obvious. */
.stat { background: var(--surface); padding: var(--s-3) var(--s-4); text-align: center; }
.stat b { display: block; font-family: var(--f-display); font-size: 1.5rem; color: var(--text-strong);
  font-variant-numeric: tabular-nums; line-height: 1.1; }
.stat span { font-family: var(--f-mono); font-size: .55rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--text-muted); }

.facet-picker { display: flex; flex-direction: column; gap: var(--s-3); }
.facet-row { border: 1px solid var(--hairline); border-radius: var(--r-control); padding: var(--s-3); }
.facet-row summary { cursor: pointer; display: flex; align-items: center; gap: 9px; }
.facet-row summary .dot { width: 9px; height: 9px; border-radius: 2px; flex: none; }
.facet-row .inner { margin-top: var(--s-3); display: grid; gap: var(--s-2); }

/* Drag handle only appears where a pointer exists. The move buttons are the
   accessible baseline and are always present. */
/* nowrap, because the grip is two characters and the column is 44px. Without
   it overflow-wrap breaks "::" BETWEEN the colons, the cell becomes the tallest
   in the row, and the handle reads as two stray dots parked at the top and
   bottom of a row 6px taller than it needs to be. */
.drag-handle { cursor: grab; color: var(--text-muted); font-family: var(--f-mono); white-space: nowrap; }
tr.dragging { opacity: .5; }
tr.drop-target td { box-shadow: inset 0 2px 0 var(--accent); }
