/* TeamRadar — "Field Notes" editorial theme, light + dark.
   App chrome is a calm neutral; --team is the per-team accent pulled from the
   uploaded logo (set inline on <html>), falling back to a neutral slate. */
:root{
  --paper:#F5F6F3; --ink:#20261F; --muted:#4E5647; --line:#DDE0D7;
  --card:#FCFCFA; --tint:#EEF0EA;
  --gold:#7E6420; --warn:#9A6B12; --crit:#9E3B2E; --good:#3B6B4A;
  --ok:#14663a;                 /* success text — theme-aware, see dark */
  --team:#3f5060;               /* overridden per-team from logo (clamped dark) */
  --team-ink:#ffffff;           /* readable text ON the team fill (set inline) */
  --team-text:var(--team);      /* team color used as text on the page */
  --team-soft:color-mix(in srgb, var(--team) 12%, var(--card));
  --team-fill:var(--team);          /* light: unchanged */
  --team-ink-dark:var(--team-ink);
  --serif:"Newsreader",Georgia,"Times New Roman",serif;
  --sans:"Public Sans",system-ui,-apple-system,sans-serif;
}
[data-theme="dark"]{
  /* Palette B, tuned. The old dark was near-black with cards 1.1:1 off
     the page and borders at 1.2:1 — flat, and nothing framed anything.
     Ground drops, cards LIFT, borders become visible at ~1.75:1.
     Owner-chosen: dark only; light mode is untouched. */
  --paper:#121418; --ink:#EAEDF1; --muted:#B4BDC8; --line:#49515F;
  --card:#272C36; --tint:#2F3540;
  --gold:#C9A24A; --warn:#D69A3A; --crit:#E7796A; --good:#6FB07E;
  --ok:#7BC493;
  /* ONE fixed accent in dark, owner's call: the team colour is clamped
     dark so it reads on white, and lightening it back produced a dusty
     nothing-colour. Light mode keeps the team colour. */
  --team-soft:color-mix(in srgb, #A6C8E4 14%, var(--card));
  --team-text:#A6C8E4;
  --team-fill:#A6C8E4;
  --team-ink-dark:#121418;
}
@media (prefers-color-scheme:dark){
  [data-theme="auto"]{
    /* Palette B, tuned. The old dark was near-black with cards 1.1:1 off
       the page and borders at 1.2:1 — flat, and nothing framed anything.
       Ground drops, cards LIFT, borders become visible at ~1.75:1.
       Owner-chosen: dark only; light mode is untouched. */
    --paper:#121418; --ink:#EAEDF1; --muted:#B4BDC8; --line:#49515F;
    --card:#272C36; --tint:#2F3540;
    --gold:#C9A24A; --warn:#D69A3A; --crit:#E7796A; --good:#6FB07E;
    --ok:#7BC493;
    /* ONE fixed accent in dark, owner's call: the team colour is clamped
       dark so it reads on white, and lightening it back produced a dusty
       nothing-colour. Light mode keeps the team colour. */
    --team-soft:color-mix(in srgb, #A6C8E4 14%, var(--card));
    --team-text:#A6C8E4;
    --team-fill:#A6C8E4;
    --team-ink-dark:#121418;
  }
}
*{box-sizing:border-box}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--sans);
  font-size:1.0625rem;line-height:1.55}
/* pin the bare-heading sizes: they inherit the UA's em defaults, so the
   17px body bump would silently enlarge every unstyled h1/h2/h3 */
h1,h2,h3{font-family:var(--serif);font-weight:600;text-wrap:balance;margin:0}
h1{font-size:1.9rem}h2{font-size:1.4rem}h3{font-size:1.1rem}
a{color:var(--team-text);text-decoration:none}
a:hover{text-decoration:underline}
.num{font-variant-numeric:tabular-nums}
:focus-visible{outline:2px solid var(--ink);outline-offset:2px;
  box-shadow:0 0 0 4px color-mix(in srgb, var(--team-text) 45%, transparent)}

