/* ==========================================================================
   asset-slots.css — placeholder wells for assets that aren't in yet

   A slot is a `.media` that reserves its final aspect ratio up front and, while
   its file is missing, paints a labelled well in that exact box instead. So the
   page lays out at its true height from the first draft, and every gap states
   what belongs in it and what to name the file.

   `.media` is already `position: relative` (blocks.css), so the well's absolute
   children resolve against the slot rather than the band — which is what keeps
   `under-line` safe on a band that contains one.

   Filled and empty are decided by scripts/asset-slots.js, which adds
   `is-empty` / `is-filled`. Without JS a slot with a missing file shows the
   well's styling minus the state classes, i.e. an empty bordered box — never a
   broken-image icon on a collapsed line.
   ========================================================================== */

.media.slot {
  --slot-ink: #8a8a8f;
  --slot-ink-strong: #1d1d1f;
  --slot-line: rgba(0, 0, 0, 0.16);
  --slot-fill: rgba(0, 0, 0, 0.022);
  --slot-accent: #0a84ff;
}

/*
 * The box itself carries the border, not the well — so a slot whose file is
 * missing reads as an empty frame at the right ratio even with JS off, which is
 * the honest failure. The well only adds the words.
 */
.slots-ready .media.slot:not(.is-filled) {
  border: 1px dashed var(--slot-line);
  border-radius: 10px;
  background: var(--slot-fill);
  transition:
    border-color 160ms ease,
    background-color 160ms ease;
}

.slots-ready .media.slot:not(.is-filled):hover {
  border-color: rgba(0, 0, 0, 0.28);
}

/* Drag state: the whole box takes the accent so the target is unambiguous. */
.media.slot.is-dragover {
  border-color: var(--slot-accent);
  border-style: solid;
  background: rgba(10, 132, 255, 0.06);
}

/* Hide the well the moment a real file is confirmed. */
.media.slot.is-filled > .slot-well {
  display: none;
}

/*
 * And hide the media element until then, so a 404 can't flash its icon.
 * Scoped under `.slots-ready`, which asset-slots.js adds: if that script never
 * runs, nothing here applies and the images simply show. Unscoped, a blocked
 * script would hide every image on the page.
 */
.slots-ready .media.slot:not(.is-filled) > img,
.slots-ready .media.slot:not(.is-filled) > video {
  visibility: hidden;
}

/* --- the well ---------------------------------------------------------- */

.media.slot > .slot-well {
  position: absolute;
  inset: 0;
  z-index: 1;

  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;

  padding: 24px;
  text-align: center;
  line-height: 1.45;
  color: var(--slot-ink);

  /*
   * `1rem` is the 10px root, so every `em` below resolves against 10px no
   * matter where the slot is placed. Without this the well inherits its
   * container's size — inside a case body column that is 17px, which rendered
   * the well's own 1.7em title at 29px.
   */
  font-size: 1rem;
}

/* --- well contents ----------------------------------------------------- */

/* "07" — the slot's number, matching the manifest in the assets folder. */
.media.slot .slot-index {
  font-size: 1.1em;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: #c4c4c8;
}

/* What the asset should show. The one line to read if you read nothing else. */
.media.slot .slot-title {
  max-width: 46ch;
  font-size: 1.7em;
  font-weight: 600;
  color: var(--slot-ink-strong);
}

.media.slot .slot-desc {
  max-width: 62ch;
  font-size: 1.4em;
}

/* Filename + dimensions, in mono so they read as things to be typed. */
.media.slot .slot-file,
.media.slot .slot-spec {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: 1.2em;
}

.media.slot .slot-file {
  display: inline-flex;
  align-items: center;
  gap: 8px;

  margin-top: 4px;
  padding: 5px 10px;
  border: 1px solid var(--slot-line);
  border-radius: 6px;
  background: #fff;
  color: var(--slot-ink-strong);

  cursor: copy;
  transition: border-color 160ms ease;
}

.media.slot .slot-file:hover {
  border-color: var(--slot-accent);
}

.media.slot .slot-file::after {
  content: "copy";
  font-size: 0.82em;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--slot-ink);
}

.media.slot .slot-file.is-copied::after {
  content: "copied";
  color: var(--slot-accent);
}

.media.slot .slot-spec {
  color: #aeaeb2;
}

/* "or drop a file here to preview" — only worth saying where there's a cursor
   to drop with, and only on a device that can drag at all. */
.media.slot .slot-drop {
  font-size: 1.2em;
  color: #c4c4c8;
}

@media (hover: none) {
  .media.slot .slot-drop {
    display: none;
  }
}

/* --- compact wells ----------------------------------------------------- */
/*
 * For slots in boxes too small to hold the full stack — the logo grid forces
 * `aspect-ratio: 1 / 1`, which on a phone is a ~155px cell. Keep the number
 * and the filename; the description and the spec are in the manifest.
 */

