/* ==========================================================================
   Opleague — responsive
   --------------------------------------------------------------------------
   Every breakpoint lives here rather than scattered through the other sheets,
   so "why does this look wrong on a phone" has one file to open.

   The mockup is drawn at 1440. Three breakpoints carry it down:

     1100px  laptop and tablet landscape. The 1280 content rail stops fitting.
     900px   tablet portrait and large phones. The nav collapses here.
     560px   phones. Everything becomes one column.

   Enqueued last, so it wins over the component sheets without !important.
   ========================================================================== */


/* 1100 — the wide rail stops fitting ------------------------------------- */

@media (max-width: 1100px) {

  .opl-nav__inner,
  .opl-footer__inner { max-width: 100%; }

  .opl-nav__menu { gap: 24px; }

  /*
   * THE BAND BETWEEN DESKTOP AND THE BURGER, 901 to 1100.
   *
   * Tournaments became a fourth group on 2026-09-20, and four groups plus
   * Sign in, Sign up and the tournament button stopped fitting before the
   * menu collapses at 900. Measured at 950: the actions row hung 85px past
   * the right edge, which is content sliced off rather than scrolled,
   * because the bar has no overflow to scroll into.
   *
   * Sign in is the one that goes. It is the quietest of the three, the one
   * only a returning member looks for, and it is a text button so it is
   * also the cheapest to lose. It already disappears below 900 for exactly
   * the same reason; this just starts it earlier, where the squeeze
   * actually begins.
   *
   * Caught by measuring four widths rather than two. 1440 and 492 were both
   * clean, and the fault lived entirely in between them.
   */
  .opl-nav__actions .opl-btn--ghost { display: none; }
  .opl-nav__inner { gap: var(--opl-s4); }

  /* The four-across game row becomes two-across before it becomes one. */
  .opl-tiles { grid-template-columns: repeat(2, 1fr); }

  /* Three featured players become two, then one. */
  .opl-featured { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* The gallery keeps rolling; it just shows fewer at a time. */
  .opl-featured--roll > .opl-feat { flex-basis: clamp(230px, 44%, 300px); }

  .opl-display { font-size: 44px; letter-spacing: 4px; }
}


/* 900 — the nav collapses ------------------------------------------------- */

@media (max-width: 900px) {

  /* Nav. The menu is hidden until the toggle opens it; nav.js flips
     aria-expanded and the is-open class together. */
  /* On a phone the message wraps and the button drops under it. */
  .opl-announce__inner { flex-wrap: wrap; justify-content: flex-start; gap: var(--opl-s4); padding-inline: var(--opl-gutter); }
  .opl-announce__text { flex: 1 1 100%; }

  .opl-nav__inner { padding-inline: var(--opl-gutter); flex-wrap: wrap; }
  .opl-nav__toggle { display: inline-flex; order: 2; }
  .opl-nav > .opl-nav__inner > nav { order: 3; flex-basis: 100%; }
  .opl-nav__menu { display: none; }
  .opl-nav__menu.is-open,
  nav[data-open="true"] .opl-nav__menu {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--opl-s4);
    padding-block: var(--opl-s5);
    border-top: 1px solid var(--opl-blue-300);
  }
  /*
   * Sub-nav on a phone: no panels, no hover, everything already open.
   *
   * A hover-opened dropdown cannot work on a touch screen, and reproducing
   * it with tap-to-open would add a script, a state and a way to be stuck
   * with a panel you cannot close. The menu is already a drawer the visitor
   * opened on purpose, so the honest thing is to show the whole
   * architecture at once and let them scroll.
   */
  .opl-nav__group { width: 100%; }
  .opl-nav__sub {
    position: static;
    visibility: visible;
    opacity: 1;
    transform: none;
    transition: none;
    min-width: 0;
    margin: var(--opl-s3) 0 var(--opl-s4);
    padding: 0 0 0 var(--opl-s5);
    background: none;
    border: 0;
    border-left: 1px solid var(--opl-blue-300);
    border-radius: 0;
    box-shadow: none;
  }
  /*
   * nowrap is right in a floating panel, which sizes itself to its content.
   * It is a trap in the drawer, which cannot grow: a label longer than the
   * column would run off the right edge with nothing to stop it, silently,
   * because the drawer has no horizontal scroll. Today's longest is
   * "Download the client" and it fits at 320px with room to spare, so this
   * changes nothing now and prevents the next label from being a bug.
   */
  .opl-nav__sub a { padding: 9px 0; white-space: normal; }

  /* The hover bridge is a desktop crutch and would sit over real links. */
  .opl-nav__group::after { content: none; }

  /*
   * The action buttons on a phone.
   *
   * Three buttons plus a burger plus the wordmark does not fit across 390px,
   * so signing in drops out of the bar rather than being squeezed: it is the
   * one a returning member will look for in the menu anyway, and it is also
   * in the Get started section. Sign up and the tournament button stay,
   * because those are the two the site is trying to get a stranger to press.
   */
  .opl-nav__actions { order: 1; gap: var(--opl-s2); }
  .opl-nav__actions .opl-btn--ghost { display: none; }
  .opl-nav .opl-btn { padding: 12px 14px; }

  /* Bands breathe less on a small screen or the page becomes scrolling. */
  .opl-band { padding-block: var(--opl-s8); }

  .opl-display { font-size: 34px; letter-spacing: 3px; }
  .opl-title   { font-size: 26px; letter-spacing: 2px; }
  .opl-h2      { font-size: 24px; }

  /* Cards and tiles. */
  .opl-tiles { grid-template-columns: repeat(2, 1fr); }
  .opl-tile  { min-height: 240px; }
  .opl-stats { gap: var(--opl-s6); }

  /* The step rows stack: a 200px label column leaves nothing for the body. */
  .opl-step { flex-direction: column; gap: var(--opl-s2); }
  .opl-step__label { width: auto; }

  /* Footer. */
  .opl-footer { padding-inline: var(--opl-gutter); }
  .opl-footer__columns { gap: var(--opl-s7); }
  .opl-footer__brand { max-width: 100%; flex-basis: 100%; }
  .opl-signup { gap: var(--opl-s6); }
}


