/* ============================================================
   conor.bio — /log (gig log) page-scoped styles.
   Only what site.css has no class for. Form fields, labels, the
   submit button and the custom checkbox all reuse site.css's
   .quote-* / .songs-checkbox* / .song-* classes as-is. Tokens
   only; nothing here edits tokens.css or site.css.
   ============================================================ */

/* Bare admin page: the wordmark alone, linking home. Sizing comes
   from site.css's .header-wordmark img (--wordmark-height-m). */
.log-admin-home {
  padding: var(--s2) var(--grid-margin);
  /* site.css's >=768px .header-wordmark rule assumes a header grid:
     justify-self:center (which Chrome applies to a block child, so it
     shrinks and centres) and a translateY level with the nav text.
     Neither applies to a bare page; left-aligned at every width. */
  justify-self: start;
  transform: none;
}

/* Date is short content; same "field width by expected content"
   logic as the quote form's date field (site.css .quote-field--date). */
.log-field--date { grid-column: 1 / 5; }
@media (min-width: 768px) {
  .log-field--date { grid-column: 1 / 4; }
}

/* File input — no other form on the site uploads. Same box as
   .quote-input; the native button inside takes the same type. */
.log-file {
  width: 100%;
  max-width: 100%;
  min-height: var(--tap-target-min);
  border: var(--rule);
  border-radius: var(--shape-firm-a);
  padding-inline: var(--rule-pad);
  padding-block: var(--s1);
  font-family: var(--font-body);
  font-size: var(--t-body);
  color: var(--ink);
  background: var(--ground);
}
.log-file::file-selector-button {
  margin-right: var(--s2);
  border: var(--rule);
  border-radius: var(--shape-firm-a);
  padding-inline: var(--s2);
  min-height: var(--tap-target-min);
  font-family: var(--font-body);
  font-size: var(--t-label);
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
  color: var(--ink);
  background: var(--ground);
}
.log-hint {
  margin: 0;
  font-size: var(--t-label);
  color: var(--ink-quiet);
}
.log-current {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2);
}
.log-current[hidden] { display: none; }

/* Boxed secondary control: Cancel, Delete. Same box as the fields. */
.log-button {
  border: var(--rule);
  border-radius: var(--shape-firm-a);
  padding-inline: var(--rule-pad);
  min-height: var(--tap-target-min);
  font-family: var(--font-body);
  font-size: var(--t-label);
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
  color: var(--ink);
  background: var(--ground);
}
.log-button[hidden] { display: none; }

.log-actions {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
}
.log-actions .quote-error { flex: 1 0 100%; }

/* Two-step delete and remove. Both labels share one grid cell so the button
   never changes size; only one is visible. Same technique as
   .copy-label / .quote-submit-label in site.css. */
.log-swap { display: inline-grid; }
.log-swap span { grid-area: 1 / 1; }
.log-swap .state-confirm { visibility: hidden; }
.log-delete.is-confirming .state-default,
.log-remove.is-confirming .state-default { visibility: hidden; }
.log-delete.is-confirming .state-confirm,
.log-remove.is-confirming .state-confirm { visibility: visible; }
.log-delete.is-confirming,
.log-remove.is-confirming {
  background: var(--ink);
  color: var(--ink-inverse);
}

/* Entry list — the song list's construction (.songs-index box,
   .song-row dividers and padding rhythm), without its fixed height
   and inner scroll: the admin list is long and scrolls with the page. */
.log-list {
  grid-column: 1 / -1;
  border: var(--rule);
  padding: var(--s2) var(--rule-pad);
  border-radius: var(--shape-mid-a);
}
@media (max-width: 767px) {
  .log-list { padding: var(--s2); }
}

/* .song-row is a flex row/column; the admin row is checkbox | entry |
   delete, so it becomes a three-track grid at every width. */
