/* judo.lt portal — a working register for the federation and its clubs.
   Ink-and-gold to match the public site, but tuned for people who will spend
   real hours in here: quiet chrome, one spacing scale, one type scale, press
   feedback on everything you can press, and a light mode for daylight offices. */

/* ---------------------------------------------------------------- tokens -- */
:root {
  color-scheme: dark light;

  /* Surfaces climb from the page towards the viewer. */
  --ink:  #07090d;
  --ink2: #0d1117;
  --ink3: #131926;
  --line:      rgba(242, 238, 230, .10);
  --line-firm: rgba(242, 238, 230, .18);

  --fg:  #f2eee6;
  --fg2: #c9c8c2;
  --mut: #8d95a3;

  --gold:     #fdb913;
  --gold-ink: #07090d;      /* text that sits on gold */
  --red:      #ff5c65;
  --ok:       #45c07e;

  /* One spacing scale. Every gap in this file comes from it. */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 24px; --s6: 32px; --s7: 48px; --s8: 64px;

  --r-sm: 8px; --r-md: 12px; --r-lg: 16px; --r-full: 999px;

  /* Motion. Entering and pressing use the same strong ease-out; nothing here
     runs longer than 220ms, because every one of these is seen daily. */
  --e-out: cubic-bezier(.22, 1, .36, 1);
  --t-press: 140ms;
  --t-ui: 200ms;

  --header-h: 60px;
}

@media (prefers-color-scheme: light) {
  :root {
    --ink:  #f7f6f3;
    --ink2: #ffffff;
    --ink3: #f0eeea;
    --line:      rgba(7, 9, 13, .10);
    --line-firm: rgba(7, 9, 13, .20);

    --fg:  #14181f;
    --fg2: #3a4049;
    --mut: #61697a;

    --gold:     #ac7600;   /* the public site's daylight gold — #fdb913 fails contrast on white */
    --gold-ink: #ffffff;
    --red:      #b21e27;
    --ok:       #056b42;
  }
}

/* ------------------------------------------------------------------ base -- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--ink);
  color: var(--fg);
  font: 400 16px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--gold); text-underline-offset: 2px; }

/* One focus ring for everything, keyboard only, so a mouse user never sees a
   ring they did not ask for and a keyboard user never loses their place. */
:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

.skip {
  position: absolute; left: var(--s3); top: var(--s3); z-index: 20;
  padding: var(--s3) var(--s4); border-radius: var(--r-sm);
  background: var(--gold); color: var(--gold-ink);
  font-size: 14px; font-weight: 600; text-decoration: none;
  transform: translateY(-200%);
}
.skip:focus-visible { transform: none; }

/* ------------------------------------------------------------------ type -- */
/* Tracking is size-specific: large text reads too loose at 0, small caps too
   tight. Nothing here inherits one blanket letter-spacing. */
h1 {
  margin: 0 0 var(--s5);
  font-size: clamp(24px, 1.1rem + 1vw, 30px);
  line-height: 1.15;
  letter-spacing: -.021em;
  font-weight: 700;
}
h2 {
  margin: var(--s6) 0 var(--s3);
  font-size: 17px;
  line-height: 1.3;
  letter-spacing: -.008em;
  font-weight: 650;
}
p { margin: 0 0 var(--s3); }
p:last-child { margin-bottom: 0; }

.muted { color: var(--mut); }
.lede  { color: var(--fg2); max-width: 60ch; }

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .92em;
  padding: 1px 5px;
  border-radius: 5px;
  background: var(--ink3);
  border: 1px solid var(--line);
}

/* --------------------------------------------------------------- chrome --- */
/* The bar floats over the content rather than owning a solid strip of the
   page, and it stays put so a long club register never means scrolling back
   up to change page. */
.top {
  position: sticky; top: 0; z-index: 10;
  background: color-mix(in srgb, var(--ink2) 78%, transparent);
  backdrop-filter: blur(20px) saturate(170%);
  -webkit-backdrop-filter: blur(20px) saturate(170%);
  border-bottom: 1px solid var(--line);
}
.top-in {
  max-width: 1040px; margin: 0 auto;
  padding: var(--s2) var(--s5);
  display: flex; align-items: center; gap: var(--s5); flex-wrap: wrap;
  min-height: var(--header-h);
}

.brand {
  display: inline-flex; align-items: baseline; gap: .45em;
  font-weight: 800; font-size: 15px;
  letter-spacing: .13em; text-transform: uppercase;
  text-decoration: none; color: var(--gold);
  white-space: nowrap;
}
.brand span { color: var(--mut); font-weight: 500; letter-spacing: .1em; }

.nav { display: flex; gap: var(--s1); margin-right: auto; flex-wrap: wrap; }
.nav a {
  display: inline-flex; align-items: center;
  min-height: 40px; padding: 0 var(--s3);
  border-radius: var(--r-sm);
  font-size: 14px; font-weight: 500;
  color: var(--fg2); text-decoration: none;
}
.nav a.on { background: var(--ink3); color: var(--gold); font-weight: 600; }

