/* The cover on the track studio, and the crop-and-zoom modal (2026-09-09).
 *
 * Loaded LAST in foundry/app/index.html so these rules win on the studio head
 * without !important. Two things live here and nothing else: the record's
 * cover in the studio head with its "Change cover" control, and the square
 * frame the profile photo is cropped in (js/crop.js). Same tokens as
 * style.css, no gradients, no glow — a hard-edged scrim is the only shading. */

/* ---------- the cover in the studio head ----------
 * A column: the picture, then the one control under it, so the button reads
 * as belonging to the picture and not to the title beside it. The face is the
 * same shape the library card's cover wears — the library's square in the
 * studio's row. */
.studio-cover { display: flex; flex-direction: column; align-items: center; gap: 6px; flex: none; }
.studio-cover-face {
  width: 72px; height: 72px; border-radius: var(--r-ctl); overflow: hidden;
  border: 1px solid var(--border); background: var(--surface-2);
  display: grid; place-items: center; position: relative;
}
.studio-cover-img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* A face with no picture yet: the same note the library card draws, quiet. */
.studio-cover-glyph { color: var(--text-3); font-size: 22px; line-height: 1; }
.studio-cover-btn { font-size: 12px; padding: 4px 8px; }
.studio-cover-note { font-size: 12px; color: var(--text-3); max-width: 160px; text-align: center; margin: 0; }
.studio-cover-note:empty { display: none; }
.studio-cover.is-busy .studio-cover-face { opacity: 0.55; }

@media (max-width: 640px) {
  .studio-cover-face { width: 56px; height: 56px; }
}

/* ---------- the crop modal ----------
 * Same surface language as the record dialog (.t-overlay/.t-modal): a card
 * over a dimmed page, one live thing. */
.crop-overlay {
  position: fixed; inset: 0; z-index: 70;
  background: color-mix(in srgb, var(--bg) 74%, transparent);
  display: flex; align-items: center; justify-content: center;
  padding: 16px; overflow-y: auto;
  animation: crop-in 120ms ease-out;
}
@keyframes crop-in { from { opacity: 0; } to { opacity: 1; } }
.crop-modal {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r);
  width: min(420px, 100%); padding: 18px 20px 18px;
  display: flex; flex-direction: column; gap: 14px;
}
.crop-head { display: flex; flex-direction: column; gap: 4px; }
.crop-title { font-size: 17px; font-weight: 600; margin: 0; letter-spacing: -0.2px; }
.crop-hint { margin: 0; font-size: 12.5px; color: var(--muted); line-height: 1.5; }

/* The frame is square and the picture inside it is laid out at natural size,
 * centred, then moved by a transform crop.js computes — the same numbers the
 * export reads. touch-action none so a finger drags the picture, not the page. */
.crop-frame {
  position: relative; align-self: center;
  width: min(320px, 100%); aspect-ratio: 1 / 1;
  overflow: hidden; border-radius: var(--r-ctl);
  border: 1px solid var(--border); background: var(--surface-2);
  cursor: grab; touch-action: none; user-select: none; -webkit-user-select: none;
}
.crop-frame.is-dragging { cursor: grabbing; }
.crop-frame:focus-visible { outline: 2px solid var(--border-2); outline-offset: 2px; }
.crop-img {
  position: absolute; max-width: none; display: block;
  transform-origin: center center; will-change: transform;
  pointer-events: none; -webkit-user-drag: none;
}
/* The circle the avatar is shown in, drawn over the square so what is outside
 * it reads as "kept in the file, not shown in the ring". A solid scrim with a
 * hard edge — the zero-blur shadow is a mask, not a glow. */
.crop-mask { display: none; }
.crop-frame.is-circle .crop-mask {
  display: block; position: absolute; inset: 0; border-radius: 50%;
  box-shadow: 0 0 0 400px color-mix(in srgb, var(--bg) 55%, transparent);
  pointer-events: none;
}
.crop-state {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 13px; color: var(--muted); background: var(--surface-2);
}
.crop-state[hidden] { display: none; }

.crop-zoom { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.crop-zoom-k { color: var(--muted); flex: none; }
.crop-zoom-v { color: var(--text-2); flex: none; min-width: 3.2em; text-align: right; font-variant-numeric: tabular-nums; }
.crop-zoom input[type=range] { flex: 1; min-width: 0; accent-color: var(--text); margin: 0; }

.crop-acts { display: flex; justify-content: flex-end; gap: 8px; }

@media (prefers-reduced-motion: reduce) {
  .crop-overlay { animation: none; }
}

/* ---------- the photo actually shows in its circle ----------
 * Measured while verifying the crop (2026-09-09): a signed-in account's
 * avatar wears BOTH .on and .has-img, and style.css declares `.avatar.on`
 * (a `background` shorthand and an ink colour) 200 lines AFTER
 * `.avatar.has-img` (background-size: cover, color: transparent) at the same
 * specificity — so the shorthand reset the size to auto and the initials
 * were painted over the picture. Every stored photo rendered as initials on
 * the account card and in the rail. Restated here at higher specificity, in
 * the file that ships the crop, because "Adjust" beside a circle that never
 * shows the photo is not a feature. The inline background-image is what
 * app.js already sets; this only lets it be seen. */
.avatar.on.has-img {
  background-size: cover; background-position: center; color: transparent;
}
