/* Broomstack design system.
 *
 * Ported from the Claude Design project "Broomstack league platform design"
 * (Broomstack.html — nine high-fidelity screen mockups plus a component
 * inventory). Tokens, chrome, and components are taken from that file
 * verbatim so the built screens and the mockups stay the same design.
 *
 * The mockup expresses per-screen layout as inline styles on a fixed
 * 1440px frame. Those repeated patterns are lifted into real classes here
 * (.page, .weekgrid, .iceblock, .banner, …) so templates stay readable and
 * the layout is responsive rather than frame-width.
 *
 * Colors, per the design's own legend:
 *   Slate #2D3042 — chrome and headings
 *   Gold  #C9A54A — the single primary action per view, used sparingly
 *   Blue  #5B7B9A — secondary actions, info, the home club
 *   Paper #F7F7F2 — page background
 * Stone red and yellow are team colors only, never chrome.
 */

:root {
  --slate: #2d3042;
  --slate-70: rgba(45, 48, 66, 0.7);
  --slate-45: rgba(45, 48, 66, 0.45);
  --slate-surface: #363a4f;
  --gold: #c9a54a;
  --gold-dk: #b08f36;
  --gold-tint: #f6efdc;
  --paper: #f7f7f2;
  --blue: #5b7b9a;
  --blue-dk: #4a677f;
  --blue-tint: #eaf0f5;
  --ink: #2d3042;
  --muted: #6f7280;
  --faint: #9a9ca6;
  --line: #e4e4de;
  --line-2: #d6d6cf;
  --white: #fff;
  --red: #c0392b;
  --red-tint: #fbe9e6;
  --yellow: #e5b028;
  --yellow-tint: #fbf1d6;
  --green: #4b8a5a;
  --green-tint: #e7f1e9;
  --r: 5px;
  --r-lg: 8px;
  --sh: 0 1px 2px rgba(45, 48, 66, 0.06), 0 1px 3px rgba(45, 48, 66, 0.05);
  --sh-md: 0 4px 14px rgba(45, 48, 66, 0.09);
}

* { box-sizing: border-box; }
html, body { margin: 0; }