.out { display: flex; align-items: center; gap: var(--s3); }
.who {
  color: var(--mut); font-size: 13px;
  max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Signing out is not the thing anyone came here to do, so it does not get to
   be the loudest control on the page. */
.out button {
  min-height: 36px; padding: 0 var(--s3);
  font-size: 13px; font-weight: 500;
  color: var(--mut); background: transparent; border-color: transparent;
}

/* ---------------------------------------------------------------- layout -- */
.wrap {
  flex: 1;
  width: 100%; max-width: 1040px; margin: 0 auto;
  padding: var(--s6) var(--s5) var(--s8);
}
/* Signed out, there is one card and nothing else — centre it rather than
   pinning it under the bar with a screen of dead space below. */
body.auth .wrap { display: grid; align-content: center; justify-items: stretch; }

.foot {
  padding: var(--s5);
  text-align: center;
  color: var(--mut); font-size: 13px;
}

/* ----------------------------------------------------------------- cards -- */
.card {
  background: var(--ink2);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s5);
  margin-bottom: var(--s4);
}
.card > :first-child { margin-top: 0; }
.card > :last-child  { margin-bottom: 0; }
.card.narrow { max-width: 460px; margin-inline: auto; }
.card.wide   { max-width: 620px; margin-inline: auto; }

/* An anchored club must not land under the sticky bar. */
.card[id] { scroll-margin-top: calc(var(--header-h) + var(--s5)); }

/* A wide table scrolls inside its own box; the page never slides sideways.
   This lives on an explicit wrapper, not on every card, so a form card keeps
   its overflow visible. */
.scroll { overflow-x: auto; overscroll-behavior-x: contain; }

/* ----------------------------------------------------------------- forms -- */
/* A field is label + control + hint + error, kept together as one block, with
   8px inside the pair and 24px to the next one so a label always reads as
   belonging to the box beneath it and not the one above. */
.field { margin-bottom: var(--s5); }
.field > label, label { display: block; font-size: 13px; color: var(--mut); }
label { margin-bottom: var(--s5); }
.field > label { margin-bottom: 0; }
.req { color: var(--gold); }

input, select, textarea {
  display: block; width: 100%;
  margin-top: var(--s2);
  padding: 11px var(--s3);
  min-height: 44px;
  /* 16px keeps iOS from zooming the page when a field takes focus. */
  font: inherit; font-size: 16px;
  color: var(--fg);
  background: var(--ink3);
  border: 1px solid var(--line-firm);
  border-radius: var(--r-sm);
  transition: border-color var(--t-ui) ease, box-shadow var(--t-ui) ease;
}
input::placeholder, textarea::placeholder { color: var(--mut); opacity: 1; }

/* Fields show focus on click too — you need to see where you are typing. */
input:focus, select:focus, textarea:focus {
  border-color: var(--gold);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--gold) 22%, transparent);
}
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: none; }

.hint { display: block; margin-top: var(--s1); font-size: 12px; color: var(--mut); }
.err  { display: block; margin-top: var(--s1); font-size: 12px; color: var(--red); font-weight: 500; }
input[aria-invalid="true"] { border-color: var(--red); }

/* Row gap comes from the label's own margin so a field and its label stay
   visibly bound together — 8px inside the pair, 24px between pairs. */
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); column-gap: var(--s5); }
.grid > h2, .grid > .full { grid-column: 1 / -1; }
.grid > h2 { margin-top: var(--s5); }

fieldset { margin: 0 0 var(--s2); padding: 0; border: 0; }
legend { padding: 0; }

/* --------------------------------------------------------------- buttons -- */
button, .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  min-height: 44px; padding: 0 var(--s5);
  font: inherit; font-size: 14px; font-weight: 600;
  color: var(--fg);
  background: var(--ink3);
  border: 1px solid var(--line-firm);
  border-radius: var(--r-sm);
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--t-press) var(--e-out),
              background-color var(--t-ui) ease,
              border-color var(--t-ui) ease,
              color var(--t-ui) ease;
}
button.primary, .btn.primary {
  background: var(--gold); color: var(--gold-ink); border-color: var(--gold); font-weight: 700;
}
/* Suspending a club is not the same kind of act as saving a phone number, and
   it should not look like one. */
button.danger {
  color: var(--red);
  background: transparent;
  border-color: color-mix(in srgb, var(--red) 45%, transparent);
}
.quiet { background: transparent; border-color: transparent; color: var(--mut); }

/* Every pressable thing answers on the press, not on the release. */
button:active, .btn:active, .filters a:active { transform: scale(.97); }
.tile:active { transform: scale(.985); }

@media (hover: hover) and (pointer: fine) {
  .nav a:hover { background: var(--ink3); color: var(--fg); }
  .out button:hover, .quiet:hover { color: var(--fg); border-color: var(--line-firm); }
  button:hover, .btn:hover { border-color: var(--gold); }
  button.primary:hover { background: color-mix(in srgb, var(--gold) 88%, var(--fg)); }
  button.danger:hover { border-color: var(--red); background: color-mix(in srgb, var(--red) 12%, transparent); }
  .tile:hover { border-color: var(--line-firm); background: var(--ink3); }
  .filters a:hover { border-color: var(--line-firm); }
  .filters a.on:hover { border-color: var(--gold); }
}

/* --------------------------------------------------------------- flashes -- */
.flash {
  display: flex; align-items: flex-start; gap: var(--s3);
  padding: var(--s3) var(--s4);
  margin: 0 0 var(--s4);
  border-radius: var(--r-md);
  font-size: 14px;
  background: color-mix(in srgb, var(--ok) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--ok) 40%, transparent);
}
.flash.bad {
  background: color-mix(in srgb, var(--red) 13%, transparent);
  border-color: color-mix(in srgb, var(--red) 45%, transparent);
}
.flash::before { content: "✓"; font-weight: 700; color: var(--ok); line-height: 1.55; }
.flash.bad::before { content: "!"; color: var(--red); }

