/* blox on a desktop — a different product from the phone, in one codebase.

   The phone decides and does; this plans, enters and analyses. So where the
   phone is one column of the few things that change your behaviour today, this
   is three panes of everything at once: what the week looks like, the session
   you are working on, and the reference you keep glancing at.

   "De desktop mag druk zijn, zolang elke pixel data is."

   Everything here is behind a width query. Below it the phone's bottom tab bar
   takes over and none of this exists — the two shells never overlap, so neither
   can quietly restyle the other. */

@media (min-width: 900px) and (min-height: 500px) {
  /* ── the window ──────────────────────────────────────────────────────────
     A title bar, a sidebar, the work area, and a reference column that only
     Overzicht fills. Depth is the three lightness steps and nothing else: no
     shadow inside the window, because a shadow inside a window is a lie about
     where the light is. */
  /* Two rows: the travel banner (only sometimes there, and an empty auto row is
     0px) and the window. Without a row of its own the banner was auto-placed
     AFTER the explicitly-placed shell, which put a read-only warning underneath
     the entire page. */
  body.has-shell {
    display: grid; grid-template-rows: auto 1fr; min-height: 100vh;
  }
  body.has-shell .travel-banner { grid-row: 1; }
  body.has-shell .topbar { display: none; }
  body.has-shell .app-footer { display: none; }

  /* ── the page bar ────────────────────────────────────────────────────────
     56px, to the RIGHT of the sidebar and inside the work area, because the
     sidebar is the window's left edge and this is its top. Title, the context
     that qualifies it, then the range control and one primary action. */
  .page-bar {
    flex: none; display: flex; align-items: center; gap: 16px;
    height: 56px; padding: 0 22px; margin: -20px -22px 0;
    border-bottom: 1px solid var(--border);
  }
  .pb-title {
    margin: 0; flex: none;
    font-size: 17px; font-weight: 700; letter-spacing: -0.35px; color: var(--text);
  }
  /* A month name is a label in running text and a Title here. ::first-letter,
     not text-transform: capitalize, which would give "September 2026" its
     capital and "Dit Seizoen" three of them. */
  .pb-title::first-letter { text-transform: uppercase; }
  .pb-sub {
    margin: 0; min-width: 0; font-size: 12.5px; color: var(--text-2);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .pb-spacer { flex: 1; }
  /* The range control: one segmented switch per screen, and the screen decides
     what it switches between (6/12 weeks, week/month/year, this season/all). */
  .pb-scale { display: inline-flex; gap: 2px; padding: 2px; border-radius: 7px; background: var(--surface); }
  .pb-scale a, .pb-scale span {
    padding: 5px 12px; border-radius: 5px; font-size: 12px; font-weight: 500;
    color: var(--text-2); text-decoration: none;
  }
  .pb-scale .is-active { background: var(--surface-2); color: var(--text); font-weight: 600; }
  .pb-action {
    flex: none; padding: 7px 14px; border-radius: 7px;
    background: var(--accent); color: var(--accent-ink);
    font-size: 12.5px; font-weight: 600; text-decoration: none;
  }
  .pb-action:hover { filter: brightness(1.06); }
  /* ── Nieuw ──────────────────────────────────────────────────────────────
     Eén knop, vijf dingen die je kunt plannen (sessie · notitie · wedstrijd ·
     reis · programma). Hij ziet eruit als de oude
     actieknop (dat IS de daad van dit scherm), maar hij vouwt een lijstje uit
     in plaats van naar een ander scherm te springen. */
  .pb-newwrap { flex: none; position: relative; }
  .pb-new {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 7px 12px 7px 14px; border: none; border-radius: 7px;
    background: var(--accent); color: var(--accent-ink);
    font-family: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer;
  }
  .pb-new svg { width: 13px; height: 13px; }
  .pb-new:hover { filter: brightness(1.06); }
  .new-menu {
    position: absolute; top: calc(100% + 6px); right: 0; z-index: 60; min-width: 248px;
    display: flex; flex-direction: column; gap: 2px; padding: 6px;
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.14);
  }
  .new-menu[hidden] { display: none; }
  .new-item {
    display: flex; flex-direction: column; gap: 1px; width: 100%; box-sizing: border-box;
    padding: 8px 10px; border: none; border-radius: var(--r-md); background: none;
    font-family: inherit; text-align: left; cursor: pointer; text-decoration: none;
  }
  .new-item:hover { background: var(--surface-hover); }
  .new-label { font-size: 13px; font-weight: 600; color: var(--text); }
  .new-hint { font-size: 11.5px; color: var(--text-3); }
  /* De weekpager, naast de titel. Twee pijlen en een weg terug naar nu. */
  .pb-pager { flex: none; display: inline-flex; gap: 2px; }
  .pb-pager a {
    width: 26px; height: 26px; display: inline-flex; align-items: center;
    justify-content: center; border-radius: 6px; background: var(--surface);
    color: var(--text-2); text-decoration: none; font-size: 15px; line-height: 1;
  }
  .pb-pager a svg { width: 15px; height: 15px; }
  .pb-pager a:hover { background: var(--surface-2); color: var(--text); }
  /* Een kant die er niet is — het nieuwste seizoen heeft geen volgende. Hij
     blijft staan zodat de balk op elk scherm dezelfde vorm houdt; gedimd, en
     zonder hover, want er valt niets te klikken. */
  .pb-pager .is-off {
    width: 26px; height: 26px; display: inline-flex; align-items: center;
    justify-content: center; border-radius: 6px; background: var(--surface);
    color: var(--text-2); opacity: .35;
  }
  .pb-pager .is-off svg { width: 15px; height: 15px; }
  /* De datumkiezer: het native datumveld ligt onzichtbaar over het icoon, zodat
     de kalender van de browser aan deze knop hangt. Zelfde maat als een pijl. */
  .pb-goto {
    flex: none; position: relative; width: 26px; height: 26px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 6px; background: var(--surface); color: var(--text-2); cursor: pointer;
  }
  .pb-goto:hover { background: var(--surface-2); color: var(--text); }
  .pb-goto input {
    position: absolute; inset: 0; width: 100%; height: 100%;
    margin: 0; padding: 0; border: 0; opacity: 0; cursor: pointer;
  }
  .pb-today {
    flex: none; padding: 5px 11px; border-radius: 6px; background: var(--surface);
    color: var(--text-2); text-decoration: none; font-size: 12.5px; font-weight: 500;
  }
  .pb-today:hover { background: var(--surface-2); color: var(--text); }
  /* Een tweede soort actie: een weg, geen daad. Zelfde plek, geen vlak — een
     koraalknop belooft dat er iets GEBEURT als je hem indrukt. */
  .pb-link {
    flex: none; padding: 7px 2px; font-size: 12.5px; font-weight: 600;
    color: var(--accent-text); text-decoration: none; white-space: nowrap;
  }
  /* Op het jaarplan zelf is het geen weg maar waar je staat. */
  .pb-link.is-active { color: var(--text); }

  /* Gescoped op has-shell: de <div class="app-shell"> staat er altijd, maar de
     zijbalk erin alleen als de gebruiker een gekoppelde atleet heeft. Ongescoped
     kreeg een admin zonder atleet zijn hele pagina in de zijbalk-kolom. */
  body.has-shell .app-shell {
    grid-row: 2;
    /* ÉÉN getal voor de zijbalk, want er hangen er drie rasters aan plus het
       profielmenu dat erin opent. Hij was 196px, en dat was te smal voor twee
       dingen tegelijk: de rolregel (`beheerder · atleet · coach`) brak naar een
       tweede regel, en het profielmenu had een ondergrens van 200px — breder dan
       de 176px die er binnen de padding overbleef. Een zijbalk met
       `overflow-y: auto` krijgt van de CSS automatisch `overflow-x: auto`, dus
       die 24px overschot werd een horizontale scrollbar zodra je het menu opende. */
    --sb-w: 228px;
    display: grid; grid-template-columns: var(--sb-w) minmax(0, 1fr);
    min-height: 0;
  }
  /* The reference column is Overzicht's alone; every other screen takes the
     width instead and puts its own reference in cards. */
  body.has-shell .app-shell.has-ref { grid-template-columns: var(--sb-w) minmax(700px, 1fr) 334px; }

  /* ── sidebar ─────────────────────────────────────────────────────────────
     Vier gelabelde groepen — Training · Instellingen · Trainer · Beheer — elk
     inklapbaar; welke er staan en welke open is komt uit
     blox.frameworks.web.sidebar. No icons: twenty icons you rarely point at are
     twenty riddles, and a word is faster. */
  .sidebar {
    background: var(--surface); border-right: 1px solid var(--border);
    padding: 14px 10px; overflow-y: auto;
    display: flex; flex-direction: column; gap: 12px;
  }
  .sb-brand { display: flex; align-items: center; gap: 11px; padding: 2px 6px 16px; }
  .sb-brand svg { width: 26px; height: 21px; shape-rendering: crispEdges; }
  /* Wordmark over version, in a 26px column so the lockup is exactly as tall as
     the mark beside it. */
  .sb-lockup { display: flex; flex-direction: column; justify-content: center; height: 26px; }
  .sb-word {
    font-size: 18px; font-weight: 700; letter-spacing: -0.5px; line-height: 1.02;
    color: var(--text);
  }
  .sb-version {
    font-size: 9.5px; font-weight: 600; line-height: 1; color: var(--text-3);
    font-variant-numeric: tabular-nums;
  }
  /* Elke groep is een <details>: de kop klapt hem in en uit, zonder JS. De
     flexkolom zit op de <nav> erin — `display: flex` op een <details> zelf
     tekent Safari niet. */
  .sb-group { display: block; }
  .sb-items { display: flex; flex-direction: column; gap: 2px; padding-top: 3px; }
  .sb-label {
    display: flex; align-items: center; justify-content: space-between;
    height: 22px; padding: 0 8px; border-radius: 6px;
    list-style: none; cursor: pointer; user-select: none;
    font-size: 10px; font-weight: 700; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--text-3);
  }
  /* Safari tekent zijn eigen driehoekje zonder deze regel. */
  .sb-label::-webkit-details-marker { display: none; }
  .sb-label:hover { color: var(--text-2); }
  .sb-label:focus-visible { outline: 2px solid var(--accent-text); outline-offset: 1px; }
  /* Wijst naar rechts als de groep dicht is en naar beneden als hij open is:
     de richting ZEGT de stand, er is geen tweede teken nodig. */
  .sb-caret { width: 14px; height: 14px; flex-shrink: 0; transition: transform .15s ease; }
  .sb-group[open] > .sb-label .sb-caret { transform: rotate(90deg); }
  @media (prefers-reduced-motion: reduce) { .sb-caret { transition: none; } }
  .sb-item {
    position: relative; display: block;
    height: 33px; line-height: 33px; padding: 0 10px; border-radius: 7px;
    font-size: 13px; font-weight: 500; color: var(--text-2); text-decoration: none;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .sb-item:hover { background: var(--surface-2); color: var(--text); }
  .sb-item.is-active { background: var(--surface-2); color: var(--text); font-weight: 600; }
  /* The 3px bar is the state; the weight change alone reads as a hover. */
  .sb-item.is-active::before {
    content: ""; position: absolute; left: 0; top: 7px; bottom: 7px;
    width: 3px; border-radius: 0 2px 2px 0; background: var(--accent);
  }
  /* A screen that is designed but not built yet says so rather than 404ing. */
  .sb-item.is-todo { color: var(--ink-decor); cursor: default; }
  .sb-item.is-todo:hover { background: none; color: var(--ink-decor); }


  /* The account control: the athlete row IS the button, and the menu opens
     UPWARD out of it, because the sidebar's bottom is where it lives. */
  .sb-account { margin-top: auto; position: relative; }
  .sb-athlete {
    width: 100%; display: flex; align-items: center; gap: 9px; text-align: left;
    padding: 8px 6px; border: 0; border-top: 1px solid var(--border);
    border-radius: 0 0 7px 7px; background: none; cursor: pointer; font: inherit;
  }
  .sb-athlete:hover { background: var(--surface-2); }
  .sb-chev { width: 14px; height: 14px; margin-left: auto; color: var(--text-3); flex-shrink: 0; }
  .sb-athlete[aria-expanded="true"] .sb-chev { transform: rotate(180deg); }
  .sb-account .account-menu {
    top: auto; bottom: calc(100% + 6px); right: auto; left: 0;
    /* Precies de zijbalk breed — geen ondergrens meer. Een `max(200px, 100%)`
       kan de container overschrijden zodra de zijbalk smaller is dan die 200,
       en dat is precies wat er gebeurde. Nu is de zijbalkbreedte de enige knop. */
    min-width: 0; width: 100%;
  }
  .sb-avatar {
    width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    background: linear-gradient(135deg, var(--accent-from), var(--accent-to));
    color: var(--accent-ink); font-size: 12px; font-weight: 700;
  }
  .sb-who { min-width: 0; display: flex; flex-direction: column; }
  /* Allebei op één regel. De zijbalk is breed genoeg voor de drie rollen voluit;
     het afkappen is de bodem waar niets doorheen zakt, niet het ontwerp — een
     rolregel die naar twee regels brak duwde de accountknop uit zijn ritme. */
  .sb-name, .sb-role { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .sb-name { font-size: 13px; font-weight: 600; color: var(--text); }
  .sb-role { font-size: 11px; color: var(--text-3); }

  /* ── the panes ───────────────────────────────────────────────────────────
     Denser than the phone throughout: a mouse is more precise than a thumb. */
  .workarea { background: var(--bg); padding: 20px 22px; min-width: 0; overflow-y: auto; }
  .refcol {
    background: var(--surface); border-left: 1px solid var(--border);
    padding: 18px 16px; overflow-y: auto;
    display: flex; flex-direction: column; gap: 16px;
  }
  /* Below 1360 the reference column is the first thing to go — the work area
     keeps its 700px floor, and the reference is the least urgent of the three. */
  @media (max-width: 1359px) {
    body.has-shell .app-shell.has-ref { grid-template-columns: var(--sb-w) minmax(0, 1fr); }
    .refcol { display: none; }
  }

  /* The phone's screens still render here (a mobile route opened on a laptop);
     they simply stop growing rather than rearranging. */
  .workarea .m-screen { padding-left: 0; padding-right: 0; }

  /* The year plan is a TABLE on a desktop, not a reading column, so it takes the
     work area's width like every other screen in this shell. It has to: its eight
     columns need 660px of fixed track, and inside the 720px reading cap that left
     28px for the goal — one character per line. --screen-max is the right cap for
     a phone and the wrong one for a table. */
  .workarea .yp-page { max-width: none; padding-left: 0; padding-right: 0; }
  /* De kop van de telefoon (titel, seizoenskiezer, Deze week) is hier dubbel:
     de paginabalk erboven draagt het seizoen in de titel, ‹ › en de datumkiezer
     om te wisselen, en Vandaag. Twee koppen boven één scherm is er één te veel. */
  .workarea .yp-head { display: none; }
}

/* Below the shell's width the phone's own navigation is the navigation. */
@media (max-width: 899px), (max-height: 499px) {
  .sidebar, .refcol { display: none; }
  /* The phone's screens carry their own header; this bar is the desktop's. */
  .page-bar { display: none; }
}

/* Kopiëren en plakken op de maandkalender.
   Het klembord staat in de querystring, dus deze knoppen zijn gewone links en
   formulieren — geen JS, en je ziet in de adresbalk wat je vast hebt. */
.ag-clipbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px; border-radius: var(--r-md); background: var(--surface-2);
}
/* Op de grijze strook is de grijze knop onzichtbaar; hij neemt hier de kaartkleur. */
.ag-clipbar .card-btn { background: var(--surface); }
.ag-clipbar .card-btn:hover { background: var(--surface-hover); }
.ag-clipnow { font-size: 12.5px; color: var(--text-2); }
.ag-clipnow strong { color: var(--text); font-weight: 600; }
.ag-paste {
  background: var(--accent-soft); color: var(--accent-text);
  border: 1px solid transparent; border-radius: var(--r-md);
  font-family: inherit; font-size: 12.5px; font-weight: 600;
  padding: 5px 12px; cursor: pointer;
}
.ag-paste:hover { border-color: var(--accent-text); }
/* In de week staat het klembord boven de dagen, niet onder een gekozen dag. */
.cal-clipbar { margin-bottom: 16px; }