/* shell */
.topbar{display:flex;align-items:center;justify-content:space-between;
  /* viewport-fit=cover puts the page under the iOS status bar in
     standalone mode; the safe-area insets are 0 everywhere else, so
     nothing shifts in ordinary browsers */
  padding:calc(.8rem + env(safe-area-inset-top)) calc(1.5rem + env(safe-area-inset-right))
    .8rem calc(1.5rem + env(safe-area-inset-left));
  border-bottom:1px solid var(--line);background:var(--paper)}
.topbar .brand{font-family:var(--serif);font-weight:600;font-size:1.3rem;
  color:var(--ink);text-decoration:none;letter-spacing:.01em}
.topbar .team{color:var(--muted);font-weight:500;display:flex;align-items:center;gap:.5rem}
.teamswitch{font-family:var(--serif);font-weight:600;color:var(--ink);background:none;
  border:0;width:100%;padding:.2rem 0;margin:1.3rem 0 .3rem;font-size:1rem;cursor:pointer}
.teamswitch:hover{color:var(--team-text)}
.topbar .user{display:flex;align-items:center;gap:.55rem;font-weight:500;color:var(--ink);
  text-decoration:none;min-width:0}
/* the display name falls back to the username, which is an email: one
   unbreakable token that pushed the page wider than the viewport */
.topbar .user{overflow:hidden}
.usermenu>summary.user{white-space:nowrap;text-overflow:ellipsis}
.avatar{width:30px;height:30px;border-radius:50%;background:var(--team);
  color:var(--team-ink);display:grid;place-items:center;font-family:var(--serif);font-weight:600}
/* top-right account dropdown (no-JS <details>) */
.usermenu{position:relative}
.usermenu>summary{display:flex;align-items:center;gap:.55rem;cursor:pointer;
  list-style:none;user-select:none}
.usermenu>summary::-webkit-details-marker{display:none}
.usermenu>summary::marker{content:""}
.usermenu-panel{position:absolute;right:0;top:calc(100% + .45rem);z-index:60;
  min-width:190px;display:flex;flex-direction:column;padding:.3rem;
  background:var(--card);border:1px solid var(--line);border-radius:10px;
  box-shadow:0 8px 28px rgba(0,0,0,.14)}
.usermenu-panel a,.usermenu-panel button{display:block;width:100%;text-align:left;
  padding:.55rem .65rem;border:0;border-radius:7px;background:none;color:var(--ink);
  font:inherit;font-weight:500;text-decoration:none;cursor:pointer}
.usermenu-panel a:hover,.usermenu-panel button:hover{background:var(--tint);
  filter:none;text-decoration:none}
.usermenu-panel form{margin:0}
.navtoggle{display:none;background:none;border:0;color:var(--ink);font-size:1.5rem;
  line-height:1;padding:.2rem .5rem;margin-right:.2rem;cursor:pointer}
.scrim{display:none}
.layout{display:flex;min-height:calc(100vh - 56px)}
.sidebar{width:210px;flex:0 0 210px;padding:1.25rem 1rem;border-right:1px solid var(--line)}
.sidebar nav{display:flex;flex-direction:column}
.sidebar nav a{padding:.42rem .3rem;color:var(--muted);font-size:1.02rem;font-weight:500;
  border-bottom:1px solid transparent}
.sidebar nav a.active{color:var(--team-text);font-weight:700}
.sidebar nav a:hover{color:var(--ink);text-decoration:none}
.sidebar .grp{margin:1.3rem .3rem .4rem;font-size:.78rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted)}
main{flex:1;max-width:860px;margin:0 auto;padding:1.8rem 2.4rem;width:100%}
@media (max-width:720px){
  .navtoggle{display:inline-flex;align-items:center}
  /* compose the safe-area insets here too: this later rule wins the
     cascade on phones — the only hardware with a notch to clear */
  .topbar{padding:calc(.7rem + env(safe-area-inset-top))
    calc(1rem + env(safe-area-inset-right)) .7rem
    calc(1rem + env(safe-area-inset-left))}
  .topbar .brand{font-size:1.15rem}
  .topbar .team{display:none}          /* team name still shows in the open menu */
  main{padding:1.2rem;max-width:none}
  /* sidebar becomes a slide-in drawer toggled by the hamburger */
  .sidebar{position:fixed;top:0;left:0;bottom:0;z-index:40;width:78%;max-width:300px;
    background:var(--paper);border-right:1px solid var(--line);
    padding:calc(1.1rem + env(safe-area-inset-top)) 1.1rem 2rem;
    overflow-y:auto;transform:translateX(-100%);transition:transform .2s ease;
    box-shadow:2px 0 16px rgba(0,0,0,.12)}
  body.nav-open .sidebar{transform:translateX(0)}
  body.nav-open .scrim{display:block;position:fixed;inset:0;z-index:30;
    background:rgba(0,0,0,.35)}
  .sidebar nav a{display:block;padding:.85rem .2rem;font-size:1.02rem;
    border-bottom:1px solid var(--line)}
  .sidebar .grp{margin:1.1rem .2rem .3rem}
}

