/*
 * studio.css — the whole visual language, shared by the gallery and the editor.
 *
 * ONE FILE FOR TWO PAGES, because they are one app. The Studio used to be a single page with its
 * CSS inline; splitting it into a gallery and an editor without pulling the styles out would have
 * meant two copies of the same tokens, and the copy that gets edited is never the copy the bug is
 * in.
 *
 * The measurements come from the editor Josh works in daily, at
 * ~/Desktop/code/Affin/repurposing-engine/editor/app.css: 13px base in the panel, section headings
 * at 10px uppercase with .08em tracking so they read as labels rather than titles, 6px rhythm
 * inside a group and a 1px rule between groups rather than cards. The COLOURS are not from there.
 * That tool is dark grey on purpose; this one stays white, and the only thing borrowed from its
 * palette is the idea that the canvas ground should sit one step deeper than the panels so a white
 * poster reads as an object on a surface rather than as more page.
 */

:root {
  --ink: #17212e;
  --muted: #5d6b7c;
  --line: #d9e2ec;
  --paper: #f7fafc;
  --panel: #ffffff;
  /* Deeper than --paper, and the only reason it exists: the posters are mostly pale, and on
     --paper a 1080x1350 white canvas had no edge at all. */
  --stage: #e7edf3;
  --accent: #3b5880;
  --warn: #8a5a00;
  --warn-bg: #fff8e6;
  --bad: #a11d2b;
  --bad-bg: #fdeced;
  --good: #1c6b46;
  --radius: 8px;
  --bar-h: 52px;
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, monospace;
}
@media (prefers-color-scheme: dark) {
  :root {
    --ink: #e8eef5; --muted: #9aa9b8; --line: #2b3644; --paper: #131a22; --panel: #1a222c;
    --stage: #0c1117;
    --accent: #8fb3e0; --warn: #e0b355; --warn-bg: #2e2718; --bad: #f08a95; --bad-bg: #2e1a1d;
    --good: #6fd3a3;
  }
}

* { box-sizing: border-box; }
body {
  margin: 0; font-family: var(--sans); color: var(--ink); background: var(--paper);
  font-size: 14px; line-height: 1.45;
}
h1 { font-size: 15px; margin: 0; font-weight: 600; letter-spacing: .2px; }
h2 { font-size: 12px; margin: 0 0 10px; text-transform: uppercase; letter-spacing: .09em; color: var(--muted); font-weight: 600; }
a { color: var(--accent); }

button {
  font: inherit; font-size: 13px; padding: 6px 12px; border: 1px solid var(--line);
  background: var(--panel); color: var(--ink); border-radius: var(--radius); cursor: pointer;
}
button:hover:not(:disabled) { border-color: var(--accent); }
button:disabled { opacity: .45; cursor: not-allowed; }
button.primary { background: var(--accent); border-color: var(--accent); color: #fff; font-weight: 600; }
@media (prefers-color-scheme: dark) { button.primary { color: #0d1117; } }
button.ghost { background: transparent; border-color: transparent; }
button.ghost:hover:not(:disabled) { border-color: var(--line); }
/* Offered only when a newer build is already downloaded and waiting, so it has to read as a
   choice rather than as an error. */
#update { border-color: var(--warn); color: var(--warn); font-weight: 600; }

input[type=text], textarea {
  font: inherit; width: 100%; padding: 6px 8px; border: 1px solid var(--line);
  border-radius: 6px; background: var(--panel); color: var(--ink); resize: vertical;
}
input:focus, textarea:focus, button:focus-visible, a:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}

header {
  display: flex; align-items: center; gap: 10px; height: var(--bar-h); padding: 0 14px;
  border-bottom: 1px solid var(--line); background: var(--panel); position: sticky; top: 0; z-index: 5;
}
header .spacer { flex: 1; }
header .note { color: var(--muted); font-size: 12px; }
.quiet { color: var(--muted); font-size: 12px; }
.backlink { text-decoration: none; font-size: 13px; white-space: nowrap; }
.backlink:hover { text-decoration: underline; }

/*
 * The status line, and its one job.
 *
 * Deliberately quiet, because it is confirmation rather than a control. It raises its voice for
 * exactly one thing: the review found something. Then it is the way IN to the drawer, so it has to
 * look like it can be pressed, which is why it is a button that spends most of its life not looking
 * like one.
 */
.status {
  font: inherit; font-size: 12px; color: var(--muted); background: none; border: 1px solid transparent;
  padding: 4px 8px; border-radius: 6px; cursor: default; text-align: left;
}
.status[data-open="1"] { cursor: pointer; }
.status[data-open="1"]:hover { border-color: currentColor; }
.status.warn { color: var(--warn); }
.status.bad { color: var(--bad); font-weight: 600; }

/* --- the gallery ------------------------------------------------------------------------------ */

.gallery { max-width: 1180px; margin: 0 auto; padding: 22px 16px 64px; }
.gallery section + section { margin-top: 30px; }
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 16px; }

/* The whole card is the click target. An anchor rather than a button, so the editor URL is real:
   it can be opened in a new tab, bookmarked, and pasted to somebody else. */
.card {
  display: block; position: relative; text-decoration: none; color: inherit;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel); overflow: hidden;
}
.card:hover { border-color: var(--accent); }
.card .shot {
  display: block; width: 100%; aspect-ratio: 4 / 5; object-fit: cover;
  background: var(--stage); border-bottom: 1px solid var(--line);
}
.card .body { padding: 9px 11px 11px; }
.card .name { display: block; font-weight: 600; font-size: 13.5px; }
.card .meta { display: block; font-size: 11.5px; color: var(--muted); margin-top: 2px; }
/* Two lines of the look note and no more. It is a card, not a brief; the whole of whenToUse and
   whenNotToUse is on the card's title attribute for anyone who hovers. */
