/* =========================================================================
   shared.css — components both shells need.

   The admin shell (_base.html) and the player shell (_player_base.html) load
   different stylesheets on purpose: admin.css is desk-shaped, climb.css and
   court.css are courtside-shaped, and court.css styles .pick and .search, which
   two admin templates use for other things. Keeping them apart is deliberate.

   But a few components are genuinely shared, and duplicating them into both is
   how the palette ended up in seven files. They live here, and both shells load
   this.

   Starts with the flash block, which was in admin.css — so a flash set before
   redirecting to a PLAYER page rendered unstyled, and nobody had noticed because
   no player page had a flash until the join button arrived.

   The form primitives followed, with the structured score control: .field and
   friends, .abtn, .radio-row, .dlg-actions, .report-dlg, .panel-title. A form
   field looks the same wherever it is and had no business living in an admin
   stylesheet — _report_dialog.html is included by an ADMIN page and a PLAYER
   page, and only one of them loads admin.css.

   Both shells load this file LAST, so a rule moved here still wins wherever it
   won before.

   Still on the admin shell and still to move: nothing the dialog needs.
   `player_tournament.html` itself uses only .page-title, .page-sub and
   .stub-eyebrow — the three that stand between it and _player_base.html
   (HANDOFF §7 step 5).
   ========================================================================= */

/* Links carry no decoration anywhere in this product; a row, a tab and a card
   are all anchors, and the browser default underlines every one of them.

   This lived in admin.css only, because climb.css never needed it — in
   climb.html every row is a <div> the JS makes tappable, so there were no
   anchors to reset. The moment the player pages became real links, every row,
   tab and chevron rendered underlined and link-coloured. It belongs to both
   shells, so it belongs here. */
a { color: inherit; text-decoration: none; }

.flashes { display: grid; gap: 8px; margin: 0 0 18px; padding: 0; list-style: none; }

.flash {
  padding: 11px 14px;
  border-radius: var(--r-s);
  border: 1px solid var(--border-2);
  background: var(--surface);
  color: var(--t-body);
  font: 600 14px/1.45 var(--sans);
}

.flash-ok {
  border-color: var(--acc-line);
  background: var(--acc-wash);
  color: var(--acc);
}

.flash-error {
  border-color: var(--danger-line);
  background: var(--danger-wash);
  color: var(--danger);
}

.flash-warn {
  border-color: var(--amb-line);
  background: var(--amb-wash);
  color: var(--amb);
}

/* A section heading between blocks on a page. HANDOFF §7b flagged this as
   "applied but defined NOWHERE": prod_home.html carried the whole recipe as an
   inline style on all three of its headings, because there was no class to use.
   It was real only inside the demo CRM's page-local <style>. */
.sech {
  font: 700 11px var(--mono); letter-spacing: .16em; text-transform: uppercase;
  color: var(--t-muted-2); margin: 28px 0 10px;
}

/* =========================================================================
   In-app notifications.

   Amber rather than the accent, deliberately: --acc is this product's "good",
   and one of the three things a bubble can mean is that somebody's run ended.
   Amber says "there is something here" without saying whether it is welcome.
   ========================================================================= */

.news-dot {
  flex: none; align-self: center;
  min-width: 20px; height: 20px; padding: 0 6px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px;
  /* Solid amber with its PAIRED ink. --amb-container is a 14% tint and
     --on-amb is the screen colour, so pairing those two would put near-black
     on near-black; the container tint is for panels, not for a badge that has
     to be legible at 20px. */
  background: var(--amb); color: var(--on-amb);
  font: 700 11px var(--mono); letter-spacing: .02em;
}

.news {
  border: 1px solid var(--amb-line); border-radius: var(--r-m);
  background: var(--amb-wash);
  padding: 12px 14px; margin: 0 0 18px;
  display: flex; flex-direction: column; gap: 6px;
}
.news-line {
  font: 600 13px/1.45 var(--sans); color: var(--amb);
  overflow-wrap: anywhere;
}

/* =========================================================================
   Form primitives — moved verbatim from admin.css.

   `.field` is a COLUMN. Never reach for it to make a row: writing
   <div class="field" style="display:flex"> re-declares `display` without
   overriding `flex-direction`, so it renders a stack with every flex:1 on its
   children inert. That is what left six list pages with no layout (CLAUDE.md
   trap 8, HANDOFF §7a). `.field-row` is the row.
   ========================================================================= */

.field { display: flex; flex-direction: column; margin-bottom: 16px; }
.field-row { display: flex; flex-direction: column; gap: 0; }
.field-row .field { flex: 1; }
.field-label { font: 700 11px var(--sans); letter-spacing: .04em; color: var(--t-body); margin-bottom: 7px; }
.field-hint { font: 500 11.5px var(--sans); color: var(--t-muted-2); margin-bottom: 8px; }
.field-input {
  font: 500 14px var(--sans); color: var(--t-hi);
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: var(--r-s);
  padding: 11px 13px; width: 100%; outline: none;
  transition: border-color 150ms ease;
}
.field-input:focus { border-color: var(--acc); }
.field-textarea { resize: vertical; font: 500 13px var(--mono); line-height: 1.6; }
select.field-input { cursor: pointer; }
.field-err { font: 600 11.5px var(--sans); color: var(--danger); margin-top: 7px; }