/* Het rechtsklikmenu van de agenda (calendar_context.js). Hetzelfde vlak als het
   Nieuw-menu — een zwevend menu, dus de enige plek met de zware schaduw — maar
   dichter: dit zijn opdrachten, geen keuzes met uitleg eronder. Alleen de
   desktop opent het, dus er is geen telefoonvariant. */
.ctx-menu {
  position: fixed; z-index: 90; min-width: 196px; max-width: 300px;
  display: flex; flex-direction: column; padding: 5px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.14);
  font-family: var(--sans);
}
.ctx-menu:focus { outline: none; }
.ctx-item {
  display: flex; align-items: center; gap: 8px; width: 100%; box-sizing: border-box;
  height: 28px; padding: 0 10px; border: 0; border-radius: var(--r-sm);
  background: none; color: var(--text); font: inherit; font-size: 13px; text-align: left;
  cursor: default;
}
.ctx-item:focus { outline: none; }
.ctx-item.is-active, .ctx-item[aria-expanded="true"] { background: var(--surface-hover); }
.ctx-item.is-danger { color: var(--danger); }
.ctx-item[aria-disabled="true"] { color: var(--text-3); }
.ctx-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ctx-chev { flex: none; color: var(--text-3); }
.ctx-sep { height: 1px; margin: 5px 8px; background: var(--border); }
