/*
  Plain CSS, no build step. Written for a choir of about fourteen people, many of them
  older: large type, strong contrast, wide touch targets, quiet traditional typography.
  Nothing here needs compiling — edit it and reload the page.
*/

:root {
  --ink: #1b1b1b;
  --ink-soft: #444444;
  --paper: #fbf9f4;
  --panel: #ffffff;
  --rule: #b9b2a3;
  --accent: #5a2a2a; /* oxblood, like a hymnal spine */
  --good: #1f5130;
  --bad: #8a1d1d;
  --font-body: Baskerville, "Libre Baskerville", "Times New Roman", Georgia, serif;
}

* {
  box-sizing: border-box;
}

html {
  font-size: 20px;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  line-height: 1.6;
}

main {
  max-width: 54rem;
  margin: 0 auto;
  padding: 1.5rem 1.25rem 4rem;
}

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

.site-header {
  border-bottom: 3px double var(--rule);
  padding: 1.25rem 1.25rem 0.75rem;
  text-align: center;
  background: var(--panel);
}

.site-title {
  display: inline-block;
  font-size: 2.1rem;
  letter-spacing: 0.02em;
  color: var(--accent);
  text-decoration: none;
}

.site-subtitle {
  margin: 0.2rem 0 0.75rem;
  color: var(--ink-soft);
  font-size: 0.9rem;
  font-variant: small-caps;
  letter-spacing: 0.08em;
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  justify-content: center;
  align-items: center;
  padding-bottom: 0.5rem;
}

.site-nav a,
.link-button {
  display: inline-block;
  padding: 0.6rem 0.25rem;
  min-height: 2.75rem;
  color: var(--ink);
  font-size: 1.05rem;
}

.nav-form {
  margin: 0;
}

.site-footer {
  border-top: 1px solid var(--rule);
  padding: 1rem 1.25rem 2rem;
  text-align: center;
  color: var(--ink-soft);
  font-size: 0.85rem;
}

/* ---------- type ---------- */

h1,
h2,
h3 {
  font-weight: normal;
  color: var(--accent);
  line-height: 1.25;
}

h1 {
  font-size: 2rem;
  margin: 0.5rem 0 1rem;
}

h2 {
  font-size: 1.5rem;
  margin: 2rem 0 0.75rem;
}

p,
li {
  font-size: 1.05rem;
  max-width: 40rem;
}

a {
  color: var(--accent);
}

.hint {
  color: var(--ink-soft);
  font-size: 0.95rem;
}

/* ---------- panels and notices ---------- */

.panel {
  background: var(--panel);
  border: 1px solid var(--rule);
  padding: 1.25rem 1.5rem;
  margin-bottom: 1.5rem;
}

.flash,
.notice,
.error {
  border-left: 6px solid var(--rule);
  background: var(--panel);
  padding: 0.9rem 1.1rem;
  margin: 0 0 1.5rem;
  font-size: 1.05rem;
  max-width: none;
}

.flash {
  border-left-color: var(--good);
}

.error {
  border-left-color: var(--bad);
  color: var(--bad);
}

/*
 * The four things to know before sending a text. They are set apart because
 * they are the difference between a message arriving and a message vanishing,
 * and a director reading this screen for the first time must not skim them.
 */
.caveats {
  border-left: 6px solid var(--accent);
}

.caveats h2 {
  margin-top: 0;
}

.caveats li {
  margin-bottom: 0.6rem;
}

/* A block that belongs to the radio button above it. */
.indented {
  margin: 0.4rem 0 1rem 1.9rem;
}

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

form {
  margin: 1rem 0 2rem;
}

.field {
  margin-bottom: 1.25rem;
  max-width: 34rem;
}

label {
  display: block;
  margin-bottom: 0.35rem;
  font-size: 1.05rem;
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="tel"],
input[type="file"],
select,
textarea {
  width: 100%;
  font-family: var(--font-body);
  font-size: 1.15rem;
  padding: 0.7rem 0.6rem;
  min-height: 3rem;
  border: 2px solid var(--rule);
  background: #fff;
  color: var(--ink);
}

