/* PC SOX — STACKED layout (hamburger).
 *
 * Loaded as <link media="(max-width:1240px)">, so every rule in here is
 * unreachable above the break and a phone fix can no longer land on desktop.
 * The file has exactly three width sub-tiers — 1024 (tablet), 640 (phone) and
 * 520 (small phone) — replacing the old 960/900/860/760/700/640/620/560/520
 * spread, where an iPad Mini at 768px got the stacked header from the 1240
 * rule and the DESKTOP version of 25 rules from the 760 rule. No min-width
 * queries: the link's media attribute is the only lower bound this file has.
 * scripts/check-layout.mjs enforces both.
 */

/* ---------- the reserved header band ---------- */
/* The stacked header is TWO rows now, not three: brand+hamburger (62px + the
   .site-header hairline) and the fixed one-line Next Up row (2.75rem + its own
   border-top). The season row that used to be the third one is back in the
   brand row (see .na-season below) — it was 41px of decoration eating 6% of a
   phone viewport. These two numbers are the entire contract with tokens.css,
   site.js and chrome-boot.js; chrome-boot still overrides --chrome-h from the
   real measurement in pcsox-chrome-h. */
:root{--header-h:63px}
html.pcsox-has-nextup{--header-h:107px}

/* ---------- header: the hamburger stack ---------- */
/* This used to sit at 760px with three graduated squeeze tiers (1240/1040/860)
   shrinking the tab row to 11.5px type — a budget written for ten tabs while
   PAGES ships eleven. The row is now either full size or the hamburger. */
.nav{position:relative}
.nav-brand{flex:1;justify-content:flex-start;padding:12px 14px;border-right:none}
.nav-toggle{
  display:inline-flex;align-items:center;gap:8px;margin:0;padding:10px 14px;
  border:0;border-left:1px solid var(--hairline);background:transparent;color:var(--hdr-text,var(--text-2));
  font-family:var(--cond);font-weight:600;font-size:var(--t-base);letter-spacing:var(--tr-label);text-transform:uppercase;
  cursor:pointer;
}
.nav-toggle:hover,.nav-toggle[aria-expanded="true"]{color:var(--hdr-text-hi,var(--white))}
.nav-toggle-bars{
  display:block;width:18px;height:2px;background:currentColor;position:relative;
  box-shadow:0 -6px 0 currentColor,0 6px 0 currentColor;
}
.nav-alert{order:4;width:100%;border-top:1px solid var(--hairline)}
/* The panel is an OVERLAY, not a flow child of the bar.
   Measured (W9 mobile F2): as an in-flow sibling inside #app-header — which is
   position:sticky;top:0, so its in-flow box sits at the very top of the
   document — opening it grew document.scrollHeight 2452 -> 3111 and the bar
   63 -> 722. html.pcsox-lock froze scrollY through the open, then on close the
   document shrank 659px back and scroll anchoring "corrected" the reader to
   scrollY 949: 0.78 of a screen away from where they tapped MENU, with no
   explanation. Taken out of flow the panel contributes zero height, so docH
   and scrollY are both untouched by open and close.
   top/left/right resolve against the viewport OR against .site-header (its
   backdrop-filter makes it a containing block for fixed descendants) — those
   are the same coordinates here, because the sticky bar is pinned at y=0.
   Kept: its own scroll, measured from the bar above it (--chrome-h when JS
   has measured, --header-h before that), so 13 rows can never overrun the
   viewport and strand "Coaches" the way a sticky box's overflow did. */
