/* poetesse torturate - Sorbet.
   Values read off design/QueensSorbet.dc.html, not guessed. Built at 390px and
   allowed to grow from there. */

:root {
  --page: #FFF4EC;
  --card: #FFFDFB;
  --line: #F0DFD4;
  --ink: #2E1F1B;
  --muted: #8A736B;
  --faint: #B39C93;
  --accent: #E8674C;
  --accent-pressed: #C0452C;
  --wash: #FDE3D8;
  --wash-ink: #8A5A48;
  --nudge: #F7E7DC;
  --nudge-line: #E8B79F;

  --heat-0: #FFF4EC;
  --heat-1: #FCEBE2;
  --heat-2: #F9D3C2;
  --heat-3: #F3AE95;
  --heat-4: #E8674C;

  --serif: 'Instrument Serif', Georgia, serif;
  --sans: Karla, system-ui, -apple-system, sans-serif;

  --r-card: 26px;
  --r-cell: 15px;
  --r-pill: 999px;

  /* Sorbet is flat, and mostly stays flat. This is a shadow you notice only
     when it is missing: a hairline of contact plus a wide, very soft pool, so
     a card reads as sitting on the cream rather than being drawn onto it. */
  --lift: 0 1px 1px rgba(46, 31, 27, .03), 0 12px 28px -16px rgba(46, 31, 27, .22);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--page);
  color: var(--ink);
  font-family: var(--sans);
  text-wrap: pretty;
  -webkit-text-size-adjust: 100%;
}

input, button, textarea {
  font: inherit;
  color: inherit;
  border: none;
  background: none;
}
button { cursor: pointer; }
a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-pressed); }

.shell {
  width: 100%;
  max-width: 430px;
  margin: 0 auto;
  padding: 26px 18px 36px;
  display: flex;
  flex-direction: column;
  gap: 20px;
  position: relative;
  /* No overflow: hidden here. It made the shell the scroll context, which
     quietly broke both sticky elements on the page - the topbar below and the
     toast, which has always been written position: sticky and never once
     stuck. The confetti layer clips its own bits, so nothing needs it. */
}

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

/* Sticky, because the grid is five weeks long and the way back to Copy link
   and Nudge should not be a scroll to the top. The page colour is carried up
   with it so nothing shows through. */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  position: sticky;
  top: 0;
  z-index: 5;
  margin: -26px -18px 0;
  padding: 18px 18px 12px;
  background: linear-gradient(var(--page) 76%, rgba(255, 244, 236, 0));
}
.brand { display: flex; align-items: baseline; gap: 7px; min-width: 0; }
.brand b {
  font: 700 10px/1 var(--sans);
  letter-spacing: .2em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.brand span { font: 500 11px/1 var(--sans); color: var(--muted); white-space: nowrap; }

.actions { display: flex; gap: 6px; flex: none; }
.pill {
  white-space: nowrap;
  min-height: 38px;
  padding: 7px 15px;
  border-radius: var(--r-pill);
  font: 600 11px/1 var(--sans);
}
.pill-wash { background: var(--wash); color: var(--accent-pressed); }
.pill-wash:hover { background: #F9CEBE; }
.pill-ghost { background: var(--card); border: 1px solid var(--line); color: var(--muted); }
.pill-ghost:hover { color: var(--ink); }

.lede h1 {
  margin: 0;
  font-family: var(--serif);
  font-size: 35px;
  line-height: 1.02;
  font-weight: 400;
  letter-spacing: -.01em;
}
.lede h1 em { color: var(--accent); }
.lede p { margin: 7px 0 0; font: 400 13px/1.5 var(--sans); color: var(--muted); }

.me-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 15px;
  border-radius: var(--r-pill);
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--lift);
}
.me-row .who { display: flex; align-items: center; gap: 8px; min-width: 0; }
.me-row b { font: 600 12.5px/1 var(--sans); }
.me-row .link {
  font: 500 11px/1 var(--sans);
  color: var(--muted);
  text-decoration: underline;
  white-space: nowrap;
}
.me-row .link:hover { color: var(--accent); }
.me-row .inline-form { display: contents; }

.swatch { width: 11px; height: 11px; border-radius: var(--r-pill); display: block; flex: none; }

/* --- cards ---------------------------------------------------------------- */

.card {
  padding: 19px 18px 20px;
  border-radius: var(--r-card);
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: var(--lift);
  display: flex;
  flex-direction: column;
  gap: 13px;
}