textarea {
  min-height: 14rem;
  line-height: 1.5;
  font-family: "SF Mono", Menlo, Consolas, monospace;
  font-size: 1rem;
}

input:focus,
select:focus,
textarea:focus,
button:focus,
a:focus {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

.checkbox {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 1rem;
}

.checkbox input {
  width: 1.4rem;
  height: 1.4rem;
}

.checkbox label {
  margin: 0;
}

button,
.button {
  display: inline-block;
  font-family: var(--font-body);
  font-size: 1.1rem;
  padding: 0.75rem 1.5rem;
  min-height: 3rem;
  border: 2px solid var(--accent);
  background: var(--accent);
  color: #fff;
  text-decoration: none;
  cursor: pointer;
}

button:hover,
.button:hover {
  background: #421e1e;
}

button.secondary,
.button.secondary {
  background: #fff;
  color: var(--accent);
}

.link-button {
  border: none;
  background: none;
  color: var(--ink);
  font-size: 1.05rem;
  padding: 0.6rem 0.25rem;
  min-height: 2.75rem;
  text-decoration: underline;
  cursor: pointer;
}

.link-button:hover {
  background: none;
  color: var(--accent);
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
}

/* ---------- tables ---------- */

table {
  width: 100%;
  border-collapse: collapse;
  margin: 1rem 0 2rem;
}

th,
td {
  text-align: left;
  padding: 0.7rem 0.6rem;
  border-bottom: 1px solid var(--rule);
  font-size: 1rem;
  vertical-align: top;
}

th {
  font-variant: small-caps;
  letter-spacing: 0.05em;
  border-bottom: 2px solid var(--rule);
}

tr.inactive td {
  color: var(--ink-soft);
  font-style: italic;
}

.tag {
  display: inline-block;
  padding: 0.15rem 0.5rem;
  border: 1px solid var(--rule);
  font-size: 0.85rem;
  white-space: nowrap;
}

.tag.warn {
  border-color: var(--bad);
  color: var(--bad);
}

.tag.ok {
  border-color: var(--good);
  color: var(--good);
}

.row-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}

.row-actions form {
  margin: 0;
}

.row-actions .link-button {
  padding: 0.5rem 0.4rem;
}

.outcome-create { color: var(--good); }
.outcome-update { color: var(--ink); }
.outcome-unchanged { color: var(--ink-soft); }
.outcome-skip { color: var(--bad); }

/* "failed — Resend answered 422: …" is a sentence, so let it wrap like one. */
.outbox-outcome {
  white-space: normal;
}

.message-body {
  white-space: pre-wrap;
  font-family: "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.9rem;
  background: #f3efe6;
  padding: 0.75rem;
  border: 1px solid var(--rule);
  overflow-x: auto;
}

/* A label that only a screen reader reads. Used where the column heading is the label. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/*
  The director's working list. Setting anthems is the job done most often, so the
  anthem box is the widest thing on the row and can be typed into where it stands.
*/
.schedule-edit td {
  vertical-align: top;
}

.schedule-edit .c-anthem {
  width: 45%;
  min-width: 14rem;
}

.schedule-edit .c-date {
  white-space: nowrap;
}

.anthem-form {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.2rem;
}

.anthem-form textarea {
  width: 100%;
  font-size: 0.95rem;
  line-height: 1.35;
}

.season-heading {
  margin-top: 2rem;
}

/* ---------- availability ---------- */

/*
  The four states, wherever they appear. Unanswered is deliberately unlike the
  other three: hatched, grey, dotted, and always carrying the words "not
  answered". It must never be mistakable for available, which is the only state
  here that is green.
*/
.state-available {
  background: #eef4ee;
  border-left: 6px solid var(--good);
}

.state-unavailable {
  background: #f7eded;
  border-left: 6px solid var(--bad);
}

.state-unsure {
  background: #fbf4e6;
  border-left: 6px solid #8a5f10;
}