/* ----------------------------------------------------------------- tiles -- */
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--s3); margin-bottom: var(--s5); }
.tile {
  display: block; padding: var(--s5);
  background: var(--ink2); border: 1px solid var(--line); border-radius: var(--r-lg);
  text-decoration: none; color: var(--fg);
  transition: transform var(--t-press) var(--e-out), background-color var(--t-ui) ease, border-color var(--t-ui) ease;
}
.tile b {
  display: block;
  font-size: 34px; line-height: 1.05; letter-spacing: -.03em; font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--gold);
}
.tile.zero b { color: var(--mut); }
.tile span { display: block; margin-top: var(--s1); color: var(--mut); font-size: 13px; }

/* ---------------------------------------------------------------- tables -- */
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th {
  text-align: left; padding: var(--s2) var(--s3);
  color: var(--mut); font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .1em;
  border-bottom: 1px solid var(--line-firm);
  white-space: nowrap;
}
td { padding: var(--s3); border-bottom: 1px solid var(--line); vertical-align: top; font-variant-numeric: tabular-nums; }
tbody tr:last-child td { border-bottom: 0; }

/* ----------------------------------------------------------------- clubs -- */
.club-head { display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap; margin-bottom: var(--s4); }
.club-head h2 { margin: 0; font-size: 19px; letter-spacing: -.014em; }
.club-head .where { color: var(--mut); font-size: 14px; }

.pill {
  display: inline-flex; align-items: center;
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .08em;
  padding: 3px 10px; border-radius: var(--r-full);
  border: 1px solid currentColor;
  white-space: nowrap;
}
.pill.pending   { color: var(--gold); }
.pill.active    { color: var(--ok); }
.pill.suspended { color: var(--red); }

/* A quieter sibling of .pill, for a marker beside a value ("dabartinis", "tai
   jūs") or a count in a summary row ("Bus įrašyta: 12"). Sentence case and no
   letter-spacing, because these read as words rather than as statuses.

   It was used on six pages before it existed as a rule, so "tai jūs" beside a
   manager's name rendered as ordinary body text — the marker was there and
   marked nothing. .tag.warn picks up the gold from the standalone .warn rule. */
.tag {
  display: inline-flex; align-items: center; gap: var(--s1);
  font-size: 12px; font-weight: 500;
  padding: 2px 8px; border-radius: var(--r-sm);
  border: 1px solid var(--line-firm);
  background: var(--ink3);
  color: var(--fg2);
  white-space: nowrap;
}

/* A fixed label column so the values line up down the whole page, not just
   within one card. Ragged columns between cards read as carelessness. */
.facts { margin: 0 0 var(--s5); font-size: 14px; }
.facts dt { color: var(--mut); }
.facts dd { margin: 0 0 var(--s3); font-variant-numeric: tabular-nums; }
@media (min-width: 620px) {
  .facts { display: grid; grid-template-columns: 180px 1fr; gap: var(--s2) var(--s4); }
  .facts dd { margin: 0; }
}

.actions { display: flex; gap: var(--s2); flex-wrap: wrap; align-items: center; }
/* A free-text field that is optional should not be the widest thing in the
   row. Capped, so the buttons stay near the note they annotate. */
.actions .note { flex: 1 1 220px; min-width: 0; max-width: 420px; margin-top: 0; }
.actions .spacer { flex: 1 1 auto; }

.searchbar { margin: 0 0 var(--s3); }
.searchbar .note { max-width: 460px; }
.count { margin: 0 0 var(--s5); }
.count strong { color: var(--fg); font-variant-numeric: tabular-nums; }

.filters { display: flex; gap: var(--s2); flex-wrap: wrap; margin: 0 0 var(--s5); }
.filters a {
  display: inline-flex; align-items: center;
  min-height: 40px; padding: 0 var(--s4);
  border: 1px solid var(--line-firm); border-radius: var(--r-full);
  color: var(--fg2); text-decoration: none; font-size: 13px; font-weight: 500;
  transition: transform var(--t-press) var(--e-out), background-color var(--t-ui) ease, border-color var(--t-ui) ease, color var(--t-ui) ease;
}
.filters a.on { background: var(--gold); color: var(--gold-ink); border-color: var(--gold); font-weight: 600; }

/* An empty screen should say what to do next, not just that there is nothing
   here. This is the first screen the federation ever sees. */
.empty { padding: var(--s6) var(--s5); text-align: center; }
.empty h2 { margin: 0 0 var(--s2); }
.empty p { margin: 0 auto var(--s4); max-width: 46ch; color: var(--mut); font-size: 14px; }
.empty .copyrow {
  display: flex; gap: var(--s2); flex-wrap: wrap; justify-content: center; align-items: center;
  max-width: 520px; margin: 0 auto;
}
.empty .copyrow input { flex: 1 1 240px; margin-top: 0; text-align: center; font-size: 14px; }

/* A page whose title carries one primary action. */
.page-head { display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap; margin-bottom: var(--s5); }
.page-head h1 { margin: 0; margin-right: auto; }

.crumb { font-size: 14px; margin: 0 0 var(--s3); }
.crumb a { text-decoration: none; }

.club-head .edit { margin-left: auto; font-size: 13px; white-space: nowrap; }

.warn { color: var(--gold); }

/* Whether a club can actually sign in is a fact about the club, so the login
   block sits between its details and the decisions taken about it. Dashed,
   because it is scaffolding: once the club has an account it disappears. */