/* headers */
.eyebrow{font-size:.8rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--gold);font-weight:600;margin-bottom:.4rem}
.phead{display:flex;align-items:baseline;gap:.8rem;border-bottom:2px solid var(--ink);
  padding-bottom:.6rem;margin-bottom:1.2rem;flex-wrap:wrap}
.phead .no{font-family:var(--serif);font-weight:600;color:var(--muted);font-size:1.4rem}
.phead h1{font-size:2.1rem;line-height:1.05}
.phead .pos{color:var(--muted);font-style:italic;font-family:var(--serif);font-size:1rem}
.team-logo{height:1.5rem;width:1.5rem;object-fit:contain;border-radius:4px;
  vertical-align:middle;margin-right:.4rem}
h1 .team-logo{height:1.9rem;width:1.9rem}
.crumb{color:var(--muted);font-size:.95rem;margin-bottom:.5rem}
/* player-page action row (clickable words, not chunky buttons) */
.phead-manage{margin-left:auto;font-size:1rem;font-weight:600;color:var(--ink);
  text-decoration:none;white-space:nowrap}
.phead-manage:hover{text-decoration:underline}
.pactions{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem 1.6rem;margin:0 0 1.4rem}
.pactions form{margin:0;display:inline}
/* bare-word actions still need a finger-sized target */
.linkbtn{background:none;border:0;padding:.5rem 0;margin:0;font-family:var(--sans);
  font-size:1.02rem;font-weight:600;color:var(--team-text);cursor:pointer;
  text-decoration:none;line-height:1.4}
.linkbtn:hover{text-decoration:underline}
.linkbtn[disabled]{opacity:.6;cursor:progress}
.sectitle{font-family:var(--serif);font-size:1.2rem;font-weight:600;
  margin:1.9rem 0 .7rem;padding-bottom:.3rem;border-bottom:1px solid var(--line)}

/* stat tiles */
.tiles{display:flex;flex-wrap:wrap;margin:0 0 1.4rem;border:1px solid var(--line);
  border-radius:5px;overflow:hidden;background:var(--card)}