/* 560 — phones ------------------------------------------------------------ */

@media (max-width: 560px) {

  /*
   * Footer links big enough for a thumb, on phones only.
   *
   * They were 18px tall on a 33px pitch. That clears WCAG 2.5.8, which
   * asks for 24px, and misses the 44px Apple and Android both point at.
   * Fifteen of them stacked, the narrowest only 33px wide, and they are
   * the last thing on every page, which on a phone is exactly where a
   * thumb is least accurate.
   *
   * Done as min-height plus centering rather than padding, so the text
   * does not move and the type scale is untouched. The row gap comes off
   * to pay for some of the height: pitch goes 33px to 44px, so the footer
   * grows about 11px per link rather than 26px.
   *
   * Phones only. On a desktop these are mouse targets and 18px is fine.
   * Mike's call, delegated 2026-09-19: "just follow what you think is
   * best on that one."
   */
  .opl-footer__col ul { gap: 0; }
  .opl-footer__col li > a,
  .opl-footer__col li { display: flex; align-items: center; min-height: 44px; }
  .opl-footer__col li > a { flex: 1 1 auto; }
  .opl-legal a, .opl-social a { display: inline-flex; align-items: center; min-height: 44px; }


  .opl-wrap,
  .opl-wrap--wide,
  .opl-wrap--read { padding-inline: var(--opl-gutter); }

  .opl-display { font-size: 28px; letter-spacing: 2px; }
  .opl-title   { font-size: 22px; letter-spacing: 1.5px; }
  .opl-h2      { font-size: 20px; }
  .opl-lede    { font-size: var(--opl-size-body-sm); }

  /* One column, everywhere. */
  .opl-tiles   { grid-template-columns: 1fr; }
  .opl-featured { grid-template-columns: 1fr; }

  /*
   * On a phone the next card peeks past the edge. Without the peek a
   * scrollable row looks exactly like a single card and nobody swipes.
   */
  .opl-featured--roll > .opl-feat { flex-basis: 82%; }

  /* The profile portrait stacks above the name on a phone. */
  .opl-profilehead { flex-direction: column; align-items: flex-start; gap: var(--opl-s4); }
  .opl-portrait--profile { width: 96px; }
  .opl-tile    { min-height: 200px; }
  .opl-tiers   { flex-direction: column; }
  .opl-tier    { flex: 1 1 100%; }
  .opl-reasons { flex-direction: column; }
  .opl-reason  { flex: 1 1 100%; }

  /* A score line that wraps mid-match reads badly, so the names wrap
     together and the score stays with them. */
  .opl-card__players { flex-wrap: wrap; row-gap: 4px; }
  .opl-card__actions { flex-wrap: wrap; gap: var(--opl-s3); }

  .opl-stats { gap: var(--opl-s5); }
  .opl-stat__value { font-size: 22px; }

  /* Buttons go full width so they are thumb-sized. */
  .opl-btn { width: 100%; }
  .opl-btn-row { display: flex; flex-direction: column; gap: var(--opl-s3); }

  /* The signup form stacks. */
  .opl-signup__form { width: 100%; }
  .opl-signup__form input[name="opl_fname"],
  .opl-signup__form input[name="opl_email"] { width: 100%; flex: 1 1 100%; }
  .opl-signup__form .opl-btn { width: 100%; }

  .opl-footer__row { flex-direction: column; align-items: flex-start; }
  .opl-legal { flex-wrap: wrap; row-gap: 4px; }
}


