/* ═══════════════════════════════════════════════════════════════════
   OTX2 team portal.

   Two visual languages on purpose, and the spec asks for both.

   The sign-in and invite cards follow the ORDER SHEET: black section
   bands, hairline #eee panels, a narrow document column, Segoe UI.
   They are forms, and they should not look like they came from a
   different product than the sheet the coach fills in next.

   The card rows are the one place that departs from it, because they
   are a navigation surface rather than a document. Horizontal scroll,
   real buttons, thumb-sized targets.

   Light only. The order sheet is a print document and the rest must not
   disagree with it, so there is no prefers-color-scheme block anywhere
   in this file.
   ═══════════════════════════════════════════════════════════════════ */

:root {
  color-scheme: light;
  /* Read off https://www.otx2.com rather than sampled from a mockup. The
     identity is near-black and white; #334FB4 is the site's own blue and is
     spent on state, never on a surface. The name --navy is kept because it
     is used throughout, but the value is now the real one. */
  --navy:     #121212;
  --blue:     #334FB4;
  --ink:      #000;
  --grey:     #555;
  --grey-lt:  #888;
  --rule:     #eee;
  --rule-mid: #ddd;
  --field:    #ccc;
  --fill:     #f2f2f2;
  --cream:    #f4f7fc;
  --cream-br: #ccd8ee;
  --cream-tx: #3f5580;
  --bad:      #9b1c1c;
  --bad-bg:   #fdf2f2;
  --bad-br:   #f0c8c8;
  --good:     #16a34a;
  --pad:      20px;
  /* Assistant is what otx2.com sets, and brand.css self-hosts it. The stack
     behind it is the platform's own UI face, so a coach on a slow connection at
     a ground reads something sensible rather than nothing. Segoe UI stays in
     the list because the printed design proof is set in it and the two sit
     together without a visible seam. */
  --sans: "Assistant", -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, Helvetica, sans-serif;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

/* overflow-x is clipped at the root rather than trusted to every child.
   The rows below are the only thing on the page allowed to scroll
   sideways, and one long unbroken word in a team name must not be able
   to turn the whole document into a sideways-scrolling page at 320px. */
body {
  margin: 0;
  overflow-x: hidden;
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink);
  background: #fff;
}

h1, h2, h3, p { margin: 0; }
img { max-width: 100%; }
button, input, select { font: inherit; color: inherit; }

.eyebrow {
  font-size: 10px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--grey);
}
.num { font-variant-numeric: tabular-nums; }

/* Everything focusable gets the same ring, set once. A card row that is
   scrolled with a keyboard is unusable without it, and the spec asks
   for the rows to be keyboard reachable. */
:focus-visible {
  outline: 3px solid var(--navy);
  outline-offset: 2px;
}

/* ── top bar ─────────────────────────────────────────────────────── */

.topbar {
  background: var(--navy); color: #fff;
  display: flex; align-items: center; gap: 12px;
  padding: 12px var(--pad);
}
/* The supplied wordmark, not type set to look like it. It is white artwork on
   a transparent ground, which is why the bar behind it has to stay dark. */
.topbar .mark { display: flex; align-items: center; flex: none; text-decoration: none; }
.topbar .mark img { display: block; height: 19px; width: auto; }
/* THE PARTNERSHIP, SAID IN THE BAR RATHER THAN NOWHERE.
   Romero, 28 August 2026: "tnza is the governing body and otx2 is apparel
   partner so we need to show that relationship". A manager arrives here from a
   TNZA link and lands on a page marked only with the supplier's name, which
   gets the hierarchy exactly backwards.

   Set as a lockup and not two logos in a row: the words carry the relationship
   and the rule separates the two marks, so it reads as one statement. The TNZA
   mark is the taller of the two because it is the governing body; OTX2's
   wordmark stays at its own 19px.

   The words go first on a phone and would wrap into a second line of bar, so
   below 560px the lockup keeps the mark and drops the words. The relationship
   is still shown; it is just no longer spelled out where there is no room. */
.topbar .partner {
  display: flex; align-items: center; gap: 9px; flex: none;
  padding-left: 12px; margin-left: 2px;
  border-left: 1px solid rgba(255,255,255,.22);
}
/* THE DEVICE, NOT THE FULL LOCKUP. The supplied mark sets the association's
   name under the ball, and at the 26px a bar allows that name renders about
   four pixels tall: a smudge, which is worse than not showing it. So the ball
   carries the mark and the WORDS carry the name, at a size somebody can read.
   The two halves of the lockup, set at the sizes each half actually works at. */
.topbar .partner-of {
  font-size: 9px; line-height: 1.35; letter-spacing: .07em;
  text-transform: uppercase; opacity: .6; white-space: nowrap;
}
.topbar .partner-of b { font-weight: 700; opacity: .95; letter-spacing: .04em; }
.topbar .partner img { display: block; height: 28px; width: auto; }
@media (max-width: 560px) {
  /* The words are two lines and would make the bar half again as tall. The
     mark stays: the relationship is still shown, it is just not spelled out
     where there is no room to spell it. */
  .topbar .partner-of { display: none; }
  .topbar .partner { gap: 0; padding-left: 10px; }
  .topbar .partner img { height: 22px; }
}