.card .look {
  font-size: 11.5px; color: var(--muted); margin: 6px 0 0;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.card .tag {
  position: absolute; top: 8px; left: 8px; font-size: 10px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; padding: 3px 7px; border-radius: 20px;
  background: var(--panel); border: 1px solid var(--line); color: var(--muted);
}
/* The delete control is a SIBLING of the card, not a child: the card is an anchor, and a button
   inside an anchor is a click target inside a navigation. So the wrapper is what it positions
   against, and scoping this to `.card .del` put it in the flow underneath every card instead. */
.card-wrap { position: relative; }
.card-wrap .del {
  position: absolute; top: 6px; right: 6px; width: 26px; height: 26px; padding: 0; line-height: 1;
  font-size: 15px; border-radius: 50%; color: var(--muted); background: var(--panel);
}
.card-wrap .del:hover { color: var(--bad); border-color: var(--bad); }
.card.blocked { opacity: .62; }

details { margin-top: 16px; }
summary { cursor: pointer; font-size: 12px; color: var(--muted); }
.blocked-row { padding: 8px 0; border-bottom: 1px solid var(--line); font-size: 12px; }
.blocked-row .name { font-weight: 600; font-size: 13px; display: block; }
.blocked-row .meta { color: var(--muted); display: block; }

/* --- the editor ------------------------------------------------------------------------------- */

/* Two columns. There is no left rail: choosing a template, resuming a draft and opening a file all
   happen on the gallery now, and a poster is one slide, so there is no filmstrip to put there. */
.editor { display: grid; grid-template-columns: minmax(0, 1fr) 320px; height: calc(100vh - var(--bar-h)); }
@media (max-width: 900px) { .editor { grid-template-columns: 1fr; height: auto; } }

/*
 * The stage, and the whole of the layout complaint it answers.
 *
 * This column holds the poster and nothing else. It used to carry a zoom row above it and a 150px
 * feed thumbnail plus a paragraph explaining the thumbnail below it, which pushed a poster that
 * never resized itself into the middle of a column it did not fill. Zoom moved to the header and
 * fits the window by default; the thumbnail is gone.
 */
.stage-area {
  position: relative; background: var(--stage); overflow: auto;
  display: grid; padding: 24px;
}
/* `margin: auto` on a grid child rather than `place-items: center` on the parent. They centre
   identically until the poster is bigger than the area, and then place-items overflows in both
   directions and the top and left of the poster become unreachable by scrolling. */
.stage-wrap { position: relative; margin: auto; }
/* .stage is the fixed 1080x1350 design surface. Only the VIEWPORT scales, which is what keeps the
   exported pixels identical to the previewed ones. */
.stage {
  width: 1080px; height: 1350px; transform-origin: top left;
  background: #fff; box-shadow: 0 4px 26px rgba(0, 0, 0, .18);
}
.stage iframe { width: 1080px; height: 1350px; border: 0; display: block; }

.zoom { display: flex; align-items: center; gap: 2px; }
.zoom button { padding: 4px 9px; }
/* Undo and redo carry a glyph rather than a word, so the glyph has to hold the line on its own. */
.glyph { font-size: 16px; line-height: 1; padding: 4px 8px; }
.zoom output { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; min-width: 42px; text-align: center; }

/* --- the inspector ---------------------------------------------------------------------------- */

.inspector {
  overflow-y: auto; background: var(--panel); border-left: 1px solid var(--line); padding: 12px;
  font-size: 13px;
}
.insp-head { display: flex; align-items: center; gap: 6px; margin-bottom: 10px; }
.insp-head h2 { margin: 0; font-size: 14px; text-transform: none; letter-spacing: 0; color: var(--ink); }
.pill {
  font-size: 10px; text-transform: uppercase; letter-spacing: .06em; font-weight: 600;
  padding: 2px 7px; border-radius: 20px; border: 1px solid var(--line); color: var(--muted);
}

.grp { border-top: 1px solid var(--line); padding: 10px 0; }
.grp:first-child { border-top: 0; }
.grp > h3 {
  font-size: 10px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted);
  font-weight: 600; margin: 0 0 7px; display: flex; align-items: baseline; gap: 6px;
}
.grp > h3 .count { margin-left: auto; font-family: var(--mono); font-weight: 400; }
.grp > h3 .count.over { color: var(--bad); font-weight: 600; }
.hint { font-size: 11px; color: var(--muted); margin: 5px 0 0; }
.evidence { font-size: 11px; color: var(--muted); border-left: 2px solid var(--line); padding-left: 7px; margin: 6px 0 0; }
.row { display: flex; gap: 6px; flex-wrap: wrap; }

