/* lapetitekozel admin — the gallery's design language applied to a tool.
   Same paper, ink, accent and 2px borders as STYLE-DNA.md; the differences
   are the ones a working interface needs — denser spacing, real form
   controls, and a fixed sidebar. No border radius here either. */

:root {
  --paper: #F4EDE0;
  --card: #FFFDF7;
  --ink: #141210;
  --ink-soft: #3A342C;
  --accent: #C42B7A;
  --body: #443E36;
  --muted: #6B6257;
  --ok: #1F8A7A;
  --warn: #C4633A;
  --edge: 2px solid var(--ink);
  --display: Oswald, "Arial Narrow", sans-serif;
  --text: "Golos Text", system-ui, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, monospace;
}

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

body {
  margin: 0;
  background: var(--paper);
  background-image: radial-gradient(var(--ink) 1px, transparent 1px);
  background-size: 22px 22px;
  font-family: var(--text);
  color: var(--ink);
}

.mono { font-family: var(--mono); text-transform: uppercase; letter-spacing: .12em; }
button { font: inherit; color: inherit; cursor: pointer; }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }

/* ── Buttons ──────────────────────────────────────────────────────────── */

.btn {
  border: var(--edge); background: var(--card); color: var(--ink);
  padding: 10px 16px;
  font-family: var(--display); font-weight: 600; font-size: 14px;
  letter-spacing: .06em; text-transform: uppercase;
  box-shadow: 4px 4px 0 var(--ink);
  transition: box-shadow .14s ease, transform .14s ease;
}
.btn:hover:not(:disabled) { box-shadow: 0 0 0 var(--ink); transform: translate(4px, 4px); }

/* Buttons with a leading icon. The arrow used to be a literal "←", which sits
   on the MATH AXIS — roughly 0.28em up — while the uppercase label runs from
   the baseline to the cap height, centred nearer 0.35em. The glyph therefore
   reads low next to the text, and no font choice fixes it because that is
   what the character is for. An SVG centred by flexbox has no axis to sit on.

   :not([hidden]) is load-bearing. admin.js toggles `back.hidden`, and the UA
   rule that hides it is `[hidden] { display: none }` — an AUTHOR `display`
   rule beats it no matter the order, so declaring display here unscoped would
   pin the button visible on the list view, where there is nothing to go back
   to. */
/* justify-content is not optional here. A <button> centres its label with
   text-align: center, which is why the other buttons look right — but the
   moment this one became a flex container, text-align stopped positioning
   anything and the icon+label packed to flex-start. In the sidebar the
   buttons stretch full width, so that reads as a plainly left-aligned button
   sitting between two centred ones. */
