/* =====================================================================
   Szakosztály — alapréteg

   Világos alapú, levegős felület. Szándékosan NEM követi a rendszer
   sötét módját: az edző napfényben, a pálya szélén nézi, ahol a világos
   háttér olvashatóbb. A sötét tokenek megmaradnak egy későbbi kapcsolóhoz.

   Nincs build lépés, nincs külső erőforrás. A klub saját színe a --club
   változóban érkezik, nonce-olt stílusblokkból.
   ===================================================================== */

:root {
  /* Felületek. Három különböző szerep, három különböző érték — korábban a
     --paper és a --surface is #FFFFFF volt, ezért a naptárcsempe pontosan
     olyan fehér volt, mint a cella, ami alatt ült. */
  --page:#E9EEF2;      /* a lap alapja, minden mögött */
  --paper:#FFFFFF;     /* nagy, összefüggő adatfelület (naptárcella, tábla) */
  --surface:#FFFFFF;   /* kiemelkedő kártya */
  --field:#F4F7F9;     /* süllyesztett mező kártyán belül (input, nap-doboz) */
  --surface-2:#F0F4F7;

  /* A színezett csempe: ennyit keverünk az esemény saját típusszínéből a
     háttérbe, és ennyi fehérrel világosítjuk a színt sötét témán. */
  --tint:16%;
  --ink-mix:0%;

  --ink:#12171C;
  --ink-2:#47525E;
  /* #77838F csak 3,87:1 volt fehéren — az AA 4,5-öt kér. */
  --muted:#626D79;

  --line:#E4EAEF;
  --line-strong:#C9D3DC;

  /* A klub színe felülírja a --club értékét a nonce-olt blokkból. */
  --club:#0E5F52;
  --club-soft:#E6F1EE;
  --club-soft:color-mix(in srgb, var(--club) 12%, #FFFFFF);
  --accent:var(--club);
  --accent-soft:var(--club-soft);

  /* Jelzésszínek. Szándékosan NEM a klub színéből származnak: a jelenlét
     nem márkakérdés, és egy kék klubnál a „hiányzott" nem lehet kék. */
  --st-present:#0E7C46;  --st-present-soft:#E3F5EB;
  --st-absent:#C0392B;   --st-absent-soft:#FDEAE7;
  --st-late:#9A6212;     --st-late-soft:#FCF1DE;
  --st-excused:#3C6494;  --st-excused-soft:#E9F0F8;
  --st-injured:#6A4CA8;  --st-injured-soft:#EFEBF9;

  --ok:var(--st-present);
  --warn:var(--st-late);
  --danger:var(--st-absent);

  --radius:12px;
  --radius-sm:9px;
  --lift:0 1px 2px rgba(18,23,28,.05), 0 6px 20px -12px rgba(18,23,28,.18);
}

/* Sötét tokenek — egyelőre csak explicit választásra, nem automatikusan. */
:root[data-theme="dark"] {
  --page:#0B0F12;
  --paper:#0E1215; --field:#141A1E; --surface:#171E22; --surface-2:#1D262B;
  --tint:26%; --ink-mix:45%;
  --accent:color-mix(in srgb, #FFFFFF 45%, var(--club));
  --ink:#E6ECF0; --ink-2:#B6C2CB; --muted:#8B98A3;
  --line:#242F36; --line-strong:#35434C;
  --club-soft:color-mix(in srgb, var(--club) 34%, var(--paper));
  --st-present:#4FC684;  --st-present-soft:#10291D;
  --st-absent:#E9897C;   --st-absent-soft:#2D1A18;
  --st-late:#DBA648;     --st-late-soft:#2A2113;
  --st-excused:#93B6DE;  --st-excused-soft:#17222E;
  --st-injured:#AB92D8;  --st-injured-soft:#211B2D;
  --lift:0 1px 2px rgba(0,0,0,.4), 0 8px 24px -14px rgba(0,0,0,.7);
}

* { box-sizing:border-box; }

body {
  margin:0; background:var(--paper); color:var(--ink);
  font:15px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing:antialiased;
  font-variant-numeric:tabular-nums;
}

.wrap { max-width:1120px; margin-inline:auto; padding-inline:clamp(18px,4vw,36px); }
a { color:var(--accent); }
:focus-visible { outline:2px solid var(--accent); outline-offset:2px; border-radius:3px; }

h1 { font-size:clamp(23px,2.6vw,28px); font-weight:700; letter-spacing:-.02em;
     line-height:1.2; margin:22px 0 4px; }
h2 { font-size:17.5px; font-weight:650; letter-spacing:-.011em; margin:0 0 3px; }
h3 { font-size:15px; font-weight:600; letter-spacing:-.005em; margin:20px 0 8px; }
h4 { font-size:13px; font-weight:600; color:var(--ink-2); margin:18px 0 6px; }
p  { margin:0 0 10px; line-height:1.6; }
.muted { color:var(--muted); }
.sr-only { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); }

/* ---- fejléc ---- */
.topbar { background:var(--surface); border-bottom:1px solid var(--line);
  position:sticky; top:0; z-index:20; }
.topbar-inner { display:flex; align-items:center; gap:16px; flex-wrap:wrap;
                min-height:56px; padding-block:8px; }
.brand { font-weight:600; text-decoration:none; color:var(--ink); }
.club-name, .who { color:var(--muted); font-size:13.5px; }
.topbar-right { margin-left:auto; display:flex; align-items:center; gap:14px; }
.club-switch select {
  font-size:13.5px; padding:5px 8px;
}

/* =====================================================================
   ŰRLAPVEZÉRLŐK — egy szabály mindenhová
   Korábban négyféle sugár, padding és betűméret élt egymás mellett
   (.field, .inline-form, .maker-grid, .userbar), a fókuszállapot pedig
   csak néhány helyen látszott. Ez az alap; a komponensek csak a méretet
   hangolják, a kinézetet nem írják felül.

   KÉT űrlapforma van, mindegyiknek külön dolga:
     .field-grid   címkézett űrlap panelben vagy felugró ablakban
                   → ui_fields([...]) / ui_field([...])
     .filters      GET-szűrősor egy lista fölött
                   → ui_filters('/utvonal', ...)
   A .inline-form megszűnt: ami maradt belőle, az nem űrlapforma volt,
   hanem műveletsor — .act-row, ui_actions() + ui_post_button().
   Több nincs, és újat sem kell csinálni. Ha egy mező máshogy néz ki egy
   oldalon, az hiba, nem stílus.
   ===================================================================== */

.main input:not([type="radio"]):not([type="checkbox"]),
.main select,
.main textarea,
.card-narrow input,
.card-narrow select,
.card-narrow textarea {
  font:inherit; font-size:14px; color:var(--ink);
  padding:9px 11px; max-width:100%; min-width:0;
  background:var(--surface);
  border:1px solid var(--line); border-radius:var(--radius-sm);
}
.main input:hover:not([type="radio"]):not([type="checkbox"]),
.main select:hover, .main textarea:hover { border-color:var(--line-strong); }

.main input:focus-visible, .main select:focus-visible, .main textarea:focus-visible,
.card-narrow input:focus-visible, .card-narrow select:focus-visible {
  outline:none; border-color:var(--club);
  box-shadow:0 0 0 3px var(--club-soft);
}
/* A böngésző alapból 3px/4px margót tesz a jelölőnégyzet köré. Ettől a
   sor 4 px-rel beljebb kezdődik, mint a fölötte álló mezők — a térközt a
   sorelrendezés `gap`-je adja, nem a vezérlő margója. */
.main input[type="checkbox"], .main input[type="radio"] {
  accent-color:var(--club); margin:0; flex:0 0 auto;
}
.main textarea { min-height:90px; resize:vertical; line-height:1.55; }
.main input::placeholder, .main textarea::placeholder { color:var(--muted); }

/* ---- panelek ---- */
.panel {
  background:var(--surface); border:1px solid var(--line);
  border-radius:var(--radius); padding:16px 18px; margin:14px 0;
  box-shadow:var(--lift);
}
.panel > .btn, .panel > .sheet-toggle + label.btn { margin-top:14px; }
/* A panel első címsora a doboz fejléce, nem egy bekezdés fölötti cím. */
.panel > h2:first-child, .panel > h3:first-child { margin-top:0; }
/* Panelfejléc: cím balra, a hozzá tartozó művelet jobbra. A kapcsoló, a
   címke és az ablak egymás mellett áll, mert a megnyitást szomszédsági
   szabály dönti el (.sheet-toggle:checked + label + .sheet-wrap). */
.panel-head {
  display:flex; align-items:center; justify-content:space-between;
  gap:12px; flex-wrap:wrap; margin:0 0 12px;
}
.panel-head h3 { margin:0; }
.panel > .panel-head:first-child { margin-top:0; }
.panel > :last-child { margin-bottom:0; }
/* A figyelmeztetés nem ugyanolyan doboz, mint egy keresőmező. */
.panel.warn { border-color:var(--st-late); background:var(--st-late-soft); }
.panel.warn h3 { color:var(--st-late); }
.note {
  border-left:2px solid var(--accent); padding-left:14px;
  color:var(--ink-2); font-size:13.5px; margin-top:14px;
}

/* ---- szerepkörök ---- */
.roles { list-style:none; margin:0; padding:0; }
.roles li { display:flex; align-items:center; gap:8px; padding:4px 0; flex-wrap:wrap; }
.dot { width:9px; height:9px; border-radius:50%; flex:0 0 auto; }

.chips { list-style:none; display:flex; flex-wrap:wrap; gap:6px; margin:10px 0 0; padding:0; }
.chips li { font-size:12px; }

/* ---- jogosultsági tábla ---- */
.grants { width:100%; border-collapse:collapse; font-size:13.5px; }
.grants td { padding:5px 10px 5px 0; border-bottom:1px solid var(--line); vertical-align:top; }
.grants tr.off { color:var(--muted); }
.grants tr.off code { opacity:.55; }
.grants .k { width:34%; min-width:150px; }
.grants .s { text-align:right; white-space:nowrap; width:120px; }
/* A csapattáblában KÉT művelet áll egymás mellett — a szerkesztés ehhez az
   egy tagsághoz tartozik, ezért van itt és nem a panel fejlécében. Két
   gombnak 120 képpont kevés, és tördelniük is szabad. */
.grants-team .s { width:auto; min-width:220px; white-space:normal; }
.grants-team .act-row { justify-content:flex-end; }
.yes { color:var(--accent); font-weight:500; }
.no  { color:var(--muted); }
.tag { font-size:10.5px; text-transform:uppercase; letter-spacing:.06em;
       color:var(--danger); border:1px solid var(--danger);
       padding:0 5px; border-radius:4px; margin-left:6px; }
code { font-family:ui-monospace, SFMono-Regular, Menlo, monospace; font-size:12.5px;
       background:var(--surface-2); padding:1px 5px; border-radius:4px; }

/* ---- űrlapok ---- */
.centered { display:flex; min-height:100vh; align-items:center; justify-content:center; padding:20px; }
.card-narrow {
  width:100%; max-width:380px; background:var(--surface);
  border:1px solid var(--line); border-radius:var(--radius); padding:28px 26px;
}
.stack { display:flex; flex-direction:column; gap:14px; margin-top:18px; }
.field { display:flex; flex-direction:column; gap:5px; }
.field label { font-size:13px; color:var(--ink-2); font-weight:500; }
.field input {
  width:100%;
}
.btn {
  display:inline-block; text-align:center; text-decoration:none;
  font:inherit; font-weight:600; font-size:13.5px; padding:8px 15px; border:0;
  cursor:pointer; border-radius:var(--radius-sm); background:var(--club); color:#fff;
  letter-spacing:-.003em; line-height:1.4; white-space:nowrap;
}
.btn:hover { filter:brightness(1.08); }
.btn-link {
  font:inherit; font-size:13.5px; background:none; border:0; cursor:pointer;
  color:var(--accent); padding:0; text-decoration:underline;
}

/* ---- visszajelzés ---- */
.flash { padding:10px 14px; border-radius:7px; font-size:13.5px; margin:14px 0; }
.flash-error   { background:var(--st-absent-soft); color:var(--danger); border:1px solid var(--danger); }
.flash-success { background:var(--st-present-soft); color:var(--st-present); border:1px solid var(--st-present); }
/* Tájékoztatás, nem hiba és nem siker: a lejárt munkamenet nem a felhasználó
   hibája, de nem is eredmény — a semleges klubszín ezt mondja. */
.flash-info    { background:var(--club-soft); color:var(--club); border:1px solid var(--club); }
.login-note    { margin-top:0; }

.err-code { font-size:46px; margin:0; color:var(--accent); }
.foot { color:var(--muted); font-size:12.5px; padding-block:28px 40px; }

@media (max-width:600px) {
  .grants .k { width:auto; }
  .grants .s { width:auto; }
  .topbar-right { width:100%; margin-left:0; }
}

/* ---- ki léphet be ezen a címen ----
   Három cím van, három jelentéssel; a belépő mondja meg, melyiken állsz. */
.who { list-style:none; margin:14px 0 0; padding:0; font-size:13px; }
.who li { position:relative; padding-left:20px; margin-bottom:7px; color:var(--ink-2); line-height:1.5; }
.who li::before { position:absolute; left:0; top:0; font-weight:700; }
.who-yes::before { content:"✓"; color:var(--ok); }
.who-no::before  { content:"✕"; color:var(--muted); }
.who-no { color:var(--muted); }

/* ---- tenant jelölés a belépő felületen ---- */
.tenant-badge {
  display:inline-block; font-size:11.5px; letter-spacing:.08em; text-transform:uppercase;
  border:1px solid var(--accent); color:var(--accent); border-radius:999px;
  padding:3px 11px; margin:0 0 18px;
}

/* ---- szakosztályváltó ---- */
.section-switch select {
  font-size:13.5px; padding:5px 8px;
}
.section-name { color:var(--muted); font-size:13.5px; }
.tenant-badge-inline { margin:0; }
.tag-neutral { color:var(--muted); border-color:var(--line); }
/* Az elsődleges kapcsolattartót hívni fogják, ha baj van: kitöltött
   címke, nem csak egy keret a többi közt. */
.tag-primary {
  color:var(--accent); border-color:transparent;
  background:var(--surface-2);
  background:color-mix(in srgb, var(--accent) 14%, var(--surface));
}

/* =====================================================================
   RENDSZERKONZOL
   Ugyanaz a nyelv, mint a klubfelületen, csak fejlécsávval oldalsáv
   helyett: itt nyolc menüpont van, nem napi munkafolyamat.
   ===================================================================== */

body.console { background:var(--page); }
body.console .topbar {
  background:var(--surface); border-bottom:1px solid var(--line);
  box-shadow:var(--lift);
}
body.console .topbar-inner { max-width:1180px; margin-inline:auto; padding-inline:clamp(20px,3vw,40px); }
body.console > .wrap { max-width:1180px; margin-inline:auto; padding-inline:clamp(20px,3vw,40px); }
body.console .brand { font-size:15px; letter-spacing:-.01em; }

.console-nav {
  display:flex; flex-wrap:wrap; gap:2px; padding:3px;
  background:var(--field); border-radius:var(--radius-sm);
  /* Nyolc menüpont sok. A sortörést a flex-basis dönti el, nem a
     tényleges szélesség: kis alappal a profilkép marad az első sorban,
     a sáv pedig belül törik. A max-content sapka miatt széles képernyőn
     mégsem nyúlik el az üres helyre. */
  flex:1 1 380px; min-width:0; max-width:max-content;
}
.console-nav a {
  text-decoration:none; color:var(--ink-2); font-size:13.5px; font-weight:500;
  padding:6px 12px; border-radius:6px;
}
.console-nav a:hover { color:var(--ink); }
.console-nav a.is-here {
  background:var(--surface); color:var(--ink); font-weight:600; box-shadow:var(--lift);
}

/* ---- szerkeszthető mátrix ---- */
.matrix-wrap { overflow-x:auto; border:1px solid var(--line); border-radius:var(--radius); background:var(--surface); }
table.matrix { border-collapse:collapse; width:100%; font-size:13px; }
table.matrix th, table.matrix td { padding:6px 8px; border-bottom:1px solid var(--line); }
table.matrix thead th {
  position:sticky; top:0; background:var(--surface-2); z-index:2;
  font-size:11px; text-transform:uppercase; letter-spacing:.06em;
  color:var(--muted); font-weight:600; text-align:center; white-space:nowrap;
}
table.matrix th.ability, table.matrix td.ability {
  position:sticky; left:0; background:var(--surface); text-align:left;
  min-width:230px; border-right:1px solid var(--line); z-index:1;
  /* A rögzített oszlop alá becsúszó tartalom eddig félbevágott vezérlőnek
     látszott. Az árnyék megmondja, hogy ez átfedés, nem törés. */
  box-shadow:6px 0 8px -8px rgba(18,23,28,.35);
}
table.matrix thead th.ability { background:var(--surface-2); z-index:3; }
/* A gépi kulcs és a „veszélyes" jelzés egy sorban, a név ALATT. A név mellé
   fűzve kétsoros címkénél a mondat közepén landolt. */
.ability-meta { display:flex; align-items:center; gap:7px; margin-top:3px; flex-wrap:wrap; }
.ability-meta .tag { margin-left:0; }
table.matrix tr.group td {
  background:var(--surface-2); font-size:11px; text-transform:uppercase;
  letter-spacing:.08em; color:var(--muted); font-weight:600;
}
table.matrix select {
  font-size:12px; padding:3px 5px; border-radius:5px; width:100%; min-width:124px;
}
/* A kiosztott jog a lényeg, a 336 üres cella a háttér — ezért a „— nincs"
   halkabb, a beállított érték pedig klubszínnel keretezett. */
table.matrix select.is-set { border-color:var(--accent); color:var(--accent); font-weight:500; }
table.matrix select.is-empty { color:var(--muted); }
/* A zárolt oszlop szövege: állapot, nem vezérlő. */
.cell-locked {
  display:block; text-align:center; font-size:12px; color:var(--muted);
  padding:4px 5px; white-space:nowrap;
}
.ability-name { font-weight:500; }
.ability-key { font-size:11px; color:var(--muted); font-family:ui-monospace, Menlo, monospace; }

.sticky-actions {
  position:sticky; bottom:0; z-index:10;
  background:var(--surface); border-top:1px solid var(--line);
  border-radius:0 0 var(--radius) var(--radius);
  padding:14px 16px; margin-top:0; box-shadow:0 -6px 18px -14px rgba(18,23,28,.5);
  display:flex; gap:12px; align-items:center; flex-wrap:wrap;
}
.sticky-actions .muted { font-size:13px; }

/* ---- funkciókapcsolók ---- */
.feature-row { display:grid; grid-template-columns:1fr auto; gap:12px 20px;
  padding:12px 0; border-bottom:1px solid var(--line); align-items:start; }
.feature-row:last-child { border-bottom:0; }
.tri { display:flex; gap:0; border:1px solid var(--line); border-radius:7px; overflow:hidden; }
.tri label { font-size:12px; padding:5px 10px; cursor:pointer; color:var(--muted);
  border-right:1px solid var(--line); white-space:nowrap; }
.tri label:last-child { border-right:0; }
.tri input { position:absolute; opacity:0; width:0; height:0; }
.tri input:checked + span { color:var(--accent); font-weight:600; }
.tri label:has(input:checked) { background:var(--accent-soft); }
.badge-inherit { font-size:11px; color:var(--muted); }

/* ---- szervezeti fa ---- */
.org-group { border-left:2px solid var(--line); padding:12px 0 12px 16px; margin:14px 0; }
/* A korosztály neve balra, a műveletei jobbra — ugyanaz a rend, mint a
   panelfejlécben és a táblasorokban. */
.org-head {
  display:flex; flex-wrap:wrap; gap:10px 14px;
  align-items:center; justify-content:space-between;
}
.org-title { display:flex; flex-wrap:wrap; gap:8px; align-items:baseline; min-width:0; }
/* A csapatok táblázata a korosztály alatt: a panel már doboz, ezért itt
   nem kell újabb árnyék és keret — csak a fejléc és a sorok rácsa. */
.org-group .scroller { margin:10px 0 0; }
.org-group .tbl-card { box-shadow:none; border-radius:var(--radius-sm); }
/* A fán belüli műveletsor halkabb és szűkebb, mint egy önálló lapé: itt
   sok ilyen áll egymás alatt. */
.org-head .act-row, .org-group .act-row { gap:8px; }
.org-head .btn, .org-group .btn { font-size:12.5px; padding:6px 11px; }
.org-group .act-row > .ask > summary { font-size:12.5px; padding:6px 11px; }
.org-squad { margin:10px 0 0; }
.is-archived { opacity:.55; }
.wrap-anywhere { overflow-wrap:anywhere; }
.roles li form { display:inline; }

/* ---- játékosok ---- */
.pill { display:inline-block; font-size:12px; background:var(--surface-2);
  border-radius:999px; padding:2px 9px; margin:1px 3px 1px 0; }
.pill b { color:var(--accent); }
.med-valid    { color:var(--ok); }
.med-expiring { color:var(--warn); font-weight:500; }
.med-expired  { color:var(--danger); font-weight:600; }
.med-missing  { color:var(--muted); font-style:italic; }
/* A jelölőnégyzet és a szövege egy sor, bárhol áll is — a rácsok
   címke-szabálya (.field-grid > label) különben oszlopba fordítaná, és a
   doboz a szövege fölé, középre csúszna. */
.check, .field-grid label.check, .field-grid .field.check {
  display:flex; flex-direction:row; align-items:center; justify-content:flex-start;
  gap:8px; font-size:13.5px; font-weight:400; color:var(--ink-2); cursor:pointer;
}
/* Eltávolítás egy mentőűrlapon belül: nem tilthatjuk meg, de nem is állhat
   ugyanolyan halkan, mint egy sima beállítás. Bepipálva pirosra vált — a
   mentés előtti utolsó pillantás így megmutatja, mi tűnik majd el. */
.check-danger { margin-top:10px; }
.check-danger > span { color:var(--muted); }
.check-danger:has(input:checked) > span { color:var(--danger); font-weight:600; }
.check-danger:has(input:checked) > span .hint { color:var(--danger); }

/* Jelölőnégyzetes választólista ablakban (játékosfelvevő). Görgethető, mert
   egy korosztálynyi névsor nem fér ki — de nem lapozós, mert a lényeg épp az,
   hogy egy menetben lehessen végigmenni rajta. */
.pick-list {
  max-height:46vh; overflow-y:auto; padding:2px 2px 2px 0; margin-bottom:14px;
  border:1px solid var(--line); border-radius:var(--radius-sm); background:var(--field);
}
.pick-list .check { padding:7px 12px; }
.pick-list .check:hover { background:var(--surface-2); }
.pick-head {
  position:sticky; top:0; z-index:1; margin:0;
  padding:9px 12px 6px; font-size:11px; text-transform:uppercase;
  letter-spacing:.06em; font-weight:600; color:var(--muted);
  background:var(--field); border-bottom:1px solid var(--line);
}
.sensitive-block { border:1px solid var(--warn); border-radius:var(--radius);
  padding:16px 18px; margin:14px 0; background:var(--surface); }
.sensitive-block h4 { margin-top:0; color:var(--warn); }
/* ---- az EGYETLEN űrlaprács ----
   Korábban két rács élt egymás mellett (.field-grid és .maker-grid),
   alig eltérő méretekkel — ezért nézett ki másképp ugyanaz a mező két
   oldalon. Most egy van. Kétféle szerkezetet fogad el: a ui_field() által
   írt <div class="field"><label>…</label><input></div>-et, és a régebbi,
   kézzel írt <label>Szöveg <input></label> formát. A kettő EGYFORMÁN néz
   ki, tehát a még át nem írt oldalak sem lógnak ki. */
.field-grid {
  display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
  gap:14px 16px;
}
.field-grid > .field, .field-grid > label {
  margin:0; min-width:0;
  display:flex; flex-direction:column; gap:5px;
  font-size:13px; font-weight:500; color:var(--ink-2);
}
/* Ahol a címke MAGA fogja körbe a vezérlőt, ott a felirat és a mellette álló
   zárójeles súgó két külön rácselem — oszlopirányban két sorba kerültek.
   Sorirányban tördelve a felirat és a súgó egy sor, a vezérlő alattuk. */
.field-grid > label { flex-flow:row wrap; align-items:baseline; gap:5px; }
/* A címke alatt teljes sort kap a vezérlő — DE a jelölőnégyzet és a
   rádiógomb nem vezérlőmező, hanem a szövege elé tartozó kis doboz.
   Kizárás nélkül az is külön sorba ugrott, a felirata alá csúszott, és a
   kettő szétesett; a `.check` sorszabálya ezt nem tudta felülírni, mert az
   a szülőre vonatkozik, ez meg a gyerekre. */
.field-grid > label > input:not([type="radio"]):not([type="checkbox"]),
.field-grid > label > select,
.field-grid > label > textarea { flex:1 0 100%; }
/* A rács cellája a legmagasabb mezőhöz nyúlik; az egysoros jelölőnégyzet
   ilyenkor a cella tetejére tapadna, a szomszéd mező közepe helyett. */
.field-grid > label.check { align-self:center; }
/* Saját sor a rácsban — ugyanaz, amit a `.field.wide` tud, csak címkére. */
.field-grid > label.wide { grid-column:1/-1; }
/* A jelölőnégyzet és a rádiógomb nem szövegmező: teljes szélességre
   nyújtva a rajzolt doboz a sor közepére kerül, elszakadva a címkéjétől. */
.field-grid input:not([type="radio"]):not([type="checkbox"]),
.field-grid select, .field-grid textarea { width:100%; }

/* ---- mezőcsoport ----
   Egy hosszú adatlapot nem a mezők száma tesz olvashatatlanná, hanem hogy
   nincs benne fogódzó. A csoportcím adja meg, mit keresel; vonal választja
   el, nem újabb doboz — a panel már doboz. */
.fset { border:0; margin:0; padding:0; min-width:0; }
/* Egyenlő levegő a vonal fölött és alatt — különben az elválasztó az előző
   csoport utolsó mezőjéhez tapad, és a következőhöz tartozónak látszik. */
.fset + .fset { margin-top:22px; padding-top:22px; border-top:1px solid var(--line); }
/* Az első rovatcím se tapadjon a fölötte álló címsorhoz vagy bekezdéshez… */
.fset:first-of-type { margin-top:16px; }
/* …az ablakokban viszont az űrlap belső tere már megadja a levegőt. */
.sheet-form .fset:first-of-type { margin-top:0; }
/* A <legend> alapból RÁÜL a fieldset felső keretére, és kivág belőle egy
   rést: az elválasztó vonal így a rovatcím közepén futna át. A float
   kiveszi ebből a különleges pozícióból, és sima blokként viselkedik. */
.fset > legend {
  float:left; width:100%;
  padding:0; margin:0 0 12px; font-size:12px; font-weight:600;
  letter-spacing:.06em; text-transform:uppercase; color:var(--muted);
}
.fset > legend + * { clear:both; }
/* A hosszú szöveges mezők a teljes sort kapják, nem fél oszlopot. */
.field-grid .field.wide { grid-column:1/-1; }
/* Páros elrendezés: ahol a mezők összetartoznak (vezetéknév–keresztnév,
   születési hely–dátum), ott a sor NEM változhat a panel szélességével.
   Az `auto-fit` széles helyen három hasábot nyit, és a pár szétcsúszik. */
.fset-pairs .field-grid { grid-template-columns:repeat(2, minmax(0, 1fr)); }
@media (max-width:520px) {
  .fset-pairs .field-grid { grid-template-columns:1fr; }
}
/* Egy pipához tartozó magyarázat: a négyzet alá, a szövegével egy vonalban. */
.check-note {
  margin:-4px 0 0; padding-left:21px; font-size:12.5px; color:var(--muted);
}
.check-note strong { color:var(--ink-2); font-weight:600; }
/* Ahol a csoportcím tulajdonnév — egy csapat neve —, ott nem kiskapitális
   rovatcím kell, hanem maga a név. */
.fset-plain > legend {
  text-transform:none; letter-spacing:0; font-size:14px; color:var(--ink);
}
.fset-plain > legend .muted { font-weight:400; }

/* ---- esemény ---- */
.avail-form { display:flex; flex-wrap:wrap; gap:10px; align-items:center;
  padding:10px 0; border-bottom:1px solid var(--line); }
.avail-form:last-child { border-bottom:0; }
.avail-form input[type=text] { font-size:13.5px; padding:7px 10px; }
.avail-yes { color:var(--ok); font-weight:500; }
.avail-no { color:var(--danger); font-weight:500; }
.avail-maybe { color:var(--warn); }
.avail-none { color:var(--muted); font-style:italic; }
.avail-comment { color:var(--ink-2); font-size:13px; }
.coach-reply { flex-basis:100%; margin:4px 0 0; font-size:13px; color:var(--accent); }
.reply-form { margin-top:4px; }
tr.has-warning { background:color-mix(in srgb, var(--warn) 7%, transparent); }
.plan-row { padding:5px 0; border-bottom:1px solid var(--line); font-size:13.5px; }
.plan-row:last-child { border-bottom:0; }
.plan-row.is-cancelled { opacity:.55; }
.plan .k { width:110px; }

/* ---- gyors jelenlét ---- */
.code-panel { text-align:center; }
.big-code { font-family:ui-monospace, Menlo, monospace; font-size:clamp(40px,12vw,72px);
  letter-spacing:.12em; color:var(--accent); margin:8px 0; font-weight:600; }

/* ---- riport ---- */
.meter-track {
  display:inline-block; width:110px; height:8px; border-radius:4px;
  background:var(--surface-2);
  background:color-mix(in srgb, var(--ink) 10%, var(--surface));
  vertical-align:middle; margin-right:8px;
  line-height:0; font-size:0; overflow:hidden;
}
.meter { display:block; height:100%; border-radius:4px; background:var(--accent); }

/* ---- sávok: 5%-os lépcsők, hogy ne kelljen inline stílus ---- */
.meter-0{width:0%}
.meter-5{width:5%}
.meter-10{width:10%}
.meter-15{width:15%}
.meter-20{width:20%}
.meter-25{width:25%}
.meter-30{width:30%}
.meter-35{width:35%}
.meter-40{width:40%}
.meter-45{width:45%}
.meter-50{width:50%}
.meter-55{width:55%}
.meter-60{width:60%}
.meter-65{width:65%}
.meter-70{width:70%}
.meter-75{width:75%}
.meter-80{width:80%}
.meter-85{width:85%}
.meter-90{width:90%}
.meter-95{width:95%}
.meter-100{width:100%}

/* ---- segédosztályok az egykori inline stílusok helyett ---- */
.grow { flex:1 1 260px; }
.w-score { width:70px; }
.w-shirt { width:110px; }
.lead { font-size:16px; }
.span-all { grid-column:1/-1; }
.stack-top { margin-top:16px; }
/* A kódmező ui_field()-del készül, ezért az osztály a .field burkolaton van;
   a nagybetűs, ritkított írás a benne lévő beviteli mezőé. */
.code-input input { text-transform:uppercase; letter-spacing:.2em; width:190px; }

/* ---- a klub színe, ha van; egyébként az alapértelmezett akcentus ---- */

/* =====================================================================
   JELENLÉTI ÍV
   Az edző a pálya szélén áll, egy kézzel, sietve. Minden döntés ebből
   következik: a mezszám a horgony, a három gyakori állapot nagy és
   egymás mellett, a ritka kettő halkabban, a megjegyzés csak akkor
   jelenik meg, ha van mit magyarázni.
   ===================================================================== */

.crumb { font-size:13px; margin:18px 0 0; }
.sheet-header { margin:6px 0 18px; }
.sheet-header h1 { margin:0 0 2px; }
.sheet-meta { color:var(--muted); font-size:14px; margin:0; }

/* A művelet- és haladássáv a lista fölött marad, hogy az edző lássa,
   hol tart — tizennyolc gyereknél ez nem kozmetika. */
.sheet-bar {
  position:sticky; top:0; z-index:5;
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:10px 0; margin-bottom:2px;
  background:var(--paper); border-bottom:1px solid var(--line);
}
.sheet-progress { font-size:14px; color:var(--muted); font-variant-numeric:tabular-nums; }
.sheet-progress strong { color:var(--ink); font-size:17px; }

.btn-quiet {
  background:transparent; color:var(--club); border:1px solid var(--club);
  font-weight:500;
}

.sheet { list-style:none; margin:0; padding:0; }

.row {
  display:grid; grid-template-columns:auto 1fr; gap:0 14px;
  padding:14px 0; border-bottom:1px solid var(--line);
}
.row:last-child { border-bottom:0; }
.row-empty { display:block; color:var(--muted); padding:28px 0; }

/* A mezszám: a tárgykör legjellegzetesebb száma, tehát ekkora is legyen.
   Tabuláris számjegyek, hogy a lista széle egyenes maradjon. */
.shirt {
  font-size:26px; font-weight:600; line-height:1.1;
  font-variant-numeric:tabular-nums; letter-spacing:-.02em;
  color:var(--ink); min-width:1.9em; text-align:right;
  padding-top:1px;
}
.row:has(.state-hianyzott input:checked) .shirt { color:var(--st-absent); }
.row:has(.state-jelen input:checked) .shirt     { color:var(--st-present); }

.row-name { margin:0 0 8px; font-size:16px; font-weight:500; line-height:1.25; }
.row-hint { margin:-4px 0 8px; font-size:13px; color:var(--muted); }

.states { display:flex; gap:6px; }
.states-rare { margin-top:6px; }

/* Szélesebb képernyőn ne nyúljanak abszurd szélesre a gombok:
   a hüvelykujjnak elég 120 pixel, a szemnek zavaró a 700. */
@media (min-width:560px) {
  .states { max-width:520px; }
  .states-rare { max-width:520px; }
}

.state {
  flex:1 1 0; cursor:pointer; text-align:center;
  padding:10px 6px; border:1px solid var(--line); border-radius:8px;
  font-size:14px; color:var(--ink-2); background:var(--surface);
  user-select:none; line-height:1.2;
  transition:background .12s ease, border-color .12s ease, color .12s ease;
}
.state input { position:absolute; opacity:0; width:0; height:0; }
.state:has(input:focus-visible) { outline:2px solid var(--club); outline-offset:2px; }

.states-rare .state { padding:7px 6px; font-size:13px; color:var(--muted); }

/* Az állapotszínek szándékosan NEM a klub színéből jönnek: a jelenlét
   nem márkakérdés, és egy kék klubnál a „hiányzott" nem lehet kék. */
.state-jelen:has(input:checked)     { background:var(--st-present-soft); border-color:var(--st-present); color:var(--st-present); font-weight:600; }
.state-hianyzott:has(input:checked) { background:var(--st-absent-soft);  border-color:var(--st-absent);  color:var(--st-absent);  font-weight:600; }
.state-keset:has(input:checked)     { background:var(--st-late-soft);    border-color:var(--st-late);    color:var(--st-late);    font-weight:600; }
.state-igazolt:has(input:checked)   { background:var(--st-excused-soft); border-color:var(--st-excused); color:var(--st-excused); font-weight:600; }
.state-serult:has(input:checked)    { background:var(--st-injured-soft); border-color:var(--st-injured); color:var(--st-injured); font-weight:600; }
.state-clear:has(input:checked)     { border-color:var(--line-strong); color:var(--ink-2); }

/* A megjegyzés csak akkor jelenik meg, ha van mit magyarázni —
   jelenlétnél üres mező csak zajt csinálna tizennyolcszor. */
.row-note {
  margin-top:8px; width:100%; font:inherit; font-size:14px;
  padding:8px 10px; border:1px solid var(--line); border-radius:8px;
  background:var(--paper); color:var(--ink);
}
.row:not(:has(.state-hianyzott input:checked,
              .state-keset input:checked,
              .state-igazolt input:checked,
              .state-serult input:checked)) .row-note { display:none; }

.sheet-save {
  position:sticky; bottom:0; z-index:5;
  display:flex; align-items:center; gap:16px; flex-wrap:wrap;
  padding:14px 0; margin-top:4px;
  background:var(--paper); border-top:1px solid var(--line);
}
.sheet-save .btn { font-size:16px; padding:12px 22px; }

@media (max-width:420px) {
  .row { gap:0 10px; }
  .shirt { font-size:22px; min-width:1.7em; }
  .state { padding:11px 4px; font-size:13.5px; }
}

@media (prefers-reduced-motion:reduce) {
  .state { transition:none; }
}

/* =====================================================================
   HETI NAPTÁR
   Az adat kapja a helyet; a létrehozó űrlapok lenyílóban várnak alatta.
   ===================================================================== */

.cal-head {
  display:flex; align-items:center; justify-content:space-between;
  gap:16px; flex-wrap:wrap; margin:0 0 16px;
}
.cal-head h1 { margin:0; }

/* Nezetvalto: honap az alapertelmezes, mert a szulo a kovetkezo meccset
   keresi, nem csak ezt a hetet. */
.views {
  display:inline-flex; gap:2px; padding:3px;
  background:var(--field); border-radius:var(--radius-sm);
}
.views a {
  font-size:13.5px; font-weight:500; text-decoration:none;
  color:var(--ink-2); padding:6px 13px; border-radius:6px;
}
.views a:hover { color:var(--ink); }
.views a.is-here { background:var(--surface); color:var(--ink); box-shadow:var(--lift); }
/* Ikonos változat: a felirat mondja meg, mit kapcsolsz, az ikon adja a
   ránézésre felismerhető formát. Szűk helyen a felirat elmarad — az ikon
   marad a kapaszkodó, ezért kap ott címkét a képernyőolvasónak is. */
.views-icon a { display:inline-flex; align-items:center; gap:7px; padding:6px 11px; }
.views-icon .side-icon { width:16px; height:16px; }

.cal-bar { display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin:0 0 16px; }
.step {
  width:32px; height:32px; display:grid; place-items:center;
  text-decoration:none; color:var(--ink-2);
  background:var(--surface); border:1px solid var(--line); border-radius:var(--radius-sm);
}
.step:hover { border-color:var(--line-strong); color:var(--ink); }
.cal-label { font-size:17px; font-weight:600; letter-spacing:-.01em; }
.today-link { font-size:13.5px; color:var(--muted); }
.today-link:hover { color:var(--club); }
.cal-filter { margin-left:auto; display:flex; gap:8px; }
.cal-filter select {
  font-size:14px; padding:8px 12px;
}
.cal-filter button {
  font:inherit; font-size:13.5px; padding:8px 14px; cursor:pointer;
  color:var(--ink-2); background:var(--surface);
  border:1px solid var(--line); border-radius:var(--radius-sm);
}
.cal-filter button:hover { border-color:var(--line-strong); color:var(--ink); }

/* =====================================================================
   HETI ÓRAGRID
   A hét korábban napokra bontott felsorolás volt — abból nem derült ki,
   hogy két edzés ütközik-e, és mekkora a szünet közöttük. Ez a nézet
   időben helyezi el az alkalmakat.

   A pozíciót nonce-olt CSS adja változókban (--wk-top, --wk-h, --wk-left,
   --wk-w): inline `style`-t a szigorú CSP némán eldobna, és minden csempe
   a bal felső sarokba csúszna.
   ===================================================================== */

/* A rácsnak SAJÁT felülete van, különben a lap szürkéje (--page) üt át
   rajta, és az egész nézet kifakul. A havi nézet ugyanígy kártyában ül. */
.wk {
  margin:0 0 28px;
  background:var(--paper);
  border:1px solid var(--line);
  border-radius:var(--radius);
  overflow:hidden;
}
/* A fejlécben a hét nap HÉT külön elem, a törzsben viszont egyetlen
   .wk-cols tartja őket — ezért nem ugyanaz a két rács. Közös szabállyal a
   .wk-cols egyetlen 1fr sávba szorult, és a napok 19 pixelesek lettek. */
.wk-head { display:grid; grid-template-columns:56px repeat(7, minmax(0,1fr)); }
/* A felső levegő az óracímkéé: a felirat a vonal FÖLÉ ül (translateY),
   enélkül a legelső óra félig kilógna a rácsból. A gutter és a naposzlopok
   együtt tolódnak, tehát az igazítás nem romlik el. */
.wk-body { display:grid; grid-template-columns:56px minmax(0,1fr); padding:9px 0 0; background:var(--paper); }
/* A fejlécsáv süllyesztett, mint a havi nézet napnevei. Nem ragasztott:
   az `overflow:hidden` kártyában a `position:sticky` amúgy sem működne,
   és egy ~700 pixeles rácshoz nem is kell. */
.wk-head { background:var(--field); }
.wk-dayhead {
  display:flex; align-items:baseline; gap:6px; justify-content:center;
  padding:8px 4px; font-size:12.5px; color:var(--muted);
  border-bottom:1px solid var(--line-strong);
}
.wk-dayhead b { font-size:16px; font-weight:700; letter-spacing:-.02em; color:var(--ink); }
.wk-dayhead.is-today { color:var(--club); }
.wk-dayhead.is-today b { color:var(--club); }
.wk-gutter-head { border-bottom:1px solid var(--line-strong); }
.wk-gutter { background:var(--paper); }

/* Az órasáv címkéi a vonalra ülnek, nem a sáv közepére: a 17:00 felirat
   ott van, ahol a 17:00 kezdődik. */
.wk-gutter { position:relative; }
.wk-hour {
  display:block; height:var(--wk-hour,54px); box-sizing:border-box;
  padding-right:8px; text-align:right;
  font-size:11px; color:var(--muted); font-variant-numeric:tabular-nums;
  transform:translateY(-.55em);
}

.wk-cols {
  position:relative; height:var(--wk-height);
  display:grid; grid-template-columns:repeat(7, minmax(0,1fr));
  /* Az óravonalak háttérként: nem külön elemek, tehát nem tolják el a
     csempéket, és a nyomtatásban is maradnak. */
  background-image:repeating-linear-gradient(
      to bottom, var(--line) 0 1px, transparent 1px var(--wk-hour,54px));
}
.wk-day { position:relative; border-left:1px solid var(--line); min-width:0; }
.wk-day:first-child { border-left:0; }
.wk-day.is-today { background:var(--club-soft); }
.wk-daylabel { display:none; }

/* ---- átfedő alkalmak: teljes szélességű rétegek ----
   Hasábokra vágás helyett egymásra rétegezve, mindegyik majdnem teljes
   szélességben. Minden réteg egy sávval beljebb kezdődik, hogy az alatta
   lévőnek maradjon kilátszó felülete, amire rá lehet mutatni.

   A lépcső EGYETLEN helyen áll (--wk-lepcso), és egyenletes: nincs
   felső korlát, ami a negyedik réteget a harmadikra ejtené. Legfeljebb
   négy réteg van (EventService::MAX_RETEG), tehát a legbeljebbi csempe
   3 × 12 = 36 pixelt veszít — egy 135 pixeles naposzlopban is marad
   bőven hely a szövegnek.

   A 12 pixeles sáv keskenyebb az általános 24–32 pixeles ajánlásnál, de
   itt a kilátszó felület nem 12×12: a csempe TELJES magasságában sáv,
   vagyis egy 12 × 80 pixeles cél — azt könnyű eltalálni. */
.wk-slot {
  --wk-lepcso:12px;
  position:absolute;
  top:var(--wk-top,0); height:var(--wk-h,54px);
  left:calc(var(--wk-i,0) * var(--wk-lepcso));
  width:calc(100% - var(--wk-i,0) * var(--wk-lepcso));
  z-index:calc(var(--wk-i,0) + 1);
  padding:1px 2px; box-sizing:border-box; min-width:0;
  transition:opacity .12s ease;
}

/* A fürt burkolata. Méret nélküli, nem pozicionált elem: a benne lévő
   csempék továbbra is a naposzlophoz igazodnak, viszont a hover a FÜRTRE
   szól, nem az egész napra. Enélkül egy mozdulat a nap összes alkalmát
   elhalványította — azokat is, amiknek semmi közük az átfedéshez. */
.wk-stack { display:contents; }

/* Csak akkor halványítunk, ha tényleg van mit szétválasztani: egyetlen
   csempéjű fürtnél a hover nem csinál semmit. */
/* FIGYELEM a specifikusságra. A `:has()` a legerősebb argumentumának a
   súlyát veszi fel, tehát a halványító szabály (0,5,0) erősebb volt, mint
   a kiemelő (0,3,0) — a kiemelés sosem érvényesült, minden halvány maradt.
   A két szabály ezért UGYANARRA az alapra épül, a kiemelő eggyel
   erősebben. */
.wk-stack:has(.wk-slot + .wk-slot):hover .wk-slot,
.wk-stack:has(.wk-slot + .wk-slot):focus-within .wk-slot { opacity:.22; }

.wk-stack:has(.wk-slot + .wk-slot):hover .wk-slot:hover,
.wk-stack:has(.wk-slot + .wk-slot):focus-within .wk-slot:focus-within {
  opacity:1; z-index:90;
}
.wk-stack:has(.wk-slot + .wk-slot):hover .wk-slot:hover > .ev,
.wk-stack:has(.wk-slot + .wk-slot):focus-within .wk-slot:focus-within > .ev {
  box-shadow:0 6px 20px -8px rgba(18,23,28,.45);
}

@media (prefers-reduced-motion:reduce) {
  .wk-slot { transition:none; }
}
/* Az egymásra csúszó csempéknek keret kell, különben összefolynak. */
.wk-slot > .ev { border-color:var(--line-strong); }
/* ---- azonos idejű alkalmak egy dobozban ----
   Négy egyszerre induló edzés négy hasábban 25%-ot kapna: egy 135 pixeles
   naposzlopban 33 pixel, amin sem az idő, sem a csapat neve nem fér el.
   Utánpótlásban viszont ez a normál eset — az U8–U14 együtt van jégen. Amit
   ilyenkor tudni kell, az nem a geometria, hanem hogy MELYIK csapatok. */
.wk-group {
  height:100%; box-sizing:border-box; overflow:hidden;
  display:flex; flex-direction:column;
  padding:4px 5px; border-radius:var(--radius-sm);
  background:var(--paper); border:1px solid var(--line-strong);
  box-shadow:var(--lift);
}
/* Szoros méretek, hogy négy csapat elférjen a saját idősávjában: egy
   másfél órás alkalom 81 pixel, abból a fejléc után ~56 marad négy sorra. */
.wk-group-head {
  display:flex; align-items:baseline; gap:5px;
  margin:0 0 2px; flex:0 0 auto; white-space:nowrap;
}
.wk-group-head time { font-weight:700; font-size:12px; color:var(--ink); line-height:1.1; }
.wk-group-n { font-size:11px; color:var(--muted); }
.wk-group-list {
  list-style:none; margin:0; padding:0; min-height:0; overflow-y:auto;
  display:flex; flex-direction:column; gap:2px;
}
/* A sor ugyanazt a színnyelvet viszi, mint az önálló csempe: halvány
   kitöltés a saját színéből, erősebb bal él. Az összevonás nem veheti el a
   színt — épp attól olvasható, melyik csapat melyik. */
/* Az alapszín a LISTÁN ül, nem a soron: így a sorra tett `.ev-c…` (az
   esemény saját színe) és az `.ev-match` azonos súllyal versenyez, és a
   későbbi nyer — pontosan úgy, ahogy az önálló csempénél. Ha a sorra
   tennénk, elnyomná az esemény színét, és minden mérkőzés egyforma lenne. */
.wk-group-list { --evc:var(--club); }
.wk-group-list li {
  --evl:color-mix(in srgb, #FFFFFF var(--ink-mix), var(--evc));
  border-radius:4px;
  background:var(--surface);                                    /* tartalék */
  background:color-mix(in srgb, var(--evl) var(--tint), var(--paper));
  border-left:3px solid var(--evl);
}
/* A sor a MEGLÉVŐ .ev-match és .ev-off osztályokat viszi, nem újakat: a
   mérkőzés jelzőszíne és az elmaradás halványítása így egy helyen van
   definiálva, és a sor meg a csempe nem tud szétcsúszni. */
.wk-group-list li.ev-off .wk-group-team { text-decoration:line-through; }
.wk-group-list a {
  display:flex; align-items:baseline; gap:5px; min-width:0;
  padding:1px 5px; font-size:11.5px; line-height:1.3;
  color:var(--ink); text-decoration:none;
}
.wk-group-list a:hover .wk-group-team { text-decoration:underline; }
/* ---- ütközésjelzés ----
   Csak akkor, ha UGYANAZON A HELYSZÍNEN fedik egymást — az a valódi
   ütközés. Két párhuzamos edzés külön pályán nem baj; ha arra is szólnánk,
   a jelzés zajjá válna. A jelölés csíkos sarok + felirat, nem csak szín:
   színvakság mellett is látszik. */
/* A csíkozás a CSEMPÉN van, nem a felsorolás sorain: ott a sor amúgy is
   keskeny, és a minta a saját színét nyomná el. A listában a jel elég. */
.ev.ev-clash {
  border-top:2px solid var(--st-late);
  background-image:repeating-linear-gradient(135deg,
      color-mix(in srgb, var(--st-late) 16%, transparent) 0 6px,
      transparent 6px 12px);
}
.ev-clash-flag {
  display:inline-block; margin-top:3px;
  font-size:10.5px; font-weight:700; letter-spacing:.02em;
  color:var(--st-late);
}
.wk-group-clash { color:var(--st-late); font-weight:700; flex:0 0 auto; font-size:11px; }

.wk-group-time {
  font-variant-numeric:tabular-nums; color:var(--muted); flex:0 0 auto;
}
.wk-group-team { font-weight:600; flex:0 0 auto; }
.wk-group-kind {
  color:var(--ink-2); overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}

/* A csempe kitölti a sávját — így a magassága a valódi hosszt mutatja. */
.wk-slot > .ev { height:100%; box-sizing:border-box; padding:5px 7px; gap:1px; overflow:hidden; }
.wk-slot .ev-sub { display:none; }
/* Egy óránál hosszabb alkalomnál elfér a csapat neve is. */
.wk-slot > .ev { container-type:inline-size; }
@media (min-width:1100px) {
  .wk-slot .ev-sub { display:block; }
}

.week {
  display:grid; grid-template-columns:repeat(7,1fr); gap:10px;
  margin:0 0 28px;
}
.day {
  background:var(--paper); border:1px solid var(--line); border-radius:var(--radius);
  padding:12px 10px; min-height:132px;
  display:flex; flex-direction:column; gap:8px;
}
.day-today { background:var(--club-soft); box-shadow:inset 0 0 0 1.5px var(--club); }

.day-head { display:flex; align-items:baseline; gap:7px; flex-wrap:wrap; margin:0 0 2px; min-width:0; }
.day-num  { font-size:19px; font-weight:700; letter-spacing:-.02em; line-height:1; }
.day-name { font-size:12.5px; color:var(--muted); }
.day-today .day-num { color:var(--club); }
.day-empty { margin:auto 0; font-size:12.5px; color:var(--muted); text-align:center; }

/* Az esemény kártyája: a bal éle az edzéstípus színét viszi — ezt eddig
   lekérdeztük az adatbázisból, és sosem rajzoltuk ki. */
/* A csempe színét az esemény saját típusszíne adja: a --evc változót a
   nonce-olt blokk tölti fel az edzéstípus listaértékéből, mérkőzésnél a
   figyelmeztető szín lép be. A --evl ennek a témához igazított változata:
   világos témán maga a szín, sötéten fehérrel világosítva.

   Korábban a háttér fix --surface (fehér) volt, a cella alatta pedig --paper
   (szintén fehér) — 1,00:1, vagyis semmi nem különítette el őket. Most a
   kitöltés a típusszín halvány keveréke, plusz egy valódi 1px-es keret. */
.ev {
  --evc:var(--club);
  --evl:color-mix(in srgb, #FFFFFF var(--ink-mix), var(--evc));
  display:block; text-decoration:none; color:var(--ink);
  border-radius:var(--radius-sm);
  padding:9px 11px; box-shadow:var(--lift);

  background:var(--surface);                                   /* tartalék */
  background:color-mix(in srgb, var(--evl) var(--tint), var(--paper));
  border:1px solid var(--line);                                 /* tartalék */
  border:1px solid color-mix(in srgb, var(--evl) 34%, var(--paper));
  border-left:3px solid var(--evl);
}
.ev:hover { transform:translateY(-1px); border-color:var(--line-strong); border-left-color:var(--evl); }
.ev-match { --evc:var(--st-late); border-left-width:5px; }
.ev-match .ev-title { font-weight:650; }
.ev-off { opacity:.55; }
.ev-off .ev-title { text-decoration:line-through; }
.ev-time  { display:block; font-size:15px; font-weight:700; letter-spacing:-.01em; }
.ev-title { display:block; font-size:13.5px; font-weight:500; margin-top:1px; }
.ev-sub   { display:block; font-size:12px; color:var(--ink-2); line-height:1.35; }
.ev-flag  {
  display:inline-block; margin-top:4px; font-size:11px; font-weight:600;
  color:var(--st-absent); background:var(--st-absent-soft);
  padding:1px 7px; border-radius:5px;
}

@media (prefers-reduced-motion:reduce) { .ev:hover { transform:none; } }

@media (max-width:860px) {
  .week { grid-template-columns:repeat(2,1fr); }
  .day { min-height:0; }
}
@media (max-width:520px) {
  .week { grid-template-columns:1fr; gap:8px; }
  .day-head { border-bottom:1px solid var(--line); padding-bottom:7px; }
}

/* =====================================================================
   HAVI RACS
   Egy cellaban legfeljebb harom esemeny fer el olvashatoan; a tobbi
   "+N tovabbi" linkkel a heti nezetbe visz, ahol mar mind kifer.
   ===================================================================== */

.month {
  display:grid; grid-template-columns:repeat(7,1fr); gap:1px;
  background:var(--line); border:1px solid var(--line);
  border-radius:var(--radius); overflow:hidden; margin:0 0 28px;
}
.month-dow {
  background:var(--field); padding:8px 10px;
  font-size:12px; font-weight:600; color:var(--muted); text-align:center;
}
.month-dow abbr { text-decoration:none; }

.cell {
  background:var(--paper); min-height:114px; padding:7px 7px 9px;
  display:flex; flex-direction:column; gap:4px; min-width:0;
}
.cell-out { background:var(--surface-2); }
.cell-out .cell-num { color:var(--muted); }
.cell-num {
  align-self:flex-start; width:24px; height:24px; display:grid; place-items:center;
  font-size:13px; font-weight:600; color:var(--ink-2);
  text-decoration:none; border-radius:50%;
}
.cell-num:hover { background:var(--field); color:var(--ink); }
.cell-today .cell-num { background:var(--club); color:#fff; }
.cell-more { font-size:11.5px; color:var(--muted); text-decoration:none; padding-left:3px; }
.cell-more:hover { color:var(--club); }

.month .ev { padding:4px 7px 5px; border-radius:6px; box-shadow:none; min-width:0; }
.month .ev:hover { transform:none; }
.month .ev-time  { font-size:11.5px; line-height:1.2; }
.month .ev-title {
  margin:1px 0 0; font-size:11.5px; line-height:1.25;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.month .ev-sub, .month .ev-flag { display:none; }
.month .ev-off .ev-time { text-decoration:line-through; }

/* =====================================================================
   LISTA
   Telefonon ez a leghasznalhatobb: nincs cellapasztazas, csak a kovetkezo
   esemenyek idorendben.
   ===================================================================== */

.agenda { list-style:none; margin:0 0 28px; padding:0; }
.agenda-day {
  display:flex; align-items:baseline; gap:10px;
  padding:22px 2px 8px; margin:0 0 10px; border-bottom:1px solid var(--line);
}
.agenda-day:first-child { padding-top:4px; }
.agenda-num { font-size:21px; font-weight:700; letter-spacing:-.02em; }
.agenda-when { font-size:13px; color:var(--muted); }
.agenda-day.is-today .agenda-num { color:var(--club); }
.agenda-day.is-today .agenda-when strong { color:var(--club); }
.agenda-item { margin:0 0 8px; }
.agenda-item .ev {
  display:flex; align-items:baseline; gap:14px; flex-wrap:wrap; padding:12px 14px;
  background:var(--surface);
}
.agenda-item .ev-time  { min-width:50px; }
.agenda-item .ev-title { margin:0; font-size:14.5px; flex:1 1 140px; }
.agenda-item .ev-sub   { flex:0 0 auto; }
.agenda-empty { list-style:none; color:var(--muted); padding:28px 0; }

@media (max-width:680px) {
  .cal-filter { margin-left:0; width:100%; }
  .cal-filter select { flex:1 1 auto; min-width:0; }
  .cell { min-height:62px; padding:4px 3px; gap:2px; }
  .cell-num { align-self:center; width:22px; height:22px; font-size:12px; }
  .month-dow { padding:6px 2px; font-size:11px; }
  .month .ev { padding:2px 4px; border-radius:3px; }
  .month .ev-match { border-left-width:4px; }
  .month .ev-time { font-size:10px; }
  .month .ev-title { display:none; }
  .cell-more { font-size:10px; text-align:center; padding:0; }
}

/* ---- lenyíló űrlapok ---- */
.maker {
  border:1px solid var(--line); border-radius:var(--radius);
  margin:14px 0; background:var(--surface);
}
.maker > summary {
  cursor:pointer; padding:15px 20px; font-weight:600; font-size:15.5px;
  list-style:none; display:flex; align-items:center; gap:10px;
}
.maker > summary::-webkit-details-marker { display:none; }
.maker > summary::before {
  content:"+"; color:var(--club); font-size:19px; font-weight:400; line-height:1;
}
.maker[open] > summary::before { content:"–"; }
.maker[open] > summary { border-bottom:1px solid var(--line); }
.maker-form { padding:20px; }
.hint { font-size:13px; color:var(--muted); font-weight:400; }
.maker-form .hint { margin:12px 0 0; }
.maker-form .field-grid { margin-bottom:18px; }

.weekdays { border:0; padding:0; margin:0; }
.weekdays legend { font-size:13.5px; font-weight:500; color:var(--ink-2); margin-bottom:8px; }
.wd { position:relative; display:inline-flex; }
.wd input { position:absolute; opacity:0; width:0; height:0; }
.wd span {
  display:inline-block; min-width:44px; text-align:center; cursor:pointer;
  padding:9px 6px; margin:0 5px 5px 0; font-size:14px;
  border:1px solid var(--line); border-radius:var(--radius-sm);
  background:var(--paper); color:var(--ink-2);
}
.wd:has(input:checked) span {
  background:var(--club); border-color:var(--club); color:#fff; font-weight:600;
}
.wd:has(input:focus-visible) span { outline:2px solid var(--club); outline-offset:2px; }

/* =====================================================================
   JÁTÉKOSLISTA
   A mezszám a horgony; a sportorvosi állapot ránézésre olvasható.
   ===================================================================== */

.list-header {
  display:flex; align-items:center; justify-content:space-between;
  gap:16px; flex-wrap:wrap; margin:0 0 16px;
}
.list-header h1 { margin:22px 0 0; }
.list-count { margin:2px 0 0; color:var(--muted); font-size:13.5px; }

/* A figyelmeztetés nem ugyanolyan doboz, mint a keresőmező. */
.alert {
  background:var(--st-late-soft); border:1px solid var(--st-late);
  border-radius:var(--radius); padding:18px 22px; margin:0 0 18px;
}
.alert h2 { font-size:17px; color:var(--st-late); margin:0 0 4px; }
.alert p { margin:0 0 10px; font-size:14px; color:var(--ink-2); }
.alert-list { list-style:none; margin:0; padding:0; display:flex; flex-wrap:wrap; gap:6px; }
.alert-list li {
  display:inline-flex; align-items:baseline; gap:7px; font-size:13px;
  padding:4px 10px; border-radius:999px;
  background:var(--surface); border:1px solid var(--line-strong);
}
.alert-list a { font-weight:600; text-decoration:none; color:var(--ink); }
.alert-list a:hover { text-decoration:underline; }

.filters {
  display:flex; flex-wrap:wrap; gap:8px; align-items:center;
  padding:0 0 12px; border-bottom:1px solid var(--line); margin-bottom:2px;
}
.filters input[type=search], .filters input[type=date], .filters select {
  font-size:13.5px; padding:8px 11px;
}
/* Csak a KÖZVETLEN gyerekre: a .field oszlopirányú, ott a flex-basis a
   magasságot állítaná, és a keresőmező 230 px magas lenne. */
.filters > input[type=search] { min-width:230px; flex:1 1 230px; max-width:360px; }
.filters input:focus, .filters select:focus { border-color:var(--club); outline:none; }
.toggle { display:flex; align-items:center; gap:7px; font-size:14px; color:var(--ink-2); }

/* Rövid névsor a kezdőlapon. A teljes játékoslista táblázat — ez itt
   néhány soros kiemelés, annak a kártya a jó forma. */
.roster {
  list-style:none; margin:0 0 24px; padding:0;
  background:var(--surface); border:1px solid var(--line);
  border-radius:var(--radius); box-shadow:var(--lift); overflow:hidden;
}
.pl { border-bottom:1px solid var(--line); }
.pl:last-child { border-bottom:0; }
.pl-link:hover { background:var(--field); }

.pl-link {
  display:flex; align-items:center; justify-content:space-between; gap:14px;
  padding:11px 16px; text-decoration:none; color:var(--ink);
}
.pl-name { font-size:15px; font-weight:600; letter-spacing:-.008em; }
.pl-meta { font-size:13.5px; font-weight:600; white-space:nowrap; }

/* A mezszám a táblázat horgonya: nagy, jobbra zárt, egymás alatt igazodó. */
.pl-shirt {
  font-size:19px; font-weight:700; letter-spacing:-.025em; line-height:1.2;
  color:var(--ink); font-variant-numeric:tabular-nums;
}
tr.is-off .pl-shirt { color:var(--muted); }

.s-ok     { color:var(--st-present); }
.s-late   { color:var(--st-late); }
.s-absent { color:var(--st-absent); }

/* =====================================================================
   ALKALMAZÁS-VÁZ
   Bal oldali sáv asztalon, kihúzható fiók telefonon. A fiók tiszta
   CSS-sel nyílik — a rendszer továbbra sem használ JavaScriptet.
   ===================================================================== */

.shell { background:var(--page); min-height:100vh; }
.nav-toggle { position:absolute; opacity:0; width:0; height:0; }

.side {
  position:fixed; inset:0 auto 0 0; width:252px; z-index:40;
  display:flex; flex-direction:column;
  background:var(--surface); border-right:1px solid var(--line);
}

.side-brand {
  display:flex; align-items:center; gap:11px;
  padding:18px 18px 16px; text-decoration:none; color:var(--ink);
  border-bottom:1px solid var(--line);
}
.side-mark {
  display:grid; place-items:center; width:34px; height:34px; flex:0 0 auto;
  border-radius:10px; background:var(--club); color:#fff;
  font-weight:700; font-size:17px;
}
.side-club { font-weight:650; font-size:15px; letter-spacing:-.01em; line-height:1.25; }

.side-nav { flex:1 1 auto; overflow-y:auto; padding:14px 12px; }
.side-group {
  margin:14px 10px 6px; font-size:12px; font-weight:600; color:var(--muted);
}
.side-group:first-child { margin-top:2px; }

.side-link {
  display:flex; align-items:center; gap:11px;
  padding:7px 10px; margin-bottom:1px; border-radius:var(--radius-sm);
  text-decoration:none; color:var(--ink-2); font-size:14px; font-weight:500;
}
.side-link:hover { background:var(--field); color:var(--ink); }
.side-link.is-here { background:var(--club-soft); color:var(--club); font-weight:600; }

.side-icon {
  width:19px; height:19px; flex:0 0 auto;
  fill:none; stroke:currentColor; stroke-width:1.7;
  stroke-linecap:round; stroke-linejoin:round;
}
/* Vonalas ikon gombokban (ui_icon). Ugyanaz a rajzstílus, de vastagabb
   vonallal: ezek kis méretben, önmagukban állnak, nem felirat mellett. */
.ui-icon {
  width:16px; height:16px; display:block; flex:0 0 auto;
  fill:none; stroke:currentColor; stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round;
}

.side-foot { padding:14px 18px; border-top:1px solid var(--line); }
.side-user { margin:0 0 6px; font-size:13.5px; font-weight:500; }
.side-out {
  font:inherit; font-size:13.5px; background:none; border:0; padding:0;
  color:var(--club); cursor:pointer; text-decoration:underline;
}

.scrim { display:none; }

.main { margin-left:252px; min-height:100vh; display:flex; flex-direction:column; }
.main .wrap {
  flex:1 1 auto; max-width:1180px; margin-inline:0;
  padding-inline:clamp(20px,3vw,40px);
  /* A felső belső margó megállítja a címsor margójának összecsúszását:
     enélkül a h1 kicsúszik a dobozból, és a ragadós fejléc alá kerül. */
  padding-block:1px 0;
}

/* Felső sáv: asztalon csak a váltókat viszi, telefonon a menügombot is. */
.bar {
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:9px clamp(18px,3vw,36px);
  background:var(--surface); border-bottom:1px solid var(--line);
  position:sticky; top:0; z-index:20;
}
.bar-club { display:none; font-weight:650; font-size:15px; }
.bar-picks { display:flex; align-items:center; gap:10px; flex-wrap:wrap; min-width:0; }
.bar-section { font-size:14px; color:var(--muted); }
/* A váltó mezője a ui_field() óta .field burkolatban áll. Az oszlopirányú
   burkolatban a flex-basis a MAGASSÁGRA hatna, ezért a vezérlő itt fix
   méretű, és a burkolat rugalmas. */
.bar-pick .field { gap:0; min-width:0; flex:0 1 auto; }
.bar-pick select {
  font-size:14px; padding:7px 11px; max-width:190px; flex:0 0 auto;
}
.burger { display:none; }
.burger svg {
  width:23px; height:23px; fill:none; stroke:var(--ink);
  stroke-width:1.9; stroke-linecap:round;
}

.main .foot { color:var(--muted); font-size:13px; padding-block:26px 34px; }

@media (max-width:1023px) {
  .side {
    transform:translateX(-100%);
    transition:transform .22s ease;
    box-shadow:var(--lift);
    width:272px;
  }
  .nav-toggle:checked ~ .side { transform:translateX(0); }
  .nav-toggle:checked ~ .scrim {
    display:block; position:fixed; inset:0; z-index:30;
    background:rgba(18,23,28,.42);
  }
  .main { margin-left:0; }
  .burger { display:grid; place-items:center; cursor:pointer;
            width:38px; height:38px; margin-left:-6px; border-radius:9px; }
  .burger:hover { background:var(--field); }
  /* Telefonon a burger, a klub neve és a profilkép az első sor. A váltók
     saját sorba kerülnek: egymás mellé szorítva a „Váltás" gomb és a
     szakosztály neve egymásra csúszott. */
  .bar { flex-wrap:wrap; row-gap:8px; gap:9px; }
  .bar-club {
    display:block; margin-right:auto; font-size:14.5px;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
    flex:1 1 auto; min-width:0;
  }
  .bar .me { order:1; }
  .bar-picks { order:2; flex:1 1 100%; }
  .bar-pick { min-width:0; flex:1 1 150px; display:flex; gap:6px; align-items:center; }
  .bar-pick .field { flex:1 1 auto; }
  .bar-pick select { min-width:0; width:100%; max-width:none; font-size:13.5px; padding:6px 8px; }
  .bar-go { flex:0 0 auto; font-size:13px; padding:6px 9px; }
  .bar-section { flex:0 0 auto; }
}

@media (prefers-reduced-motion:reduce) { .side { transition:none; } }

/* A régi vízszintes menü és a hozzá tartozó mobilszabályok kikerültek;
   a konzol saját fejléce (.topbar) változatlanul működik. */

/* =====================================================================
   KÉTLÉPCSŐS MEGERŐSÍTÉS
   A confirm() párbeszéd a CSP miatt sosem jelent meg, tehát a törlések
   visszakérdezés nélkül futottak le. Itt a kérdés a lapon marad: a nyitás
   maga az első lépés, a gomb a második.
   ===================================================================== */

.ask { display:inline-block; }
.ask > summary {
  list-style:none; cursor:pointer; font-size:13.5px;
  color:var(--st-absent); text-decoration:underline; text-underline-offset:3px;
}
.ask.ask-warn > summary { color:var(--st-late); }
.ask > summary::-webkit-details-marker { display:none; }
.ask > summary:focus-visible { outline:2px solid var(--club); outline-offset:3px; border-radius:3px; }
.ask[open] > summary { color:var(--muted); text-decoration:none; }
.ask[open] > summary::after { content:" — mégsem"; }

.ask-box {
  display:flex; flex-direction:column; align-items:flex-start; gap:9px;
  margin-top:9px; padding:13px 14px; max-width:400px;
  background:var(--st-absent-soft); border-radius:var(--radius-sm);
  border-left:3px solid var(--st-absent);
}
.ask-warn .ask-box { background:var(--st-late-soft); border-left-color:var(--st-late); }
.ask-msg { margin:0; font-size:13px; line-height:1.5; color:var(--ink-2); }
.ask-box input[type="text"] {
  font-size:14px; width:100%; padding:8px 10px;
}
.ask-yes {
  font:inherit; font-size:13.5px; font-weight:600; cursor:pointer;
  padding:8px 15px; border:0; border-radius:var(--radius-sm);
  color:#fff; background:var(--st-absent);
}
.ask-warn .ask-yes { background:var(--st-late); }
.ask-yes:hover { filter:brightness(1.08); }

/* Műveletsorban a megerősítés is GOMB. Szöveglinkként a tömör gombok
   mellett úgy nézett ki, mintha más súlyú dolog lenne — pedig ugyanúgy
   egy művelet, csak kétlépcsős. A doboz kinyílva továbbra is a kérdés.

   Ugyanez áll a felugró ablak veszélyzónájára: oda az ablakban álló művelet
   kerül, ami nem fér az űrlapba (más a célpontja). Ott is gomb, csak az
   ablak lábában, elkülönítve a mentéstől. */
:is(.act-row, .sheet-danger) > .ask > summary {
  display:inline-block; text-align:center; text-decoration:none;
  font:inherit; font-weight:600; font-size:13.5px; padding:8px 15px;
  border-radius:var(--radius-sm); cursor:pointer;
  background:var(--club-soft); color:var(--club);
}
:is(.act-row, .sheet-danger) > .ask.ask-warn > summary { background:var(--st-late-soft); color:var(--st-late); }
:is(.act-row, .sheet-danger) > .ask > summary:hover { background:var(--club); color:#fff; }
:is(.act-row, .sheet-danger) > .ask.ask-warn > summary:hover { background:var(--st-late); color:#fff; }
:is(.act-row, .sheet-danger) > .ask[open] > summary { background:var(--field); color:var(--muted); }
:is(.act-row, .sheet-danger) > .ask[open] > summary::after { content:" — mégsem"; }
/* Kinyitva a kérdés ne a gomb mellé, hanem alá kerüljön. */
.act-row > .ask[open] { flex:1 1 100%; }

/* A fejléc váltógombja: a select mellett áll, nem helyette. */
.bar-go {
  font:inherit; font-size:13.5px; cursor:pointer; padding:7px 12px;
  color:var(--ink-2); background:var(--surface);
  border:1px solid var(--line); border-radius:var(--radius-sm);
}
.bar-go:hover { border-color:var(--line-strong); color:var(--ink); }
.bar-pick { display:flex; gap:6px; align-items:center; }

/* =====================================================================
   FELVEVŐ ABLAK
   A <dialog> csak showModal()-lal nyílik, inline JS pedig nincs, ezért egy
   rejtett jelölőnégyzet tartja az állapotot — ugyanaz a minta, mint a
   mobilmenünél. A :has() köti össze a kettőt, így nem kell testvérnek
   lenniük a lapon.
   ===================================================================== */

.cal-tools { display:flex; align-items:center; gap:12px; flex-wrap:wrap; }

/* Nem rejtjük el teljesen: így Tab-bal elérhető, Szóközzel nyitható. */
.sheet-toggle { position:absolute; width:1px; height:1px; opacity:0; }
.sheet-open { cursor:pointer; }
.sheet-open::before { content:"+"; margin-right:7px; font-weight:400; }
/* IKONOS nyitógomb — a csapat névsorában álló eltávolító ikon formanyelvével
   (`.ros-del`): KERET ÉS HÁTTÉR NÉLKÜL, halvány rajz, ami csak hoverre kap
   színt. Egy táblázatsorban két bekeretezett gomb két kis dobozt rajzol
   minden sorba, és a lista ettől rácsossá válik; a puszta ikon nem visz el
   figyelmet a sortól, amíg nincs rá szükség.

   A „+" itt értelmetlen (nem új dolgot veszünk fel), a felirat pedig a
   tooltipbe és a képernyőolvasóhoz megy. */
.btn-icon {
  display:grid; place-items:center; width:32px; height:32px;
  padding:0; flex:0 0 auto;
  border:0; background:none; box-shadow:none;
  color:var(--muted); border-radius:var(--radius-sm);
}
.btn-icon::before { content:none; }
.btn-icon .ui-icon { width:18px; height:18px; }
.btn-icon:hover { background:var(--club-soft); color:var(--club); filter:none; }
/* A művelet JELENTÉSE adja a hover színét — ugyanaz a három szín, amit a
   jelenléti státuszok használnak, tehát a felület máshol is ezt jelenti:
   zöld = rendben, narancs = óvatosan, piros = visszafordíthatatlan. */
.btn-icon.ico-ok:hover     { background:var(--st-present-soft); color:var(--st-present); }
.btn-icon.ico-warn:hover   { background:var(--st-late-soft);    color:var(--st-late); }
.btn-icon.ico-danger:hover { background:var(--st-absent-soft);  color:var(--st-absent); }

/* Ikonos MEGERŐSÍTÉS a műveletsorban. A `ui_confirm()` nyitója `<summary>`,
   amit a műveletsor egyébként teli gombbá formáz — ikonos módban viszont
   ugyanazt a négyzetet kell adnia, mint a többi ikonnak, különben két
   különböző formájú gomb állna egymás mellett ugyanabban a sorban. */
:is(.act-row, .sheet-danger) > .ask.ask-icon > summary {
  display:grid; place-items:center; width:32px; height:32px;
  padding:0; border:0; background:none; color:var(--muted);
  border-radius:var(--radius-sm);
}
:is(.act-row, .sheet-danger) > .ask.ask-icon > summary:hover {
  background:var(--st-absent-soft); color:var(--st-absent);
}
:is(.act-row, .sheet-danger) > .ask.ask-icon.ask-warn > summary:hover {
  background:var(--st-late-soft); color:var(--st-late);
}
/* Nyitva a jelölés marad, de a „— mégsem" felirat ikonos gombba nem fér:
   a nyitott állapotot a szín mutatja. */
:is(.act-row, .sheet-danger) > .ask.ask-icon[open] > summary::after { content:none; }
:is(.act-row, .sheet-danger) > .ask.ask-icon[open] > summary {
  background:var(--field); color:var(--ink);
}
.ask-icon > summary .ui-icon { width:18px; height:18px; }
/* Ami meglévőt módosít, az nem vesz fel újat — a plusz ott félrevezetne. */
.sheet-open.btn-outline::before { content:none; }
/* Halkabb gomb a másodlagos műveletekhez: kitöltött, de halvány klubszín.
   A fehér, csak keretes változat eltűnt a fehér panelen — és a szürke
   kártyákon sem látszott gombnak. Ez mindkét háttéren megáll. */
.btn-outline { background:var(--club-soft); color:var(--club); }
.btn-outline:hover { filter:none; background:var(--club); color:#fff; }
.sheet-toggle:focus-visible + .sheet-open { outline:2px solid var(--club); outline-offset:3px; }

.sheet-wrap { display:none; }
.sheet-toggle:checked + label + .sheet-wrap {
  display:grid; place-items:end center; position:fixed; inset:0; z-index:60;
  padding:0;
}
@media (min-width:721px) {
  .sheet-toggle:checked + label + .sheet-wrap { place-items:center; padding:24px; }
}
/* A háttér görgetése zavaró, amíg az ablak nyitva van. */
body:has(.sheet-toggle:checked) { overflow:hidden; }

.sheet-scrim {
  position:absolute; inset:0; cursor:pointer;
  background:rgba(12,20,26,.44);
}
.sheet-box {
  /* Az ablak ott áll a jelölésben, ahol a nyitógombja — akár egy jobbra
     zárt, nem törő táblázatcellában. A `text-align` és a `white-space`
     öröklődik, és az ablak ezeket a cellától vette át: a címkék jobbra
     zártak lettek, a magyarázó bekezdés pedig egyetlen sorban futott ki az
     ablakból (a felszabadítás ablakánál pont ez történt). Mindkettőt itt
     állítjuk vissza, egy helyen — nem ablakonként. */
  text-align:left; white-space:normal;
  position:relative; width:min(620px,100%); max-height:92vh; overflow-y:auto;
  background:var(--surface); border:1px solid var(--line);
  border-radius:var(--radius) var(--radius) 0 0;
  box-shadow:0 -8px 40px -12px rgba(12,20,26,.4);
}
@media (min-width:721px) {
  .sheet-box { border-radius:var(--radius); box-shadow:0 24px 60px -20px rgba(12,20,26,.45); }
}

.sheet-head {
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:13px 18px; border-bottom:1px solid var(--line);
  position:sticky; top:0; background:var(--surface); z-index:1;
}
.sheet-head h2 { margin:0; font-size:17px; letter-spacing:-.01em; }
.sheet-x {
  cursor:pointer; color:var(--muted);
  width:32px; height:32px; display:grid; place-items:center; border-radius:var(--radius-sm);
}
.sheet-x:hover { background:var(--field); color:var(--ink); }

.sheet-form { padding:18px; }
/* A lábléc az ŰRLAPON KÍVÜL áll (lásd `ui_sheet()`), tehát a saját belső
   margóját is magának kell hoznia — az űrlap 18 képpontja már nem védi.
   Enélkül a gombok az ablak széléhez tapadtak. */
.sheet-foot {
  display:flex; align-items:center; justify-content:flex-end; gap:12px;
  flex-wrap:wrap;
  padding:14px 18px; border-top:1px solid var(--line);
}
.sheet-foot .btn-quiet { cursor:pointer; color:var(--muted); font-size:14px; border:0; background:none; padding:8px 4px; }
.sheet-foot .btn-quiet:hover { color:var(--ink); }

/* ---- szegmentált választó ----
   Rádiógomb, mert a CSS nem tud egy <select> aktuális értékére illeszkedni,
   a :checked állapotra viszont igen — ez tartja a feltételes mezőket. */

.pick { display:flex; gap:6px; border:0; padding:0; margin:0 0 18px; }
.pick-wrap { flex-wrap:wrap; margin:0; }
.pick-opt { position:relative; cursor:pointer; }
.pick-opt input { position:absolute; width:1px; height:1px; opacity:0; }
.pick-opt span {
  display:block; padding:7px 14px; font-size:13.5px; font-weight:500;
  color:var(--ink-2); background:var(--surface);
  border:1px solid var(--line); border-radius:999px;
}
.pick-opt:hover span { border-color:var(--line-strong); color:var(--ink); }
.pick-opt input:checked + span {
  color:#fff; background:var(--club); border-color:var(--club); font-weight:600;
}
.pick-opt input:focus-visible + span { outline:2px solid var(--club); outline-offset:2px; }

/* ---- ismétlődés: egy űrlap, egy kapcsoló ---- */

.repeat { margin:20px 0 0; padding:16px; border:1px solid var(--line); border-radius:var(--radius-sm); background:var(--field); }
/* Ugyanaz a floatos kivétel, mint a .fset-nél: a legend alapból a keretre ül,
   és a doboz belső térközével együtt jobbra csúszik a benne álló mezőkhöz
   képest. Floattal sima blokk lesz, a doboz bal szélével egy vonalban. */
.repeat > legend {
  float:left; width:100%; padding:0; margin:0 0 12px;
  font-size:13px; font-weight:600; color:var(--ink-2);
}
.repeat > legend + * { clear:both; }

.when-row { display:flex; flex-wrap:wrap; gap:12px; align-items:flex-end; }
/* A címke és a vezérlő egymás alatt — de SORIRÁNYBAN tördelve, nem
   oszlopban: így a címke melletti zárójeles súgó a címkével egy sorban
   marad, a mező pedig alá kerül (teljes szélességű alapmérettel). */
.when-date, .when-freq, .when-time, .repeat-until {
  display:flex; flex-wrap:wrap; align-items:baseline; gap:6px;
  font-size:13.5px; color:var(--ink-2); min-width:0;
}
.when-date > input, .when-date > select, .when-freq > select,
.when-time > input, .repeat-until > input { flex:1 0 100%; }
.when-date { flex:1 1 160px; }
.when-freq { flex:1 1 170px; }
.when-time { flex:0 1 116px; }
.repeat-until { margin-top:14px; max-width:220px; }
.when-row input, .when-row select, .repeat-until input {
  font-size:14px; padding:9px 11px; min-width:0;
}
.repeat-days { margin-top:16px; }
.repeat-note { margin:14px 0 0; max-width:46ch; }
.wd-legend { display:block; font-size:13.5px; color:var(--ink-2); margin-bottom:8px; }

/* ---- feltételes mezők ----
   Alapból rejtve, és csak az ág kapcsolja be, amelyikhez tartoznak. Így ami
   az adott választásnál értelmetlen, meg sem jelenik. */

/* A `:has(option:checked)` a <select> aktuális értékére illeszkedik, tehát a
   feltételes mezőkhöz nem kell JavaScript. A sorrend számít: a mérkőzés-ág
   szabályai jönnek utoljára, mert azok írják felül a ritmusból következőket. */

.sheet-form .only-match,
.sheet-form .only-repeat,
.sheet-form .only-weekly,
.sheet-form .only-once { display:none; }

/* A :has() az argumentuma specifikusságát veszi fel, tehát egy #freq-es
   feltétel erősebb, mint egy osztályalapú mérkőzés-szabály. Ezért a két ág
   nem felülírja egymást, hanem eleve kizárja: az ismétlődő ág feltétele
   tartalmazza, hogy nem mérkőzésről van szó. */

/* Egyszeri ág — mérkőzés mindig ide tartozik. */
.sheet-form:has(#freq option[value="once"]:checked) .only-once,
.sheet-form:has(#type-match:checked) .only-once { display:inline; }

/* Ismétlődő ág — csak edzésnél. */
.sheet-form:not(:has(#type-match:checked)):not(:has(#freq option[value="once"]:checked)) .only-repeat { display:flex; }
.sheet-form:not(:has(#type-match:checked)):not(:has(#freq option[value="once"]:checked)) .repeat-note { display:block; }
.sheet-form:not(:has(#type-match:checked)):has(#freq option[value="weekly"]:checked) .only-weekly,
.sheet-form:not(:has(#type-match:checked)):has(#freq option[value="biweekly"]:checked) .only-weekly { display:block; }

/* Típusfüggő mezők. Mérkőzésnél az ismétlődés választója is eltűnik: a
   szabályból mindig edzés generálódik, mert a mérkőzések a szövetségi
   sorsolásból jönnek. Ugyanezt a szerver is kikényszeríti. */
.sheet-form:has(#type-match:checked) .only-training { display:none; }
.sheet-form:has(#type-match:checked) .only-match { display:flex; }

/* ---- színválasztó ---- */

/* A <legend> alapból a fieldset felső keretére ül, és a keret belső
   térközével együtt jobbra csúszik: a felirat így egyetlen másik
   mezőcímkével sem volt egy vonalban. Keret helyett a színválasztó ugyanúgy
   néz ki, mint bármelyik mező — címke, alatta a vezérlő —, a legend pedig
   floattal kikerül a keret-pozícióból. */
.swatches {
  display:flex; flex-wrap:wrap; align-items:center; gap:8px;
  margin:16px 0 0; padding:0; border:0; min-width:0;
}
.swatches legend {
  float:left; width:100%; padding:0; margin:0 0 9px;
  font-size:13px; font-weight:500; color:var(--ink-2);
}
.swatches legend + * { clear:both; }
.sw-opt { position:relative; display:inline-flex; align-items:center; gap:8px; cursor:pointer; }
.sw-opt input { position:absolute; width:1px; height:1px; opacity:0; }
.sw-chip {
  display:block; width:26px; height:26px; border-radius:50%;
  border:1px solid rgba(0,0,0,.14); box-sizing:border-box;
}
.sw-inherit { background:var(--surface-2); border-style:dashed; border-color:var(--line-strong); }
.sw-label { font-size:13.5px; color:var(--ink-2); }
.sw-none { margin-right:6px; }
.sw-opt input:checked + .sw-chip {
  box-shadow:0 0 0 2px var(--surface), 0 0 0 4px var(--ink-2);
}
.sw-opt input:focus-visible + .sw-chip { outline:2px solid var(--club); outline-offset:3px; }

/* ---- csapatszín a szervezet oldalon ---- */

.team-dot {
  display:inline-block; width:10px; height:10px; border-radius:50%;
  margin-right:7px; vertical-align:baseline;
  border:1px solid rgba(0,0,0,.14);
}
.tint { display:inline-block; }
.tint > summary {
  cursor:pointer; font-size:13.5px; font-weight:500; color:var(--ink-2); list-style:none;
  display:inline-block; padding:7px 13px; border-radius:var(--radius-sm);
  border:1px solid var(--line); background:var(--surface);
}
.tint > summary:hover { border-color:var(--line-strong); color:var(--ink); }
.tint > summary:focus-visible { outline:2px solid var(--club); outline-offset:2px; }
.tint[open] > summary { border-color:var(--line-strong); }
.tint > summary::-webkit-details-marker { display:none; }
.tint-form {
  margin-top:10px; padding:16px; max-width:420px;
  background:var(--surface); border:1px solid var(--line); border-radius:var(--radius-sm);
}
.tint-form .swatches { margin:0 0 14px; }

/* =====================================================================
   KEZDŐLAP
   Nem műszerfal: három szám tájékozódásnak, alatta az, ami jön, és ami
   figyelmet kér. A jogosultság-kiíratás lenyílóba került — az a rendszer
   önellenőrzése, nem napi munkaeszköz.
   ===================================================================== */

.tiles {
  display:grid; grid-template-columns:repeat(auto-fit,minmax(104px,1fr));
  gap:10px; margin:0 0 26px;
}
@media (min-width:700px) {
  .tiles { grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:12px; }
}
.tile {
  display:flex; flex-direction:column; gap:1px;
  padding:11px 13px; background:var(--surface);
  border:1px solid var(--line); border-radius:var(--radius); box-shadow:var(--lift);
}
.tile-n { font-size:clamp(19px,4vw,24px); font-weight:700; letter-spacing:-.03em; line-height:1.15; }
.tile-l { font-size:13px; color:var(--muted); }
/* Kattintható csempe: ugyanaz a doboz, csak elvezet valahová. */
a.tile { color:inherit; text-decoration:none; transition:border-color .12s, box-shadow .12s; }
a.tile:hover { border-color:var(--club); box-shadow:var(--lift-2, var(--lift)); }
a.tile:focus-visible { outline:2px solid var(--club); outline-offset:2px; }

.cols { display:grid; grid-template-columns:1.4fr 1fr; gap:28px; align-items:start; }
.cols > section { min-width:0; }
.cols h2 { margin-bottom:10px; }
.cols .agenda, .cols .roster { margin-bottom:12px; }
.cols .agenda-day { padding-top:14px; }
.cols .agenda-day:first-child { padding-top:0; }

@media (max-width:860px) {
  .cols { grid-template-columns:1fr; gap:24px; }
}

/* A heti terv sorai ugyanazt a kártyanyelvet beszélik, mint a naptár. */
.plan-row { padding:6px 0; }
.plan-row.is-cancelled { opacity:.6; }

/* =====================================================================
   ESEMÉNY RÉSZLETEI
   A fejléc ugyanazt a színt viszi, mint a naptárcsempe: az esemény
   ránézésre azonosítható, akárhonnan érkezik ide a felhasználó.
   ===================================================================== */

.ev-head {
  --evc:var(--club);
  --evl:color-mix(in srgb, #FFFFFF var(--ink-mix), var(--evc));
  border-left:4px solid var(--club);
  border-left-color:var(--evl);
  padding:2px 0 2px 18px; margin:0 0 22px;
}
.ev-head h1 { margin-top:14px; }
.ev-head p  { margin-bottom:14px; }
.ev-head.ev-match { border-left-width:6px; }

/* ---- az esemény operatív adatai ----
   Gyülekező, helyszín, eredmény a FEJLÉCBEN. Eddig a gyülekező ideje
   kizárólag a szerkesztő űrlap beviteli mezőjében jelent meg — vagyis
   aki nem szerkeszthetett, egyáltalán nem látta, pedig mérkőzésnél épp a
   szülőnek a legfontosabb adat. */
.ev-facts {
  display:flex; flex-wrap:wrap; gap:6px 26px; margin:0 0 14px; padding:0;
}
.ev-facts > div { min-width:0; }
.ev-facts dt {
  font-size:11px; letter-spacing:.06em; text-transform:uppercase;
  color:var(--muted); font-weight:600; margin:0 0 1px;
}
.ev-facts dd { margin:0; font-size:15px; font-weight:600; }
.ev-score { font-variant-numeric:tabular-nums; letter-spacing:.02em; }
.ev-head .act-row { margin-bottom:6px; }

/* ---- keret-tábla ---- */
/* A NÉV HASÁBJA IS KAP SZÉLESSÉGET. Enélkül ő volt a maradék, és az új
   „Figyelem" hasáb pont belőle vett el: 144 képpont maradt, amin a
   „#34 Kovács Gábor" kettétört. Rögzített elrendezésnél a maradékot a
   szélesség nélküli oszlopok osztják el — a névnek nem szabad köztük
   lennie, mert ő a lap fő oszlopa. */
.tbl-squad .col-name  { width:26%; }
.tbl-squad .col-avail { width:22%; }
/* A keret hasábja a legördülő szélessége: a „— nincs nevezve —" a
   leghosszabb választható érték, és levágva nem olvasható. */
.tbl-squad .col-squad { width:20%; }
/* A figyelmeztetés hasábja csak akkor létezik, ha van benne adat (lásd a
   sablont), ezért itt fix arányt kaphat — nem fenyeget azzal, hogy üresen
   viszi el a helyet. */
.tbl-squad .col-warn { width:18%; }
/* ---- keret posztonként ----
   Csoportsáv a névsorban: nem új doboz, csak halk sáv, ami megmondja, hol
   tart a felsorolás. Az edző ezt olvassa először: van-e kapus, miből hány. */
.tbl tr.tbl-group th {
  padding:10px 14px; text-align:left; font-weight:600;
  background:var(--field); border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
}
.tbl tbody tr:first-child.tbl-group th { border-top:0; }
.grp-name {
  font-size:11px; text-transform:uppercase; letter-spacing:.06em; color:var(--ink-2);
}
.grp-count { margin-left:10px; font-size:12px; font-weight:400; color:var(--muted); }
/* A beugrók saját sorba: ez a sáv válasza arra, hogy „és akkor most ki?" */
.grp-cover {
  display:block; margin-top:3px; font-size:12px; font-weight:400; color:var(--muted);
  overflow-wrap:anywhere;
}
.tag-warn { color:var(--warn); border-color:var(--warn); }
/* A kapitányi jelölés kitöltött címke, mint az elsődleges kapcsolattartóé:
   egy csapatban egy ember viseli, tehát nem sorolható a többi pirula közé. */
.pill-role {
  color:var(--accent); font-weight:600;
  background:color-mix(in srgb, var(--accent) 14%, var(--surface));
}
.pill-soft { color:var(--muted); }
.tbl-squad .avail-comment,
.tbl-squad .ev-warning { display:block; margin-top:3px; font-size:12.5px; }
/* SAJÁT HASÁBBAN a „figyelem" címke fölösleges: az oszlop fejléce mondja
   ki. A szín viszont kell — ez az egyetlen dolog a sorban, ami a döntést
   megállíthatja. A hasáb első eleme nem kap felső margót, különben a
   szomszéd cellák tetejéhez képest elcsúszna. */
.tbl-squad .col-warn .ev-warning { color:var(--warn); font-weight:500; }
.tbl-squad .col-warn .ev-warning:first-child { margin-top:0; }
.tbl-squad select { width:100%; font-size:13px; padding:6px 8px; }
/* Az edzői válasz soron belüli űrlap: a megjegyzés alatt áll, nem külön
   panelben — ott olvasható, amire válaszol. */
.tbl-squad .reply-form { display:flex; gap:6px; margin-top:5px; flex-wrap:wrap; }
.tbl-squad .reply-form input[type=text] { flex:1 1 150px; min-width:0; font-size:13px; padding:5px 8px; }
.tbl-squad .reply-form .btn { flex:0 0 auto; }
/* A visszajelzés-csempék szűkebbek: itt négy szám áll, nem egy műszerfal. */
.panel > .tiles { margin-bottom:18px; }
/* Súgó a címke mellett. Saját soron ez ugyanolyan súlyú sornak látszott,
   mint maga a címke — holott csak zárójeles pontosítás. Ezért egy sorban áll
   a címkével, zárójelben, kisebben. */
.hint { font-size:12px; color:var(--muted); font-weight:400; }
/* Címkén BELÜL: zárójelben, a címkeszöveggel egy sorban. Külön soron ugyanolyan
   súlyúnak látszott, mint maga a címke — holott csak pontosítás. */
label .hint { font-size:11.5px; }
label .hint::before { content:"("; }
label .hint::after  { content:")"; }
/* A vezérlő UTÁN álló súgó viszont nem pontosítás, hanem egész mondatos
   magyarázat: az marad saját sorban, zárójel nélkül. */
input + .hint, select + .hint, textarea + .hint {
  display:block; margin-top:5px; font-size:12px; line-height:1.4;
}
input + .hint::before, select + .hint::before, textarea + .hint::before,
input + .hint::after,  select + .hint::after,  textarea + .hint::after { content:none; }

/* =====================================================================
   FELHASZNÁLÓLISTA
   Minden fiókhoz tartozott egy állandóan nyitott hozzárendelő űrlap, ami
   hosszúra nyújtotta és zajossá tette a listát. A műveletek lenyílóba
   kerültek, így a lap arról szól, kinek mihez van joga.
   ===================================================================== */

.count {
  font-size:13px; font-weight:600; color:var(--muted);
  background:var(--surface-2); border-radius:999px; padding:2px 10px;
  vertical-align:middle; margin-left:6px;
}

/* Szűrősáv: a keresés és a szerepkör együtt szűkíti a listát. */
/* A .userbar beolvadt a .filters-be: egy szűrősor-forma van, nem kettő. */
.filters .field { gap:0; flex:0 0 auto; }
.filters .field > input, .filters .field > select { flex:0 0 auto; }
.filters .field-grow { flex:1 1 240px; max-width:360px; }
/* A szűrőgomb és a mellé tett művelet egy blokk: együtt tördelnek — és a sor
   JOBB SZÉLÉRE kerülnek (`margin-left:auto`), hogy a szűrősor a teljes
   szélességet kitöltse. Balra húzva a gombok a mezők után lógtak, és a
   következő sorba törve is a bal szélen ragadtak. */
.filters-go { display:inline-flex; align-items:center; gap:8px; flex:0 0 auto; margin-left:auto; }
.filters-clear { font-size:13.5px; color:var(--muted); }
.filters-clear:hover { color:var(--ink); }

/* Kompakt sorok kártyák helyett: 77 kártya ötven képernyőnyi volt, és a
   három állandóan nyitott gomb tette a java részét. A műveletek most egy
   lenyíló mögött várnak — a lista arról szól, ki kicsoda. */
.people { list-style:none; margin:0 0 20px; padding:0;
  background:var(--surface); border:1px solid var(--line);
  border-radius:var(--radius); box-shadow:var(--lift); overflow:hidden; }
.person { padding:12px 16px; border-bottom:1px solid var(--line); }
.person:last-child { border-bottom:0; }
.person:hover { background:var(--field); }

.person-main { display:flex; align-items:baseline; justify-content:space-between; gap:14px; flex-wrap:wrap; }
.person-who { min-width:0; flex:1 1 220px; }
.person-name { font-size:14.5px; font-weight:600; }
.person-mail { display:block; font-size:12.5px; color:var(--muted); margin-top:1px; overflow-wrap:anywhere; }
.person-roles { display:flex; flex-wrap:wrap; gap:6px; align-items:center; font-size:12.5px; }

.rolechip {
  display:inline-flex; align-items:baseline; gap:6px;
  padding:3px 9px; border-radius:999px; background:var(--field);
  font-weight:500;
  /* Rögzített oszlopszélességnél a nowrap levágná a hosszú nevet és
     hatókört; így a címke inkább törik. A pötty viszont nem szakadhat el a
     névtől — ezért az saját elem, ami sosem zsugorodik, a név pedig
     magán belül tördelődik. */
  flex-wrap:nowrap; max-width:100%;
}
/* Tördeléskor a tagok NEM ugranak új sorba (akkor a pötty magára maradna),
   hanem összenyomódnak, és a szöveg magán belül törik. */
.rolechip .dot { flex:0 0 auto; align-self:center; }
.rolechip-name { min-width:0; overflow-wrap:break-word; }
.rolechip em { min-width:0; overflow-wrap:break-word; }
.rolechip em { font-style:normal; font-weight:400; color:var(--muted); }
.rolechip em:empty { display:none; }

.person-more { margin-top:8px; }
.person-more > summary {
  display:inline-block; cursor:pointer; list-style:none;
  font-size:12.5px; color:var(--muted);
}
.person-more > summary::-webkit-details-marker { display:none; }
.person-more > summary::after { content:" ▾"; }
.person-more[open] > summary::after { content:" ▴"; }
.person-more > summary:hover { color:var(--ink); }

.person-acts { display:flex; flex-wrap:wrap; gap:14px; margin-top:12px; padding-top:12px; border-top:1px solid var(--line); }
.person-acts .tint-form { max-width:380px; }

/* Lapozó */
.pager { display:flex; align-items:center; gap:16px; margin:0 0 28px; font-size:14px; }
.pager-now { color:var(--muted); }
.pager-off { color:var(--line-strong); }

/* =====================================================================
   AVATAR-MENÜ
   A fejléc jobb szélén ül, és a profil minden nézetébe innen lehet
   belépni. Rejtett jelölőnégyzet tartja nyitva, a takaró réteg bárhová
   kattintva becsukja — inline JavaScript a CSP mellett nem futna.
   ===================================================================== */

.me { position:relative; margin-left:auto; flex:0 0 auto; }
.me-toggle { position:absolute; width:1px; height:1px; opacity:0; }

.avatar {
  display:grid; place-items:center; width:36px; height:36px; flex:0 0 auto;
  border-radius:50%; cursor:pointer; user-select:none;
  font-size:13px; font-weight:650; letter-spacing:.01em; line-height:1;
  color:#fff; background:var(--club);
  border:2px solid var(--surface); box-shadow:0 0 0 1px var(--line-strong);
}
.avatar:hover { filter:brightness(1.1); }
.me-toggle:focus-visible + .avatar { outline:2px solid var(--club); outline-offset:3px; }
.avatar-plain { cursor:default; border-color:transparent; box-shadow:none; }
.avatar-lg { width:46px; height:46px; font-size:16px; }

/* A takaró réteg csak nyitott menünél fogja a kattintást. */
.me-scrim { display:none; }
.me:has(.me-toggle:checked) .me-scrim {
  display:block; position:fixed; inset:0; z-index:40; cursor:default;
}

.me-menu {
  display:none; position:absolute; right:0; top:calc(100% + 10px); z-index:50;
  min-width:232px; padding-bottom:6px; overflow:hidden;
  background:var(--surface); border:1px solid var(--line);
  border-radius:var(--radius); box-shadow:0 18px 44px -18px rgba(12,20,26,.45);
}
.me:has(.me-toggle:checked) .me-menu { display:block; }

.me-head {
  display:flex; align-items:center; gap:11px;
  padding:14px 16px; margin-bottom:6px;
  background:var(--club); color:#fff;
}
.me-head .avatar-plain { background:rgba(255,255,255,.22); }
.me-head > div > strong { display:block; font-size:14.5px; line-height:1.3; }
.me-head > div > span   { display:block; font-size:12.5px; opacity:.82; }

.me-item {
  display:block; width:100%; text-align:left; font:inherit; font-size:14px;
  padding:9px 16px; text-decoration:none; color:var(--ink-2);
  background:none; border:0; cursor:pointer;
}
.me-item:hover { background:var(--field); color:var(--ink); }
.me-item:focus-visible { outline:2px solid var(--club); outline-offset:-2px; }
.me-out { margin-top:6px; padding-top:6px; border-top:1px solid var(--line); }
.me-quit { color:var(--st-absent); }
.me-quit:hover { background:var(--st-absent-soft); color:var(--st-absent); }

/* ---- legördülő menü (ui_menu) ----
   Ugyanaz a mechanika, mint a profilmenünél, csak általánosítva: ide a
   ritkán használt műveletek kerülnek, hogy a napi munka gombjai maradjanak
   elöl. Nem rejt el semmit — rangsorol. */

.menu { position:relative; flex:0 0 auto; }
.menu-toggle { position:absolute; width:1px; height:1px; opacity:0; }
.menu-btn {
  display:grid; place-items:center; width:36px; height:36px;
  border:1px solid var(--line); border-radius:var(--radius-sm);
  background:var(--surface); color:var(--ink-2); cursor:pointer;
}
.menu-btn:hover { border-color:var(--line-strong); color:var(--ink); }
.menu-toggle:focus-visible + .menu-btn { outline:2px solid var(--club); outline-offset:2px; }
.menu:has(.menu-toggle:checked) .menu-btn { border-color:var(--line-strong); color:var(--ink); }

.menu-scrim { display:none; }
.menu:has(.menu-toggle:checked) .menu-scrim {
  display:block; position:fixed; inset:0; z-index:40; cursor:default;
}

.menu-list {
  display:none; position:absolute; right:0; top:calc(100% + 8px); z-index:50;
  min-width:250px; padding:6px; text-align:left;
  background:var(--surface); border:1px solid var(--line);
  border-radius:var(--radius); box-shadow:0 18px 44px -18px rgba(12,20,26,.45);
}
/* Nyitva marad, amíg a benne indított ablak vagy megerősítés él: a menü
   becsukódása különben a saját gyerekét, az ablakot is eltüntetné. */
.menu:has(.menu-toggle:checked) .menu-list,
.menu:has(.sheet-toggle:checked) .menu-list,
.menu:has(details[open]) .menu-list { display:block; }

/* …de amíg az ablak áll, a menü ne lebegjen mellette. A `.menu-list` saját
   rétegkontextust nyit (z-index + position), ezért az ablak elsötétítő rétege
   nem tud ráterülni — kívülről nézve a menü az ablak FÖLÖTT világított.
   A láthatóság öröklődik, tehát a sorokat elrejtjük, az ablakot visszakapcsoljuk. */
.menu:has(.sheet-toggle:checked) .menu-list {
  background:none; border-color:transparent; box-shadow:none;
}
.menu:has(.sheet-toggle:checked) .menu-row { visibility:hidden; }
.menu:has(.sheet-toggle:checked) .sheet-wrap { visibility:visible; }

/* A menüben minden elem teljes szélességű menüsor — a gombforma itt nem
   segít, mert nincs mihez képest kiemelni, és három egymás alatti tömör
   gomb csak zajt csinál. */
/* A POST-ot indító menüpont űrlapba van csomagolva (CSRF-token kell hozzá),
   tehát a gomb nem a sor közvetlen gyereke. Az űrlap ezért átlátszó: nem
   látszik belőle semmi, csak a benne álló gomb viselkedik menüsorként. */
.menu-row > form { display:block; margin:0; }
.menu-row > .btn,
.menu-row > label.btn,
.menu-row > form > .btn,
.menu-row > .ask > summary {
  display:block; width:100%; text-align:left; font:inherit; font-size:14px;
  font-weight:500; padding:9px 12px; border:0; border-radius:6px;
  background:none; color:var(--ink-2); box-shadow:none;
  text-decoration:none; white-space:normal;
}
.menu-row > .btn:hover,
.menu-row > label.btn:hover,
.menu-row > form > .btn:hover,
.menu-row > .ask > summary:hover { background:var(--field); color:var(--ink); }
.menu-row > form > .btn:focus-visible,
.menu-row > label.btn:focus-visible { outline:2px solid var(--club); outline-offset:-2px; }
/* A „+" az ÚJ dolgot felvevő gomboké. A menüben meglévőt módosítunk. */
.menu-row > .sheet-open::before { content:none; }
/* Az archiválás itt is halkabb, de felismerhetően veszélyes. */
.menu-row > .ask { display:block; }
.menu-row > .ask-warn > summary { color:var(--st-late); }
.menu-row > .ask-warn > summary:hover { background:var(--st-late-soft); color:var(--st-late); }
/* Ugyanez a narancs annak a menüsornak is, ami egy lépésben vesz ki valamit
   a forgalomból (inaktiválás) — megerősítést nem kér, mert visszafordítható,
   de a szem ugyanazt a formanyelvet lássa, mint az archiválásnál. */
.menu-row > form > .btn.menu-warn { color:var(--st-late); }
.menu-row > form > .btn.menu-warn:hover { background:var(--st-late-soft); color:var(--st-late); }
.menu-row > .ask[open] > summary { color:var(--muted); }
.menu-row .ask-box { margin:2px 0 4px; max-width:none; }

/* ---- mezszám mezben ----
   A névsor horgonya a szám, és a mez színe ugyanaz, mint a naptárcsempén meg
   a csapatlistán: ránézésre látszik, melyik csapat névsora ez. A szín
   nonce-olt szabályból jön (`--jersey`); ha a csapatnak nincs saját színe, a
   klubszín az alapértelmezés — a mez soha nem marad színtelen. */
.jersey {
  position:relative; display:inline-grid; place-items:center;
  width:40px; height:40px; line-height:1;
}
.jersey-svg {
  position:absolute; inset:0; width:100%; height:100%;
  fill:var(--jersey, var(--club)); stroke:none;
}
/* A szám a MELLKASON ül, ahogy igazi mezen is: a törzs felső felén, nem a
   szegély fölött. A rajz y 3–21 között áll a 24-es viewBoxban, aminek a
   közepe 53% — ez a mellkas magassága. */
.jersey b {
  position:absolute; left:0; right:0; top:53%; transform:translateY(-50%);
  z-index:1; text-align:center; font-size:13px; font-weight:700;
  color:#fff; font-variant-numeric:tabular-nums; letter-spacing:-.02em;
}
/* Szám nélkül halványabb: a hiány látszódjon, de ne kiabáljon. */
.jersey.is-empty { opacity:.32; }

/* Ikonos megerősítés táblázatsorban. A szöveges címke szétfeszítené az
   oszlopot; a felirat a `title`-ben és képernyőolvasónak marad meg. */
.ask-icon { display:inline-block; }
/* A fajsúly szándékos: a `.ask.ask-warn > summary` borostyánra festené, és
   tizennyolc borostyán kuka egy névsorban hangosabb, mint a névsor maga.
   Alapból halk, és csak rámutatva vagy nyitva válik veszélyes színűvé. */
.ask.ask-icon > summary {
  display:grid; place-items:center; width:32px; height:32px;
  border-radius:var(--radius-sm); color:var(--muted);
  text-decoration:none; list-style:none;
}
.ask.ask-icon > summary:hover { background:var(--st-absent-soft); color:var(--st-absent); }
.ask.ask-icon[open] > summary { background:var(--st-absent); color:#fff; }
.ask-icon[open] > summary::after { content:none; }
/* A kérdés egy 52 képpontos cellából nyílik: ott elfért egy ikon, egy mondat
   nem. Ezért kilép a cellából, a sor alá, jobbra igazítva.

   A szűk oszlop CSAK a névsoré: ott a művelet egyetlen kuka ikon. Máshol
   (szervezeti fa, törzsadat-listák) szöveges gombok állnak benne, és a
   `table-layout:fixed` nem növeszti meg a cellát a tartalom kedvéért — a
   gomb egyszerűen kilógott a táblázatból. */
.tbl-roster .col-act { width:52px; }
.tbl .ask-icon { position:relative; }
.tbl .ask-icon .ask-box {
  position:absolute; right:0; top:calc(100% + 6px); z-index:5;
  width:max-content; max-width:min(320px, 70vw);
  box-shadow:0 14px 32px -12px rgba(12,20,26,.4);
}
/* A táblázat vízszintesen görgethető, ami a kilógó dobozt levágná. Nyitott
   kérdésnél viszont nincs mit görgetni — ott a vágás felfüggeszthető. */
.scroller:has(.ask-icon[open]) { overflow:visible; }

/* ---- játékos-fejléc a fényképpel ----
   Két hasáb: a kép és a név. A kép hasábja FIX szélességű, hogy a név
   ugyanott kezdődjön minden adatlapon — a kép megléte nem tolhatja el a
   címsort. Telefonon a kettő egymás mellett marad, csak kisebben: a fejléc
   a lap teteje, azt nem éri meg két sorra bontani. */

.phead { display:flex; gap:16px; align-items:flex-start; margin:0 0 4px; }
.phead-txt { min-width:0; }
.phead-txt h1 { margin:0; }
.phead-txt p { margin:4px 0 0; }
.phead-photo { flex:0 0 auto; width:96px; text-align:center; }

/* `object-fit:cover`: a bélyegkép nem biztos, hogy négyzetes — vágjuk, nem
   torzítjuk. Egy megnyúlt arc rosszabb, mint egy levágott váll. */
.phead-pic {
  display:block; width:96px; height:96px; object-fit:cover;
  border-radius:var(--radius-sm); border:1px solid var(--line);
  background:var(--field);
}
.phead-empty {
  display:flex; align-items:center; justify-content:center;
  font-size:30px; font-weight:600; color:var(--muted);
  border-style:dashed;
}
/* Egymás ALATT, nem egymás mellett: a hasáb 96 képpont, két szó nem fér
   el egy sorban — tördelve pedig magától is így állna, csak csúnyábban. */
.phead-acts { display:flex; flex-direction:column; align-items:center; gap:2px; margin-top:6px; }
/* A „+" a lenyíló ablakok nyitógombjának jele, ott „új tétel" a jelentése.
   Itt nem új adat keletkezik, hanem egy meglévő kép cserélődik. */
.phead-acts .sheet-open::before { content:none; }
/* A fénykép műveletei nem gombok: a lap tárgya a játékos, nem a kép.
   Halk szöveges hivatkozás — ugyanaz a méret a `<a>`-nak, a lenyíló
   ívnek (`ui_sheet`) és a megerősítésnek (`ui_confirm`). */
/* Halk hivatkozás GOMBOK KÖZT. A nézetváltó szegmensei is kerekített,
   halványzöld dobozok — egy `btn-outline` mellettük harmadik NÉZETNEK
   látszott, pedig művelet. Aláhúzott szöveg mellett ez nem téveszthető
   össze. */
.head-lnk { align-self:center; margin-left:4px; }

.lnk-quiet, .phead-acts .ask > summary {
  font-size:13px; color:var(--muted); cursor:pointer;
  background:none; border:0; padding:0; text-decoration:underline;
}
.lnk-quiet:hover, .phead-acts .ask > summary:hover { color:var(--ink); }
.phead-acts .ask { display:inline-block; }

@media (max-width:640px) {
  .phead-photo, .phead-pic { width:72px; }
  .phead-pic { height:72px; }
  .phead-empty { font-size:24px; }
}

/* ---- hasábválasztó (statisztika-profil) ----
   Rács, nem táblázat: soronként három különböző típusú elem áll (jelölés,
   magyarázat, sorszám), és telefonon más elrendezésben kell lenniük.
   A KIKAPCSOLT sor halkabb, de nem tűnik el — abból kell látszania, hogy
   mi az, amit be lehetne kapcsolni. */

.colpick { list-style:none; margin:10px 0 0; padding:0; border:1px solid var(--line);
           border-radius:var(--radius-sm); overflow:hidden; }
.colpick-row {
  display:grid; grid-template-columns:minmax(150px, 15em) 1fr 74px;
  gap:4px 14px; align-items:center;
  padding:10px 14px; border-bottom:1px solid var(--line);
}
.colpick-row:last-child { border-bottom:0; }
.colpick-row.is-off { background:var(--field); }
.colpick-row.is-off .colpick-note { color:var(--muted); }
.colpick-on { margin:0; }
.colpick-note { font-size:12.5px; color:var(--ink-2); }
.colpick-num { width:100%; text-align:center; font-variant-numeric:tabular-nums; }

@media (max-width:640px) {
  /* Telefonon a magyarázat a jelölés ALÁ kerül, a sorszám pedig a jelölés
     mellé marad: az a kettő tartozik össze („benne van-e" és „hányadik").
     A helyeket ki kell írni — magától a teljes szélességű magyarázat után
     a számmező új sort kezdene, és végigfutna a lapon. */
  .colpick-row { grid-template-columns:1fr 64px; }
  .colpick-on   { grid-column:1; grid-row:1; }
  .colpick-num  { grid-column:2; grid-row:1; }
  .colpick-note { grid-column:1 / -1; grid-row:2; }
}

/* ---- névsorszerkesztő (Játékosok kezelése) ----
   Rács, nem táblázat: a sor öt eleme különböző típusú vezérlő, és telefonon
   más elrendezésben kell állniuk. Táblázatban ez `table-layout` csatákká
   fajulna, rácsban egy sor a szabály. */

.ros { border:1px solid var(--line); border-radius:var(--radius-sm); overflow:hidden; }
/* Hét oszlop: a születési év és a sportorvosi SAJÁT hasábot kap. Eddig a
   név alatt csúsztak össze, ahol egyik sem volt összevethető a többiekével —
   pedig a keret átnézésekor épp ez a két szám fut végig a szemed előtt. */
.ros-head, .ros-row {
  display:grid; align-items:center; gap:10px;
  grid-template-columns:64px minmax(0,1fr) 58px 150px 148px 148px 36px;
  padding:8px 12px;
}
.ros-head {
  background:var(--field); border-bottom:1px solid var(--line);
  font-size:11px; text-transform:uppercase; letter-spacing:.06em;
  color:var(--muted); font-weight:600;
}
.ros-row + .ros-row { border-top:1px solid var(--line); }
.ros-row:hover { background:var(--field); }
.ros-shirt { text-align:center; font-variant-numeric:tabular-nums; }
.ros-name { min-width:0; }
.ros-name a { font-weight:600; color:var(--ink); text-decoration:none; }
.ros-name a:hover { color:var(--club); text-decoration:underline; }
.ros-year { font-size:13px; color:var(--muted); font-variant-numeric:tabular-nums; }
.ros-med  { font-size:13px; font-weight:600; }

/* Az eltávolítás JELÖLÉS, nem azonnali művelet: a mentésig visszavonható.
   Ezért rejtett jelölőnégyzet, ikonnal — és bejelölve a SOR húzódik át, hogy
   mentés előtt látszódjon, mi fog eltűnni. */
.ros-del {
  display:grid; place-items:center; width:32px; height:32px; cursor:pointer;
  border-radius:var(--radius-sm); color:var(--muted);
}
.ros-del input { position:absolute; width:1px; height:1px; opacity:0; }
.ros-del:hover { background:var(--st-absent-soft); color:var(--st-absent); }
.ros-del:has(input:checked) { background:var(--st-absent); color:#fff; }
.ros-del input:focus-visible + .ui-icon { outline:2px solid var(--club); outline-offset:3px; }
.ros-row:has(.ros-del input:checked) { background:var(--st-absent-soft); }
.ros-row:has(.ros-del input:checked) .ros-name a { text-decoration:line-through; color:var(--muted); }
.ros-row:has(.ros-del input:checked) .ros-shirt,
.ros-row:has(.ros-del input:checked) select { opacity:.45; }

/* A felvehetők listája ezen a lapon magasabb lehet: nem ablakban van. */
.pick-tall { max-height:min(58vh, 520px); }
/* A jelölt sora kinyílik: bejelölve megjelenik a mezszám és a poszt, hogy a
   felvétel EGY mentés legyen. A mezők jelöletlenül is a DOM-ban vannak
   (JS nélkül nincs más mód a feltételes megjelenítésre), de a szerver csak a
   bejelölt sorokét nézi. */
.cand-row { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.cand-row > .check { flex:1 1 220px; min-width:0; }
.cand-fields { display:none; gap:8px; margin-left:auto; }
.cand-row:has(input[type="checkbox"]:checked) { background:var(--club-soft); }
.cand-row:has(input[type="checkbox"]:checked) .cand-fields { display:flex; }
.cand-fields .ros-shirt { width:66px; }
.cand-fields select { width:140px; }

/* ---- csapatválasztó a felvevő ablakban ----
   Egyszerre EGY csapathoz adunk hozzá, minden adatával. A poszt viszont
   szakosztályfüggő, a listáját tehát a választott csapat dönti el — és
   JavaScript nélkül nem cserélhető utólag. Ezért minden csapat a maga
   mezőivel kimegy, és csak a bejelölté látszik. Ugyanaz a fogás, mint a
   névsor-varázsló felvehető sorainál, csak rádióval: ott több sor is
   bejelölhető, itt pontosan egy. */
.teampick { display:flex; flex-direction:column; gap:2px; }
.teampick-row {
  display:flex; align-items:center; gap:10px; cursor:pointer;
  padding:9px 12px; border-radius:var(--radius-sm);
}
.teampick-row:hover { background:var(--field); }
.teampick-row:has(input:checked) { background:var(--club-soft); font-weight:600; }
.teampick-fields { display:none; padding:2px 12px 14px; }
.teampick-row:has(input:checked) + .teampick-fields { display:block; }
/* Az űrlap a kiválasztott csapat alatt nyílik, nem a lista végén: enélkül a
   mezők egy hosszú listánál elszakadtak volna attól, amire vonatkoznak. */
.teampick-fields .field-grid { margin:0; }

/* A kereső a lista FÖLÖTT áll, a panel fejlécében — nem a lap alján. */
.pick-search { display:flex; align-items:center; gap:8px; margin-left:auto; flex-wrap:wrap; }
.pick-search input[type=search] { width:min(240px, 52vw); }
.pick-empty { padding:14px 12px; margin:0; }

/* ---- varázsló lépésjelző ----
   Nem díszítés: a lépésenkénti mentés enélkül véget nem érő űrlapnak tűnne.
   Megmondja, hol tartasz és mi jön még. */
.wiz {
  display:flex; flex-wrap:wrap; gap:8px 18px; list-style:none;
  margin:0 0 18px; padding:0;
}
.wiz li { display:flex; align-items:center; gap:8px; font-size:13.5px; color:var(--muted); }
.wiz-n {
  display:grid; place-items:center; width:24px; height:24px; flex:0 0 auto;
  border-radius:50%; font-size:12.5px; font-weight:650;
  background:var(--field); color:var(--muted); border:1px solid var(--line);
}
.wiz li.is-here { color:var(--ink); font-weight:600; }
.wiz li.is-here .wiz-n { background:var(--club); color:#fff; border-color:var(--club); }
.wiz li.is-done .wiz-n { background:var(--club-soft); color:var(--club); border-color:transparent; }

@media (max-width:720px) {
  .wiz-l { display:none; }
}

/* A névsorszerkesztő hét oszlopa ~1050 képpontot kér. A saját töréspontja
   ezért magasabb a lap többi eleménél: 1080 alatt nem szorulnak össze a
   hasábok, hanem a SOR tördel — fent a mez, a név és a törlés, alatta az
   évjárat és a sportorvosi, majd a két poszt. */
@media (max-width:1080px) {
  .ros-head { display:none; }
  .ros-row {
    grid-template-columns:56px auto minmax(0,1fr) 32px;
    grid-template-areas:
      'shirt name name del'
      'year  med  med  med'
      'pos   pos  pos  pos'
      'pos2  pos2 pos2 pos2';
    gap:8px; padding:10px 12px;
  }
  .ros-shirt { grid-area:shirt; }
  .ros-name  { grid-area:name; }
  .ros-year  { grid-area:year; }
  .ros-med   { grid-area:med; }
  .ros-del   { grid-area:del; }
  .ros-row > select:nth-of-type(1) { grid-area:pos; }
  .ros-row > select:nth-of-type(2) { grid-area:pos2; }
}

/* ---- widget-sáv (globális) ----
   Kísérőinformáció, nem fő tartalom. Széles kijelzőn jobb oldali tapadó
   sávban áll, a tartalmi keret MELLETT — a keret szélessége nem változik
   tőle, a sáv negatív margóval a jobbra maradó üres helyre lóg ki. Keskenyen
   a tartalom után jelenik meg, vízszintesen húzható kártyasorként.

   Hogy mi kerül ide, azt a config/widgets.php és a widget_settings dönti el;
   ez a szabálykészlet csak a HELYÉRŐL szól. */

/* Visszalépő morzsa a lapfejléc fölött. A mérete RÖGZÍTETT, mert a
   widget-sáv igazítása erre épül: 24 sormagasság + 10 alsó térköz = 34.
   A szabály itt áll, nem a tipográfiánál: a `.muted` azonos fajsúlyú, és a
   fájlban később jön — ott a margó felülíródna. */
.crumb { margin:0 0 10px; line-height:24px; }

.page-body { display:block; }
.page-rail { margin:18px 0 0; }

/* A sáv csak akkor jelenik meg oldalt, ha a hely tényleg megvan.
   A töréspont számolt, nem tetszőleges:
     bal menü            252
     tartalmi keret     1180  (1120 + 2×30 belső térköz)
     sáv + rés     284 + 24 = 308
     jobb oldali levegő   40
     ────────────────────────
                        1780
   Ez alatt nincs hova kilógni, ezért marad a kártyasor. Köztes, szűkített
   változat nincs: vagy mellé fér, vagy csúszka. */
@media (min-width:1780px) {
  /* A szélesség a tényleges maradék hely, nem fix érték: fix 284-gyel a jobb
     oldal harmada üresen maradna. A felső határ azért kell, hogy nagyon
     széles kijelzőn a kártyák ne nyúljanak el. */
  .page-body.has-rail {
    --rail:clamp(284px, calc(100vw - 1478px), 460px);
    display:grid; grid-template-columns:minmax(0,1fr) var(--rail);
    gap:0 24px; margin-right:calc(-1 * (var(--rail) + 24px));
  }
  .page-body.has-rail > .page-main { grid-column:1; grid-row:1; min-width:0; }
  .page-body.has-rail > .page-rail {
    /* A sáv a LAPFEJLÉCHEZ igazodik, nem a tartalomoszlop tetejéhez — ott
       ugyanis a visszalépő morzsa áll, ami nem a lap címe. A 22 a h1 saját
       felső térköze: ennyivel kezdődik lejjebb a fejléc a hasáb tetejénél. */
    grid-column:2; grid-row:1; align-self:start; margin:22px 0 0;
    /* A fejlécsáv tapadó és a 20-as rétegen van: enélkül görgetéskor
       ráfeküdne a sávra. A 68 = a sáv magassága plusz levegő. */
    position:sticky; top:68px;
  }
  /* Ahol morzsa is van a fejléc fölött, annyival lejjebb: a morzsa
     24 képpont sormagasság + 10 alsó térköz. Nem becslés — a `.crumb`
     mérete ezért van rögzítve. */
  .page-body.has-rail:has(> .page-main > .crumb:first-child) > .page-rail {
    margin-top:34px;
  }
  .page-rail .panel { margin:0; }
  /* A sávban a kártyák egymás alatt állnak: ott a függőleges hely az olcsó. */
  .page-rail .ev-strip {
    flex-direction:column; overflow:visible; padding-bottom:0; scroll-snap-type:none;
  }
  .page-rail .ev-card { flex:0 0 auto; }
}
.panel-tight { padding:14px 15px; }
.panel-tight .panel-head { margin-bottom:10px; }
.panel-tight h3 { font-size:15px; }
/* A „Naptár” gomb, nem szöveglink: a sáv fejlécében ez egy művelet, és a
   nyilak mellett szöveglinkként más súlyúnak látszott. Az ikon ugyanaz,
   mint az oldalsó menüben — a link is ugyanoda visz. */
.rail-more {
  display:inline-flex; align-items:center; gap:6px;
  margin-left:auto; padding:5px 10px; font-size:12.5px; font-weight:500;
}
.rail-more .side-icon { width:15px; height:15px; }
.rail-note { margin:12px 0 0; font-size:12px; line-height:1.5; color:var(--muted); }

/* ---- widget-beállítások ----
   Oldalanként egy sor: balra, hogy melyik oldal, jobbra a választás. Nem
   táblázat-szerkesztő, mert oldalanként egyetlen döntés van. */
.widget-form { margin-top:4px; }
.widget-row {
  display:flex; align-items:center; gap:14px; flex-wrap:wrap;
  padding:10px 0; border-bottom:1px solid var(--line);
}
.widget-row:last-of-type { border-bottom:0; }
.widget-page { flex:1 1 220px; min-width:0; }
.widget-page strong { display:block; font-size:14px; font-weight:600; }
.widget-page span { font-size:12px; color:var(--muted); font-family:ui-monospace, SFMono-Regular, Menlo, monospace; }
.widget-row .field { flex:0 0 240px; max-width:100%; }
.widget-row .field label:empty { display:none; }
.widget-form > .btn { margin-top:16px; }

/* Kártyasor. Nem Swiper: `scroll-snap` érintésen ugyanazt az élményt adja,
   viszont nem hoz be JavaScript-függőséget — a lap enélkül is teljes értékű,
   és a sor egérrel-billentyűvel is görgethető. */
.ev-strip {
  display:flex; gap:9px; overflow-x:auto; padding-bottom:6px;
  scroll-snap-type:x mandatory; overscroll-behavior-x:contain;
  /* Alapból vékony, halk csúszka: JavaScript nélkül ez az EGYETLEN mód
     egérrel léptetni, tehát nem tüntethető el. */
  scrollbar-width:thin;
  scrollbar-color:var(--line-strong) transparent;
}
/* Ha az app.js kitette a léptetőnyilakat, a natív csúszka mehet: Windowson
   vastag és zajos, és már van helyette gomb. macOS-en ráúszó, ott eddig sem
   zavart — de a nyilak ott is jól jönnek egérrel. */
.ev-strip.has-nav { scrollbar-width:none; padding-bottom:0; }
.ev-strip.has-nav::-webkit-scrollbar { display:none; }

/* Léptetők a panel fejlécében, nem a kártyák fölött: így nem takarnak
   tartalmat, és nem kell abszolút pozicionálás. */
/* A „Naptár” link viszi a szabad helyet, a nyilak utána jönnek — így a
   kettő EGYÜTT áll jobbra, nem szétdobva a fejlécben. */
.strip-nav { display:flex; gap:4px; }
.strip-step {
  width:28px; height:28px; display:grid; place-items:center; padding:0;
  cursor:pointer; color:var(--ink-2); background:var(--field);
  border:1px solid var(--line); border-radius:var(--radius-sm);
}
.strip-step .ui-icon { width:15px; height:15px; }
.strip-step:hover { border-color:var(--line-strong); color:var(--ink); background:var(--surface-2); }
.strip-step:focus-visible { outline:2px solid var(--club); outline-offset:2px; }
.ev-card {
  flex:0 0 min(84%, 244px); scroll-snap-align:start;
  display:block; padding:10px 12px; text-decoration:none; color:inherit;
  background:var(--field); border-radius:var(--radius-sm);
  border:1px solid transparent; border-left:3px solid var(--line-strong);
}
.ev-card:hover { background:var(--surface-2); border-color:var(--line); border-left-color:var(--ink-2); }
/* A mérkőzés kiemelve: abból van kevés, és arra készül a keret. */
.ev-card.is-match { border-left-color:var(--accent); }
.ev-card.is-off { opacity:.6; }
/* A LEJÁRT BECSLÉS ugyanezen a csatornán szól: a bal szél a sürgősségé.
   Nem piros, hanem a „késés" színe — a naplóban is ez jelöli a lejárt
   visszatérést (`.s-late`), és ez nem hiba, hanem megválaszolatlan kérdés. */
.ev-card.is-late { border-left-color:var(--st-late); }
/* Fent az azonosítás, lent a körülmények. A típus a cím mellett zárójelben:
   ugyanahhoz a kérdéshez tartozik („mi ez"), nem az adatsorhoz. */
.ev-card-title {
  display:block; font-size:13.5px; font-weight:600; line-height:1.35;
  margin:0 0 3px; overflow-wrap:anywhere;
}
/* A típus a címhez tartozik, de nem vele egyenrangú: kisebb és halkabb,
   hogy a cím maradjon a kártya horgonya. */
.ev-card-kind { font-size:11.5px; font-weight:400; color:var(--muted); }
.ev-card-title .tag { margin-left:4px; }
.ev-card-meta {
  display:block; font-size:11.5px; color:var(--muted); line-height:1.5;
  font-variant-numeric:tabular-nums;
}
.ev-card-meta em { font-style:normal; }
.ev-card-meta .v { white-space:nowrap; }
/* A tagolójel halkabb, mint az adat, amit elválaszt — különben a szem
   először a vonalakat látja meg, nem az értékeket. */
.ev-card-meta .sep {
  display:inline-block; margin:0 6px; color:var(--line-strong);
}
.ev-empty { margin:0; font-size:13px; }

/* =====================================================================
   PROFILOLDAL
   ===================================================================== */

.profile-head { display:flex; align-items:center; gap:14px; margin:22px 0 16px; }
.profile-head h1 { margin:0; }
.profile-head p  { margin:2px 0 0; font-size:13.5px; }
.profile-tabs { margin:0 0 24px; flex-wrap:wrap; }

.panel-form { max-width:620px; }
.panel-form .btn { margin-top:18px; }
.panel-form h3 { margin-top:26px; }
.panel-form .panel { margin:18px 0 0; box-shadow:none; }

.role-cards { list-style:none; margin:14px 0 0; padding:0; display:flex; flex-direction:column; gap:8px; }
.role-card {
  display:flex; align-items:flex-start; gap:11px;
  padding:13px 15px; background:var(--field); border-radius:var(--radius-sm);
}
.role-card .dot { margin-top:6px; }
.role-card strong { display:block; font-size:14.5px; }
.role-card .muted { font-size:13px; }
.role-desc { margin:5px 0 0; font-size:13px; color:var(--ink-2); max-width:52ch; }
.role-since { margin-left:auto; font-size:12.5px; white-space:nowrap; }
.ask-icon.role-since { display:block; }
/* A név és a jelölése egy sorban áll, nem egymás alatt. */
.role-title { display:flex; align-items:center; gap:8px; margin:0; flex-wrap:wrap; }
.role-title strong { display:inline; }
.role-title .tag { margin-left:0; }
/* Kártyaműveletek: a módosítás elöl, az eltávolítás halkabban alatta. */
.role-acts {
  margin-left:auto; font-size:12.5px;
  display:flex; flex-direction:column; align-items:flex-end; gap:7px;
}
/* …de ha IKONOK állnak benne, akkor egy sorban: két 32 képpontos rajz
   egymás alatt kétszer olyan magas kártyát csinálna, mint amennyi kell.
   Ugyanaz a szabály, mint a táblázatok műveletsoránál. */
.role-acts:has(.btn-icon), .role-acts:has(.ask-icon) {
  flex-direction:row; align-items:center; gap:4px;
}
/* A kártyában is ugyanaz a négyzet, amit a táblázatsorban adunk — akár a
   műveletsorban áll (`.role-acts`), akár közvetlenül a kártya jobb szélén
   (`.role-since`, pl. szerepkör visszavonása). */
.role-card .ask.ask-icon > summary {
  display:grid; place-items:center; width:32px; height:32px;
  padding:0; border:0; background:none; color:var(--muted);
  border-radius:var(--radius-sm); cursor:pointer; list-style:none;
}
.role-card .ask.ask-icon > summary::-webkit-details-marker { display:none; }
.role-card .ask.ask-icon > summary:hover {
  background:var(--st-absent-soft); color:var(--st-absent);
}
.role-card .ask.ask-icon[open] > summary::after { content:none; }
.role-card .ask.ask-icon[open] > summary { background:var(--field); color:var(--ink); }
/* A megerősítő doboz a kártyából is kilebeg, jobbra igazítva — a kártya
   jobb szélén 64 képpont van, egy mondat nem fér bele. */
.role-card .ask-icon { position:relative; }
.role-card .ask-icon .ask-box {
  position:absolute; right:0; top:calc(100% + 6px); z-index:5;
  width:max-content; max-width:min(320px, 70vw);
  box-shadow:0 14px 32px -12px rgba(12,20,26,.4);
}

@media (max-width:600px) {
  .role-card { flex-wrap:wrap; }
  .role-since { margin-left:0; width:100%; }
  .role-acts { margin-left:0; width:100%; align-items:flex-start; }
}

/* Az oldalsáv lábában a saját fiók — a kilépés az avatar-menübe került,
   hogy ne két helyen álljon ugyanaz a művelet. */
.side-me {
  display:flex; align-items:center; gap:10px; text-decoration:none;
  padding:10px 12px; border-radius:var(--radius-sm); color:var(--ink);
}
.side-me:hover { background:var(--field); }
.side-me .avatar-plain { width:32px; height:32px; font-size:12px; }
.side-me strong { display:block; font-size:13.5px; font-weight:600; }
.side-me em { display:block; font-style:normal; font-size:12px; color:var(--muted); }

/* A gyors jelenlét QR-kódja. Az SVG beágyazva megy ki, ezért nyomtatásban
   is éles marad — az öltözőajtóra kitűzött lap a tipikus használat. */
.qr { margin:4px 0 18px; line-height:0; }
.qr svg { max-width:100%; height:auto; }
@media print {
  .qr svg { width:70mm; height:70mm; }
  .code-panel { border:0; box-shadow:none; }
}

/* ---- táblázatos listák ---- */

/* Rögzített elrendezés: a szélességet a szabály adja, nem a tartalom.
   Automatikus elrendezésnél minden oldal és minden rendezés más
   oszlopszélességet kapott — a leghosszabb név vagy e-mail-cím döntött —,
   és a táblázat lapozáskor odébb ugrott a szem alól. */
.tbl { width:100%; border-collapse:collapse; font-size:14px; table-layout:fixed; }

/* ---- IGAZÍTÁS: egy szabály minden táblázatra ----
   A hasábok középre igazítanak — rövid értékek (szám, évjárat, állapot,
   művelet) így rendezettebbek, mint balra zárva, és a fejléc velük együtt
   mozog.

   A FŐ OSZLOP kivétel: a nevet, a megnevezést balra zárva futja végig a szem,
   és a középre igazítás ragged bal szélt ad, amiben a keresés lassabb. A fő
   oszlop jelölése `col-name` a fejlécen ÉS a cellán — a fejléc csak így tud
   együtt mozogni a cellával, mert a cella tartalmáról a CSS-nek nincs
   tudomása. Tartalékként az az oszlop is balra marad, amelyikben a fő link
   (`.tbl-main`) vagy egy alsor (`.tbl-sub`) áll. */
.tbl th, .tbl td { text-align:center; vertical-align:middle; }
/* Függőlegesen is középen: a névhez alsor tartozik, a szomszéd hasábban
   egyetlen szó áll — felülre zárva az a szó a név fölé csúszna, nem a
   sorhoz tartozna. Kivétel a névsor kezelő rácsa, ami nem táblázat. */
.tbl th.col-name,
.tbl td.col-name,
.tbl td:has(> .tbl-main),
.tbl td:has(> .tbl-sub) { text-align:left; }
.tbl thead th {
  text-align:center; font-size:11px; text-transform:uppercase; letter-spacing:.06em;
  color:var(--muted); font-weight:600; padding:13px 14px 11px; white-space:nowrap;
  background:var(--field); border-bottom:1px solid var(--line);
}
/* Rendezés: a fejléc link, mert a rendezés szerveroldali. A nyíl helye
   akkor is megvan, ha nem ez az aktív oszlop — különben a fejlécek
   odébb ugranának kattintásra. */
.tbl thead a.sort {
  display:inline-flex; align-items:center; justify-content:center; gap:5px;
  color:inherit; text-decoration:none; letter-spacing:inherit;
}
.tbl thead a.sort:hover { color:var(--club); }
.tbl thead a.sort:focus-visible { outline:2px solid var(--club); outline-offset:3px; border-radius:3px; }
.tbl thead a.sort.is-on { color:var(--ink); }
/* A jel mindig ott van, csak halkan: a fejléc így magától elárulja, hogy
   rendezhető. Aktív oszlopon teli erővel és egy irányba mutatva. */
.sort-arrow {
  width:14px; height:14px; flex:0 0 auto; opacity:.45;
  fill:none; stroke:currentColor; stroke-width:2;
  stroke-linecap:round; stroke-linejoin:round;
}
.tbl thead a.sort:hover .sort-arrow { opacity:.75; }
.tbl thead a.sort.is-on .sort-arrow { opacity:1; }

/* A fejléc a kártya tetejéhez tapadt: nem volt felső térköze, és semmi nem
   választotta el az első sortól — így inkább az első sor részének látszott. */
.tbl thead tr:first-child th:first-child { border-top-left-radius:var(--radius); }
.tbl thead tr:first-child th:last-child  { border-top-right-radius:var(--radius); }
.tbl tbody tr:first-child { border-top:0; }
.tbl tbody tr { border-top:1px solid var(--line); }
.tbl tbody tr:hover { background:var(--field); }
.tbl td { padding:11px 14px; }
.tbl-main { font-weight:600; color:var(--ink); text-decoration:none; }
.tbl-main:hover { color:var(--club); text-decoration:underline; }
.tbl-soft { color:var(--muted); font-size:13px; overflow-wrap:anywhere; }
/* A táblázat maga a kártya: keret, lekerekítés, árnyék — így a lista
   ugyanúgy „doboz", mint a panelek, nem csak sorok a lap hátterén. */
.tbl-card {
  background:var(--surface); border:1px solid var(--line);
  border-radius:var(--radius); box-shadow:var(--lift); overflow:hidden;
}
/* Játékoslista-oszlopok. A név kapja a maradékot: az a leghosszabb, és az
   kell a leginkább egészben. */
.tbl .col-shirt { width:58px; white-space:nowrap; }
.tbl .col-shirt:has(.jersey) { width:64px; }

.tbl .col-team  { width:20%; }
.tbl .col-med   { width:24%; font-weight:600; }

/* ---- Felszerelés ----
   A méret és az állapot rövid érték, fix sávot kap; a tétel és a játékos
   neve kapja a maradékot. Az állapot félkövér, mert a lista ezért az egy
   szóért létezik: nála van, vagy visszavéve. */
.tbl .col-size  { width:96px; white-space:nowrap; }
.tbl .col-state { width:140px; font-weight:600; }
/* A két „hosszú" hasáb — a gyerek neve és a tétel neve — fix arányt kap,
   különben a hat oszlop mindkettőt annyira összenyomja, hogy a nevek
   betűnként törnek. A tétel balra zárva fut, mint minden fő oszlop. */
/* Csak a kiadási listán: ott HÉT hasáb osztozik a helyen (játékos, csapat,
   tétel, méret, kiadva, állapot, művelet). Szélesség nélkül a maradékon
   osztozó műveletoszlop nullára fogyott, és a gomb kilógott a táblázatból —
   minden hasáb kap tehát mértéket, és a végösszeg belefér a kártyába.
   A művelet azóta EGY ikon (visszavétel), tehát a felszabaduló hely a
   tételnévé és a játékosnévé lett. */
.tbl-equip-list .col-name  { width:23%; overflow-wrap:normal; }
.tbl-equip-list .col-team  { width:12%; }
.tbl-equip-list .col-item  { width:24%; text-align:left; }
.tbl-equip-list .col-size  { width:76px; }
.tbl-equip-list .col-state { width:150px; }
.tbl-equip-list .col-act   { width:84px; }
/* Mez a listában: a sziluett a szám körül, mellette a tétel neve — a kettő
   egy sorban marad, mert együtt azonosít. */
.equip-jersey { display:inline-flex; align-items:center; gap:8px; }
.equip-jersey > span { font-weight:600; }

/* Méretskála szerkesztője: a méretek csipeszként állnak egymás mellett.
   Soronként egy-egy méret külön űrlap lenne — így a lista három sor, nem
   fél képernyő. */
.scale { padding:14px 18px; border-top:1px solid var(--line); }
.scale:first-child { border-top:0; }
.scale h4 { margin:0 0 10px; font-size:14px; }
.size-row { display:flex; flex-wrap:wrap; gap:8px; margin-bottom:12px; }
.size-chip {
  display:inline-flex; align-items:center; gap:6px;
  padding:5px 8px 5px 11px; border:1px solid var(--line); border-radius:999px;
  background:var(--surface); font-size:13px;
}
.size-chip b { font-variant-numeric:tabular-nums; }
.size-chip.is-off { opacity:.5; }
.size-chip form { margin:0; }
.size-chip .size-act {
  display:inline-flex; border:0; background:none; padding:2px; color:var(--muted); cursor:pointer;
}
.size-chip .size-act:hover { color:var(--club); }
.size-icon { width:14px; height:14px; fill:none; stroke:currentColor; stroke-width:2;
             stroke-linecap:round; stroke-linejoin:round; }
.size-chip .ask { margin:0; }
.size-chip .ask > summary { padding:0; }
/* A skála fejléce: a neve balra, a felvevő gomb jobbra — a méretek sora
   alatta fut végig, teljes szélességben. */
.scale-head {
  display:flex; align-items:center; justify-content:space-between;
  gap:12px; margin:0 0 10px;
}
.scale-head h4 { margin:0; }
.scale-head .sheet-open { flex:0 0 auto; }
.size-row:last-child { margin-bottom:0; }

/* ---- nyomtatás-menü ----
   Ikonos művelet a szűrősorban: a nyomtatás ugyanarra a körre vonatkozik,
   mint a szűrő, ezért mellette áll — de felirat nélkül, mert a sor a
   szűrésről szól, nem róla. A jelentés a tooltipben és a felolvasónak
   marad meg. */
.print-menu .menu-btn { width:38px; height:38px; }
.print-menu .menu-btn .ui-icon { width:18px; height:18px; }
/* A kijelölést vivő űrlap csak rejtett mezőket tartalmaz: ne foglaljon
   helyet a szűrősorban. */
.pick-form { display:none; }

/* ---- kijelölő mód ----
   A „Kiválasztott" egy rejtett jelölőnégyzetet kapcsol be; erre nyílik ki a
   táblázat kijelölő oszlopa és a sáv. `:has()`-szal a lap bármely pontján
   álló kapcsoló elér a táblázatig — sibling-szabállyal nem érne, mert a
   kettő nem egymás mellett áll. */
.pick-toggle { position:absolute; width:1px; height:1px; opacity:0; pointer-events:none; }
/* Kijelölő módban a menü lapja eltűnik: a vezérlés átkerül a sávba, és a
   nyitva maradt lista különben pont azt takarná. A kapcsoló a menü ELŐTT
   álló testvér, ezért éri el a `~`. */
.pick-toggle:checked ~ .print-menu .menu-list { display:none; }
.col-pick { display:none; }
body:has(.pick-toggle:checked) .col-pick { display:table-cell; }
.tbl .col-pick { width:44px; }
.pick-one { justify-content:center; }
.pick-one input { margin:0; }

.pick-bar { display:none; }
body:has(.pick-toggle:checked) .pick-bar {
  display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:10px;
  margin:0 0 12px; padding:11px 14px;
  background:var(--field); border:1px solid var(--line); border-radius:var(--radius);
  font-size:13.5px; color:var(--ink-2);
}
.pick-bar-go { display:inline-flex; align-items:center; gap:10px; }
/* A „Mégsem" címke, nem gomb (rejtett jelölőnégyzetet kapcsol) — de a sávban
   a szomszédja egy tömör gomb, és felirat-szerűen ott elveszne. Ugyanaz a
   méret és keret, csak halkabb kitöltéssel: másodlagos művelet, nem szöveg. */
.pick-bar-go .btn-quiet {
  display:inline-flex; align-items:center; justify-content:center;
  /* A szomszédjának NINCS kerete, ezért itt a belső margó függőlegesen és
     vízszintesen is egy képponttal kevesebb — a két doboz így pontosan
     egyforma magas és egy vonalban ül. */
  padding:7px 14px; border:1px solid var(--line); border-radius:9px;
  background:var(--surface); color:var(--ink-2);
  font-size:13.5px; font-weight:500; line-height:18.9px; cursor:pointer;
}
.pick-bar-go .btn-quiet:hover { border-color:var(--line-strong); color:var(--ink); }

/* Katalóguslista: a név kapja a maradékot, a három szám keskeny és
   táblázatszámmal (tabular-nums) áll, hogy egymás alatt olvasható legyen. */
.tbl-catalog .col-cat   { width:18%; }
.tbl-catalog .col-scale { width:18%; }
.tbl-catalog .col-count { width:88px; font-variant-numeric:tabular-nums; }

/* A játékos adatlapján négy hasáb van (tétel, kiadva, állapot, művelet). A
   műveletoszlop mérték nélkül a maradék felét vitte — 342 képpont egyetlen
   gombnak —, a tétel nevétől elvéve. */
/* A `col-when` marad a közös 74 képpont: egy dátum elfér benne. */
.tbl-equip-player .col-state { width:168px; }
.tbl-equip-player .col-act   { width:84px; }

/* A tétel lapján a „Kinél van" tábla MÁS arányokat kér, mint a kiadási
   lista: itt nincs „Tétel" hasáb (a lap egyetlen tételről szól), viszont a
   „Mit kapott" viszi a leghosszabb szöveget — méret · garnitúra · szám · db.
   Az örökölt 96 képpontos hasábban ez három sorba tört, miközben a csapat
   hasábja 179 képponton tartott egy „U12"-t, a művelet meg 210-en egy
   gombot. A szélességek ezért itt fölülíródnak. */
.tbl-equip-item .col-name  { width:24%; overflow-wrap:normal; }
.tbl-equip-item .col-team  { width:12%; }
.tbl-equip-item .col-size  { width:20%; white-space:normal; }
/* Az állapot alatt a visszavétel napja ÉS az állapota áll egy sorban
   („2026. 08. 05. · Kopott") — ennyi kell neki, hogy ne törjön három sorba. */
.tbl-equip-item .col-state { width:172px; }
.tbl-equip-item .col-act   { width:84px; }

/* Készlettáblázat: a darabszám beírható mező, nem szöveg — a leltár egy
   menetben megy végig a méreteken, egyetlen mentéssel a végén. */
.tbl-stock .col-qty   { width:110px; }
.tbl-stock .col-count { width:92px; font-variant-numeric:tabular-nums; }
.tbl-stock input.qty {
  width:72px; padding:7px 8px; text-align:center;
  font-variant-numeric:tabular-nums;
  border:1px solid var(--line); border-radius:8px; background:var(--surface); color:var(--ink);
}
.tbl-stock input.qty:focus-visible { outline:2px solid var(--club); outline-offset:1px; }
/* A frissítő gomb a táblázat alatt, jobbra — ott van a szem, amikor az
   utolsó sort beírta. */
.stock-save { display:flex; justify-content:flex-end; padding:0 18px 16px; }
/* …és csak akkor, ha van mit menteni. Az `can-hide-save` osztályt a
   kényelmi szkript teszi ki: nélküle (vagy ha a szkript nem töltődik be) a
   gomb végig látszik, tehát a mentés sosem válik elérhetetlenné. */
.stock-form.can-hide-save .stock-save { display:none; }
.stock-form.can-hide-save.is-dirty .stock-save { display:flex; }
.panel-stock .scroller { margin-bottom:12px; }

/* ---- Nyomtatható lap ----
   Se menü, se kártyaárnyék: a papíron az árnyék szürke folt. A blokkot nem
   törjük ketté oldalhatáron — egy játékos felsorolása és az aláírása
   összetartozik. */
.paper { background:#fff; color:#111; }
.sheet-page { max-width:820px; margin:0 auto; padding:28px 24px 40px; }
.paper-head { border-bottom:2px solid #111; padding-bottom:10px; margin-bottom:20px; }
.paper-head h1 { font-size:20px; margin:0 0 4px; }
.paper-head p { margin:0; font-size:13px; color:#444; }
.paper-block { margin-bottom:26px; break-inside:avoid; page-break-inside:avoid; }
.paper-block h2 { font-size:15px; margin:0 0 8px; }
.paper-block h2 small { font-weight:400; color:#555; margin-left:8px; }
.paper-block .tbl { font-size:13px; }
.paper-sign { display:flex; gap:40px; margin:14px 0 0; }
.paper-sign span {
  flex:1; border-top:1px solid #111; padding-top:4px;
  font-size:11.5px; color:#444;
}
/* A szezonstatisztika papíron: a NÉV kapja a helyet. A számhasábok rövidek
   („55", „1"), a nevek nem — enélkül minden második gyerek neve két sorba
   tört, és a lap kétszer olyan hosszú lett. */
.paper .tbl .col-name { width:34%; }
.paper .tbl th:not(.col-name) { white-space:nowrap; }

@media print {
  .sheet-page { padding:0; max-width:none; }
  .paper-block .tbl { border:1px solid #999; }
}
/* Törzsadat-listák: az átnevező mező és a műveletek fix sávot kapnak, hogy
   soronként egy vonalban álljanak — eddig a jobb szélen ragadtak, egymás
   alatt, más-más behúzással. */
/* Asztalon három oszlop; telefonon az öröklődés a név alá csúszik, és a
   táblázat elfér görgetés nélkül. */
.tbl-lookup { min-width:600px; }
.tbl-lookup .col-origin { width:22%; }
/* Képpontban, nem százalékban: fix méretű gombok állnak benne. Két ikon és
   a köztük lévő rés — a hasáb ennyi, mióta a szerkesztés és a ki-be
   kapcsolás rajz, nem felirat. (Szövegesen 240 képpont kellett neki.) */
.tbl-lookup .col-act    { width:104px; }
/* A műveletek egymás alatt, azonos kezdőponttal — nem ott, ahol az előző
   űrlap véletlenül véget ért. A cellán nem állítunk `display`-t: az kivenné
   a táblázat elrendezéséből, és az oszlopszélesség böngészőnként eltérne. */
/* A két művelet egymás mellett. A `display` a cellán belüli sorra kerül, nem
   magára a cellára: az kivenné a táblázat elrendezéséből. */
.act-row { display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
/* Az IKONOS műveletsor soha nem törik két sorba: a sortörés megduplázná a
   sor magasságát, és pont azt a levegőt venné vissza, amiért ikonra
   váltottunk. A `nowrap` a képpontra kiszámolt hasábszélesség mellé is kell,
   mert a rejtett jelölőnégyzetek és a kerekítés néhány tizedet hozzátesznek. */
.act-row:has(.btn-icon), .act-row:has(.ask-icon) { flex-wrap:nowrap; }
/* …KIVÉVE, amíg egy megerősítés nyitva van: a doboz saját sort kér
   (`.act-row > .ask[open] { flex:1 1 100% }`), és tördelés nélkül kifolyt a
   cellából, rá a következő sorokra. */
.act-row:has(.ask[open]) { flex-wrap:wrap; }
/* Ikonos műveletoszlop alapszélessége EGY ikonra: az a tipikus eset. Ahol
   kettő van (sérülés, törzsadat-lista, csapatsor), a tábla saját szabálya
   írja felül — a szám ott is mért, nem becsült.

   Nem 32+margó, hanem 84: a hasáb FEJLÉCE („MŰVELET", ritkított nagybetűkkel)
   szélesebb, mint maga az ikon, és a szűkebb hasábból kilógott. */
.tbl .col-act:has(.btn-icon), .tbl .col-act:has(.ask-icon) { width:84px; }
/* A műveletoszlop cellája középre igazít, tehát a benne álló gombsornak is
   középen a helye — különben a gombok balra húznak a középre zárt fejléc
   alatt. A táblázaton KÍVÜLI műveletsorok (lapfejléc, szervezeti fa) ezt
   nem öröklik: ott a sor a bal szélhez tartozik. */
.tbl .act-row { justify-content:center; }
.act-row > form, .act-row > details { margin:0; }
/* Gyors jelenlét: ezek a gombok a belépett szülő SAJÁT gyerekeinek nevei.
   Egymás mellett a testvérnevek egy eltévesztett koppintásra vannak
   egymástól, és rossz gyerek jelenlétét rögzíteni nem kozmetikai hiba —
   ezért itt a műveletsor egymás alá rendez, gombszélességben. */
.check-in .act-row { flex-direction:column; align-items:flex-start; }
/* A gépi azonosító mindig külön sorban áll a név alatt — nem a név része. */
.tbl .ability-key { display:block; margin-top:3px; }
/* Mindig látszó kiegészítő sor a cellában — a .tbl-sub telefonra való. */
.tbl-note { display:block; font-size:12.5px; color:var(--muted); margin-top:2px;
            overflow-wrap:anywhere; }

/* Az ablak veszélyes művelete a LÁBLÉCBEN áll, de BALRA húzva: egy sorban a
   „Mégsem"-mel és a „Mentés"-sel, tőlük mégis elhúzva, hogy ne lehessen
   véletlenül eltalálni. (Korábban külön sávot kapott a doboz alján — egy
   háromgombos ablaknál az fölösleges emelet volt.) */
.sheet-danger { padding:14px 18px; border-top:1px solid var(--line); background:var(--field); }
.sheet-foot .sheet-foot-danger {
  margin-right:auto; padding:0; border:0; background:none;
}
/* A jobb oldali pár együtt marad, akkor is, ha a lábléc tördel. */
.sheet-foot-go { display:flex; align-items:center; gap:12px; }
/* Csatolmány-hivatkozás: ikon + felirat, a fájl típusával. A puszta „lelet"
   szövegből nem derült ki, hogy fájl van mögötte, sem hogy milyen. */
.file-link { display:inline-flex; align-items:center; gap:7px; text-decoration:none; }

/* CSIPESZ-forma ugyanarra, naplósorokba. A gombforma egy tételes listában
   túl hangos: a csatolmány nem művelet, hanem a bejegyzés tartozéka — a
   sorban a dátum és a diagnózis a fontos, a lelet csak elérhető legyen.
   A színt hoverre kapja, mint a műveleti ikonok. */
.file-chip {
  display:inline-flex; align-items:center; gap:6px;
  padding:3px 10px 3px 8px; border-radius:999px;
  border:1px solid var(--line); background:var(--surface-2);
  color:var(--ink-2); font-size:12.5px; font-weight:500;
  text-decoration:none; white-space:nowrap;
}
.file-chip:hover { border-color:var(--club); background:var(--club-soft); color:var(--club); }
.file-chip .ui-icon { width:14px; height:14px; }
/* „Nincs csatolmány" UGYANEBBEN a dobozban, szaggatott kerettel. Csupasz
   szürke szóként a hasáb formája soronként ugrált — egyik sorban egy tömör
   csipesz, a másikban egy szó, más magasságban. Nem hivatkozás: nincs hová
   vinnie, tehát nem is viselkedik úgy. */
.file-chip.is-empty {
  border-style:dashed; background:none; color:var(--muted); cursor:default;
}
.file-chip.is-empty .ui-icon { opacity:.6; }

/* FELTÖLTŐ MEZŐ — ugyanaz a formanyelv, mint a csipeszé: szaggatott pirula,
   benne a választógomb. Ott áll, ahol a „nincs lelet" csipesz állna, és úgy
   is néz ki, csak ez a doboz cselekvésre hív.

   A natív vezérlő MARAD: a rendszer JavaScript nélkül is működik, és a
   kiválasztott fájl nevét csak a böngésző tudja kiírni. Elrejtve és egy
   címkével helyettesítve a felhasználó nem látná, mit választott ki. */
.field input[type="file"] {
  max-width:100%; padding:5px 13px 5px 5px;
  border:1px dashed var(--line-strong); border-radius:999px;
  background:none; color:var(--ink-2); font-size:12.5px;
}
.field input[type="file"]::file-selector-button {
  margin-right:10px; padding:5px 12px; border:0; border-radius:999px;
  background:var(--club-soft); color:var(--club);
  font:inherit; font-weight:600; cursor:pointer;
}
.field input[type="file"]:hover { border-color:var(--club); }
.field input[type="file"]:hover::file-selector-button { background:var(--club); color:#fff; }
.field input[type="file"]:focus-visible { outline:2px solid var(--club); outline-offset:2px; }

/* …és ha a szkript lefutott, a natív mező HELYETT a csipesz áll ott. A
   kapcsolót a szkript teszi rá (`is-masked`), tehát JavaScript nélkül a
   fentebbi natív mező marad — feltölteni enélkül is lehet.

   A mező nem tűnik el teljesen, csak láthatatlan: így Tab-bal elérhető, és
   a fókuszgyűrű a csipeszen jelenik meg. */
.file-pick { display:inline-flex; position:relative; max-width:100%; }
.file-pick-face { display:none; }
.file-pick.is-masked input[type="file"] {
  position:absolute; width:1px; height:1px; padding:0; border:0; opacity:0;
}
.file-pick.is-masked .file-pick-face {
  display:inline-flex; cursor:pointer; border-style:dashed;
  border-color:var(--line-strong);
}
.file-pick.is-masked .file-pick-face:hover {
  border-style:solid; border-color:var(--club);
}
/* Kiválasztott fájllal tömör keret és klubszín: ugyanaz a forma, amit a
   már feltöltött lelet csipesze visel — a kettő ugyanazt jelenti. */
.file-pick.has-file .file-pick-face {
  border-style:solid; border-color:var(--club);
  background:var(--club-soft); color:var(--club);
}
.file-pick .file-pick-name { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.file-pick input:focus-visible + .file-pick-face {
  outline:2px solid var(--club); outline-offset:2px;
}
.file-chip .file-ext { margin-left:0; }
/* FELTÖLTŐ MEZŐ (`ui_upload`): fent a már meglévő fájlok, alatta a választó.
   A csipesz balra zárva áll, nem a mezőrács teljes szélességében nyúlik el —
   egy hivatkozás annyi helyet foglaljon, amennyi a nevéhez kell. A fájlnév
   hosszú lehet („lelet-fodor-aron-2026-09-13.pdf"), ezért a végén elfogy. */
.upload-list { display:flex; flex-direction:column; align-items:flex-start; gap:6px; }
.upload .file-chip { max-width:100%; }
.upload .file-chip > span:not(.file-ext) {
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.upload-note { font-size:12.5px; font-weight:400; color:var(--muted); }
/* Több csipesz egymás alatt — a naplósorban, ahol csak megnézni lehet őket. */
.chip-stack { display:inline-flex; flex-direction:column; align-items:flex-end; gap:5px; }

/* A lelet és a törlése EGY SORBAN: a csatolmány és a rá vonatkozó művelet
   összetartozik, két sorba szedve pedig nem látszott, hogy melyik fájlról
   van szó. */
.file-row { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
/* Rejtett jelölőnégyzet az ikon mögött — a törlés a mentésig JELÖLÉS.
   Nem teljesen elrejtve: így Tab-bal elérhető és Szóközzel kapcsolható. */
/* Ugyanaz a halvány szürke, mint a többi ikonnál: a `.field` `--ink-2`
   színét örökölte volna, ami egy árnyalattal sötétebb. */
.file-del { cursor:pointer; color:var(--muted); }
.file-del input { position:absolute; width:1px; height:1px; opacity:0; }
/* Bejelölve UGYANAZ a halvány piros, amit a többi ikon hoveren mutat — a
   rendszerben ez a „visszafordíthatatlan" színe, és egy ikon nem visel két
   különböző formát. A `:hover`-rel azonos súllyal, különben az egér alatt
   nem látszana, hogy sikerült-e bejelölni. */
.file-del:has(input:checked),
.file-del:has(input:checked):hover {
  background:var(--st-absent-soft); color:var(--st-absent);
}
.file-del input:focus-visible + .ui-icon { outline:2px solid var(--club); outline-offset:3px; }
/* Bejelölve a csipesz áthúzódik: mentés előtt látszódjon, mi tűnik el. */
.file-row:has(input:checked) .file-chip {
  text-decoration:line-through; color:var(--muted);
  background:var(--surface-2); border-color:var(--line); opacity:.65;
}
/* A figyelmeztetés csak akkor szólal meg, amikor van miről szólnia. */
.upload:has(.file-del input:checked) .upload-note { color:var(--danger); }

/* Sérülési napló a játékos adatlapján: a LELET és a MŰVELET külön hasáb.
   Egy cellába zsúfolva a csatolmány és a két ikon egymás alá csúszott — és
   a kettő nem is ugyanaz a dolog. */
.grants-injury .s { width:118px; }
.grants-injury .a { width:84px; text-align:right; white-space:nowrap; }
/* A `.grants` cellái felülre igazítanak, mert szöveget tartalmaznak, és a
   soron belül több sornyi leírás is lehet. A CSIPESZ és a MŰVELETSOR viszont
   egyetlen, fix magasságú elem: felülre húzva a többsoros szomszédja mellett
   a sor tetejére tapadt. Ezek középen állnak.

   A sérülési naplóban a LELET hasábja akkor is középen áll, ha üres („nincs
   lelet"): a helyettesítő szöveg ugyanoda tartozik, mint a csipesz, és
   felülre húzva egy vonalból kilógott a mellette álló műveletekkel. */
.grants td.s:has(.file-chip), .grants td.s:has(.act-row), .grants td.a,
.grants-injury td.s { vertical-align:middle; }
.file-ext {
  margin-left:6px; font-size:10.5px; font-weight:700; letter-spacing:.05em;
  opacity:.7;
}
.sheet-danger .ask { margin:0; }

/* Konzol-listák. */
.tbl .col-use   { width:30%; }
.tbl .col-where { width:26%; }
.tbl .col-ver   { width:16%; }
.tbl .col-lvl   { width:22%; }
.tbl .col-count { width:11%; white-space:nowrap;
                  font-variant-numeric:tabular-nums; }
/* A szervezeti fában a csapattábla szűkebb: a panelen belül áll, nem
   önálló lapként. */
.tbl-team { font-size:13.5px; }
.tbl-team td, .tbl-team th { padding-block:9px; }
/* Saját hasábarányok: a többi lista arányai (24% + 20%) ehhez a rövid
   tartalomhoz túl bőek voltak — a „2026/27" egy 128 képpontos hasáb közepén
   lebegett, a csapatnévnek meg maradt egy majdnem üres 235 képpont.

   A műveletoszlop KÉPPONTBAN van megadva, nem százalékban: fix méretű gombok
   állnak benne, tehát a kellő hely is fix. Százalékon a két gomb szűk
   panelben egymás alá esett, és a különböző szélességük miatt lépcsőzött. */
.tbl-team .col-act   { width:104px; }
.tbl-team .col-count { width:70px; }
.tbl-team .col-med   { width:24%; }
.tbl-team .col-team  { width:90px; }
/* Csoportválasztó sor a hosszú listákban: nem adat, hanem tájékozódási pont. */
.tbl tbody tr.grp td {
  background:var(--field); padding:11px 14px 9px;
  font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:.06em;
  color:var(--muted); border-bottom:1px solid var(--line);
}
.tbl tbody tr.grp .tbl-soft { text-transform:none; letter-spacing:0; margin-left:6px; }

/* Fiókok: az azonosító és a szerepkörök fix hányadot kapnak. A szerepkör
   kapja a többet — a leghosszabb címke („Felszerelésmenedzser · Jégkorong
   szakosztály") egy sorba kell hogy férjen, egy e-mail-cím rövidebb. */
.tbl .col-id    { width:24%; }
.tbl .col-roles { width:42%; }
/* Rögzített elrendezésnél a hosszú érték nem tolja szét az oszlopot, hanem
   tördelődik — a név viszont maradjon egyben, ahol csak fér. */
.tbl td { overflow-wrap:break-word; }
/* A lezárt sor halványabb. Az `opacity` viszont az EGÉSZ részfát átlátszóvá
   teszi, a sorból nyíló felugró ablakot és megerősítő dobozt is — a lezárt
   sérülés módosító ablaka 55%-osan jelent meg a lap fölött, a saját
   sötétítő rétegén átlátszva. Amíg a sorból nyitva van valami, a sor teljes
   erővel látszik; a szem úgyis az ablakon van, a sort a scrim takarja. */
.tbl tbody tr.is-off { opacity:.55; }
.tbl tbody tr.is-off:has(.sheet-toggle:checked),
.tbl tbody tr.is-off:has(details[open]) { opacity:1; }
/* A születési év saját oszlop: a név után futva minden soron máshol kezdődne,
   így viszont egymás alatt áll, és a szem végig tudja pásztázni. */
/* Dátumoszlop: keskeny, és a nap alatt az óra — a sor horgonya az, hogy
   mikor, nem az, hogy mi. */
.tbl .col-when {
  width:74px; white-space:nowrap; color:var(--ink-2);
  font-variant-numeric:tabular-nums;
}
.tbl .col-when .tbl-note { margin-top:1px; }
.tbl .col-year {
  width:68px; white-space:nowrap;
  color:var(--muted); font-variant-numeric:tabular-nums;
}
.tbl-year { color:var(--muted); font-variant-numeric:tabular-nums; }
.scroller { overflow-x:auto; margin:0 0 18px; }

/* Konzol-link az avatar-menüben: két soros, mert a második sor mondja meg,
   mi van ott és hogy külön belépés kell. */
.me-console { display:block; border-top:1px solid var(--line); }
.me-console span { display:block; font-size:12px; color:var(--muted); margin-top:1px; }

/* Keretlétszám-gomb a Szervezet oldalon. */

/* Csak a kiválasztott létrehozási út mezői látszanak. */
.sheet-form .only-invite, .sheet-form .only-local { display:none; }
.sheet-form:has(#mode-invite:checked) .only-invite { display:flex; }
.sheet-form:has(#mode-local:checked)  .only-local  { display:flex; }
.sheet-form:has(#mode-invite:checked) p.only-invite,
.sheet-form:has(#mode-local:checked)  p.only-local { display:block; }


/* ---- Egészség és statisztika (7. fázis) --------------------------------

   Három tábla jött ezzel a fázissal — sérüléslista, jegyzőkönyv, szezon-
   összesítő —, és mindhárom ugyanabból a szókincsből épül, mint a korábbiak:
   a név kapja a maradékot, a rövid értékek fix sávot, a számok tabuláris
   számjegyet, hogy a hasáb végig egy vonalban álljon.                     */

/* Számhasáb. Az összesítőben nyolc-tíz ilyen áll egymás mellett, ezért
   keskeny és jobbra zárt: a szem az egyesek helyiértékét pásztázza. */
.tbl .col-num {
  width:74px; text-align:right; white-space:nowrap;
  font-variant-numeric:tabular-nums;
}
.tbl .col-num .tbl-note { display:block; text-align:right; }
/* AZ EGYETLEN TÁBLA, AHOL `table-layout:auto` KELL.
   Mindenhol máshol fix hasábszám van, és a `fixed` a jó: kiszámítható,
   nem ugrál a tartalomtól. Itt viszont a hasábok SZÁMA és a FEJLÉCÜK IS
   adat — a jegyzőkönyv-típusok a szakosztály listájából jönnek, tehát
   lehet belőlük kettő vagy nyolc, és a nevük lehet „Gól" vagy „Kétperces
   kiállítás". Ekkora szórásra nem lehet képpontban méretet mondani: a fix
   78 hol pazarolt, hol levágta a fejléc rendezőnyilát.

   Az `auto` mellett minden hasáb annyit kap, amennyi a tartalma, a
   maradékot pedig a név viszi (`width:100%`). Ha mégsem fér ki, a
   `.scroller` vízszintesen görgethetővé teszi — nem összenyomja. */
.tbl-stats { table-layout:auto; }
.tbl-stats .col-name { width:100%; min-width:150px; }
.tbl-stats .col-num  { width:auto; padding-left:14px; }
/* A fejléc és a rendezőnyila EGYBEN marad: külön sorba törve a nyíl
   elveszne, összenyomva pedig levágódna. */
.tbl-stats thead th { white-space:nowrap; }

/* ELOSZLÁS-CSÍK: meccsenként egy kis négyzet, öt telítettségi fokozatban.
   Nem pixelre pontos oszlopdiagram — mintázat. A „9, 10, 10, 20" és az
   „55, 0, 0, 0" ugyanazt az összeget adja, de ránézésre különbözik, és a
   lapnak épp ez a kérdése.

   ÖT FIX OSZTÁLY, nem soronkénti stílus: a szigorú CSP tiltja az inline
   `style`-t, egy nonce-olt szabály pedig játékosonként külön sort jelentene
   a fejlécben. A pontos érték a `title`-ben van. */
/* FIX SZÉLESSÉG, nem `auto`: a tábla `table-layout:fixed`, tehát az `auto`
   hasáb a MARADÉK helyet viszi el — a csík emiatt átlógott a fél
   táblázaton, pedig négy jel ötven képpont. A tizenkét jel két sorba
   tördel, és ez rendben van: hosszú szezonnál a sor amúgy is magasabb. */
.tbl-stats .col-spread { width:104px; }
/* ALULRA IGAZÍTVA: a jelek oszlopdiagramot alkotnak, tehát a talpuk egy
   vonalban áll — enélkül a különböző magasságok középre rendezve
   hullámoznának, és a „több" nem látszana „magasabbnak". */
.spread {
  display:inline-flex; gap:3px; align-items:flex-end; flex-wrap:wrap;
  min-height:18px;
}
.spread i {
  width:11px; border-radius:2px; display:block;
  /* LÁTHATÓ KERET minden jelen: ez adja a „teljes" viszonyítást. Enélkül
     a kitöltetlen rész a sor hátterébe olvadt (a track `--line` volt,
     ami gyakorlatilag fehér), és a 67% ugyanúgy nézett ki, mint a 100%. */
  border:1px solid var(--line-strong);
  background:var(--club);
}
/* ALAPVONAL a jelek alatt: enélkül különálló kis kártyáknak látszottak, és
   nem derült ki, hogy oszlopdiagram — hogy EGY OSZLOP EGY MÉRKŐZÉS. Egy
   hajszálvonal a talpuk alatt tengellyé teszi a sort. A jelmagyarázatban
   nincs rá szükség: ott egy-egy jel áll, nem sorozat.

   A visszajelzés, amiből ez lett: „ja, hogy egy olyan kis kártya az egy
   meccs?" — a négy jelet egy mérkőzés négy negyedének olvasta valaki, és
   nem alaptalanul: két hasábbal arrébb tényleg a játékrészek állnak. */
.tbl-stats .col-spread .spread {
  border-bottom:1px solid var(--line-strong); padding-bottom:2px;
}
/* A FOKOZAT KITÖLTÖTTSÉG, nem magasság — és ez a negyedik nekifutás.

   1. Átlátszóság volt: tíz képpont széles jeleken nem látszott.
   2. Magasság lett: jobb, de VISZONYÍTÁSI PONT NÉLKÜL. Egy 11 és egy 18
      képpontos oszlop egymás mellett alig különbözik, ha nincs mihez
      mérni — „a részben és a végig pályán nagyon láthatatlan".
   3. Most minden jel EGYFORMA MAGAS, és a kitöltöttsége mutatja az
      arányt: a fele üresen maradt oszlop ránézésre „nem teljes", mert
      ott van fölötte a saját üres kerete. A szem nem két oszlopot
      hasonlít össze, hanem egy oszlopot a saját keretéhez.

   A kitöltés `linear-gradient` éles átmenettel, nem belső elem: így a
   jel továbbra is egyetlen üres `<i>`, és a soronkénti stílus is
   elmarad (a szigorú CSP miatt amúgy sem lehetne).

   A track az `--line`: üres rekesznek látszik a sor hátterén, nem
   hibának. */
.spread i { height:18px; }
.spread .sp-1 { background:linear-gradient(to top, var(--club) 8%, var(--surface) 8%); }
.spread .sp-2 { background:linear-gradient(to top, var(--club) 17%, var(--surface) 17%); }
.spread .sp-3 { background:linear-gradient(to top, var(--club) 25%, var(--surface) 25%); }
.spread .sp-4 { background:linear-gradient(to top, var(--club) 33%, var(--surface) 33%); }
.spread .sp-5 { background:linear-gradient(to top, var(--club) 42%, var(--surface) 42%); }
.spread .sp-6 { background:linear-gradient(to top, var(--club) 50%, var(--surface) 50%); }
.spread .sp-7 { background:linear-gradient(to top, var(--club) 58%, var(--surface) 58%); }
.spread .sp-8 { background:linear-gradient(to top, var(--club) 67%, var(--surface) 67%); }
.spread .sp-9 { background:linear-gradient(to top, var(--club) 75%, var(--surface) 75%); }
.spread .sp-10 { background:linear-gradient(to top, var(--club) 83%, var(--surface) 83%); }
.spread .sp-11 { background:linear-gradient(to top, var(--club) 92%, var(--surface) 92%); }
/* A teljesen kitöltött jelnél a keret is a klub színe: különben szürke
   vonal keretezné a tömör zöldet, és „nem egészen tele"-nek látszana. */
.spread .sp-12 { background:var(--club); border-color:var(--club); }
/* A két ÜRES állapot nem lehet egyforma, mert nem ugyanaz:

     sp-0    — NEM JÁTSZOTT: teljes magas üres keret a hiányzás színével.
               Ott volt a lehetőség, nem élt vele — ezért kap keretet, nem
               üres rekeszt: a piros vonal állítás, nem hiány.
     sp-none — NINCS ADAT: ugyanakkora téglalap, de SZAGGATOTT kerettel
               és kitöltés nélkül. A szaggatott vonal az, ami „nincs
               megállapítva"-t jelent; a piros folytonos ellenben állítás:
               ott volt a lehetőség, nem élt vele.

   Előbb alacsony vonás volt, hogy „ne jelentsen vádat" — de az meg nem
   jelentett SEMMIT: egy 2 képpontos csík a sor alján nem jel, hanem
   hiány. A jelek egyforma méretű rekeszek, különben a szem nem is
   számolja össze őket. */
.spread .sp-0    { background:transparent; border:1.5px solid var(--st-absent); }
.spread .sp-none {
  background:transparent;
  /* A `--line-strong` szaggatva alig látszott — a szaggatás maga
     megtöri a vonalat, tehát világosabbnak hat, mint folytonosan. Egy
     fokkal erősebb szín kell hozzá, hogy ugyanannyira legyen jelen, mint
     a piros folytonos. */
  border:1.5px dashed color-mix(in srgb, var(--muted) 70%, var(--surface));
}

/* Az IRÁNY a csík alatt: halk, és csak ott, ahol van mit mondania. */
.tbl-stats .col-spread .tbl-note { margin-top:3px; font-variant-numeric:tabular-nums; }

/* A jelmagyarázatban a jelek a szöveg sorába állnak be. */
.spread-key .spread { vertical-align:-3px; margin:0 1px; }
.spread-key .spread i { width:9px; height:14px; }

/* A helyezésszám csak a rangsoroló profilokban jelenik meg (`rank`).
   Tabuláris szám, hogy a 9. és a 10. ne csússzon el egymáshoz képest. */
.rank-n {
  display:inline-block; min-width:22px; margin-right:2px;
  color:var(--muted); font-variant-numeric:tabular-nums; font-size:12.5px;
}
.tbl-stats thead th { letter-spacing:0; }
/* A „kevés játékidő" címke EGYBEN törjön a név alá, ne a közepén: két
   sorba tört címke magasabbra tolja a sort, mint egy külön sorba került. */
.tbl-stats .col-name .tag { white-space:nowrap; }
/* A számhasábok alatti jegyzet nem lóghat ki a hasábjából — a szomszéd
   cella jegyzetével összeolvasva értelmetlen szöveg keletkezik
   („4 nevezésből0 / 12"). Ami nem fér ki, az a `title`-ben van. */
.tbl-stats .col-num .tbl-note {
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}

/* Súlyosság. NEM a klub színéből származik, ugyanazzal az indokkal, mint a
   jelenléti státuszoknál: a „súlyos" nem márkakérdés. A lila a rendszerben
   már a sérülés színe (jelenléti státusz), ezért kapja a legsúlyosabb fokozat. */
.sev-mild, .sev-moderate, .sev-severe {
  display:inline-block; font-size:12px; font-weight:600;
  padding:1px 8px; border-radius:999px; white-space:nowrap;
}
.sev-mild     { color:var(--st-excused); background:var(--st-excused-soft); }
.sev-moderate { color:var(--st-late);    background:var(--st-late-soft); }
.sev-severe   { color:var(--st-injured); background:var(--st-injured-soft); }

/* Nyitott sérülés — a „nála van" párja a felszerelésnél. */
.s-open { color:var(--st-injured); }

/* A név kapja a maradékot (alatta a csapattal), a többi hasáb rövid értéket
   visz. Az ÁLLAPOT egyetlen szó — a magyarázata a „Vissza" hasábban áll —,
   ezért fér el 104 képpontban; korábban a teljes mondattal 190 kellett neki,
   és így is három sorba tört. */
/* A dátumhasábok mértéke MÉRT, nem becsült: a „2026. 09. 13." tizennégy
   pontos tabuláris számjegyekkel 92 képpont, plusz a cella bal-jobb margója.
   Szűkebbre véve a két dátum összeért a szomszédos hasábbal. */
.tbl-injury .col-name  { width:auto; min-width:150px; overflow-wrap:normal; }
.tbl-injury .col-kind  { width:18%; }
.tbl-injury .col-when  { width:112px; white-space:nowrap; font-variant-numeric:tabular-nums; }
.tbl-injury .col-back  { width:134px; white-space:nowrap; font-variant-numeric:tabular-nums; }
.tbl-injury .col-back .tbl-note { white-space:normal; }
.tbl-injury .col-state { width:96px; font-weight:400; }
/* A két művelet IKON, nem felirat: szövegesen 220 képpontot kértek ketten,
   és ez pont annyi, amennyi a sérülés fajtájának és a két dátumnak együtt
   jut. Ikonnal jóval kevesebb — a maradék a táblázat többi hasábjáé. A két
   32 képpontos ikon és a rés 72; a hasáb ennél bővebb, mert egy hajszálnyi
   kerekítés is a második sorba lökné a másodikat. */
.tbl-injury .col-act   { width:104px; }
/* Hét hasáb helyett hat, de mindegyik valódi tartalommal: a cellamargó
   ennyivel szűkebb, hogy a név ne szoruljon 130 képpont alá. */
.tbl-injury th, .tbl-injury td { padding-inline:12px; }

/* Jegyzőkönyv. A perc a sor horgonya — az edző azt keresi először —, ezért
   az első hasáb, keskenyen és jobbra zárva. */
.tbl-report .col-min  { width:58px; text-align:right; font-variant-numeric:tabular-nums; }
.tbl-report .col-name { width:34%; }
.tbl-report .col-kind { width:20%; }
.tbl-report .col-note { color:var(--ink-2); font-size:13.5px; }
/* A műveletoszlop szélesebb, mint amennyi az ikonhoz kellene: a törlés
   megerősítő doboza EBBEN a hasábban nyílik ki, és egy 64 képpontos
   sávban a kérdés szavanként tört volna. */
.tbl-report .col-act  { width:84px; }

/* Játszott perc a keret-táblázatban: beírható mező, a készletmezővel azonos
   dobozzal — ugyanaz a gesztus, ugyanaz a forma. A szélesség a léptető
   nyilakra is számol: nélkülük a kétjegyű szám a nyilak alá csúszott. */
.tbl-squad .col-min { width:96px; }

/* JÁTÉKRÉSZ-RÁCS a keret táblázatában.
   Ugyanaz a forma, mint a jelenléti státuszoknál (`.state`): rejtett
   jelölőnégyzet, a címke a gomb, a kipipált állapot `:has()`-sal látszik.
   JavaScript nélkül működik, és egy koppintás egy játékrész — ez a
   rögzítés lényege: gépelni senki nem fog a pálya szélén.

   A doboz 34 képpont, mert ennél kisebbet hüvelykujjal nem lehet eltalálni,
   és a táblázat sormagassága még elbírja. Négy játékrésznél 4×34+gap fér ki
   a 96 képpontnál szélesebb hasábba — a szélességet ezért a darabszám adja,
   nem fix érték. */
.tbl-squad .col-per { width:auto; min-width:96px; white-space:nowrap; }
.per-grid { display:inline-flex; gap:4px; }
.per-box {
  position:relative; width:34px; height:34px; display:grid; place-items:center;
  cursor:pointer; user-select:none; font-size:13px; font-weight:600;
  color:var(--muted); background:var(--surface);
  border:1px solid var(--line); border-radius:8px;
  transition:background .12s ease, border-color .12s ease, color .12s ease;
}
.per-box input { position:absolute; opacity:0; width:0; height:0; }
.per-box:hover { border-color:var(--line-strong); color:var(--ink-2); }
.per-box:has(input:focus-visible) { outline:2px solid var(--club); outline-offset:2px; }
/* A kipipált játékrész a KLUB színét kapja, szemben a jelenléti
   státuszokkal: ott az „elmulasztotta" és a „jelen volt" nem lehet
   márkakérdés, itt viszont nincs jó és rossz érték — a pipa csak tény. */
.per-box:has(input:checked) {
  background:color-mix(in srgb, var(--club) 14%, var(--surface));
  border-color:var(--club); color:var(--club);
}
input.min-input {
  width:76px; padding:7px 8px; text-align:center;
  font-variant-numeric:tabular-nums;
  border:1px solid var(--line); border-radius:8px;
  background:var(--surface); color:var(--ink);
}
input.min-input:focus-visible { outline:2px solid var(--club); outline-offset:1px; }

.tbl-sub { display:none; }
@media (max-width:720px) {
  /* Telefonon az óragrid olvashatatlan: hét oszlop 375 képponton nem fér
     ki. Visszaesik napokra bontott felsorolássá — ugyanaz a jelölés, más
     elrendezés, nem külön sablon. */
  .wk { background:none; border:0; border-radius:0; overflow:visible; }
  .wk-head { display:none; }
  .wk-body { display:block; padding:0; background:none; }
  .wk-gutter { display:none; }
  .wk-cols { display:block; height:auto; background-image:none; }
  .wk-day {
    background:var(--paper);
    border:1px solid var(--line); border-radius:var(--radius);
    padding:10px 12px; margin:0 0 10px; min-height:0;
  }
  .wk-day.is-today { box-shadow:inset 0 0 0 1.5px var(--club); }
  .wk-daylabel {
    display:flex; align-items:baseline; gap:7px; margin:0 0 8px;
    font-size:12.5px; color:var(--muted);
  }
  .wk-daylabel b { font-size:17px; font-weight:700; color:var(--ink); }
  .wk-slot {
    position:static; height:auto; width:auto; padding:0; margin:0 0 6px;
  }
  .wk-slot > .ev { height:auto; }
  .wk-slot .ev-sub { display:block; }

  /* Telefonon nincs hely a kiegészítő oszlopoknak: a név alá kerülnek. */
  .tbl .col-id, .tbl .col-team, .tbl .col-med, .tbl .col-year,
  .tbl .col-use, .tbl-lookup .col-origin { display:none; }
  /* A felszerelés-listán a tétel, a méret és a kiadás napja a név alatti
     alsorban is ott van — négy hasáb 375 képponton a nevet betűnként törné.
     Marad a név (alsorral) és az állapot; a százalékos szélességek pedig
     elengednek, mert két hasábnál már nincs mit arányosítani. */
  .tbl-equip .col-size, .tbl-equip .col-when, .tbl-equip .col-item { display:none; }
  /* A katalógusban a kategória és a skála a név alatti alsorban is ott van. */
  .tbl-catalog .col-cat, .tbl-catalog .col-scale { display:none; }
  /* A „kint" is a név alatti alsorba kerül: három szám mellett a
     megnevezésnek 88 képpont maradt, és betűnként tört („Sípcsontvé / dő").
     A készlet és a szabad marad hasábban — az a két szám, amiért a listát
     nézik; a kint a kettő különbségéből úgyis kijön. */
  .tbl-catalog .col-out { display:none; }
  .tbl-catalog .col-count { width:64px; }
  .tbl-catalog th, .tbl-catalog td { padding-inline:8px; }
  .tbl-catalog thead th { letter-spacing:0; font-size:10px; }
  /* A készlettáblán mind a négy hasáb kell — ott a beírható mező a lényeg —,
     ezért csak szűkülnek, nem tűnnek el. */
  .tbl-stock .col-qty   { width:88px; }
  .tbl-stock .col-count { width:66px; }
  .tbl-stock input.qty  { width:58px; padding:6px 4px; }
  .tbl-stock th, .tbl-stock td { padding-inline:8px; }
  /* A „Szabad" fejléc 375 képponton a ritkított betűköztől lógott ki a
     hasábjából — a fejlécnek itt szűkebb betűköz jut. */
  .tbl-stock thead th { letter-spacing:0; font-size:10px; }
  /* A maradék három hasáb aránya kézzel: a tétel neve kapja a legtöbbet.
     A műveletnek már csak egy ikonnyi kell — a „Visszavétel" felirat
     korábban a hasáb harmadát elvitte. */
  .tbl-equip .col-name  { width:auto; }
  /* „Nála van" 77 képponton két sorba tört — a hasáb egy hajszállal
     szélesebb lett. */
  .tbl-equip .col-state { width:104px; }
  .tbl-equip .col-act   { width:84px; }
  /* A kiadáskori állapot („kiadva: Jó") telefonon elmarad: másodlagos adat,
     és a saját sorával az állapot hasábja három sorosra nőtt. A visszavétel
     jegyzete marad — ott a dátum a lényeg. */
  .tbl-equip .tbl-cond { display:none; }
  /* Sérüléslista telefonon HÁROM hasáb, mint a felszerelésnél: a dátum, a
     sérülés fajtája és a súlyosság mind ott van a név alatti alsorban is,
     tehát a hasábjuk elhagyható. Marad a név, az állapot és a művelet —
     erre a háromra van szükség ahhoz, hogy a listát használni lehessen.
     Öt hasáb 375 képponton oda vezetett, hogy az állapot betűnként tört. */
  .tbl-injury .col-when, .tbl-injury .col-kind, .tbl-injury .col-back { display:none; }
  /* A csapat és az állapot magyarázata a telefonos alsorban áll, ott is
     egyszer — a névsor alatti külön jegyzet így fölösleges ismétlés lenne. */
  .tbl-injury .col-name > .tbl-note { display:none; }
  .tbl-injury .col-name { min-width:0; }
  /* A műveletnek kell a legtöbb: a „Felszabadítás" a leghosszabb gomb a
     rendszerben, és félbevágva nem gomb. */
  /* Telefonon is elfér mindhárom hasáb, mert a művelet ikon: a név kapja a
     maradékot. */
  .tbl-injury .col-name  { width:auto; }
  .tbl-injury .col-state { width:96px; }
  .tbl-injury .col-act   { width:100px; }
  /* Az állapot egyetlen szó — ne törjön ketté („Lábadozi / k"). */
  .tbl-injury .col-state > span { white-space:nowrap; }
  /* Az állapot MAGYARÁZATA a név alatti alsorba került; a hasábban csak a
     szó marad („Aktív", „Lábadozik"). A mondat 97 képponton szavakat tört
     ketté — „Visszatéré / s 24 nap". */
  .tbl-injury .col-state .tbl-note { display:none; }

  /* Az összesítőben nyolc-tíz számhasáb van: telefonon egy sem fér ki
     olvashatóan. Mind a név alatti alsorba kerül — ott végig ott is volt —,
     a hasábból csak a perc marad, mert azért nyitják meg a lapot. */
  .tbl-stats .col-num  { display:none; }
  .tbl-stats .col-perc { display:table-cell; width:64px; }
  .tbl-stats .col-name { width:auto; min-width:0; }
  /* A MECCSENKÉNTI csík telefonon is marad: négy apró jel kevesebb helyet
     kér, mint egy szám, és pont az a fajta információ, amit egy pillantásra
     nézünk.

     A szűk keresztmetszet nem a csík, hanem a FEJLÉC: a „Meccsenként" egy
     hosszú, oszthatatlan szó, és `nowrap` mellett ez határozta meg a hasáb
     szélességét — a táblázat emiatt negyven képponttal túllógott. Itt tehát
     elválasztjuk (`hyphens`), a szavunk nem rövidül, a hasáb viszont igen. */
  .tbl-stats .col-spread { width:52px; min-width:0; }
  /* Ami csak SZÉLES nézetben kell: a mértékegység szava a számpár mellett.
     Telefonon a szomszédos hasáb nem is látszik, tehát nincs mivel
     összekeverni — a név alatti alsor pedig kiírja. */
  .u-wide { display:none; }
  .tbl-stats th.col-spread {
    white-space:normal; hyphens:auto; overflow-wrap:break-word;
  }
  .tbl-stats .col-num { padding-left:8px; }
  .tbl-stats .col-spread { padding-left:6px; padding-right:8px; }
  /* A keret miatt a jel 2 képponttal szélesebb, mint volt — telefonon
     ezt a szélességből vesszük vissza, a magasságból nem. */
  .spread i { width:9px; }
  .spread { gap:2px; }

  .tbl-squad .col-min { width:76px; }
  /* Telefonon a rács szűkebb dobozokat kap, de 30 alá nem megyünk: az már
     nem eltalálható. Négy játékrésznél inkább a név hasábja adja a helyet. */
  .tbl-squad .col-per { min-width:0; }
  .per-box { width:30px; height:30px; }
  input.min-input { width:62px; padding:6px 4px; }
  /* A jegyzőkönyvnél a megjegyzés esik ki: kiegészítés, nem a lényeg. */
  .tbl-report .col-note { display:none; }
  .tbl-report .col-name { width:auto; }

  /* A keretnél MINDHÁROM adat kell: a név, a visszajelzés és a nevezés
     együtt adja a döntést — egyiket sem lehet elhagyni. Három oszlopban
     viszont 375px-en a név kettétörik és a legördülő levágódik, ezért a
     sor kártyává nyílik: fent a név és a nevezés egy vonalban, alatta
     teljes szélességben a visszajelzés (ami a leghosszabb szöveg). */
  .tbl-squad, .tbl-squad tbody, .tbl-squad tr, .tbl-squad td { display:block; }
  /* A csoportsáv telefonon is sáv marad — csak a rács szűnik meg alatta. */
  /* Csoportsávos táblázat telefonon: `table-layout:fixed` mellett a
     colspan="5" sáv a REJTETT oszlopokra is szélességet foglalt, és a
     névoszlop 64 képpontra szorult — a nevek betűnként törtek. Automatikus
     elrendezéssel az oszlopok a látható tartalomhoz igazodnak; fix méret
     itt már úgysem kell, mert két oszlop marad. */
  /* Szűk helyen a nézetváltó ikonra fogy: a panelfejlécben a cím és a
     két művelet mellett a feliratos változat harmadik sorba törne. */
  .views-icon a > span { position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); }
  .views-icon a { padding:7px 10px; }
  .tbl:has(tr.tbl-group) { table-layout:auto; }
  .tbl tr.tbl-group th { padding:9px 12px; }
  .tbl-squad tr.tbl-group, .tbl-squad tr.tbl-group th { display:block; }
  .tbl-squad tr.tbl-group { padding:0; border-bottom:0; }
  .tbl-squad thead { display:none; }
  .tbl-squad { min-width:0; }
  .tbl-squad tr { padding:11px 12px; border-bottom:1px solid var(--line); }
  .tbl-squad tr:last-child { border-bottom:0; }
  .tbl-squad td { padding:0; border:0; }
  /* A százalékos oszlopszélességek blokk-elemként is érvényesek maradnának,
     és 375px-en kettétörnék a nevet — telefonon a cella a teljes sort kapja. */
  .tbl-squad .col-name, .tbl-squad .col-avail,
  .tbl-squad .col-warn, .tbl-squad .col-squad { width:auto; }
  .tbl-squad .col-avail { margin-top:5px; }
  .tbl-squad .col-warn { margin-top:5px; }
  .tbl-squad .col-squad { margin-top:8px; }
  .tbl-squad .col-squad.is-empty { display:none; }
  /* Kártyás soron a fejléc nem látszik, tehát a gondolatjel semmit nem
     jelentene — az ép játékos sorából a hasáb egyszerűen kimarad. */
  .tbl-squad .col-warn.is-empty { display:none; }
  .tbl-lookup { min-width:0; }
  /* Telefonon a TÁBLÁZAT műveletoszlopában nincs hely két gombnak egymás
     mellett: ott egymás alá kerülnek, azonos szélességben. Az űrlap a
     rugalmas elem, nem a benne álló gomb — ezért a szélességet annak kell
     kapnia. Máshol (szervezeti fa) van teljes szélesség, ott sorban
     maradnak és tördelnek. */
  .tbl-lookup .col-act { width:100px; }
  .tbl .act-row { flex-direction:column; align-items:stretch; }
  .tbl .act-row > form, .tbl .act-row > label.btn,
  .tbl .act-row > .ask > summary { width:100%; }
  .tbl .act-row .btn { width:100%; }
  /* …de az IKONOS műveletsor vízszintes marad. A teljes szélességű gombokra
     azért állunk át telefonon, mert két szöveges gomb egymás mellett nem fér
     ki — két 32 képpontos ikon viszont igen, és egymás alá rakva megduplázná
     a sor magasságát. */
  .tbl .act-row:has(.btn-icon) {
    flex-direction:row; align-items:center; justify-content:center;
  }

  /* Szervezeti fa: a megnevezés saját sorba, a műveletek alá — de egymás
     MELLÉ, tördelve. Egy gomb per sor öt korosztálynál olvashatatlanul
     hosszú lapot adna. */
  .org-head { flex-direction:column; align-items:flex-start; }
  .org-head .act-row { width:100%; }
  /* A csapattáblából telefonon az évad esik ki először — az a korosztály
     szintjén úgyis egységes. A megmaradt oszlopok fix szélességet kapnak:
     a 11%-os arány mellett a „JÁTÉKOS" fejléc a szomszédjára csúszott. */
  /* A fában a táblázat a behúzás miatt alig 280 képpont: ott a névnek kell
     a hely. Az évad a korosztály szintjén úgyis egységes, a létszám és a
     rendezendő pedig a név alá csúszik — enélkül a „sportorvosi" szó a
     betűk közt tört ketté. */
  .tbl-team .col-team, .tbl-team .col-count { display:none; }
  .tbl-team .col-act { width:96px; }
  /* A „Játékos" fejléc nem fér el 11%-on: fix szélesség kell, különben
     a szomszédjára csúszik. */
  .tbl .col-count { width:64px; }
  .tbl-sub { display:block; margin-top:2px; }
  .tbl td { padding:10px 12px; }
  .tbl .col-shirt { width:42px; padding-right:4px; }
  .rolechip em { display:none; }
  /* Telefonon a belépési azonosító oszlopa eltűnik: a szerepkörök kapják
     a felszabaduló helyet. */
  .tbl .col-roles { width:40%; }
  /* A cím és a hatókörszint nem hagyható el — csak kap több helyet. */
  .tbl .col-where { width:44%; }
  .tbl .col-lvl   { width:34%; }
  .tbl .col-ver   { width:28%; }

  /* Konzol: nyolc menüpont nem fér a márkanév mellé. A sáv saját sorba
     kerül, a profilkép pedig fent marad, ahol keresik. */
  .console-nav { order:3; flex:1 1 100%; max-width:none; }
}

/* ---- szülői igénylés ---- */

.req {
  display:flex; justify-content:space-between; gap:16px; flex-wrap:wrap;
  padding:12px 0; border-top:1px solid var(--line);
}
.req:first-of-type { border-top:0; }
.req-acts { display:flex; gap:14px; align-items:flex-start; }

/* Csak a választott ág mezői látszanak a szülő-felvevőben. */
.sheet-form .only-existing, .sheet-form .only-new { display:none; }
.sheet-form:has(#g-existing:checked) .only-existing { display:flex; }
.sheet-form:has(#g-new:checked) .only-new { display:flex; }

/* Adatpárok listája: a kulcs halvány, az érték hangsúlyos. */
.facts { display:grid; grid-template-columns:auto 1fr; gap:7px 20px; margin:4px 0 0; }
.facts dt { font-size:12.5px; color:var(--muted); line-height:1.5; }
.facts dd { margin:0; font-size:13.5px; line-height:1.5; }
@media (max-width:520px) {
  .facts { grid-template-columns:1fr; gap:2px; }
  .facts dd { margin-bottom:10px; }
}

/* =====================================================================
   TOOLTIP
   =====================================================================

   A natív `title` marad a markupban — ez a fallback. Az `app.js` veszi át
   (`data-tip`), és csak akkor teszi ki a `has-tips` osztályt, ha sikerült:
   script nélkül tehát a böngésző saját buboréka működik, ahogy eddig.

   Miért kell egyáltalán. A natív `title` másfél másodperc múlva jelenik
   meg, a kinézete rendszerenként más, és sok helyen ez az egyetlen
   magyarázat — a sorműveletek ikonjainál épp az mondja meg, mit csinál a
   gomb. Fél perc böngészés alatt kétszer futsz bele, hogy vártál rá.

   A pozicionálás JS-ből megy (`element.style`), és ez a szigorú CSP-vel
   nem ütközik: az irányelv a MARKUPBAN lévő `style` attribútumot és a
   `<style>` blokkot tiltja, a CSSOM-on át írt értéket nem. */
.tip {
  position:fixed; top:0; left:0; z-index:60;
  max-width:min(300px, 72vw); padding:7px 10px;
  border-radius:var(--radius-sm);
  background:var(--ink); color:var(--paper);
  font-size:12.5px; line-height:1.45; text-align:left; white-space:normal;
  box-shadow:0 6px 22px -8px rgba(18,23,28,.45);
  /* Nem fogja el az egeret: enélkül a saját maga alatt lévő gombról
     levenné a hovert, és villogna. */
  pointer-events:none;
  opacity:0; visibility:hidden;
  transition:opacity .12s ease, visibility .12s;
}
.tip.is-on { opacity:1; visibility:visible; }

/* SÖTÉT TÉMÁHOZ NINCS KÜLÖN SZABÁLY, és ez nem feledékenység: az
   `--ink`/`--paper` pár a `[data-theme="dark"]` alatt megcserélődik, tehát
   a buborék magától fordul — sötét lapon világos lesz. Ez a helyes: a
   tooltip mindig ELÜT a laptól.

   Az első változatban itt egy `prefers-color-scheme` blokk állt, és az
   hibás volt: ez a rendszer szándékosan NEM követi az operációs rendszer
   beállítását („egyelőre csak explicit választásra, nem automatikusan"),
   tehát a lap világos maradt, a buborék viszont átváltott — világos
   szöveg világos háttéren. */

/* A játékos adatlapján a meccsenkénti csík: a csempék alatt, saját sorban.
   Ugyanazok a jelek, mint a statisztika lapon — egy jel nem jelenthet két
   dolgot a rendszerben —, de itt elfér mellettük a magyarázat is, mert
   egyetlen sorról van szó, nem tizenháromról. */
.pstat-spread {
  display:flex; align-items:center; flex-wrap:wrap; gap:8px;
  margin:0 0 14px; padding:10px 12px;
  background:var(--field); border-radius:var(--radius-sm);
}
.pstat-label { font-size:12px; font-weight:600; color:var(--ink-2); }
.pstat-spread .spread { border-bottom:1px solid var(--line-strong); padding-bottom:2px; }
.pstat-trend { font-size:12.5px; font-variant-numeric:tabular-nums; color:var(--muted); }
/* A magyarázat a sor végére kerül, és ha nem fér ki, új sorba — a
   csíknak akkor is a címke mellett kell maradnia. */
.pstat-hint { flex:1 1 220px; font-size:12px; color:var(--muted); line-height:1.4; }

/* A játékos adatlapján a MECCSENKÉNTI lista. Saját szélességek, mert a
   `.tbl` fix elrendezésű: itt hat hasáb van, és az ellenfél neve meg az
   események kapják a maradékot. */
.tbl-pmatch .col-when { width:96px; white-space:nowrap; }
.tbl-pmatch .col-num  { width:74px; }
.tbl-pmatch .col-team { width:80px; }
.tbl-pmatch .col-perc { width:86px; text-align:left; }
/* Az esemény-hasáb nem kiemelt, szemben a `.tbl .col-med` alapjával: itt
   nem rendezendő teendő van benne, hanem felsorolás. */
.tbl-pmatch .col-med  { width:30%; font-weight:400; }
.tbl-pmatch .col-med .pill { margin:1px 3px 1px 0; }
/* A kis jel a szám ELŐTT, a szöveg alapvonalára ültetve. */
.tbl-pmatch .spread { vertical-align:-4px; margin-right:5px; border-bottom:0; }

/* A statisztika MECCSENKÉNTI nézete. A `.tbl` fix elrendezésű, tehát a hat
   hasábnak itt is kell szélesség — a mérkőzés neve és a jegyzőkönyv kapja
   a maradékot. A „Pályára lépett" a leghosszabb fejléc: az szabja meg a
   hasáb alsó határát. */
.tbl-mlist .col-when { width:96px; white-space:nowrap; }
.tbl-mlist .col-num  { width:78px; }
.tbl-mlist .col-med  { width:28%; font-weight:400; }
.tbl-mlist .col-med .pill { margin:1px 3px 1px 0; }
@media (max-width:720px) {
  /* Telefonon a keret és a pályára lépés a mérkőzés alá csúszik — ott az
     eredmény és a jegyzőkönyv a két beszédes adat. */
  .tbl-mlist .col-num:not(:nth-of-type(3)) { display:none; }
  .tbl-mlist .col-when { width:70px; }
  .tbl-mlist .col-med  { width:34%; }
}

/* Sérülés az esemény lapján — három hasáb, nem hat. A sérülési napló
   `tbl-injury` szélességei ott jók, ahol hat oszlop osztozik a helyen; itt
   a név kapná az egészet, az állapot mondata meg öt sorba törne. */
.tbl-evinjury .col-name  { width:30%; }
.tbl-evinjury .col-kind  { width:34%; }
.tbl-evinjury .col-state { width:auto; }
.tbl-evinjury .col-state .tbl-note { display:block; }

/* =====================================================================
   ÉRTÉKELÉS (8. fázis)
   ===================================================================== */

/* Időszakok sora. Link, nem fül: minden időszak saját címen él, tehát
   megosztható és visszakereshető — ugyanaz az elv, mint a profil füleinél. */
nav.chips { margin:0 0 16px; }
nav.chips .chip {
  display:inline-flex; align-items:center; gap:8px;
  padding:7px 12px; border-radius:999px; font-size:13.5px;
  border:1px solid var(--line-strong); background:var(--surface);
  color:var(--ink); text-decoration:none;
}
nav.chips .chip:hover { border-color:var(--accent); }
nav.chips .chip.is-on { border-color:var(--accent); background:var(--accent-soft); font-weight:600; }
.chip-state { font-size:10.5px; text-transform:uppercase; letter-spacing:.06em; color:var(--muted); font-weight:500; }
.chip-state.st-open     { color:var(--st-present); }
.chip-state.st-closed   { color:var(--st-late); }
.chip-state.st-released { color:var(--st-excused); }

/* A pontszám választója: nagy, ujjal is eltalálható gombsor. Rádiógomb
   alatta, tehát JavaScript nélkül működik, és billentyűzettel is. */
.score { border:0; margin:0; padding:10px 0; border-top:1px solid var(--line); }
.score:first-of-type { border-top:0; }
.score legend { font-size:14px; font-weight:600; padding:0; margin-bottom:8px; }
.score legend .hint { display:block; font-weight:400; }
.score-row { display:flex; flex-wrap:wrap; gap:6px; }
.score-opt { position:relative; }
.score-opt input { position:absolute; opacity:0; width:1px; height:1px; }
.score-opt span {
  display:inline-flex; align-items:center; justify-content:center;
  min-width:38px; height:38px; padding:0 8px; cursor:pointer;
  border:1px solid var(--line-strong); border-radius:var(--radius-sm);
  background:var(--field); font-weight:600; font-variant-numeric:tabular-nums;
}
.score-opt input:checked + span { background:var(--accent); border-color:var(--accent); color:#fff; }
.score-opt input:focus-visible + span { outline:2px solid var(--club); outline-offset:2px; }
.score-none span { color:var(--muted); font-weight:400; }
.score-none input:checked + span { background:var(--surface-2); border-color:var(--line-strong); color:var(--ink-2); }

/* Az értékelt időszak tényei. Csempe, nem táblázat: négy-öt szám, amit egy
   pillantással át kell látni, mielőtt az ember véleményt ír. */
.facts { display:flex; flex-wrap:wrap; gap:10px; margin:8px 0; }
.fact {
  flex:1 1 140px; display:flex; flex-direction:column; gap:3px;
  padding:10px 12px; border-radius:var(--radius-sm); background:var(--field);
}
.fact-n { font-size:22px; font-weight:700; font-variant-numeric:tabular-nums; }
.fact-l { font-size:12.5px; color:var(--ink-2); line-height:1.4; }

.assess-h { font-size:13px; text-transform:uppercase; letter-spacing:.05em; color:var(--muted); margin:14px 0 4px; }
.assess-h:first-of-type { margin-top:4px; }
.assess-text { margin:0; line-height:1.6; }
/* 11.61: az átlag számként és a lap szerzői; a kikapcsolt kritérium csak olvasható */
.assess-meta { margin:0 0 12px; line-height:1.6; }
.score-off .legend { font-size:14px; font-weight:600; margin:0 0 4px; }
.score-off p:last-child { margin:0; font-size:13px; }
.grants-score .k { width:45%; }

/* Jegyzetek. A láthatóság a bal szegély színe ÉS a kiírt szó: a „szülő is
   látja" nem maradhat egy apró jel, amit át lehet siklani. */
.notes { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:10px; }
.note-item {
  position:relative; padding:10px 12px 10px 14px; border-radius:var(--radius-sm);
  background:var(--field); border-left:3px solid var(--line-strong);
}
.note-item.vis-section { border-left-color:var(--st-excused); }
.note-item.vis-parents { border-left-color:var(--st-late); background:var(--st-late-soft); }
.note-item.vis-parents .vis-label { color:var(--st-late); font-weight:600; }
.note-body { margin:0 0 4px; line-height:1.55; padding-right:84px; }
.note-meta { margin:0; font-size:12.5px; }
.note-acts { position:absolute; top:8px; right:8px; }
/* A megerősítés FELUGRÓ doboz, mint a táblázatsorokban (`.tbl .ask-icon`):
   az ikon a helyén marad, a kérdés alatta nyílik, jobbra igazítva. Nélküle
   a doboz a műveletsort 400 képpontosra feszítette, az ikonok balra, a
   jegyzet szövegére csúsztak. */
/* Egy sor, két fix hely. A közös szabály nyitáskor saját sort ad a
   megerősítőnek (`.act-row > .ask[open]`, `.act-row:has(.ask[open])`), mert
   ott a doboz a sorba nyílik. Itt felugró doboz, tehát nincs miért törni —
   különben a második ikon a ceruza alá ugrott. */
.note-acts .act-row,
.note-acts .act-row:has(.ask[open]) { flex-wrap:nowrap; }
.note-acts .act-row > .ask-icon,
.note-acts .act-row > .ask-icon[open] { position:relative; flex:none; width:32px; }
.note-acts .ask-icon .ask-box {
  position:absolute; right:0; top:calc(100% + 6px); z-index:5;
  width:max-content; max-width:min(320px, 80vw); margin-top:0;
  box-shadow:0 14px 32px -12px rgba(12,20,26,.4);
}

.tbl-assess .col-team  { width:28%; }
.tbl-assess .col-state { width:120px; }
.tbl-assess .col-act   { width:96px; }
.tbl-crit .col-kind { width:22%; }
.tbl-crit .col-num  { width:80px; }
.tbl-crit .col-act  { width:96px; }
@media (max-width:720px) {
  .tbl-assess .col-team { display:none; }
  .note-body { padding-right:0; }
  .note-acts { position:static; margin-top:6px; }
  /* Jobbra: a felugró kérdés az ikon jobb széléhez igazodik, balra nyílna ki
     a képernyőből, ha az ikon a sor elején állna. */
  .note-acts .act-row { justify-content:flex-end; }
}
@media (min-width:721px) {
  .tbl-assess .col-name .tbl-sub { display:none; }
}

/* Papíron a panel keret nélküli blokk — a nyomtatványon nincs kártya. */
.paper .panel { border:0; box-shadow:none; padding:0; background:none; }
.paper .panel-head h3 { font-size:15px; margin:0 0 8px; }
.paper .meter-track { background:#ddd; }
.paper .meter { background:#111; }

/* Letiltott ikon egy műveletoszlopban. A hely megmarad, a jel halvány, és
   nem reagál: se hover-szín, se mutató — de a tooltip megmondja, miért nem
   érhető el. Az értékelés névsora használja (a nyomtatás ikonja így
   soronként ugyanott áll). */
.btn-icon.is-disabled { opacity:.35; cursor:not-allowed; }
.btn-icon.is-disabled:hover { background:none; color:var(--muted); }

/* ---- Tagdíj (9. fázis) ----
   A pénz hasábjai jobbra zártak, tabuláris számjeggyel (`.col-num`): a szem
   a helyiértéket pásztázza, és a „8 000" meg a „12 500" így egy vonalban
   áll. A hátralék félkövér — a lista ezért az egy számért létezik.
   A csapat egyik táblán sem külön hasáb, hanem a név alatt áll (mint a
   sérüléslistán): nyolc fix hasáb 800 képpontos ablakban a névre nullát
   hagyott, és a név betűnként tört. A dátum a mért 112 képpont. */
.tbl-fees .col-when, .tbl-fee-player .col-when, .tbl-fee-plans .col-when, .tbl-fee-debts .col-when {
  width:112px; white-space:nowrap; font-variant-numeric:tabular-nums;
}
.tbl-fees .col-name, .tbl-fee-player .col-name, .tbl-fee-plans .col-name, .tbl-fee-debts .col-name {
  width:auto; overflow-wrap:normal;
}
.tbl-fees .col-num, .tbl-fee-player .col-num { width:96px; }
.tbl-fees .col-state, .tbl-fee-player .col-state { width:112px; font-weight:600; }
.tbl-fees .col-act, .tbl-fee-player .col-act, .tbl-fee-plans .col-act { width:96px; }
.tbl-fees th, .tbl-fees td { padding-inline:12px; }
.tbl-fee-plans .col-num   { width:104px; }
.tbl-fee-plans .col-day   { width:88px; }
.tbl-fee-plans .col-state { width:120px; }
.tbl-fee-debts .col-num, .tbl-fee-groups .col-num { width:110px; }
.tbl-fee-groups { margin-bottom:18px; }

/* Sztornózott befizetés: áthúzva marad — az elszámolásban ott a helye, csak
   nem számít. */
.is-void { text-decoration:line-through; color:var(--muted); }

/* A befizetések listája a díj kezelésének ablakában: soronként az összeg, a
   nap, a mód, alatta ki rögzítette — jobbra a bizonylat és a sztornó. */
.sheet-after { padding:0 22px 18px; }
.sheet-sub { font-size:12px; text-transform:uppercase; letter-spacing:.06em; color:var(--muted); margin:16px 0 6px; }
.fee-pays { list-style:none; margin:0; padding:0; }
.fee-pays li {
  display:flex; align-items:center; gap:10px; padding:8px 0;
  border-top:1px solid var(--line);
}
.fee-pays li:first-child { border-top:0; }
.fee-pay-main { flex:1 1 auto; }
.fee-pays li.is-void .fee-pay-main strong { text-decoration:line-through; }
/* A sztornó kérdése FELFELÉ nyílik: az ablak sorai a táblázatsor
   szabályát öröklik (lefelé nyíló doboz), a lista pedig az ablak alján áll —
   lefelé az ablak görgethető doboza levágta, és a kattintás a semmibe ment. */
.fee-pays .ask-icon { position:relative; }

/* Állandó kedvezmények az adatlapon: szabályonként egy sor, jobbra a
   megszüntetés. A lejárt szabály halványan marad — látszódjon, meddig járt. */
.fee-rules { list-style:none; margin:0 0 12px; padding:0; }
.fee-rules li {
  display:flex; align-items:center; justify-content:space-between; gap:10px;
  padding:9px 12px; border:1px solid var(--line); border-radius:var(--radius-sm); margin-bottom:6px;
}
.fee-rules li.is-off { opacity:.55; }
.fee-rules .ask-icon { position:relative; }
.fee-rules .ask-icon .ask-box { position:absolute; right:0; top:calc(100% + 6px); z-index:5;
  width:max-content; max-width:min(320px, 70vw); box-shadow:0 14px 32px -12px rgba(12,20,26,.4); }
/* A szétosztás sorrendje az ablakban. */
.fee-order { margin:0 0 12px; padding-left:20px; font-size:13.5px; }
.fee-order li { margin:2px 0; }
.tbl-fee-debts .col-act { width:64px; }
.fee-pays .ask-icon .ask-box { top:auto; bottom:calc(100% + 6px); right:0; left:auto; }

/* Keskenyebb ablakban (oldalsávval 1100 alatt) a befizetett rész és a
   határidő elmarad: a díj kezelésének ablakában és a név alatti alsorban
   ott van. A név így sosem szorul 150 képpont alá. */
@media (max-width:1100px) {
  .tbl-fees .col-paid, .tbl-fees .col-when,
  .tbl-fee-player .col-paid, .tbl-fee-player .col-when,
  .tbl-fee-plans .col-day,
  .tbl-fee-debts .col-items, .tbl-fee-debts .col-when { display:none; }
  .tbl-fees .col-name .tbl-sub, .tbl-fee-player .col-name .tbl-sub { display:block; margin-top:2px; }
}
/* Telefonon a díj összege is: marad a név, a hátralék, az állapot és a
   művelet — ennyi kell ahhoz, hogy az edzés után rögzíteni lehessen. */
@media (max-width:720px) {
  .tbl-fees .col-due, .tbl-fee-player .col-due, .tbl-fee-plans .col-when { display:none; }
}

/* =====================================================================
   ÉRTESÍTÉSEK (10. fázis)
   A harang a fejlécben, a profilkép előtt. A profilmenü a `margin-left:auto`-
   val tolódott jobbra; a harang most átveszi ezt a szerepet, és a menü
   mellé zár.
   ===================================================================== */
.bell {
  position:relative; margin-left:auto; flex:0 0 auto;
  display:grid; place-items:center; width:38px; height:38px; border-radius:50%;
  color:var(--ink-2); text-decoration:none;
}
.bell:hover { background:var(--field); color:var(--ink); }
.bell:focus-visible { outline:2px solid var(--club); outline-offset:2px; }
.bell svg { width:22px; height:22px; fill:none; stroke:currentColor; stroke-width:1.8;
            stroke-linecap:round; stroke-linejoin:round; }
.bell + .me { margin-left:0; }
.bell-n {
  position:absolute; top:2px; right:1px; min-width:18px; height:18px; padding:0 5px;
  border-radius:9px; background:var(--danger); color:#fff;
  font-size:11px; font-weight:700; line-height:18px; text-align:center;
  box-shadow:0 0 0 2px var(--surface);
}

/* A harang listája: egy sor egy üzenet, maga a sor a hivatkozás. */
.inbox { list-style:none; margin:0 0 20px; padding:0;
         background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); overflow:hidden; }
.inbox-row + .inbox-row { border-top:1px solid var(--line); }
.inbox-row > a {
  display:grid; grid-template-columns:10px minmax(0,1fr) auto; gap:12px; align-items:start;
  padding:12px 16px; color:var(--ink-2); text-decoration:none;
}
.inbox-row > a:hover { background:var(--field); }
.inbox-dot { width:8px; height:8px; margin-top:7px; border-radius:50%; background:transparent; }
.inbox-row.is-new .inbox-dot { background:var(--club); }
.inbox-row.is-new strong { color:var(--ink); }
.inbox-main strong { display:block; font-weight:600; }
.inbox-row:not(.is-new) .inbox-main strong { font-weight:500; }
.inbox-main span { display:block; font-size:13.5px; color:var(--muted); margin-top:2px; }
.inbox-meta { display:flex; flex-direction:column; align-items:flex-end; gap:4px; font-size:12.5px; color:var(--muted); white-space:nowrap; }
@media (max-width:640px) {
  .inbox-row > a { grid-template-columns:10px minmax(0,1fr); }
  .inbox-meta { grid-column:2; flex-direction:row; align-items:center; }
}

/* Beállítások: típus × csatorna. */
.tbl-prefs .col-check { width:84px; text-align:center; }
.tbl-prefs .check-solo { justify-content:center; }
.tbl-prefs .check-solo input:disabled { opacity:.55; }
.push-box { display:flex; flex-wrap:wrap; align-items:center; gap:12px; margin:6px 0 14px; }
.push-box[hidden] { display:none; }
.device-list { list-style:none; margin:0; padding:0; }
.device-list li { display:flex; align-items:center; justify-content:space-between; gap:12px;
                  padding:9px 0; border-top:1px solid var(--line); }

/* Sablonszerkesztő: bal oldalt az űrlap, jobb oldalt az előnézet. */
.tpl-edit { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:20px; align-items:start; }
.tpl-edit .panel { margin-bottom:0; }
.tpl-edit textarea { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:13.5px; line-height:1.5; }
.tpl-acts { margin:14px 0 10px; }
.tpl-frame { width:100%; height:640px; border:1px solid var(--line); border-radius:var(--radius-sm); background:#f3f4f6; }
.tpl-vars { width:100%; font-size:13px; margin-top:6px; }
.tpl-vars td { padding:5px 8px 5px 0; border-bottom:1px solid var(--line); vertical-align:top; }
.tpl-vars td:first-child { white-space:nowrap; width:1%; }
.tpl-pre { white-space:pre-wrap; font-size:12.5px; background:var(--field); padding:10px 12px;
           border-radius:var(--radius-sm); overflow-wrap:anywhere; margin:8px 0 0; }
.tpl-parent { margin-top:14px; }
.tpl-parent summary { cursor:pointer; color:var(--ink-2); font-size:14px; }
.tbl-templates .col-subject code { font-size:12.5px; }
@media (max-width:1100px) {
  .tpl-edit { grid-template-columns:minmax(0,1fr); }
  .tpl-frame { height:520px; }
}

/* Faliújság */
.notice-head { display:flex; justify-content:space-between; align-items:flex-start; gap:12px; }
.notice-head h3 { margin:0 0 4px; }
.notice-head .muted { margin:0; font-size:13px; display:flex; flex-wrap:wrap; gap:6px; align-items:center; }
.notice.is-pinned { border-color:var(--club); box-shadow:inset 3px 0 0 var(--club), var(--lift); }
.notice.is-off { opacity:.7; }
.notice-body { margin-top:10px; }
.notice-body p { margin:0 0 10px; overflow-wrap:anywhere; }
.notice-mini { list-style:none; margin:0; padding:0; }
.notice-mini li { display:flex; flex-wrap:wrap; justify-content:space-between; gap:4px 12px;
                  padding:8px 0; border-top:1px solid var(--line); }
.notice-mini li:first-child { border-top:0; padding-top:0; }
.notice-mini a { color:var(--ink); text-decoration:none; }
.notice-mini a:hover { text-decoration:underline; }
.notice-mini .muted { font-size:13px; }

/* Születésnapok a csapat lapján */
.bday-list { list-style:none; margin:0; padding:0; }
.bday-list li { display:flex; flex-wrap:wrap; justify-content:space-between; gap:4px 12px;
                padding:8px 0; border-top:1px solid var(--line); }
.bday-list li:first-child { border-top:0; }
.bday-list li.is-today a { font-weight:650; }
.tbl-templates .col-name { width:34%; }
.tbl-templates .col-subject { text-align:left; }
.tbl-templates .col-state { width:120px; }
.tbl-templates .col-act { width:64px; }
.tbl-outbox .col-when { width:110px; }
.tbl-outbox .col-team { width:150px; }
.tbl-outbox .col-name { width:24%; }
.tbl-outbox .col-subject { text-align:left; }
.tbl-outbox .col-state { width:190px; }
.tbl-outbox .col-act { width:64px; }
@media (max-width:720px) {
  .tbl-templates .col-subject, .tbl-outbox .col-subject, .tbl-outbox .col-team { display:none; }
}
@media (max-width:640px) {
  .tbl-prefs .col-check { width:60px; padding-inline:4px; }
  .tbl-prefs th.col-check { font-size:10.5px; letter-spacing:.02em; }
}
