/* =========================================================================
   styles.css - Rhythm of Praise
   ITEC100 reference project E

   One stylesheet, no framework, no build step, no web fonts.

   A lit stage seen from the back of a dark room: the board is the thing with
   light on it, everything else steps back so the eye goes where the notes
   are. The lane colours are the one place this page is allowed to be loud -
   they are how a player tells the columns apart at speed, and game.js reads
   them straight out of these custom properties, so changing a lane's colour
   here changes it on the canvas too.
   ========================================================================= */

:root {
  --ink: #f4f1e9;
  --ink-dim: #99a2b8;
  --ink-faint: #6f7893;

  --ground: #0a0d15;
  --ground-2: #0e1220;
  --panel: rgba(22, 27, 43, .72);
  --raise: rgba(255, 255, 255, .045);
  --line: rgba(255, 255, 255, .085);
  --line-strong: rgba(255, 255, 255, .16);

  --gold: #e8bc55;
  --gold-deep: #a9761d;
  --good: #59c9a8;
  --ok: #e8bc55;
  --miss: #e0616b;

  /* The four lanes. Read by the canvas as well as by this file. */
  --lane-1: #6fb1e0;
  --lane-2: #b48ce0;
  --lane-3: #e0a06f;
  --lane-4: #7fd0b8;

  --sans: "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", sans-serif;
  --display: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, ui-serif, serif;
  --mono: ui-monospace, "Cascadia Mono", Consolas, monospace;

  --radius: 18px;
  --shadow: 0 30px 80px -34px rgba(0, 0, 0, .9);
  --width: 1180px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  color: var(--ink);
  font-family: var(--sans);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  background: var(--ground);
  overflow-x: hidden;
}

.stage-light {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(720px 480px at 16% -8%, rgba(111, 177, 224, .16), transparent 62%),
    radial-gradient(680px 460px at 84% 0%, rgba(180, 140, 224, .15), transparent 60%),
    radial-gradient(900px 620px at 55% 110%, rgba(232, 188, 85, .10), transparent 64%),
    linear-gradient(180deg, var(--ground-2), var(--ground) 45%);
}

/* --- the hero ------------------------------------------------------------ */
.hero { max-width: var(--width); margin: 0 auto; padding: 2.6rem 1.4rem 1.2rem; }

.hero__inner {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1.5rem;
  align-items: center;
}