.state-unanswered {
  background: repeating-linear-gradient(135deg, #efece4, #efece4 6px, #e2ded1 6px, #e2ded1 12px);
  border-left: 6px dotted var(--ink-soft);
  color: var(--ink-soft);
}

/* The singer's own page: one event per block, everything thumb-sized. */

.answer-list {
  list-style: none;
  margin: 1rem 0 2rem;
  padding: 0;
}

.answer-row {
  border: 1px solid var(--rule);
  margin-bottom: 1.25rem;
  padding: 0.9rem 1rem;
}

.answer-when {
  margin: 0 0 0.4rem;
  max-width: none;
}

.answer-date {
  font-size: 1.2rem;
  font-weight: bold;
  margin-right: 0.5rem;
  white-space: nowrap;
}

.answer-day {
  font-size: 1.1rem;
}

.answer-time {
  display: block;
  color: var(--ink-soft);
  font-size: 0.95rem;
}

.answer-form {
  margin: 0;
}

.answer-now {
  margin: 0 0 0.5rem;
  font-variant: small-caps;
  letter-spacing: 0.06em;
  font-size: 1rem;
}

.answer-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

/* Wide enough for a thumb on a phone; the three share the row evenly. */
.answer-button {
  flex: 1 1 8rem;
  min-height: 3.5rem;
  background: #fff;
  color: var(--accent);
  font-size: 1.05rem;
  padding: 0.75rem 0.5rem;
}

.answer-button.chosen {
  background: var(--accent);
  color: #fff;
  box-shadow: inset 0 0 0 3px #fff, 0 0 0 3px var(--accent);
}

.answer-note-label {
  font-size: 0.95rem;
  color: var(--ink-soft);
}

.answer-note {
  width: 100%;
  font-family: var(--font-body);
  font-size: 1.1rem;
  padding: 0.7rem 0.6rem;
  min-height: 3rem;
  border: 2px solid var(--rule);
  background: #fff;
  color: var(--ink);
}

/*
  "Prudence Ashford entered this answer for you on 3 Nov 2026." Said in a
  sentence rather than by a mark, because this is the page a singer reads and a
  mark on it would need a key.
*/
.answer-entered {
  margin: 0 0 0.6rem;
  font-size: 1rem;
  border-left: 4px solid var(--ink-soft);
  padding-left: 0.6rem;
}

.answer-list.past .answer-row {
  padding: 0.6rem 1rem;
}

.answer-past-note {
  margin: 0.2rem 0 0;
  font-size: 0.95rem;
  color: var(--ink-soft);
}

/*
  The director's grid. Fourteen singers against a season of events fits on no
  screen there is, so it scrolls sideways with the names held still rather than
  shrinking the type until nobody can read it.
*/
.grid-scroll {
  overflow-x: auto;
  border: 1px solid var(--rule);
  background: var(--panel);
  margin: 1rem 0 2rem;
}

.availability-grid {
  border-collapse: separate;
  border-spacing: 0;
  width: auto;
  margin: 0;
}

.availability-grid th,
.availability-grid td {
  border-bottom: 1px solid var(--rule);
  border-right: 1px solid var(--rule);
  padding: 0.5rem 0.6rem;
  font-size: 0.95rem;
  vertical-align: top;
  min-width: 8rem;
}

.availability-grid thead th {
  border-bottom: 2px solid var(--rule);
  font-variant: normal;
  letter-spacing: 0;
  background: var(--panel);
}

.availability-grid .grid-date {
  display: block;
  font-weight: bold;
  white-space: nowrap;
}

.availability-grid .grid-day {
  display: block;
  font-size: 0.85rem;
  color: var(--ink-soft);
}

/*
  The dagger on a cell somebody entered on a singer's behalf. It is a shape, not
  a colour: the grid is read by people who cannot tell red from green, and the
  screen-reader label beside it names who entered the answer and when.
*/
.entered-mark {
  font-weight: bold;
  margin-left: 0.3em;
}

/* The names stay put while the events run off to the right. */
.availability-grid .c-name {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--panel);
  border-right: 2px solid var(--rule);
  text-align: left;
  font-variant: normal;
  letter-spacing: 0;
  min-width: 11rem;
}

.availability-grid tfoot .count-row th,
.availability-grid tfoot .count-row td {
  border-top: 2px solid var(--rule);
  border-bottom: none;
}