.slider { display: grid; grid-template-columns: 52px 1fr 42px; gap: 7px; align-items: center; margin-bottom: 6px; font-size: 11px; }
.slider label { color: var(--muted); }
.slider output { font-family: var(--mono); color: var(--muted); text-align: right; }
.slider input[type=range] { width: 100%; accent-color: var(--accent); }

.swatches { display: flex; gap: 6px; flex-wrap: wrap; }
.swatch { width: 26px; height: 26px; border-radius: 5px; border: 1px solid var(--line); cursor: pointer; padding: 0; }
.swatch[aria-pressed=true] { outline: 2px solid var(--accent); outline-offset: 1px; }

/*
 * The slot index: what the inspector shows when nothing is selected.
 *
 * Affin shows nothing at all in this state, and that is the better answer there. It cannot be the
 * answer here, because overlay.js only hits elements with a width and a height: empty a headline
 * and its box collapses to nothing, so a panel that only ever shows the selection would strand it
 * with no way back. These rows call select() by id, which does not hit-test.
 */
.slot {
  display: flex; align-items: baseline; gap: 8px; width: 100%; text-align: left;
  padding: 6px 8px; margin-bottom: 3px; border-color: transparent; font-size: 12px;
}
.slot:hover { background: var(--paper); }
.slot .k { color: var(--muted); font-size: 11px; flex: none; max-width: 45%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.slot .v { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.slot .v:empty::before { content: 'empty'; color: var(--bad); }

/* --- the review drawer ------------------------------------------------------------------------ */

/*
 * Fixed and dismissible rather than a third section of the panel, which is where it used to live
 * and where it was permanently in the way of the thing people are actually editing. It never opens
 * itself: the status button in the header is the only way in, so it cannot interrupt typing.
 */
.drawer {
  position: fixed; right: 14px; bottom: 14px; width: min(460px, calc(100vw - 28px)); max-height: 46vh;
  overflow: auto; z-index: 50; padding: 12px 14px 14px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, .18);
}
.drawer h2 { margin-bottom: 8px; }
.drawer-close { position: absolute; top: 8px; right: 8px; padding: 2px 8px; line-height: 1.2; }
.msg { padding: 8px 10px; border-radius: 6px; margin-bottom: 6px; font-size: 12.5px; }
.msg.bad { background: var(--bad-bg); color: var(--bad); }
.msg.warn { background: var(--warn-bg); color: var(--warn); }
.msg.good { color: var(--good); }
.msg code { font-family: var(--mono); font-size: 11.5px; }