.eyebrow {
  margin: 0 0 .5rem;
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.hero h1 {
  margin: 0 0 .5rem;
  font-family: var(--display);
  font-size: clamp(2.2rem, 5.5vw, 3.3rem);
  font-weight: 600;
  line-height: 1.02;
  letter-spacing: -.015em;
  background: linear-gradient(96deg, #fffaf0 4%, var(--gold) 55%, #c79a3f 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero__lead { margin: 0; max-width: 60ch; color: var(--ink-dim); }

.mark { width: clamp(84px, 11vw, 116px); height: auto; }
.mark__lanes rect { fill: rgba(255, 255, 255, .10); }
.mark__lanes rect:nth-child(1) { fill: rgba(111, 177, 224, .55); }
.mark__lanes rect:nth-child(2) { fill: rgba(180, 140, 224, .45); }
.mark__lanes rect:nth-child(3) { fill: rgba(224, 160, 111, .5); }
.mark__lanes rect:nth-child(4) { fill: rgba(127, 208, 184, .4); }
.mark__line { stroke: var(--gold); stroke-width: 2.4; stroke-linecap: round; }
.mark__hit { fill: var(--gold); }
.mark__glow { animation: pulse 2.4s ease-in-out infinite; transform-origin: 60px 60px; }

@keyframes pulse { 0%, 100% { opacity: .5; } 50% { opacity: 1; } }

.verse {
  margin: 1rem 0 0;
  padding-left: 1rem;
  border-left: 2px solid rgba(232, 188, 85, .45);
}

.verse p {
  margin: 0;
  max-width: 54ch;
  font-family: var(--display);
  font-style: italic;
  font-size: 1rem;
  color: #e7e0cd;
}

.verse cite {
  display: block;
  margin-top: .2rem;
  font-style: normal;
  font-size: .72rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* --- the deck: board on the left, everything about it on the right ------- */
.deck {
  max-width: var(--width);
  margin: 0 auto;
  padding: .6rem 1.4rem 2.5rem;
  display: grid;
  grid-template-columns: minmax(0, 560px) minmax(260px, 1fr);
  gap: 1.4rem;
  align-items: start;
}

.cabinet {
  position: relative;
  padding: .9rem .9rem 1rem;
  background: linear-gradient(180deg, rgba(28, 34, 52, .9), rgba(14, 18, 30, .95));
  border: 1px solid var(--line);
  border-radius: 22px;
  box-shadow: var(--shadow);
}

/* The light along the top edge of the cabinet, as if the board were lit from
   above rather than glowing on its own. */
.cabinet::before {
  content: "";
  position: absolute;
  top: 0;
  left: 12%;
  right: 12%;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(232, 188, 85, .6), rgba(111, 177, 224, .4), transparent);
}

.stage {
  position: relative;
  border-radius: 14px;
  overflow: hidden;
  background: #060810;
}

.stage canvas {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 560 / 720;
}

/* --- the overlay --------------------------------------------------------- */
.overlay {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 1rem;
  background: radial-gradient(120% 90% at 50% 0%, rgba(6, 8, 16, .72), rgba(6, 8, 16, .93));
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}

.overlay[hidden] { display: none; }

.card {
  width: min(100%, 27rem);
  max-height: 100%;
  overflow-y: auto;
  padding: 1.3rem 1.4rem 1.5rem;
  text-align: center;
  background: linear-gradient(180deg, rgba(30, 36, 56, .96), rgba(18, 22, 35, .97));
  border: 1px solid var(--line-strong);
  border-radius: 16px;
  box-shadow: 0 30px 70px -22px rgba(0, 0, 0, .9);
  scrollbar-width: thin;
}

.card h2 {
  margin: 0 0 .5rem;
  font-family: var(--display);
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -.01em;
}

.card p { margin: .4rem 0; color: var(--ink-dim); font-size: .92rem; }
.sub { color: var(--ink-dim); font-size: .92rem; }
.tiny { font-size: .8rem; color: var(--ink-faint); }

.keys { display: flex; justify-content: center; gap: .4rem; margin: .9rem 0 .3rem; }

kbd {
  display: inline-grid;
  place-items: center;
  min-width: 2.2rem;
  padding: .35rem .5rem;
  font: inherit;
  font-size: .9rem;
  font-weight: 600;
  color: var(--ink);
  background: linear-gradient(180deg, rgba(255, 255, 255, .10), rgba(255, 255, 255, .03));
  border: 1px solid var(--line-strong);
  border-bottom-width: 3px;
  border-radius: 9px;
}

.keys kbd:nth-child(1) { border-bottom-color: var(--lane-1); }
.keys kbd:nth-child(2) { border-bottom-color: var(--lane-2); }
.keys kbd:nth-child(3) { border-bottom-color: var(--lane-3); }
.keys kbd:nth-child(4) { border-bottom-color: var(--lane-4); }

.btn {
  margin: 1rem 0 .2rem;
  font: inherit;
  font-weight: 600;
  font-size: .98rem;
  color: #1c1402;
  background: linear-gradient(180deg, #f5cf6e, var(--gold) 55%, #cf9f3a);
  border: 0;
  border-radius: 999px;
  padding: .7rem 2rem;
  cursor: pointer;
  transition: transform .14s ease, filter .14s ease;
  box-shadow: 0 10px 26px -12px rgba(232, 188, 85, .9);
}

.btn:hover { transform: translateY(-1px); filter: brightness(1.05); }
.btn:active { transform: translateY(0); }

/* The secondary buttons. Without these every button on the page was the
   primary one, which is the same as having none: three gold buttons in a row
   say nothing about which to press. */
.btn--small { padding: .45rem 1rem; font-size: .86rem; }

.btn--quiet {
  color: var(--ink);
  background: var(--raise);
  border: 1px solid var(--line);
  box-shadow: none;
}

.btn--quiet:hover { border-color: rgba(232, 188, 85, .5); background: rgba(232, 188, 85, .08); }

.btn[disabled] {
  opacity: .45;
  cursor: default;
  transform: none;
  filter: none;
}

:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; border-radius: 8px; }

/* --- opening a recording ------------------------------------------------- */
.own-song {
  margin-top: 1.2rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
}

.file {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .7rem;
  margin: .6rem 0 .5rem;
  padding: .8rem 1rem;
  text-align: left;
  font-size: .86rem;
  color: var(--ink-dim);
  background: var(--raise);
  border: 1.5px dashed var(--line-strong);
  border-radius: 12px;
  cursor: pointer;
  transition: border-color .18s ease, background-color .18s ease;
}

.file:hover, .file:focus-within, .file.is-over {
  border-color: rgba(232, 188, 85, .7);
  background: rgba(232, 188, 85, .08);
}

.file svg { color: var(--gold); flex: none; }
.file strong { color: var(--ink); font-weight: 600; }

.file input[type="file"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

/* --- lane buttons, under the board --------------------------------------- */
.lanes {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: .5rem;
  margin-top: .8rem;
}

.lane-btn {
  font: inherit;
  font-weight: 700;
  font-size: 1rem;
  letter-spacing: .04em;
  color: var(--ink);
  background: linear-gradient(180deg, rgba(255, 255, 255, .08), rgba(255, 255, 255, .02));
  border: 1px solid var(--line);
  border-bottom-width: 3px;
  border-radius: 12px;
  padding: .75rem .4rem;
  cursor: pointer;
  transition: transform .08s ease, background-color .08s ease;
  touch-action: manipulation;
  user-select: none;
}

.lane-btn:nth-child(1) { border-bottom-color: var(--lane-1); }
.lane-btn:nth-child(2) { border-bottom-color: var(--lane-2); }
.lane-btn:nth-child(3) { border-bottom-color: var(--lane-3); }
.lane-btn:nth-child(4) { border-bottom-color: var(--lane-4); }

.lane-btn.is-down,
.lane-btn:active {
  transform: translateY(2px);
  background: rgba(255, 255, 255, .14);
}

/* --- the HUD ------------------------------------------------------------- */
.hud { display: grid; gap: .9rem; position: sticky; top: 1rem; }

.panel {
  position: relative;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1rem 1.1rem 1.1rem;
  box-shadow: var(--shadow);
}

.panel .eyebrow { margin-bottom: .35rem; }
.panel .sub { margin: .35rem 0 0; font-size: .88rem; }

.hud__song {
  margin: 0;
  font-family: var(--display);
  font-size: 1.05rem;
  color: var(--ink);
}

.scores {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: .6rem;
  margin: 0;
}

.score {
  padding: .7rem .85rem .8rem;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
}

.score dt {
  font-size: .66rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.score dd {
  margin: .15rem 0 0;
  font-family: var(--mono);
  font-size: 1.5rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

/* The combo is the number a player actually watches, so it gets the gold and
   the size, and it is the only one that moves. */
.score--combo dd {
  font-size: 2rem;
  color: var(--gold);
  text-shadow: 0 0 26px rgba(232, 188, 85, .35);
}

/* --- the foot ------------------------------------------------------------ */
.foot {
  max-width: var(--width);
  margin: 0 auto;
  padding: 1.6rem 1.4rem 3rem;
  border-top: 1px solid var(--line);
  text-align: center;
}

.foot .sub { max-width: 62ch; margin: .4rem auto; }

/* --- smaller screens ------------------------------------------------------ */
@media (max-width: 940px) {
  .deck { grid-template-columns: 1fr; }
  .hud { position: static; }
  .scores { grid-template-columns: repeat(4, 1fr); }
}

@media (max-width: 720px) {
  .hero { padding-top: 1.8rem; }
  .hero__inner { gap: 1rem; align-items: start; }
  .cabinet { padding: .6rem .6rem .7rem; border-radius: 18px; }
  .scores { grid-template-columns: repeat(2, 1fr); }
  .lane-btn { padding: .95rem .3rem; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* --- how hard to make it -------------------------------------------------- */
.levels {
  display: inline-flex;
  gap: 2px;
  margin: 1rem 0 .3rem;
  padding: 3px;
  background: rgba(10, 13, 21, .6);
  border: 1px solid var(--line);
  border-radius: 999px;
}

.level {
  font: inherit;
  font-size: .85rem;
  font-weight: 600;
  color: var(--ink-dim);
  background: none;
  border: 0;
  border-radius: 999px;
  padding: .4rem 1rem;
  cursor: pointer;
  transition: background-color .14s ease, color .14s ease;
}

.level:hover { color: var(--ink); }

.level.is-on {
  color: #1c1402;
  background: linear-gradient(180deg, #f5cf6e, var(--gold) 60%, #cf9f3a);
}

.level[disabled] { opacity: .5; cursor: default; }

/* --- while it is working -------------------------------------------------- */
.working { margin: .6rem 0 .2rem; }
.working[hidden] { display: none; }

.working__bar {
  height: 6px;
  background: rgba(10, 13, 21, .7);
  border: 1px solid var(--line);
  border-radius: 999px;
  overflow: hidden;
}

.working__bar span {
  display: block;
  width: 0;
  height: 100%;
  background: linear-gradient(90deg, var(--lane-1), var(--gold));
  transition: width .25s ease;
}

.working__what {
  margin: .4rem 0 0;
  font-size: .8rem;
  color: var(--ink-dim);
}

/* --- writing a chart by tapping ------------------------------------------ */
.panel--edit .row { margin-top: .7rem; }

.mine { margin-top: .8rem; padding-top: .7rem; border-top: 1px solid var(--line); }
.mine[hidden] { display: none; }

.mine__row {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .45rem .1rem;
  border-bottom: 1px solid var(--line);
}

.mine__row:last-child { border-bottom: 0; }

.mine__name {
  flex: 1 1 auto;
  min-width: 0;
  font: inherit;
  font-size: .88rem;
  text-align: left;
  color: var(--ink);
  background: none;
  border: 0;
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mine__name:hover { color: var(--gold); }
.mine__when { font-size: .74rem; color: var(--ink-faint); }

.mine__drop {
  font: inherit;
  font-size: .74rem;
  color: var(--ink-faint);
  background: none;
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: .15rem .45rem;
  cursor: pointer;
}

.mine__drop:hover { color: var(--miss); border-color: var(--miss); }

/* While a chart is being tapped the board says so, because the keys are not
   scoring anything and it should not look as though they failed. */
.cabinet--taping { box-shadow: 0 0 0 2px rgba(232, 188, 85, .55), var(--shadow); }

@media (max-width: 720px) {
  /* Thumbs, not fingers: the lane buttons are the whole interface on a phone
     and they are what a chart is tapped with. */
  .lane-btn { padding: 1.15rem .3rem; font-size: 1.05rem; }
  .panel--edit .row { gap: .4rem; }
  .panel--edit .btn { flex: 1 1 auto; }
}

/* --- sync ----------------------------------------------------------------- */
.sync__value {
  margin-left: auto;
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-size: .95rem;
  color: var(--gold);
}

.sync__slider {
  width: 100%;
  margin: .7rem 0 .2rem;
  accent-color: var(--gold);
}

/* --- the set: songs charted this visit ----------------------------------- */
.row--wrap {
  flex-wrap: wrap;
  gap: .5rem;
}

.set {
  list-style: none;
  margin: .4rem 0 0;
  padding: 0;
  display: grid;
  gap: .3rem;
}

.set__song {
  width: 100%;
  text-align: left;
  font: inherit;
  font-size: .9rem;
  color: inherit;
  background: rgba(255, 255, 255, .04);
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 10px;
  padding: .45rem .7rem;
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.set__song:hover,
.set__song:focus-visible {
  border-color: var(--gold);
}

.set__song.is-on {
  border-color: var(--gold);
  background: rgba(214, 178, 94, .12);
}

.set__song.is-on::before {
  content: "\25B6  ";
  color: var(--gold);
}

/* --- the beat model's line in the HUD ------------------------------------- */
.refine {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .35rem .6rem;
}

/* --- finding your way on a phone ------------------------------------------ */
/* The keys are for keyboards; a touch screen is told about the lanes. */
.keys-touch { display: none; }
@media (hover: none) {
  .keys--board { display: none; }
  .keys-touch { display: block; }
}

@media (max-width: 720px) {
  /* The mark above the title rather than beside it, so the words get the
     width of the screen and the board is not a screen and a half down. */
  .hero { padding: 1.2rem 1rem .8rem; }
  .hero__inner { grid-template-columns: 1fr; gap: .4rem; }
  .mark { width: 64px; }
  .hero h1 { font-size: 2rem; }
  .hero__lead { font-size: .9rem; }
  .hero .verse { margin-top: .6rem; font-size: .82rem; }

  /* The card over the board says less, so Start is on screen without
     scrolling inside it. */
  .card { padding: 1rem .9rem; }
  .card h2 { font-size: 1.35rem; margin-bottom: .2rem; }
  .card p { font-size: .84rem; }
  #level-note { display: none; }
}

/* --- panels that fold ------------------------------------------------------
   The side of the board is the score and what is playing; sync, writing a
   chart and how charting works are there when wanted. On a phone they start
   folded - open, the column under the board was nearly two thousand pixels
   of reading between a player and the lane buttons' own page.            */
.fold > summary {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin: 0;
  list-style: none;
  cursor: pointer;
}
.fold > summary::-webkit-details-marker { display: none; }
.fold > summary::after {
  content: "\25BE";
  margin-left: auto;
  font-size: .8rem;
  letter-spacing: 0;
  transition: transform .15s ease;
}
.fold:not([open]) > summary::after { transform: rotate(-90deg); }
.fold[open] > summary { margin-bottom: .35rem; }
.fold__value { letter-spacing: .04em; color: var(--gold); text-transform: none; }