/* A flex item defaults to min-width:auto, which resolves to MIN-CONTENT — and a
   <select>'s min-content width is its widest option, so the reviewer dropdown on
   the join-requests queue refused to shrink and pushed Approve off-screen. It is
   a flex child everywhere it appears, so this is fixed at every width. */
.field-input { min-width: 0; }

/* Emails and member ids carry no break opportunity, so without this a hint
   widens its container past the viewport instead of wrapping. */
.field-hint { overflow-wrap: anywhere; }

.panel-title { font: 800 17px var(--cond); letter-spacing: .04em; text-transform: uppercase; color: var(--t-hi); margin-bottom: 14px; }

.abtn {
  display: inline-block; cursor: pointer;
  font: 700 12px var(--sans); letter-spacing: .02em;
  padding: 10px 16px; border-radius: var(--r-s);
  background: var(--surface); border: 1px solid var(--border-2); color: var(--t-hi);
  transition: border-color 150ms ease, background 150ms ease;
}
.abtn:hover { border-color: var(--t-dim); background: var(--surface-2); }
.abtn--primary { background: var(--acc); border-color: var(--acc); color: var(--on-acc); }
.abtn--primary:hover { filter: brightness(1.06); }
.abtn--danger { color: var(--danger); border-color: var(--danger-line); }
.abtn--danger:hover:not(:disabled) { background: var(--danger-wash); }
.abtn:disabled { opacity: .4; cursor: not-allowed; }

/* =========================================================================
   The result dialog, and the score control inside it.
   ========================================================================= */

.report-dlg {
  border: 1px solid var(--border-2); border-radius: var(--r-l);
  background: var(--surface); color: var(--t-body);
  padding: 20px 20px 18px; width: min(420px, calc(100vw - 32px));
}
.report-dlg::backdrop { background: rgba(0, 0, 0, .6); }
.radio-row { display: flex; align-items: center; gap: 9px; padding: 9px 11px; margin-bottom: 7px; border: 1px solid var(--border-2); border-radius: var(--r-s); font: 600 13.5px var(--sans); color: var(--t-body); cursor: pointer; }
.radio-row:hover { border-color: var(--t-dim); }
.radio-row input { accent-color: var(--acc); }
.dlg-actions { display: flex; justify-content: flex-end; gap: 9px; margin-top: 16px; }

/* One set: a label, two games boxes, and the tiebreak affordance that appears
   when they tie at the format's tiebreak point. Grid rather than flex so the
   boxes stay the same width whether or not the row carries a label. */
.set-row {
  display: grid; grid-template-columns: 34px 1fr 12px 1fr;
  align-items: center; gap: 8px; margin-bottom: 8px;
}
.set-no { font: 700 11px var(--mono); color: var(--t-muted-2); }
/* Names over the columns. Ellipsis rather than wrap, so a long name cannot
   push the two boxes out of alignment with each other. */
.set-head { margin-bottom: 4px; }
.set-who {
  font: 700 10px var(--mono); letter-spacing: .08em; text-transform: uppercase;
  color: var(--t-muted-2); text-align: center;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.set-x { font: 600 12px var(--sans); color: var(--t-dim); text-align: center; }
.set-games {
  font: 700 15px var(--mono); color: var(--t-hi); text-align: center;
  background: var(--surface-2); border: 1px solid var(--border-2);
  border-radius: var(--r-s); padding: 10px 6px; width: 100%;
  outline: none; min-width: 0;
  transition: border-color 150ms ease;
}
.set-games:focus { border-color: var(--acc); }
/* The spinners are noise on a two-digit field and shrink the tap target. */
.set-games::-webkit-outer-spin-button,
.set-games::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.set-games { -moz-appearance: textfield; appearance: textfield; }

/* The tiebreak question. It spans the whole row because it replaces the pair
   below it rather than sitting beside them. */
.set-tb {
  grid-column: 1 / -1;
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 8px 10px; margin-top: 2px;
  border: 1px solid var(--amb-line); border-radius: var(--r-s);
  background: var(--amb-wash);
}
.set-tb-q { font: 600 11.5px var(--sans); color: var(--amb); }
.set-tb-opt {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  font: 600 12.5px var(--sans); color: var(--t-body);
}
.set-tb-opt input { accent-color: var(--acc); }

/* What the boxes compose, echoed back so the score being saved is visible
   before saving it. The server still validates it — this is not a verdict. */
.score-preview {
  font: 700 13px var(--mono); letter-spacing: .04em; color: var(--acc);
  margin-top: 4px; min-height: 18px;
}
.score-preview.is-empty { color: var(--t-dim); }

/* Touch. Same reasoning as bracket.css:157 and admin.css's own block: there is
   no hover to reveal anything, and a 24-30px target is far below what a finger
   needs. These live here because the player shell does not load admin.css. */
@media (hover: none) {
  .abtn { min-height: 44px; }
  .set-games { min-height: 44px; }
  .set-tb-opt { min-height: 44px; }
}

/* Desktop is the additive layer, the same polarity as admin.css and climb.css. */
@media (min-width: 880px) {
  .field-row { flex-direction: row; gap: 14px; }
}