.btn-ico:not([hidden]) {
  display: inline-flex; align-items: center; justify-content: center; gap: .5em;
}
/* Sized in em so it tracks the label, and never shrunk by the flex layout. */
.btn-ico svg { width: .78em; height: .78em; flex: none; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn-primary { background: var(--accent); color: var(--paper); }
.btn-danger { background: var(--card); color: var(--warn); }
.btn-sm { padding: 6px 11px; font-size: 12px; box-shadow: 3px 3px 0 var(--ink); }
.btn-sm:hover:not(:disabled) { transform: translate(3px, 3px); }

/* ── Login ────────────────────────────────────────────────────────────── */

.login-body { display: grid; place-items: center; min-height: 100vh; padding: 24px; }
.login-card {
  width: 100%; max-width: 380px;
  border: var(--edge); background: var(--card);
  box-shadow: 8px 8px 0 var(--ink); padding: 32px 28px;
}
.login-title {
  margin: 0; font-family: var(--display); font-weight: 700; font-size: 30px;
  text-transform: uppercase; letter-spacing: -.01em;
}
.login-sub { margin: 4px 0 24px; font-size: 10px; color: var(--muted); }

.field { display: block; margin-bottom: 16px; }
.field-label { display: block; font-size: 9.5px; color: var(--muted); margin-bottom: 5px; }
.field input, .field select, .field textarea {
  width: 100%; border: var(--edge); background: var(--paper); color: var(--ink);
  padding: 10px 12px; font-family: var(--text); font-size: 14px;
}
.field textarea { resize: vertical; min-height: 68px; line-height: 1.5; }
.err {
  margin: 0 0 14px; border: var(--edge); border-color: var(--warn);
  background: #FBEDE7; color: #8A3A18; padding: 9px 12px; font-size: 13px;
}
/* Breathing room between the password field and the button; the fields
   carry their own bottom margin but the button had none of its own. */
.login-card .btn-primary { margin-top: 10px; width: 100%; }

/* ── Shell ────────────────────────────────────────────────────────────── */

.shell { display: grid; grid-template-columns: 260px minmax(0, 1fr); min-height: 100vh; }

.side {
  border-right: var(--edge); background: var(--ink); color: var(--paper);
  padding: 22px 20px; display: flex; flex-direction: column; gap: 22px;
  position: sticky; top: 0; height: 100vh;
}
.side-brand { font-family: var(--display); font-weight: 700; font-size: 19px; text-transform: uppercase; }
.side-who { font-size: 10px; color: #9C9384; }
.side-actions { display: flex; flex-direction: column; gap: 8px; }
.side-foot { margin-top: auto; display: flex; flex-direction: column; gap: 10px; }
.side .btn { background: transparent; color: var(--paper); border-color: var(--paper); box-shadow: none; }
.side .btn:hover:not(:disabled) { background: var(--accent); border-color: var(--accent); transform: none; }
.side .btn-primary { background: var(--accent); border-color: var(--accent); }

.main { padding: 24px 28px 60px; min-width: 0; }
.main-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 18px;
}
.main-title { margin: 0; font-family: var(--display); font-weight: 700; font-size: 26px; text-transform: uppercase; }
.count { font-family: var(--mono); font-size: 11px; color: var(--muted); text-transform: none; }

.search {
  border: var(--edge); background: var(--card); padding: 9px 12px;
  font-family: var(--text); font-size: 14px; min-width: 240px;
}

/* ── List ─────────────────────────────────────────────────────────────── */

.rows { display: flex; flex-direction: column; gap: 8px; }
.row {
  display: grid; grid-template-columns: 56px minmax(0, 1fr) auto;
  gap: 14px; align-items: center;
  border: var(--edge); background: var(--card); padding: 9px 12px;
  box-shadow: 4px 4px 0 var(--ink);
  transition: transform .14s ease, box-shadow .14s ease;
}
.row:hover { transform: translate(-2px, -2px); box-shadow: 7px 7px 0 var(--ink); }
.row-thumb {
  width: 56px; height: 56px; border: var(--edge); object-fit: cover;
  display: block; background: var(--paper);
}
.row-thumb-empty {
  display: grid; place-items: center;
  font-family: var(--mono); font-size: 8px; color: var(--muted);
}
.row-main { min-width: 0; }
.row-title {
  font-family: var(--display); font-weight: 600; font-size: 17px;
  text-transform: uppercase; line-height: 1.1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.row-meta {
  font-family: var(--mono); font-size: 9px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); margin-top: 3px;
  display: flex; gap: 8px; flex-wrap: wrap; align-items: center;
}
.dot { width: 9px; height: 9px; border: 1.5px solid var(--ink); display: inline-block; }
.pill-off {
  border: 1.5px solid var(--warn); color: var(--warn);
  padding: 1px 5px; font-size: 8px;
}

/* ── Editor ───────────────────────────────────────────────────────────── */

.editor { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 22px; align-items: start; }
.panel { border: var(--edge); background: var(--card); box-shadow: 5px 5px 0 var(--ink); padding: 20px; }
.panel + .panel { margin-top: 16px; }
.panel-title {
  margin: 0 0 14px; font-family: var(--display); font-weight: 600; font-size: 15px;
  text-transform: uppercase; letter-spacing: .06em;
  border-bottom: var(--edge); padding-bottom: 8px;
}
.grid2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 16px; }
.grid4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0 12px; }
.lang-tag {
  font-size: 8px; border: 1.5px solid var(--muted); color: var(--muted);
  padding: 1px 4px; margin-left: 5px;
}

.stat-row { display: flex; align-items: center; gap: 10px; }
.stat-row input[type=range] { flex: 1; accent-color: var(--accent); }
.stat-row input[type=number] { width: 68px; }

.media-list { display: flex; flex-direction: column; gap: 10px; }
.media-item { border: var(--edge); padding: 8px; display: flex; gap: 10px; align-items: center; }
.media-item img { width: 64px; height: 64px; object-fit: cover; border: var(--edge); display: block; }
.media-info { flex: 1; min-width: 0; font-family: var(--mono); font-size: 9px; color: var(--muted); }
.media-actions { display: flex; flex-direction: column; gap: 5px; }
.badge-primary {
  display: inline-block; background: var(--accent); color: var(--paper);
  padding: 1px 6px; font-size: 8px; font-family: var(--mono); letter-spacing: .1em;
}

.drop {
  border: 2px dashed var(--ink); background: var(--paper);
  padding: 22px; text-align: center; cursor: pointer;
  font-family: var(--mono); font-size: 10px; color: var(--muted);
  transition: background-color .14s ease;
}
.drop.over { background: var(--accent); color: var(--paper); }

.actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; }

.toast {
  position: fixed; right: 20px; bottom: 20px; z-index: 50;
  border: var(--edge); background: var(--ink); color: var(--paper);
  box-shadow: 5px 5px 0 rgba(20,18,16,.3);
  padding: 12px 18px; font-family: var(--display); font-weight: 600;
  font-size: 14px; letter-spacing: .05em; text-transform: uppercase;
}
.toast-bad { background: var(--warn); }
.toast-good { background: var(--ok); }

