/* Paddle Rack brand system: navy surfaces, yellow for action, blue for the
   interactive/community layer, green for what is available or won. The colour
   roles are carried by the tokens, so the whole app re-skins from here.
     --action  Paddle Yellow  primary buttons and calls to action (used sparingly)
     --court   Sky Blue       links, focus, active tabs, selected/joined states
     --ball    Fresh Green    next up, winner, available, "you"
     --clay    warm red       leave / danger */
:root {
  --ground: #f7f9f7;
  --surface: #ffffff;
  --sunk: #edf2f4;
  --ink: #102a43;
  --ink-soft: #6b8192;
  --ink-faint: #94a7b3;
  --line: #d9e3e7;
  --line-firm: #c0cfd6;
  --court: #0e7cb8;
  --court-ink: #ffffff;
  --court-wash: #e3f2fb;
  --ball: #8fce2a;
  --ball-ink: #16330a;
  --action: #f7c928;
  --action-ink: #102a43;
  --action-dim: #e3b517;
  --clay: #b3512f;
  --clay-wash: #f4e0d8;
  --shadow: 0 1px 2px rgba(16, 42, 67, .06), 0 8px 22px -14px rgba(16, 42, 67, .26);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground: #081c2c;
    --surface: #102a43;
    --sunk: #0c2338;
    --ink: #f7f9f7;
    --ink-soft: #9bb0ba;
    --ink-faint: #6b8192;
    --line: #285064;
    --line-firm: #37627a;
    --court: #20a9e8;
    --court-ink: #04202e;
    --court-wash: #123a52;
    --ball: #a8e63d;
    --ball-ink: #123008;
    --action: #f7c928;
    --action-ink: #102a43;
    --action-dim: #ffd84d;
    --clay: #f08a6a;
    --clay-wash: #3a211a;
    --shadow: 0 1px 2px rgba(0, 0, 0, .45), 0 10px 26px -16px rgba(0, 0, 0, .85);
  }
}