.tiles .tile{flex:1;min-width:90px;padding:.75rem 1rem;border-right:1px solid var(--line)}
.tiles .tile:last-child{border-right:0}
.tile .k{font-size:.85rem;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.tile .v{font-family:var(--serif);font-weight:600;font-size:1.6rem;margin-top:.1rem}

/* alert chips / rows */
.chips{display:flex;flex-direction:column;margin:0 0 1.4rem}
/* alert rows are solid severity-colored bars with light text (dark text in dark
   mode, where the severity colors are pastel) */
.chip{display:flex;align-items:center;gap:.5rem;padding:.6rem .85rem;
  border-radius:6px;margin-bottom:.45rem;font-size:1.02rem;background:var(--muted)}
.chip .dot{display:none}
.chip.badge-alert,.chip.crit{background:var(--crit)}
.chip.badge-watch,.chip.warn{background:var(--warn)}
.chip.badge-info{background:var(--muted)}
.chip.badge-good,.chip.good{background:var(--good)}
.chip .lab{font-weight:700;color:#fff}
/* Clear sits INSIDE a solid severity chip, where the page-level ghost
   colours are unreadable */
/* clearing has no undo, so the target stays finger-sized */
.chip .ghost{color:#fff;
  background:transparent;padding:.3rem .6rem;font-size:.8rem}
[data-theme="dark"] .chip .ghost{color:#15171B;
  border-color:rgba(21,23,27,.45)}
@media (prefers-color-scheme:dark){
  [data-theme="auto"] .chip .ghost{color:#15171B;
    border-color:rgba(21,23,27,.45)}
}
.chip .det{color:rgba(255,255,255,.88)}
.flagged-name{display:inline-block;font-family:var(--serif);font-weight:700;
  font-size:1.15rem;color:var(--team-text)}
.flagged-name:hover{text-decoration:underline}
.chip form{margin-left:auto}
[data-theme="dark"] .chip .lab{color:#15171B}
[data-theme="dark"] .chip .det{color:rgba(21,23,27,.82)}
@media (prefers-color-scheme:dark){
  [data-theme="auto"] .chip .lab{color:#15171B}
  [data-theme="auto"] .chip .det{color:rgba(21,23,27,.82)}
}

/* cards / notes / charts */
.card{background:var(--card);border:1px solid var(--line);border-radius:8px;
  padding:1rem 1.15rem;margin:.7rem 0}
.card h3{font-size:1.05rem;margin-bottom:.2rem}
.card .sub{color:var(--muted);font-size:.92rem;font-style:italic;font-family:var(--serif);
  margin-bottom:.4rem}
details.card>summary{cursor:pointer;font-weight:600;font-family:var(--serif)}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:1.4rem}
@media (max-width:640px){.grid2{grid-template-columns:1fr}}
.legend{display:flex;gap:1rem;flex-wrap:wrap;font-size:.88rem;color:var(--muted);margin-top:.4rem}
.legend b{display:inline-block;width:16px;height:2px;margin-right:.35rem;vertical-align:middle}
canvas{max-width:100%}
.note{font-family:var(--serif);font-size:1.1rem;line-height:1.6;color:var(--ink);
  border-left:3px solid var(--team-text);padding-left:1.1rem;background:none}
.note .by,.muted{color:var(--muted)}
.note .by{font-family:var(--sans);font-size:.86rem;margin-top:.6rem}
/* Roster row. The trailing group travels as ONE unit on its own auto
   margin -- two auto margins would split a wrapped line's free space and
   strand the link mid-row. It wraps and right-aligns rather than letting
   the phrase break, which at 320px split "opened 3 / weeks ago". */
.rosterrow{display:flex;flex-wrap:wrap;align-items:baseline;gap:.6rem}
.rosterrow .mark{margin-left:0}      /* .mark's inline margin doubles the gap */
.rowend{margin-left:auto;display:flex;flex-wrap:wrap;justify-content:flex-end;
  gap:.7rem;align-items:center}
/* How long since she opened her own link. Deliberately NOT .mark, in
   shape OR colour: the roster's marks are a closed vocabulary with a
   legend above the list (asked / quiet / trend), and --crit is what
   "? asked" means there. One base class so the column does not change
   size and weight as a player crosses the threshold. */
.seen{font-size:.95rem;white-space:nowrap}
.seen-stale{color:var(--warn);font-weight:600}
.prewrap{white-space:pre-wrap}
.draft{border-left:3px solid var(--gold)}

/* A section that is capped and scrolls inside itself, so a long history
   cannot push the rest of the page below the fold. vh so it stays a
   fraction of the phone in hand rather than a fixed pixel guess, and
   overscroll-behavior so reaching the end does not start scrolling the
   page underneath -- on iOS that reads as the page jumping. */
.scrollbox{max-height:min(24rem,55vh);overflow-y:auto;overscroll-behavior:contain;
  padding-right:.5rem}

/* timeline */
.tl{list-style:none;margin:.3rem 0 0;padding:0}
.tl li{display:flex;gap:1rem;padding:.5rem 0;border-bottom:1px solid var(--line)}
.tl .d{font-family:var(--serif);font-style:italic;color:var(--gold);white-space:nowrap}

/* forms + buttons */
label{display:block;margin:.6rem 0;font-size:1.02rem}
input,select,textarea{width:100%;padding:.55rem .6rem;font-size:1.05rem;font-family:var(--sans);
  border:1px solid var(--line);border-radius:6px;background:var(--card);color:var(--ink)}
input[type=checkbox]{width:auto}
button,.button{padding:.5rem 1rem;font-size:1rem;font-weight:600;border:0;border-radius:6px;
  font-family:inherit;
  background:var(--team-fill);color:var(--team-ink-dark);cursor:pointer;display:inline-block;
  text-decoration:none;line-height:1.2}
button:hover,.button:hover{filter:brightness(.94);text-decoration:none}
/* Owner's call (option A): every button is the Save button. The old
   outline style marked "secondary", but it also marked destructive, and
   on one card it made Save look like the only real control. One button
   style, one tap target, everywhere. `.chip .ghost` below is a
   different thing — it sits inside a solid severity chip. */
button.ghost,.button.ghost{background:var(--team-fill);
  color:var(--team-ink-dark);border:0}
/* ...but NOT inside a severity chip: the rule above sets border:0, which
   out-specifies .chip .ghost's border-color and left Clear as bare text
   floating in a solid chip. It needs its box back. */
.chip .ghost{border:1px solid rgba(255,255,255,.7)}
[data-theme="dark"] .chip .ghost{border:1px solid rgba(18,20,24,.6)}
@media (prefers-color-scheme:dark){
  [data-theme="auto"] .chip .ghost{border:1px solid rgba(18,20,24,.6)}}
/* Owner: "Delete should be fire engine red every other button matches."
   #CE2029 carries 5.4:1 with a white label and reads as the same button
   shape, so the only thing that changes is the colour of the one you
   cannot undo. */
button.danger,.button.danger{background:#CE2029;color:#fff;border:0}
/* On a dark card the fire-engine fill is only 2.58:1 — the fill IS the
   boundary when there is no border, so the one button you cannot undo
   was the dimmest thing on the card while Save blazed at 8:1. A light
   red edge fixes the boundary (4.89:1) without touching the white
   label's 5.44:1. */
/* inset shadow, not a border: a border adds 2px to the rendered box
   and left every Delete taller and wider than the buttons beside it. */
[data-theme="dark"] button.danger,
[data-theme="dark"] .button.danger{box-shadow:inset 0 0 0 1px #E7796A}
@media (prefers-color-scheme:dark){
  [data-theme="auto"] button.danger,
  [data-theme="auto"] .button.danger{box-shadow:inset 0 0 0 1px #E7796A}}
button.danger:hover,.button.danger:hover{filter:brightness(.92)}
button[disabled]{opacity:.6;cursor:progress}
/* compact styled file picker (hides the native widget, keeps it clickable) */
.filepick{position:relative;display:inline-flex;align-items:center;gap:.45rem;
  cursor:pointer}
/* iOS only accepts taps on a file input's own intrinsic button box, so a
   stretched transparent input swallowed every tap and opened nothing.
   The <label> wrapper forwards the tap; the input just has to stay
   focusable (not hidden) for keyboard use. */
.filepick input[type=file]{position:absolute;width:1px;height:1px;
  margin:0;padding:0;opacity:0;pointer-events:none}
.filepick .fp-btn{display:inline-flex;align-items:center;gap:.35rem;
  padding:.5rem .8rem;border:1px solid var(--line);border-radius:6px;
  background:var(--card);color:var(--team-text);font-size:1rem;font-weight:600;
  line-height:1.2;white-space:nowrap}
.filepick:hover .fp-btn{filter:brightness(.96)}
/* general sibling: the logo thumb sits between the input and the
   button whenever a team already has a logo, which killed the only
   focus indicator the 1px input has */
.filepick input[type=file]:focus-visible~.fp-btn{outline:2px solid var(--ink);
  outline-offset:2px}
.filepick .fp-thumb{height:1.7rem;width:1.7rem;object-fit:contain;
  border:1px solid var(--line);border-radius:5px;background:var(--card)}
.filepick .fp-name{font-size:.92rem;color:var(--muted);max-width:9rem;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* photo thumbnails under a coach note (fp-thumb treatment, sized up) */
.note-photos{display:flex;flex-wrap:wrap;gap:.4rem;margin-top:.5rem}
.note-photos img{width:4.5rem;height:4.5rem;object-fit:cover;
  border:1px solid var(--line);border-radius:5px;background:var(--card)}
/* needs-a-word markers: distinct GLYPHS, never colour alone — the app
   has a dark theme and colourblind coaches read this roster too */
.mark{display:inline-block;margin-left:.35rem;font-weight:600;
  font-size:.85rem;line-height:1.4;white-space:nowrap}
.mark-crit{color:var(--crit)}
.mark-warn{color:var(--warn)}
.mark-team{color:var(--team-text)}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
/* inline entry editor: sits in the card's meta line, quiet until opened */
.edit-journal{display:inline}
.edit-journal>summary{cursor:pointer;display:inline;color:var(--team-text);
  font-weight:600;list-style:none}
.edit-journal>summary::-webkit-details-marker{display:none}
.edit-journal>summary::marker{content:""}
.edit-journal>summary::before{content:" · ";color:var(--muted)}
.edit-journal>summary:hover{text-decoration:underline}
/* open: indent under the entry it belongs to, so a long list stays legible */
.edit-journal[open]{display:block;margin:.5rem 0 .2rem;
  border-left:2px solid var(--line);padding-left:.8rem}
.edit-journal[open]>summary{display:block;margin-bottom:.3rem}
/* foldable note/plan cards: an AI note runs long and a coach may have
   several — the marker is the shrink control the owner asked for */
details.fold>summary{cursor:pointer;list-style:revert;margin:0}
details.fold>summary::-webkit-details-marker{display:revert}
details.fold>summary>strong{text-transform:capitalize}
details.fold>summary>.muted{margin-left:.4rem}
details.fold[open]>summary{margin-bottom:.5rem}
/* Event log: 200 rows on a phone. Tight, with the meta line visibly
   subordinate — the import log's one-line idiom, not a stack of cards. */
.logline{padding:.5rem .8rem;margin:.35rem 0;overflow-wrap:anywhere}
.logline-refused{border-left:3px solid var(--warn)}
.logmeta{font-size:.85rem}
.logday{font-weight:600;margin:1.1rem 0 .3rem}
form.inline{display:inline}
.table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
/* drag-and-drop CSV import */
.dropzone{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:.25rem;padding:2.6rem 1rem;border:2px dashed var(--line);border-radius:12px;
  background:var(--card);cursor:pointer;text-align:center;
  transition:border-color .15s,background .15s}
.dropzone:hover{border-color:var(--team-text)}
.dropzone.drag{border-color:var(--team-text);
  background:color-mix(in srgb, var(--team) 12%, var(--card))}
.dropzone.busy{opacity:.55;pointer-events:none}
.dropzone .dz-icon{font-size:1.9rem;line-height:1;color:var(--team-text)}
.dropzone .dz-main{font-family:var(--serif);font-size:1.15rem;font-weight:600}
.dropzone .dz-sub{color:var(--muted);font-size:1rem}
.dropzone .dz-file{margin-top:.4rem;font-weight:600;color:var(--team-text)}
.error{color:var(--crit)}
table{width:100%;border-collapse:collapse}
td,th{padding:.45rem .3rem;text-align:left;border-bottom:1px solid var(--line)}
th{font-size:.8rem;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);font-weight:600}
.muted{font-size:1rem}
.ok{font-size:1rem;color:var(--ok);font-weight:600}
.mono{font-family:ui-monospace,Menlo,monospace}
code{font-family:ui-monospace,Menlo,monospace;font-size:.92em;background:var(--tint);
  padding:.1rem .35rem;border-radius:4px;overflow-wrap:anywhere}
.badge{display:inline-block;padding:.12rem .55rem;border-radius:999px;font-size:.8rem;
  font-weight:600;color:#fff;margin-right:.4rem}
.badge-alert{background:var(--crit)}.badge-watch{background:var(--warn)}
.badge-info{background:var(--muted)}.badge-good{background:var(--good)}
/* dark theme lightens the semantic fills → white text fails; use dark ink instead */
[data-theme="dark"] .badge{color:#15171B}
@media (prefers-color-scheme:dark){[data-theme="auto"] .badge{color:#15171B}}