.empty-note {
  border: var(--edge); background: var(--card); padding: 26px; text-align: center;
  font-family: var(--mono); font-size: 11px; color: var(--muted);
}

/* Below 1000px the sidebar stops being a sidebar and becomes a header bar.
   The previous rule only flipped flex-direction to row and let it wrap, which
   left the brand and five buttons wrapping against each other into an uneven
   stack — tall, ragged, and pushing the actual work off-screen. */
@media (max-width: 1000px) {
  .shell { grid-template-columns: minmax(0, 1fr); }
  .side {
    position: static; height: auto; padding: 14px 18px;
    flex-direction: row; flex-wrap: wrap; align-items: center; gap: 10px 14px;
  }
  /* The brand block takes the slack so the buttons sit together on the right
     instead of being spread across the bar by the gap. */
  .side > :first-child { margin-right: auto; }
  .side-brand { font-size: 16px; }
  .side-actions, .side-foot { flex-direction: row; margin-top: 0; gap: 8px; }
  .side .btn { padding: 8px 12px; font-size: 12px; }
  .editor { grid-template-columns: minmax(0, 1fr); }
  .main { padding: 18px 18px 48px; }
}

/* On a phone there is no room for brand-and-buttons on one line, so give each
   group its own full-width row and let the buttons share it equally. Equal
   halves rather than content-width keeps the tap targets big and the rows
   from looking accidental. */
@media (max-width: 620px) {
  .side { padding: 12px 14px; gap: 8px; }
  .side > :first-child { flex: 1 1 100%; margin-right: 0; }
  .side-actions, .side-foot { flex: 1 1 100%; }
  .side-actions .btn, .side-foot .btn, .side-foot .btn-link { flex: 1 1 0; min-width: 0; }
  .main { padding: 16px 14px 44px; }
  .main-head { gap: 12px; }
  .main-title { font-size: 22px; }
  /* 240px min-width overflowed a 375px viewport once padding was accounted
     for, which is what put the search field on its own cramped line. */
  .search { min-width: 0; width: 100%; }
  .grid2, .grid4 { grid-template-columns: minmax(0, 1fr); }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: .001ms !important; }
}

/* Utility classes replacing style="" attributes — the CSP is style-src 'self',
   which blocks inline style attributes in markup. */
.btn-link { text-decoration: none; text-align: center; display: block; }
.check-inline { display: flex; align-items: center; gap: 7px; font-size: 10px; }
.drop { margin-top: 12px; }

/* ── Media library ─────────────────────────────────────────────────────── */
.lib-grid {
  margin-top: 14px;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 12px;
}
.lib-item {
  border: var(--edge); background: var(--card); box-shadow: 4px 4px 0 var(--ink);
  display: flex; flex-direction: column;
}
.lib-item img { width: 100%; aspect-ratio: 1/1; object-fit: cover; border-bottom: var(--edge); display: block; }
.lib-meta { padding: 8px 9px; font-size: 8.5px; color: var(--muted); line-height: 1.6; word-break: break-all; }
.lib-unattached { color: var(--warn); }
.lib-actions { margin-top: auto; padding: 0 9px 9px; display: flex; gap: 5px; flex-wrap: wrap; }

/* ── Checkbox, house style ─────────────────────────────────────────────── */
/* appearance:none replaces the native widget so the 2px-ink-border language
   applies. The checkmark is an SVG data URI — permitted by the CSP's
   img-src 'self' data: — because pseudo-elements on <input> are still
   inconsistent across engines. */
.check-inline input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 22px; height: 22px; flex: none;
  margin: 0;
  border: var(--edge);
  background: var(--card);
  box-shadow: 3px 3px 0 var(--ink);
  cursor: pointer;
  transition: box-shadow .14s ease, transform .14s ease, background-color .14s ease;
}
.check-inline input[type="checkbox"]:hover {
  box-shadow: 0 0 0 var(--ink);
  transform: translate(3px, 3px);
}
.check-inline input[type="checkbox"]:checked {
  background-color: var(--accent);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 8.5 6.5 12 13 4.5' fill='none' stroke='%23F4EDE0' stroke-width='2.6' stroke-linecap='square'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 14px;
}
.check-inline { cursor: pointer; user-select: none; }

/* Visibility field: a labelled control like the others, not a stray button. */
.field-check { display: flex; flex-direction: column; gap: 6px; }
.field-check .check-inline {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--display); font-weight: 600; font-size: 14px;
  letter-spacing: .04em; text-transform: uppercase;
}
/* The 6px column gap sets label-to-control spacing; the hint needs more than
   that or it crowds the toggle it explains. */
.field-hint {
  margin-top: 4px;
  font-size: 11.5px; line-height: 1.45; color: var(--muted); font-family: var(--text);
}