:root[data-theme="dark"] {
  --ground: #081c2c;
  --surface: #102a43;
  --sunk: #0c2338;
  --ink: #f7f9f7;
  --ink-soft: #9bb0ba;
  --ink-faint: #6b8192;
  --line: #285064;
  --line-firm: #37627a;
  --court: #20a9e8;
  --court-ink: #04202e;
  --court-wash: #123a52;
  --ball: #a8e63d;
  --ball-ink: #123008;
  --action: #f7c928;
  --action-ink: #102a43;
  --action-dim: #ffd84d;
  --clay: #f08a6a;
  --clay-wash: #3a211a;
  --shadow: 0 1px 2px rgba(0, 0, 0, .45), 0 10px 26px -16px rgba(0, 0, 0, .85);
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: "Public Sans", system-ui, -apple-system, sans-serif;
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

button, input, select, textarea { font: inherit; color: inherit; }
/* Any rule that sets `display` outranks the browser's own [hidden] rule, so
   anything laid out as flex or grid stays on screen when hidden. Say it once,
   with the weight to win. */
[hidden] { display: none !important; }

:focus-visible { outline: 2px solid var(--court); outline-offset: 2px; border-radius: 2px; }

.wrap { max-width: 720px; margin: 0 auto; padding: 2.25rem 1.25rem 4rem; }

/* ---- masthead ---- */
.mast { display: flex; align-items: flex-end; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }

.brand { display: flex; flex-direction: column; gap: .15rem; }

.brand h1 {
  margin: 0;
  font-family: "Archivo", system-ui, sans-serif;
  font-variation-settings: "wdth" 118;
  font-weight: 800;
  font-size: clamp(1.9rem, 6vw, 2.6rem);
  letter-spacing: -.015em;
  line-height: .95;
  text-transform: uppercase;
  text-wrap: balance;
}

.brand .sub {
  font-family: "DM Mono", ui-monospace, monospace;
  font-size: .7rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.sidelines { margin: 1rem 0 1.5rem; border-top: 2.5px solid var(--ink); border-bottom: 1px solid var(--line-firm); height: 4px; }

/* ---- identity chip ---- */
.whoami { display: flex; align-items: center; gap: .5rem; }

.whoami-btn {
  display: inline-flex; align-items: center; gap: .5rem;
  background: var(--surface); border: 1.5px solid var(--line-firm);
  border-radius: 999px; padding: .3rem .75rem .3rem .35rem;
  cursor: pointer; box-shadow: var(--shadow);
}
.whoami-btn:hover { border-color: var(--court); }

.avatar {
  width: 1.6rem; height: 1.6rem; border-radius: 50%;
  background: var(--court); color: var(--court-ink);
  display: grid; place-items: center;
  font-family: "Archivo", sans-serif; font-weight: 700; font-size: .72rem;
  letter-spacing: .02em; flex: none;
}

/* Named skins, not hex codes - the stored value is a name, so changing the
   palette later changes everybody's colour instead of freezing today's into
   the database. */
.avatar.skin-court { background: var(--court); color: var(--court-ink); }
.avatar.skin-clay  { background: #b5563f; color: #fff; }
.avatar.skin-ball  { background: #c9a227; color: #241f10; }
.avatar.skin-deep  { background: #1f4e6b; color: #fff; }
.avatar.skin-plum  { background: #6d4472; color: #fff; }
.avatar.skin-slate { background: #4a5259; color: #fff; }
/* An emoji has no business being squeezed into a 700-weight display face. */
.avatar.has-face {
  font-family: inherit; font-weight: 400; font-size: .95rem; line-height: 1;
}

/* ---- picking one ---- */
.face-now {
  display: flex; align-items: center; gap: .7rem; margin: .1rem 0 .6rem;
  flex-wrap: wrap;
}
#f-faceopen { min-height: 44px; }
/* Folded, the grid must not leave a gap where it used to be. */
#f-facebox { margin-top: .2rem; }
.face-now .avatar { width: 2.4rem; height: 2.4rem; font-size: 1rem; }
.face-now .avatar.has-face { font-size: 1.4rem; }
.face-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(2.6rem, 1fr));
  gap: .35rem;
}
.face-opt {
  min-height: 2.6rem; border: 1px solid var(--line); border-radius: 4px;
  background: var(--surface); cursor: pointer; font-size: 1.25rem; line-height: 1;
  display: grid; place-items: center; padding: 0;
}
/* The initials option is text, not an emoji, and should not shout. */
.face-opt:first-child {
  font-family: "Archivo", sans-serif; font-weight: 700; font-size: .8rem;
  color: var(--ink-soft);
}
.face-opt:hover { border-color: var(--court); }
.face-opt.on { border-color: var(--court); box-shadow: inset 0 0 0 1.5px var(--court); }
.face-opt:focus-visible { outline: 2px solid var(--court); outline-offset: 1px; }

.skin-row { display: flex; gap: .45rem; margin-top: .55rem; flex-wrap: wrap; }
.skin-opt {
  width: 1.9rem; height: 1.9rem; border-radius: 50%; cursor: pointer;
  border: 2px solid transparent; padding: 0;
}
.skin-opt.on { border-color: var(--ink); }
.skin-opt:focus-visible { outline: 2px solid var(--court); outline-offset: 2px; }
.skin-opt.skin-court { background: var(--court); }
.skin-opt.skin-clay  { background: #b5563f; }
.skin-opt.skin-ball  { background: #c9a227; }
.skin-opt.skin-deep  { background: #1f4e6b; }
.skin-opt.skin-plum  { background: #6d4472; }
.skin-opt.skin-slate { background: #4a5259; }

/* Two chips at the top right: who you are, and everybody else. They wrap
   under the wordmark on a narrow phone rather than squeezing it. */
.mast-right { display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; justify-content: flex-end; }
.community-btn { gap: .45rem; }
.comm-ico { color: var(--court); font-size: .6rem; letter-spacing: -.12em; }

/* The notifications bell: a round button with a count badge when something is
   waiting. Icon-only to keep the masthead from crowding on a phone. */
.notif-btn { position: relative; padding: .3rem .5rem; }
.notif-ico { font-size: 1rem; line-height: 1; filter: grayscale(1); opacity: .85; }
.notif-badge {
  position: absolute; top: -.3rem; right: -.3rem; min-width: 1.05rem; height: 1.05rem;
  padding: 0 .25rem; border-radius: 999px; background: var(--clay); color: #fff;
  font-family: "DM Mono", monospace; font-size: .62rem; font-weight: 700;
  display: inline-flex; align-items: center; justify-content: center; line-height: 1;
  box-shadow: 0 0 0 2px var(--ground);
}

.whoami-name, .comm-label { font-weight: 600; font-size: .88rem; }
.whoami-rating { font-family: "DM Mono", monospace; font-size: .74rem; color: var(--ink-soft); font-variant-numeric: tabular-nums; }

/* ---- status banner ---- */
.banner {
  display: flex; align-items: flex-start; gap: .6rem;
  padding: .7rem .9rem; border-radius: 4px;
  font-size: .84rem; margin-bottom: 1.25rem;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink-soft);
}
.banner.warn { border-color: var(--clay); background: var(--clay-wash); color: var(--ink); }
.banner b { color: var(--ink); font-weight: 600; }
.banner .dot { width: .5rem; height: .5rem; border-radius: 50%; background: var(--ball); margin-top: .45rem; flex: none; }
.banner.warn .dot { background: var(--clay); }

/* "Is this you?" under the name box on sign-up. Folded away until a name is
   typed - a wall of every name on the board invites the wrong tap. */
.claim { margin: -.4rem 0 1rem; }
.claim .pick-list { max-height: 13rem; }
.claim .pick-row .pos { max-width: 55%; text-align: right; }

/* The menu on your own name. Everything about you or your club, in one place
   you reach the same way every time, instead of two tabs and a footer link. */
.whoami { position: relative; }
.whoami-btn .caret { margin-left: .1rem; font-size: .6rem; color: var(--ink-faint); }

/* Anchored to whichever edge the chip is actually against: it wraps under the
   masthead and sits LEFT on a phone, where right-anchoring ran the whole menu
   off the side of the screen and left only the grey labels showing. */
.whomenu {
  position: absolute; left: 0; right: auto; top: calc(100% + .35rem); z-index: 40;
  min-width: 15rem; max-width: min(20rem, calc(100vw - 2rem));
  background: var(--surface); border: 1px solid var(--line); border-radius: 6px;
  box-shadow: var(--shadow); overflow: hidden;
}
.whomenu-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: .8rem;
  width: 100%; text-align: left; background: none; border: none; cursor: pointer;
  padding: .7rem .85rem; font: inherit; font-size: .92rem; color: var(--ink);
  border-bottom: 1px solid var(--line);
}
.whomenu-row:last-child { border-bottom: none; }
.whomenu-row:hover { background: var(--sunk); }
@media (min-width: 561px) {
  .whomenu { left: auto; right: 0; }
}

.whomenu-row .pos {
  font-family: "DM Mono", monospace; font-size: .68rem; color: var(--ink-faint);
  flex: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  max-width: 9rem;
}

/* A screen reached from the menu rather than a tab. */
.pane-top {
  display: flex; align-items: baseline; gap: .8rem; flex-wrap: wrap;
  margin: 0 0 1.2rem; padding-bottom: .7rem; border-bottom: 1px solid var(--line);
}
.pane-top h2 { margin: 0; font-size: 1.15rem; }

/* ---- tabs ---- */
/* Which board you are looking at. It sits above the tabs because it changes
   what every one of them contains, and it is deliberately quiet - this is a
   thing you set once and forget, not a thing you press. */
/* An invite sits above everything else on the board, because somebody who
   followed a link needs to see what happened before anything else. */
.panel.invite {
  border-left: 3px solid var(--ball);
  margin-bottom: 1.1rem;
}
.invite-box { margin: .9rem 0 0; }

/* Background-photo picker (game and group forms). */
.bg-file { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.bg-row { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; }
.bg-pick { flex: none; cursor: pointer; }
.bg-preview { display: inline-flex; align-items: center; gap: .6rem; min-height: 2.5rem; }
.bg-thumb {
  width: 3.4rem; height: 2.5rem; border-radius: 5px; flex: none;
  background-size: cover; background-position: center;
  border: 1px solid var(--line-firm);
}
.bg-none { font-size: .82rem; color: var(--ink-faint); }
.bg-err { font-size: .82rem; color: var(--clay); }

/* Invite by email: the send row, and the list of who is still outstanding. */
.email-invite-row {
  display: flex;
  gap: .5rem;
  align-items: center;
  margin: .5rem 0 .2rem;
}
.email-invite-row .inp { flex: 1 1 auto; min-width: 0; }
.email-invite-row .btn { flex: 0 0 auto; white-space: nowrap; }
.ok-note { margin: .35rem 0 0; font-size: .85rem; color: var(--sea, #10665f); }
.pinv-none { margin: .55rem 0 0; font-size: .85rem; color: var(--muted, #6b807c); }
.pinv-list { list-style: none; margin: .55rem 0 0; padding: 0; }
.pinv-row {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .35rem 0;
  border-top: 1px solid var(--hair, #eef1f0);
  font-size: .9rem;
}
.pinv-email { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.pinv-acts { flex: 0 0 auto; display: flex; gap: .75rem; }
.linkish.danger { color: var(--clay, #b5533b); }

/* Templates to start a game from. They sit above the form because picking one
   changes what the form says, so it has to come first. */
.tpl { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin: 0 0 1rem; }
.tpl-lbl {
  font-family: "DM Mono", monospace; font-size: .68rem;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint);
  flex: none; margin-right: .1rem;
}
.chip.tpl-chip { padding: .1rem .35rem .1rem .1rem; gap: .1rem; }
.chip.tpl-chip.on { border-color: var(--court); background: var(--court); color: var(--court-ink); }
.chip.tpl-chip.on .del { color: var(--court-ink); }

.tpl-save {
  display: flex; align-items: flex-start; gap: .55rem;
  margin: 1rem 0 0; font-size: .84rem; color: var(--ink-soft); cursor: pointer;
}
.tpl-save input { flex: none; width: 1.05rem; height: 1.05rem; margin-top: .05rem; }

/* A heading over a run of ticks. Quieter than a section title - it is dividing
   a form, not the page - and it carries the rule above it rather than beside
   it, so the ticks underneath read as answers to one question. */
.set-head {
  margin: 1.1rem 0 .1rem; padding-top: .7rem;
  border-top: 1px solid var(--line);
  font-family: "DM Mono", monospace; font-size: .64rem; font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint);
}
.set-head + .tpl-save { margin-top: .55rem; }
/* A little extra air above the major sections in a group's settings. */
.set-head-sep { margin-top: 1.7rem; }

/* A tick that stands alone across the form's grid, and the fields it reveals.
   `display: contents` keeps those fields in the grid rather than boxing them
   inside one cell - [hidden]'s own !important still folds them away. */
.wide-check { grid-column: 1 / -1; }

/* ---- help ---- */
.help-list { display: flex; flex-direction: column; gap: .5rem; margin-top: 1rem; }
.help-item { border: 1px solid var(--line); border-radius: 4px; background: var(--surface); }
.help-q {
  display: flex; align-items: center; justify-content: space-between; gap: .8rem;
  width: 100%; min-height: 48px; padding: .8rem 1rem; text-align: left;
  background: none; border: 0; cursor: pointer;
  font-family: "Archivo", sans-serif; font-variation-settings: "wdth" 108;
  font-weight: 600; font-size: .96rem; color: var(--ink);
}
.help-q:hover { color: var(--court); }
.help-q:focus-visible { outline: 2px solid var(--court); outline-offset: -2px; }
.help-q .caret { color: var(--ink-faint); flex: none; }
.help-a { padding: 0 1rem 1rem; }
.help-a p { margin: 0 0 .6rem; font-size: .92rem; line-height: 1.55; color: var(--ink-soft); }
.help-a p:last-child { margin-bottom: 0; }
.help-a b { color: var(--ink); font-weight: 600; }
.subfields {
  display: grid; grid-template-columns: 1fr 1fr; gap: .7rem;
  grid-column: 1 / -1; margin: .2rem 0 .2rem;
}
.subfields[hidden] { display: none; }

/* The finder's own list. It sits under the club's on the Players tab and has to
   read as a different thing: these are people you have not met. */
.finder-list { margin-top: .2rem; }
.finder-list .prow { align-items: center; gap: .7rem; }
.finder-list .prow .foot-actions { flex: none; gap: .5rem; align-items: center; }
.prow.going {
  display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
  padding: .7rem 0; border-bottom: 1px solid var(--line);
}

/* The cost of the night. A second rack under the first: same shape, because it
   answers the same kind of question about the same list of people. */
.rack.cost { margin-top: .5rem; }
.rack.cost .pick-list.open { max-height: none; margin-top: .5rem; }
.rack.cost .pick-row[aria-pressed="true"] .nm { color: var(--ink-faint); }
.cost-you {
  margin: .7rem 0 0; font-size: .86rem; color: var(--ink);
  padding: .55rem .7rem; border-radius: 4px; background: var(--court-wash);
}
.cost-you b { font-weight: 600; }

.grp-edit { margin: 0 0 .3rem; }
.grp-edit .grid { margin-top: .6rem; }
.grp-court { font-size: .82rem; color: var(--ink-soft); margin-top: .1rem; }

/* Who runs a club. Sits above the Hello Club row, because who may connect one
   is decided here. */
.grp-links { display: flex; align-items: center; gap: 1.1rem; flex-wrap: wrap; margin: .7rem 0 0; }
.grp-links .linkish .pos {
  font-family: "DM Mono", monospace; font-size: .72rem; color: var(--ink-faint);
}
.grp-links .grp-crew { margin: 0; padding: 0; border-top: none; flex: 1 1 100%; }

.grp-crew { margin: .7rem 0 0; padding-top: .7rem; border-top: 1px solid var(--line); }
.grp-crew .prow { align-items: center; gap: .7rem; }
.grp-crew h3 { font-size: .95rem; }

/* A club's Hello Club connection, on its card. Quiet until it has something to
   say, because most clubs will never connect one. */
.grp-hc {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  margin: .7rem 0 0; padding-top: .7rem; border-top: 1px solid var(--line);
}
.grp-hc .lbl {
  font-family: "DM Mono", monospace; font-size: .66rem;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint);
}
.grp-hc .hc-state { font-size: .84rem; color: var(--ink-soft); flex: 1; }
.grp-hc .hc-members-msg { flex-basis: 100%; font-size: .8rem; color: var(--ink-soft); }
.grp-hc.open { display: block; }
.dupr-file, .member-csv-file { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.dupr-pick { cursor: pointer; }
/* The owner-only ids under a player row in the admin list. */
.padmin-row .pl-ids {
  flex-basis: 100%; font-family: "DM Mono", ui-monospace, monospace;
  font-size: .72rem; letter-spacing: .02em; color: var(--ink-faint);
}

.clubbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .8rem;
  margin: 0 0 .55rem;
}
/* Each question keeps its label welded to its answer, and the pair wraps as a
   unit - on a narrow phone "In" must never end up on the line above its own
   dropdown. */
.bar-bit {
  display: flex; align-items: center; gap: .55rem;
  flex: 1 1 12rem; min-width: 0;
}
.clubbar label {
  font-family: "DM Mono", monospace; font-size: .68rem;
  letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint);
  flex: none;
}
.clubbar select {
  flex: 1 1 auto; min-width: 0; max-width: 20rem;
  padding: .3rem .5rem; border-radius: 4px;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  font: inherit; font-size: .86rem; font-weight: 500;
}
.clubbar select:focus-visible { outline: 2px solid var(--court); outline-offset: 1px; }

/* Three tabs, an equal share of the width each. Left-bunched they left most of
   the bar empty and the selected underline was a stub under one word; a third
   each makes it a segment, and the whole strip reads as one control. Wrapping
   is gone with it - five tabs needed it, three never will. */
.tabs { display: flex; margin-bottom: 1.5rem; border-bottom: 1px solid var(--line); }

.tab {
  flex: 1 1 0; min-width: 0; text-align: center;
  background: none; border: none; cursor: pointer;
  padding: .5rem .35rem;
  font-family: "Archivo", sans-serif; font-variation-settings: "wdth" 112;
  font-weight: 600; font-size: .84rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-faint); border-bottom: 2.5px solid transparent; margin-bottom: -1px;
}

/* Four tabs on a phone. "Trainings" is the long one and at .84rem with wide
   tracking it ran into the tab beside it - fitting inside 84px is not the same
   as looking like it fits. Narrower letterforms and tighter tracking rather
   than a smaller size, so it stays readable. */
@media (max-width: 430px) {
  /* Three tabs again, so they have room - the tightening below was for four. */
  .tab {
    font-size: .78rem; letter-spacing: .02em;
    font-variation-settings: "wdth" 92;
    padding-left: .15rem; padding-right: .15rem;
  }
  .tab .count { margin-left: .22rem; font-size: .68rem; }

  /* The top controls (Community, notifications, your name) do not fit beside
     the wordmark on a phone, so they drop to their own row. Left-aligned, not
     right: right-aligned they hugged the edge in a ragged two-row stack with a
     dead gap down the left. Left-aligned they read as one tidy toolbar under
     the title, and a long name is capped rather than pushing the row wider. */
  .mast { gap: .55rem; }
  .mast-right {
    width: 100%;
    justify-content: flex-start;
    gap: .4rem;
  }
  .whoami-btn { padding: .28rem .6rem .28rem .3rem; min-width: 0; }
  .whoami-name {
    max-width: 8rem; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
}
.tab:hover { color: var(--ink); }
.tab[aria-selected="true"] { color: var(--ink); border-bottom-color: var(--court); }
.tab .count { font-family: "DM Mono", monospace; font-size: .72rem; color: var(--ink-faint); margin-left: .3rem; }

/* ---- buttons ---- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  background: var(--action); color: var(--action-ink);
  border: 1.5px solid var(--action); border-radius: 6px;
  padding: .55rem 1rem; font-weight: 700; font-size: .88rem;
  cursor: pointer; transition: transform .06s ease, background .12s ease, border-color .12s ease;
}
.btn:hover { background: var(--action-dim); border-color: var(--action-dim); color: var(--action-ink); }
.btn:active { transform: scale(.98); }
.btn[disabled] { opacity: .45; cursor: not-allowed; transform: none; }

.btn-quiet { background: transparent; color: var(--ink); border-color: var(--line-firm); }
.btn-quiet:hover { background: var(--sunk); color: var(--ink); border-color: var(--ink-soft); }

.btn-leave { background: transparent; color: var(--clay); border-color: var(--clay); }
.btn-leave:hover { background: var(--clay); color: var(--surface); border-color: var(--clay); }

.btn-sm { padding: .35rem .7rem; font-size: .8rem; }

.linkish {
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--ink-faint); font-size: .78rem; text-decoration: underline;
  text-underline-offset: 3px;
}
.linkish:hover { color: var(--clay); }

/* ---- section head ---- */
.sec-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; margin: 2rem 0 .85rem;
}
.sec-head:first-child { margin-top: 0; }
.sec-title {
  font-family: "Archivo", sans-serif; font-variation-settings: "wdth" 108;
  font-weight: 700; font-size: .78rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-soft); margin: 0;
}

/* A section heading that is also its own fold. Inherits the heading's type so
   it reads as the heading it is, not as a control bolted onto one. */
.sec-fold {
  font: inherit; letter-spacing: inherit; text-transform: inherit; color: inherit;
  background: none; border: 0; padding: 0; margin: 0; cursor: pointer;
  display: inline-flex; align-items: center; gap: .4rem;
  min-height: 44px;            /* a thumb-sized target, not a 12px word */
}
.sec-fold:hover { color: var(--ink); }
.sec-fold:focus-visible { outline: 2px solid var(--court); outline-offset: 3px; }
.fold-caret { font-size: .7em; color: var(--ink-faint); }
.sec-fold .count {
  font-family: "DM Mono", monospace; font-size: .72rem; letter-spacing: 0;
  color: var(--ink-faint);
}

/* ---- tournament ---- */
.pool { border: 1px solid var(--line); border-radius: 4px; padding: .7rem .8rem; margin-bottom: .6rem; background: var(--surface); }
.pool-head {
  font-family: "DM Mono", monospace; font-size: .64rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-faint); margin-bottom: .4rem;
}
.pool-table { width: 100%; border-collapse: collapse; font-size: .88rem; }
.pool-table th {
  font-family: "DM Mono", monospace; font-size: .62rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-faint); font-weight: 500;
  text-align: right; padding: 0 0 .25rem;
}
.pool-table th:first-child { text-align: left; }
.pool-table td { padding: .28rem 0; text-align: right; font-variant-numeric: tabular-nums; }
.pool-table td:first-child { text-align: left; }
/* Going through, while the pool is still being played - the only reason
   anybody reads a table mid-tournament. */
.pool-table tr.qual td { font-weight: 600; color: var(--court); }

.ko-tie {
  display: flex; align-items: center; justify-content: space-between; gap: .6rem;
  padding: .35rem 0; font-size: .9rem;
}
.ko-tie .won { font-weight: 700; color: var(--court); }

/* ---- game card ---- */
.games { display: flex; flex-direction: column; gap: 1rem; }

.game {
  background: var(--surface); border: 1px solid var(--line);
  border-top: 3px solid var(--court); border-radius: 4px;
  padding: 1.1rem 1.15rem 1rem; box-shadow: var(--shadow);
}
.game.next { border-top-color: var(--ball); }
.game.live { border-top-color: var(--clay); border-top-width: 4px; }
.game.past { opacity: .62; border-top-color: var(--line-firm); }

/* A game with a photo shows it as a banner across the top of the tile, with
   all the information on the ordinary surface below - the card is too busy to
   sit over a full-bleed image. */
.game-photo {
  height: 128px;
  margin: -1.1rem -1.15rem .9rem;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  border-radius: 3px 3px 0 0;
}
.game.past .game-photo { filter: grayscale(.3); }
@media (max-width: 430px) { .game-photo { height: 108px; } }

/* A group card with a background photo. Same treatment as a game card. */
.grp.has-bg {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  border-color: rgba(255, 255, 255, .16);
}
.grp.has-bg h3,
.grp.has-bg .grp-court,
.grp.has-bg .grp-meta,
.grp.has-bg .grp-code .lbl,
.grp.has-bg .grp-code .code,
.grp.has-bg .foot-note { color: #f7f9f7; }
.grp.has-bg .grp-meta,
.grp.has-bg .grp-court { opacity: .92; }
/* An open panel over a photo gets a solid backing so its fields stay legible. */
.grp.has-bg .invite-box {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: .85rem;
}

.eyebrow {
  font-family: "DM Mono", monospace; font-size: .66rem;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--ball-ink); background: var(--ball);
  display: inline-block; padding: .12rem .45rem; border-radius: 2px;
  margin-bottom: .6rem;
}

/* A game being played right now. Terracotta rather than the ball yellow so the
   two flags cannot be mistaken for each other at a glance, and a dot that
   breathes - the one thing on the board that is moving is the one thing that
   is happening. */
.eyebrow.on {
  color: #fff; background: var(--clay);
  display: inline-flex; align-items: center; gap: .35rem;
}
.eyebrow .pip {
  width: .38rem; height: .38rem; border-radius: 50%;
  background: currentColor; animation: pip 1.8s ease-in-out infinite;
}
@keyframes pip { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }
@media (prefers-reduced-motion: reduce) {
  .eyebrow .pip { animation: none; }
}

/* The venue is the thing you read first, so it gets the width and the flags sit
   under it, wrapping onto as many rows as they need. They used to share the
   line, and since a flex item will not shrink below its own content width, five
   flags squeezed a long venue name into a column of single words. The only
   thing beside the title is the share icon, which is fixed-width and does not
   compete with it. */
.game-top { display: flex; align-items: flex-start; gap: .6rem; }
.game-titles { flex: 1 1 auto; min-width: 0; }

/* A quiet square target in the corner. 40px so it is thumb-sized on a phone
   without drawing the eye away from the buttons that actually change things. */
.icon-btn {
  flex: none; width: 2.5rem; height: 2.5rem; margin: -.35rem -.35rem 0 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: 1px solid transparent; border-radius: .5rem;
  color: var(--ink-faint); cursor: pointer;
  transition: color .12s ease, border-color .12s ease, background .12s ease;
}
.icon-btn:hover { color: var(--court); border-color: var(--line); background: var(--sunk); }
.icon-btn:focus-visible { outline: 2px solid var(--court); outline-offset: 2px; }

/* Back on the left, the line-up on the right, above the venue name. */
.runbar-top { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }
.runbar-links { display: flex; gap: .9rem; flex-wrap: wrap; justify-content: flex-end; }
.icon-btn.done { color: var(--court); border-color: var(--court); background: var(--court-wash); }

.venue {
  margin: 0; font-family: "Archivo", sans-serif; font-variation-settings: "wdth" 112;
  font-weight: 700; font-size: 1.18rem; letter-spacing: -.005em; line-height: 1.15;
  text-wrap: balance;
}

/* Where a game with a title is played. Sits between the name and the clock,
   quieter than the name and louder than the numbers. */
.at { font-size: .85rem; color: var(--ink); font-weight: 500; margin-top: .2rem; }

.when {
  font-family: "DM Mono", monospace; font-size: .8rem; color: var(--ink-soft);
  font-variant-numeric: tabular-nums; margin-top: .25rem;
}

.badges { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .5rem; }

.badge {
  font-family: "DM Mono", monospace; font-size: .68rem; letter-spacing: .06em;
  padding: .18rem .45rem; border-radius: 2px; border: 1px solid var(--line-firm);
  color: var(--ink-soft); white-space: nowrap; font-variant-numeric: tabular-nums;
}
.badge.level { border-color: var(--court); color: var(--court); }
.badge.full { border-color: var(--clay); color: var(--clay); background: var(--clay-wash); }
.badge.in { border-color: var(--court); background: var(--court); color: var(--court-ink); }
/* Who can see this game. The open one is quiet; the restricted one is not, so
   nobody posts to a group by accident and wonders where everyone went. */
.badge.open { border-color: var(--line-firm); color: var(--ink-faint); }
.badge.shut { border-color: var(--clay); color: var(--clay); background: var(--clay-wash); }

.note { margin: .7rem 0 0; font-size: .87rem; color: var(--ink-soft); }

/* ---- the rack ---- */
.rack { margin-top: .95rem; }

.rack-top {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: .75rem; margin-bottom: .45rem;
}
.rack-label {
  font-family: "DM Mono", monospace; font-size: .66rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-faint); display: block;
}
.unfold { white-space: nowrap; text-decoration: none; }
.unfold:hover { text-decoration: underline; text-underline-offset: 3px; }
.unfold .caret { font-size: .6rem; margin-left: .25rem; }

.slots { display: flex; flex-wrap: wrap; gap: .4rem; }

.chip {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .28rem .6rem; border-radius: 999px;
  border: 1.5px solid var(--court); background: var(--court-wash);
  font-size: .82rem; font-weight: 500; max-width: 100%;
}
.chip .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chip .rt {
  font-family: "DM Mono", monospace; font-size: .7rem; color: var(--ink-soft);
  font-variant-numeric: tabular-nums; flex: none;
}
.chip.me { background: var(--court); border-color: var(--court); color: var(--court-ink); }
.chip.me .rt { color: var(--court-ink); opacity: .8; }
.chip .org { font-size: .62rem; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-faint); flex: none; }
.chip.me .org { color: var(--court-ink); opacity: .8; }

/* A pair whose two halves are each their own tap target, so a partner can be
   changed without breaking the pair up first. The names carry the padding
   rather than the chip, which keeps them thumb-sized on a phone. */
.chip.pair { padding: .1rem .35rem .1rem .1rem; gap: .1rem; }
.chip .pnm {
  font: inherit; color: inherit; background: none; border: none; cursor: pointer;
  padding: .3rem .45rem; border-radius: 999px; max-width: 9rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chip .pnm:hover { background: rgba(16, 102, 95, .12); }
.chip .pnm[aria-pressed="true"] {
  background: var(--court); color: var(--court-ink);
}
.chip .amp { color: var(--ink-faint); font-size: .74rem; flex: none; }

.chip-empty {
  border: 1.5px dashed var(--line-firm); background: transparent; color: var(--ink-faint);
  font-family: "DM Mono", monospace; font-size: .74rem;
}

.chip-queued { border-color: var(--line-firm); background: transparent; }
.chip-queued .pos {
  font-family: "DM Mono", monospace; font-size: .68rem; color: var(--ink-faint);
  font-variant-numeric: tabular-nums; flex: none;
}
.chip-queued.me { background: var(--sunk); border-color: var(--ink-soft); color: var(--ink); }
.chip-queued.me .rt, .chip-queued.me .pos { color: var(--ink-soft); }

.kitchen {
  display: flex; align-items: center; gap: .6rem; margin: .9rem 0 .55rem;
}
.kitchen .rule { flex: 1; border-top: 1.5px dashed var(--line-firm); }
.kitchen .tag {
  font-family: "DM Mono", monospace; font-size: .64rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-faint); white-space: nowrap;
}

.game-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: .75rem; margin-top: 1rem; padding-top: .85rem; border-top: 1px solid var(--line);
  flex-wrap: wrap;
}
.foot-note { font-size: .78rem; color: var(--ink-faint); }
.foot-note.warn { color: var(--clay); }
.foot-actions { display: flex; align-items: center; gap: .6rem; margin-left: auto; }

/* ---- forms ---- */
.panel {
  background: var(--surface); border: 1px solid var(--line); border-radius: 4px;
  padding: 1.1rem 1.15rem; box-shadow: var(--shadow); margin-bottom: 1.25rem;
}
.panel h2 {
  margin: 0 0 .2rem; font-family: "Archivo", sans-serif; font-variation-settings: "wdth" 112;
  font-weight: 700; font-size: 1.1rem; text-wrap: balance;
}
.panel p.lede { margin: 0 0 1rem; font-size: .87rem; color: var(--ink-soft); }
.form-head { display: flex; align-items: flex-start; justify-content: space-between; gap: .6rem; margin-bottom: .2rem; }
.form-head h2 { margin-bottom: 0; }
.form-head .btn { flex: none; }

.grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .8rem; }
.field { display: flex; flex-direction: column; gap: .3rem; min-width: 0; }
.field.wide { grid-column: 1 / -1; }

.field label {
  font-family: "DM Mono", monospace; font-size: .66rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-faint);
}

.field input, .field select, .field textarea {
  background: var(--ground); border: 1.5px solid var(--line-firm); border-radius: 3px;
  padding: .5rem .6rem; font-size: .9rem; width: 100%; min-width: 0;
}
.field textarea { resize: vertical; min-height: 3.2rem; font-family: inherit; }
.field input:focus, .field select:focus, .field textarea:focus { border-color: var(--court); }

/* ---- form controls under a thumb ----
   iOS zooms the whole page in when you focus an input whose text is smaller
   than 16px, and it does not zoom back out afterwards - which is what makes the
   date and time fields feel broken rather than merely small. It also lays its
   own date and time controls out to fit their contents and centres the value
   inside them, so those two came out a different height and alignment from
   every other field on the form. None of this applies to a mouse, so none of it
   is done to one. */
@media (pointer: coarse), (max-width: 560px) {
  /* Anything below 16px zooms the page on focus in iOS Safari, and there is no
     way back out of that zoom. The club switcher is a select like any other. */
  .field input, .field select, .field textarea, .pick-search,
  .clubbar select { font-size: 16px; }
  .field input, .field select { min-height: 2.75rem; }
  .field input[type="date"], .field input[type="time"] {
    -webkit-appearance: none; appearance: none; display: block;
  }
  .field input[type="date"]::-webkit-date-and-time-value,
  .field input[type="time"]::-webkit-date-and-time-value {
    text-align: left; margin: 0;
  }
}

.form-foot { display: flex; align-items: center; gap: .7rem; margin-top: 1rem; flex-wrap: wrap; }
.form-foot .spacer { flex: 1; }
/* The other ways in, under the one you are on. */
.signin-ways { gap: .5rem 1.1rem; margin-top: .8rem; }

/* Social sign-in: an "or" rule, then a button per provider. */
.or-line {
  display: flex; align-items: center; gap: .7rem; margin: 1rem 0 .8rem;
  font-family: "DM Mono", monospace; font-size: .68rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-faint);
}
.or-line::before, .or-line::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.social-ways { display: flex; flex-direction: column; gap: .5rem; }
.btn-social { width: 100%; justify-content: center; }

/* The "check your email" notice a brand-new account lands on. */
.verify-notice { text-align: center; }
.verify-icon { font-size: 2.6rem; line-height: 1; margin-bottom: .4rem; }
.verify-notice .form-foot { justify-content: center; }

/* First-run intro. A single centred card, one step at a time. */
.intro { min-height: 60vh; display: flex; align-items: center; justify-content: center; padding: 1rem 0; }
.intro-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: 6px;
  box-shadow: var(--shadow); padding: 1.6rem 1.4rem; max-width: 30rem; width: 100%; text-align: center;
}
.intro-step {
  font-family: "DM Mono", monospace; font-size: .64rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-faint); margin-bottom: .6rem;
}
.intro-icon { font-size: 2.6rem; line-height: 1; margin-bottom: .5rem; }
.intro-card h2 {
  margin: 0 0 .6rem; font-family: "Archivo", sans-serif; font-variation-settings: "wdth" 112;
  font-weight: 700; font-size: 1.25rem;
}
.intro-card p { margin: 0 0 .7rem; font-size: .92rem; color: var(--ink-soft); line-height: 1.5; }
.intro-card p b { color: var(--ink); font-weight: 600; }
.intro-dots { display: flex; justify-content: center; gap: .35rem; margin: 1rem 0 1.2rem; }
.intro-foot { display: flex; align-items: center; justify-content: space-between; gap: .7rem; }
.intro-foot .btn { min-width: 6.5rem; justify-content: center; }

.privacy { font-size: .76rem; color: var(--ink-faint); margin: .8rem 0 0; }

/* ---- players ---- */
.roster { display: flex; flex-direction: column; }

.prow {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center;
  gap: .85rem; padding: .9rem 0; border-bottom: 1px solid var(--line);
}
.prow:first-child { border-top: 1px solid var(--line); }

.prow .avatar { width: 2.1rem; height: 2.1rem; font-size: .84rem; }
.prow.me .avatar { background: var(--ball); color: var(--ball-ink); }

.pname { font-weight: 600; font-size: .96rem; display: flex; align-items: center; gap: .45rem; flex-wrap: wrap; }
.pmeta { font-size: .78rem; color: var(--ink-faint); margin-top: .12rem; }

.pstat { text-align: right; flex: none; }
.pstat .n {
  font-family: "Archivo", sans-serif; font-variation-settings: "wdth" 108;
  font-weight: 700; font-size: 1.15rem; font-variant-numeric: tabular-nums; line-height: 1;
}
.pstat .l {
  font-family: "DM Mono", monospace; font-size: .62rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-faint);
}