.topbar .who {
  margin-left: auto; font-size: 12px; opacity: .82;
  text-align: right; min-width: 0;
  /* An email is one long unbroken token, and it is the single most
     likely thing on this page to push the layout past 320px. */
  overflow-wrap: anywhere;
}
.topbar .who b { font-weight: 600; }
.linkish {
  background: none; border: none; padding: 0;
  color: #fff; font-size: 12px; text-decoration: underline;
  cursor: pointer; flex: none;
}
.linkish:hover { opacity: .8; }

/* ── the document column: sign in, invite, messages ──────────────── */

.doc { max-width: 460px; margin: 0 auto; padding: 34px var(--pad) 60px; }
.doc.wide { max-width: 1100px; }

.band {
  background: #000; color: #fff; padding: 7px 16px;
  font-size: 12px; font-weight: 700; letter-spacing: .3px; text-align: center;
}
.panel { border: 1px solid var(--rule); border-top: none; padding: 18px 16px; }

.lede { font-size: 13px; color: var(--grey); margin-bottom: 16px; }

.field { margin-bottom: 14px; }
.field label { display: block; font-size: 11px; font-weight: 700; color: var(--grey); margin-bottom: 5px; }
.field input {
  width: 100%; border: 1px solid var(--field); background: #fff;
  padding: 11px 12px; font-size: 16px; /* 16px: anything smaller and iOS zooms the page on focus */
}
.field input:focus { outline: 2px solid var(--navy); outline-offset: -2px; border-color: var(--navy); }
.field .hint { font-size: 11px; color: var(--grey-lt); margin-top: 5px; }

.btn {
  display: block; width: 100%; border: none; cursor: pointer;
  background: var(--navy); color: #fff;
  font-size: 15px; font-weight: 700; padding: 13px 18px;
}
.btn:hover { background: #02194f; }
.btn[disabled] { opacity: .55; cursor: default; }

/* The error strip, in the shape of the order sheet's status strip. */
.note {
  display: none; margin-bottom: 16px; padding: 10px 14px;
  font-size: 12.5px; border: 1px solid var(--cream-br);
  border-left: 4px solid var(--navy); background: var(--cream); color: var(--cream-tx);
}
.note.is-shown { display: block; }
.note.is-bad { background: var(--bad-bg); border-color: var(--bad-br); border-left-color: var(--bad); color: var(--bad); }

/* The "my link does not work" escape hatch. Set apart by a rule rather than
   made to look like a second sign-in form: it is the exception, and somebody
   who has a working password should be able to skip past it without reading. */
.relink { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--rule); }
.linky {
  background: none; border: none; padding: 0; cursor: pointer;
  font-size: 12.5px; color: var(--navy); text-decoration: underline;
}
.relink .hint { font-size: 12px; color: var(--grey); margin: 10px 0 12px; }

.footnote { font-size: 11.5px; color: var(--grey-lt); margin-top: 18px; text-align: center; }

/* ── the card rows ───────────────────────────────────────────────── */

/* ONE COLUMN, AND EVERYTHING SITS IN IT.
 *
 * Romero, 29 Aug 2026, on the manager view: "this ui doesnt make sense from
 * asthetic and functional pov".
 *
 * The cards were capped at 1160px and centred; the labels above them were not,
 * so on a 1440px window the word TEAM sat at x=20 and the tiles it named began
 * at x=160. Three different left edges down one page, and a 140px trench
 * between a heading and the thing it heads. The cap is a shared token now and
 * the head, the jobs list and the cards all read from it, so a label lines up
 * with its own content at every width. */
:root { --shell: 1160px; }

.rows { padding: 26px 0 70px; }
.row { margin-bottom: 30px; }
.row-head {
  display: flex; align-items: baseline; gap: 10px;
  padding: 0 var(--pad); margin-bottom: 10px;
  max-width: var(--shell); margin-left: auto; margin-right: auto;
}
.row-note { font-size: 12px; color: var(--grey-lt); }

/* A grid, not a scroller.

   This started as a horizontal snap row, and on a phone that was the
   wrong shape: a coach could see two cards of six and had no way to
   tell there were four more off the right edge. Sideways scroll hides
   the size of a list, and the size of the list is the thing a manager
   is trying to read.

   Two columns on a phone, more as there is room. minmax(0, 1fr) rather
   than 1fr because a grid track's default minimum is its content, and
   one long unbroken team name in a 1fr track is exactly how a grid
   pushes the page wider than the viewport. */