.nav-links{
  display:flex;order:5;margin:0;flex-direction:column;flex-wrap:nowrap;
  /* A bare left:0;right:0 stretched this to the full viewport width at every
     stacked width up to 1240px — a sheet meant to hold one short word per row
     reading edge-to-edge on a laptop. Pinned to the right edge instead, with a
     cap, so it reads as a menu rather than a takeover; small phones (<=520px,
     below) still want the full width, since 400px there would run off-screen
     on the left with nothing to relate to. */
  position:fixed;left:auto;right:0;width:100%;max-width:400px;
  top:var(--chrome-h,var(--header-h));
  z-index:var(--z-chrome);
  max-height:calc(100vh - var(--chrome-h,var(--header-h)));
  max-height:calc(100dvh - var(--chrome-h,var(--header-h)));
  overflow-y:auto;overscroll-behavior:contain;
  border-top:1px solid var(--hairline);background:var(--hdr-menu,var(--surface-1));
  /* Batch 6 (UI review): the same card treatment as the desktop "More" menu
     (.nav-more-menu, desktop.css) — one radius/shadow pair for every
     menu-shaped surface instead of three separately tuned. Only above the
     520px tier: below it this is a full-bleed sheet, not a floating card,
     and the small-phone override further down puts the square corners and
     the heavier elevation back. */
  border-radius:var(--r-md);box-shadow:var(--elev-2);
  /* Closed state. visibility (not display) so both directions can animate;
     it still drops the rows out of the tab order and out of hit-testing.
     The visibility hop is delayed by the transition so the panel is still
     painted while it slides away. */
  visibility:hidden;opacity:0;transform:translateY(-8px);pointer-events:none;
  transition:opacity var(--dur-2) var(--ease-out),
    transform var(--dur-2) var(--ease-out),
    visibility 0s linear var(--dur-2);
}
.nav-links.is-open{
  visibility:visible;opacity:1;transform:none;pointer-events:auto;
  transition-delay:0s;
}
@media (prefers-reduced-motion:reduce){
  .nav-links{transition:visibility 0s}
}
/* An opaque bar over an opaque panel. At rgba(11,11,13,.92)+blur(8px) the
   footer's "Fall 2026" was legible THROUGH the brand row behind the logo with
   the menu open (mobile F4) — a translucent bar over a menu reads as a smudge,
   not as glass. Scoped to the open state so the scrolled-page blur survives. */
#app-header:has(.nav-links.is-open) .site-header{background:rgb(var(--hdr-rgb,11 11 13))}
/* 44px pitch (was 50.7), and one hairline BETWEEN rows rather than one under
   every row: 13 bottom borders drew a hairline hard against the panel's own
   bottom edge and made the menu read as a table. border-top + :first-child
   leaves exactly the 12 dividers there are gaps for. */
.nav-links a{
  display:flex;align-items:center;min-height:44px;padding:0 18px;
  font-size:var(--t-base);white-space:nowrap;
  /* site.css's row carries a 3px transparent bottom border as the desktop
     current-page underline. Left on, it made every stacked row 47px. */
  border-top:1px solid var(--hairline);border-bottom:0;
}
.nav-links > a:first-child{border-top:0}
.nav-links a[aria-current="page"]{background:var(--hdr-tint,var(--surface-active));color:var(--hdr-text-hi,var(--text-1))}
/* Touch has no hover, so the row needs a pressed state or the tap reads as
   nothing happening (mobile F5). */
.nav-links a:active{background:var(--hdr-tint,var(--surface-active))}
/* No nested disclosure inside the hamburger: the panel is already a stack,
   so the More links are simply more rows in it. site.js un-hides the menu
   below this width, and the button goes away with the dropdown it opened. */
.nav-more{display:none}
.nav-more-menu a{padding:0 18px;border-bottom:0}

/* ---------- header: Next Up + season ---------- */
/* Fixed one-line Next Up row — stacking 2–3 games used to grow/shrink the
   sticky bar after GC and make the hero jump under the header. */
.nav-alert{
  order:4;flex:1 1 100%;justify-content:flex-start;flex-wrap:nowrap;
  padding:0 14px;border-top:1px solid var(--hairline);
  height:2.75rem;min-height:2.75rem;max-height:2.75rem;overflow:hidden;
}
.nav-alert:empty{display:none}
/* Same-session navigations usually have Next Up — keep the second row's
   height while progressive chrome waits on /api/gc so the hero does not jump. */