.you-tag {
  font-family: "DM Mono", monospace; font-size: .62rem; letter-spacing: .08em;
  text-transform: uppercase; background: var(--ball); color: var(--ball-ink);
  padding: .1rem .35rem; border-radius: 2px;
}

/* ---- empty ---- */
.empty {
  border: 1.5px dashed var(--line-firm); border-radius: 4px;
  padding: 2.2rem 1.25rem; text-align: center; color: var(--ink-soft);
}
.empty strong {
  display: block; font-family: "Archivo", sans-serif; font-variation-settings: "wdth" 110;
  font-weight: 700; font-size: 1.05rem; color: var(--ink); margin-bottom: .3rem;
}
.empty p { margin: 0; font-size: .87rem; }

/* ---- saving ---- */
.saving {
  position: fixed; left: 50%; bottom: 1.25rem; transform: translateX(-50%);
  background: var(--ink); color: var(--ground);
  padding: .5rem 1rem; border-radius: 999px; font-size: .82rem; font-weight: 500;
  box-shadow: var(--shadow); z-index: 50; display: flex; align-items: center; gap: .5rem;
}
.saving .pip {
  width: .5rem; height: .5rem; border-radius: 50%; background: var(--ball);
  animation: pulse 1s ease-in-out infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }

footer.page-foot {
  margin-top: 3rem; padding-top: 1rem; border-top: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  font-family: "DM Mono", monospace; font-size: .7rem; letter-spacing: .04em; color: var(--ink-faint);
}