.row-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
  padding: 4px var(--pad) 14px;
  max-width: var(--shell); margin: 0 auto;
}
@media (min-width: 560px)  { .row-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 780px)  { .row-cards { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 1020px) { .row-cards { grid-template-columns: repeat(5, minmax(0, 1fr)); } }

.card {
  width: auto; min-width: 0;   /* min-width:0 for the same reason as minmax above */
  -webkit-appearance: none; appearance: none;
  border: none; padding: 0; cursor: pointer;
  text-align: left; font: inherit;
  background: #fff;
  display: flex; flex-direction: column;
}

/* Crest cards: the club or team's own colour, its own artwork, its own
   ink. Every hex here comes from the row, set inline by portal.html —
   nothing about a club's brand is hard coded in this file. */
.card-brand {
  border: 1px solid var(--rule);
  background: var(--brand, var(--navy));
  color: var(--ink-on, #fff);
}
/* THE CREST, CENTRED ON THE TEAM'S OWN COLOUR, which is what this always
   wanted to be. It used to run full bleed at its own aspect ratio, and the
   note here used to explain why: the supplied PNGs were opaque RGB with a
   baked-in background each, navy for the Wolves, black for the Lions and
   the Rams, near-white for the Ravens and the Raiders. Floating those on
   the brand colour put a hard black rectangle on Canterbury's maroon and a
   white one on Harbour's purple, so full bleed was the lesser evil.

   Full bleed cost the thing Romero asked for on 28 August 2026: "make sure
   all the boxes same size and layout an format is spacing padding is the
   same". At its own ratio every card is a different height, and a card
   with no crest at all is a different shape again.

   The crests are transparent now, knocked out and trimmed and centred on a
   square canvas, so this is the same box as .crest-box below it: same
   ratio, same padding, same everything. A team with a crest and a team
   without now come out identical. */
.card-brand .crest {
  width: 100%; flex: none;
  aspect-ratio: 1 / 1;
  display: flex; align-items: center; justify-content: center;
  padding: 14px; overflow: hidden;
}
.card-brand .crest img {
  display: block;
  /* CONTAIN, and no width:100%. A wordmark is far wider than it is tall and
     a crest is nearly square; stretching either to the box would distort
     one of them. This lets each sit at its own shape inside an identical
     frame, which is the only way "same size boxes" and "undistorted
     artwork" are both true. */
  max-width: 100%; max-height: 100%; width: auto; height: auto;
  object-fit: contain;
}

/* The typographic fallback, for a team with no crest file. A supported
   state and not a missing image: Senior Black Tags has no crest, and a
   hole in the row would read as a bug.

   In a grid the tile can no longer be pinned to a fixed height, because
   the card is now as wide as its column rather than 200px. It takes the
   crests' own square ratio instead, so a typographic card and a crest
   card in the same row still come out the same height.

   width:100% is load bearing, not tidiness. This box is an item in a
   COLUMN flex container, so its height is the main size and is resolved
   from content BEFORE the cross axis is stretched — at which point the
   width is still indefinite and aspect-ratio has nothing to work from.
   The tile then collapses to the height of its one line of text. */
.card-brand .crest-box {
  width: 100%; flex: none;
  aspect-ratio: 1 / 1;
  display: flex; align-items: center; justify-content: center;
  padding: 14px; overflow: hidden;
}
.card-brand .crest-type {
  font-size: 19px; font-weight: 800; line-height: 1.2;
  letter-spacing: .02em; text-align: center; text-transform: uppercase;
  opacity: .95; overflow-wrap: anywhere;
}
.card-brand .cap {
  padding: 10px 12px; font-size: 13px; font-weight: 700;
  border-top: 1px solid rgba(255,255,255,.18);
}
.card-brand .cap span { display: block; font-size: 11px; font-weight: 400; opacity: .78; }
/* Accent is a rule and not a fill, so a team that has one reads as the
   same card with a stripe rather than a different design. */
.card-brand.has-accent { border-bottom: 3px solid var(--accent); }

.card[aria-pressed="true"] { box-shadow: 0 0 0 3px var(--navy); }

/* Form cards: typographic, in the document look, because the row they
   sit in is the last step before a form opens. */
.card-form {
  border: 1px solid var(--rule);
  padding: 14px; gap: 6px; text-decoration: none; color: var(--ink);
  min-height: 150px;
}
.card-form:hover { border-color: var(--rule-mid); background: #fcfcfd; }
.card-form h3 { font-size: 14px; font-weight: 700; color: var(--navy); }
.card-form p { font-size: 12px; color: var(--grey); flex: 1; }
.card-form .state {
  font-size: 11px; font-weight: 700; color: var(--grey-lt);
  text-transform: uppercase; letter-spacing: .06em;
}
.card-form .state.is-set { color: var(--good); }
/* Shown and disabled rather than hidden. A manager hunting for the
   top-up form should find out why it is not available, not wonder
   whether they misremembered it. */
.card-form.is-off { opacity: .5; cursor: default; }
.card-form.is-off:hover { border-color: var(--rule); background: #fff; }

.row-empty {
  max-width: var(--shell); margin-left: auto; margin-right: auto;
  padding: 0 var(--pad); font-size: 13px; color: var(--grey-lt);
}

/* A grade tile. Same brand card, but the grade IS the whole card, so it
   is shorter than a crest tile — six of them stacked two-up should not
   be six screens of scrolling. The side's crest is deliberately not
   repeated here: every card in this row belongs to the same side, so
   printing the same crest six times says nothing and only makes the
   grade harder to read. */
.card-grade .crest-box { aspect-ratio: 5 / 3; }
.card-grade .crest-type { font-size: 16px; }

/* ── narrow ──────────────────────────────────────────────────────── */

@media (max-width: 420px) {
  :root { --pad: 14px; }
  .row-cards { gap: 10px; }
  .card-brand .crest-type { font-size: 16px; }
  .card-grade .crest-type { font-size: 14px; }
  .doc { padding-top: 26px; }
}

/* ── what is due ──────────────────────────────────────────────────────
   A LIST, not the card grid the rows below use. The cards answer "where am
   I"; this answers "what do they need from me", and a job is read left to
   right — the thing, the squad, the deadline — rather than looked at. Giving
   it the same treatment as a team card would say they are the same kind of
   thing, and they are not. */
.jobs {
  display: flex; flex-direction: column; gap: 8px;
  padding: 0 var(--pad);
  max-width: var(--shell); margin: 0 auto;   /* same column as the cards below it */
}

.job {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 15px;
  background: var(--card, #fff);
  border: 1px solid var(--rule);
  border-left: 4px solid #333;      /* the team's own colour, set inline */
  border-radius: 10px;
  text-decoration: none;
  color: inherit;
}
.job:hover { border-color: var(--rule-firm, #bbb); }

.job-b { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.job-what { font-size: 15px; font-weight: 650; line-height: 1.3; }
.job-meta { font-size: 12.5px; color: var(--grey); }

.job-due {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  padding: 4px 8px;
  border-radius: 5px;
  white-space: nowrap;
  flex: none;
}
.job-due.wait { background: #FBEEDA; color: #8A5200; }
.job-due.good { background: #DFF0E6; color: #13633C; }
.job-due.late { background: #FBE4E7; color: #9B1226; }

.job-act {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--navy);
  white-space: nowrap;
  flex: none;
}

@media (max-width: 520px) {
  /* The action word is the whole card's job on a phone, so it goes; tapping
     the row is the action. The deadline stays, because it is the information. */
  .job-act { display: none; }
  .job { padding: 12px 13px; }
}

/* Squad ticks on the join screen. Deliberately plain: this is the one screen a
   stranger sees, and it should read as a form rather than as a product. */
.check-row {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 2px; cursor: pointer; font-size: 15px;
  border-bottom: 1px solid var(--rule);
}
.check-row:last-child { border-bottom: none; }
.check-row input { width: 18px; height: 18px; flex: none; accent-color: var(--navy); }

/* "optional" beside a label. Small and grey so the field reads as skippable at
   a glance: the whole point of asking for an email now is that it is a choice. */
.field label .opt {
  font-weight: 400; font-size: 12px; color: var(--grey);
  text-transform: none; letter-spacing: 0; margin-left: 6px;
}

/* THE SQUAD PICKER, 2026-08-19.
   A team link now opens the proof sheet directly. This list only appears when
   one link genuinely stands for several squads, because somebody still has to
   say which one they are filling in. Rows rather than cards: it is tapped once
   and never seen again, and a 56px tap target beats a design. */
.joinlist { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
/* THE PIECES THAT ARE ALREADY DECIDED, on a reversible set.
   Most of the kit is not a choice there: the singlet, the women's singlet and
   the shorts wear both designs because that is what reversible means. Said only
   in a sentence, a manager wonders whether they have missed a question. Shown as
   settled rows above the one real choice, the shape of the decision is visible
   before it is read. Ticks rather than padlocks: nothing is being withheld, it
   is already sorted. */
.klocked {
  border: 1px solid var(--rule); border-radius: 10px;
  background: #fafbfc; padding: 4px 0; margin-bottom: 10px;
}
.klock {
  display: flex; align-items: center; gap: 9px;
  padding: 8px 12px; font-size: 13px; color: var(--navy);
  position: relative;
}
/* Both designs of the piece, side by side, which is what the row claims. Small,
   because the row is a confirmation and the design cards below are the
   decision; the magnifier is there for a proper look. */
.klock-imgs { display: flex; gap: 4px; flex: none; }
.klock-imgs img {
  height: 42px; width: auto; max-width: 40px; object-fit: contain;
  display: block; border-radius: 3px; background: #fff;
}
/* THE SPACE THE DESIGN GOES IN. A dashed frame at the size of the real thing,
   so the row keeps its shape and the gap is something somebody can see rather
   than something they have to notice is absent. */
.klock-ph {
  width: 32px; height: 42px; flex: none;
  border: 1.5px dashed var(--rule-mid); border-radius: 3px;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; color: var(--grey-lt); background: #fcfcfd;
}
.klock-n { min-width: 0; overflow-wrap: anywhere; }
/* MORE SPECIFIC, NOT MERELY EARLIER. .dzoom is positioned absolute for the
   design cards and is declared after this block, so a bare .klock-z lost the
   position and the magnifier landed on top of the "both designs" text. Same
   lesson as the desktop type an hour ago: at equal specificity the later rule
   wins, and a media query or a good intention does not change that. */
.klock .klock-z {
  position: static; margin-left: 4px; flex: none;
  width: 24px; height: 24px; font-size: 13px;
}
.klock + .klock { border-top: 1px solid var(--rule); }
.klock-i {
  flex: none; width: 18px; height: 18px; border-radius: 50%;
  background: var(--navy); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; line-height: 1;
}
.klock-s {
  margin-left: auto; font-size: 11.5px; color: var(--grey-lt); white-space: nowrap;
  flex: none;
}

/* A GARMENT IN THE SET THAT NOBODY HAS DRAWN YET. Amber rather than red: red is
   for the rule that governs the choice, and this is not a rule, it is work
   outstanding. A manager should read it and carry on, not stop. */
.kpending {
  margin-top: 10px; padding: 9px 12px;
  border-left: 3px solid #B45309; border-radius: 0 8px 8px 0;
  background: #FFFBEB; color: #92400E;
  font-size: 12.5px; line-height: 1.55;
}
@media (min-width: 720px) { .kpending { font-size: 13.5px; } }

/* The FYI. Red because it is the sentence explaining why most of the kit has no
   question against it, and a manager who misses it thinks the form is broken.
   A tinted panel rather than red type on white: red text alone reads as an
   error, and nothing here has gone wrong. */
.kfyi {
  margin-top: 10px; padding: 10px 12px;
  border-left: 3px solid #B42318; border-radius: 0 8px 8px 0;
  background: #FEF3F2; color: #912018;
  font-size: 12.5px; line-height: 1.55;
}
@media (min-width: 720px) { .kfyi { font-size: 13.5px; } }

/* THE MAGNIFIER ON A DESIGN CARD, and the viewer it opens.
   A design card is a thumbnail of a kit, and a kit is what a squad wears for a
   season, so there has to be a way to actually look at it. The control is its
   own button rather than the picture, because the card already means "choose
   this" and one press should never mean two things. */
.dbtn { position: relative; }
.dzoom {
  position: absolute; top: 6px; right: 6px;
  width: 26px; height: 26px; border-radius: 7px;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.94); border: 1px solid var(--rule-mid);
  font-size: 15px; line-height: 1; color: var(--navy); cursor: zoom-in;
}
.dzoom:hover { background: #fff; border-color: var(--navy); }
.dbtn:hover .dzoom { border-color: var(--navy); }

.biglook {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(10,10,12,.82);
  display: flex; align-items: center; justify-content: center; padding: 16px;
}
.biglook-box {
  background: #fff; border-radius: 14px; max-width: 1000px; width: 100%;
  max-height: 92vh; display: flex; flex-direction: column; overflow: hidden;
}
.biglook-head {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; border-bottom: 1px solid var(--rule);
}
.biglook-t { font-weight: 700; font-size: 15px; flex: 1; }
.biglook-x {
  border: none; background: none; font-size: 26px; line-height: 1;
  cursor: pointer; color: var(--grey); padding: 0 4px;
}
.biglook-imgs {
  display: flex; gap: 10px; padding: 14px; overflow: auto;
  align-items: flex-start; justify-content: center; flex-wrap: wrap;
}
/* Tall enough to judge a design by, and each piece still its own shape. */
.biglook-imgs img { max-height: 62vh; max-width: 100%; width: auto; display: block; }
@media (max-width: 560px) {
  .biglook-imgs { flex-wrap: nowrap; }
  .biglook-imgs img { max-height: 52vh; }
}

/* ── THE NOTICE BOARD ──────────────────────────────────────────────
   The front page, for anybody who has not signed in. Romero, 28 August 2026:
   "act as slick visual notice board that suits the branding, tnza should set at
   the top".

   OTX2's own language rather than a new one: white paper, a black band, heavy
   uppercase type. What makes it a board rather than a form is that the dates
   and the sides are the content and the sign-in is a consequence of clicking
   something, instead of a form being the whole page. */
.boardhead { padding: 34px var(--pad) 6px; text-align: center; }
/* TNZA SITS ABOVE THE EVENT'S OWN NAME, because it is their tournament and OTX2
   runs the kit for it. The mark whole here, on white, at a size where the
   association's name under the ball is readable. */
.boardmark { display: block; height: 64px; width: auto; margin: 0 auto 18px; }
.boardhead h1 {
  font-size: 30px; font-weight: 800; letter-spacing: -.01em; margin: 0;
  line-height: 1.15;
}
.boardsub {
  margin: 8px auto 0; max-width: 46ch;
  font-size: 14px; color: var(--grey); line-height: 1.5;
}

/* THE DATES, AS DEADLINES. Three cards rather than a sentence, because the one
   that matters is the next one and a reader should find it without parsing a
   paragraph. */
.dates {
  display: grid; gap: 10px; padding: 22px var(--pad) 4px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  max-width: 860px; margin: 0 auto;
}
.date {
  border: 1px solid var(--rule-mid); border-left: 4px solid var(--navy);
  border-radius: 10px; padding: 13px 15px; background: #fff;
}
.date .dk {
  font-size: 10.5px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--grey);
}
.date .dv { font-size: 17px; font-weight: 700; margin-top: 3px; }
.date .dn { font-size: 12.5px; color: var(--grey); margin-top: 2px; }
.date .dw { font-size: 11.5px; color: var(--grey-lt); margin-top: 7px; line-height: 1.45; }
/* Ten days out it stops being a date and starts being a deadline. */
.date.soon { border-left-color: #B45309; }
.date.soon .dn { color: #B45309; font-weight: 700; }
.date.gone { border-left-color: var(--rule-mid); opacity: .62; }

.boardband {
  margin: 26px var(--pad) 0; padding: 9px 14px;
  background: var(--navy); color: #fff;
  font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  max-width: 860px; margin-left: auto; margin-right: auto;
}

/* THE SIDES. Same card as the signed-in row so the page a manager sees before
   and after signing in is recognisably one product, but bigger, because here it
   is the thing to press rather than a filter. */
.tiles {
  display: grid; gap: 12px; padding: 12px var(--pad) 0;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  max-width: 860px; margin: 0 auto;
}
.tile {
  border: 1px solid var(--rule); border-radius: 12px; overflow: hidden;
  background: var(--brand, var(--navy)); color: var(--ink-on, #fff);
  padding: 0; cursor: pointer; font: inherit; text-align: left;
  display: flex; flex-direction: column;
  transition: transform .12s ease, box-shadow .12s ease;
}
.tile:hover { transform: translateY(-2px); box-shadow: 0 6px 18px rgba(0,0,0,.16); }
.tile:active { transform: none; }
.tile.has-accent { border-bottom: 3px solid var(--accent); }
.tcrest {
  width: 100%; flex: none; aspect-ratio: 1 / 1;
  display: flex; align-items: center; justify-content: center;
  padding: 14px; overflow: hidden; box-sizing: border-box;
}
.tcrest img {
  display: block; max-width: 100%; max-height: 100%;
  width: auto; height: auto; object-fit: contain;
}
.ttype {
  font-size: 17px; font-weight: 800; line-height: 1.2; text-align: center;
  text-transform: uppercase; letter-spacing: .02em; overflow-wrap: anywhere;
}
.tcap {
  padding: 10px 12px; font-size: 13px; font-weight: 700;
  border-top: 1px solid rgba(255,255,255,.18);
}
.boardfoot {
  max-width: 860px; margin: 22px auto 0; padding: 0 var(--pad);
  font-size: 12.5px; color: var(--grey-lt); line-height: 1.6; text-align: center;
}
/* The way back out of a side's sign-in, to the board. */
.backboard {
  border: none; background: none; padding: 0 0 10px; font: inherit;
  font-size: 13px; font-weight: 600; color: var(--navy); cursor: pointer;
}

@media (max-width: 420px) {
  .boardhead { padding-top: 24px; }
  .boardmark { height: 52px; }
  .boardhead h1 { font-size: 24px; }
  .tiles { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 10px; }
}

/* THE KIT PICKERS on the contingent join form. The design buttons ARE the
   mockups, because nobody picks a kit off a radio labelled "design 1", and the
   person reading this has no account yet so the images come through the link's
   own guard. Sized by WIDTH and allowed to shrink: sized by height, a squarer
   file than the 1080x1380 these are drawn at pushes the second design off the
   edge of a phone, which is the one thing a picker made of pictures cannot
   afford. min-width: 0 on every link in the chain, or a flex item refuses to
   shrink below its content. */
.kpick { margin-top: 2px; }
.krow  { display: flex; gap: 10px; flex-wrap: wrap; }
.kbtn {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  flex: 1 1 150px; min-width: 0; padding: 11px 13px; min-height: 48px;
  border: 1.5px solid var(--rule-mid); border-radius: 10px; background: #fff;
  font: inherit; color: var(--navy); text-align: left; cursor: pointer;
}
.kbtn:hover { border-color: #98a2ad; }
.kbtn.on { border-color: var(--navy); background: var(--navy); color: #fff; cursor: default; }
.kbtn b { font-weight: 700; font-size: 13px; }
.kbtn .ksub { font-size: 11px; opacity: .72; }
.dbtn {
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  flex: 1 1 calc(50% - 5px); min-width: 0; max-width: 320px;
  padding: 10px; border: 1.5px solid var(--rule-mid); border-radius: 10px;
  background: #fff; font: inherit; color: var(--grey); cursor: pointer;
}
.dbtn:hover { border-color: #98a2ad; }
.dbtn.on { border-color: var(--navy); }
.dbtn.on b { color: var(--navy); }
.dbtn b { font-weight: 700; font-size: 12px; }
/* A SET, NOT A GARMENT. The card carries four or five pieces now rather than
   two views of one, so they share the width evenly and shrink together. flex
   1 1 0 with min-width 0 is what makes five items fit a 150px card at all:
   without the min-width each refuses to go below its intrinsic size and the
   row overflows the tile it is in. */
.dimgs { display: flex; gap: 4px; width: 100%; min-width: 0; align-items: flex-end; }
.dimgs img {
  flex: 1 1 0; min-width: 0; width: 100%; height: auto;
  max-height: 120px; object-fit: contain; display: block; border-radius: 3px;
}
@media (min-width: 720px) {
  /* Two sets side by side is the comparison, so on a desktop they get the room
     to actually be compared. */
  .dbtn { flex: 1 1 calc(50% - 6px); max-width: none; }
  .dimgs img { max-height: 170px; }
}

.joinrow { display: flex; align-items: center; gap: 10px; text-decoration: none;
  border: 1px solid rgba(128, 128, 128, .35); border-radius: 10px;
  padding: 15px 16px; min-height: 56px; color: inherit; }
.joinrow .jl { font-weight: 650; font-size: 16px; }
.joinrow .jr { margin-left: auto; font-size: 12.5px; opacity: .7; }
.joinrow:active { opacity: .6; }

/* THE SAME ROW WITH NOTHING TO OPEN. An entry link lists the contingent's teams
   so a manager can see whether their grade is already in, but it holds no sheet
   link for any of them, so the row must not read as a control: no press state,
   no pointer, and the name in the muted ink the rest of the page uses for
   information rather than action. Romero, 2 September 2026, on why the links
   are not there: "make sure everyones details stays with them individually". */
.joinrow-flat { cursor: default; border-style: solid;
  border-color: rgba(128, 128, 128, .18); }
.joinrow-flat:active { opacity: 1; }
.joinrow-flat .jl { font-weight: 550; opacity: .72; }
.joinrow-flat .jr { opacity: .55; }

/* DECLARING A SQUAD, 2026-08-21.
 *
 * A contingent link arrives at a page with nothing on it, because on the day it
 * is sent the contingent has entered nothing. The row that adds one has to read
 * as the primary thing on that screen rather than as a footer link, so it is
 * dashed instead of solid: an outline waiting to be filled rather than a squad
 * that already exists. Same 56px target as the rows above it. */
.joinadd {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  border: 1px dashed var(--navy); border-radius: 10px; background: none;
  padding: 15px 16px; min-height: 56px; color: var(--navy);
  font-weight: 650; font-size: 16px; cursor: pointer; margin-top: 8px;
}
.joinadd:active { opacity: .6; }
.joinadd .plus { font-size: 20px; line-height: 1; }

/* The declare form. Same .field furniture as everywhere else, plus a select,
   which the portal had not needed until a grade had to be picked from a list
   that is 22 long and grows. */
.field select {
  width: 100%; border: 1px solid var(--field); background: #fff;
  padding: 11px 12px; font-size: 16px; /* 16px, or iOS zooms the page on focus */
}
.field select:focus { outline: 2px solid var(--navy); outline-offset: -2px; border-color: var(--navy); }

/* Coach or manager, side by side. Two taps' worth of choice does not deserve a
   dropdown, and the answer decides which half of team_details gets filled. */
.whois { display: flex; gap: 8px; }
.whois label {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 7px;
  border: 1px solid var(--field); border-radius: 10px; padding: 12px;
  font-size: 15px; font-weight: 600; cursor: pointer; margin: 0;
  text-transform: none; letter-spacing: 0; color: inherit;
}
.whois label:has(input:checked) { border-color: var(--navy); box-shadow: inset 0 0 0 1px var(--navy); }
/* width:auto and flex:none, because .field input above sets width:100% for the
   text boxes and a radio inheriting that claims the whole row and shoves its
   own label to the far edge. It looked like a spacing bug and was a selector
   one. */
.whois input { margin: 0; width: auto; flex: none; padding: 0; border: 0; background: none; }

/* THE CONTINGENT'S DELIVERY ADDRESS. Above the teams, because it is true of all
   of them: one contingent, one place the kit lands. Set off by a rule rather
   than a box, so it reads as a fact about the contingent rather than as another
   thing to fill in before you can get on with entering a team. */
.delivery { margin: 18px 0 6px; padding-top: 14px; border-top: 1px solid var(--rule); }
.dl-head { font-size: 11px; font-weight: 700; color: var(--grey); text-transform: uppercase;
  letter-spacing: .06em; margin-bottom: 6px; }
.dl-now { font-size: 14px; white-space: pre-wrap; margin-bottom: 10px; }
.dl-now.dl-none { font-size: 13px; color: var(--grey); }
.delivery textarea {
  width: 100%; border: 1px solid var(--field); background: #fff;
  padding: 11px 12px; font-size: 16px; font-family: inherit; resize: vertical;
}
.delivery textarea:focus { outline: 2px solid var(--navy); outline-offset: -2px; border-color: var(--navy); }

/* ── DESKTOP TYPE ─────────────────────────────────────────────────
   Romero, 28 August 2026: "make the font more bold an easier on the eyes on
   desktop mode".

   Everything here was sized for the hard case, which is a phone on a sideline,
   and then used unchanged on a 1400px monitor where 11px uppercase labels and
   12px hints are genuinely hard work. The phone sizes are untouched: this only
   lifts from 720px up, where there is room and where nobody is squinting at a
   screen held at arm's length.

   The 16px on inputs is load bearing on a phone, because anything smaller makes
   iOS zoom the page on focus, so it only ever goes UP from here. */
/* LAST IN THE FILE ON PURPOSE. These override base rules at the same
   specificity, and a media query adds none, so the only thing deciding the
   winner is order. Written above the rules it overrode, .hint and .kbtn b both
   silently lost. */
@media (min-width: 720px) {
  .field label { font-size: 12.5px; letter-spacing: .05em; font-weight: 700; }
  .field textarea,
  .field select,
  .field input { font-size: 16.5px; padding: 13px 14px; }
  /* Both of the places a hint actually lives, because .hint on its own loses
     to .field .hint and .relink .hint, which are more specific rather than
     merely earlier. Order fixed the ones that were only earlier; these two
     needed the same specificity to match. */
  .field .hint,
  .relink .hint { font-size: 13.5px; line-height: 1.6; }
  .lede { font-size: 15.5px; line-height: 1.65; }
  .band { font-size: 12.5px; letter-spacing: .11em; }
  .footnote { font-size: 13px; line-height: 1.65; }
  .btn { font-size: 15.5px; padding: 13px 18px; font-weight: 700; }
  /* The kit pickers read as headings on a desktop form, so they carry a little
     more weight than the fields around them rather than the same. */
  .kbtn b { font-size: 15px; }
  .kbtn .ksub { font-size: 12px; }
  .dbtn b { font-size: 13.5px; }
  .joinrow .jl { font-size: 17px; }
  .joinrow .jr { font-size: 13.5px; }
}

/* WHEN THE LOCKED ROWS ARE THE WHOLE ANSWER.
 *
 * Romero, 30 Aug 2026: "remove that line an just enlarge these 2". On a men's
 * reversible set there is no design to choose, so these two rows stop being a
 * preamble to the real question and become the answer itself. At the size they
 * were drawn for sitting above a picker, they read as a footnote to a question
 * that is no longer there. */
.klocked-only .klock { padding: 12px 14px; gap: 14px; }
.klocked-only .klock-imgs img,
.klocked-only .klock-ph { width: 74px; height: 74px; }
.klocked-only .klock-n { font-size: 15px; font-weight: 600; }
.klocked-only .klock-s { font-size: 12.5px; }
.klocked-only .klock-i { transform: scale(1.15); }

/* The per-squad delivery line on a contingent's squad list. Quiet, on its own
   line under the squad name: it is the lead's oversight, not the headline. */
.joinrow .jw { display: block; font-size: 12px; color: var(--txt-3, #6b7280);
               font-weight: 400; margin-top: 2px; }


/* WHAT IS WAITING ON TNZA.
 *
 * Gate 3 had no screen for three weeks: the only way to reach it was one
 * squad's own proof at a time. Orion, relayed 1 September 2026: TNZA "oversees
 * the contingent" and is "approving the contingent orders", so this is grouped
 * by contingent and reads as a worklist rather than a gallery. */
.tqlist { display: block; padding: 12px var(--pad) 0; max-width: 860px; margin: 0 auto; }
.tq-head { padding: 4px 0 14px; }
.tq-head h2 { margin: 0 0 4px; font-size: 19px; }
.tq-c { border: 1px solid #e3e5e9; border-radius: 10px; margin-bottom: 12px; }
.tq-ch {
  padding: 10px 14px; font-weight: 650; font-size: 13px;
  border-bottom: 1px solid #e3e5e9; background: #f7f8fa;
  border-radius: 10px 10px 0 0;
}
.tq-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px; border-top: 1px solid #eef0f3;
}
.tq-row:first-of-type { border-top: none; }
.tq-body { flex: 1; min-width: 0; }
/* .btn is width:100% by design everywhere else in this portal, which inside a
   flex row eats the whole row and squeezes the squad's name to nothing. Both
   buttons here sit beside the text, not under it. */
.tq-row .btn { flex: 0 0 auto; width: auto; display: inline-block;
  padding: 10px 20px; font-size: 14px; border-radius: 8px; }
.tq-look { margin-top: 7px; }
.tq-look .linky { font-size: 13px; }
.tq-name { font-weight: 600; font-size: 15px; }
.tq-meta { font-size: 12.5px; color: #6b7280; margin-top: 2px; }
/* Why a squad cannot be approved. Said above the button rather than only when
   it is pressed, because a refusal after the fact reads as a broken screen. */
.tq-block { font-size: 12.5px; color: #9B1226; margin-top: 5px; }
/* True and not blocking: an approved squad with nowhere to ship still gets
   made, and then sits. */
.tq-warn { font-size: 12.5px; color: #8a6d1c; margin-top: 5px; }

/* TNZA in one place (15 Sep 2026): the contingent header carries Add a team on
   the right, approved teams fold behind a quiet toggle, and Change team is a
   quiet button because it undoes two signatures. */
.tq-event { margin-bottom: 26px; }
.tq-chflex { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.tq-chflex .linky { font-size: 13px; font-weight: 600; white-space: nowrap; }
.tq-empty { color: #6b7280; font-size: 13px; }
.tq-more { display: block; width: 100%; text-align: left; background: none; border: 0;
  border-top: 1px solid #eef0f3; padding: 10px 14px; font-size: 13px; color: #374151; cursor: pointer; }
.tq-more:hover { background: #f7f8fa; }
.tq-row .btn.tq-quiet { background: #fff; color: #111; border: 1px solid #cbd5e1; }
.tq-row a.btn { text-decoration: none; text-align: center; }

@media (max-width: 620px) {
  .tq-row { flex-wrap: wrap; }
  .tq-body { flex-basis: 100%; }
  .tq-row .btn { flex: 1 1 auto; }
}