/* (0,3,1) already outranks .nav-alert:empty's (0,2,0) — no !important. */
html.pcsox-has-nextup .nav-alert:empty,
html.pcsox-has-nextup .nav-alert.is-empty{
  display:flex;visibility:hidden;pointer-events:none;
}
.na-text{
  white-space:nowrap;text-align:left;font-size:var(--t-sm);line-height:1.3;
  overflow:hidden;text-overflow:ellipsis;
}
.na-rot{
  position:relative;flex:1;min-width:0;align-self:stretch;
  display:flex;align-items:center;
}
.na-rot > .na-text,.na-rot[data-n="3"] > .na-text{
  position:absolute;left:0;right:0;max-width:100%;
}
.na-game{flex:none;text-align:left;max-width:100%}
/* mobile F16: the Next Up band is 44px and the link inside it was 16.9px of
   that — .na-text is absolutely positioned inside .na-rot and only ever as
   tall as its own line box, so 27px of the row you are aiming at did nothing.
   line-height carries the text down the middle of the band without making the
   box a flex container, which is what would have cost the ellipsis this row
   depends on at 390px. */
.na-rot > .na-text,.nav-alert > .na-game{
  top:0;bottom:0;height:auto;line-height:2.75rem;
}
.nav-alert > .na-game{align-self:stretch}
a.na-text:active{color:var(--hdr-text-hi,var(--link,var(--red-text)))}
/* P5: the season chip rides the brand row instead of owning a third full-width
   row of its own. "FALL 2026" is decoration; 41px of a 664px viewport is not.
   The <i>Season</i> label goes with it — this is what the old max-width:1280
   rule did, minus the 40px band where it half-fired above the nav break. */
.na-season i{display:none}
/* Row one of the stacked bar, left to right: the brand (it fills the row), the
   season chip (tablet widths only — the phone tier below drops it), Coach login
   as a round icon, and Menu, which keeps the corner. The orders are spelled out
   because the DOM order is brand, Menu, alert, drawer, chip, Coach login; row
   two is the alert slot, and the drawer is out of the flow altogether.
   The budget the row is held to, narrowest case: brand 127 + chip ~94 + Coach
   login 52 + Menu 92 = 365px, inside the 641px this tier starts at; below 641
   the chip goes and there is room to spare. */
.nav-brand{order:0}
.na-season{order:1;flex:none;border-left:1px solid var(--hairline)}
.nav-coach{
  order:2;align-self:center;width:44px;height:44px;min-height:0;
  margin:0 var(--s-1);padding:0;
  border-radius:var(--r-full);
}
.nav-coach-icon{display:block}
.nav-coach-text{display:none}
.nav-toggle{order:3}
/* The Watch link in the 44px alert row is the row's own height and bleeds to
   its edge, set off by a hairline, instead of the pill it is on desktop — a
   30px pill was under the 40px floor every tap target here is held to. */
.na-watch{
  align-self:stretch;min-height:0;margin-right:-14px;padding:0 14px;
  border:0;border-left:1px solid var(--hairline);border-radius:0;
}

/* ---------- footer ---------- */
/* 1025-1240 still has room for the four columns; the tiers below collapse it. */
.foot-grid{grid-template-columns:1.5fr 1fr 1fr 1.2fr}

/* ---------- hero rungs ---------- */
/* Each hero exists at 800/1200/1600px next to its 2400px master; the master is
   285-745 KB and a 360px phone was downloading every byte of it to sit under a
   68-88% dark wash.
   Deliberately media queries and not image-set(): --hero-img feeds the
   `background` shorthand through var(), and a custom property holding an
   image-set() a browser does not understand is still a VALID custom property
   value — the failure lands later, on the background shorthand, which drops to
   nothing and leaves the hero blank. `resolution` picks the same rung
   image-set() would, and an old browser simply keeps the master.
   A coach-set header (--page-hero-image) is the first arm of the var chain, so
   it overrides all of these and is unaffected. */