.eyebrow {
  font: 700 9.5px/1 var(--sans);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
}

/* --- winning night -------------------------------------------------------- */

.winner {
  padding: 19px 19px 20px;
  border-radius: var(--r-card);
  background: var(--wash);
  box-shadow: var(--lift);
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.winner .eyebrow { color: var(--accent-pressed); }
.winner .date { font-family: var(--serif); font-size: 32px; line-height: 1.05; }
.winner .sub { font: 500 12.5px/1.4 var(--sans); color: var(--wash-ink); }
.winner .lock {
  margin-top: 9px;
  align-self: flex-start;
  padding: 9px 14px;
  border-radius: var(--r-pill);
  background: var(--ink);
  color: var(--page);
  font: 600 11px/1 var(--sans);
}
.winner .lock:hover { background: var(--accent); }

/* Label first, then the button: locking asks what the night is, and the answer
   is what everyone reads under Coming up afterwards. */
.winner .lock-row { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; margin-top: 9px; }
.winner .lock-row .field { flex: 1; min-width: 150px; background: var(--card); }
.winner .lock-row .lock { margin-top: 0; }

/* --- in agenda ------------------------------------------------------------ */

/* The dark "it's happening" treatment from the Sorbet handoff. It was written
   for the locked winner card, which no longer exists now that any number of
   nights can be locked at once, so it moves here: a night in the diary is the
   one thing on this page that is settled, and it should not look like another
   white card. */
.nights-card { background: var(--ink); border-color: var(--ink); }
.nights b { font-size: 14px; }
.nights-card .eyebrow { color: var(--wash); }
.nights-card .nights b { color: var(--card); }
.nights-card .nights .when { color: var(--nudge-line); }
.nights-card .nights .unlock { background: var(--wash); color: var(--accent-pressed); }

.nights { display: flex; flex-direction: column; gap: 10px; margin: 0; padding: 0; list-style: none; }
.nights li { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.nights b { font: 600 13px/1.2 var(--sans); display: block; }
.nights .when { font: 500 11px/1.4 var(--sans); color: var(--muted); }
.nights .unlock {
  padding: 7px 11px;
  border-radius: var(--r-pill);
  background: var(--wash);
  color: var(--accent-pressed);
  font: 600 10.5px/1 var(--sans);
  flex: none;
}
.nights .unlock:hover { background: var(--nudge-line); }

.day-locked {
  margin: 0;
  font: 600 11.5px/1.4 var(--sans);
  color: var(--accent-pressed);
}

/* --- your answer for the chosen day --------------------------------------- */

/* Three named options in the card that was already showing this day, rather
   than one cell cycling silently through them. */
.picker { display: flex; flex-direction: column; gap: 9px; }
.seg { display: flex; gap: 6px; }
.seg button {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 42px;
  padding: 13px 4px;
  border-radius: var(--r-pill);
  background: var(--page);
  border: 1px solid var(--line);
  font: 600 11.5px/1 var(--sans);
  color: var(--muted);
}
.seg button:hover { border-color: var(--heat-3); }
.seg button.on { background: var(--ink); border-color: var(--ink); color: var(--page); }

/* The same shapes the grid uses: filled for free, ring for evenings, empty for
   no. In your own colour, since that is the dot you are putting on the day. */
.pip {
  width: 9px;
  height: 9px;
  border-radius: var(--r-pill);
  flex: none;
  background: var(--me, var(--accent));
}
.pip.eve { background: var(--card); box-shadow: inset 0 0 0 2px var(--me, var(--accent)); }
.pip.non { background: transparent; box-shadow: inset 0 0 0 1px var(--faint); }

/* --- grid ----------------------------------------------------------------- */

.grid-card { padding: 17px 14px 19px; gap: 12px; }
.grid-head { display: flex; align-items: baseline; justify-content: space-between; }
.grid-head .span { font: 500 11px/1 var(--sans); color: var(--faint); white-space: nowrap; }

.dow, .grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 7px;
}
.dow span {
  text-align: center;
  font: 700 9.5px/1 var(--sans);
  letter-spacing: .16em;
  color: var(--faint);
}
.dow .weekend { color: var(--accent); }

.cell {
  height: 70px;
  border-radius: var(--r-cell);
  background: var(--heat-0);
  color: var(--ink);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 4px 2px;
  touch-action: manipulation; /* no double-tap zoom to fight with */
}
.cell:hover { filter: brightness(.97); }
.cell[data-heat="0"] { background: var(--heat-0); color: var(--faint); }
.cell[data-heat="1"] { background: var(--heat-1); }
.cell[data-heat="2"] { background: var(--heat-2); }
.cell[data-heat="3"] { background: var(--heat-3); }
.cell[data-heat="4"] { background: var(--heat-4); color: var(--card); }
/* Your own answer rings the cell. Driven by data-state rather than by
   aria-pressed, which described a toggle the cell no longer is. */
.cell[data-state="free"],
.cell[data-state="evening"] { box-shadow: inset 0 0 0 2px var(--ink); }
.cell.is-locked-night { box-shadow: inset 0 0 0 2px var(--accent-pressed); }

/* The day the card below is answering. Outside the cell and dashed, so being
   chosen never looks like being answered. */
.cell.is-selected { outline: 2px dashed var(--muted); outline-offset: 3px; }

/* Days already gone. They stay on the grid - the marks people made are still
   the record of what happened - but there is nothing left to answer. */
.cell[data-past="1"] { opacity: .38; cursor: default; }
.cell[data-past="1"]:hover { filter: none; }

.cell .num { font: 600 16.5px/1 var(--sans); }

/* Two rows of dots so all seven fit. SPEC.md §4.2 says both "all seven fit
   without truncation" and "capped at five with +N"; at 390px a cell is ~41.7px
   wide and five 8px dots need 52px, so the cap was the wrong half. */
.dots {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-content: center;
  gap: 2px;
  max-width: 100%;
  min-height: 14px;
}
.dot {
  width: 7px;
  height: 7px;
  border-radius: var(--r-pill);
  display: block;
  flex: none;
  /* A full-house cell is painted in the accent, which is also the first
     person's identity colour - without this halo her dot disappears into the
     background on exactly the days everyone is free. Outline rather than
     border or box-shadow: it costs no layout and leaves box-shadow free for
     the evenings-only ring. */
  outline: 1px solid var(--card);
}
/* Cream centre rather than transparent. A transparent centre takes the
   cell's colour, so on a full-house cell an evenings-only ring and a solid
   dot in the same hue become the same shape - and SPEC.md §4.2 keeps both
   precisely because the fill difference carries meaning colour does not. */
.dot.evening { background: var(--card) !important; }
.badge { font: 700 11px/1 var(--sans); opacity: .9; }
.badge-eve {
  width: 7px; height: 7px; border-radius: var(--r-pill);
  box-shadow: inset 0 0 0 2px currentColor; opacity: .75; display: block;
}

.legend {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
  padding-top: 2px;
  font: 500 10px/1 var(--sans);
  color: var(--faint);
}
.legend i { width: 15px; height: 9px; border-radius: var(--r-pill); display: block; }
.legend .rule { width: 1px; height: 11px; background: var(--line); display: block; }
.legend .ring {
  width: 8px; height: 8px; border-radius: var(--r-pill);
  box-shadow: inset 0 0 0 2px var(--muted); display: block;
}

/* --- day detail ----------------------------------------------------------- */

.day-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.day-head h2 { margin: 0; font-family: var(--serif); font-size: 25px; line-height: 1.05; font-weight: 400; }
.day-head .count { font: 600 11px/1 var(--sans); color: var(--accent); white-space: nowrap; }

.people { display: flex; flex-direction: column; gap: 9px; margin: 0; padding: 0; list-style: none; }
.people li { display: flex; align-items: flex-start; gap: 9px; }
.people .swatch { margin-top: 4px; width: 9px; height: 9px; }
.people b { font: 600 12.5px/1.2 var(--sans); font-weight: 600; }
.people .tag { font: 500 11px/1.2 var(--sans); color: var(--faint); }
.people .note { display: block; font: 400 11.5px/1.4 var(--sans); color: var(--muted); }
.people.waiting b { color: var(--faint); font-weight: 500; }

.rule-h { height: 1px; background: var(--line); }

.field {
  width: 100%;
  padding: 11px 13px;
  border-radius: var(--r-cell);
  background: var(--page);
  font: 400 12.5px/1.3 var(--sans);
  outline: none;
}
.field:focus { box-shadow: inset 0 0 0 1.5px var(--heat-3); }

/* --- chat ----------------------------------------------------------------- */

.chat { display: flex; flex-direction: column; gap: 9px; margin: 0; padding: 0; list-style: none; }
.chat li { display: flex; gap: 9px; align-items: flex-start; }
.chat .swatch { margin-top: 5px; width: 9px; height: 9px; }
.chat .name { font: 600 11px/1 var(--sans); color: var(--muted); }
.chat .bubble {
  display: block;
  margin-top: 2px;
  font: 400 12.5px/1.45 var(--sans);
  padding: 8px 11px;
  border-radius: var(--r-cell);
  background: var(--page);
  overflow-wrap: anywhere;
}
.composer { display: flex; gap: 7px; align-items: center; }
.composer .field { flex: 1; }
.send {
  padding: 11px 15px;
  border-radius: var(--r-cell);
  background: var(--accent);
  color: var(--card);
  font: 600 12px/1 var(--sans);
  flex: none;
}
.send:hover { background: var(--accent-pressed); }

/* --- nudge ---------------------------------------------------------------- */

.nudge-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 13px 15px;
  border-radius: var(--r-card);
  background: var(--nudge);
  border: 1px dashed var(--nudge-line);
}
.nudge-bar span { font: 500 12px/1.4 var(--sans); color: var(--wash-ink); }
.nudge-bar button {
  white-space: nowrap;
  padding: 9px 13px;
  border-radius: var(--r-pill);
  background: var(--ink);
  color: var(--page);
  font: 600 11px/1 var(--sans);
  flex: none;
}
.nudge-bar button:hover { background: var(--accent); }
/* display: flex would otherwise win over the hidden attribute, and the bar is
   toggled from JS as people answer. */