@media (prefers-reduced-motion: reduce) {
  .btn, .chip { transition: none; }
  .saving .pip { animation: none; }
}

/* ---- running a session ---- */
.runbar { margin-bottom: 1.4rem; }
.runbar h2 {
  margin: .35rem 0 0; font-family: "Archivo", sans-serif;
  font-variation-settings: "wdth" 114; font-weight: 700; font-size: 1.35rem;
  letter-spacing: -.01em; text-wrap: balance;
}

.mode-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .6rem; }

.mode-card {
  position: relative; border: 1.5px solid var(--line-firm); border-radius: 4px;
  padding: .7rem .8rem; cursor: pointer; background: var(--ground); text-align: left;
  display: block; width: 100%;
}
.mode-card:hover { border-color: var(--court); }

/* Folded down to the one that is chosen, it is the only card on screen and
   should read as a statement rather than as one option among five. */
.mode-grid.one { grid-template-columns: 1fr; }
.mode-card.on {
  border-color: var(--court); border-width: 2px; background: var(--court-wash);
  box-shadow: inset 3px 0 0 var(--court);
}
.mode-card.on .mt { color: var(--court); }
.mode-tick { float: right; font-weight: 700; color: var(--court); margin-left: .5rem; }

.mode-card .mt { font-weight: 600; font-size: .89rem; display: block; }
.mode-card .md { font-size: .77rem; color: var(--ink-soft); display: block; margin-top: .2rem; line-height: 1.35; }

