/* PC SOX — DESKTOP layout.
 *
 * Loaded as <link media="(min-width:1241px)">, so nothing in here can reach a
 * stacked viewport no matter what it selects. That is the point: the nav row,
 * the More dropdown card and the four-column footer used to sit in the shared
 * cascade and be un-styled again by a max-width block 60 lines later, which is
 * how a phone fix kept landing on desktop and vice versa. The "undo" rules do
 * not exist any more — the base simply is not there below 1241px.
 *
 * The only @media allowed in this file is (min-width:1440px) for a wide tier,
 * plus the feature queries (hover/pointer/resolution/print) that modify rules
 * living here. scripts/check-layout.mjs enforces that.
 */

/* ---------- header: the full-size link row ---------- */
.nav-links{display:flex;flex-wrap:wrap;align-items:stretch;margin-left:auto}
.nav-toggle{display:none}
/* "More" disclosure, as a real dropdown card. Below the break this is not a
   disclosure at all — the panel is already a stack, so the More links are
   simply more rows in it — which is why none of this belongs in the shared
   sheet. */
.nav-more-wrap{position:relative;display:flex;align-items:stretch}
/* A DETACHED card, not the bar extruding downward.
   Measured before (W9 desktop F1, identical at 1280/1440/1920): 196 x 302px —
   28% of a 1080px viewport — six 50px rows for one-word labels, `top:100%`
   with `border-top:0` and the bar's own #0b0b0d ground, so the gap between
   trigger and card was 0px and the 0 18px 40px shadow was invisible at the
   only edge that mattered. Nothing about it read as a layer.
   A gap, a radius, a lighter ground and the shared elevation ring are what
   make it a layer; --elev-2 carries its own hairline, so no border is needed
   and the card stops being another outline box. */
.nav-more-menu{
  position:absolute;top:calc(100% + 8px);right:-12px;z-index:var(--z-header);min-width:220px;
  display:flex;flex-direction:column;padding:5px;
  /* Opaque on purpose: at .98 the score ticker's text still ghosted through
     the LIVE row, because the header's backdrop-filter composites the card
     against the blurred ticker rather than the page. */
  background:var(--hdr-menu,var(--surface-1));border-radius:var(--r-md);
  box-shadow:var(--elev-2);isolation:isolate;
  /* Motion. `hidden` is a binary — nothing can transition it — so site.js
     drops `hidden` first and adds .is-open on the next frame, and on close
     removes .is-open and re-hides on transitionend. `hidden` stays the
     a11y truth; the class is only what moves. */
  opacity:0;transform:translateY(-6px) scale(.98);transform-origin:100% 0;
  /* `hidden` lands ~180ms after the class comes off, so for those frames the
     card is on its way out but still hit-testable over the page under it. */
  pointer-events:none;
  transition:opacity var(--dur-1) var(--ease-out),transform var(--dur-2) var(--ease-out);
}
.nav-more-menu.is-open{opacity:1;transform:none;pointer-events:auto}
@media (prefers-reduced-motion:reduce){.nav-more-menu{transition:none}}
/* ~34px rows instead of 50, and the divider-per-row goes: the highlight is an
   inset pill (the card has 5px of padding for it), which is the menu idiom.
   Hover was colour-only, so the cursor moved over six rows and the page did
   not respond to it at all.
   line-height is declared rather than inherited so the row height is
   arithmetic (17.6 + 16 = 33.6px) instead of a function of whichever face has
   loaded — the card is 302px -> ~217px, and it stays there through the font
   swap rather than settling into its final size a second after it opened. */
/* The menu rows shout like the bar rows — they are the same kind of nav label,
   so a row that changed case on its way into the card would read as a
   different kind of thing. */
.nav-more-menu a{
  padding:8px 14px;font-size:var(--t-sm);line-height:1.3;letter-spacing:var(--tr-label);
  text-transform:uppercase;color:var(--hdr-text,var(--text-2));
  /* These <a>s are descendants of .nav-links, which now floors a BAR row at
     62px so --header-h:63px is arithmetic rather than a back-calculation. A
     menu row is not a bar row: left on, it took the card to 387px. */
  min-height:0;
  border-bottom:0;border-radius:var(--r-sm);
}
@media (hover:hover){
  .nav-more-menu a:hover{background:var(--hdr-tint,var(--surface-hover));color:var(--hdr-text-hi,var(--text-1))}
}
.nav-more-menu a:active{background:var(--hdr-tint,var(--surface-active))}
.nav-more[aria-expanded="true"]{background:var(--hdr-tint,var(--surface-hover))}

