/* ==========================================================================
   Festivus Hunger Games — Phase 7

   Continues the Phase 6 visual language rather than replacing it: the same
   dark palette, the same card and sheet primitives, the same focus ring. What
   is new here is the states Part V asks to feel DISTINCT, and the surfaces
   Phase 7 adds.

   Three rules this file follows throughout:

   1. NEVER COLOUR ALONE. Every state carries an icon or a word as well as a
      hue. A family member with a colour-vision difference, or a phone in
      bright sun, gets the same information.
   2. PHONE FIRST. Every layout here works at 320px. Touch targets are at
      least 44px. Nothing scrolls sideways.
   3. REDUCED MOTION IS HONOURED, in CSS as well as in script, so a
      preference set after the page loaded still applies.
   ========================================================================== */

/* ==========================================================================
   STATE BANDS — Part V's distinct states
   ========================================================================== */

.statebar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 0.9rem;
  border-radius: var(--radius, 14px);
  border: 1px solid var(--line, #27423c);
  background: var(--surface, #11201d);
  font-weight: 600;
  line-height: 1.3;
  margin-bottom: 0.9rem;
}

.statebar__icon {
  flex: 0 0 auto;
  width: 1.35rem;
  height: 1.35rem;
  fill: currentColor;
}

.statebar__text { min-width: 0; }

.statebar__label {
  display: block;
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.statebar__detail {
  display: block;
  font-size: 0.85rem;
  font-weight: 400;
  opacity: 0.85;
}

/* BIDDING OPEN — calm. Nothing is urgent yet. */
.statebar--open {
  border-color: #2f6f5b;
  background: #0f2520;
  color: #8fe3c2;
}

/* FINAL CALL — the one genuinely urgent state in the application. */
.statebar--final-call {
  border-color: #a8651f;
  background: #2a1a0b;
  color: #ffc98a;
}

/* BIDDING CLOSED — finished, not alarming. */
.statebar--closed {
  border-color: #3b4a56;
  background: #161e24;
  color: #b7c7d4;
}

/* FROZEN — aimed at the player it affects, and only them. */
.statebar--frozen {
  border-color: #2f5f8a;
  background: #0d1b28;
  color: #93c6f0;
}

/* TEST MODE — deliberately loud. Nobody should mistake a playtest for the
   real season, and the indicator is server state, not a browser toggle. */
.statebar--test {
  border-color: #8a6f1f;
  background: #251f08;
  color: #f0da93;
}

/* MAINTENANCE — the application is briefly read-only. */
.statebar--maintenance {
  border-color: #8a2f2f;
  background: #280f0f;
  color: #f0a5a5;
}

/* EVENT MODE, in its three states. */
.statebar--locked { border-color: #4a4a52; background: #191920; color: #b9b9c6; }
.statebar--ready  { border-color: #2f6f8a; background: #0d1f28; color: #93dcf0; }
.statebar--active { border-color: #2f8a4f; background: #0d2814; color: #96f0ab; }

/* The authoritative countdown, when there is one. */
.statebar__clock {
  margin-left: auto;
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.statebar--final-call .statebar__clock { animation: statebar-pulse 2s ease-in-out infinite; }

@keyframes statebar-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}

@media (prefers-reduced-motion: reduce) {
  .statebar--final-call .statebar__clock { animation: none; }
  .lightbox { transition: none; }
}

/* Set by script when the preference is read at the moment of opening. */
.lightbox--no-motion { transition: none; }

/* An informational expected close must never read as a deadline. */
.statebar__informational {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3rem;
  font-size: 0.85rem;
  font-weight: 400;
  opacity: 0.8;
}

.statebar__informational::before {
  content: "~";
  font-weight: 700;
  opacity: 0.7;
}

/* ==========================================================================
   PRIZE DETAIL IMAGE — J1, the defect this phase exists partly to fix
   ========================================================================== */

/*
 * The whole media block is a BUTTON, so it is reachable by keyboard and
 * announces what it does. It is styled here rather than inline because the
 * Content Security Policy is `style-src 'self'` and blocks element.style
 * assignments outright.
 */
/*
 * A LINK STYLED AS A BUTTON STILL HAS TO BE 44px TALL.
 *
 * app.css gives `.btn` `min-height: 44px` but sets no `display`. A <button> is
 * replaced-inline and honours it; an <a> is a plain inline box, and CSS does
 * not apply `min-height` to inline boxes -- so the floor was silently ignored
 * on every anchor-button in the app. A browser smoke measured the "Manage"
 * link on the admin rounds list at 78x19. Scoped to `a.btn` so no <button>
 * anywhere changes.
 */
/* ========================================================================== *
 * ADMIN DIAGNOSTICS and LOGIN LOCKOUTS (Phase 7.1)
 * ========================================================================== */
.admin-diagnostics__list {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 0.3rem 0.6rem;
  margin: 0.5rem 0 0.75rem;
  font-size: 0.82rem;
}

.admin-diagnostics__list dt { color: var(--text-dim, #9ab6ad); }

.admin-diagnostics__list dd {
  margin: 0;
  /* A commit id and a cache version read as data, not prose. */
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  overflow-wrap: anywhere;
}

/* At 320px two columns of monospace values collide; stack them. */
@media (max-width: 360px) {
  .admin-diagnostics__list { grid-template-columns: minmax(0, 1fr); }
  .admin-diagnostics__list dt { margin-top: 0.3rem; }
}

.admin-locks__row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0;
  border-top: 1px solid var(--line, #27423c);
}

.admin-locks__who {
  flex: 1 1 auto;
  min-width: 0;
  display: grid;
  gap: 0.1rem;
}

.admin-locks__identity {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.8rem;
  overflow-wrap: anywhere;
}

.admin-locks__meta {
  font-size: 0.75rem;
  color: var(--text-dim, #9ab6ad);
}

/* Locked out is the row an operator is looking for, so it is not subtle. */
.admin-locks__row--locked .admin-locks__meta { color: var(--warn, #f0b86e); }

/* ========================================================================== *
 * THE UPDATE BANNER
 *
 * Bottom-anchored and above the tab bar, because a family member's thumb is
 * already down there and a top banner on a phone collides with the status bar
 * and the notch. It must never cover a bid button, so it sits in the safe area
 * and leaves the tab bar reachable.
 * ========================================================================== */
.app-update {
  position: fixed;
  left: max(12px, env(safe-area-inset-left));
  right: max(12px, env(safe-area-inset-right));
  bottom: calc(68px + env(safe-area-inset-bottom));
  z-index: 60;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--accent, #4fd1a5);
  border-radius: 12px;
  background: #0d1a17;
  box-shadow: 0 6px 24px rgb(0 0 0 / 45%);
}

.app-update__text {
  flex: 1 1 10rem;
  font-size: 0.85rem;
  color: var(--text, #e8f3ef);
}

/* At 320px the two buttons share a row under the text rather than squeezing. */
@media (max-width: 360px) {
  .app-update__text { flex: 1 1 100%; }
  .app-update__action,
  .app-update__dismiss { flex: 1 1 0; }
}

@media (prefers-reduced-motion: reduce) {
  .app-update { transition: none; }
}

/* Replaces a blocked `style="min-height:88px;padding-top:10px"` attribute. */
.field__input--tall {
  min-height: 88px;
  padding-top: 10px;
}

/* Spacing for a countdown sitting under a card body. Replaces an inline
   `style.marginTop` that the Content Security Policy blocked. */
.countdown--inset { margin-top: 10px; }

a.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.prize-detail__trigger {
  display: block;
  width: 100%;
  padding: 0;
  margin: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: inherit;
  cursor: zoom-in;
  -webkit-appearance: none;
  appearance: none;
}

.prize-detail__trigger:focus-visible {
  outline: 3px solid var(--accent, #4fd1a5);
  outline-offset: 3px;
  border-radius: var(--radius, 14px);
}

/* While the lightbox is open the page behind must not scroll. */
body.has-lightbox {
  overflow: hidden;
}

/*
 * THE WHOLE POINT OF J1.
 *
 * `cover` fills the box and crops whatever does not fit, which is right for a
 * list card and wrong for the page a player is deciding from. `contain` keeps
 * the entire composition visible and letterboxes the remainder onto a neutral
 * surface.
 *
 * The container has an explicit max-height rather than an aspect ratio, so a
 * very tall portrait photo is bounded by the viewport instead of pushing the
 * bid controls off the screen, and a very wide panorama still shows end to end.
 */
.prize-detail__media {
  position: relative;
  width: 100%;
  background: #0a1412;
  border: 1px solid var(--line, #27423c);
  border-radius: var(--radius, 14px);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 12rem;
  max-height: min(70vh, 30rem);
}

.prize-detail__image {
  display: block;
  max-width: 100%;
  max-height: min(70vh, 30rem);
  width: auto;
  height: auto;
  object-fit: contain;
  object-position: center;
  cursor: zoom-in;
}

.prize-detail__media--empty {
  min-height: 9rem;
  color: var(--muted, #7fa89c);
}

.prize-detail__zoom-hint {
  position: absolute;
  inset-inline-end: 0.5rem;
  inset-block-end: 0.5rem;
  padding: 0.25rem 0.5rem;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.6);
  color: #e8f4f0;
  font-size: 0.75rem;
  pointer-events: none;
}

/* ==========================================================================
   GALLERY — J7
   ========================================================================== */

.gallery {
  margin-top: 0.6rem;
}

.gallery__position {
  display: block;
  text-align: center;
  font-size: 0.82rem;
  color: var(--muted, #7fa89c);
  font-variant-numeric: tabular-nums;
  margin-bottom: 0.4rem;
}

.gallery__strip {
  display: flex;
  gap: 0.45rem;
  overflow-x: auto;
  padding-bottom: 0.3rem;
  /* Swipe-friendly on a phone, and keyboard-reachable on anything. */
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
}

.gallery__strip::-webkit-scrollbar { height: 6px; }
.gallery__strip::-webkit-scrollbar-thumb { background: var(--line, #27423c); border-radius: 3px; }

.gallery-thumb {
  flex: 0 0 auto;
  width: 4.5rem;
  height: 4.5rem;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 10px;
  overflow: hidden;
  background: #0a1412;
  cursor: pointer;
  scroll-snap-align: start;
}

.gallery-thumb[aria-current="true"] {
  border-color: var(--accent, #4fd1a5);
}

/* A thumbnail MAY crop: it is an index, not the picture. */
.gallery-thumb__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.gallery__nav {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.gallery__nav-button {
  flex: 1 1 0;
  min-height: 44px;
}

/* ==========================================================================
   LIGHTBOX — J2
   ========================================================================== */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  background: rgba(3, 9, 8, 0.96);
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom)
    env(safe-area-inset-left);
}

.lightbox__bar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
}

.lightbox__position {
  font-size: 0.85rem;
  color: #cfe6df;
  font-variant-numeric: tabular-nums;
}

.lightbox__close {
  margin-left: auto;
  min-width: 44px;
  min-height: 44px;
}

.lightbox__stage {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  /* No horizontal page scroll, ever: the stage is the viewport. */
  overflow: hidden;
  padding: 0 0.5rem;
}

/* The enlarged view preserves the whole image, exactly as the detail does. */
.lightbox__image {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  display: block;
}

.lightbox__nav {
  display: flex;
  gap: 0.5rem;
  padding: 0.6rem 0.75rem;
}

.lightbox__nav .btn {
  flex: 1 1 0;
  min-height: 48px;
}

/* ==========================================================================
   ARSENAL — E13
   ========================================================================== */

.arsenal {
  display: grid;
  gap: 0.6rem;
}

.arsenal-item {
  display: grid;
  grid-template-columns: 2.6rem 1fr auto;
  gap: 0.7rem;
  align-items: start;
  padding: 0.75rem;
  border: 1px solid var(--line, #27423c);
  border-radius: var(--radius, 14px);
  background: var(--surface, #11201d);
}

.arsenal-item--empty { opacity: 0.55; }

.arsenal-item__icon {
  font-size: 1.6rem;
  line-height: 1;
  text-align: center;
}

.arsenal-item__name {
  margin: 0;
  font-size: 1rem;
  font-weight: 700;
}

.arsenal-item__desc {
  margin: 0.15rem 0 0;
  font-size: 0.87rem;
  color: var(--muted, #7fa89c);
}

/* The reason a control is unavailable. NEVER just a disabled button. */
.arsenal-item__reason {
  margin: 0.35rem 0 0;
  font-size: 0.82rem;
  color: #ffc98a;
  display: flex;
  align-items: baseline;
  gap: 0.3rem;
}

.arsenal-item__reason::before { content: "⚠"; }

.arsenal-item__count {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 1.05rem;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  background: #0a1412;
  border: 1px solid var(--line, #27423c);
}

.arsenal-item__actions {
  grid-column: 1 / -1;
  display: flex;
  gap: 0.5rem;
}

.arsenal-item__actions .btn { flex: 1 1 0; min-height: 44px; }

.arsenal__active {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.8rem;
}

.arsenal-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.3rem 0.6rem;
  border-radius: 999px;
  font-size: 0.82rem;
  font-weight: 600;
  border: 1px solid currentColor;
}

.arsenal-badge--shield { color: #93c6f0; }
.arsenal-badge--reflect { color: #d7a8f0; }
.arsenal-badge--tripwire { color: #ffc98a; }
.arsenal-badge--frozen { color: #93c6f0; }

/* ==========================================================================
   CHAOS FEED — Part F
   ========================================================================== */

.feed { display: grid; gap: 0.4rem; }

.feed__row {
  display: grid;
  grid-template-columns: 1.6rem 1fr auto;
  gap: 0.5rem;
  align-items: baseline;
  padding: 0.55rem 0.6rem;
  border-radius: 10px;
  background: #0d1a17;
  border: 1px solid #1d332e;
  font-size: 0.9rem;
}

.feed__glyph { text-align: center; }
.feed__text { min-width: 0; }
.feed__when {
  font-size: 0.75rem;
  color: var(--muted, #7fa89c);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.feed__row--trap { border-color: #4a3520; background: #1a1209; }
.feed__row--blocked { border-color: #20374a; background: #0b1620; }
.feed__row--win { border-color: #205f3f; background: #0b2017; }

/* ==========================================================================
   HOW WELL DO YOU KNOW...?
   ========================================================================== */

.hwdyk-card__featured {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.95rem;
}

.hwdyk-rewards {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0.5rem 0;
}

.hwdyk-reward {
  font-size: 0.78rem;
  padding: 0.2rem 0.5rem;
  border-radius: 999px;
  background: #0a1412;
  border: 1px solid var(--line, #27423c);
  color: var(--muted, #7fa89c);
}

.hwdyk-question {
  padding: 0.8rem 0;
  border-top: 1px solid var(--line, #27423c);
}

.hwdyk-question:first-of-type { border-top: 0; }

.hwdyk-question__prompt {
  margin: 0 0 0.5rem;
  font-weight: 600;
}

.hwdyk-question__number {
  display: inline-block;
  min-width: 1.4rem;
  color: var(--muted, #7fa89c);
  font-variant-numeric: tabular-nums;
}

.hwdyk-choices { display: grid; gap: 0.4rem; }

.hwdyk-choice {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.7rem 0.75rem;
  min-height: 44px;
  border: 1px solid var(--line, #27423c);
  border-radius: 10px;
  background: #0d1a17;
  cursor: pointer;
}

.hwdyk-choice:has(input:checked) {
  border-color: var(--accent, #4fd1a5);
  background: #0f2520;
}

.hwdyk-choice input { width: 1.1rem; height: 1.1rem; flex: 0 0 auto; }

.hwdyk-result {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0.5rem;
  align-items: baseline;
  padding: 0.6rem 0.7rem;
  border-radius: 10px;
  background: #0d1a17;
  border: 1px solid #1d332e;
}

.hwdyk-result--winner {
  border-color: #205f3f;
  background: #0b2017;
}

.hwdyk-result__score { font-variant-numeric: tabular-nums; font-weight: 700; }

.hwdyk-answer-reveal {
  display: grid;
  gap: 0.2rem;
  padding: 0.6rem 0;
  border-top: 1px solid var(--line, #27423c);
}

.hwdyk-answer-reveal__prompt { font-size: 0.85rem; color: var(--muted, #7fa89c); }
.hwdyk-answer-reveal__answer { font-weight: 700; }

.hwdyk-answer-reveal__mine {
  font-size: 0.85rem;
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
}

.hwdyk-answer-reveal__mine--match { color: #8fe3c2; }
.hwdyk-answer-reveal__mine--miss { color: var(--muted, #7fa89c); }

/* ==========================================================================
   ADMIN SURFACES
   Denser than the player side, as Part V permits — but still phone-usable.
   ========================================================================== */

.admin-grid {
  display: grid;
  gap: 0.5rem;
  grid-template-columns: 1fr;
}

@media (min-width: 30rem) {
  .admin-grid--two { grid-template-columns: 1fr 1fr; }
}

.admin-stat {
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--line, #27423c);
  border-radius: 10px;
  background: #0d1a17;
}

.admin-stat__label {
  display: block;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted, #7fa89c);
}

.admin-stat__value {
  display: block;
  font-size: 1.3rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* A destructive action is visually distinct AND says so in words. */
.btn--danger {
  background: #3a1414;
  border-color: #8a2f2f;
  color: #f7c9c9;
}

.btn--danger:hover:not([disabled]) { background: #4a1a1a; }

.danger-zone {
  border: 1px solid #8a2f2f;
  border-radius: var(--radius, 14px);
  background: #1a0b0b;
  padding: 0.9rem;
}

.danger-zone__title {
  margin: 0 0 0.4rem;
  font-size: 1rem;
  font-weight: 700;
  color: #f7c9c9;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.danger-zone__title::before { content: "⚠"; }

.danger-zone__body { font-size: 0.88rem; color: #e8c6c6; }

.danger-zone__list {
  margin: 0.5rem 0;
  padding-left: 1.1rem;
  font-size: 0.85rem;
  color: #dcc0c0;
}

/* The typed-confirmation field. */
.confirm-field {
  margin-top: 0.6rem;
}

.confirm-field__phrase {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: #f7c9c9;
}

/* ==========================================================================
   ADMIN GALLERY MANAGEMENT — J8
   ========================================================================== */

.gallery-admin { display: grid; gap: 0.5rem; }

.gallery-admin__row {
  display: grid;
  grid-template-columns: 4rem 1fr;
  gap: 0.6rem;
  align-items: center;
  padding: 0.5rem;
  border: 1px solid var(--line, #27423c);
  border-radius: 10px;
  background: #0d1a17;
}

.gallery-admin__row[data-cover="true"] { border-color: var(--accent, #4fd1a5); }

.gallery-admin__image {
  width: 4rem;
  height: 4rem;
  object-fit: cover;
  border-radius: 8px;
  display: block;
  background: #0a1412;
}

.gallery-admin__meta { min-width: 0; }

.gallery-admin__label {
  font-size: 0.8rem;
  color: var(--muted, #7fa89c);
  font-variant-numeric: tabular-nums;
}

/*
 * BUTTONS, NOT ONLY DRAG.
 *
 * J8 requires an accessible alternative to dragging, and the simplest correct
 * answer is to make buttons the primary mechanism rather than the fallback:
 * move-up and move-down work with a keyboard, with a screen reader, and with a
 * thumb on a moving train.
 */
.gallery-admin__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin-top: 0.35rem;
}

.gallery-admin__actions .btn {
  min-height: 40px;
  min-width: 40px;
  padding: 0.3rem 0.55rem;
  font-size: 0.82rem;
}

.upload-status {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
  margin-top: 0.4rem;
}

.upload-status--working { color: #ffc98a; }
.upload-status--ok { color: #8fe3c2; }
.upload-status--error { color: #f0a5a5; }

/* ==========================================================================
   NARROW PHONES — 320px must work, not merely not break
   ========================================================================== */

@media (max-width: 22.5rem) {
  .arsenal-item {
    grid-template-columns: 2.2rem 1fr;
  }
  .arsenal-item__count {
    grid-column: 2;
    justify-self: start;
    margin-top: 0.2rem;
  }
  .statebar {
    flex-wrap: wrap;
  }
  .statebar__clock {
    margin-left: 0;
    width: 100%;
  }
  .gallery-admin__row {
    grid-template-columns: 3rem 1fr;
  }
  .gallery-admin__image { width: 3rem; height: 3rem; }
}

/* Nothing in this file may introduce a sideways scroll. */
.view, .card, .statebar, .arsenal, .feed, .gallery {
  max-width: 100%;
  overflow-wrap: anywhere;
}