/* The head-count, live, next to the heading - it is the number the organiser
   keeps recounting off the chips, so it should just be on screen. */
.here-count {
  font-family: "DM Mono", monospace; font-size: .78rem; letter-spacing: .04em;
  padding: .2rem .55rem; border-radius: 999px; flex: none;
  background: var(--court); color: var(--court-ink); font-variant-numeric: tabular-nums;
}
.here-count.thin { background: var(--clay-wash); color: var(--clay); }

.att { display: flex; flex-wrap: wrap; gap: .4rem; }
.att-chip {
  border: 1.5px dashed var(--line-firm); background: transparent; color: var(--ink-faint);
  border-radius: 999px; padding: .28rem .65rem; font-size: .82rem; cursor: pointer;
}
.att-chip[aria-pressed="true"] {
  border-style: solid; border-color: var(--court);
  background: var(--court-wash); color: var(--ink);
}
.att-chip .pos {
  font-family: "DM Mono", monospace; font-size: .68rem; color: var(--ink-faint);
  margin-left: .3rem; font-variant-numeric: tabular-nums;
}
.att-chip[aria-pressed="true"] .pos { color: var(--ink-soft); }

.bump {
  background: none; border: none; cursor: pointer; color: var(--court);
  font-size: .82rem; line-height: 1; padding: 0 0 0 .35rem; font-weight: 700;
}
.bump:hover { color: var(--ink); }

/* Take someone back off a staged line-up. */
.del {
  background: none; border: none; cursor: pointer; color: var(--ink-faint);
  font-size: 1rem; line-height: 1; padding: 0 0 0 .3rem; font-weight: 700; flex: none;
}
.del:hover { color: var(--clay); }
.picker-note { font-size: .8rem; color: var(--ink-faint); margin: .25rem 0 0; }

/* The share message, when the browser will hand us neither a share sheet nor
   the clipboard and the only way out is for someone to select it themselves. */
.share-box {
  width: 100%; padding: .6rem .7rem; border: 1px solid var(--line-firm);
  border-radius: .5rem; background: var(--card); resize: vertical;
  font-family: "DM Mono", monospace; font-size: .8rem; line-height: 1.5;
}

/* The King's Court. One court on the page is the one worth getting to, so it
   is the one court that is marked. */
.court-card.crown { border-color: var(--court); }
.court-card.crown .court-head { background: var(--ball); color: var(--ball-ink); }

/* ---- searchable multi-select ----
   A filter box over a scrolling list of names. The list is capped in height so
   a club of forty does not push the rest of the panel off the screen, and the
   whole row is the hit target - a tick box alone is a poor thing to aim at on
   a phone at the side of a court. */
.picker { display: flex; flex-direction: column; gap: .45rem; }
.pick-search {
  width: 100%; padding: .55rem .7rem; border: 1px solid var(--line-firm);
  border-radius: .5rem; background: var(--card); -webkit-appearance: none; appearance: none;
}
.pick-search:focus { border-color: var(--court); outline: none; }
.pick-list {
  max-height: 13.5rem; overflow-y: auto; border: 1px solid var(--line);
  border-radius: .5rem; background: var(--card);
  display: flex; flex-direction: column;
}
.pick-row {
  display: flex; align-items: center; gap: .55rem; width: 100%;
  padding: .5rem .65rem; background: none; border: none; border-bottom: 1px solid var(--line);
  text-align: left; cursor: pointer; color: inherit;
}
.pick-row:last-child { border-bottom: none; }
.pick-row:hover { background: var(--sunk); }
.pick-row .nm { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Where a venue is, beside its name. It gives way first: on a narrow phone the
   name is the part you are reading. */
.pick-row .pos { max-width: 45%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick-row .pos {
  font-family: "DM Mono", monospace; font-size: .72rem; color: var(--ink-faint);
  font-variant-numeric: tabular-nums; flex: none;
}
.pick-row .tick {
  flex: none; width: 1.05rem; height: 1.05rem; border-radius: .28rem;
  border: 1.5px solid var(--line-firm); position: relative;
}
/* Hello Club event rows stack their info rather than squeezing it onto one
   line: with the form hidden while the list is up, each event has the room to
   show its full name with the venue and time underneath. */
.pick-list.hc-list { max-height: none; }
.pick-row.hc-row { align-items: center; gap: .6rem; padding: .7rem .75rem; }
.pick-row.hc-row .hc-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .2rem; }
.pick-row.hc-row .nm {
  flex: none; white-space: normal; overflow: visible; text-overflow: clip;
  font-weight: 600; line-height: 1.25;
}
.pick-row.hc-row .pos {
  max-width: none; white-space: normal; overflow: visible; text-overflow: clip;
  font-size: .76rem;
}
.pick-row.hc-row .hc-row-count {
  flex: none; display: flex; flex-direction: column; align-items: center;
  line-height: 1.05; color: var(--ink-soft); min-width: 2.6rem; text-align: center;
}
.pick-row.hc-row .hc-row-count b {
  font-family: "DM Mono", monospace; font-size: 1.1rem; font-weight: 600;
  color: var(--court); font-variant-numeric: tabular-nums;
}
.pick-row.hc-row .hc-row-count span {
  font-size: .62rem; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-faint);
}
.pick-row.hc-row .hc-row-go { flex: none; color: var(--ink-faint); font-size: 1.2rem; line-height: 1; }

.pick-row[aria-pressed="true"] { background: var(--court-wash); }
.pick-row[aria-pressed="true"] .tick { background: var(--court); border-color: var(--court); }
/* Adding somebody the club has never seen, from the same box you searched in. */
.pick-new {
  border: 1px dashed var(--line-firm); border-radius: .5rem;
  padding: .6rem .7rem; display: flex; flex-direction: column; gap: .5rem;
}
.pick-new-lede { font-size: .82rem; color: var(--ink-soft); }
.pick-new-row { display: flex; gap: .5rem; align-items: center; }
.pick-new-row input { flex: 1; min-width: 0; }
.pick-new-row .btn { flex: none; }

.pick-row[aria-pressed="true"] .tick::after {
  content: ""; position: absolute; left: .3rem; top: .12rem;
  width: .26rem; height: .52rem; border: solid var(--court-ink);
  border-width: 0 2px 2px 0; transform: rotate(42deg);
}

/* ---- drill diagrams ----
   A looping court rather than a video: no file to load, no compression, legible
   at any width, and it follows the light/dark palette like everything else. */
.dg {
  display: block; width: 100%; height: auto; margin: 0 0 1rem;
  background: var(--sunk); border: 1px solid var(--line); border-radius: 3px;
}
.dg .court { fill: none; stroke: var(--line-firm); stroke-width: 2; }
.dg .kz { fill: var(--court-wash); }
.dg .net { stroke: var(--ink-soft); stroke-width: 3; stroke-dasharray: 5 4; }
.dg .zone { fill: var(--ball); opacity: .25; }
.dg .dead { fill: var(--ink-faint); opacity: .2; }
.dg .pl { fill: var(--court); }
.dg .pl.two { fill: var(--clay); }
.dg .trace { fill: none; stroke: var(--ink-faint); stroke-width: 1.5; stroke-dasharray: 3 5; opacity: .6; }
.dg .ball { fill: var(--ball); stroke: var(--ball-ink); stroke-width: 1.5; }

@keyframes dgrun { from { offset-distance: 0%; } to { offset-distance: 100%; } }
.dg .ball, .dg .mover {
  offset-rotate: 0deg;
  animation: dgrun 2.4s ease-in-out infinite alternate;
}

/* Each path is the shot the drill is actually about. */
.dg .b-dinks  { offset-path: path("M138,60 Q220,88 302,140"); animation-duration: 2.2s; }
.dg .b-fig8   { offset-path: path("M138,60 L302,140 L138,140 L302,60 Z");
                animation-duration: 4.8s; animation-timing-function: linear;
                animation-direction: normal; }
.dg .b-drop   { offset-path: path("M18,100 Q120,8 255,96"); animation-duration: 2.6s; }
.dg .b-reset  { offset-path: path("M302,100 L62,100"); animation-duration: 1.3s; }
.dg .m-reset  { offset-path: path("M40,100 L140,100"); animation-duration: 5.2s; }
.dg .b-fire   { offset-path: path("M138,62 L302,132"); animation-duration: .62s; }
.dg .b-depth  { offset-path: path("M18,140 Q210,34 400,72"); animation-duration: 2.6s; }
.dg .b-skinny { offset-path: path("M60,150 Q220,112 380,150"); animation-duration: 2.4s; }
.dg .b-two    { offset-path: path("M302,60 Q200,102 104,138"); animation-duration: 1.2s; }
.dg .m-two    { offset-path: path("M104,62 L104,138"); animation-duration: 2.4s; }

/* Anyone who has asked for less motion gets the same diagram, held still. */
@media (prefers-reduced-motion: reduce) {
  .dg .ball, .dg .mover { animation: none; offset-distance: 55%; }
}

/* ---- groups ---- */
/* A strip inside a screen, not on the masthead - quieter than the main tabs so
   the two do not compete for the same job. */