.nudge-bar[hidden] { display: none; }

.foot { margin: 0; text-align: center; font: 400 10.5px/1.5 var(--sans); color: var(--faint); }

/* --- toast + confetti ----------------------------------------------------- */

.toast {
  position: sticky;
  /* Clear of the sticky title bar rather than under it. */
  top: 64px;
  z-index: 8;
  align-self: center;
  white-space: nowrap;
  padding: 9px 13px;
  border-radius: var(--r-pill);
  background: var(--ink);
  color: var(--page);
  font: 500 12px/1.3 var(--sans);
  animation: gcpop .25s ease-out;
}
.toast[hidden] { display: none; }

.confetti { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 6; }
.confetti i { position: absolute; top: 90px; display: block; }

@keyframes gcfall {
  0%   { transform: translateY(-20px) rotate(0deg); opacity: 1; }
  100% { transform: translateY(560px) rotate(560deg); opacity: 0; }
}
@keyframes gcpop {
  from { transform: translateY(6px) scale(.96); opacity: 0; }
  to   { transform: translateY(0) scale(1); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .confetti { display: none; }
  * { animation-duration: .01ms !important; }
}

/* --- sign in and sign up -------------------------------------------------- */

.auth { gap: 9px; }
.auth .field { padding: 12px 14px; }
.auth .submit {
  margin-top: 3px;
  padding: 12px 14px;
  border-radius: var(--r-pill);
  background: var(--ink);
  color: var(--page);
  font: 600 12px/1 var(--sans);
}
.auth .submit:hover { background: var(--accent); }
.auth-alt { margin: 2px 0 0; font: 500 11.5px/1.4 var(--sans); color: var(--muted); }

/* One message for a wrong password and an unknown username alike, sitting on
   the form rather than on a page of its own. */
.form-error {
  margin: 0;
  padding: 10px 12px;
  border-radius: 13px;
  background: var(--nudge);
  border: 1px dashed var(--nudge-line);
  font: 500 12px/1.45 var(--sans);
  color: var(--wash-ink);
}

/* --- organiser ------------------------------------------------------------ */

.admin { border-style: dashed; }
.admin-warn { font: 500 11.5px/1.45 var(--sans); color: var(--wash-ink); margin: 0; }
.admin-row { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.admin-row .field { flex: 1; min-width: 120px; }
.admin-row button {
  padding: 8px 12px;
  border-radius: var(--r-pill);
  background: var(--wash);
  color: var(--accent-pressed);
  font: 600 11px/1 var(--sans);
  flex: none;
}
.admin details summary { font: 600 12px/1 var(--sans); cursor: pointer; padding: 4px 0; }
.admin-label { font: 500 11.5px/1 var(--sans); color: var(--muted); flex: none; }