.invite {
  padding: var(--s4);
  margin: 0 0 var(--s4);
  border: 1px dashed var(--line-firm);
  border-radius: var(--r-md);
}
.invite > .sub { margin: 0 0 var(--s3); }
.invite .actions .sub { margin: 0; }

/* Lets a one-button form take part in the flex row around it instead of
   becoming a block that breaks the line. */
form.inline { display: contents; }

/* The read-only club summary on the invite-claim form. */
.club-facts { padding: var(--s4); background: var(--ink3); border-radius: var(--r-md); }

/* Visible to assistive tech, not on screen. */
.sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* A quiet line of explanation under a section heading. */
.sub { font-size: 14px; margin-top: calc(var(--s2) * -1); }
.mt  { margin-top: var(--s5); }

/* Honeypot: positioned away rather than display:none, which some bots skip.
   aria-hidden and tabindex="-1" keep it away from assistive tech and the tab
   order, so nobody using the form ever meets it. */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* Revealed by portal.js when a destructive button is pressed once. */
[hidden] { display: none !important; }
.confirm { display: flex; gap: var(--s2); flex-wrap: wrap; align-items: center; font-size: 14px; }
.confirm .q { color: var(--fg2); }

/* --------------------------------------------------- accessibility prefs -- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  button:active, .btn:active, .tile:active, .filters a:active { transform: none; }
}

@media (prefers-reduced-transparency: reduce) {
  .top { background: var(--ink2); backdrop-filter: none; -webkit-backdrop-filter: none; }
}

@media (prefers-contrast: more) {
  :root { --line: rgba(242,238,230,.28); --line-firm: rgba(242,238,230,.5); --mut: #b3bac6; }
  .top { background: var(--ink2); backdrop-filter: none; }
  .card, .tile { border-width: 1px; }
}
@media (prefers-contrast: more) and (prefers-color-scheme: light) {
  :root { --line: rgba(7,9,13,.28); --line-firm: rgba(7,9,13,.5); --mut: #3d4453; }
}

/* ------------------------------------------------------------- narrow UI -- */
@media (max-width: 560px) {
  .top-in { padding: var(--s2) var(--s4); gap: var(--s3); }
  .wrap { padding: var(--s5) var(--s4) var(--s7); }
  .card { padding: var(--s4); border-radius: var(--r-md); }
  .who { display: none; }              /* the club name is on the page already */
  .nav { width: 100%; order: 3; margin-right: 0; }
  .nav a { flex: 1 1 0; justify-content: center; }
  .out { margin-left: auto; }
  /* Four stat tiles stacked one per row push the actual work an entire screen
     down. At 180px they never fit two across on a phone; at 140px they do. */
  .tiles { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: var(--s2); }
  .tile { padding: var(--s4); }
  .actions .note { flex-basis: 100%; max-width: none; }
  .club .actions button { flex: 1 1 140px; }
  .full > button, .card.narrow button[type=submit] { width: 100%; }
  .page-head { gap: var(--s3); }
  .page-head .btn { width: 100%; }
  .club-head .edit { margin-left: 0; }
}

/* Role checkboxes: a person can hold several at once, so they read as a set
   rather than a list of unrelated fields. */
.roles { grid-column: 1 / -1; border: 1px solid rgba(242,238,230,.16); border-radius: 6px; padding: 12px 14px; margin: 0 0 14px; }
.roles legend { color: var(--mut); font-size: 13px; padding: 0 6px; }
.check { display: inline-flex; align-items: center; gap: 8px; margin: 0 18px 0 0; min-height: 44px; font-size: 14px; color: var(--fg); }
.check input { width: auto; margin: 0; min-height: 0; }

/* A set of .check boxes as one labelled group — what a badge grants, what an
   import will write. A <fieldset> because these answer one question together,
   and a screen reader should say the question before the first option. */
.checks {
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: var(--s2) var(--s3) 0;
  margin: 0 0 var(--s3);
  min-width: 0;               /* a fieldset will not shrink inside flex without it */
}
.checks legend {
  padding: 0 var(--s2);
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .08em;
  color: var(--mut);
}
/* Denser than a standalone .check: nine of them in a table cell, where the 44px
   row height that suits a lone control becomes a column three screens long. The
   whole label stays the target, so it is still comfortably tappable. */
.checks .check { min-height: 32px; margin-right: var(--s3); font-size: 13px; }

/* The grant form stacks: the boxes, then the note, then the buttons. Inline
   .actions puts everything on one line, which is right for two buttons and wrong
   for a fieldset of nine. */
.grant { display: block; }
.grant .note { margin: 0 0 var(--s2); }

/* ------------------------------------------------------------ fee tables -- */
/* A warning is not a failure: no current season yet is something to fix, not
   something that went wrong, so it reads gold rather than red. */
.flash.warn {
  background: color-mix(in srgb, var(--gold) 12%, transparent);
  border-color: color-mix(in srgb, var(--gold) 40%, transparent);
}
.flash.warn::before { content: "!"; color: var(--gold); }

.pill.current { color: var(--gold); }

/* The season whose prices are open below. */
tr.on > td { background: color-mix(in srgb, var(--gold) 7%, transparent); }

/* A price cell is narrow on purpose — it holds "12.00", not a sentence — but
   it still has to be tappable, so the height comes from the shared control
   rules and only the width is trimmed. */
.fee-grid input[type=text] { width: 6.5em; text-align: right; }
.fee-grid td { vertical-align: middle; }