/* ---------- header: what the Next Up line has to share the row with -------- */
/* desktop F22: at 1280 the bar carries brand (131px) + the NEXT UP tag + the
   game line + seven nav links + More + a SEASON FALL 2026 block — eleven
   elements in 1265px — and the one that gets ellipsised by
   `.na-text{text-overflow:ellipsis}` is the single most time-sensitive fact on
   the site: "10U vs Georgia Sticks 10U — Sun, …". The season is decoration, it
   is repeated in every hero eyebrow, and mobile.css already demotes it to a
   chip for the same reason. Below the wide tier it gives its ~130px back to
   the game line; at 1440+ there is room for both. */
.na-season{display:none}
@media (min-width:1440px){
  .na-season{display:flex}
}
/* The bar's budget, in the order it gives things up as it gets busy or narrow:
   the season chip is decoration and goes first (its "Season" word, then the whole
   chip while an alert is up), the links take back some side padding, and the Next
   up / live alert slot (flex:1, the only elastic part) keeps what is left, its
   words wrapping onto a second line before they lose their end. Nothing in the
   row is ever clipped or drawn over its neighbour.
   Fixed parts, measured: the brand 132px, seven links and More 642px (13px of
   padding either side of each), Coach login ~130px, the chip ~148px (~100px
   without its word). Tournament mode adds an eighth link (~113px). That leaves
   the alert slot ~320px at 1241px with no tournament, and with the Tournament
   link the row would leave it ~210px — too little for a LIVE line (its tag, score
   and Watch alone are ~165px) — so while the link is there every link gives back
   side padding: 13px becomes 6px at 1241px and 10px from 1341px up, in a straight
   line between (nine items, so ~126px back at 1241px and ~54px from 1341px).
   Measured with the Tournament link and a LIVE line, the slot is 317px at 1241
   and 345px from 1341. The chip drops its "Season" word while the link is there;
   below 1440px it is not drawn at all (above); and from 1440px up it is not drawn
   while an alert is up either (the slot carries data-ga): a season is free text up
   to 40 characters for a generated club, "Spring Classic 2027" alone left the LIVE
   line's words 67px at 1440, and a longer one squeezed them to nothing and drew
   the score over Watch. The season is repeated in every hero's eyebrow; the alert
   is the one thing in this row that is only true for a few hours.
   The padding is arithmetic on the viewport rather than a media query because
   desktop.css has exactly one width it may name (1440), and a step would only
   move the cliff. (:has() on the link and on the slot keeps this in step with the
   markup, including the cached header chrome-boot.js replays.) */
.nav-links:has(> a[href="/live"]) > a,
.nav-links:has(> a[href="/live"]) .nav-more{padding-inline:clamp(6px,calc(6px + (100vw - 1241px) * .04),10px)}
.nav:has(.nav-links > a[href="/live"]) .na-season i{display:none}
.nav:has(.nav-alert[data-ga]) .na-season{display:none}

/* ---------- footer ---------- */
/* Four columns is a desktop measure. mobile.css keeps them at 1025-1240 and
   collapses to two at its own tiers. */
.foot-grid{grid-template-columns:1.5fr 1fr 1fr 1.2fr}

/* ---------- roster cards: hover choreography ---------- */
/* Still gated on a fine pointer: a >=1241px viewport can still be a
   touchscreen, and :hover sticks there after a tap. */
@media (hover:hover) and (pointer:fine){
  .player-card:hover{
    border-color:rgb(var(--red-rgb) / .55);
    transform:translateY(-5px);
    box-shadow:0 18px 36px rgba(0,0,0,.45), 0 0 0 1px rgb(var(--red-rgb) / .12);
  }
  .player-card:hover::before{transform:scaleX(1)}
  .player-card:hover .pc-photo > img,
  .player-card:hover .pc-photo .pc-ph{transform:scale(1.1)}
  .player-card:hover .pc-photo::after{
    opacity:1;
    background:
      linear-gradient(180deg,rgb(var(--red-rgb) / .16) 0%,transparent 38%,rgba(0,0,0,.7) 100%),
      linear-gradient(135deg,rgb(var(--red-rgb) / .2),transparent 50%);
  }
  .player-card:hover .pc-ph img{opacity:.7;transform:scale(1.06)}
  .player-card:hover .pc-num{
    transform:skewX(var(--skew)) scale(1.1) translate(-1px,-2px);
    box-shadow:0 10px 22px rgb(var(--red-rgb) / .45);
  }
  .player-card:hover .pc-meta{transform:translateY(-2px)}
  /* `.player-card:hover b{letter-spacing:.06em}` used to live here. Tracking is
     not in the transitionable set (colour, background, border, opacity,
     transform, shadow — nothing else): it re-lays out the name on every
     pointer-enter, so a card the mouse crosses reflows text under the cursor. */
  .player-card:hover .pc-squad{color:var(--text-2)}
  /* Active cards are <a class="player-card"> links, so this IS the focused
     element. The 1px red-tinted border it used to substitute for the ring
     blends to ~#730E1F over --ink: 1.7:1, i.e. no visible focus at all. */
  .player-card:focus-within{
    border-color:rgb(var(--red-rgb) / .55);
    outline:2px solid var(--white);outline-offset:2px;
  }
}
@media (hover:hover) and (pointer:fine){
  .roster-inactive .player-card:hover{
    transform:none;box-shadow:none;border-color:var(--hairline);
  }
  .roster-inactive .player-card:hover::before{transform:scaleX(0)}
  .roster-inactive .player-card:hover .pc-photo > img,
  .roster-inactive .player-card:hover .pc-photo .pc-ph{transform:none}
  .roster-inactive .player-card:hover .pc-num{
    transform:skewX(var(--skew));box-shadow:0 6px 16px rgba(0,0,0,.35);
  }
}

