/* Vendored from design-system/css/df-mobile.css.
   Re-vendor via scripts/sync_design_system.sh; import a new drop with --import.
   Do not hand-edit this file. */

/* =============================================================
   df-mobile.css — Downfield Forecast mobile/narrow primitives
   Pairs with colors_and_type.css + df.css + df-utilities.css.
   Link order: colors_and_type.css FIRST, then df.css, then
   df-utilities.css, then this file.

   The system breakpoint is 720px. Anything <=720px is "mobile";
   the marketing site and the app both use this single break.
   (Tablets in landscape land on the desktop layout — that's
   intentional; the mobile patterns are for thumbs, not for
   "narrower screen.")

   Most rules in this file are bare class selectors so they can
   be applied at any width — `.df-bottom-sheet` and
   `.df-sticky-bottom` are useful on desktop occasionally too.
   The breakpoint-gated bits (auto-promoting `.df-btn` to 44px
   touch targets, `.df-table-mobile-collapse` switching modes)
   are wrapped in `@media (max-width: 720px)` blocks at the end.

   This file is additive — nothing here overrides existing
   df.css rules outside the media query. Vendoring it is a
   one-line append to scripts/sync_design_system.sh and a one-line
   <link> in base.html (after df.css).
   ============================================================= */

/* ============================================================
   BREAKPOINT CONSTANT (documentation only — CSS doesn't have
   custom-property-driven media queries yet).

     --bp-mobile: 720px;

   Use `@media (max-width: 720px)` consistently. If you ever
   need to special-case bigger phones (Plus/Max sizes around
   428px width), prefer adding a second nested media query
   inside this file rather than introducing a second breakpoint.
   ============================================================ */

/* ---------- CARD-LIST ----------
   The vertical-stack-of-cards pattern that replaces tables on
   mobile. Each row of a desktop table becomes one card; the
   primary text and primary number lead, secondary stats stack
   below as label/value pairs.

   Pattern:
     <ul class="df-card-list">
       <li class="df-card-list-item">
         <div class="df-card-list-lead">
           <div class="df-card-list-title">Ja'Marr Chase</div>
           <div class="df-card-list-meta">WR · CIN · vs CLE</div>
         </div>
         <div class="df-card-list-stat">18.9</div>
       </li>
       …
     </ul>

   For tap-to-expand, wrap the body in a <details>:
     <li class="df-card-list-item">
       <details class="df-card-list-expand">
         <summary class="df-card-list-summary">   /* styled by the rule below; the
     bare descendant selector .df-card-list-expand summary also matches, so the
     class is optional — but it IS defined, and templates that follow this
     example are not carrying dead weight. (v0.3.2: it previously was not.) */…lead + stat row…</summary>
         <div class="df-card-list-detail">…expanded content…</div>
       </details>
     </li>
   The `.df-card-list-expand` rule below removes default summary
   marker styling and adds a chevron via background-image.
   ============================================================ */
.df-card-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.df-card-list-item {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  padding: var(--s-3) var(--s-4);
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-height: 64px;            /* big enough for thumb tap, leaves room for two-line lead */
}
.df-card-list-lead {
  flex: 1 1 auto;
  min-width: 0;                /* lets title truncate cleanly */
}
/* Wraps rather than clips. The title carries the availability pills, and at
   375px `overflow: hidden; white-space: nowrap` cut them to an ellipsis: on
   the roster's best receiver the pill that was cut was FULL VALUE — the
   disclosure that says a Questionable player's number has NOT been discounted
   (review 2026-08-30 §2.6; 9 of 145 pills clipped, FULL VALUE overhanging by
   74px and "high upside" by 159px). Truncating a disclosure is worse than a
   two-line title. Clean at 768 either way. */
.df-card-list-title {
  font-family: var(--font-ui);
  font-weight: var(--w-semibold);
  font-size: 15px;
  color: var(--fg);
  line-height: var(--lh-snug);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  min-width: 0;
  overflow-wrap: anywhere;
}
.df-card-list-meta {
  font-family: var(--font-ui);
  font-size: 12px;
  color: var(--fg-muted);
  margin-top: 2px;
  letter-spacing: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.df-card-list-stat {
  font-family: var(--font-mono);
  font-feature-settings: "tnum" 1, "zero" 1;
  font-size: 22px;
  font-weight: var(--w-semibold);
  color: var(--fg);
  text-align: right;
  flex: 0 0 auto;
}
.df-card-list-stat-label {
  display: block;
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: var(--w-semibold);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--fg-muted);
  margin-top: 2px;
}