/* The availability box is alone in its column, so the label around it has to
   be the target — a bare 13px checkbox is not something a thumb can hit. The
   box itself grows too, because a 44px label around a speck still looks like a
   speck. */
.fee-grid .check { margin: 0; min-width: 44px; justify-content: center; }
.fee-grid input[type=checkbox], .roles input[type=checkbox] { width: 20px; height: 20px; }

/* A link inside a table row IS the row's action, and its text is two words, so
   the hit area comes from padding. The matching negative margin keeps the row
   the height it was: without it every table on the portal would grow by 24px
   per row for a target nobody can see. */
td a, p.sub > a, .card > p > a { display: inline-block; padding: 13px 4px; margin: -13px -4px; }
/* A row's actions are NOT the .actions flex row: display:flex on a <td> stops
   it being a table cell, so it no longer stretches to the row's height and a
   tall row shows a white gap beneath it. The cell stays a cell; its contents
   sit inline. */
.row-actions > form { display: inline-block; vertical-align: middle; }
.row-actions > a { vertical-align: middle; margin-right: var(--s2); }

/* The copy-forward control is a different decision from the prices above it,
   so it gets a rule and some air rather than sitting against the save button. */
.copy-fees {
  margin-top: var(--s5); padding-top: var(--s4);
  border-top: 1px solid var(--line);
}

/* A table that scrolls says so: the shadow appears only when there is more to
   the right and slides away as it is scrolled, because background-attachment
   local pins one layer to the content and leaves the other on the box. No JS,
   and nothing to keep in sync. */
.scroll {
  background:
    linear-gradient(to right, var(--ink2) 30%, transparent) left / 24px 100% no-repeat local,
    linear-gradient(to left, var(--ink2) 30%, transparent) right / 24px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%, rgba(0,0,0,.18), transparent) left / 12px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, rgba(0,0,0,.18), transparent) right / 12px 100% no-repeat scroll;
}

/* Below 560px a six-column table cannot be rescued by scrolling sideways: the
   columns that matter — the price, the action — are exactly the ones that fall
   off the edge, and nothing on screen says they are there. So the supporting
   columns fold into the first cell and the row keeps what the page is for. */
.folded { display: none; }
/* A date broken across lines is not a date. Only the parts that must stay
   whole get this — making the entire folded line unbreakable would hand the
   first column all the width and push the row's action off the screen, which
   is the problem folding was meant to solve. */
.nb { white-space: nowrap; }
@media (max-width: 560px) {
  .fold { display: none; }
  .folded {
    display: block; margin-top: 3px;
    color: var(--mut); font-size: 12px; font-weight: 400;
  }
  /* The price is the point of this grid, so it keeps its own column and the
     rest of the row gives back the width it needs. */
  .fee-grid input[type=text] { width: 4.5em; }
  .fee-grid th, .fee-grid td { padding-left: var(--s2); padding-right: var(--s2); }
  .fee-grid th { letter-spacing: .02em; }
}

/* ------------------------------------------------------------ touch size -- */
/* The chrome is sized for a mouse: 40px nav pills and a deliberately quiet
   36px sign-out read well on a desktop and are a few pixels short of what a
   thumb needs. Rather than making everything bigger everywhere, the minimum
   only applies where the pointer is coarse — a phone or a tablet — so the
   desktop keeps its proportions and a finger still gets 44px.
   The federation runs the renewal window from a phone as often as not. */
@media (pointer: coarse) {
  .nav a, .filters a { min-height: 44px; }
  .out button { min-height: 44px; }
  .brand { min-height: 44px; align-items: center; }
}

/* ------------------------------------------------------------ setup steps -- */
/* The dashboard's readiness chain. Numbered because the order is a real
   dependency — a price cannot exist before the category it prices — and the
   number becomes a tick once the step is done, so the eye lands on the first
   thing still open rather than having to read all of them. */
.steps { list-style: none; margin: 0; padding: 0; }
.steps li {
  display: flex; align-items: flex-start; gap: var(--s3);
  padding: var(--s3) 0;
  border-top: 1px solid var(--line);
}
.steps li:first-child { border-top: 0; }

.steps .mark {
  flex: 0 0 26px; height: 26px; margin-top: 2px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--r-full); border: 1px solid var(--line-firm);
  font-size: 12px; font-weight: 700; color: var(--mut);
}
.steps .done .mark { border-color: var(--ok); color: var(--ok); }
.steps .todo .mark { border-color: var(--gold); color: var(--gold); }

.steps .what { flex: 1 1 auto; min-width: 0; }
.steps .what strong { display: block; font-size: 15px; }
.steps .what .sub { display: block; margin-top: 2px; font-size: 13px; }
.steps .done .what strong { color: var(--fg2); font-weight: 600; }

/* The action stays on the row it belongs to, and reaches 44px like every other
   link in a list. */
.steps .go {
  flex: 0 0 auto; align-self: center;
  display: inline-flex; align-items: center; min-height: 44px;
  padding: 0 var(--s3);
  font-size: 13px; font-weight: 500; white-space: nowrap;
}

@media (max-width: 560px) {
  /* Stacked, because a label, a sentence of detail and an action do not fit
     across 390px without one of them being unreadable. */
  .steps li { flex-wrap: wrap; }
  .steps .go { margin-left: calc(26px + var(--s3)); padding-left: 0; }
}

/* A heading that introduces a run of cards or tiles rather than sitting inside
   one, so the dashboard reads as sections instead of one long stack. */
