/* Rochtunes — design tokens ported from LincTunes/public/style.css:1-24.
   Dark only, mobile-first: most contributions arrive from a phone. */

:root {
  --bg:            #111111;
  --surface:       #1a1a1a;
  --surface-hover: #222222;
  --border:        #2a2a2a;
  --text:          #e5e5e5;
  --text-dim:      #888888;
  --accent:        #6366f1;
  --accent-hover:  #818cf8;
  --accent-muted:  #4f46e5;
  --success:       #4ade80;
  --warning:       #facc15;
  --danger:        #f87171;
  --danger-bg:     #dc2626;

  --font-heading: "Space Grotesk", -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* One type scale. Every size on the site comes from here, so text lines up
     across pages instead of drifting a half-pixel at a time. 16px on inputs is
     a hard floor, not a preference: below it iOS zooms the page on focus. */
  --fs-display: 26px;   /* the one big number on a page: gate heading, keys  */
  --fs-title:   20px;   /* page and panel headings                           */
  --fs-lead:    15px;   /* opening paragraph                                 */
  --fs-body:    14px;   /* default                                           */
  --fs-sm:      12.5px; /* secondary lines, captions, footer                 */
  --fs-micro:   11px;   /* uppercase section labels, badges                  */
  --fs-input:   16px;   /* iOS zoom floor                                    */
  --fs-icon:    17px;   /* standalone icons                                  */

  --ls-tight:  -0.01em; /* large headings                                    */
  --ls-label:   0.08em; /* uppercase labels                                  */
  --ls-key:     0.3em;  /* the spaced-out access key                         */

  --radius: 6px;
  --radius-lg: 8px;
}

*, *::before, *::after { box-sizing: border-box; }

/* iOS Safari zooms the whole page when a focused input is under 16px, then
   zooms back out on blur -- which reads as the page jumping around every time
   you tap the search box. 16px is the threshold, not a style choice.
   Deliberately NOT fixed with maximum-scale=1 on the viewport: that would also
   block deliberate pinch-zoom, which people need. */
input, textarea, select { font-size: var(--fs-input); }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: var(--fs-body);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { font-family: var(--font-heading); font-weight: 600; margin: 0; }

.icon { width: 1em; height: 1em; stroke: currentColor; fill: none;
        stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
        flex: none; vertical-align: -0.125em; }

[hidden] { display: none !important; }

.view { max-width: 720px; margin: 0 auto; padding: 24px 16px 96px; }

/* ---------- key entry ---------- */

.gate { min-height: 100dvh; display: flex; align-items: center; justify-content: center; padding: 24px; }
.gate-card { width: 100%; max-width: 380px; text-align: center; }
.gate-card h1 { font-size: var(--fs-display); letter-spacing: var(--ls-tight); margin-bottom: 10px; }
.gate-card p { color: var(--text-dim); font-size: var(--fs-sm); margin: 0 0 24px; }

.key-input {
  width: 100%;
  font-family: var(--font-mono);
  font-size: var(--fs-display);
  letter-spacing: var(--ls-key);
  text-align: center;
  text-transform: uppercase;
  padding: 16px 12px 16px 24px; /* offset the trailing letter-space */
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  outline: none;
}
.key-input:focus { border-color: var(--accent); }
.key-input::placeholder { color: #3a3a3a; letter-spacing: var(--ls-key); }

/* ---------- buttons ---------- */

button {
  font-family: var(--font-mono);
  font-size: var(--fs-body);
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 9px 14px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  transition: background .12s, border-color .12s, opacity .12s;
}
button:hover:not(:disabled) { background: var(--surface-hover); border-color: #3a3a3a; }
button:disabled { opacity: .45; cursor: default; }

.btn-primary { background: var(--accent-muted); border-color: var(--accent-muted); color: #fff; width: 100%; justify-content: center; padding: 13px; margin-top: 14px; }
.btn-primary:hover:not(:disabled) { background: var(--accent); border-color: var(--accent); }

.btn-icon { padding: 8px; border-color: transparent; background: transparent; color: var(--text-dim); }
.btn-icon:hover:not(:disabled) { color: var(--danger); background: var(--surface-hover); border-color: transparent; }

.btn-add { padding: 8px 12px; }
.btn-add[data-state="added"] { color: var(--success); border-color: transparent; background: transparent; cursor: default; }

/* ---------- header ---------- */

.top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 20px; }
.top h1 { font-size: var(--fs-title); letter-spacing: var(--ls-tight); }
.top .who { color: var(--text-dim); white-space: nowrap; }
.top .who { display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-sm); }
.icon-link {  color: var(--text-dim); display: inline-flex; align-items: center;
  padding: 6px; border-radius: var(--radius); font-size: var(--fs-icon); text-decoration: none;
  transition: color .12s, background .12s;
}
.icon-link:hover { color: var(--text); background: var(--surface-hover); }
.top .who #who-name { margin-right: 4px; }

/* ---------- search ---------- */

.search-wrap { position: relative; margin-bottom: 8px; }
.search-wrap > .icon.lead { position: absolute; left: 13px; top: 50%; transform: translateY(-50%); color: var(--text-dim); font-size: var(--fs-icon); }
.search-input {
  width: 100%;
  font-family: var(--font-mono);
  font-size: var(--fs-input);
  padding: 13px 40px 13px 40px;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  outline: none;
}
.search-input:focus { border-color: var(--accent); }
.search-input::placeholder { color: #4a4a4a; }
.search-clear { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); }

/* input[type=search] draws its own clear button in Chrome and Safari on
   desktop, which sits right next to ours -- two X's doing slightly different
   things. Ours stays, because it also has to clear the results list, not just
   the field. Mobile Safari does not draw one, which is why this only showed up
   on desktop. */
.search-input::-webkit-search-cancel-button,
.search-input::-webkit-search-decoration { -webkit-appearance: none; appearance: none; display: none; }

/* ---------- rows ---------- */

.section-label {
  font-family: var(--font-heading);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--text-dim);
  margin: 26px 0 10px;
  display: flex; align-items: center; gap: 8px;
}

