/* ==========================================================================
   Layout that belongs to a page rather than to a block.

   sbi.css is extracted from the prototype unchanged and is not hand-edited,
   so the few rules that exist only because a prototype *page* was split into
   separate builder blocks live here instead.

   Loaded after sbi.css by config('page-builder.public_css').
   ========================================================================== */

/*
   The rankings run — the rail, the board and the standings table.

   The prototype drew all three inside one <section class="section-tight rk-sec">,
   with a 28px .tp-gap between the rail and the board. As builder blocks they
   are three sections, each bringing its own section padding, which pushed them
   roughly 170px apart instead of 28px.

   These rules give the run back the prototype's rhythm: the first block opens
   the section, the ones after it sit a gap apart, and the last one closes it.
   Written on the run itself rather than on named blocks, so an editor can
   reorder, add or remove one and the spacing still comes out right.
*/
.rk-run { padding-block: clamp(24px, 3vw, 40px) 0; }
.rk-run + .rk-run { padding-top: 28px; }
.rk-run:not(:has(+ .rk-run)) { padding-bottom: clamp(48px, 6vw, 80px); }

/* :has() is recent enough to want a floor under it — without it every block in
   the run simply keeps its own opening padding, which is loose but not broken. */
@supports not selector(:has(*)) {
  .rk-run { padding-block: clamp(24px, 3vw, 40px); }
}

/* The board is a panel inside the page here, so its heading sits on the paper
   above the panel rather than on the felt inside it. */
.rk-run.rank-home .pod-stage { margin-top: 4px; }

/*
   A block being swapped in place after the rail changed tour. It stays put and
   readable — a spinner over a table that is about to be replaced by a nearly
   identical table reads as a fault rather than as progress.
*/
[data-tour-block][aria-busy="true"] { opacity: .55; transition: opacity .15s linear; }
[data-tour-block] { transition: opacity .2s linear; }

/* ==========================================================================
   The phone tab bar
   ==========================================================================

   Five destinations pinned to the bottom of the screen on phones, with Book
   raised into the middle. Markup in resources/views/partials/mobile-tabbar.
   Site chrome, so it is page layout rather than a block, which is why it lives
   here rather than in sbi-elements.css.

   It only exists below the width at which the burger takes over the header; on
   anything wider the full navigation is on screen already and a tab bar would
   be a second copy of it. `display: none` by default means it costs a desktop
   visitor nothing but the markup. */
.sbi-tabbar { display: none; }

@media (max-width: 760px) {
  .sbi-tabbar {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 70;
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    align-items: end;
    background: var(--paper);
    border-top: 1px solid var(--line);
    /* The bar sits above the home indicator rather than under it. */
    padding: 8px 4px calc(8px + env(safe-area-inset-bottom, 0px));
  }

  .sbi-tab {
    display: grid;
    justify-items: center;
    gap: 4px;
    padding: 2px 0;
    color: var(--ink-soft);
    text-decoration: none;
    /* A 44px target even though the label is small. */
    min-height: 44px;
    transition: color .2s;
  }

  .sbi-tab__ico { display: grid; place-items: center; width: 24px; height: 24px; }
  .sbi-tab__ico svg { width: 22px; height: 22px; }
  .sbi-tab__lbl { font-size: 11px; line-height: 1; letter-spacing: .01em; }

  .sbi-tab.is-on { color: var(--ink); }
  .sbi-tab.is-on .sbi-tab__ico { color: var(--baize); }

  /* Book: lifted out of the bar on a gold disc. The negative margin pulls the
     disc up without changing the row's height, so the other four labels stay
     on the same baseline as its own. */
  .sbi-tab.is-raised .sbi-tab__ico {
    width: 46px; height: 46px;
    margin-top: -24px;
    border-radius: 999px;
    background: var(--gold-2);
    color: var(--deep);
    box-shadow: 0 6px 16px rgba(12, 30, 32, .28);
  }

  .sbi-tab.is-raised .sbi-tab__ico svg { width: 24px; height: 24px; stroke-width: 2.2; }
  .sbi-tab.is-raised { color: var(--ink); }
  .sbi-tab.is-raised.is-on .sbi-tab__ico { color: var(--deep); }

  .sbi-tab:focus-visible { outline: 2px solid var(--gold-2); outline-offset: -4px; border-radius: 10px; }

  /* Nothing may end up underneath the bar: the page gets its height back as
     padding, and the two things already pinned to the bottom right move up. */
  body { padding-bottom: calc(68px + env(safe-area-inset-bottom, 0px)); }

  .sbi-a11y-toggle { bottom: calc(80px + env(safe-area-inset-bottom, 0px)) !important; }
  .toasts { bottom: calc(92px + env(safe-area-inset-bottom, 0px)); }
}

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

/* ---------- the standings table on phones ----------

   Every other table on the site sits in `.tbl-wrap`, which is an
   `overflow-x: auto` scroller. The standings table turns that off:
   `.rank-wrap { overflow-x: visible }` (sbi.css:3255, and the prototype does
   the same), so that the row menus and the tour picker above it are not
   clipped by a scroll container.

   The cost is that the table has nowhere to go when it does not fit. Two of
   its eight columns carry `hide-sm` and drop at 760px, but the six that remain
   — position, move, player, events, best finish, points — are still wider than
   a phone, so the table ran off the side of the page and took the layout with
   it.

   Below 760px the scroller comes back. Nothing on a phone opens beside a row
   that would need to escape the box, and a table that scrolls inside its own
   card is far better than one that pushes the whole page sideways.

   `overscroll-behavior-x: contain` keeps a sideways swipe inside the table
   rather than letting it turn into a browser back-gesture. */
@media (max-width: 760px) {
  .rank-wrap {
    overflow-x: auto !important;
    overscroll-behavior-x: contain;
  }
}

/* ==========================================================================
   The coach directory as a stack of features.

   The prototype draws one `.coach-feature` — the National Coach — because its
   demo register holds one person. A real register holds several, and the page
   is a directory, so sbi.coaches draws a row per coach in that same shape.
   Nothing in sbi.css says what two of them in a column should look like, which
   is the one rule needed here.

   A rule, not a gap on the Container: the rows come from inside a block, so
   there is no Container between them to carry one.
   ========================================================================== */
.coach-rows { display: grid; gap: clamp(40px, 6vw, 80px); }

/* A line between them, so a long directory reads as a list rather than as one
   run-on article. Not on the last, which the band's own padding follows. */
.coach-rows > .coach-feature + .coach-feature {
  padding-top: clamp(40px, 6vw, 80px);
  border-top: 1px solid var(--line);
}

/* A photograph in the coach feature.

   sbi.css sizes a photo in every other art box — `.pp-img img`, `.hs-art img`,
   `.pn-art img` and the rest all get `width/height: 100%; object-fit: cover`.
   `.cf-art img` is missing from that list, and not by oversight: the prototype's
   coach feature only ever drew the generated portrait, so the sheet styles
   `.cf-art svg` and stops there. A real coach with a photograph on file dropped
   it into the corner of the box at its natural size.

   The box already has the aspect ratio and the clipping, so this is only the
   same declaration the other art boxes get. */
.cf-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