/* Tables ------------------------------------------------------------------ */
/* Wide tables scroll sideways rather than squashing to unreadable. The
   wrapper is focusable so a keyboard user can reach the scroll area. */

@media (max-width: 900px) {
  .opl-table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    /* A soft edge hints there is more to the right. */
    -webkit-mask-image: linear-gradient(90deg, #000 90%, transparent 100%);
            mask-image: linear-gradient(90deg, #000 90%, transparent 100%);
  }
  .opl-table-scroll:focus-visible { outline: 2px solid var(--opl-accent); outline-offset: 2px; }
  .opl-table-scroll > .opl-table { min-width: 640px; }
  .opl-table th,
  .opl-table td { padding: var(--opl-s3) var(--opl-s4); white-space: nowrap; }
}


/* Motion and contrast preferences ----------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* The fading light is decoration. If someone has asked for less, drop it
   rather than leaving a blurred smear behind the text. */
@media (prefers-reduced-transparency: reduce) {
  .opl-glow { display: none; }
}

@media (prefers-contrast: more) {
  .opl-glow { opacity: .4; }
  .opl-lede { color: var(--opl-slate); }
  .opl-band--dark .opl-lede,
  .opl-band--dark-mid .opl-lede { color: var(--opl-white); }
  .opl-footer__col a { color: var(--opl-white); }
}


/* Print ------------------------------------------------------------------- */
/* Someone will print the rules or the terms. Make that not embarrassing. */

@media print {
  .opl-nav, .opl-footer, .opl-glow, .opl-btn { display: none !important; }
  body.opl { background: #fff !important; color: #000; }
  .opl-band { padding-block: var(--opl-s5); background: #fff !important; color: #000 !important; }
  .opl-wrap, .opl-wrap--wide, .opl-wrap--read { max-width: 100%; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 10px; }

  /*
   * No elevation on paper. A shadow is a hint about depth on a screen and a
   * grey smear on a page, and every card, tier, tile and callout now has
   * one. The band rule above already forces white, so a shadow would be the
   * only dark thing left on an otherwise clean print.
   */
  * { box-shadow: none !important; }

  /* The bar goes with the nav, the footer and the glows. */
  .opl-announce { display: none !important; }
}


/* ---------------------------------------------------------------------------
   Home page blocks. Added with the home template; the breakpoints match the
   ones above so nothing reflows at a width the rest of the site does not.
   --------------------------------------------------------------------------- */

@media (max-width: 1100px) {
  .opl-grid--4 { grid-template-columns: repeat(2, 1fr); }
  .opl-nova    { grid-template-columns: 1fr; gap: var(--opl-s7); }
}

@media (max-width: 900px) {
  .opl-grid--3 { grid-template-columns: 1fr; }
  .opl-hero    { padding-block: var(--opl-s8); }
}

@media (max-width: 560px) {
  .opl-grid--4        { grid-template-columns: 1fr; }
  .opl-hero__mark span { font-size: 26px; }
  .opl-hero__actions  { flex-direction: column; align-items: stretch; }
}


/* The About essay. The definition pair and the do/you table both carry two
   columns of prose, which stops working before the phone breakpoint. */
@media (max-width: 900px) {
  .opl-defs { grid-template-columns: 1fr; }
}
@media (max-width: 560px) {
  .opl-split, .opl-split tbody, .opl-split tr, .opl-split td, .opl-split th { display: block; width: auto; }
  .opl-split thead { display: none; }
  .opl-split tr { border-bottom: var(--opl-hairline); padding-block: var(--opl-s3); }
  .opl-split td { border-bottom: 0; }
  .opl-split td::before { content: attr(data-col); display: block; font-size: var(--opl-size-micro); letter-spacing: 0.6px; text-transform: uppercase; color: var(--opl-gray); }
}


/* Legal documents. The contents list stops being a sidebar and becomes an
   ordinary block above the text. */
@media (max-width: 900px) {
  .opl-doc { grid-template-columns: 1fr; gap: var(--opl-s7); }

  /* Contact stacks the same way: the form first, the other ways beneath. */
  .opl-contact { grid-template-columns: 1fr; gap: var(--opl-s7); }
  .opl-form--card { padding: var(--opl-s6); }
  .opl-doc__nav { position: static; }
  .opl-doc__toc { flex-direction: row; flex-wrap: wrap; gap: var(--opl-s3) var(--opl-s5); }
}


/* How It Works. The spec grid and the step heads both stack. */
@media (max-width: 560px) {
  .opl-specs,
  .opl-specs--wide,
  .opl-specs--narrow,
  .opl-specs--tight { grid-template-columns: 1fr; gap: 2px var(--opl-s4); }
  /* --split keeps two columns: its second column is a short score or record
     like "5 - 0", which reads better beside its label than under it. */
  .opl-specs--split { grid-template-columns: 1fr auto; }
  .opl-specs dd { margin-bottom: var(--opl-s4); }
  .opl-howto__head { gap: var(--opl-s4); }
  .opl-howto__num { font-size: 26px; }
}


/* Ranks and scoring. The swing pair and the chart both get tight. */
@media (max-width: 560px) {
  .opl-swing { gap: var(--opl-s5); }
  .opl-dist  { height: 130px; gap: 2px; }
  .opl-dist__label { font-size: 9px; }
}


/* Bracket rows. Below the tablet width the action drops under the row and
   the date marker sits inline with the game name. */
@media (max-width: 900px) {
  .opl-bracket { grid-template-columns: 80px 1fr; gap: var(--opl-s4) var(--opl-s5); }
  .opl-bracket__spots { grid-column: 2; }
  .opl-bracket .opl-btn { grid-column: 2; justify-self: start; }
}
@media (max-width: 560px) {
  .opl-tabs { gap: var(--opl-s4); overflow-x: auto; }
  .opl-bracket { grid-template-columns: 1fr; }
  .opl-bracket__spots, .opl-bracket .opl-btn { grid-column: 1; }
}


/* The podium stacks, and drops its visual reordering so the source order
   (1, 2, 3) is what you read. */
@media (max-width: 700px) {
  .opl-podium { flex-direction: column; align-items: stretch; }
  .opl-podium__slot--1,
  .opl-podium__slot--2,
  .opl-podium__slot--3 { order: 0; }
  .opl-podium__slot--1 { padding-block: var(--opl-s6); }
}


/* Download rows drop their action under the text. */
@media (max-width: 700px) {
  .opl-dl { grid-template-columns: 44px 1fr; }
  .opl-dl .opl-btn { grid-column: 2; justify-self: start; }
}

@media (max-width: 900px) { .opl-grid--2 { grid-template-columns: 1fr; } }