h2.section {
  margin: var(--s6) 0 var(--s3);
  font-size: 13px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .1em; color: var(--mut);
}

/* The federation's standing message to clubs, set in /nustatymai. Marked out
   from the club's own cards so it does not read as one of the club's facts. */
.card.notice { border-left: 3px solid var(--gold); }
.card.notice h2 { color: var(--gold); }

/* The dashboard's find box. It is a card so it reads as the page's first
   action rather than a filter on something below it, and the label sits above
   the row because a placeholder disappears the moment anyone types. */
/* The register's search row: one line on a desktop rather than the box, then
   a full-width select, then the button on three. The select is capped because
   a club name is short and letting it eat the remaining width made the row
   read as two unrelated controls. */
.searchbar select { flex: 0 1 220px; min-width: 0; }
.searchbar .note { flex: 2 1 260px; }
.searchbar .found { flex-basis: 100%; margin: var(--s2) 0 0; }

.find { margin-bottom: var(--s5); }
.find > label { font-size: 13px; color: var(--mut); margin-bottom: var(--s2); }
.find .actions { margin-bottom: var(--s2); }
.find .note { flex: 1 1 320px; max-width: none; }

/* ------------------------------------------------------------ licence card -- */
/* The card is looked at on a phone held up at a door, so the name and the code
   are the two things that have to be legible across a metre. */
.licence { padding: 0; overflow: hidden; }
.licence.void { opacity: .96; }

.lic-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
  padding: var(--s4) var(--s5);
  border-bottom: 1px solid var(--line);
}
.lic-head .org {
  font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--gold);
}

.lic-body { display: flex; gap: var(--s5); padding: var(--s5); flex-wrap: wrap; }
.lic-who { flex: 1 1 260px; min-width: 0; }
.lic-who h2 { margin: 0 0 var(--s4); font-size: 24px; letter-spacing: -.02em; }
.lic-no { font-variant-numeric: tabular-nums; letter-spacing: .04em; }

/* The QR sits on white whatever the page does, because a scanner needs the
   contrast the specification assumes and a dark card would defeat it. */
.lic-qr { flex: 0 0 auto; text-align: center; }
.lic-qr svg { display: block; border-radius: var(--r-sm); background: #fff; }
.lic-qr .sub { margin-top: var(--s2); font-size: 11px; word-break: break-all; }

/* A licence that is not valid must not be mistakable for one that is, at a
   glance, from a metre away, by someone who is not really looking. */
.licence.void .lic-body { background: repeating-linear-gradient(
    135deg, transparent, transparent 10px,
    color-mix(in srgb, var(--red) 6%, transparent) 10px,
    color-mix(in srgb, var(--red) 6%, transparent) 20px); }

/* ----------------------------------------------------------- the verdict -- */
.verdict-line { display: flex; align-items: center; gap: var(--s3); margin: 0 0 var(--s4); font-size: 20px; }
.verdict-line .mark {
  flex: 0 0 34px; height: 34px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--r-full); border: 2px solid currentColor; font-weight: 700;
}
.verdict.valid .verdict-line { color: var(--ok); }
.verdict.void .verdict-line { color: var(--red); }
.verdict.valid { border-left: 3px solid var(--ok); }
.verdict.void { border-left: 3px solid var(--red); }

/* The select-all column on the licence list stays narrow. */
th.tick, td.tick { width: 44px; padding-right: 0; }
td.tick .check { margin: 0; min-width: 44px; justify-content: center; }
.bulk { margin-top: var(--s4); }
.bulk .note { flex: 1 1 260px; }
/* The explanatory line under the buttons; .sub pulls itself up by default,
   which collides with a row of them. */
.bulk + .sub { margin-top: var(--s3); }

@media (max-width: 560px) {
  /* "Laukia apmokėjimo" in letterspaced capitals is nearly half a phone wide,
     and it pushed the licence list's action column off the screen. A status is
     a word, not a monument: on a narrow screen it drops the affectation and
     wraps. */
  .pill {
    text-transform: none; letter-spacing: 0; font-size: 12px;
    white-space: normal; text-align: center;
  }
}

/* ---------------------------------------------------------------- portrait -- */
/* The crop box on /foto. The frame is 3:4 because every stored portrait is, so
   what is inside the frame is exactly what ends up on the card — no surprise
   between choosing and seeing. */
[data-portrait] .crop-stage {
  position: relative; overflow: hidden;
  max-width: 260px; aspect-ratio: 3 / 4;
  border: 1px solid var(--line-firm); border-radius: var(--r-md);
  background: var(--ink3);
  touch-action: none;                 /* the drag is ours, not the page's */
  cursor: grab;
}
[data-portrait] .crop-stage.dragging { cursor: grabbing; }
[data-portrait] .crop-stage img {
  position: absolute; top: 0; left: 0;
  transform-origin: 0 0; max-width: none;
  user-select: none; -webkit-user-drag: none;
}

/* Until the picture has loaded there is nothing to frame, so the controls stay
   out of the way rather than sitting there inert. */
[data-portrait] .crop-tools { display: none; margin-top: var(--s3); }
[data-portrait].has-image .crop-tools { display: flex; }
[data-portrait] .crop-zoom { flex: 1 1 160px; max-width: 240px; min-height: 44px; }

/* The portrait on the on-screen card, next to the facts. */
.lic-photo { flex: 0 0 auto; }
.lic-photo img {
  width: 150px; aspect-ratio: 3 / 4; object-fit: cover; display: block;
  border-radius: var(--r-md); border: 1px solid var(--line);
  background: var(--ink3);
}