.availability-grid tfoot .count {
  font-size: 1.15rem;
  text-align: center;
}

.availability-grid tfoot .total th,
.availability-grid tfoot .total td {
  font-weight: bold;
}

/* One event close up. */
.roll-call {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
}

.roll-call li {
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--rule);
}

.roll-call li:last-child {
  border-bottom: none;
}

.roll-note {
  display: block;
  color: var(--ink-soft);
  font-size: 0.95rem;
  font-style: italic;
}

/* Who entered this answer, in words, under the name it belongs to. */
.roll-entered {
  display: block;
  font-size: 0.95rem;
}

/* The form that sets one singer's answer. A fieldset for the legend, not for a box. */
.roll-set {
  border: 0;
  margin: 0;
  padding: 0;
}

.roll-form {
  margin: 0.5rem 0 0;
}

/* Smaller than the singer's own buttons: four of them, fourteen times down a page. */
.roll-form .answer-button {
  flex: 1 1 7rem;
  min-height: 2.75rem;
  font-size: 0.95rem;
  padding: 0.5rem 0.4rem;
}

.roll-form .answer-note {
  min-height: 2.5rem;
  font-size: 1rem;
  padding: 0.45rem 0.5rem;
}

@media (max-width: 40rem) {
  html {
    font-size: 19px;
  }
  table,
  thead,
  tbody,
  th,
  td,
  tr {
    display: block;
  }
  thead {
    display: none;
  }
  tr {
    border-bottom: 2px solid var(--rule);
    padding: 0.5rem 0;
  }
  td {
    border: none;
    padding: 0.3rem 0;
  }

  /*
    The grid is the one table that must NOT become stacked blocks on a phone. A
    thing read down one axis and across the other stops being a grid the moment
    it is unrolled into a list, so it keeps its shape and scrolls instead.
  */
  .availability-grid {
    display: table;
  }
  .availability-grid thead {
    display: table-header-group;
  }
  .availability-grid tbody {
    display: table-row-group;
  }
  .availability-grid tfoot {
    display: table-footer-group;
  }
  .availability-grid tr {
    display: table-row;
    border-bottom: none;
    padding: 0;
  }
  .availability-grid th,
  .availability-grid td {
    display: table-cell;
    border-bottom: 1px solid var(--rule);
    border-right: 1px solid var(--rule);
    padding: 0.5rem 0.6rem;
  }
}

/* ---------- learning resources ---------- */

/*
  The Resources pages are read on phones at rehearsal, by people holding a pencil in
  the other hand. Every piece is one large link, every file has full-size buttons, and
  nothing on a singer's page needs JavaScript: audio is the browser's own player, a
  PDF is the browser's own viewer, a video is YouTube's own frame.
*/

.crumb {
  margin: 0 0 0.5rem;
  font-size: 1rem;
}

.page-tools {
  margin-bottom: 1.5rem;
}

.piece-list {
  list-style: none;
  padding: 0;
  margin: 0 0 2rem;
  border-top: 1px solid var(--rule);
  max-width: none;
}

.piece-list li {
  max-width: none;
  border-bottom: 1px solid var(--rule);
}

.piece-link {
  display: block;
  padding: 0.9rem 0.25rem;
  color: var(--ink);
  text-decoration: none;
}

.piece-link:hover .piece-title {
  text-decoration: underline;
}

.piece-title {
  display: block;
  font-size: 1.25rem;
  color: var(--accent);
}

.piece-composer {
  display: block;
  font-style: italic;
  color: var(--ink-soft);
}

.piece-next {
  display: block;
  font-size: 0.95rem;
  color: var(--ink-soft);
}

.piece-heading {
  margin-bottom: 0.15rem;
}

.piece-byline {
  font-style: italic;
  color: var(--ink-soft);
  font-size: 1.15rem;
  margin: 0 0 1.25rem;
}

.piece-dates {
  list-style: none;
  padding: 0;
  margin: 0 0 1.25rem;
}

.piece-dates li {
  margin-bottom: 0.2rem;
}