@media (max-width:1024px),(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 hero's platform strip ---------- */
/* "Built by" and "Compatible with" share one line only where both fit: the
   seven badges alone are about 990px, so beside the other group and its rule
   the row wants 1140px, and a wrapped group beside a rule is a worse picture
   than two stacked ones. Up to 1240 the groups stack, the maker's line first,
   and the rule (a border on the second group) goes. The strip's measured
   heights, which the hero reserves by growing to hold them, are in
   docs/STATE-OF-PLAY.md. */
.affil-strip{flex-direction:column;gap:12px}
.affil-with{padding-left:0;border-left:0}
.affil-label{justify-content:center}

/* ================= TABLET — max-width:1024px ================= */
/* The old 960 / 900 / 860 numbers, which were three different single-purpose
   breakpoints for the same "the two-up grids stop fitting" moment. */
@media (max-width:1024px){
  .sp-terms-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .bx-swipe{display:block}
  .foot-grid{grid-template-columns:1fr 1fr}
  .foot-brand{grid-column:1/-1}
}

/* ================= PHONE — max-width:640px ================= */
/* Everything that used to be split across 760 and 640. 760 was the worst
   number in the file: an iPad Mini portrait is 768px, so it took the stacked
   header from the 1240 rule and the desktop version of all 25 of these rules.
   641-768 now reads as a tablet, which is what it is. */
@media (max-width:640px){
  .section{padding-block:var(--sec-sm)}
  .accolade .acc-line{font-size:var(--t-sm);letter-spacing:var(--tr-eyebrow);gap:12px}
  .accolade .acc-line i{width:44px}
  /* Below 640 the brand row has no room for it either — logo + hamburger +
     "FALL 2026" is three things in ~360px. The season is on the page. */
  .na-season{display:none}
  /* Rows of 44px tap targets, packed: with four calls in the hero the
     badges have to sit above the fold of a 390x664 phone. */
  .affil-strip{gap:6px;margin-top:10px}
  /* The strip grew two label lines and the maker's row (about 80px) when it
     became two groups, so the badges pull in to buy part of that back: from
     360 up the seven fit two rows instead of three, which is a row of 44px. The
     Rally mark stands a step taller than the tool logos because its own
     guidelines set a minimum size it cannot meet here (brand/README.md). */
  .affil-group{--affil-gap:10px}
  .affil-strip img{height:22px}
  .affil-strip img[alt="GameChanger"]{height:12px}
  .affil-strip img[alt="Rally"]{height:28px}
  /* 19.6x19px logos with no padding — eight of them across the hero.
     The 44px floor now comes from .affil-strip a's min-width/min-height in
     site.css, so the padding only has to keep the rows apart. */
  .affil-strip a{padding:2px 4px}
  /* 84+108 = 192px of padding inside a box that was already at its minimum,
     which is most of why .hero-full rendered 809.6px tall in a 737px slot
     (W9/mobile F1). padding-top still clears the 42px score ticker that is
     absolutely positioned over the top of the hero. */
  .hero-full{padding:50px 0 8px}
  .hero-content .tagline{font-size:var(--t-base);line-height:1.45;max-width:36ch;margin-top:10px}
  /* Four calls, two per row: the stacked column .btn-row uses elsewhere
     would put four slabs under the wordmark and push the platform badges
     below the fold. */
  .hero-content .btn-row{margin-top:14px;flex-direction:row;flex-wrap:wrap;justify-content:center;gap:8px}
  .hero-content .btn-row .btn{flex:1 1 calc(50% - 4px);min-height:44px;padding:0 10px;font-size:var(--t-sm)}
  .hero-content .accolade{margin-top:10px}
  /* The strip under the hero is a strip, not a second hero: the kicker is a
     desktop nicety and the two CTAs share the row. */
  .page-hero{
    min-height:clamp(180px,28vh,240px);
    padding:40px 0 36px;
  }
  .page-body,.sc-body,.ro-body,.ph-body,.soc-body,.jn-body,.sh-body,.og-body,.adm-body,.cal-body{padding-block:var(--s-6)}
  .sb{padding:16px 14px 14px}
  .sc-panel-head,.sc-grp-head,.sc-block{padding-left:16px;padding-right:16px}
  .sc-panel-head{padding-right:46px}
  .cal-next{padding:18px 16px 16px}
  /* The next-game countdown: four cells in one row, always. At a 78px
     minimum plus 12px gaps the four wrapped to three-and-one on a 390px
     phone, and 38px numerals made the card the tallest thing on the page.
     Four equal columns with no minimum, smaller numerals and tighter
     padding keep it a strip, not a billboard. */
  .cal-next .countdown{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;margin-top:12px}
  .cal-page .cd-cell{min-width:0;padding:10px 4px}
  .cal-page .cd-cell b{font-size:var(--t-2xl)}
  .cal-cell{min-height:72px;padding:5px}
  .cal-cell>b{width:22px;height:22px;font-size:var(--t-xs);margin-bottom:4px}
  /* One line per chip, always: a wrapped label made a two-event weekend
     three times taller than the rest of the month. The squad tag and the
     start of the label show; the ellipsis says "tap me" and the popup has
     the rest. 22px tall so the row count, not the title, sets the height. */
  .cal-ev{
    display:flex;flex-direction:column;gap:2px;
    font-size:10px;padding:3px 4px;min-height:22px;line-height:1.2;
    white-space:nowrap;overflow:hidden;
  }
  /* Squads on their own line so 12U, 13U, 10U and 8U on the same day both show: the
     tags drop their "U" (see calSquadHtml) and sit side by side in the squad
     colours; the time or event name is the single trimmed line under them.
     var(--t-2xs) (11px) rather than the .cal-ev label's own 10px: the harness
     warns under 11px, and the squad tag is a 1-2 digit number, not running
     text — one token step up costs a couple of px of width, not a wrapped
     row, and the ≤520px tier below already trims the tag's own padding to
     make room for "10" and "9" side by side. */
  .cal-ev .cal-sqs{display:flex;flex-wrap:wrap;gap:2px}
  .cal-ev .cal-sq{font-size:var(--t-2xs);font-weight:700;padding:0 3px;line-height:14px}
  .cal-ev .cal-sq i{display:none}
  .cal-ev .cal-lbl{display:block;overflow:hidden;text-overflow:ellipsis}
  .cal-more{font-size:10px;padding:3px 4px;min-height:22px}
  .cal-title{font-size:var(--t-lg)}
  .cal-head{padding:14px 12px}
  /* 48x39 prev/next and a 76x32 "Today" are the month's only controls. */
  .cal-nav{padding:8px 14px;min-height:44px}
  .cal-today{min-height:40px}
  .btn-row{flex-direction:column;align-items:stretch;gap:12px}
  .btn{justify-content:center}
  .empty{padding:30px 18px}
  .carousel{aspect-ratio:4/3}
  .thumb-grid{grid-template-columns:repeat(3,1fr);gap:6px}
  .frow{grid-template-columns:1fr}
  .ro-squad-head,.ro-squad-body{padding-left:16px;padding-right:16px}
  .gc-bar,.ro-gc-bar{padding:12px 14px}
  .roster-grid{grid-template-columns:repeat(2,1fr);gap:10px}
  .hl-grid{grid-template-columns:repeat(2,1fr);gap:10px}
  .sp-story-grid{grid-template-columns:1fr;gap:var(--s-4)}
  .sp-tiers{grid-template-columns:1fr;gap:var(--s-3)}
  /* The spacer only lines headings up across a row of cards; a phone has one column. */
  .sp-tier-badge-ghost{display:none}
  .sp-signup-panel.card{padding:var(--s-4)}
  .sponsor-grid{grid-template-columns:repeat(2,1fr)}
  .sp-profile{grid-template-columns:1fr;gap:var(--s-4)}
  /* The comparison table stops being a table on a phone: one card per feature,
     each level's value labelled with its own name (sponsor.js writes
     data-tier-name), so all four levels read without a sideways scroll. The
     header row stays in the accessibility tree — clipped, not display:none —
     so a screen reader still hears what each column is. */
  .sp-matrix{min-width:0}
  .sp-matrix > [role="rowgroup"]:first-child{
    position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;
  }
  .sp-matrix-row,.sp-matrix-row:nth-child(odd){
    grid-auto-flow:row;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s-2) var(--s-4);
    align-items:start;padding:var(--s-4);background:transparent;
  }
  .sp-matrix-row > div,.sp-matrix-row > div:first-child{border-left:0;padding:0;text-align:left}
  .sp-matrix-row > div[role="rowheader"]{
    grid-column:1/-1;color:var(--text-1);font-family:var(--cond);font-weight:600;
    font-size:var(--t-base);letter-spacing:var(--tr-label);text-transform:uppercase;
  }
  .sp-matrix-row > [role="cell"]::before{
    content:attr(data-tier-name);display:block;margin-bottom:2px;
    font-family:var(--cond);font-weight:600;font-size:var(--t-2xs);letter-spacing:var(--tr-label);
    text-transform:uppercase;color:var(--text-3);
  }
  /* 16-18px consent boxes on the two forms a parent must not get wrong. */
  .sp-check input[type="checkbox"],.check-row input,.fan-ok input{width:22px;height:22px;margin-top:1px}
  .sp-check,.check-row,.fan-ok{padding:5px 0}
  #sponsors.section{padding-bottom:28px}
  /* 797px of footer on a 2,452px home page was 32.5% of the document. The
     rows below carry the saving; these two trim the frame around them. */
  .site-footer{margin-top:40px;padding:24px 0 20px}
  .foot-grid{grid-template-columns:1fr 1fr;gap:14px 16px;text-align:left}
  /* The 44px link rows below already space themselves; the desktop 7px gap
     on top of them made a 13-link footer a thousand pixels tall. */
  .foot-col{gap:0}
  .foot-col b{margin-bottom:2px}
  /* Connect spans the width and lays its links two-up, so it does not sit
     under a three-link column and a five-link column as a third tall stack. */
  .foot-connect{grid-column:1/-1;display:grid;grid-template-columns:1fr 1fr;column-gap:16px}
  .foot-connect b{grid-column:1/-1}
  .foot-brand{grid-column:1/-1;text-align:center}
  .foot-brand.foot-col{align-items:center}
  .f-mark{align-self:center}
  .foot-legal{justify-content:center;text-align:center;margin-top:18px;padding-top:12px}
  /* The owner's complaint, verbatim: "rows of text are still double spaced in
     the footer". Measured at 390: pitch 44.0px for a 21.7px line box and 17px
     of ink — 2.03x the line, 2.59x the ink, exactly, on all 18 links. The old
     rule's padding:9px 0 came to 39.7px, so min-height:44px set the box.
     44 was taken from Apple's HIG figure for primary CONTROLS; the actual
     conformance bar for a link index is WCAG 2.5.8 AA = 24x24 CSS px, and the
     shipping norm for a dense 14px footer index is a 30-34px pitch.
     34px — the top of that shipping-norm range — is also the harness's own
     ceiling: scripts/ui-check.mjs's (t) footer-pitch scenario fails the build
     the moment top-to-top spacing passes 34px at 390 (that is how it caught
     the 44px regression above). Rows stack with .foot-col{gap:0} and no
     margin, so pitch tracks min-height exactly; a flat 40px "primary
     control" floor (a later accessibility pass's first ask, before this file
     was measured) would put every one of these 18 links at a 40px pitch and
     fail that scenario outright, or require
     overlapping the boxes with negative margins to fake a smaller pitch,
     which would just make neighbouring links mis-tap each other. 34px is the
     largest tap target this index can carry without reopening either bug.
     The TeamReach control sits in that same list as a <button class="link-like">
     (it opens a dialog), so a rule that only names <a> leaves exactly one
     un-sized target per page. */
  .foot-col a,.foot-col button.link-like{
    display:flex;align-items:center;padding:0;min-height:34px;
    font-size:var(--t-base);line-height:1.35;
  }
  /* .foot-legal is TWO <span>s (site.js renderChrome): a privacy sentence in
     plain type, then the Privacy / Terms row. The old rule hit both, so a
     44px-tall inline-block sat inside a 19.4px line box and overlapped the
     lines above and below it. Only the second span is a link row. */
  .foot-legal span:last-child a{display:inline-flex;align-items:center;min-height:34px}
  /* /shop: one column, the mark above a full-width button, product photos at
     their natural proportions in a slim plate beside the prices. */
  .sh-products{grid-template-columns:1fr}
  .sh-store{flex-direction:column;align-items:stretch}
  .sh-mark{align-self:flex-start;height:18px}
  .sh-photo{flex-basis:112px}
  .sh-order{grid-template-columns:1fr}
  .ps-hero{align-items:flex-start}
  .ps-photo{width:100%}
  .ro-stat-strip .cd-cell b{font-size:var(--t-lg)}

  /* ---------- the drawn lockup ----------
     A club with no wordmark of its own has its name SET rather than drawn as a
     picture (assets/site.css, .hero-lockup). The name itself rides --d-hero,
     which already bottoms out at 56px here; what has to come down is
     everything AROUND it, or the eyebrow and the age chip crowd a name that is
     already using the full gutter-to-gutter width of a 390px screen. The
     keylines thin for the same reason: a 2px stroke on 56px type closes the
     counters. Dormant on this club, whose hero is still its wordmark image. */
  .hero-lockup{gap:4px}
  .hero-lockup .lk-eyebrow{font-size:var(--t-sm)}
  .hero-lockup .lk-tag{font-size:var(--t-xs);padding:2px 10px}
  .hero-lockup[data-style="varsity"] .lk-word{-webkit-text-stroke-width:1px}
  .hero-lockup[data-style="brush"] .lk-word{-webkit-text-stroke-width:2px}
  .nav-brand .nav-word{font-size:var(--t-md)}
}