/* Tap-to-expand variant — uses native <details>/<summary>. */
.df-card-list-expand          { width: 100%; }
.df-card-list-expand summary,
.df-card-list-summary  {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: 0;                              /* parent .df-card-list-item supplies padding */
}
.df-card-list-expand summary::-webkit-details-marker,
.df-card-list-summary::-webkit-details-marker { display: none; }
.df-card-list-expand summary::after,
.df-card-list-summary::after {
  content: "";
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  background: center / 16px no-repeat
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'><path d='M4 6l4 4 4-4' stroke='%236B7A70' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  transition: transform var(--dur-fast) var(--ease-standard);
}
.df-card-list-expand[open] summary::after { transform: rotate(180deg); }
.df-card-list-detail {
  margin-top: var(--s-3);
  padding-top: var(--s-3);
  border-top: 1px solid var(--rule-2);
  display: grid;
  grid-template-columns: repeat(2, 1fr);   /* 2-col label/value grid by default */
  gap: var(--s-2) var(--s-3);
  font-size: 13px;
}
.df-card-list-detail dt {
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: var(--w-semibold);
  letter-spacing: var(--ls-caps);
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: 0;
}
.df-card-list-detail dd {
  font-family: var(--font-mono);
  font-size: 14px;
  color: var(--fg);
  margin: 2px 0 0 0;
  font-feature-settings: "tnum" 1, "zero" 1;
}

/* ---------- BOTTOM SHEET ----------
   Modal that slides up from the bottom edge. Built on native
   <dialog> so close-on-Esc and backdrop click are free; HTMX
   wires .showModal()/.close().

   Pattern:
     <dialog class="df-bottom-sheet" id="trade-result">
       <form method="dialog" class="df-bottom-sheet-grabber" aria-label="Close"></form>
       <h3 class="df-bottom-sheet-title">Trade analysis</h3>
       <div class="df-bottom-sheet-body">…</div>
       <div class="df-bottom-sheet-actions">
         <button class="df-btn df-btn-secondary" formmethod="dialog">Close</button>
         <button class="df-btn df-btn-primary">Apply trade</button>
       </div>
     </dialog>

   The `<form method="dialog">` grabber is just a tap target at
   the top — submitting the form closes the dialog. Works with
   keyboard (Esc) and screen readers because <dialog> handles it.
   ============================================================ */
.df-bottom-sheet {
  position: fixed;
  left: 0; right: 0; bottom: 0; top: auto;
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
  padding: var(--s-5) var(--s-5) calc(var(--s-5) + env(safe-area-inset-bottom, 0px));
  background: var(--paper);
  border: 0;
  border-top-left-radius: var(--r-lg);
  border-top-right-radius: var(--r-lg);
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  box-shadow: 0 -8px 32px rgba(0,0,0,0.18);
  max-height: 85vh;
  overflow-y: auto;
}
.df-bottom-sheet::backdrop {
  background: rgba(20, 30, 22, 0.45);
}
.df-bottom-sheet[open] {
  animation: df-bottom-sheet-in 220ms cubic-bezier(.2,.8,.2,1);
}
@keyframes df-bottom-sheet-in {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}
.df-bottom-sheet-grabber {
  display: block;
  width: 36px;
  height: 4px;
  margin: -8px auto var(--s-3);
  border-radius: var(--r-pill);
  background: var(--rule);
  border: 0;
  cursor: pointer;
}
.df-bottom-sheet-title {
  font-family: var(--font-display);
  font-weight: var(--w-semibold);
  font-size: var(--t-h4);
  color: var(--fg);
  margin: 0 0 var(--s-3) 0;
  line-height: var(--lh-snug);
}
.df-bottom-sheet-body {
  font-family: var(--font-ui);
  font-size: 14px;
  color: var(--fg);
  line-height: var(--lh-normal);
}
.df-bottom-sheet-actions {
  display: flex;
  gap: var(--s-2);
  margin-top: var(--s-5);
  padding-top: var(--s-4);
  border-top: 1px solid var(--rule-2);
}
.df-bottom-sheet-actions .df-btn { flex: 1 1 auto; }

@media (prefers-reduced-motion: reduce) {
  .df-bottom-sheet[open] { animation: none; }
}

/* ---------- STICKY-BOTTOM CTA ----------
   Thumb-zone sticky bar for the primary action of a screen.
   Pattern:
     <div class="df-sticky-bottom">
       <button class="df-btn df-btn-primary df-btn-touch">Re-optimize lineup</button>
     </div>
   Sits at the bottom of its scroll container with a small shadow
   and safe-area padding for iPhones with home-indicator areas. */