.media.slot.slot-compact > .slot-well {
  gap: 6px;
  padding: 10px;
}

.media.slot.slot-compact .slot-desc,
.media.slot.slot-compact .slot-spec,
.media.slot.slot-compact .slot-drop {
  display: none;
}

.media.slot.slot-compact .slot-title {
  font-size: 1.3em;
}

.media.slot.slot-compact .slot-file {
  font-size: 1.05em;
}

/* --- session preview --------------------------------------------------- */
/*
 * A dropped file is previewed from an object URL: it is in the page but not on
 * disk, and it is gone on reload. The badge is there so that is never mistaken
 * for a file that actually landed.
 */

.media.slot.is-preview::after {
  content: "session preview — not saved";
  position: absolute;
  z-index: 2;
  top: 10px;
  left: 10px;

  padding: 4px 8px;
  border-radius: 5px;
  background: rgba(10, 132, 255, 0.92);

  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: 1.1em;
  line-height: 1;
  color: #fff;
}

/* --- dark bands -------------------------------------------------------- */
/*
 * Slots on the cover and on any dark surface invert, otherwise a light well
 * punches a hole through the band.
 */

.surface-cover .media.slot,
.surface-accent .media.slot,
.media.slot.on-dark {
  --slot-ink: rgba(255, 255, 255, 0.56);
  --slot-ink-strong: #f5f5f7;
  --slot-line: rgba(255, 255, 255, 0.24);
  --slot-fill: rgba(255, 255, 255, 0.04);
}

.surface-cover .media.slot .slot-index,
.surface-accent .media.slot .slot-index,
.media.slot.on-dark .slot-index,
.surface-cover .media.slot .slot-spec,
.surface-accent .media.slot .slot-spec,
.media.slot.on-dark .slot-spec,
.surface-cover .media.slot .slot-drop,
.surface-accent .media.slot .slot-drop,
.media.slot.on-dark .slot-drop {
  color: rgba(255, 255, 255, 0.42);
}

.surface-cover .media.slot .slot-file,
.surface-accent .media.slot .slot-file,
.media.slot.on-dark .slot-file {
  background: rgba(255, 255, 255, 0.08);
}

/* --- small screens ----------------------------------------------------- */
/*
 * A slot keeps its aspect ratio on a phone, so a 3:4 well is short and a 16:9
 * one is very short. Drop the secondary lines rather than let the stack
 * overflow its own box.
 */

@media (max-width: 768px) {
  .media.slot > .slot-well {
    gap: 6px;
    padding: 14px;
  }

  .media.slot .slot-title {
    font-size: 1.5em;
  }

  .media.slot .slot-desc,
  .media.slot .slot-drop {
    display: none;
  }
}

/* ==========================================================================
   The checklist panel — scripts/asset-slots.js, localhost only

   A fixed pill listing what is still missing, so filling the page in doesn't
   mean scrolling it looking for dashed boxes. Never rendered on a real host.
   ========================================================================== */

.slot-panel {
  position: fixed;
  z-index: 1500;
  /* Above the reading bar's 144px scrim, so it never sits on the options
     button in the bar's bottom-left corner. */
  bottom: 168px;
  left: 16px;

  max-width: min(420px, calc(100vw - 32px));
  border-radius: 12px;
  border: 1px solid rgba(0, 0, 0, 0.1);
  background: rgba(255, 255, 255, 0.86);
  backdrop-filter: blur(20px) saturate(180%);
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.08),
    0 12px 32px rgba(0, 0, 0, 0.16);

  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
  font-size: 1.2em;
  color: #1d1d1f;
  overflow: hidden;
}

.slot-panel__toggle {
  display: block;
  width: 100%;
  padding: 10px 14px;
  border: 0;
  background: none;

  font: inherit;
  text-align: left;
  color: inherit;
  cursor: pointer;
}

.slot-panel__toggle b {
  font-weight: 600;
}

.slot-panel__list {
  display: none;
  max-height: min(52vh, 480px);
  margin: 0;
  padding: 0 6px 6px;
  overflow-y: auto;
}

.slot-panel.is-open .slot-panel__list {
  display: block;
}

.slot-panel__list li {
  border-top: 1px solid rgba(0, 0, 0, 0.06);
}

.slot-panel__list button {
  display: block;
  width: 100%;
  padding: 8px;
  border: 0;
  border-radius: 7px;
  background: none;

  font: inherit;
  text-align: left;
  color: inherit;
  cursor: pointer;
}

.slot-panel__list button:hover {
  background: rgba(0, 0, 0, 0.04);
}

.slot-panel__list .n {
  color: #aeaeb2;
  margin-right: 8px;
}

.slot-panel__list .f {
  display: block;
  margin-top: 2px;
  color: #0a84ff;
}

@media print {
  .slot-panel {
    display: none;
  }
}