.subtabs {
  display: flex; gap: .4rem; margin: 0 0 1.2rem;
  border-bottom: 1px solid var(--line); padding-bottom: .5rem;
}
.subtab {
  background: none; border: 1px solid transparent; border-radius: 999px;
  padding: .4rem .85rem; min-height: 40px; cursor: pointer;
  font-family: "Archivo", sans-serif; font-variation-settings: "wdth" 108;
  font-weight: 600; font-size: .86rem; color: var(--ink-soft);
}
.subtab:hover { color: var(--ink); }
.subtab[aria-selected="true"] {
  background: var(--court-wash); border-color: var(--court); color: var(--court);
}
.subtab:focus-visible { outline: 2px solid var(--court); outline-offset: 2px; }
.subtab .count {
  font-family: "DM Mono", monospace; font-size: .72rem;
  color: var(--ink-faint); margin-left: .35rem;
}
.subtab[aria-selected="true"] .count { color: var(--court); }

/* The queue sits inside the club card, under everything else about it. */
.grp-queue {
  margin-top: .9rem; padding-top: .8rem; border-top: 1px dashed var(--line-firm);
}
.grp-queue .prow { padding: .45rem 0; }

.groups-list { display: flex; flex-direction: column; gap: .6rem; }

.grp {
  background: var(--surface); border: 1px solid var(--line);
  border-left: 3px solid var(--line-firm); border-radius: 4px;
  padding: .75rem .85rem; box-shadow: var(--shadow);
}
.grp.current { border-left-color: var(--court); }

.grp-top { display: flex; align-items: flex-start; justify-content: space-between; gap: .9rem; }
.grp h3 {
  margin: 0; font-family: "Archivo", sans-serif; font-variation-settings: "wdth" 112;
  font-weight: 700; font-size: .96rem; line-height: 1.2; text-wrap: balance;
}
.grp-meta {
  font-family: "DM Mono", monospace; font-size: .68rem; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-faint); margin-top: .25rem;
}
.grp-here {
  font-family: "DM Mono", monospace; font-size: .62rem; letter-spacing: .1em;
  text-transform: uppercase; background: var(--court); color: var(--court-ink);
  padding: .16rem .45rem; border-radius: 2px; white-space: nowrap; flex: none;
}

/* The code is the whole security boundary, so it gets read like a password. */
/* The code used to be the loudest thing on the tile. It is a thing you read out
   once, not the point of the club, so it is now a line like any other. */
.grp-code {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  margin-top: .55rem; padding: 0; background: none;
}
.grp-code .lbl {
  font-family: "DM Mono", monospace; font-size: .6rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-faint);
}
.grp-code .code {
  font-family: "DM Mono", monospace; font-weight: 500; font-size: .82rem;
  letter-spacing: .1em; color: var(--ink-soft); font-variant-numeric: tabular-nums;
}
.grp-code .linkish { margin-left: auto; }

.grp-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: .6rem; margin-top: .6rem; flex-wrap: wrap;
}

/* ---- managing the people in a group ---- */
.padmin { display: flex; flex-direction: column; }

.padmin-row {
  display: grid; grid-template-columns: 1fr auto auto auto;
  gap: .6rem; align-items: center;
  padding: .55rem 0; border-bottom: 1px solid var(--line); font-size: .9rem;
}
.padmin-row:first-child { border-top: 1px solid var(--line); }
.padmin-row.editing, .padmin-row.going { background: var(--sunk); }
.padmin-row .nm { font-weight: 500; overflow-wrap: anywhere; }
.padmin-row .lvl {
  font-family: "DM Mono", monospace; font-size: .76rem; color: var(--ink-faint);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.padmin-edit { display: grid; grid-template-columns: 1fr 8rem auto auto; gap: .5rem; align-items: center; }
.padmin-warn { font-size: .8rem; color: var(--clay); }

@media (max-width: 560px) {
  .padmin-row { grid-template-columns: 1fr auto; row-gap: .35rem; }
  .padmin-row .lvl { grid-column: 2; }
  .padmin-edit { grid-template-columns: 1fr; }
}

/* ---- drills ---- */
.drills-list { display: flex; flex-direction: column; gap: .85rem; }

.drill {
  background: var(--surface); border: 1px solid var(--line);
  border-left: 3px solid var(--ball); border-radius: 4px;
  padding: 1rem 1.1rem; box-shadow: var(--shadow);
}
.drill.booked { border-left-color: var(--court); }

.drill-top { display: flex; align-items: flex-start; justify-content: space-between; gap: .9rem; }
/* The Edit control and the focus tag share the right of a drill's heading. */
.drill-icons { display: flex; align-items: center; gap: .5rem; flex: none; }
.drill h3 {
  margin: 0; font-family: "Archivo", sans-serif; font-variation-settings: "wdth" 112;
  font-weight: 700; font-size: 1.05rem; line-height: 1.2; text-wrap: balance;
}
.drill-meta {
  font-family: "DM Mono", monospace; font-size: .68rem; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-faint); margin-top: .25rem;
}
.drill-tag {
  font-family: "DM Mono", monospace; font-size: .64rem; letter-spacing: .06em;
  padding: .16rem .45rem; border-radius: 2px; white-space: nowrap; flex: none;
  background: var(--ball); color: var(--ball-ink);
}
.drill-foot {
  display: flex; align-items: center; justify-content: space-between; gap: .7rem;
  margin-top: .85rem; flex-wrap: wrap;
}

.drill-body {
  margin-top: .9rem; padding-top: .9rem; border-top: 1px dashed var(--line-firm);
  font-size: .87rem;
}
.drill-body h4 {
  margin: 1rem 0 .3rem; font-family: "DM Mono", monospace; font-size: .62rem;
  letter-spacing: .13em; text-transform: uppercase; color: var(--ink-faint); font-weight: 500;
}
.drill-body h4:first-child { margin-top: 0; }
.drill-body p { margin: 0; color: var(--ink-soft); }
.drill-body ol { margin: .2rem 0 0; padding-left: 1.15rem; color: var(--ink-soft); }
.drill-body ol li { margin-bottom: .3rem; }
.drill-body .watch { color: var(--clay); }

.imp-paste {
  min-height: 9rem; font-family: "DM Mono", monospace; font-size: .78rem; line-height: 1.5;
}
.imp-read { margin: .9rem 0 0; }

.round { margin-bottom: .4rem; }
.round-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin-bottom: .7rem; flex-wrap: wrap; }
/* The remove control and its confirmation, at the right of a round's heading.
   Wraps under on a phone rather than squeezing the round number. */
.round-drop { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.round-n {
  font-family: "Archivo", sans-serif; font-variation-settings: "wdth" 110;
  font-weight: 700; font-size: .78rem; letter-spacing: .1em; text-transform: uppercase;
}
/* The "tap a team" prompt, said once beside the round title instead of under
   every court. Sits right after the number and fades out as courts get scored. */
.round-title { display: flex; align-items: baseline; gap: .55rem; flex-wrap: wrap; min-width: 0; }
.round-hint {
  font-family: "DM Mono", monospace; font-size: .68rem; letter-spacing: .02em;
  color: var(--ink-faint); font-style: italic; text-transform: none;
}

/* A whole round on one screen. Courts tile in a grid rather than stacking,
   and a card is as small as two names each way can be read at arm's length.
   Six courts is three rows on a phone, which fits under the heading with the
   standings still to come. */
/* One court per row, full width, so the two teams can sit side by side
   inside it - a whole court reads across the row rather than down a column. */
.courts {
  display: grid; grid-template-columns: 1fr;
  gap: .5rem;
}

/* Between rounds. The arrows are for desktops and for anyone who does not
   guess the swipe; the dots say where you are. */
.round-carousel { touch-action: pan-y; margin-bottom: 1.4rem; }
.round-nav {
  display: flex; align-items: center; justify-content: space-between; gap: .6rem;
  margin-bottom: .55rem;
}
.round-of {
  font-family: "Archivo", sans-serif; font-variation-settings: "wdth" 110;
  font-weight: 700; font-size: .95rem; color: var(--ink);
}
.round-latest { font-weight: 500; font-size: .78rem; color: var(--clay); }
.round-arrow {
  width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--line-firm);
  background: var(--surface); color: var(--ink); font-size: 1.5rem; line-height: 1;
  cursor: pointer; display: grid; place-items: center; padding: 0;
}
.round-arrow[disabled] { opacity: .3; cursor: default; }
.round-arrow:focus-visible { outline: 2px solid var(--court); outline-offset: 2px; }
.round-dots { display: flex; justify-content: center; gap: .35rem; margin-top: .6rem; }
.dot-r { width: 6px; height: 6px; border-radius: 50%; background: var(--line-firm); }
.dot-r.on { background: var(--court); width: 16px; border-radius: 3px; }

.court-card { border: 1px solid var(--line); border-radius: 4px; background: var(--surface); overflow: hidden; }
.court-head {
  font-family: "Archivo", sans-serif; font-variation-settings: "wdth" 110;
  font-weight: 700; font-size: .8rem; letter-spacing: .02em;
  color: var(--court-ink); background: var(--court);
  padding: .25rem .6rem; border-bottom: 1px solid var(--line);
}
/* One court per row, so the two teams sit side by side with the net between
   them - left pair versus right pair, the way they face off on court. */
.teams { display: grid; grid-template-columns: 1fr auto 1fr; align-items: stretch; }

/* The whole half-court is the button for "these two won", so it wants to be a
   comfortable target rather than a tidy one. */
.team {
  background: transparent; border: none; text-align: left; padding: .6rem .6rem;
  cursor: pointer; display: flex; align-items: center; gap: .5rem; min-width: 0;
  min-height: 2.75rem;   /* still a thumb-sized target */
}

/* A court on a game that records nothing. The same shape as a team, but
   plainly not a button - there is nothing to press. */
.team-flat { cursor: default; background: var(--sunk); }
.tnames { display: flex; flex-direction: column; gap: .2rem; min-width: 0; flex: 1; }
.tend { display: flex; flex-direction: column; align-items: flex-end; gap: .1rem; flex: none; }
.team:hover:not([disabled]) { background: var(--sunk); }
.team[disabled] { cursor: default; }
.team .pl { font-size: .82rem; font-weight: 500; overflow-wrap: anywhere; line-height: 1.2; }
.team .rt2 { font-family: "DM Mono", monospace; font-size: .68rem; color: var(--ink-faint); }
.team[aria-pressed="true"] { background: var(--court-wash); box-shadow: inset 3px 0 0 var(--court); }
.team .wtag {
  font-family: "DM Mono", monospace; font-size: .6rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--court); white-space: nowrap;
}
/* A "VS" token between the two pairs - a filled court-green circle, like a
   fixture, so a court reads as two teams facing off, not one list of four. */