/* And on the public verdict, where an official is comparing a face to a card. */
.verdict-photo { margin: 0 0 var(--s4); }
.verdict-photo img {
  width: 150px; aspect-ratio: 3 / 4; object-fit: cover; display: block;
  border-radius: var(--r-md); border: 1px solid var(--line);
  background: var(--ink3);
}

/* The photo already on file, beside the picker. */
.portrait-current { display: flex; gap: var(--s4); align-items: flex-start; flex-wrap: wrap; }
.portrait-current img {
  width: 120px; aspect-ratio: 3 / 4; object-fit: cover;
  border-radius: var(--r-md); border: 1px solid var(--line);
  background: var(--ink3);
}
.portrait-none {
  width: 120px; aspect-ratio: 3 / 4;
  display: flex; align-items: center; justify-content: center; text-align: center;
  border: 1px dashed var(--line-firm); border-radius: var(--r-md);
  color: var(--mut); font-size: 12px; padding: var(--s3);
}

/* ------------------------------------------------------------------ badge -- */
/* The printed licence card, at ID-1 (the bank-card size, 85.6 x 54 mm) turned
   portrait — 54 wide by 85.6 tall, which is what a lanyard holder takes.
   Sized in millimetres so what comes out of the printer is the size it says,
   and shown on screen at the same size so the preview is not a lie. */
.badge-sheet { margin: 0 0 var(--s5); }
.badge {
  width: 54mm; height: 85.6mm;
  display: flex; flex-direction: column;
  box-sizing: border-box; padding: 3mm;
  background: #fff; color: #14110c;
  border: 1px solid #cfc7b8; border-radius: 3mm;
  font-size: 7pt; line-height: 1.25;
  overflow: hidden;
}