.song-row.log-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  column-gap: var(--s2);
}
.log-row-main {
  display: flex;
  flex-direction: column;
  gap: var(--s1);
  min-width: 0;
  min-height: var(--tap-target-min);
  justify-content: center;
  text-align: left;
}
.log-row-main .song-artist { text-align: left; }
/* Edit and Delete sit together at the row's end, --s2 apart (the row's
   own column gap). The confirm state makes Delete wide; on a phone both
   drop under the entry instead of squeezing the title. */
.log-row-actions { display: flex; align-items: center; gap: var(--s2); }
@media (max-width: 767px) {
  .song-row.log-row { grid-template-columns: auto 1fr; }
  .log-row .log-row-actions { grid-column: 2; justify-self: start; margin-top: var(--s1); }
}
.log-row.is-editing .song-title { font-weight: var(--weight-strong); }
.log-row .songs-checkbox { min-height: var(--tap-target-min); }
.log-empty {
  margin: 0;
  padding-block: var(--rule-pad);
  color: var(--ink-quiet);
}

/* Copy Markdown — the mobile sticky CTA's treatment (--ink fill,
   --ink-inverse text, --font-masthead, 15px caps, --track-caps) in the
   --shape-firm family. Its two labels sit in site.css's .copy-label
   grid cell, so the button never resizes when the label swaps. */
.log-toolbar {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s2);
  margin-bottom: var(--s2);
}
.log-toolbar .quote-error { flex: 1 0 100%; }
.log-copy {
  border: var(--rule);
  border-radius: var(--shape-firm-c);
  background: var(--ink);
  color: var(--ink-inverse);
  padding-inline: var(--rule-pad);
  padding-block: var(--s2);
  min-height: var(--tap-target-min);
  font-family: var(--font-masthead);
  font-size: var(--t-label);
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
}
.log-copy .copy-label { text-align: center; }

/* ---------- PUBLIC PAGE (/log) ------------------------------------ */

/* Box and dividers are the song list's (.song-row rules in site.css);
   the entry list reuses .log-list above for the box. Each entry is a
   .song-row head button plus a drawer, so the divider sits on the
   entry, not the head. */
/* The public log lives only in a big window on the homepage
   (log/popup.js). The window's frame and title bar stay dark; its body
   is a light pane (--ground, the Newsletter window's look) holding the
   log as designed. The window frame is the box, so the list drops its
   own border and radius there and keeps its padding. The pane scrolls;
   entries need no header clearance inside it. */
.log-pane {
  height: 100%;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--ground);
  color: var(--ink);
}
.log-pane .log-list { border: 0; border-radius: 0; }
.log-pane .log-entry { scroll-margin-top: 0; }
.log-entry { scroll-margin-top: var(--header-row1-m); }
.log-entry:not(:last-child) { border-bottom: var(--rule); }
.song-row.log-entry-head {
  width: 100%;
  border-bottom: none;
  text-align: left;
  color: var(--ink);
}
.log-entry-date { color: var(--ink-quiet); font-size: var(--t-label); }
.log-entry-head .song-artist { text-align: left; }
@media (min-width: 768px) {
  .song-row.log-entry-head {
    display: grid;
    grid-template-columns: 1fr 2fr 1fr;
    align-items: baseline;
    column-gap: var(--grid-gutter);
  }
  .log-entry-date { font-size: inherit; }
  .log-entry-head .song-artist { font-size: var(--t-label); }
}
.log-entry-head[aria-expanded="true"] .log-entry-event { font-weight: var(--weight-strong); }

/* Drawer: the same 0fr/1fr grid-row toggle the header dropdown uses
   (site.css), snapping with no transition. Without JS every drawer
   stays open (.js is set by an inline script in the page head). */