/* ---------- hero rungs ---------- */
/* The 1600px rung, for the arm of the old two-arm query that lived above the
   break: (min-width:1101px) and (max-resolution:1.5dppx). A 2x desktop keeps
   the 2400px master. See mobile.css for the full explanation of why these are
   media queries and not image-set(). */
@media (max-resolution:1.5dppx){
  .soc-hero{--hero-img:url("/assets/img/social-hero-1600.webp")}
  .sc-hero{--hero-img:url("/assets/img/scores-hero-1600.webp")}
  .cal-hero{--hero-img:url("/assets/img/calendar-hero-1600.webp")}
  .ro-hero{--hero-img:url("/assets/img/roster-hero-1600.webp")}
  .ph-hero{--hero-img:url("/assets/img/photos-hero-1600.webp")}
  .jn-hero{--hero-img:url("/assets/img/join-hero-1600.webp")}
  .og-hero{--hero-img:url("/assets/img/calendar-hero-1600.webp")}
  .sh-hero{--hero-img:url("/assets/img/shop-hero-1600.webp")}
  .sp-hero{--hero-img:url("/assets/img/sponsors-hero-1600.webp")}
  .fr-hero{--hero-img:url("/assets/img/join-hero-1600.webp")}
  .lv-hero{--hero-img:url("/assets/img/scores-hero-1600.webp")}
  .du-hero{--hero-img:url("/assets/img/roster-hero-1600.webp")}
}

/* ---------- the schedule page's next-game card ----------
   Its own floor, for the reason .ro-board / .mcal / #sc-panels have one in
   assets/site.css: the countdown cannot be drawn until the schedule sources
   answer, and those reads only start once site.js has parsed — always after
   the load event. At this width the card is above the fold with the toolbar
   and the whole month grid beneath it, so a card that arrives late took 309px
   of page with it (desktop CLS 0.086). Reserved here and not in mobile.css
   because below the break the card is under the fold and reserving it would
   only buy a tall blank box on a phone. Centred, so the "nothing yet" line
   sits in the box rather than at the top of it. */
.cal-next{
  min-height:280px;
  display:flex;flex-direction:column;justify-content:center;
}

/* ---------- the coach bar (assets/coach-edit.js) ----------
   Top-right, under the sticky header rather than over it: --chrome-h is the
   measured bar height site.js publishes, the token is the reserve for before
   it does. A desktop reader's eye starts top-left, so the corner is where
   this belongs — and clear of the page's own controls, which the gear's rule
   below is for. */
.coach-bar{
  top:calc(var(--chrome-h,var(--header-h)) + var(--s-3));
  right:var(--s-5);
}

/* ---------- the gear on a page header (assets/coach-edit.js) ----------
   site.css draws it in the band's top-right corner, and at this width that is
   the bar's corner: the bar sat exactly on it, so the gear was on the page and
   a press landed on the bar (a coach could not open the dues settings from
   /dues, 2026-10-07; the harness never saw it because a DOM click() sails
   through whatever is on top). The band's bottom-right corner is photograph and
   nothing else at this width, so the gear is drawn there. Below the break the
   bar is at the bottom of the screen and the gear keeps the top-right corner. */
.page-hero>.cg-gear{
  top:auto;
  bottom:var(--s-3);
}

/* ---------- the Undo toast (assets/coach-edit.js) ----------
   Under the bar in the same corner: the bar is where this coach's attention
   already is, and the toast is the answer to what they just pressed there.
   --cb-bar is the bar's measured height, written onto the toast when it
   mounts — the strip grows a row when it has something to say, and a fixed
   guess would drop the Undo button on top of the message. */
.cb-toast{
  top:calc(var(--chrome-h,var(--header-h)) + var(--s-3) + var(--cb-bar,56px) + var(--s-2));
  right:var(--s-5);
}