.net {
  align-self: center; width: 1.9rem;
  display: flex; align-items: center; justify-content: center;
}
.net span {
  width: 1.6rem; height: 1.6rem; border-radius: 50%;
  background: var(--court); color: var(--court-ink);
  display: grid; place-items: center;
  font-family: "DM Mono", monospace; font-size: .55rem; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase;
}

.sitting { margin-top: .65rem; display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; }
.sitting .lbl {
  font-family: "DM Mono", monospace; font-size: .63rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-faint); margin-right: .15rem;
}

/* Who is sitting the next round out, read off while you play. Set on the
   "Who is here" screen; cleared the moment the next round is drawn. */
.rest-next { margin-top: .55rem; }
.chip-rest { background: var(--clay-wash, var(--sunk)); }

/* On "Who is here": the name is a button that sits the person out. A greyed
   chip is resting; the tag says so in place of the played/sat count. */
.chip .pnm.here-name {
  display: inline-flex; align-items: baseline; gap: .35rem;
  background: none; border: none; padding: 0; margin: 0; font: inherit;
  color: inherit; cursor: pointer; text-align: left;
}
.chip-resting { background: var(--clay-wash, var(--sunk)); opacity: .7; }
.chip-resting .nm { text-decoration: line-through; text-decoration-thickness: 1px; }
.chip-resting .pos { color: var(--clay); text-decoration: none; }

/* The DUPR on a "Who is here" chip, tappable to set it. Monospaced so the
   numbers line up, quiet until hovered. "+ DUPR" when there is none yet. */
.chip .pnm-rate {
  font: inherit; font-family: "DM Mono", monospace; font-size: .68rem;
  font-variant-numeric: tabular-nums; color: var(--ink-soft);
  background: var(--sunk); border: 1px solid var(--line-firm); cursor: pointer;
  padding: .12rem .4rem; border-radius: 999px; flex: none; white-space: nowrap;
}
.chip .pnm-rate:hover { border-color: var(--court); color: var(--court); }

/* The chip turned into a little DUPR editor in place. */
.chip.chip-rate { gap: .3rem; padding: .18rem .35rem .18rem .6rem; }
.chip.chip-rate input {
  width: 5.2rem; padding: .2rem .4rem; font-size: .78rem;
  border: 1px solid var(--line-firm); border-radius: .4rem; background: var(--card);
}
.chip .pnm-set {
  font: inherit; font-size: .72rem; font-weight: 600; cursor: pointer;
  color: var(--court-ink); background: var(--court); border: none;
  padding: .22rem .5rem; border-radius: 999px; flex: none;
}

/* The Players-list search box sits above the rows, full width. */
.pl-search-field { margin: 0 0 .9rem; }

/* ---- the scoreboard ---- */
.board { border-top: 2px solid var(--ink); }

.board-head, .board-row {
  display: grid;
  grid-template-columns: 1.8rem minmax(0, 1fr) 1.9rem 1.9rem 3.2rem;
  gap: .5rem; align-items: center;
}
.board.lite .board-head, .board.lite .board-row {
  grid-template-columns: 1.8rem minmax(0, 1fr) 1.9rem 1.9rem;
}

.board-head {
  padding: .4rem .35rem .4rem 0; border-bottom: 1px solid var(--line);
  font-family: "DM Mono", monospace; font-size: .6rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-faint);
}
.board-head span:nth-child(n+3) { text-align: right; }
.board-head span:first-child { text-align: right; }

.board-row { padding: .5rem .35rem; border-bottom: 1px solid var(--line); }
/* The leader gets the court wash rather than a trophy - it reads at a glance
   without pretending this is a tournament. */
.board-row.lead { background: var(--court-wash); box-shadow: inset 3px 0 0 var(--court); }
.board-row.lead .bd-rank { color: var(--court); }
.board-row.idle { opacity: .5; }

.bd-rank {
  font-family: "DM Mono", monospace; font-size: .76rem; color: var(--ink-faint);
  font-variant-numeric: tabular-nums; text-align: right;
}
.bd-name .nm { display: block; font-size: .9rem; font-weight: 500; overflow-wrap: anywhere; }
.bd-sub {
  display: block; margin-top: .05rem;
  font-family: "DM Mono", monospace; font-size: .66rem; color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
}
.bd-n {
  font-family: "DM Mono", monospace; font-size: .84rem; text-align: right;
  font-variant-numeric: tabular-nums; color: var(--ink-faint);
}
.bd-n.win { color: var(--ink); font-weight: 500; }
.bd-diff {
  font-family: "Archivo", sans-serif; font-variation-settings: "wdth" 104;
  font-weight: 700; font-size: 1.02rem; text-align: right; line-height: 1;
  font-variant-numeric: tabular-nums; color: var(--ink-faint);
}
.bd-diff.up { color: var(--court); }
.bd-diff.down { color: var(--clay); }

/* ---- entering a result ---- */
.res-foot {
  display: flex; align-items: center; gap: .6rem;
  padding: .45rem .7rem; border-top: 1px solid var(--line); background: var(--sunk);
}
.res-score {
  font-family: "DM Mono", monospace; font-size: .72rem; letter-spacing: .04em;
  color: var(--ink-soft); font-variant-numeric: tabular-nums; margin-right: auto;
}
/* The nudge in place of a button - quieter than a real result. */
.res-score.hint { color: var(--ink-faint); font-style: italic; }
.res-edit { padding: .75rem .8rem; border-top: 1px solid var(--line); background: var(--sunk); }
/* Only problems get a line, so the element collapses when there is none. */
.res-hint { margin: 0 0 .6rem; font-size: .8rem; color: var(--clay); }
.res-hint:empty { display: none; margin: 0; }
.res-btns { display: flex; align-items: center; justify-content: center; gap: .6rem; flex-wrap: wrap; }
.res-btns .btn { min-height: 2.75rem; padding-left: 1.4rem; padding-right: 1.4rem; }

/* ---- the dock ----
   Next round, pinned to the bottom of the screen for as long as a session is
   running, so the last thing you do to a round is next to the thing you do
   after it. */
.dock {
  position: sticky; bottom: 0; z-index: 5; margin: 1.25rem -1.25rem 0;
  padding: .55rem 1.25rem calc(.55rem + env(safe-area-inset-bottom, 0px));
  background: var(--surface); border-top: 1px solid var(--line-firm);
  box-shadow: 0 -6px 18px -12px rgba(0, 0, 0, .45);
}
.dock-in {
  display: flex; align-items: center; justify-content: space-between; gap: .75rem;
  max-width: 720px; margin: 0 auto;
}
.dock-note {
  font-family: "DM Mono", monospace; font-size: .74rem; color: var(--ink-soft);
  min-width: 0; overflow: hidden; text-overflow: ellipsis;
}
.dock .btn { flex: none; min-height: 2.6rem; }

/* The names stay tappable while editing, but the card is no longer a button -
   an input cannot live inside one. */
.tpick {
  background: none; border: none; padding: 0; margin: 0; cursor: pointer;
  display: flex; flex-direction: column; gap: .2rem;
  min-width: 0; flex: 1; text-align: left; color: inherit; font: inherit;
}
.tpick:hover .pl { color: var(--court); }
.team.picked { background: var(--court-wash); box-shadow: inset 3px 0 0 var(--court); }

/* Sized and set to match .sc, so the box sits exactly where the number reads. */
/* Typed one-handed, standing up, holding a paddle. Wide enough to hit without
   looking and tall enough that the number keypad is worth opening. */
.sc-in {
  width: 4.2rem; min-height: 3rem; text-align: center; flex: none;
  background: var(--surface); border: 2px solid var(--court); border-radius: 6px;
  padding: .35rem .3rem; color: inherit;
  font-family: "Archivo", sans-serif; font-variation-settings: "wdth" 108;
  font-weight: 700; font-size: 1.6rem; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.sc-in:focus { outline: 2px solid var(--court); outline-offset: 1px; }

.team .sc {
  font-family: "Archivo", sans-serif; font-variation-settings: "wdth" 108;
  font-weight: 700; font-size: 1.5rem; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.team[aria-pressed="true"] .sc { color: var(--court); }

@media (max-width: 560px) {
  .grid { grid-template-columns: 1fr; }
  .prow { grid-template-columns: auto 1fr; }
  .pstat { grid-column: 2; text-align: left; margin-top: .2rem; }
  .mode-grid { grid-template-columns: 1fr; }
  .board-head, .board-row {
    grid-template-columns: 1.5rem minmax(0, 1fr) 1.5rem 1.5rem 2.7rem; gap: .35rem;
  }
  .board.lite .board-head, .board.lite .board-row {
    grid-template-columns: 1.5rem minmax(0, 1fr) 1.5rem 1.5rem;
  }
}

.claim-wrap { margin-top: -.2rem; }
.claim-hint { margin-top: .5rem; }

/* ============================================================
   Group settings — redesigned layout (navigation hub, numbered
   sections, access toggles, integration status, roster dropzones)
   ============================================================ */

/* --- navigation hub: tabs on the left, group actions on the right --- */
.comm-hub {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
}
.comm-hub .subtabs {
  margin: 0; border-bottom: 0; padding-bottom: 0; flex-wrap: wrap;
}
.hub-actions { display: flex; gap: .5rem; flex-wrap: wrap; }

/* --- the settings card header --- */
.grp.is-set { padding: 0; overflow: hidden; }
.grp-set-head {
  padding: 1.1rem 1.2rem; border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--court-wash) 55%, transparent), transparent);
}
.grp-set-head .eyebrow {
  font-family: "DM Mono", monospace; text-transform: uppercase;
  letter-spacing: .15em; font-size: .68rem; color: var(--court); margin: 0 0 .3rem;
}
.grp-set-head .grp-set-title {
  font-family: "Archivo", sans-serif; font-weight: 700;
  font-size: 1.3rem; line-height: 1.15; margin: 0;
}
.grp-set-head .grp-set-sub { margin: .3rem 0 0; color: var(--ink-soft); font-size: .9rem; }

