/* StringSong admin: the app's dark "reading lamp" palette (flutter_app/lib/app.dart Pal). */
:root {
  --bg: #12100E; --paper: #1A1714; --surface: #1E1A16; --raise: #29241F;
  --ink: #F2EADF; --muted: #A89F92; --faint: #6E665B; --line: #2E2923;
  --lamp: #E8B66C; --lamp-dim: #E8B66C26; --danger: #E8907A; --ok: #8FC79A; --info: #8AB4E8; --warn: #E8C46C;
  --r: 12px; --gap: 14px;
  color-scheme: dark;
}
* { box-sizing: border-box; }
html, body { margin: 0; background: var(--bg); color: var(--ink); }
body { font: 15px/1.45 system-ui, -apple-system, "Segoe UI", "PingFang SC", "Hiragino Sans", "Microsoft YaHei", sans-serif;
  min-height: 100vh; padding-bottom: env(safe-area-inset-bottom); }
a { color: var(--lamp); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3 { margin: 0 0 8px; font-weight: 650; line-height: 1.25; }
h1 { font-size: 22px; } h2 { font-size: 17px; } h3 { font-size: 15px; color: var(--muted); font-weight: 600; }
p { margin: 0 0 8px; }
.muted { color: var(--muted); } .faint { color: var(--faint); } .small { font-size: 12.5px; }
.mono { font-family: ui-monospace, "Cascadia Mono", Consolas, monospace; font-size: 12.5px; }
[hidden] { display: none !important; }

/* ---- header / tabs ---- */
.top { position: sticky; top: 0; z-index: 10; display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 10px 16px; background: color-mix(in srgb, var(--paper) 92%, transparent); backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line); }
.brand { display: flex; align-items: center; gap: 8px; color: var(--ink); font-size: 15px; }
.brand b { color: var(--lamp); font-weight: 650; }
.mark { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 8px; background: var(--lamp);
  color: var(--bg); font-weight: 800; }
.tabs { display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none; order: 3; width: 100%; }
.tabs::-webkit-scrollbar { display: none; }
.tabs a { padding: 7px 12px; border-radius: 999px; color: var(--muted); white-space: nowrap; font-size: 14px; }
.tabs a.on { background: var(--lamp-dim); color: var(--lamp); }
.tabs a:hover { text-decoration: none; color: var(--ink); }
.tabs .badge { margin-left: 5px; }
.who { margin-left: auto; display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--muted); }
@media (min-width: 900px) {
  .tabs { order: 0; width: auto; margin-left: 18px; }
}

main { max-width: 1200px; margin: 0 auto; padding: 16px; overflow-x: clip; }
.center { display: grid; place-items: center; min-height: 60vh; text-align: center; }

/* ---- generic ---- */
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 14px; }
.card + .card { margin-top: var(--gap); }
.stack > * + * { margin-top: var(--gap); }
.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.row.between { justify-content: space-between; }
.grow { flex: 1 1 auto; min-width: 0; }
.grid { display: grid; gap: var(--gap); }
.grid.tiles { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.grid.two { grid-template-columns: minmax(0, 1fr); }
@media (min-width: 900px) { .grid.two { grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); } }
.btn { appearance: none; border: 1px solid var(--line); background: var(--raise); color: var(--ink); border-radius: 10px;
  padding: 8px 14px; font: inherit; font-size: 14px; cursor: pointer; display: inline-flex; gap: 6px; align-items: center;
  min-height: 38px; }
.btn:hover { border-color: var(--faint); }
.btn.primary { background: var(--lamp); color: var(--bg); border-color: var(--lamp); font-weight: 650; }
.btn.danger { color: var(--danger); }
.btn.ghost { background: transparent; }
.btn.sm { min-height: 30px; padding: 4px 10px; font-size: 13px; }
.btn.on { border-color: var(--lamp); color: var(--lamp); }
.btn:disabled { opacity: .5; cursor: default; }
input, select, textarea { font: inherit; font-size: 14px; color: var(--ink); background: var(--paper); border: 1px solid var(--line);
  border-radius: 10px; padding: 8px 10px; min-height: 38px; max-width: 100%; }