.log-drawer { display: grid; grid-template-rows: 1fr; }
.js .log-drawer { grid-template-rows: 0fr; }
.js .log-entry.is-open .log-drawer { grid-template-rows: 1fr; }
.log-drawer-clip { min-height: 0; overflow: hidden; }
.js .log-drawer-clip { visibility: hidden; }
.js .log-entry.is-open .log-drawer-clip { visibility: visible; }
.log-drawer-body {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
  margin-bottom: var(--s2);
  border: var(--rule);
  border-radius: var(--shape-mid-b);
  padding: var(--s2);
}
@media (min-width: 768px) {
  .log-drawer-body { padding: var(--rule-pad); margin-bottom: var(--rule-pad); }
}
.log-drawer-body > * { margin: 0; }
.log-label {
  font-size: var(--t-label);
  text-transform: uppercase;
  letter-spacing: var(--track-caps);
  color: var(--ink-quiet);
  margin-right: var(--s1);
}
.log-notes { max-width: var(--measure); white-space: pre-line; }
/* A flex column stretches an <img> to full width, which blows a
   square photo up to a page tall; align-self keeps its own size. */
.log-photo {
  align-self: flex-start;
  max-width: min(100%, var(--measure));
  height: auto;
  border-radius: var(--shape-firm-a);
}

/* ---------- AUDIO PLAYER ------------------------------------------- */

/* Custom player, no native <audio> chrome. Play/Pause reuses the
   .log-button box and .log-swap's one-grid-cell label swap; the seek
   bar is a real <input type="range"> (keyboard and touch come free),
   drawn as a boxed track with an --ink fill up to --seek-fill, which
   js/public.js sets. The readout is 15px --ink-quiet. */
.log-audio {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas: "scope scope" "toggle time" "seek seek";
  align-items: center;
  gap: var(--s2);
}
@media (min-width: 768px) {
  .log-audio {
    grid-template-columns: auto 1fr auto;
    grid-template-areas: "scope scope scope" "toggle seek time";
  }
}
.log-audio audio { display: none; }
.log-audio-toggle { grid-area: toggle; }
.log-audio-toggle.is-playing .state-default { visibility: hidden; }
.log-audio-toggle.is-playing .state-confirm { visibility: visible; }
.log-audio-toggle.is-playing {
  background: var(--ink);
  color: var(--ink-inverse);
}
.log-audio-time {
  grid-area: time;
  justify-self: end;
  font-size: var(--t-label);
  color: var(--ink-quiet);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.log-audio-seek {
  grid-area: seek;
  width: 100%;
  min-width: 0;
  height: var(--tap-target-min);
  margin: 0;
  background: none;
  -webkit-appearance: none;
  appearance: none;
}
.log-audio-seek::-webkit-slider-runnable-track {
  height: var(--checkbox-size);
  border: var(--rule);
  border-radius: var(--shape-firm-a);
  background: linear-gradient(to right, var(--ink) var(--seek-fill, 0%), var(--ground) var(--seek-fill, 0%));
}
.log-audio-seek::-moz-range-track {
  height: var(--checkbox-size);
  border: var(--rule);
  border-radius: var(--shape-firm-a);
  background: linear-gradient(to right, var(--ink) var(--seek-fill, 0%), var(--ground) var(--seek-fill, 0%));
}
.log-audio-seek::-webkit-slider-thumb { -webkit-appearance: none; width: 0; height: 0; }
.log-audio-seek::-moz-range-thumb { width: 0; height: 0; border: none; }
.log-audio-seek:disabled { cursor: not-allowed; }

/* Without JS the player can't run; the <noscript> download link is the
   only control, so the dead ones are hidden. */
html:not(.js) .log-audio-toggle,
html:not(.js) .log-audio-seek,
html:not(.js) .log-audio-time,
html:not(.js) .log-scope { display: none; }

/* ---------- OSCILLOSCOPE (stage 7) --------------------------------- */

/* PENDING A TOKEN. The oscilloscope is a NEW MOTION entry (the eighth:
   the list currently holds seven) and its values below belong in
   tokens.css. They live here, commented, until that file's owner adds
   them; see the hand-off note in GIG-LOG-SPEC.md. log/scope.js reads
   these custom properties, so retuning is a CSS-only change.

   Height is the existing --s8 spacing step (128px). The grid's cell
   is --scope-cell (tokens.css); --scope-max is a grain's side as a
   fraction of that cell. At rest only the bottom row shows. */
.log-scope {
  grid-area: scope;
  display: block;
  width: 100%;
  height: var(--s8);
  --scope-max: 0.85;
}