body {
  font-family: 'IBM Plex Sans', system-ui, sans-serif;
  background: var(--paper);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  line-height: 1.45;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

h1, h2, h3, h4, h5 { margin: 0; font-weight: 700; line-height: 1.2; }
p { margin: 0; }
a { color: var(--blue); text-decoration: none; }
a:hover { color: var(--blue-dk); text-decoration: underline; }

svg.i {
  width: 18px; height: 18px;
  stroke: currentColor; fill: none;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
  flex: none;
}

/* Every icon in the sprite is drawn as an outline — strokes, no areas — so
   `stroke: currentColor; fill: none` is not decoration, it is the
   difference between the icon existing and not.
 *
 * That treatment used to require `class="i"`, and 137 of the 141 call
 * sites did not carry it. Those icons fell back to the SVG default of
 * `fill: black; stroke: none`, which renders a path with no enclosed area
 * as *nothing at all* — the icon still occupied its box, so buttons like
 * "Add season" showed a 16px gap where the plus should be. Symbols that do
 * enclose an area (#ic-stone) came out as a black blob instead, which is
 * what the SEASON card kick was.
 *
 * Keyed on the icon being a sprite reference rather than on a class, so a
 * new `<svg><use href="#ic-…">` is correct by default and cannot
 * reintroduce this by forgetting something. The context rules further down
 * still own size and colour; this only sets paint.
 *
 * `.mark` is excluded deliberately: the brand lockup carries its own
 * `fill`/`stroke` presentation attributes, and CSS outranks those, so
 * without the exclusion this would repaint the gold logo in currentColor. */
svg:has(use):not(.mark) {
  stroke: currentColor; fill: none;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}
.i-14 { width: 14px; height: 14px; }
.i-16 { width: 16px; height: 16px; }
.i-20 { width: 20px; height: 20px; }
.i-24 { width: 24px; height: 24px; }

/* ---------- app chrome ---------- */

.appnav {
  display: flex; align-items: center; gap: 26px;
  background: var(--slate); color: #eceef4;
  padding: 0 24px; height: 58px;
  flex-wrap: wrap;
}
.brand {
  display: flex; align-items: center; gap: 10px;
  font-weight: 700; font-size: 17px; letter-spacing: -0.01em; color: #fff;
}
.brand:hover { color: #fff; text-decoration: none; }
.brand .mark { width: 28px; height: 28px; flex: none; }
.navlinks { display: flex; gap: 4px; height: 100%; }
.navlinks a {
  color: rgba(255, 255, 255, 0.72);
  font-size: 14px; font-weight: 500;
  display: flex; align-items: center;
  padding: 0 13px; height: 100%;
  border-bottom: 2px solid transparent;
}
.navlinks a:hover { color: #fff; text-decoration: none; }
.navlinks a.on { color: #fff; border-bottom-color: var(--gold); }
.navspacer { flex: 1; }
.navtools { display: flex; align-items: center; gap: 10px; }
.navbtn {
  width: 36px; height: 36px; border-radius: var(--r);
  display: flex; align-items: center; justify-content: center;
  color: rgba(255, 255, 255, 0.75); background: transparent;
  border: 0; cursor: pointer;
}
.navbtn:hover { background: rgba(255, 255, 255, 0.1); color: #fff; }
.navlink-quiet { color: rgba(255, 255, 255, 0.72); font-size: 13.5px; }
.navlink-quiet:hover { color: #fff; text-decoration: none; }
.avatar {
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--blue); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-weight: 600; font-size: 13px; flex: none;
}
.avatar-gold { background: var(--gold); color: var(--slate); }
.adminpill {
  font-size: 11px; font-weight: 600; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--slate);
  background: var(--gold); padding: 3px 9px; border-radius: 20px;
}

/* page title bar */
.pagebar {
  display: flex; align-items: center; gap: 14px;
  padding: 20px 32px; background: var(--white);
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.pagebar h3 { font-size: 20px; color: var(--slate); }
.pagebar .sub { color: var(--muted); font-size: 13px; }
.pagebar .spacer { flex: 1; }

/* ---------- page shell ---------- */

.page { padding: 28px 32px 64px; flex: 1; }
.page-narrow { max-width: 720px; margin-left: auto; margin-right: auto; }
.page-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; margin-bottom: 22px; flex-wrap: wrap;
}
.page-head h1 { font-size: 24px; color: var(--slate); }
.page-head .sub { color: var(--muted); font-size: 14px; margin-top: 2px; }
.section-title {
  font-size: 16px; color: var(--slate);
  margin: 28px 0 12px;
}

.sitefoot {
  color: var(--faint); font-size: 12.5px;
  padding: 20px 32px 32px; text-align: center;
}

/* ---------- buttons ---------- */

.btn {
  font-family: inherit; font-size: 14px; font-weight: 600;
  border-radius: var(--r); padding: 9px 16px;
  display: inline-flex; align-items: center; gap: 8px;
  cursor: pointer; border: 1px solid transparent;
  line-height: 1; white-space: nowrap;
}
.btn:hover { text-decoration: none; }
.btn svg { width: 16px; height: 16px; }
.btn-gold { background: var(--gold); color: var(--slate); border-color: var(--gold-dk); }
.btn-gold:hover { background: var(--gold-dk); color: #fff; }
.btn-slate { background: var(--slate); color: #fff; }
.btn-slate:hover { background: #3c4058; color: #fff; }
.btn-ghost { background: transparent; color: var(--slate); border-color: var(--line-2); }
.btn-ghost:hover { background: var(--white); border-color: var(--slate-45); color: var(--slate); }
.btn-blue { background: var(--blue); color: #fff; }
.btn-blue:hover { background: var(--blue-dk); color: #fff; }
.btn-sm { padding: 6px 11px; font-size: 12.5px; }
.btn-lg { padding: 14px 22px; font-size: 16px; }
.btn-block { width: 100%; justify-content: center; }
.btn:disabled, .btn.disabled { opacity: 0.45; cursor: not-allowed; }
.btnrow { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* ---------- tags ---------- */

.tag {
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.02em;
  padding: 3px 9px; border-radius: 20px;
  display: inline-flex; align-items: center; gap: 5px; line-height: 1.3;
}
.tag-gold { background: var(--gold-tint); color: var(--gold-dk); }
.tag-blue { background: var(--blue-tint); color: var(--blue-dk); }
.tag-slate { background: #e7e8ec; color: var(--slate); }
.tag-green { background: var(--green-tint); color: var(--green); }
.tag-red { background: var(--red-tint); color: var(--red); }
.tag-draft {
  background: repeating-linear-gradient(45deg, #f0ede3, #f0ede3 5px, #e8e4d4 5px, #e8e4d4 10px);
  color: #8a7a45; border: 1px dashed #cbbf94;
}
.tag-out { background: transparent; border: 1px solid var(--line-2); color: var(--muted); }

/* stone dots — team color only, never chrome */
.stone {
  width: 14px; height: 14px; border-radius: 50%; flex: none;
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.55), inset 0 -2px 3px rgba(0, 0, 0, 0.18);
}
.stone-red { background: var(--red); }
.stone-yel { background: var(--yellow); }
.stone.sm { width: 11px; height: 11px; }
.stone.lg { width: 18px; height: 18px; }

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

.card {
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh);
}
.card-pad { padding: 20px; }
.card-kick {
  font-family: 'IBM Plex Mono', monospace; font-size: 11px;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted); font-weight: 600; margin-bottom: 10px;
  display: flex; align-items: center; gap: 7px;
}
.card-kick svg { width: 14px; height: 14px; color: var(--blue); }
.card-head {
  display: flex; align-items: center; gap: 8px;
  background: var(--slate); color: #fff; padding: 11px 20px;
  font-weight: 600; font-size: 13px;
  letter-spacing: 0.04em; text-transform: uppercase;
}
.card-head svg { color: var(--gold); }
.card h2 { font-size: 16px; color: var(--slate); }
.cards {
  display: grid; gap: 20px;
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
}

/* ---------- banners and messages ---------- */

.banner {
  display: flex; align-items: center; gap: 14px;
  background: var(--gold-tint); border: 1px solid #e6d6a3;
  border-radius: var(--r-lg); padding: 14px 18px; margin-bottom: 24px;
  font-size: 13.5px; color: var(--slate); flex-wrap: wrap;
}
.banner svg { color: var(--gold-dk); flex: none; }
.banner .banner-body { flex: 1; min-width: 14rem; }
.banner-blue { background: var(--blue-tint); border-color: #c9d8e5; }
.banner-blue svg { color: var(--blue-dk); }
.banner-green { background: var(--green-tint); border-color: #c3ddca; }
.banner-green svg { color: var(--green); }
.banner-red { background: var(--red-tint); border-color: #f0cbc5; }
.banner-red svg { color: var(--red); }

.messages { list-style: none; margin: 0 0 20px; padding: 0; }
.messages li {
  border-radius: var(--r-lg); padding: 11px 16px; margin-bottom: 8px;
  font-size: 13.5px; border: 1px solid var(--line);
  background: var(--white); color: var(--slate);
}
.messages li.success { background: var(--green-tint); border-color: #c3ddca; }
.messages li.warning { background: var(--gold-tint); border-color: #e6d6a3; }
.messages li.error { background: var(--red-tint); border-color: #f0cbc5; }
.messages li.info { background: var(--blue-tint); border-color: #c9d8e5; }

.note {
  background: var(--white); border: 1px solid var(--line);
  border-left: 3px solid var(--blue); border-radius: var(--r);
  padding: 10px 14px; font-size: 13px; color: var(--slate);
  margin-bottom: 16px;
}
.note b { color: var(--blue-dk); }
.note.flag { border-left-color: var(--gold); }
.note.flag b { color: var(--gold-dk); }

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

.field { margin-bottom: 18px; }
.field label {
  display: block; font-size: 13px; font-weight: 600;
  color: var(--slate); margin-bottom: 6px;
}
.field .hint, .field .help {
  font-size: 12px; color: var(--muted); font-weight: 400; margin-top: 5px;
}
.input, .select, .textarea,
.field input[type='text'], .field input[type='email'], .field input[type='password'],
.field input[type='date'], .field input[type='time'], .field input[type='number'],
.field select, .field textarea {
  width: 100%; font-family: inherit; font-size: 14px; color: var(--ink);
  background: var(--white); border: 1px solid var(--line-2);
  border-radius: var(--r); padding: 10px 12px;
}
.input:focus, .select:focus, .textarea:focus,
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--blue);
  box-shadow: 0 0 0 3px var(--blue-tint);
}
.input::placeholder { color: var(--faint); }
.textarea, .field textarea { resize: vertical; min-height: 76px; }

/* Django renders multiple-choice widgets as a bare <ul>. */
.field ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.field ul li { font-size: 14px; }
.field ul label {
  display: flex; align-items: center; gap: 9px;
  font-weight: 400; margin: 0; cursor: pointer;
  border: 1px solid var(--line-2); border-radius: var(--r);
  background: var(--white); padding: 9px 12px;
}
.field ul label:hover { border-color: var(--slate-45); }
.field input[type='checkbox'], .field input[type='radio'] { width: auto; margin: 0; }
.field-inline label { display: inline-flex; align-items: center; gap: 8px; }

.errorlist {
  list-style: none; margin: 6px 0 0; padding: 0;
  color: var(--red); font-size: 12.5px; display: grid; gap: 3px;
}
.errorlist li { border: 0; background: none; padding: 0; }

.stacked { max-width: 40rem; }
.stacked .btn, .stacked button[type='submit'] { margin-right: 8px; }
button[type='submit'] {
  font-family: inherit; font-size: 14px; font-weight: 600;
  border-radius: var(--r); padding: 9px 16px; cursor: pointer;
  border: 1px solid var(--gold-dk); background: var(--gold); color: var(--slate);
}
button[type='submit']:hover { background: var(--gold-dk); color: #fff; }

/* A submit button that names a variant has to get it. The bare
   `button[type='submit']` rule above is an element+attribute selector
   (0,1,1), which outranks a plain `.btn-ghost` class (0,1,0) — so every
   submit button asking to be quiet came out gold instead. That put
   "Decline" on rink invitations and the pending banner in the same loud
   gold as the "Accept" next to it, which is the opposite of what the
   markup asked for. Re-stated here at (0,2,1) so the variant wins. */
button[type='submit'].btn-ghost {
  background: transparent; color: var(--slate); border-color: var(--line-2);
}
button[type='submit'].btn-ghost:hover {
  background: var(--white); border-color: var(--slate-45); color: var(--slate);
}
button[type='submit'].btn-blue { background: var(--blue); border-color: var(--blue-dk); color: #fff; }
button[type='submit'].btn-blue:hover { background: var(--blue-dk); color: #fff; }
button[type='submit'].btn-slate { background: var(--slate); border-color: var(--slate); color: #fff; }
.link-button {
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--blue); font: inherit; font-size: 12.5px;
}
.link-button:hover { color: var(--blue-dk); text-decoration: underline; }
/* A submit button asking to look like a link has to get it. The bare
   `button[type='submit']` rule is an element+attribute selector (0,1,1)
   and outranks `.link-button` (0,1,0), so all four of its properties —
   background, border, padding, colour — were being overridden and every
   one of these rendered as a full gold primary button. Eighteen of them,
   across eight templates. Re-stated at (0,2,1) so the class wins. */
button[type='submit'].link-button {
  background: none; border: 0; padding: 0;
  color: var(--blue); font: inherit; font-size: 12.5px;
}
button[type='submit'].link-button:hover {
  background: none; color: var(--blue-dk); text-decoration: underline;
}
.cancel { font-size: 13.5px; color: var(--muted); }

/* Wraps rather than overflowing: the calendar's segmented control grows
   as facility-admin screens are added (Displays, Webhooks), and a phone
   is 390px wide. */
.seg {
  display: inline-flex; flex-wrap: wrap; max-width: 100%;
  background: #edece6; border-radius: var(--r); padding: 3px; gap: 2px;
}
.seg a, .seg button {
  font-family: inherit; font-size: 13px; font-weight: 600;
  border: 0; background: transparent; color: var(--muted);
  padding: 7px 14px; border-radius: 4px; cursor: pointer;
}
.seg a:hover { text-decoration: none; color: var(--slate); }
.seg a.on, .seg button.on { background: var(--white); color: var(--slate); box-shadow: var(--sh); }

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

.tablewrap { overflow-x: auto; border-radius: var(--r-lg); border: 1px solid var(--line); }
.table { width: 100%; border-collapse: collapse; font-size: 13.5px; background: var(--white); }
.table th {
  text-align: left; font-size: 11.5px; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--muted); font-weight: 600;
  padding: 11px 14px; border-bottom: 2px solid var(--line-2); white-space: nowrap;
}
.table td { padding: 12px 14px; border-bottom: 1px solid var(--line); }
.table tbody tr:hover { background: #faf9f4; }
.table .num { text-align: right; font-variant-numeric: tabular-nums; font-family: 'IBM Plex Mono', monospace; }
.table .rk { font-family: 'IBM Plex Mono', monospace; color: var(--faint); font-weight: 600; }

/* definition lists — league format, request detail */
.detail { display: grid; grid-template-columns: 11rem 1fr; gap: 0; margin: 0; }
.detail dt {
  font-family: 'IBM Plex Mono', monospace; font-size: 11px;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted);
  padding: 11px 0; border-bottom: 1px solid var(--line);
}
.detail dd {
  margin: 0; padding: 11px 0; font-size: 14px;
  border-bottom: 1px solid var(--line); color: var(--slate);
}
@media (max-width: 40rem) {
  .detail { grid-template-columns: 1fr; }
  .detail dt { padding-bottom: 0; border-bottom: 0; }
}

/* ---------- ice calendar ---------- */

.weeknav {
  display: flex; align-items: center; gap: 16px;
  margin-bottom: 14px; font-size: 13.5px;
}
.weeknav strong { color: var(--slate); }

.weekgrid {
  display: grid; grid-template-columns: repeat(7, minmax(9rem, 1fr));
  background: var(--white); border: 1px solid var(--line-2);
  border-radius: var(--r-lg); overflow: hidden;
}
.weekgrid .day { border-left: 1px solid var(--line); min-height: 9rem; padding: 0 0 8px; }
.weekgrid .day:first-child { border-left: 0; }
.weekgrid .day.today { background: var(--gold-tint); }
.dayhead { padding: 10px 8px; text-align: center; border-bottom: 1px solid var(--line-2); }
.dayhead .dow {
  font-family: 'IBM Plex Mono', monospace; font-size: 11px;
  color: var(--muted); text-transform: uppercase;
}
.dayhead .dom { font-weight: 700; color: var(--slate); }
.day-add {
  display: block; text-align: center; font-size: 12px;
  color: var(--faint); padding: 6px;
}
.day-add:hover { color: var(--blue-dk); }

.blocks { list-style: none; margin: 0; padding: 6px; display: grid; gap: 6px; }

/* An ice block. Blue is the club you are looking as; gold is the other
   club. Matches the mockup's two-club legend. */
.iceblock {
  background: #efe7d6; border: 1px solid var(--gold-dk);
  border-left: 3px solid var(--gold-dk);
  border-radius: var(--r); padding: 7px 8px; font-size: 11.5px;
}
.iceblock .who { font-weight: 700; color: var(--gold-dk); }
.iceblock.own { background: var(--blue-tint); border-color: var(--blue); border-left-color: var(--blue); }
.iceblock.own .who { color: var(--blue-dk); }
.iceblock .when { color: var(--slate); }
.iceblock .meta { color: var(--muted); }
.iceblock .block-actions {
  display: flex; gap: 8px; align-items: center; margin-top: 5px;
  font-size: 11.5px;
}
.iceblock .block-actions form { display: inline; }
.iceblock.pending {
  background: repeating-linear-gradient(45deg, #fff, #fff 5px, #f6efdc 5px, #f6efdc 10px);
  border: 1.5px dashed var(--gold-dk);
}

.seasonday { margin-bottom: 20px; }
.seasonday h2 {
  font-size: 14px; color: var(--slate);
  padding-bottom: 6px; border-bottom: 1px solid var(--line-2); margin-bottom: 8px;
}
.seasonday .blocks { padding: 0; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); }

/* ---------- lists ---------- */

.requests { list-style: none; margin: 0 0 20px; padding: 0; }
.requests li {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 11px 14px; background: var(--white);
  border: 1px solid var(--line); border-radius: var(--r);
  margin-bottom: 6px; font-size: 13.5px;
}
.requests .req-club { color: var(--muted); font-size: 12.5px; }
.requests .req-sheets { font-family: 'IBM Plex Mono', monospace; font-size: 12.5px; color: var(--muted); }

.roster { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 6px; }
.roster li {
  display: flex; justify-content: space-between; gap: 10px;
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--r); padding: 8px 11px; font-size: 13px;
}
.roster .pos { color: var(--muted); font-size: 11px; text-transform: uppercase; }

.status { font-size: 11.5px; font-weight: 600; padding: 3px 9px; border-radius: 20px; }
.status-pending { background: var(--gold-tint); color: var(--gold-dk); }
.status-approved { background: var(--green-tint); color: var(--green); }
.status-declined { background: var(--red-tint); color: var(--red); }
.status-withdrawn { background: #e7e8ec; color: var(--slate); }

/* ---------- utilities ---------- */

.muted { color: var(--muted); }
.mono { font-family: 'IBM Plex Mono', monospace; }
.empty { color: var(--faint); font-size: 13px; }
.divider { height: 1px; background: var(--line); border: 0; margin: 16px 0; }
.iconpair { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); font-size: 13px; }
.iconpair svg { width: 15px; height: 15px; color: var(--faint); }

/* ---------- auth ---------- */

.authwrap {
  flex: 1; display: flex; align-items: center; justify-content: center;
  padding: 48px 24px;
}
.authcard { width: 100%; max-width: 25rem; }
.authcard .card-pad { padding: 28px; }
.authcard h1 { font-size: 22px; color: var(--slate); margin-bottom: 4px; }

/* ---------- responsive ---------- */

@media (max-width: 60rem) {
  .weekgrid { grid-template-columns: repeat(2, 1fr); }
  .weekgrid .day { border-left: 1px solid var(--line); border-top: 1px solid var(--line); }
}
@media (max-width: 40rem) {
  .appnav { height: auto; padding: 10px 16px; gap: 12px; }
  .navlinks { flex-wrap: wrap; height: auto; }
  .navlinks a { padding: 6px 10px; border-bottom: 0; }
  .navlinks a.on { color: var(--gold); }
  .page, .pagebar { padding-left: 16px; padding-right: 16px; }
  .weekgrid { grid-template-columns: 1fr; }
}

/* ---------- team formation board (#638) ---------- */

/* Dense by design — the registrar is comparing preferences across a
   pool of forty-odd names, so this screen trades whitespace for how
   much fits on one laptop screen. */

.page-formation { padding: 0; }
.page-formation .messages, .page-formation > .note { margin: 16px 24px 0; }

.formation {
  display: grid;
  grid-template-columns: 22rem 1fr;
  align-items: start;
  min-height: 40rem;
  margin-top: 16px;
  border-top: 1px solid var(--line-2);
}
.formation.is-saving { opacity: 0.6; pointer-events: none; }

.tray {
  border-right: 1px solid var(--line-2);
  background: var(--white);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  max-height: 100vh;
}
.tray-head { padding: 14px 16px; border-bottom: 1px solid var(--line); }
.tray-title {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 12px; font-size: 14px; color: var(--slate);
}
.tray-search input { font-size: 13px; }
.tray-list { list-style: none; margin: 0; padding: 10px 12px; overflow: auto; flex: 1; }

.tray-card {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 10px;
  border: 1px solid var(--line-2);
  border-radius: var(--r);
  padding: 9px 11px;
  margin-bottom: 8px;
  background: var(--white);
  cursor: grab;
}
.tray-card:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.tray-card.dragging {
  border: 2px solid var(--gold);
  background: var(--gold-tint);
  cursor: grabbing;
  box-shadow: var(--sh-md);
}
.tray-card .grip { color: var(--faint); }
.tray-name { font-weight: 600; font-size: 13.5px; }
.tray-meta { color: var(--muted); font-size: 11.5px; }
.tray-move { grid-column: 1 / -1; display: flex; gap: 6px; align-items: center; }
.tray-move select {
  flex: 1; font-family: inherit; font-size: 12px;
  border: 1px solid var(--line-2); border-radius: var(--r); padding: 4px 6px;
  background: var(--white); color: var(--ink);
}
.tray-empty { padding: 16px 4px; }
[data-drop-tray].drop-target { background: var(--blue-tint); }

.teams { padding: 16px 20px; background: var(--paper); }
.teamgrid {
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
}

.teamcard.complete { border-color: var(--green); border-width: 1.5px; }
.teamcard-head {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 15px; border-bottom: 1px solid var(--line);
}
.teamcard.complete .teamcard-head {
  background: var(--green-tint);
  border-bottom-color: #cfe3d3;
  border-radius: var(--r-lg) var(--r-lg) 0 0;
}
.teamname { flex: 1; min-width: 0; }
.teamname-input {
  width: 100%; border: 0; padding: 2px 0; background: transparent;
  font-family: inherit; font-weight: 700; font-size: 14px; color: var(--slate);
}
.teamname-input:focus {
  outline: none; border-bottom: 1px solid var(--blue); background: var(--white);
}
.teamcard-remove { color: var(--muted); font-size: 12px; }
.teamcard-remove:hover { color: var(--red); }

.seats { list-style: none; margin: 0; padding: 10px 12px; display: grid; gap: 6px; }
.seat {
  display: flex; align-items: center; gap: 9px;
  font-size: 13px; border-radius: var(--r); padding: 6px 8px;
}
.seat-pos { width: 3.5rem; justify-content: center; }
.seat-name { font-weight: 600; flex: 1; }
.seat.open {
  border: 1px dashed var(--line-2);
  color: var(--faint); font-size: 12.5px;
}
.seat.open .seat-empty { flex: 1; }
.seat.drop-target {
  border: 2px dashed var(--blue);
  background: var(--blue-tint);
  color: var(--blue-dk);
  font-weight: 600;
}
/* Removing somebody is a real action, so the control has to be legible.
   --faint on white was already thin; on the gold background it was
   getting from the rule above, it was almost invisible. */
.seat-clear button, .seat-clear button[type='submit'] {
  color: var(--muted); font-size: 17px; line-height: 1; font-weight: 600;
}
.seat-clear button:hover, .seat-clear button[type='submit']:hover {
  color: var(--red); text-decoration: none;
}

.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 design flags this screen as desktop-only: dragging across two
   dense panels does not work on a phone. The panels stack and the
   "Move to…" select carries the interaction instead. */
@media (max-width: 60rem) {
  .formation { grid-template-columns: 1fr; }
  .tray { position: static; max-height: none; border-right: 0; border-bottom: 1px solid var(--line-2); }
  .tray-card { cursor: default; }
  .tray-card .grip { display: none; }
}

/* ---------- draw grid (#639) ---------- */

.drawlegend {
  display: flex; gap: 16px; flex-wrap: wrap;
  font-size: 12.5px; color: var(--muted); margin-bottom: 14px;
}
.swatch-draft {
  width: 12px; height: 12px; border-radius: 3px;
  background: repeating-linear-gradient(45deg, #f0ede3, #f0ede3 4px, #e8e4d4 4px, #e8e4d4 8px);
  border: 1px dashed #cbbf94;
}

.drawgrid { width: 100%; border-collapse: separate; border-spacing: 8px; table-layout: fixed; }
.drawgrid th {
  font-size: 12px; background: var(--slate); color: #fff;
  padding: 7px; border-radius: var(--r); font-weight: 600;
}
.drawgrid th.draw-when, .drawgrid td.draw-when {
  background: transparent; color: var(--muted);
  text-align: left; width: 7rem; font-size: 11.5px;
}
.drawgrid td.draw-when { color: var(--slate); font-weight: 600; vertical-align: middle; }
.drawgrid td { vertical-align: top; }

.drawcell {
  background: var(--white); border: 1px solid var(--line-2);
  border-radius: var(--r); padding: 9px 10px;
  font-size: 12.5px; position: relative; min-height: 3.2rem;
}
.drawcell.draft {
  background: repeating-linear-gradient(45deg, #f7f5ec, #f7f5ec 5px, #f0ecdd 5px, #f0ecdd 10px);
  border: 1px dashed #cbbf94;
}
.drawcell.pinned { border-color: var(--gold-dk); }
.drawcell.placeholder { background: var(--blue-tint); border: 1px dashed var(--blue); }
.drawcell.empty {
  border: 1px dashed var(--line-2); color: var(--faint);
  text-align: center; background: transparent;
}
.drawcell-home { font-weight: 600; }
.drawcell-tbd { font-weight: 600; color: var(--blue-dk); }
.drawcell-pin { position: absolute; top: 5px; right: 5px; }
.drawcell-pin button { color: var(--line-2); }
.drawcell.pinned .drawcell-pin button { color: var(--gold-dk); }
.drawcell-pin button:hover { color: var(--gold-dk); }

.byerow td { font-size: 12px; color: var(--muted); padding-top: 0; }

/* ---------- score entry (#640) — mobile-first ---------- */

/* This screen is used standing on the ice with a phone, so targets are
   large and typing is kept to a minimum. */
.scoreform .scoremode { width: 100%; margin-bottom: 18px; }
.scoreform .scoremode button { flex: 1; }
.scorerow {
  display: flex; align-items: center; gap: 12px;
  margin-bottom: 12px;
}
.scorerow label { flex: 1; font-weight: 600; font-size: 15px; margin: 0; }
.scorebox {
  width: 5.5rem; flex: none;
  font-size: 22px; font-weight: 700; text-align: center;
  padding: 12px 8px; font-variant-numeric: tabular-nums;
}
.endstable input { padding: 6px 8px; text-align: center; }
.endstable td { padding: 6px 8px; }

/* ---------- live draft board (#642) ---------- */

.draftbar {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 12px 16px; margin-bottom: 16px;
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--r-lg);
}
.draftbar-turn { display: flex; align-items: center; gap: 12px; }
.draftbar-round {
  font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted);
}
.draftbar-onclock { font-size: 17px; color: var(--slate); }

.draftgrid { display: grid; grid-template-columns: 22rem 1fr; gap: 20px; align-items: start; }
.draftpool {
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--r-lg); overflow: hidden;
  position: sticky; top: 12px; max-height: 80vh; display: flex; flex-direction: column;
}
.draftpool .tray-list { max-height: none; }
.draftpool .tray-card { cursor: default; grid-template-columns: 1fr auto; }

.teamcard.onclock { border-color: var(--gold); border-width: 2px; }
.teamcard.onclock .teamcard-head { background: var(--gold-tint); }

.draftorder { padding-left: 1.4rem; }
.draftorder li { margin-bottom: 6px; }

/* The projected board: legible from across a room. */
.bigboard .draftbar-onclock { font-size: 28px; }
.bigboard .teamcard { font-size: 16px; }
.bigboard .seat { font-size: 16px; }
.bigboard .tray-name { font-size: 16px; }
.bigboard .draftpool { position: static; max-height: none; }

@media (max-width: 60rem) {
  .draftgrid { grid-template-columns: 1fr; }
  .draftpool { position: static; max-height: none; }
}

/* ---------- display screens (#643) ---------- */

/* A wall screen is read from across a room, so everything is larger and
   nothing is interactive. */
body.display { background: var(--slate); color: #eceef4; }

.displayhead {
  display: flex; align-items: center; gap: 14px;
  padding: 18px 32px; background: var(--slate-surface);
  border-bottom: 3px solid var(--gold);
}
.displayhead .mark { width: 36px; height: 36px; flex: none; }
.displayhead-title { font-size: 24px; font-weight: 700; color: #fff; }
.displayhead-sub { font-size: 15px; color: rgba(255, 255, 255, 0.7); }
.displayclock { font-size: 26px; font-weight: 600; color: var(--gold); }

.displaybody { padding: 28px 32px; }
.displaysplit {
  display: grid; gap: 28px;
  grid-template-columns: repeat(auto-fit, minmax(28rem, 1fr));
  align-items: start;
}
.panel-title {
  font-size: 22px; color: #fff; margin-bottom: 14px;
}
.panel-title .muted { color: rgba(255, 255, 255, 0.55); font-weight: 400; }

.displaytable { background: transparent; color: #eceef4; font-size: 18px; }
.displaytable th {
  color: rgba(255, 255, 255, 0.6); font-size: 13px;
  border-bottom-color: rgba(255, 255, 255, 0.25);
}
.displaytable td { border-bottom-color: rgba(255, 255, 255, 0.12); padding: 12px 14px; }
.displaytable tbody tr:hover { background: transparent; }
.displaytable .muted { color: rgba(255, 255, 255, 0.55); }
.displaytable .rk { color: rgba(255, 255, 255, 0.45); }
.display .empty { color: rgba(255, 255, 255, 0.5); font-size: 18px; }
.display .iceblock { background: var(--slate-surface); border-color: rgba(255,255,255,.2); }
.display .iceblock .who { color: var(--gold); }
.display .iceblock .when { color: #eceef4; }
.display .iceblock .meta { color: rgba(255, 255, 255, 0.55); }

.displaylinks { display: flex; gap: 16px; flex-wrap: wrap; font-size: 17px; }
.displaylinks a { color: var(--gold); }

/* ---------- display portal rotation editor ---------- */

.panelrota li { gap: 10px; }
.panelrota form { display: flex; align-items: center; gap: 4px; margin: 0; }
.panelseconds .input-sm { width: 4.5rem; }
.input-sm { padding: 4px 7px; font-size: 12.5px; }
.panelrota .link-button[disabled] { opacity: .3; cursor: default; }

/* Visible to a screen reader, not on screen: the per-panel seconds box
   is labelled by its row, which a sighted person reads and a screen
   reader would otherwise meet as a bare number field. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ---------- ice-entrance kiosk (#644) ---------- */

/* Sized for a tablet at the door, tapped by someone in gloves on their
   way onto the ice. Nothing here is smaller than a thumb, and the whole
   board is legible from arm's length. */

.kiosk { padding: 20px 22px 40px; }
.kiosk-board {
  display: grid; gap: 18px;
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
}
.kiosk-sheet {
  background: rgba(255, 255, 255, .04);
  border: 1px solid rgba(255, 255, 255, .1);
  border-radius: 14px; padding: 14px 16px 18px;
}
.kiosk-sheetname {
  font-size: 15px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--gold); margin: 0 0 12px;
}
.kiosk-game {
  background: rgba(255, 255, 255, .05);
  border: 1px solid rgba(255, 255, 255, .09);
  border-radius: 12px; padding: 14px; margin-bottom: 12px;
}
.kiosk-game.is-live { border-color: rgba(201, 165, 74, .55); }
.kiosk-game.is-over { opacity: .55; }
.kiosk-when {
  display: flex; justify-content: space-between; gap: 10px;
  font-size: 14px; color: rgba(255, 255, 255, .62);
}
.kiosk-league { font-size: 13px; }
.kiosk-teams {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  font-size: 21px; font-weight: 600; margin: 8px 0 12px; color: #fff;
}
.kiosk-vs { font-size: 13px; color: rgba(255, 255, 255, .45); }
.kiosk-state { font-size: 14px; color: rgba(255, 255, 255, .6); margin: 6px 0; }
.kiosk-free { color: rgba(255, 255, 255, .45); font-size: 14px; }

.kiosk-actions { display: grid; gap: 10px; }
.kiosk-btn {
  width: 100%; min-height: 60px; padding: 0 18px;
  font-size: 17px; font-weight: 600; cursor: pointer;
  border-radius: 12px; border: 1px solid rgba(255, 255, 255, .22);
  background: rgba(255, 255, 255, .09); color: #fff;
}
.kiosk-btn:active { transform: translateY(1px); }
.kiosk-btn-go { background: var(--gold); border-color: var(--gold); color: #14202b; }
.kiosk-btn-stop { background: rgba(190, 70, 60, .85); border-color: rgba(190, 70, 60, .9); }
.kiosk-finish { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.kiosk-finish .kiosk-btn { grid-column: 1 / -1; }
.kiosk-score {
  /* A grid item defaults to min-width:auto, and an <input>'s intrinsic
     min-content width is its `size` attribute — about 20 characters. So
     on a four-sheet board the two score boxes refuse to shrink into
     their 1fr columns and burst out of the card, over the next sheet.
     Only shows up once the columns are narrow enough to matter, which
     is exactly the wall-mounted four-sheet case this screen is for. */
  min-width: 0;
  min-height: 60px; font-size: 22px; text-align: center;
  border-radius: 12px; border: 1px solid rgba(255, 255, 255, .22);
  background: rgba(0, 0, 0, .25); color: #fff;
}

.kiosk-offline, .kiosk-toast {
  border-radius: 12px; padding: 12px 16px; margin-bottom: 14px; font-size: 15px;
}
.kiosk-offline { background: rgba(190, 140, 40, .2); border: 1px solid rgba(201, 165, 74, .5); color: #f2e2bb; }
.kiosk-toast { background: rgba(255, 255, 255, .1); color: #fff; }
.kiosk-toast.is-error { background: rgba(190, 70, 60, .3); }

.codeblock {
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--r);
  padding: 14px 16px; overflow-x: auto; font-size: 12.5px;
  font-family: 'IBM Plex Mono', monospace;
}

/* ---------- bonspiels (#645) ---------- */

.row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 560px) { .row2 { grid-template-columns: 1fr; } }

/* The bracket scrolls sideways in its own box — a 16-rink double
   elimination is simply wider than a laptop, and the page itself must
   never scroll horizontally. */
.bracketwrap { overflow-x: auto; padding-bottom: 8px; }
.bracket { display: flex; gap: 26px; align-items: flex-start; min-width: min-content; }
.bracket-round { min-width: 15rem; }
.bracket-round h3 {
  font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted); margin: 0 0 8px;
}
.bracket-match {
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--r); padding: 9px 11px; margin-bottom: 10px; font-size: 13px;
}
.bracket-match.is-done { border-left: 3px solid var(--green); }
.bracket-match.is-bye { opacity: .55; font-style: italic; }
.bracket-side { display: flex; justify-content: space-between; gap: 10px; }
.bracket-side.won { font-weight: 700; }
.bracket-side .muted { font-weight: 400; }
.bracket-meta { color: var(--muted); font-size: 11.5px; margin-top: 5px; }

.entryrow .tag { margin-left: 4px; }
.pooltable { margin-bottom: 20px; }
.displaytable .num { text-align: right; font-variant-numeric: tabular-nums; }
.bracket-score { display: flex; align-items: center; gap: 4px; margin: -4px 0 12px; }
.bracket-score .input-sm { width: 3.5rem; }

/* ---------- copy-to-clipboard toast (#691) ---------- */

.toast {
  position: fixed; left: 50%; bottom: 26px; transform: translate(-50%, 12px);
  background: var(--slate); color: #fff; font-size: 13.5px; font-weight: 500;
  padding: 11px 18px; border-radius: var(--r); box-shadow: var(--sh-lg);
  z-index: 60; opacity: 0; pointer-events: none;
  transition: opacity .18s ease, transform .18s ease;
}
.toast.is-on { opacity: 1; transform: translate(-50%, 0); }
.toast.is-error { background: var(--red); }
@media (prefers-reduced-motion: reduce) { .toast { transition: none; } }

.signuplink { display: flex; align-items: flex-start; gap: 14px; flex-wrap: wrap; }
.signuplink-url {
  font-size: 12.5px; margin-top: 8px; word-break: break-all; color: var(--slate);
}

/* ---- Modal ---------------------------------------------------------------
 * A page shown in place rather than navigated to (see js/modal.js). Native
 * <dialog>, so the browser handles focus trapping, Escape, and the top
 * layer; this only has to dress it.
 */
.modal {
  border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 0; background: var(--paper); color: var(--ink);
  width: min(720px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  box-shadow: 0 18px 50px rgba(45, 48, 66, 0.28);
  overflow: hidden;
}
.modal::backdrop { background: rgba(45, 48, 66, 0.45); }
.modal-body {
  padding: 24px; overflow-y: auto; max-height: calc(100vh - 132px);
}
/* The modal already frames its content, so a page's own outer chrome would
   read as a box inside a box. */
.modal-body .page-narrow { max-width: none; }
.modal-body .page-head { margin-top: 0; }
.modal-body .page-head .btnrow { display: none; }
.modal-body h1 { font-size: 22px; }
.modal-x {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 12px 24px; border-top: 1px solid var(--line); background: var(--white);
}

/* ---- Sheet ordering list -------------------------------------------------
 * Rows are the order: top to bottom is left to right in the building.
 * Dragging is an enhancement (js/sheet-order.js); the arrows in each row
 * are the control it sits on top of.
 */
.sheetlist { list-style: none; margin: 0; padding: 0; }
.sheetrow {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px; border: 1px solid var(--line);
  border-radius: var(--r); background: var(--white); margin-bottom: 8px;
}
/* Wide enough for the longest thing a facility actually calls a sheet
   ("Championship"), rather than the input's default ~20 characters. */
.sheetrow .sheetlabel { width: 16rem; flex: none; }
.sheetrow .grip {
  display: none; color: var(--faint); cursor: grab;
}
/* Only offered where dragging actually works — the class is added by the
   script, so a browser it does not run in never shows a handle it cannot
   use. */
.is-draggable .grip { display: inline-flex; }
.is-draggable .sheetrow:hover { border-color: var(--slate-45); }
.rowstatus {
  font-size: 12px; color: var(--green); font-weight: 600;
  white-space: nowrap; min-width: 4.5rem;
}
.rowstatus.is-error { color: var(--red); white-space: normal; }
.sheetrow.is-dragging {
  opacity: 0.55; border-style: dashed; border-color: var(--gold-dk);
  cursor: grabbing;
}

/* Small forms that sit inline in a list row — the role select, and the
   single-button actions beside it. Without this each <form> takes a line
   of its own and the row falls apart. */
.inline-form {
  display: inline-flex; align-items: center; gap: 6px; margin-left: 8px;
}
.inline-form .input { font-size: 13px; padding: 6px 10px; }