textarea { width: 100%; min-height: 72px; resize: vertical; }
input:focus, select:focus, textarea:focus, .btn:focus-visible { outline: 2px solid var(--lamp); outline-offset: 1px; }
label.field { display: grid; gap: 4px; font-size: 12.5px; color: var(--muted); }
label.check { display: inline-flex; gap: 8px; align-items: center; cursor: pointer; }
label.check input { min-height: auto; width: 18px; height: 18px; accent-color: var(--lamp); }
.form { display: grid; gap: 10px; }
.form .cols { display: grid; gap: 10px; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
.search { flex: 1 1 220px; }

.chip { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: 999px; font-size: 12px;
  background: var(--raise); color: var(--muted); border: 1px solid var(--line); white-space: nowrap; }
.chip.ok { color: var(--ok); border-color: #8FC79A44; }
.chip.bad, .chip.high { color: var(--danger); border-color: #E8907A55; }
.chip.warn, .chip.normal { color: var(--warn); border-color: #E8C46C44; }
.chip.info { color: var(--info); border-color: #8AB4E844; }
.chip.lamp { color: var(--lamp); border-color: #E8B66C55; }
.chip.low { color: var(--muted); }
.chips { display: flex; flex-wrap: wrap; gap: 5px; }
.badge { display: inline-grid; place-items: center; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
  background: var(--danger); color: var(--bg); font-size: 11px; font-weight: 700; }

/* ---- overview stats ---- */
.stat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 12px 14px; }
.stat .k { font-size: 12.5px; color: var(--muted); }
.stat .v { font-size: 26px; font-weight: 700; font-variant-numeric: tabular-nums; }
.stat .v small { font-size: 14px; color: var(--faint); font-weight: 500; }
.stat a { color: inherit; }
.meter { height: 6px; border-radius: 3px; background: var(--raise); overflow: hidden; margin-top: 8px; }
.meter > i { display: block; height: 100%; background: var(--lamp); width: 0; }

/* ---- lists ---- */
.list { display: grid; gap: 8px; }
.item { display: flex; gap: 12px; align-items: center; padding: 10px; border-radius: var(--r); background: var(--surface);
  border: 1px solid var(--line); color: var(--ink); }
a.item:hover { text-decoration: none; border-color: var(--faint); }
.item .title { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.item .sub { font-size: 12.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.thumb { width: 52px; height: 52px; border-radius: 9px; object-fit: cover; flex: none; background: var(--raise); }
.thumb.round { border-radius: 50%; }
.swatch { width: 52px; height: 52px; border-radius: 9px; flex: none;
  background: linear-gradient(135deg, hsl(var(--hue, 35) 45% 35%), hsl(var(--hue, 35) 40% 18%)); }

/* ---- detail ---- */
.hero { display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap; }
.hero .cover { width: 132px; height: 132px; border-radius: 14px; object-fit: cover; background: var(--raise); flex: none; }
.hero .cover.round { border-radius: 50%; }
.kv { display: grid; grid-template-columns: max-content 1fr; gap: 4px 14px; font-size: 13.5px; }
.kv dt { color: var(--muted); } .kv dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
audio { width: 100%; height: 40px; }
.lanes { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 8px; }
.lyrics { max-height: 380px; overflow: auto; font-size: 14px; }
.lyrics .sec { color: var(--lamp); font-size: 12px; text-transform: uppercase; letter-spacing: .06em; margin: 10px 0 4px; }
.lyrics .ln { display: flex; gap: 10px; padding: 2px 4px; border-radius: 6px; cursor: pointer; }
.lyrics .ln:hover { background: var(--raise); }
.lyrics .ln.now { background: var(--lamp-dim); color: var(--lamp); }
.lyrics .t { color: var(--faint); font-variant-numeric: tabular-nums; flex: none; width: 92px; font-size: 12.5px; padding-top: 1px; }
pre.text { white-space: pre-wrap; font: inherit; font-size: 13.5px; margin: 0; max-height: 380px; overflow: auto; color: var(--muted); }
.sheet { width: 100%; height: 72vh; border: 1px solid var(--line); border-radius: var(--r); background: #fff; }
.table-wrap { overflow-x: auto; }
table { border-collapse: collapse; width: 100%; font-size: 13px; font-variant-numeric: tabular-nums; }
th, td { text-align: left; padding: 7px 8px; border-bottom: 1px solid var(--line); white-space: nowrap; }
th { color: var(--muted); font-weight: 600; font-size: 12px; }
tr.chosen td { background: var(--lamp-dim); }
td.bad { color: var(--danger); } td.ok { color: var(--ok); }
.gallery { display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
.gallery figure { margin: 0; background: var(--paper); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.gallery figure.rejected { border-color: #E8907A66; }
.gallery img { width: 100%; aspect-ratio: 1; object-fit: cover; display: block; cursor: zoom-in; background: var(--raise); }
.gallery figcaption { padding: 6px 8px; font-size: 12px; display: flex; justify-content: space-between; gap: 6px; }

/* ---- flags / tasks ---- */
/* no side stripes: a flag's severity is its chip; a task's priority is a small dot in the corner */
.task { position: relative; }
.task.p0::after, .task.p1::after { content: ""; position: absolute; top: 12px; right: 12px; width: 8px; height: 8px;
  border-radius: 50%; }
.flag.done { opacity: .72; }
.recheck { margin-top: 8px; padding: 8px 10px; border-radius: 8px; background: var(--raise); border: 1px solid var(--line); }
.hist { font-size: 12.5px; color: var(--muted); border-top: 1px dashed var(--line); margin-top: 8px; padding-top: 6px; }
.hist div { padding: 2px 0; }
details > summary { cursor: pointer; color: var(--muted); font-size: 12.5px; }
.board { display: grid; gap: var(--gap); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 1000px) { .board { grid-template-columns: repeat(5, minmax(0, 1fr)); align-items: start; } }
.col { background: var(--paper); border: 1px solid var(--line); border-radius: var(--r); padding: 10px; }
.col > h2 { display: flex; justify-content: space-between; font-size: 14px; color: var(--muted); text-transform: uppercase;
  letter-spacing: .05em; }
.task { background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 10px; cursor: pointer; }
.task + .task { margin-top: 8px; }
.task:hover { border-color: var(--faint); }
.task .title { font-weight: 600; margin-bottom: 4px; }
.task.p0::after { background: var(--danger); } .task.p1::after { background: var(--warn); }
.task .title { padding-right: 16px; }
.empty { color: var(--faint); font-size: 13px; padding: 8px 2px; }

/* ---- sign-in ---- */
.signin { max-width: 380px; margin: 8vh auto; }
.signin .btn { width: 100%; justify-content: center; }
.signin .or { text-align: center; color: var(--faint); font-size: 12px; margin: 6px 0; }
.err { color: var(--danger); font-size: 13.5px; }

dialog { background: var(--surface); color: var(--ink); border: 1px solid var(--line); border-radius: 16px; padding: 0;
  width: min(640px, calc(100vw - 24px)); max-height: calc(100vh - 32px); }
dialog::backdrop { background: #000a; }
#modal-body { padding: 16px; }
dialog img.full { max-width: 100%; max-height: 75vh; display: block; margin: 0 auto; border-radius: 10px; }
.toast { position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%); background: var(--raise); color: var(--ink);
  border: 1px solid var(--lamp); box-shadow: 0 8px 28px #000a; font-weight: 600; padding: 10px 16px; border-radius: 12px; opacity: 0; pointer-events: none;
  transition: opacity .2s; z-index: 50; max-width: calc(100vw - 32px); }
.toast.on { opacity: 1; }
.devbar { background: #E8907A22; color: var(--danger); text-align: center; font-size: 12px; padding: 4px; }

/* ---- song review: lyrics + sheet + timeline on one clock ---- */
body.reviewing main { padding-bottom: calc(var(--tr-h, 100px) + 16px); }
body.reviewing .toast { bottom: calc(var(--tr-h, 100px) + 12px); }
.rv-head { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.rv-head h1 { margin: 0; font-size: 20px; }
.rv-nav { gap: 6px; }
.rv-bar { display: flex; gap: 8px 14px; align-items: center; flex-wrap: wrap; margin-bottom: 10px; }
.rv-verify { padding: 4px 12px; border: 1px solid var(--line); border-radius: 999px; background: var(--raise); font-size: 14px; }
.rv-verify.on { color: var(--ok); border-color: #8FC79A66; }
.rv-keys { margin-left: auto; }
@media (max-width: 899px) { .rv-keys { display: none; } }
.seg { display: inline-flex; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.seg .btn { border: 0; border-radius: 0; background: transparent; }
.seg .btn.on { background: var(--lamp-dim); color: var(--lamp); }

.rv-panes { display: grid; gap: 10px; grid-template-columns: minmax(0, .85fr) minmax(0, 1.4fr);
  height: max(320px, calc(100dvh - var(--hdr-h, 56px) - var(--tr-h, 100px) - 28px)); }
.rv-panes[data-layout="lyrics"] { grid-template-columns: minmax(0, 1fr); }
.rv-panes[data-layout="lyrics"] .sht, .rv-panes[data-layout="sheet"] .lyr { display: none; }
.rv-panes[data-layout="sheet"] { grid-template-columns: minmax(0, 1fr); }
@media (max-width: 899px) {
  /* phones: the header scrolls away while reviewing, so the panes can take the whole screen above the transport */
  body.reviewing .top { position: static; }
  .rv-panes { height: max(300px, calc(100dvh - var(--tr-h, 120px) - 12px)); }
  .rv-panes[data-layout="both"] { grid-template-columns: minmax(0, 1fr); grid-template-rows: minmax(0, 2fr) minmax(0, 3fr); }
}
@media (max-width: 599px) {
  .tr-row { flex-wrap: wrap; overflow: visible; }
  .tr-row .btn.sm { padding: 4px 9px; }
  .tr-row .ab { display: none; }                   /* custom A-B on desktop; phones loop the line (⟲ Line) */
  .tr-row select[aria-label="Audio lane"] { max-width: 130px; }
  .rv-time { min-width: 0; }
}
/* phone landscape: header scrolls away, panes side by side again */
@media (max-height: 520px) and (orientation: landscape) {
  body.reviewing .top { position: static; }
  .rv-panes { height: max(220px, calc(100dvh - var(--tr-h, 80px) - 12px)); }
  .rv-panes[data-layout="both"] { grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); grid-template-rows: none; }
}
.rv-pane { display: flex; flex-direction: column; min-height: 0; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); padding: 10px; }
.rv-ph { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.rv-ph h2 { margin: 0 0 6px; font-size: 15px; }
.rv-warn { color: var(--warn); margin: 0 0 6px; }
.rv-warn:empty, .rv-info:empty { display: none; }
.rv-info { color: var(--muted); margin: 0 0 6px; font-variant-numeric: tabular-nums; }
.rv-lyrics { position: relative; flex: 1; min-height: 0; overflow: auto; overscroll-behavior: contain; padding-right: 2px; }
.rv-lyrics:focus { outline: none; }
.rv-sec { color: var(--lamp); font-size: 11.5px; text-transform: uppercase; letter-spacing: .06em; margin: 12px 0 3px 8px; }
.rl { position: relative; display: flex; gap: 10px; align-items: baseline; padding: 6px 8px; border-radius: 8px; cursor: pointer;
  color: var(--muted); overflow: hidden; font-size: 15px; line-height: 1.35; }
.rl > :not(.fill) { position: relative; }
.rl .fill { position: absolute; inset: 0; background: #E8B66C2e; transform-origin: 0 50%; transform: scaleX(0);
  pointer-events: none; will-change: transform; }
.rl:hover { background: var(--raise); }
.rl .t { flex: none; width: 48px; font-size: 12px; color: var(--faint); font-variant-numeric: tabular-nums; }
.rl .x { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.rl.now { color: var(--ink); box-shadow: inset 3px 0 0 var(--lamp); font-weight: 600; }
.rl.now .t { color: var(--lamp); }
.rl.next { color: var(--muted); opacity: .6; box-shadow: inset 3px 0 0 var(--lamp-dim); }
.rl.est .t { color: var(--warn); }
.rl .est-chip { font-size: 10.5px; padding: 0 6px; align-self: center; }
.rl .drift { display: none; flex: none; font-size: 11.5px; font-variant-numeric: tabular-nums; color: var(--ok); }
.rl .drift.bad { color: var(--danger); }
.rv-lyrics.show-drift .rl .drift { display: inline; }
/* lyric timing editor (replaces the lyric list while open) */
.te-head { gap: 6px; }
.te { display: flex; flex-direction: column; flex: 1; min-height: 0; gap: 6px; }
.te-bar { gap: 6px; }.te-status { color: var(--muted); font-variant-numeric: tabular-nums; }
.te-status .bad { color: var(--danger); } .te-status .warn { color: var(--warn); }
.te-keys { margin: 0; }
@media (max-width: 899px) { .te-keys { display: none; } }
.te-row { padding: 6px 8px; border-radius: 8px; border: 1px solid transparent; color: var(--muted); cursor: pointer; }
.te-row + .te-row { margin-top: 2px; }
.te-row:hover { background: var(--raise); }
.te-row.now { box-shadow: inset 3px 0 0 var(--lamp); color: var(--ink); }
.te-row.sel { border-color: #E8B66C88; background: var(--lamp-dim); color: var(--ink); }
.te-row.edited .te-n { color: var(--info); font-weight: 700; }
.te-row.bad { border-color: #E8907A99; }
.te-top { display: flex; gap: 8px; align-items: baseline; }
.te-n { flex: none; width: 26px; text-align: right; font-size: 12px; color: var(--faint); font-variant-numeric: tabular-nums; }
.te-top .x { flex: 1; min-width: 0; overflow-wrap: anywhere; font-size: 15px; line-height: 1.35; }
.te-top .est-chip { font-size: 10.5px; padding: 0 6px; align-self: center; }
.te-ctl { display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: center; margin: 4px 0 0 34px; }
.te-grp { display: inline-flex; gap: 4px; align-items: center; white-space: nowrap; }
.te-ctl .btn.sm { min-height: 28px; padding: 2px 8px; }
.te-k { width: 28px; font-size: 11.5px; color: var(--faint); }
.te-in { width: 76px; min-height: 28px; padding: 2px 4px; text-align: center; }
.te-row.edited .te-in { color: var(--info); }
.te-err { color: var(--danger); margin: 2px 0 0 34px; }
.te-err:empty { display: none; }
@media (max-width: 599px) { .te-ctl, .te-err { margin-left: 0; } }
.rv-sheetbody { flex: 1; min-height: 0; }
.rv-frame { display: block; width: 100%; height: 100%; border: 0; border-radius: 8px; background: #fff; }

.transport { position: fixed; left: 0; right: 0; bottom: 0; z-index: 15; background: color-mix(in srgb, var(--paper) 96%, transparent);
  backdrop-filter: blur(8px); border-top: 1px solid var(--line);
  padding: 8px max(12px, env(safe-area-inset-right)) calc(8px + env(safe-area-inset-bottom)) max(12px, env(safe-area-inset-left)); }
.tr-in { max-width: 1200px; margin: 0 auto; display: grid; gap: 6px; }
.tr-row { display: flex; gap: 6px; align-items: center; overflow-x: auto; scrollbar-width: none; }
.tr-row::-webkit-scrollbar { display: none; }
.tr-row > * { flex: none; }
.tr-row select { min-height: 30px; padding: 3px 6px; font-size: 13px; }
.rv-play { min-width: 52px; justify-content: center; }
.rv-time { min-width: 108px; text-align: center; color: var(--ink); }
.rv-loopchip { cursor: pointer; font: inherit; font-size: 12px; }
.tl { position: relative; height: 42px; border-radius: 8px; background: var(--surface); overflow: hidden; cursor: pointer;
  touch-action: none; }
.tl:focus-visible { outline: 2px solid var(--lamp); }
.tl canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.tl-prog { position: absolute; inset: 0; background: #E8B66C1c; transform-origin: 0 50%; transform: scaleX(0); pointer-events: none; }
.tl-loop { position: absolute; top: 0; bottom: 0; left: 0; width: 0; display: none; background: #8AB4E82e;
  border-left: 1px solid var(--info); border-right: 1px solid var(--info); pointer-events: none; }
.tl-ph { position: absolute; top: 0; bottom: 0; left: -1px; width: 2px; background: var(--lamp); box-shadow: 0 0 6px var(--lamp);
  pointer-events: none; will-change: transform; }
@media (max-height: 520px) and (orientation: landscape) {
  .transport { padding-top: 5px; padding-bottom: calc(5px + env(safe-area-inset-bottom)); }
  .tl { height: 28px; }
}

/* ---- art: picker, crop editor, comparison matrix ---- */
.warn { color: var(--warn); }
.cropv { position: relative; overflow: hidden; aspect-ratio: 1; background: var(--raise); border-radius: 10px; display: block; }
.cropv.round { border-radius: 50%; }
.cropv img { display: block; width: 100%; height: 100%; object-fit: cover; }
.cropv img.cropped { position: absolute; height: auto; max-width: none; object-fit: fill; }
img.cropv { width: 100%; height: auto; object-fit: cover; }
.cropv.empty { display: grid; place-items: center; color: var(--faint); font-size: 12px; }
.art-picker.drop { outline: 2px dashed var(--lamp); outline-offset: -6px; }
.art-picker.busy { opacity: .7; pointer-events: none; }
.art-now { display: flex; gap: 14px; align-items: flex-start; flex-wrap: wrap; }
.art-now figure { margin: 0; width: 112px; text-align: center; }
.art-now figcaption { margin-top: 4px; }
.dropzone { border: 1px dashed var(--faint); border-radius: var(--r); padding: 14px; text-align: center; cursor: pointer; background: var(--paper); }
.dropzone:hover, .dropzone:focus-visible { border-color: var(--lamp); outline: none; }
.art-grid { display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(var(--cell, 150px), 1fr)); }
.art-grid.size-s { --cell: 104px; } .art-grid.size-l { --cell: 240px; }
.art-grid figure { margin: 0; background: var(--paper); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden;
  display: flex; flex-direction: column; }
.art-grid figure.rejected { border-color: #E8907A66; }
.art-grid figure.rejected img { opacity: .55; }
.art-grid figure.in-use { border-color: var(--lamp); box-shadow: 0 0 0 1px var(--lamp); }
.art-img { appearance: none; border: 0; padding: 0; margin: 0; background: var(--raise); cursor: zoom-in; display: block; width: 100%; }
.art-img img { width: 100%; aspect-ratio: 3 / 4; object-fit: contain; display: block; }
.art-img:focus-visible { outline: 2px solid var(--lamp); outline-offset: -2px; }
.art-grid figcaption { padding: 6px 8px 8px; font-size: 12px; display: grid; gap: 4px; }
.art-grid figcaption .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.art-grid figcaption .row { flex-wrap: nowrap; gap: 4px; }
.art-grid.size-s figcaption .small { display: none; }

.crop-ed h2 { overflow-wrap: anywhere; }
.crop-wrap { text-align: center; background: var(--paper); border-radius: 10px; padding: 6px; }
.crop-stage { position: relative; display: inline-block; touch-action: none; user-select: none; cursor: crosshair; line-height: 0; }
.crop-stage img { display: block; max-width: 100%; max-height: min(56vh, 520px); }
.crop-box { position: absolute; box-shadow: 0 0 0 9999px #000a; outline: 2px solid var(--lamp); cursor: move; }
.crop-box.round::after { content: ""; position: absolute; inset: 0; border-radius: 50%; border: 1px dashed #fff9; pointer-events: none; }
.crop-box:focus-visible { outline: 3px solid var(--info); }
.crop-stage { overflow: hidden; }
.crop-handle { position: absolute; right: 0; bottom: 0; width: 18px; height: 18px; border-radius: 4px; background: var(--lamp);
  cursor: nwse-resize; border: 2px solid var(--bg); }
.crop-pvs { gap: 8px; }
.crop-pv { width: 64px; flex: none; }
.crop-ed input[type="range"] { width: 100%; padding: 0; accent-color: var(--lamp); }

.matrix { display: grid; gap: 8px; }
.mrow { display: grid; gap: 8px; align-items: center; grid-template-columns: minmax(120px, 170px) repeat(5, minmax(0, 150px)); }
.mhead { font-size: 12px; color: var(--muted); position: sticky; top: var(--hdr-h, 56px); z-index: 2; background: var(--bg); padding: 4px 0; }
.mname { min-width: 0; overflow-wrap: anywhere; }
.mname .chips { margin-top: 4px; }
.mcell { appearance: none; border: 1px solid var(--line); background: var(--paper); border-radius: 10px; padding: 0; overflow: hidden;
  aspect-ratio: 3 / 4; display: grid; place-items: center; color: var(--faint); font-size: 12px; cursor: pointer; }
.mcell > img:not(.cropv) { width: 100%; height: 100%; object-fit: cover; display: block; }
.mcell > .cropv, .mcell > img.cropv { width: 88%; }
.mcell.missing { border-style: dashed; color: var(--danger); cursor: default; }
a.mcell:hover, button.mcell:hover { border-color: var(--lamp); text-decoration: none; }
@media (max-width: 699px) {
  .mrow { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 5px; }
  .mrow .mname { grid-column: 1 / -1; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
  .mrow .mname .chips { margin: 0; }
  .mhead { font-size: 10.5px; }
  .mhead .mname { display: none; }
}

/* ---- sheet editor (#/sheet/<id>) ---- */
.se-grid { display: grid; gap: 10px; grid-template-columns: minmax(0, 1fr); }
@media (min-width: 1000px) {
  .se-grid { grid-template-columns: minmax(0, 1.55fr) minmax(320px, 1fr); align-items: start; }
  .se-sheet { position: sticky; top: calc(var(--hdr-h, 56px) + 8px); height: calc(100dvh - var(--hdr-h, 56px) - 24px); }
  .se-side { max-height: none; }
}
.se-sheet { min-height: 0; }
.se-framebox { flex: 1; min-height: 320px; }
@media (max-width: 999px) { .se-framebox { height: 52vh; flex: none; } }
.se-frame { display: block; width: 100%; height: 100%; border: 0; border-radius: 8px; background: #fff; }
.se-strip { display: block; width: 100%; height: 86px; margin-top: 8px; background: var(--paper); border-radius: 8px; cursor: pointer; }
.se-side > .card + .card { margin-top: 0; }
.se-note { display: grid; gap: 6px; }
.se-pitch { font-size: 30px; font-weight: 700; color: var(--lamp); font-variant-numeric: tabular-nums; line-height: 1.1; }
.se-pitch small { font-size: 14px; color: var(--muted); font-weight: 500; }
.se-kv { font-size: 13px; }
.se-lyr { color: var(--muted); overflow-wrap: anywhere; }
.se-syl { color: var(--ink); background: var(--lamp-dim); border-radius: 3px; padding: 0 1px; }
.se-nav { gap: 4px; }
.se-fix { display: grid; gap: 8px; }
.se-fix .row { gap: 6px; }
.se-fix select { min-height: 30px; padding: 3px 6px; font-size: 13px; }
.se-ops { margin: 6px 0 0; padding-left: 22px; max-height: 220px; overflow: auto; }
.se-ops li { padding: 2px 0; }
.se-ops li.warn, .se-ops li.warn .linkish { color: var(--warn); }
.linkish { appearance: none; border: 0; background: none; padding: 0; color: var(--lamp); font: inherit; cursor: pointer; text-align: left; }
.linkish:hover { text-decoration: underline; }
.se-render { border-top: 1px dashed var(--line); padding-top: 8px; }
@media (max-width: 899px) { .se-keys { display: none; } }

/* ---- review queue ---- */
.q-head { display: grid; gap: 8px; }
.q-head .meter { margin-top: 0; }
.q-title { flex-wrap: nowrap; align-items: flex-start; }
.q-keys .btn { flex: 1 1 auto; justify-content: center; }

/* ---- owner scores 0-10 (song page card, review bar, songs list badge) ---- */
.score-pad { display: flex; flex-wrap: wrap; gap: 4px; }
.score-pad .btn { min-width: 36px; justify-content: center; font-variant-numeric: tabular-nums; font-weight: 600; }
.score-pad.compact .btn { min-width: 28px; min-height: 28px; padding: 2px 6px; }
.score-pad .btn.on { background: var(--lamp); border-color: var(--lamp); color: var(--bg); }
.score-pad .btn.sc-0.on { background: var(--danger); border-color: var(--danger); }
.score-pad .btn.sc-10.on { background: var(--ok); border-color: var(--ok); }
.score-pad .btn.sc-0:not(.on) { color: var(--danger); }
.score-pad .btn.sc-10:not(.on) { color: var(--ok); }
.rv-score { gap: 6px; flex-wrap: wrap; }
.score-badge { flex: none; min-width: 34px; padding: 3px 6px; border-radius: 8px; border: 1px solid var(--line); text-align: center;
  font-weight: 700; font-variant-numeric: tabular-nums; color: var(--faint); background: var(--raise); }
.score-badge.ok, .sc-txt.ok { color: var(--ok); } .score-badge.info, .sc-txt.info { color: var(--info); }
.score-badge.lamp, .sc-txt.lamp { color: var(--lamp); } .score-badge.warn, .sc-txt.warn { color: var(--warn); }
.score-badge.bad, .sc-txt.bad { color: var(--danger); }
.score-badge.ok { border-color: #8FC79A66; } .score-badge.bad { border-color: #E8907A66; }
.score-hist { max-height: 260px; overflow-y: auto; margin-top: 0; }
.score-hist div { white-space: pre-wrap; overflow-wrap: anywhere; }
.ok-text { color: var(--ok); }
.cat-warn { margin: 0 0 var(--gap); border-color: #E8907A66; }

/* ---- commissions 定制 ---- */
.cm-chat { display: flex; flex-direction: column; gap: 8px; max-height: 62vh; overflow: auto; padding-right: 4px; }
.cm-msg { max-width: 86%; padding: 8px 10px; border-radius: 12px; border: 1px solid var(--line); background: var(--raise); display: grid; gap: 6px; }
.cm-msg.us { align-self: flex-end; background: var(--paper); }
.cm-msg.them { align-self: flex-start; }
.cm-msg.special { border-color: #E8B66C88; background: var(--lamp-dim); }
.cm-text { white-space: pre-wrap; overflow-wrap: anywhere; }
.cm-sys { align-self: center; text-align: center; font-size: 12.5px; color: var(--muted); }
.cm-note { color: var(--ink); }
.cm-price { font-size: 22px; font-weight: 700; color: var(--lamp); }
.cm-img { max-width: 240px; max-height: 200px; border-radius: 10px; display: block; }
.cm-audio audio { min-width: 220px; }