.rows { display: flex; flex-direction: column; gap: 2px; }


.row {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 10px;
  border-radius: var(--radius);
  background: transparent;
  min-width: 0;
}
.row:hover { background: var(--surface); }

.art { width: 44px; height: 44px; border-radius: 4px; background: var(--surface-hover); object-fit: cover; flex: none; }

.meta { flex: 1; min-width: 0; }
.meta .t { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.meta .s { color: var(--text-dim); font-size: var(--fs-sm); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.meta .s .dot { opacity: .5; margin: 0 6px; }

/* Artist and album are links: tapping either swaps the results for
   everything by that artist, or everything on that album. Underlined on
   hover only, so a row of results does not read as a wall of links. */
.pivot { color: inherit; text-decoration: none; border-bottom: 1px dotted #3d3d3d; }
.pivot:hover { color: var(--accent-hover); border-bottom-color: currentColor; }
.pivot.is-loading { opacity: .5; pointer-events: none; }

/* The record icon marks a row as an album rather than a song. It sits in the
   actions row, just left of Add, because what it qualifies is the button: one
   press there adds every song on the record. */
.row-kind { color: var(--accent-hover); font-size: var(--fs-icon); flex: none; margin-right: 3px; }
.variant { color: var(--text-dim); }

.row-actions { display: flex; align-items: center; gap: 4px; flex: none; }

/* ---------- misc ---------- */

.empty { color: var(--text-dim); font-size: var(--fs-sm); padding: 18px 10px; text-align: center; }
.count { color: var(--text-dim); font-weight: 400; font-family: var(--font-mono); letter-spacing: 0; text-transform: none; }

.spin { animation: spin 1s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

.msg { font-size: var(--fs-sm); margin-top: 12px; min-height: 19px; }
.msg.err { color: var(--danger); }
.msg.ok  { color: var(--success); }

#toast {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%);
  background: var(--surface); border: 1px solid var(--border);
  padding: 11px 16px; border-radius: var(--radius-lg);
  font-size: var(--fs-sm); max-width: calc(100vw - 32px);
  display: flex; align-items: center; gap: 9px;
  box-shadow: 0 8px 28px rgba(0,0,0,.5);
  animation: rise .18s ease-out;
}
#toast.err { border-color: var(--danger-bg); }
@keyframes rise { from { opacity: 0; transform: translate(-50%, 10px); } }

@media (max-width: 420px) {
  .view { padding: 18px 12px 88px; }
  .top { flex-direction: column; align-items: flex-start; gap: 2px; }
  .key-input { font-size: 23px; }
}

/* ---------- admin ---------- */

.panel { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 14px; margin-bottom: 10px; }
.panel-note { color: var(--text-dim); font-size: var(--fs-sm); margin: 0 0 10px; line-height: 1.55; }
.panel .msg { margin-top: 8px; }

.cmd { display: flex; align-items: center; gap: 6px; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius); padding: 10px 8px 10px 12px; }
.cmd code { flex: 1; font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--accent-hover); overflow-x: auto; white-space: nowrap; }
.cmd .btn-icon:hover { color: var(--accent-hover); }

.first-run { margin-top: 10px; }
.first-run summary { color: var(--text-dim); font-size: var(--fs-sm); cursor: pointer; padding: 4px 0; }
.first-run summary:hover { color: var(--text); }
.first-run .cmd { margin-top: 8px; }
.first-run .panel-note { margin: 10px 0 0; }

.invite-grid { display: grid; grid-template-columns: 1fr 1fr auto auto; gap: 8px; align-items: center; }
.rename-grid { display: grid; grid-template-columns: 1fr auto; gap: 8px; }
.invite-grid input, .rename-grid input {
  font-family: var(--font-mono); font-size: var(--fs-input); padding: 9px 11px;
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius); outline: none; min-width: 0;
}
.invite-grid input:focus, .rename-grid input:focus { border-color: var(--accent); }
.invite-grid input::placeholder { color: #4a4a4a; }

.chk { display: flex; align-items: center; gap: 6px; font-size: var(--fs-sm); color: var(--text-dim); white-space: nowrap; cursor: pointer; }
.chk input { accent-color: var(--accent); width: 15px; height: 15px; }
.chk:hover { color: var(--text); }

.row.member { padding: 10px; }
.row.member.is-revoked { opacity: .45; }
.mkey { font-family: var(--font-mono); font-size: var(--fs-sm); color: var(--accent-hover); letter-spacing: .06em; flex: none; }
.badge { font-size: var(--fs-micro); text-transform: uppercase; letter-spacing: var(--ls-label); padding: 2px 6px; border-radius: 3px; background: var(--accent-muted); color: #fff; margin-left: 7px; vertical-align: 1px; }
.badge.muted { background: var(--border); color: var(--text-dim); }

@media (max-width: 560px) {
  .invite-grid { grid-template-columns: 1fr 1fr; }
  .invite-grid .chk, .invite-grid button { grid-column: span 1; }
  .row.member { flex-wrap: wrap; }
  .mkey { order: 3; }
}

/* ---------- public forms ---------- */

.lede { color: var(--text-dim); font-size: var(--fs-lead); line-height: 1.6; margin: -8px 0 4px; }
.stack { display: flex; flex-direction: column; gap: 8px; }
.stack input, .stack textarea {
  font-family: var(--font-mono); font-size: var(--fs-input); padding: 11px 12px;
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius); outline: none; width: 100%; resize: vertical;
}
.stack input:focus, .stack textarea:focus { border-color: var(--accent); }
.stack input::placeholder, .stack textarea::placeholder { color: #4a4a4a; }
.key-sm { text-transform: uppercase; letter-spacing: var(--ls-key); }
.ts { margin-top: 10px; min-height: 0; }
.ts:not(:empty) { margin-bottom: 4px; }

.req-name { font-family: var(--font-heading); font-size: var(--fs-title); }
.req-email { color: var(--text-dim); font-size: var(--fs-sm); margin-top: 2px; }
blockquote { margin: 14px 0 0; padding: 11px 13px; background: var(--bg); border-left: 2px solid var(--accent-muted); border-radius: 0 var(--radius) var(--radius) 0; color: var(--text); font-size: var(--fs-body); line-height: 1.6; }
.decide { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 12px; }
.decide button { justify-content: center; padding: 13px; }
#btn-deny:hover:not(:disabled) { border-color: var(--danger-bg); color: var(--danger); }

/* ---------- site footer ---------- */

.site-foot {
  display: flex; gap: 22px; justify-content: center;
  margin-top: 40px; padding-top: 18px;
  border-top: 1px solid var(--border);
}
.site-foot a {
  color: var(--text-dim); font-size: var(--fs-sm); text-decoration: none;
  display: inline-flex; align-items: center; gap: 6px;
}
.site-foot a:hover { color: var(--text); }
.gate-card .site-foot { margin-top: 32px; }

.view.narrow { max-width: 560px; }
.aside { color: var(--text-dim); font-size: var(--fs-sm); margin: 12px 2px 0; }
.aside a { color: var(--accent-hover); text-decoration: none; }
.aside a:hover { text-decoration: underline; }

/* ---------- prose (How it works) ---------- */

.prose h2 {
  font-size: var(--fs-lead); margin: 34px 0 10px;
  display: flex; align-items: center; gap: 9px;
}
.prose h2 .icon { color: var(--accent-hover); font-size: var(--fs-icon); }
.prose p { color: var(--text-dim); line-height: 1.7; margin: 0 0 12px; font-size: var(--fs-body); }
.prose p strong { color: var(--text); }
.prose ul { color: var(--text-dim); line-height: 1.7; font-size: var(--fs-body); padding-left: 20px; margin: 0 0 12px; }
.prose li { margin-bottom: 7px; }
.prose a { color: var(--accent-hover); text-decoration: none; }
.prose a:hover { text-decoration: underline; }
.prose code {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 3px; padding: 1px 5px; font-size: var(--fs-sm); color: var(--text);
}
.prose .lede { font-size: var(--fs-lead); color: var(--text); margin-bottom: 8px; }