.piece-dates li.past {
  color: var(--ink-soft);
}

.piece-date {
  display: inline-block;
  min-width: 6.5em;
  font-variant: small-caps;
  letter-spacing: 0.06em;
}

.piece-description {
  white-space: pre-line;
}

.resource-files,
.admin-items {
  list-style: none;
  padding: 0;
  margin: 0 0 1.5rem;
  max-width: none;
}

.resource-file,
.admin-item {
  max-width: none;
  background: var(--panel);
  border: 1px solid var(--rule);
  padding: 1rem 1.25rem;
  margin-bottom: 1rem;
}

.resource-name {
  font-size: 1.15rem;
  margin: 0 0 0.15rem;
  white-space: pre-line;
}

.resource-meta {
  color: var(--ink-soft);
  font-size: 0.95rem;
  margin: 0 0 0.75rem;
  overflow-wrap: anywhere;
}

.resource-audio {
  display: block;
  width: 100%;
  margin: 0 0 0.75rem;
}

.resource-video {
  margin: 0 0 2rem;
}

/* YouTube's player, kept at 16:9 however wide the page is. */
.video-frame {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
  margin-bottom: 0.5rem;
}

.video-frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.pdf-frame {
  display: block;
  width: 100%;
  height: 85vh;
  border: 1px solid var(--rule);
  background: #fff;
}

/* ---- the director's side ---- */

.prose-box {
  min-height: 7rem;
  font-family: var(--font-body);
  font-size: 1.1rem;
}

.item-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.5rem 0.75rem;
  margin: 0.5rem 0 0.25rem;
}

.item-form label {
  flex: 0 0 100%;
  margin: 0;
  font-size: 0.95rem;
  color: var(--ink-soft);
}

.item-form input[type="text"] {
  flex: 1 1 16rem;
}

.upload-form h3,
.upload-form + form h3,
.panel h3 {
  margin-top: 0;
}

.admin-video {
  display: grid;
  grid-template-columns: minmax(0, 16rem) minmax(0, 1fr);
  gap: 1.25rem;
  align-items: start;
}

.admin-video .item-form {
  margin-top: 0;
}

.date-picker {
  border: 1px solid var(--rule);
  background: var(--panel);
  padding: 1rem 1.25rem 0.5rem;
  margin: 0 0 1.5rem;
}

.date-picker legend {
  font-size: 1.15rem;
  padding: 0 0.4rem;
}

.date-season {
  font-size: 1.1rem;
  margin: 1.25rem 0 0.5rem;
}

.date-choice {
  align-items: flex-start;
  margin-bottom: 0.6rem;
}

.date-choice input {
  flex: 0 0 auto;
  margin-top: 0.2rem;
}

.date-when {
  display: inline-block;
  min-width: 6.5em;
  font-variant: small-caps;
  letter-spacing: 0.06em;
}

.date-anthem {
  display: block;
  font-size: 0.9rem;
  font-style: italic;
  color: var(--ink-soft);
}

.date-past {
  margin: 1.25rem 0 0.75rem;
}

.date-past summary {
  cursor: pointer;
  font-size: 1.05rem;
  color: var(--accent);
  padding: 0.4rem 0;
}

/* The words "Files" and "Videos" before a count, which only a stacked phone row needs. */
.cell-label {
  display: none;
}

@media (max-width: 40rem) {
  .admin-video {
    grid-template-columns: 1fr;
  }

  .cell-label {
    display: inline;
    color: var(--ink-soft);
  }

  .pieces-admin td:nth-child(3),
  .pieces-admin td:nth-child(4) {
    display: inline-block;
    margin-right: 1.25rem;
  }

  /* On a phone the date sits above the day it names, rather than wrapping beside it. */
  .piece-dates .piece-date {
    display: block;
    min-width: 0;
  }

  .piece-dates li {
    margin-bottom: 0.6rem;
  }

  /* A framed PDF on a phone shows one page at a time at best; Open the PDF is the way in. */
  .pdf-frame {
    display: none;
  }

  .resource-file,
  .admin-item {
    padding: 0.85rem 0.9rem;
  }
}