.df-sticky-bottom {
  position: sticky;
  bottom: 0;
  left: 0;
  right: 0;
  background: var(--paper);
  border-top: 1px solid var(--rule);
  padding: var(--s-3) var(--s-4) calc(var(--s-3) + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -2px 12px rgba(0,0,0,0.06);
  z-index: 20;
}
.df-sticky-bottom > .df-btn { width: 100%; }
.df-sticky-bottom-row {
  display: flex;
  gap: var(--s-2);
}
.df-sticky-bottom-row > .df-btn { flex: 1 1 auto; }

/* ---------- TABLE MOBILE COLLAPSE ----------
   Hide low-priority columns on narrow screens. Mark <th>/<td>
   with data-priority="2" or "3" to drop them; data-priority="1"
   (or no attribute) always shows.

   Recommended priority floor:
     1 = name, primary stat (always show)
     2 = secondary stat (hide ≤720px)
     3 = tertiary stat / metadata (hide ≤480px)

   Pattern:
     <table class="df-table df-table-mobile-collapse">
       <thead><tr>
         <th>Player</th>
         <th>Pos</th>
         <th data-priority="2">Team</th>
         <th>Median</th>
         <th data-priority="2">Floor</th>
         <th data-priority="3">Ceiling</th>
       </tr></thead>
       …
     </table> */
@media (max-width: 720px) {
  .df-table-mobile-collapse [data-priority="2"] { display: none; }
}
@media (max-width: 480px) {
  .df-table-mobile-collapse [data-priority="3"] { display: none; }
}

/* On narrow viewports, also tighten table cell padding so the
   columns that survive aren't cramped against each other. */
@media (max-width: 720px) {
  .df-table-mobile-collapse thead th,
  .df-table-mobile-collapse tbody td {
    padding: var(--s-2) var(--s-2);
    font-size: 13px;
  }
}

/* ---------- TOUCH TARGETS ----------
   On narrow viewports, auto-promote .df-btn (and its small
   variant) to a 44×44 minimum touch target — iOS HIG floor.
   `.df-btn-touch` is a manual modifier you can apply at any
   width when you know a button is the primary action even on
   desktop (e.g. mobile-only flows tested on a larger screen). */
.df-btn-touch {
  min-height: 44px;
  padding-left: var(--s-4);
  padding-right: var(--s-4);
}
@media (max-width: 720px) {
  .df-btn { min-height: 44px; }
  .df-btn-sm { min-height: 38px; }     /* still smaller than default but thumb-able */
  .df-btn-xs, .df-input-xs, .df-select-xs { min-height: 32px; }
}

/* Form-control parity — inputs at touch height too. */
@media (max-width: 720px) {
  .df-input,
  .df-select,
  .df-textarea {
    min-height: 44px;
    font-size: 16px;                   /* iOS won't zoom on focus when ≥16px */
  }
}

/* ---------- BOTTOM TAB BAR ----------
   App-style bottom navigation. RECOMMENDED nav pattern for the
   subscriber web app on mobile (see HANDOFF §Mobile navigation).
   Pattern:
     <nav class="df-tabbar" aria-label="Primary">
       <a class="df-tabbar-item" aria-current="page" href="/">
         <svg …></svg>
         <span>Dashboard</span>
       </a>
       …4 items max…
     </nav>
   ============================================================ */
.df-tabbar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
  background: var(--paper);
  border-top: 1px solid var(--rule);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  z-index: 50;
}
.df-tabbar-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 8px 4px 6px;
  min-height: 56px;
  font-family: var(--font-ui);
  font-size: 10px;
  font-weight: var(--w-semibold);
  letter-spacing: 0.02em;
  color: var(--fg-muted);
  text-decoration: none;
  border: 0;
  background: transparent;
  cursor: pointer;
}
.df-tabbar-item svg {
  width: 22px;
  height: 22px;
  stroke-width: 1.75;
}
.df-tabbar-item[aria-current="page"] {
  color: var(--field);
}
.df-tabbar-item[aria-current="page"] svg {
  stroke-width: 2;
}
.df-tabbar-item:focus-visible {
  outline: 2px solid var(--pigskin);
  outline-offset: -2px;
}

/* Push page content above the fixed tabbar — apply to the main
   scrollable container when the tabbar is present. */
.df-tabbar-pad-bottom {
  padding-bottom: calc(56px + env(safe-area-inset-bottom, 0px) + var(--s-3));
}

/* ---------- MOBILE-ONLY LAYOUT HELPERS ---------- */
@media (max-width: 720px) {
  /* Containers shrink the gutter on phones — 16px instead of 24px. */
  .df-container,
  .df-container-text,
  .df-container-prose {
    padding: 0 var(--s-4);
  }
}

/* ---------- HEADER / TOPBAR — MOBILE ----------
   On mobile, the desktop topbar pattern (title + subtitle + right
   actions on one row) wraps awkwardly. .df-topbar-mobile is the
   intended layout: title row stays compact, actions move to a
   secondary row OR collapse into an overflow menu. */
.df-topbar-mobile {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-4);
  background: var(--paper);
  border-bottom: 1px solid var(--rule);
  position: sticky;
  top: 0;
  z-index: 40;
}
.df-topbar-mobile-title {
  font-family: var(--font-display);
  font-weight: var(--w-semibold);
  font-size: 18px;
  color: var(--fg);
  line-height: var(--lh-snug);
}
.df-topbar-mobile-subtitle {
  font-family: var(--font-ui);
  font-size: 12px;
  color: var(--fg-muted);
  margin-top: 1px;
}