/* --- numbered sections --- */
.grp-sec { padding: 1.1rem 1.2rem; border-bottom: 1px solid var(--line); }
.grp-sec:last-child { border-bottom: 0; }
.grp-sec-h {
  font-family: "DM Mono", monospace; text-transform: uppercase;
  letter-spacing: .13em; font-size: .7rem; color: var(--ink-faint);
  margin: 0 0 .9rem; display: flex; align-items: center; gap: .55rem;
}
.grp-sec-h .step {
  color: var(--court); background: var(--court-wash); border: 1px solid var(--court-wash);
  width: 1.25rem; height: 1.25rem; border-radius: .4rem;
  display: grid; place-items: center; font-size: .72rem;
}

/* --- access & permissions: two panels of toggles --- */
.acc-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.acc-panel {
  background: var(--sunk); border: 1px solid var(--line);
  border-radius: .85rem; padding: .9rem 1rem .3rem;
}
.acc-panel .p-head {
  font-family: "DM Mono", monospace; text-transform: uppercase;
  letter-spacing: .1em; font-size: .68rem; color: var(--ink-soft); margin: 0 0 .3rem;
}
.toggle {
  display: flex; gap: .8rem; align-items: flex-start; justify-content: space-between;
  padding: .75rem 0; border-bottom: 1px dashed var(--line); cursor: pointer;
}
.toggle:last-child { border-bottom: 0; }
.toggle .tx strong { display: block; font-size: .9rem; font-weight: 600; }
.toggle .tx span { display: block; font-size: .78rem; color: var(--ink-soft); margin-top: .15rem; }
.sw { position: relative; display: inline-block; width: 46px; height: 27px; flex: none; margin-top: .1rem; }
.sw input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; z-index: 2; }
.sw .track { position: absolute; inset: 0; background: var(--line-firm); border-radius: 999px; transition: .18s; }
.sw .thumb {
  position: absolute; top: 3px; left: 3px; width: 21px; height: 21px;
  background: #fff; border-radius: 50%; box-shadow: 0 1px 3px rgba(0,0,0,.35); transition: .18s;
}
.sw input:checked ~ .track { background: var(--court); }
.sw input:checked ~ .thumb { transform: translateX(19px); }
.sw input:focus-visible ~ .track { outline: 2px solid var(--court); outline-offset: 2px; }

/* --- form footer inside the settings card --- */
.grp-set-foot {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--line);
}
.grp-set-foot .foot-code {
  margin-right: auto; font-family: "DM Mono", monospace;
  font-size: .78rem; color: var(--ink-faint); letter-spacing: .06em;
}
/* The single Save / Cancel at the very end of the settings card - a full bar,
   not an inline footer within a section. */
.grp-set-foot.end {
  margin: 0; padding: 1rem 1.2rem; border-top: 1px solid var(--line);
  background: var(--sunk); justify-content: flex-end;
}
/* The empty anchor form that the scattered fields tie to with form=. */
.grp.is-set > form.grp-edit { margin: 0; }

/* --- integration status bar + badge --- */
.intbar {
  display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
  padding: .7rem .85rem; background: var(--sunk); border: 1px solid var(--line);
  border-radius: .75rem; margin-bottom: .9rem;
}
.intbar .status { display: inline-flex; align-items: center; gap: .5rem; font-weight: 600; font-size: .85rem; }
.intbar .status .dot {
  width: 9px; height: 9px; border-radius: 50%; background: var(--ball);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--ball) 26%, transparent);
}
.intbar .status .dot.off { background: var(--ink-faint); box-shadow: none; }
.intbar .badge {
  display: inline-flex; align-items: center; gap: .45rem; margin-left: auto;
  background: var(--surface); border: 1px solid var(--line-firm); border-radius: 999px;
  padding: .35rem .7rem; font-weight: 600; font-size: .8rem;
}
.intbar .badge .hc {
  width: 18px; height: 18px; border-radius: 5px; display: grid; place-items: center;
  background: var(--court); color: var(--court-ink); font-size: .66rem; font-weight: 800;
  font-family: "Archivo", sans-serif;
}
.intbar .badge .ok { color: var(--ball); font-weight: 800; }

/* --- roster dropzones (member CSV, DUPR export) --- */
.dz-two { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; }
.dropzone {
  display: block; position: relative; text-align: center; cursor: pointer;
  border: 2px dashed var(--line-firm); border-radius: .7rem; background: var(--surface);
  padding: .75rem .7rem; transition: .16s;
}
.dropzone:hover, .dropzone.dragging { border-color: var(--court); background: var(--court-wash); }
.dropzone .dz-ic {
  width: 30px; height: 30px; margin: 0 auto .3rem; border-radius: .5rem;
  background: var(--court-wash); color: var(--court); display: grid; place-items: center;
}
.dropzone .dz-ic svg { width: 16px; height: 16px; }
.dropzone strong { display: block; font-size: .82rem; }
.dropzone .dz-sub { display: block; font-size: .7rem; color: var(--ink-soft); margin-top: .15rem; line-height: 1.35; }
.dropzone .dz-pick {
  display: inline-block; margin-top: .5rem; font-weight: 700; font-size: .76rem;
  color: var(--court); border: 1px solid var(--court); border-radius: .5rem; padding: .3rem .7rem;
}
.dropzone .dz-msg { display: block; margin-top: .4rem; font-size: .74rem; color: var(--ink); }
/* the real input stays hidden; the whole zone is the trigger */
.dropzone input[type="file"] {
  position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none;
}

@media (max-width: 560px) {
  .acc-grid, .dz-two { grid-template-columns: 1fr; }
  .comm-hub .subtabs, .hub-actions { width: 100%; }
  .hub-actions .btn { flex: 1; }
}

/* Join code chip - sits top-right of the collapsed group card, beside the
   name. The whole chip is the copy button; a toast confirms the copy. */
.grp-top-right {
  display: flex; align-items: center; gap: .6rem; flex: none;
  flex-wrap: wrap; justify-content: flex-end;
}
.code-chip {
  display: inline-flex; align-items: center; gap: .45rem; cursor: pointer;
  background: var(--court-wash); border: 1px solid var(--court);
  border-radius: 999px; padding: .3rem .6rem .3rem .7rem; transition: .14s;
}
.code-chip:hover { background: var(--court); }
.code-chip:hover .cc-lbl, .code-chip:hover .cc-val, .code-chip:hover .cc-ico {
  color: var(--court-ink);
}
.code-chip:focus-visible { outline: 2px solid var(--court); outline-offset: 2px; }
.code-chip:active { transform: translateY(1px); }
.cc-lbl {
  font-family: "DM Mono", monospace; text-transform: uppercase;
  letter-spacing: .1em; font-size: .6rem; color: var(--court);
}
.cc-val {
  font-family: "DM Mono", monospace; font-weight: 500; font-size: .9rem;
  letter-spacing: .08em; color: var(--court);
}
.cc-ico { font-size: .82rem; color: var(--court); line-height: 1; }

/* Post/edit game form as a sectioned card (reuses .grp-set-head, .grp-sec,
   .toggle and .sw from the group-settings redesign). */
.form-card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 16px; box-shadow: var(--shadow); overflow: hidden; margin: .9rem 0 0;
}
.form-card .tpl { padding: .9rem 1.2rem 0; margin: 0; }
.form-card-foot {
  display: flex; align-items: center; gap: .6rem; justify-content: flex-end;
  padding: 1rem 1.2rem; background: var(--sunk); border-top: 1px solid var(--line);
}
/* a toggle dropped into a form grid spans the whole row */
.wide-toggle { grid-column: 1 / -1; }
.grp-sec > .bg-field { margin-top: .7rem; }

@media (max-width: 560px) {
  .subfields { grid-template-columns: 1fr; }
  .form-card-foot .btn { flex: 1; }
}

/* Game form header with a Cancel button top-right (post/edit), alongside the
   Cancel in the footer. Only the game forms get the row modifier, so the group
   settings header is untouched. */
.grp-set-head--row {
  display: flex; align-items: flex-start; justify-content: space-between; gap: .8rem;
}
.grp-set-head--row > .btn { flex: none; }

/* ---- merging duplicate players (owner member-admin) ---- */
.merge-suggests {
  margin: 0 0 1rem; padding: .8rem .9rem; background: var(--sunk);
  border: 1px solid var(--line); border-radius: .7rem;
}
.merge-sug-row {
  display: flex; align-items: center; justify-content: space-between; gap: .6rem;
  padding: .35rem 0; font-size: .9rem;
}
.merge-sug-row + .merge-sug-row { border-top: 1px dashed var(--line); }

.merge-link { white-space: nowrap; }
.merge-link.on { color: var(--court); font-weight: 600; }
.padmin-row.merge-target {
  background: var(--court-wash); border-radius: .5rem;
  box-shadow: inset 0 0 0 1px var(--court);
}

.merge-preview { border: 1px solid var(--court); }
.merge-preview h3 { margin: 0 0 .3rem; }
.merge-what { margin: .2rem 0 .8rem; padding-left: 1.1rem; font-size: .9rem; color: var(--ink-soft); }
.merge-what li { margin: .15rem 0; }
.merge-warn {
  background: var(--clay-wash); border: 1px solid var(--clay);
  border-radius: .6rem; padding: .5rem .7rem; margin: 0 0 .8rem;
}
.merge-warn p { margin: .2rem 0; font-size: .85rem; color: var(--ink); }
.merge-choose {
  display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; margin: .5rem 0; font-size: .9rem;
}
.merge-choose .lbl {
  font-family: "DM Mono", monospace; text-transform: uppercase; letter-spacing: .08em;
  font-size: .68rem; color: var(--ink-faint); margin-right: .3rem;
}
.chip.merge-chip {
  cursor: pointer; border: 1px solid var(--line-firm); background: var(--surface);
  border-radius: 999px; padding: .25rem .7rem; font-size: .85rem; color: var(--ink);
}
.chip.merge-chip.on { background: var(--court-wash); border-color: var(--court); color: var(--court); }

/* A round drawn as a surprise (mixer) round in level tiers. */
.round-surprise {
  display: inline-block; margin-left: .5rem; vertical-align: middle;
  font-family: "DM Mono", monospace; text-transform: uppercase; letter-spacing: .08em;
  font-size: .62rem; font-weight: 500;
  color: var(--ball-ink); background: var(--ball);
  border-radius: 999px; padding: .1rem .5rem;
}