/* ================= SMALL PHONE — max-width:520px ================= */
/* The old 560 tier, plus the 520 hero rung it already shared a job with. */
@media (max-width:520px){
  /* Below the width the 400px cap above was sized for, the panel is the
     screen again — a 400px sheet on a 390px phone would only ever show
     partially, right-aligned against nothing. Square corners and the
     heavier shadow come back with it: a full-bleed sheet is not the
     floating card the panel above this width now reads as. */
  .nav-links{max-width:none;border-radius:0;box-shadow:var(--elev-3)}
  /* A 360px phone leaves ~34px inside a day cell; the chip's own padding
     and 3px accent bar ate the second squad tag. Trim both so "10 9" fits. */
  .cal-ev{padding:3px 2px;border-left-width:2px}
  .cal-ev .cal-sq{padding:0 2px}
  .cal-ev .cal-sqs{gap:1px}

  /* Two chips to a row on the narrowest phones; the 168px floor from site.css
     would otherwise force a 1-up column at 360. */
  .sc-schip{flex:1 1 46%;min-width:0}
  .sc-panel-head{gap:6px 16px}
  /* The record used to be pushed onto its own row here (flex-basis:100%),
     which is half of why the summary was 108px tall for "Overall 5-5-0". The
     title is content-sized now (h2.sc-panel-title, flex:0 0 auto), so both fit
     on one line at 360 with room to spare. */
  .sc-panel-recs{flex-basis:auto}
  .sp-terms-grid{grid-template-columns:1fr}
  .lv-slot{grid-template-columns:1fr;gap:6px}
  .lv-time{border-top:1px solid var(--hairline);padding-top:10px}
  .soc-hero{--hero-img:url("/assets/img/social-hero-1200.webp")}
  .sc-hero{--hero-img:url("/assets/img/scores-hero-1200.webp")}
  .cal-hero{--hero-img:url("/assets/img/calendar-hero-1200.webp")}
  .ro-hero{--hero-img:url("/assets/img/roster-hero-1200.webp")}
  .ph-hero{--hero-img:url("/assets/img/photos-hero-1200.webp")}
  .jn-hero{--hero-img:url("/assets/img/join-hero-1200.webp")}
  .og-hero{--hero-img:url("/assets/img/calendar-hero-1200.webp")}
  .sh-hero{--hero-img:url("/assets/img/shop-hero-1200.webp")}
  .sp-hero{--hero-img:url("/assets/img/sponsors-hero-1200.webp")}
  .fr-hero{--hero-img:url("/assets/img/join-hero-1200.webp")}
  .lv-hero{--hero-img:url("/assets/img/scores-hero-1200.webp")}
  .du-hero{--hero-img:url("/assets/img/roster-hero-1200.webp")}
}
/* A 1x phone: 800px covers a 520px slot with room to spare. */
@media (max-width:520px) and (max-resolution:1.5dppx){
  .soc-hero{--hero-img:url("/assets/img/social-hero-800.webp")}
  .sc-hero{--hero-img:url("/assets/img/scores-hero-800.webp")}
  .cal-hero{--hero-img:url("/assets/img/calendar-hero-800.webp")}
  .ro-hero{--hero-img:url("/assets/img/roster-hero-800.webp")}
  .ph-hero{--hero-img:url("/assets/img/photos-hero-800.webp")}
  .jn-hero{--hero-img:url("/assets/img/join-hero-800.webp")}
  .og-hero{--hero-img:url("/assets/img/calendar-hero-800.webp")}
  .sh-hero{--hero-img:url("/assets/img/shop-hero-800.webp")}
  .sp-hero{--hero-img:url("/assets/img/sponsors-hero-800.webp")}
  .fr-hero{--hero-img:url("/assets/img/join-hero-800.webp")}
  .lv-hero{--hero-img:url("/assets/img/scores-hero-800.webp")}
  .du-hero{--hero-img:url("/assets/img/roster-hero-800.webp")}
}

/* ---------- the coach bar (assets/coach-edit.js) ----------
   Bottom of the screen, inside the safe area: the top of a phone is the
   header's, and a strip up there would cover the page title on every page.
   It stays clear of the footer's links because it is fixed — the page behind
   it scrolls on past. */
.coach-bar{
  left:var(--s-3);right:var(--s-3);
  bottom:calc(var(--s-3) + env(safe-area-inset-bottom,0px));
}

/* ---------- the Undo toast (assets/coach-edit.js) ----------
   Directly above the coach bar, which owns the bottom of the phone. --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 56px guess
   would put the Undo button underneath it on exactly the saves that have a
   message. Both are fixed, so the page behind them scrolls on past. */
.cb-toast{
  left:var(--s-3);right:var(--s-3);
  bottom:calc(var(--s-3) + var(--cb-bar,56px) + var(--s-2) + env(safe-area-inset-bottom,0px));
}

/* The crest above the club's own wordmark — spec brand.hero "crest+lockup". */
@media (max-width:640px){.hero-content .hero-crest{max-height:110px;width:auto}}