.badge-top {
  display: flex; align-items: baseline; justify-content: space-between; gap: 2mm;
  padding-bottom: 1.5mm; border-bottom: 0.4mm solid #a8842c;
}
.badge-org {
  font-size: 5.5pt; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  color: #a8842c; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.badge-season { font-size: 8pt; font-weight: 700; font-variant-numeric: tabular-nums; }

/* The vertical budget is tight and fixed: 85.6mm of card, less 6mm of padding,
   has to hold the header, a 3:4 photo, four lines of text, a scannable QR and
   the number. The first version overflowed and the code sat on top of the
   licence number, so these sizes add up on purpose — 5 + 30 + 14 + 16 + 5 plus
   gaps, inside 79.6mm. */
.badge-main { flex: 1 1 auto; display: flex; flex-direction: column; gap: 1.5mm; padding-top: 1.5mm; min-height: 0; }

.badge-photo { align-self: center; }
.badge-photo img {
  width: 22.5mm; height: 30mm;      /* 3:4, the shape every portrait is stored in */
  object-fit: cover; display: block;
  border: 0.3mm solid #cfc7b8; border-radius: 1mm;
}
.badge-nophoto {
  width: 22.5mm; height: 30mm;
  display: flex; align-items: center; justify-content: center; text-align: center;
  border: 0.3mm dashed #cfc7b8; border-radius: 1mm; color: #8a8172; font-size: 6pt;
}

.badge-facts { display: flex; flex-direction: column; gap: 0.5mm; text-align: center; }
.badge-name { font-size: 9pt; line-height: 1.1; letter-spacing: -.01em; }
.badge-club { font-size: 6.5pt; }
.badge-cat, .badge-belt { font-size: 6pt; color: #5f5849; }

/* 16mm is comfortably above the ~10mm a phone camera needs for a version 4
   code at this module count, and it is what the height left over allows. */
.badge-qr { margin-top: auto; align-self: center; }
.badge-qr svg { display: block; width: 16mm; height: 16mm; }

.badge-foot {
  display: flex; align-items: baseline; justify-content: space-between; gap: 2mm;
  padding-top: 1.5mm; margin-top: 1.5mm; border-top: 0.4mm solid #e4ddcf;
}
.badge-no { font-size: 7pt; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: .02em; }
.badge-void { font-size: 6.5pt; font-weight: 700; color: #b3261e; letter-spacing: .08em; }
.badge.void { border-color: #b3261e; }

/* ------------------------------------------------------------------ print -- */
@media print {
  /* Everything that is page rather than card goes away, so Ctrl+P gives the
     card and only the card. */
  .top, .foot, .nav, .flash, h1, .no-print { display: none !important; }

  html, body { background: #fff; margin: 0; padding: 0; }
  .wrap { max-width: none; padding: 0; }

  /* Printers drop background colours by default; on a licence the gold rule
     and the photo frame are how it reads as a card rather than a list. */
  .badge { -webkit-print-color-adjust: exact; print-color-adjust: exact; border-color: #999; }
  .badge-sheet { margin: 0; }

  @page { margin: 8mm; }
}

/* --------------------------------------------------------- photo, in steps -- */
/* Upload, then crop, then what the card gets — laid out as three cards so the
   order is visible rather than implied. */
.steps-row { display: grid; gap: var(--s4); grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); align-items: start; }
.step h2 { display: flex; align-items: center; gap: var(--s3); }
.step .n {
  flex: 0 0 26px; height: 26px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--r-full); border: 1px solid var(--line-firm);
  font-size: 12px; font-weight: 700; color: var(--mut);
}
.step.now .n { border-color: var(--gold); color: var(--gold); }
.step.done .n { border-color: var(--ok); color: var(--ok); }
/* A step that cannot be done yet is present but quiet — hiding it would make
   the page change shape underneath someone mid-task. */
.step.waiting { opacity: .72; }

/* The photo row on the person form: thumbnail, and the way to change it. */
.photo-row { display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap; margin-bottom: var(--s5); }
.photo-label { font-size: 13px; color: var(--mut); }
.photo-thumb {
  width: 60px; aspect-ratio: 3 / 4; object-fit: cover; display: block;
  border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--ink3);
}
.photo-thumb.none {
  display: flex; align-items: center; justify-content: center;
  border-style: dashed; color: var(--mut); font-size: 11px;
}

/* A press release body, shown as plain text because the page exists to be
   copied from. pre keeps the paragraphs the editor wrote without rendering
   markdown — which would mean either a library in the portal or unescaped html
   on a page full of editor-entered text. */
.release {
  margin: 0; padding: var(--s4); border-radius: var(--r-sm);
  background: var(--ink3); color: var(--fg2);
  font: 13px/1.7 var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  white-space: pre-wrap; word-break: break-word;
}

/* Long-form text: the privacy notice, and anything like it. The portal is
   otherwise all forms and tables, so this is the one place that needs reading
   measure and paragraph rhythm. */
.prose-portal { max-width: 68ch; }
.prose-portal h2 { margin: var(--s6) 0 var(--s3); font-size: 16px; }
.prose-portal p { margin: 0 0 var(--s4); color: var(--fg2); line-height: 1.65; }
.prose-portal ul { margin: 0 0 var(--s4); padding-left: var(--s5); color: var(--fg2); line-height: 1.65; }
.prose-portal li { margin-bottom: var(--s2); }
.prose-portal .notice {
  margin: 0 0 var(--s5); padding: var(--s4); border-radius: var(--r-sm);
  border-left: 3px solid var(--gold); background: var(--ink3); color: var(--fg2);
  line-height: 1.6;
}

/* A club's logo, and the way to change it. Square rather than the portrait's
   3:4, because a crest is a crest and object-fit: contain keeps a wide one wide
   instead of cropping the club's own mark. */
.logo-row { display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap; margin-bottom: var(--s5); }
.club-logo {
  width: 96px; height: 96px; object-fit: contain; display: block; padding: var(--s2);
  border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--ink3);
}
.club-logo.none {
  display: flex; align-items: center; justify-content: center;
  border-style: dashed; color: var(--mut); font-size: 11px;
}
.club-logo.small { width: 32px; height: 32px; padding: 2px; }

/* A person's licences, and the way to their printed card. */
.licences-of { margin-bottom: var(--s5); padding-bottom: var(--s4); border-bottom: 1px solid var(--line); }

/* ---------- pasting a screenshot into a report ----------
   A screenshot lives on the clipboard, not on disk. The input stays as the
   posting field and is taken out of the tab order; everything visible here is
   the zone that accepts Ctrl+V, a drop, or a click. */
/* Visually hidden, still in the accessibility tree: this is the labelled
   control and the thing that posts, and the zone in front of it is decoration
   with a role. */
.paste-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

.paste-zone {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s1);
  min-height: 104px; padding: var(--s4);
  border: 1px dashed var(--line-firm);
  border-radius: var(--r-sm);
  background: var(--ink2);
  text-align: center;
  cursor: pointer;
  transition: border-color var(--t-ui) var(--e-out), background-color var(--t-ui) var(--e-out),
              transform var(--t-press) var(--e-out);
}
.paste-zone:hover { border-color: var(--gold); }
.paste-zone:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.paste-zone:active { transform: scale(.985); }
.paste-zone.is-over,
.paste-zone.is-flash { border-style: solid; border-color: var(--gold); background: var(--ink3); }
.paste-zone.is-full { border-style: solid; cursor: default; }

.paste-lead { margin: 0; font-size: .9375rem; color: var(--fg); }
.paste-lead b { font-weight: 600; }
.paste-sub { margin: 0; font-size: .8125rem; color: var(--mut); }

.paste-list { list-style: none; margin: var(--s3) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--s2); }
.paste-list li {
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s2);
  border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--ink2);
}
.paste-list img { width: 48px; height: 34px; object-fit: cover; border-radius: 5px; flex: 0 0 48px; }
.paste-name {
  flex: 1 1 auto; min-width: 0; font-size: .8125rem; color: var(--fg2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.paste-remove {
  flex: 0 0 auto; width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line-firm); border-radius: var(--r-full); background: none;
  color: var(--mut); font-size: 1.05rem; line-height: 1; cursor: pointer;
  transition: color var(--t-ui) var(--e-out), border-color var(--t-ui) var(--e-out),
              transform var(--t-press) var(--e-out);
}
.paste-remove:hover { color: var(--red); border-color: var(--red); }
.paste-remove:active { transform: scale(.9); }
.paste-remove:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

.paste-status { margin: 0; font-size: .8125rem; color: var(--mut); }
.paste-status:not(:empty) { margin-top: var(--s2); }
.paste-status.is-error { color: var(--red); }

@media (prefers-reduced-motion: reduce) {
  .paste-zone, .paste-remove { transition: none; }
}
.paste-kind {
  flex: 0 0 48px; width: 48px; height: 34px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); border-radius: 5px; background: var(--ink3);
  color: var(--mut); font-size: .625rem; font-weight: 700; letter-spacing: .06em;
}
