/* Structural CSS for the site-redesign shell (docs/ux/site-redesign/README.md).
 * Ported from docs/ux/site-redesign/src/_base.css. Colors/fonts/radii come from
 * pf-theme.css's custom properties on :root; this file is the layout only.
 *
 * Collision policy: pfs-web still loads DaisyUI + Tailwind's play CDN for every
 * page that hasn't been migrated yet (admin/*, home.html's league list, and the
 * not-yet-rebuilt league pages; auth/* and the public landing page use the
 * pf-auth / pf-landing blocks at the bottom of this file). A handful of names
 * in the mockup source are
 * also real DaisyUI component names (card, btn*, badge*, alert) -- those are
 * prefixed `pf-` here so they can never collide with (or be overridden by)
 * DaisyUI's own rules of the same name. Everything else in this file is a
 * name DaisyUI/Tailwind doesn't define (topbar, rail, tspan, ladder, ...) and
 * is kept verbatim.
 *
 * The lineup-timeline classes (.tl/.trow/.slot/.track/.qhead/.cell/.tspan and
 * its modifiers/.handle/.dock/.chip/.nm/.meta/.from/.pos) are an exception on
 * purpose: pfs_web/lineup_timeline_render.py and static/lineup_timeline.js
 * already emit these unprefixed and are not being touched by this redesign
 * (see the plan's Slice 4 note) -- only the rules styling them move here from
 * lineup_timeline.css.
 */

.pf-ic { width: 1em; height: 1em; display: inline-block; vertical-align: -0.15em; flex-shrink: 0; }

/* ---------- App shell ---------- */
.pf-app { background: var(--pf-bg); color: var(--pf-fg); font-size: 14px; line-height: 1.35; font-family: var(--pf-font-body); -webkit-font-smoothing: antialiased; }

.pf-topbar { background: var(--pf-top-bg); color: var(--pf-top-fg); height: 54px; display: flex; align-items: center; gap: 14px; padding: 0 18px; border-bottom: 1px solid var(--pf-line); position: sticky; top: 0; z-index: 40; }
.pf-brand { display: flex; align-items: center; gap: 8px; font-family: var(--pf-font-display); font-weight: 800; font-size: 20px; letter-spacing: .01em; text-transform: uppercase; white-space: nowrap; text-decoration: none; color: inherit; }
.pf-brand .pf-mark { width: 26px; height: 26px; border-radius: 7px; background: var(--pf-accent); color: var(--pf-accent-fg); display: inline-flex; align-items: center; justify-content: center; }
.pf-brand .pf-mark .pf-ic { width: 18px; height: 18px; }
.pf-ctx { display: flex; align-items: center; gap: 6px; padding: 5px 10px 5px 12px; border-radius: var(--pf-radius-sm); border: 1px solid var(--pf-line-2); background: var(--pf-bg-3); font-weight: 600; font-size: 13px; color: inherit; text-decoration: none; }
.pf-ctx .pf-ic { opacity: .6; transform: rotate(90deg); }
.pf-ctx small { color: var(--pf-fg-3); font-weight: 500; }
.pf-clockchip { display: inline-flex; align-items: center; gap: 7px; padding: 4px 10px; border-radius: var(--pf-radius-pill); font-family: var(--pf-font-mono); font-size: 12px; font-weight: 600; border: 1px solid color-mix(in srgb, var(--pf-live) 50%, transparent); color: var(--pf-live); background: color-mix(in srgb, var(--pf-live) 10%, transparent); white-space: nowrap; }
.pf-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--pf-live); box-shadow: 0 0 0 3px color-mix(in srgb, var(--pf-live) 25%, transparent); }
.pf-spacer { flex: 1; }
.pf-userchip { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--pf-fg-2); }
.pf-userchip .pf-av { width: 28px; height: 28px; border-radius: 50%; background: var(--pf-bg-4); border: 1px solid var(--pf-line-2); display: inline-flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 700; color: var(--pf-fg); }

.pf-dropdown { position: relative; }
.pf-dropdown summary::-webkit-details-marker { display: none; }
.pf-dropdown-menu { position: absolute; right: 0; top: calc(100% + 8px); z-index: 50; min-width: 12rem; background: var(--pf-bg-2); border: 1px solid var(--pf-line-2); border-radius: var(--pf-radius-sm); box-shadow: 0 12px 32px rgba(0, 0, 0, .5); padding: 6px; list-style: none; margin: 0; max-height: 70vh; overflow-y: auto; }
.pf-dropdown-menu li { display: block; }
.pf-dropdown-menu li a, .pf-dropdown-menu li form button { display: block; width: 100%; text-align: left; padding: 7px 10px; border-radius: var(--pf-radius-sm); color: var(--pf-fg-2); text-decoration: none; font-size: 13px; background: transparent; border: 0; cursor: pointer; font-family: var(--pf-font-body); }
.pf-dropdown-menu li a:hover, .pf-dropdown-menu li form button:hover { background: var(--pf-bg-3); color: var(--pf-fg); }
.pf-dropdown-label { padding: 6px 10px 2px; font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--pf-fg-3); font-family: var(--pf-font-display); }
.pf-dropdown-divider { height: 1px; background: var(--pf-line); margin: 6px 4px; }

.pf-body { display: flex; flex: 1; min-height: 0; }
.pf-content { flex: 1; min-width: 0; padding: 20px 24px 28px; }

/* Rail nav (Command-rail shell) */
.pf-rail { width: 212px; flex-shrink: 0; background: var(--pf-nav-bg); border-right: 1px solid var(--pf-line); padding: 14px 10px; display: flex; flex-direction: column; gap: 6px; }
.pf-rail-title { font-size: 10px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--pf-fg-3); padding: 10px 10px 4px; font-family: var(--pf-font-display); }
.pf-rail a { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: var(--pf-radius-sm); color: var(--pf-nav-fg); text-decoration: none; font-weight: 600; font-size: 13.5px; position: relative; }
.pf-rail a .pf-ic { width: 17px; height: 17px; opacity: .8; }
.pf-rail a.pf-active { background: var(--pf-nav-active-bg); color: var(--pf-nav-active-fg); }
.pf-rail a .pf-cnt { margin-left: auto; font-size: 10.5px; font-weight: 700; padding: 1px 6px; border-radius: 999px; background: var(--pf-warn); color: #1a1300; }
.pf-rail .pf-foot { margin-top: auto; padding: 10px; font-size: 11px; color: var(--pf-fg-3); line-height: 1.4; }

/* Bottom tab bar (phone) */
.pf-bottombar { position: fixed; left: 0; right: 0; bottom: 0; height: 66px; background: var(--pf-nav-bg); border-top: 1px solid var(--pf-line); display: flex; align-items: stretch; padding: 6px 4px 10px; z-index: 40; }
.pf-bottombar > a, .pf-bottombar > button { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; font-size: 10px; font-weight: 700; color: var(--pf-nav-fg); text-decoration: none; border-radius: 8px; letter-spacing: .02em; }
.pf-bottombar > button { background: transparent; border: 0; cursor: pointer; font-family: inherit; position: relative; }
.pf-bottombar > a .pf-ic, .pf-bottombar > button .pf-ic { width: 20px; height: 20px; }
.pf-bottombar > a.pf-active, .pf-bottombar > button.pf-active { color: var(--pf-accent); }
.pf-bottombar .pf-more-dot { position: absolute; top: 4px; left: calc(50% + 6px); width: 8px; height: 8px; border-radius: 50%; background: var(--pf-warn); box-shadow: 0 0 0 2px var(--pf-nav-bg); }

/* "More" bottom sheet (phone): the rail destinations the four tabs omit. The <dialog> has no
   padding of its own -- .pf-sheet-body does -- so JS can tell a backdrop click from a content click. */
.pf-sheet { position: fixed; inset: auto 0 0 0; margin: 0; width: 100%; max-width: none; max-height: 80vh; padding: 0; border: 0; border-top: 1px solid var(--pf-line-2); border-radius: 16px 16px 0 0; background: var(--pf-bg-2); color: var(--pf-fg); overflow-y: auto; overscroll-behavior: contain; }
.pf-sheet[open] { animation: pf-sheet-up .18s ease-out; }
.pf-sheet::backdrop { background: rgba(0, 0, 0, .55); }
.pf-sheet-body { padding: 8px 12px calc(16px + env(safe-area-inset-bottom)); }
.pf-sheet-head { display: flex; align-items: center; justify-content: space-between; padding: 4px 4px 2px; font-family: var(--pf-font-display); font-weight: 800; font-size: 18px; text-transform: uppercase; letter-spacing: .02em; }
.pf-sheet-close { background: transparent; border: 0; color: var(--pf-fg-2); font-size: 26px; line-height: 1; width: 44px; height: 44px; cursor: pointer; }
.pf-sheet a { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 44px; padding: 0 10px; border-radius: var(--pf-radius-sm); color: var(--pf-nav-fg); text-decoration: none; font-weight: 600; font-size: 15px; }
.pf-sheet a.pf-active { background: var(--pf-nav-active-bg); color: var(--pf-nav-active-fg); }
.pf-sheet a .pf-cnt { font-size: 11px; font-weight: 700; padding: 1px 7px; border-radius: 999px; background: var(--pf-warn); color: #1a1300; }
@keyframes pf-sheet-up { from { transform: translateY(100%); } to { transform: none; } }
@media (prefers-reduced-motion: reduce) { .pf-sheet[open] { animation: none; } }
body:has(.pf-bottombar) .pf-content { padding-bottom: 78px; }

/* Page header */
.pf-pagehead { margin-bottom: 16px; }
.pf-pagehead .pf-titles { min-width: 0; }
.pf-h1 { font-family: var(--pf-font-display); font-weight: 800; font-size: 30px; line-height: 1; letter-spacing: -.005em; text-transform: uppercase; margin: 0; position: relative; padding-left: 14px; }
.pf-h1::before { content: ''; position: absolute; left: 0; top: 2px; bottom: 2px; width: 5px; background: var(--pf-accent); border-radius: 2px; box-shadow: 0 0 12px rgba(245, 217, 10, .5); }
.pf-sub { color: var(--pf-fg-2); font-size: 13px; margin-top: 5px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pf-sub b { color: var(--pf-fg); font-weight: 600; }
.pf-pagehead .pf-actions { margin-left: auto; display: flex; align-items: center; gap: 8px; }
/* Header layout is one grid at every width, so the actions (week stepper) never change rows as
 * the viewport or a long subtitle changes: title + actions share row 1, the subtitle spans the
 * full width on row 2. `display: contents` on .pf-titles lifts the h1 and subtitle into the grid. */
.pf-pagehead { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 6px 14px; }
.pf-pagehead .pf-titles { display: contents; }
.pf-pagehead .pf-h1 { grid-column: 1; grid-row: 1; }
.pf-pagehead .pf-actions { grid-column: 2; grid-row: 1; margin-left: 0; position: relative; }
.pf-pagehead .pf-sub { grid-column: 1 / -1; grid-row: 2; margin-top: 0; }
/* Phone widths: the transient status chip (depth chart's "Saved") is taken out of flow and shrunk
 * to its icon, sitting left of the stepper, so showing it never squeezes the title. */
@media (max-width: 639px) {
  .pf-pagehead .pf-actions .pf-statuschip { position: absolute; right: calc(100% + 8px); top: 50%; transform: translateY(-50%); padding: 4px 6px; }
  .pf-pagehead .pf-actions .pf-chip-label { display: none; }
}

.pf-weekstep { display: inline-flex; align-items: stretch; border: 1px solid var(--pf-line-2); border-radius: var(--pf-radius-sm); overflow: hidden; background: var(--pf-bg-3); }
.pf-weekstep a, .pf-weekstep button { background: transparent; border: 0; color: var(--pf-fg-2); width: 30px; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; text-decoration: none; }
.pf-weekstep a.pf-disabled { opacity: .35; pointer-events: none; }
.pf-weekstep .pf-ic { width: 16px; height: 16px; }
.pf-weekstep .pf-wk { padding: 0 10px; display: flex; flex-direction: column; justify-content: center; align-items: center; border-left: 1px solid var(--pf-line-2); border-right: 1px solid var(--pf-line-2); min-width: 92px; }
.pf-weekstep .pf-wk b { font-family: var(--pf-font-display); font-size: 15px; letter-spacing: .02em; text-transform: uppercase; line-height: 1; color: var(--pf-accent); }
.pf-weekstep .pf-wk small { font-size: 10px; color: var(--pf-fg-3); margin-top: 2px; }
.pf-weekstep button.pf-wk { width: auto; font: inherit; }
.pf-weekstep button.pf-wk:hover, .pf-weekstep button.pf-wk[aria-expanded="true"] { background: var(--pf-bg-2); }
/* Week picker dropdown: 9 rows visible (selected +/- 4), the rest reachable by wheel/touch scroll. */
.pf-weekwrap { position: relative; display: inline-block; }
.pf-weekpick { --pf-weekpick-row: 36px; position: absolute; top: calc(100% + 4px); left: 50%; transform: translateX(-50%); z-index: 50; margin: 0; padding: 0; list-style: none; min-width: 132px; height: calc(var(--pf-weekpick-row) * 9); overflow-y: auto; overscroll-behavior: contain; touch-action: pan-y; -webkit-overflow-scrolling: touch; scroll-snap-type: y proximity; background: var(--pf-bg-2); border: 1px solid var(--pf-line-2); border-radius: var(--pf-radius-sm); box-shadow: 0 10px 28px rgba(0, 0, 0, .45); }
.pf-weekpick[hidden] { display: none; }
.pf-weekpick a { display: flex; align-items: baseline; justify-content: center; gap: 8px; height: var(--pf-weekpick-row); box-sizing: border-box; scroll-snap-align: center; color: var(--pf-fg-2); text-decoration: none; font-family: var(--pf-font-display); font-size: 14px; letter-spacing: .02em; text-transform: uppercase; align-items: center; }
.pf-weekpick a small { font-family: var(--pf-font-body); font-size: 10px; color: var(--pf-fg-3); }
.pf-weekpick a:hover, .pf-weekpick a:focus-visible { background: var(--pf-bg-3); color: var(--pf-fg); outline: none; }
.pf-weekpick a.pf-selected { color: var(--pf-accent); }
.pf-statuschip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: var(--pf-radius-pill); font-size: 12px; font-weight: 600; border: 1px solid var(--pf-line-2); color: var(--pf-fg-2); background: var(--pf-bg-3); white-space: nowrap; }
.pf-statuschip.pf-ok { color: var(--pf-ok); border-color: color-mix(in srgb, var(--pf-ok) 45%, transparent); background: color-mix(in srgb, var(--pf-ok) 10%, transparent); }
.pf-statuschip.pf-warn { color: var(--pf-warn); border-color: color-mix(in srgb, var(--pf-warn) 45%, transparent); background: color-mix(in srgb, var(--pf-warn) 10%, transparent); }
.pf-statuschip.pf-live { color: var(--pf-live); border-color: color-mix(in srgb, var(--pf-live) 45%, transparent); background: color-mix(in srgb, var(--pf-live) 10%, transparent); font-family: var(--pf-font-mono); }

/* Buttons, badges, cards -- prefixed: these names exist in DaisyUI too */
.pf-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 8px 14px; border-radius: var(--pf-radius-sm); border: 1px solid var(--pf-line-2); background: var(--pf-bg-3); color: var(--pf-fg); font-weight: 700; font-size: 13px; font-family: var(--pf-font-body); text-decoration: none; cursor: pointer; white-space: nowrap; }
.pf-btn .pf-ic { width: 15px; height: 15px; }
.pf-btn-primary { background: linear-gradient(180deg, #ffe84d, #f5d90a); color: var(--pf-accent-fg); border-color: var(--pf-accent); box-shadow: 0 0 0 1px rgba(245, 217, 10, .5), 0 0 22px rgba(245, 217, 10, .3); }
.pf-btn-ghost { background: transparent; border-color: transparent; color: var(--pf-fg-2); }
.pf-btn-outline { background: transparent; }
.pf-btn-sm { padding: 5px 10px; font-size: 12px; }
.pf-btn-xs { padding: 3px 8px; font-size: 11px; }
.pf-btn-block { width: 100%; }
.pf-btn:disabled, .pf-btn.pf-disabled { opacity: .5; pointer-events: none; }
.pf-badge { display: inline-flex; align-items: center; gap: 4px; padding: 1px 7px; border-radius: var(--pf-radius-pill); font-size: 10.5px; font-weight: 700; line-height: 16px; border: 1px solid var(--pf-line-2); color: var(--pf-fg-2); white-space: nowrap; letter-spacing: .02em; }
.pf-badge-warn { color: #1a1300; background: var(--pf-warn); border-color: var(--pf-warn); }
.pf-badge-err { color: #fff; background: var(--pf-danger); border-color: var(--pf-danger); }
/* Inactive (not on an active NFL roster): solid violet, deliberately outside the warn/err/live hues so it
   never reads as an injury or a live game. `.badge-inactive` is the DaisyUI-badge twin. */
.pf-badge-inactive, .badge.badge-inactive { color: #fff; background: #7c3aed; border-color: #a78bfa; font-weight: 700; }
.pf-badge-ok { color: #06281a; background: var(--pf-ok); border-color: var(--pf-ok); }
.pf-badge-accent { color: var(--pf-accent-fg); background: var(--pf-accent); border-color: var(--pf-accent); }
.pf-badge-live { color: #e0f6ff; border-color: color-mix(in srgb, var(--pf-live) 50%, transparent); background: color-mix(in srgb, var(--pf-live) 12%, transparent); box-shadow: 0 0 10px rgba(56, 189, 248, .4); }
/* Dark fill (var(--pf-bg-4)) -- for a value that's just informational (a final score)
   and shouldn't compete for attention with the warn/ok/accent/live badges
   above, which all mean "look at me." */
.pf-badge-neutral { color: var(--pf-fg-2); background: var(--pf-bg-4); border-color: var(--pf-line-2); }
.pill { display: inline-block; border: 1px solid var(--pf-line-2); border-radius: 999px; padding: 0 6px; font-size: 10px; line-height: 15px; color: var(--pf-fg-2); white-space: nowrap; font-family: var(--pf-font-mono); }
.pf-muted { color: var(--pf-fg-3); }
.pf-mono { font-family: var(--pf-font-mono); font-variant-numeric: tabular-nums; }

.pf-card { background: var(--pf-bg-2); border: 1px solid var(--pf-line); border-radius: var(--pf-radius); overflow: hidden; box-shadow: 0 8px 24px rgba(0, 0, 0, .35); }
.pf-card-h { display: flex; align-items: center; gap: 10px; padding: 11px 14px; border-bottom: 1px solid var(--pf-line); }
.pf-card-h h2 { margin: 0; font-family: var(--pf-font-display); font-size: 15px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; padding-left: 10px; box-shadow: inset 3px 0 0 var(--pf-accent); }
.pf-card-h .pf-right { margin-left: auto; display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--pf-fg-2); }
.pf-card-b { padding: 12px 14px; }
.pf-grid { display: grid; gap: 16px; }

/* Legend strip */
.pf-keys { display: flex; gap: 14px; flex-wrap: wrap; font-size: 11px; color: var(--pf-fg-2); align-items: center; }
.pf-keys i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 5px; vertical-align: -1px; }

/* ---------- Lineup timeline ----------
 * Matches lineup_timeline_render.py / lineup_timeline.js's class names
 * exactly (unprefixed) so a future rebuild needs no markup/JS changes, only
 * a stylesheet swap -- see the plan's Slice 4 note. Scoped under `.pf-timeline`
 * (a wrapper class Slice 4 adds around #lineup-timeline) rather than left
 * bare: today's *unmigrated* lineup page already has its own `#lineup-timeline`-
 * scoped rules for these same class names (static/lineup_timeline.css), and
 * this file is loaded globally (base.html) -- bare selectors here would be a
 * live collision risk on the page this redesign hasn't rebuilt yet. */
.pf-timeline .tl { display: flex; flex-direction: column; position: relative; }
.pf-timeline .trow { display: flex; align-items: center; gap: 10px; padding: 5px 10px; border-bottom: 1px solid var(--pf-line); position: relative; }
.pf-timeline .trow:last-child { border-bottom: 0; }
.pf-timeline .trow.thead { padding-bottom: 2px; }
.pf-timeline .slot { width: 40px; flex-shrink: 0; font-family: var(--pf-font-display); font-size: 12px; font-weight: 800; letter-spacing: .06em; color: var(--pf-fg-2); }
.pf-timeline .track { flex: 1; min-width: 0; display: grid; grid-template-columns: 1fr 1fr 1fr 1fr .62fr; gap: 4px; position: relative; align-items: stretch; }
.pf-timeline .track > * { grid-row: 1; }
.pf-timeline .qhead div { font-family: var(--pf-font-display); font-size: 12px; font-weight: 800; letter-spacing: .06em; color: var(--pf-fg-2); text-align: center; padding: 3px 0 4px; border-bottom: 2px solid transparent; }
.pf-timeline .qhead div small { display: block; font-size: 9.5px; font-weight: 600; color: var(--pf-fg-3); font-family: var(--pf-font-mono); letter-spacing: 0; }
.pf-timeline .qhead div.live { color: #e0f6ff; text-shadow: 0 0 10px rgba(56, 189, 248, .8); border-bottom-color: var(--pf-live); }
.pf-timeline .qhead div.live small { color: #7dd3fc; }
.pf-timeline .qhead div.past { color: var(--pf-fg-3); }
.pf-timeline .qhead div.ot { color: var(--pf-fg-3); }
.pf-timeline .cell { border-radius: 3px; min-height: 46px; }
.pf-timeline .cell.locked { background: repeating-linear-gradient(135deg, transparent 0 7px, rgba(56, 189, 248, .10) 7px 9px); }
.pf-timeline .tspan { z-index: 1; min-width: 0; border-radius: 3px; padding: 5px 8px; background: var(--pf-bg-3); border: 1px solid var(--pf-line-2); display: flex; flex-direction: column; gap: 2px; justify-content: center; min-height: 46px; cursor: grab; position: relative; }
.pf-timeline .tspan .nm { font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pf-timeline .tspan .meta { display: flex; gap: 4px; align-items: center; min-width: 0; white-space: nowrap; overflow: hidden; }
.pf-timeline .tspan .from { font-size: 10px; color: var(--pf-fg-3); }
.pf-timeline .tspan.sub { background: linear-gradient(180deg, rgba(56, 189, 248, .22), rgba(56, 189, 248, .08)); border-color: rgba(56, 189, 248, .7); box-shadow: 0 0 16px rgba(56, 189, 248, .25); }
.pf-timeline .tspan.sub .from { color: #7dd3fc; }
.pf-timeline .tspan.override { box-shadow: inset 3px 0 0 var(--pf-warn); }
.pf-timeline .tspan.locked { opacity: .8; cursor: default; }
.pf-timeline .tspan.unavail { border-color: color-mix(in srgb, var(--pf-danger) 55%, transparent); }
/* Live tiles (round-4 shock treatment): faint inner charge + shock-fine frame, see pf-theme.css */
.pf-timeline .tspan.live { border-color: rgba(56, 189, 248, .45); box-shadow: inset 0 0 18px rgba(56, 189, 248, .10); position: relative; }
.pf-timeline .tspan.live.override { box-shadow: inset 3px 0 0 var(--pf-warn), inset 0 0 18px rgba(56, 189, 248, .10); }
.pf-timeline .handle { z-index: 2; justify-self: start; width: 14px; margin-left: -9px; display: flex; align-items: center; justify-content: center; cursor: col-resize; }
.pf-timeline .handle i { display: block; width: 6px; height: 26px; border-radius: 3px; background: var(--pf-live); box-shadow: 0 0 12px var(--pf-live); opacity: .95; }
.pf-timeline .dock { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; padding: 10px 10px 8px; border-top: 1px dashed var(--pf-line-2); margin-top: 4px; min-height: 44px; }
.pf-timeline .dock .lbl { font-family: var(--pf-font-display); font-size: 11px; text-transform: uppercase; letter-spacing: .12em; color: var(--pf-fg-3); font-weight: 800; margin-right: 4px; }
.pf-timeline .chip { display: inline-flex; align-items: center; gap: 6px; background: var(--pf-bg-3); border: 1px solid var(--pf-line-2); border-radius: 999px; padding: 4px 10px 4px 6px; font-size: 12px; cursor: grab; }
.pf-timeline .chip .grip { color: var(--pf-fg-3); width: 12px; height: 12px; }
.pf-timeline .chip .nm { font-weight: 600; }
.pf-timeline .chip.unavailable { opacity: .5; }

/* Position chips: same hues everywhere (positions.css is also loaded, kept
   for legacy DaisyUI pages -- this block matches its palette for pf- pages). */
.pos { display: inline-flex; align-items: center; padding: 0 6px; border-radius: 2px; font-size: 10px; font-weight: 800; line-height: 16px; letter-spacing: .04em; font-family: var(--pf-font-display); --posrgb: 100 116 139; background: rgb(var(--posrgb) / .2); border: 1px solid rgb(var(--posrgb) / .5); color: var(--pf-fg); }
.pos[data-pos="QB"] { --posrgb: 139 92 246; }
.pos[data-pos="RB"] { --posrgb: 16 185 129; }
.pos[data-pos="WR"] { --posrgb: 59 130 246; }
.pos[data-pos="TE"] { --posrgb: 236 72 153; }
.pos[data-pos="K"] { --posrgb: 20 184 166; }
.pos[data-pos="DST"], .pos[data-pos="DEF"], .pos[data-pos="D/ST"] { --posrgb: 100 116 139; }

/* NFL team chip -- the one rule for its look on every page (depth chart, lineup,
   waivers, draft, matchup detail). Markup comes only from
   templates/components/_team_chip.html; sized to sit beside the .pos chip above. */
.pf-team-chip { display: inline-flex; align-items: center; flex-shrink: 0; padding: 0 5px; border-radius: 2px; font-size: 10px; font-weight: 600; line-height: 16px; letter-spacing: .02em; font-family: var(--pf-font-mono); color: var(--pf-fg-2); background: transparent; border: 1px solid var(--pf-line-2); white-space: nowrap; }

/* Side "this week" panel */
.pf-alerts { display: flex; flex-direction: column; gap: 8px; }
.pf-alert { display: flex; gap: 9px; align-items: flex-start; padding: 9px 10px; border-radius: var(--pf-radius-sm); border: 1px solid var(--pf-line); background: var(--pf-bg-3); font-size: 12.5px; line-height: 1.35; }
.pf-alert .pf-ic { width: 15px; height: 15px; margin-top: 1px; flex-shrink: 0; }
.pf-alert.pf-warn { border-color: color-mix(in srgb, var(--pf-warn) 45%, transparent); }
.pf-alert.pf-warn .pf-ic { color: var(--pf-warn); }
.pf-alert.pf-err { border-color: color-mix(in srgb, var(--pf-danger) 45%, transparent); }
.pf-alert.pf-err .pf-ic { color: var(--pf-danger); }
.pf-alert.pf-ok { border-color: color-mix(in srgb, var(--pf-ok) 45%, transparent); }
.pf-alert.pf-ok .pf-ic { color: var(--pf-ok); }
.pf-alert b { font-weight: 700; }

/* Matchup / score */
.pf-matchup { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 12px; }
.pf-matchup .pf-tm { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pf-matchup .pf-tm.pf-r { text-align: right; }
.pf-matchup .pf-tm .pf-nm { font-weight: 700; font-size: 14px; overflow-wrap: break-word; }
.pf-matchup .pf-nm.pf-me { color: var(--pf-accent); }
/* Full-variant team block: larger name, then owner, then record -- one line each. */
.pf-matchup:not(.pf-compact) .pf-tm .pf-nm { font-size: 17px; }
.pf-matchup .pf-tm .pf-tm-owner, .pf-matchup .pf-tm .pf-tm-rec { font-size: 12px; color: var(--pf-fg-3); overflow-wrap: break-word; }
.pf-matchup .pf-tm .pf-tm-rec { font-family: var(--pf-font-mono); font-variant-numeric: tabular-nums; }
.pf-matchup .pf-sc { font-family: var(--pf-font-mono); font-weight: 700; font-size: 26px; letter-spacing: -.02em; display: flex; align-items: center; gap: 10px; padding: 6px 10px; }
.pf-matchup .pf-sc small { font-size: 12px; color: var(--pf-fg-3); font-weight: 600; }
.pf-matchup .pf-sc .pf-win { color: #e0f6ff; text-shadow: 0 0 18px rgba(56, 189, 248, .8); }
.pf-matchup .pf-sc .pf-lose { color: var(--pf-fg-3); }
/* Quarters-remaining state -- declared after win/lose so it wins the color. */
.pf-matchup .pf-sc .pf-qlive { color: var(--pf-live); text-shadow: 0 0 12px rgba(56, 189, 248, .9), 0 0 28px rgba(56, 189, 248, .5); }
.pf-matchup .pf-sc .pf-qdone { color: var(--pf-ok); text-shadow: none; }
.pf-matchup .pf-sc:has(.pf-qrem) { display: grid; grid-template-columns: auto auto auto; justify-content: center; column-gap: 10px; row-gap: 0; }
.pf-matchup .pf-sc .pf-qrem { grid-row: 2; font-family: var(--pf-font-body, inherit); font-size: 11px; font-weight: 600; letter-spacing: 0; color: var(--pf-fg-3); white-space: nowrap; }
.pf-matchup .pf-sc .pf-qrem-l { grid-column: 1; text-align: center; }
.pf-matchup .pf-sc .pf-qrem-r { grid-column: 3; text-align: center; }
.pf-matchup.pf-compact { grid-template-columns: 1fr; gap: 4px; }
.pf-matchup.pf-compact .pf-row { display: flex; align-items: center; gap: 8px; padding: 4px 0; }
.pf-matchup.pf-compact .pf-row .pf-nm { font-weight: 700; font-size: 13px; flex: 1; min-width: 0; overflow-wrap: break-word; }
.pf-matchup.pf-compact .pf-row .pf-n { font-family: var(--pf-font-mono); font-weight: 700; font-size: 22px; letter-spacing: -.02em; color: #e0f6ff; text-shadow: 0 0 14px rgba(56, 189, 248, .6); }
.pf-matchup.pf-compact .pf-row .pf-n.pf-lose { color: var(--pf-fg-3); text-shadow: none; }

/* A whole card that's a link (Matchups list -> matchup detail). */
a.pf-card-link { display: block; color: inherit; text-decoration: none; transition: border-color .12s, transform .12s; }
a.pf-card-link:hover, a.pf-card-link:focus-visible { border-color: var(--pf-live); }
a.pf-card-link:active { transform: translateY(1px); }

/* Matchup detail: per-player Q chips. One fixed-width cell per period so chips
   line up down the column; an unslotted period is a same-width transparent
   placeholder (its text is kept, just invisible, so the widths match). A slotted
   chip is in one of three states by where his own NFL game is: done (neutral +
   corner tick), live (the electrified badge, below) or upcoming (hollow). */
.pf-qtrack { display: inline-flex; gap: 5px; }   /* 5px, not 3: room for the corner tick's overhang */
.pf-qchip { position: relative; min-width: 27px; justify-content: center; padding: 1px 4px; }
/* A slotted quarter: a light neutral chip, a step brighter than .pf-badge-neutral (the final-score
   chip's dark fill) but not an accent -- there are up to 4 per row. */
.pf-qchip.pf-qon { color: var(--pf-fg); background: var(--pf-line-2); border-color: color-mix(in srgb, var(--pf-fg-3) 65%, var(--pf-line-2)); }
/* Done: the text steps back a shade and a green tick hangs off the top-right corner, so a chip is the
   same width checked or not. Uses ::before -- a live chip's shock frame (pf-theme.css) owns ::after. */
.pf-qchip.pf-qon.pf-qdone { color: var(--pf-fg-2); }
.pf-qchip.pf-qon.pf-qdone::before {
  content: "\2713"; position: absolute; top: -4px; right: -4px; z-index: 4;
  width: 11px; height: 11px; border-radius: 50%; background: var(--pf-ok); color: #06281a;
  font-size: 8px; font-weight: 800; line-height: 11px; text-align: center;
  box-shadow: 0 0 0 1.5px var(--pf-bg-2);   /* halo, so it reads over the chip's border */
}
/* Live: the same electrified badge as the game clock beside his name (.pf-badge-live's glow, plus the
   shock frame in pf-theme.css). `.pf-qon` is more specific than `.pf-badge-live`, so restate its
   tint here or the light neutral fill would win. */
.pf-qchip.pf-qon.pf-badge-live { color: #e0f6ff; background: color-mix(in srgb, var(--pf-live) 12%, transparent); border-color: color-mix(in srgb, var(--pf-live) 50%, transparent); }
/* ...and its tint fills left to right as the quarter clock runs down (`--q-pct`, set inline from the
   game clock). Drawn as the chip's own background rather than a bar on its edge: the shock frame
   covers the chip's outer few pixels. Without a usable clock the chip just has no sweep. */
.pf-qchip.pf-badge-live.pf-qsweep { background-image: linear-gradient(90deg, color-mix(in srgb, var(--pf-live) 38%, transparent) var(--q-pct), transparent 0); }
/* Upcoming: hollow -- a solid outline, distinct from the dashed unslotted placeholder. */
.pf-qchip.pf-qon.pf-qnext { color: var(--pf-fg-2); background: transparent; border-color: var(--pf-line-2); }
.pf-qchip.pf-qgap { color: transparent; border-color: var(--pf-line); border-style: dashed; user-select: none; }
/* A lineup row's points total follows the same three states as its chips: gray until anything has
   scored, the electrified blue while a quarter it holds is in play, and green / red / plain once
   every quarter it holds is banked. */
.pf-pts-upcoming { color: var(--pf-fg-3); }
.pf-pts-live { color: var(--pf-live); text-shadow: 0 0 10px rgba(56, 189, 248, .45); }
.pf-pts-done.pf-pts-pos { color: var(--pf-ok); }
.pf-pts-done.pf-pts-neg { color: var(--pf-danger); }
.pf-section-label { font-family: var(--pf-font-display); font-size: 12px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; margin-bottom: 6px; }
.pf-section-label .pf-muted { font-family: var(--pf-font-body, inherit); font-weight: 500; letter-spacing: 0; text-transform: none; }
/* Bench table's closing Total row. */
table.pf-t tr.pf-bench-total td { border-top: 1px solid var(--pf-line-2); border-bottom: 0; font-weight: 700; font-size: 12px; text-transform: uppercase; letter-spacing: .08em; color: var(--pf-fg-3); }
/* A substitute, indented under the slot's starter (box-score style). */
.pf-subname { padding-left: 18px; }
/* ...and no divider between him and the starter above, so the pair reads as one block. */
table.pf-t tr:has(+ tr.pf-subrow) td { border-bottom-color: transparent; }
/* Player cell: one line -- position chip, name, then the game status flowing right after the name;
   wraps rather than overflowing at phone width. */
.pf-player-line { display: flex; align-items: center; flex-wrap: wrap; gap: 2px 8px; }

/* Tables */
table.pf-t { width: 100%; border-collapse: collapse; font-size: 13px; }
table.pf-t th { text-align: left; white-space: nowrap; font-size: 10.5px; text-transform: uppercase; letter-spacing: .1em; color: var(--pf-fg-3); font-weight: 700; padding: 6px 8px; border-bottom: 1px solid var(--pf-line); font-family: var(--pf-font-display); }
table.pf-t td { padding: 7px 8px; border-bottom: 1px solid var(--pf-line); vertical-align: middle; }
table.pf-t tr:last-child td { border-bottom: 0; }
table.pf-t .pf-r { text-align: right; }
table.pf-t .pf-c { text-align: center; }
table.pf-t tr.pf-me td { background: color-mix(in srgb, var(--pf-accent) 8%, transparent); }
table.pf-t td.pf-num { font-family: var(--pf-font-mono); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Standings (page + dashboard mini-table). The playoff cut line sits under
   the last team currently in playoff position. W/L/T streaks reuse the
   ok/danger tokens; a tie streak stays neutral. */
table.pf-t tr.pf-cut td { border-bottom: 2px dashed color-mix(in srgb, var(--pf-accent) 55%, transparent); }
.pf-streak { font-family: var(--pf-font-mono); font-weight: 700; font-size: 12px; }
.pf-streak-W { color: var(--pf-ok); }
.pf-streak-L { color: var(--pf-danger); }
.pf-streak-T { color: var(--pf-fg-2); }
.pf-diff-pos { color: var(--pf-ok); }
.pf-diff-neg { color: var(--pf-danger); }
.pf-cut-key { display: inline-block; width: 18px; border-top: 2px dashed color-mix(in srgb, var(--pf-accent) 55%, transparent); vertical-align: middle; margin-right: 6px; }
/* Secondary standings columns (PA, Diff) drop at phone width so the table
   fits 390px without a sideways scroll. */
@media (max-width: 639px) {
  table.pf-t .pf-col-wide { display: none; }
}

/* Depth chart ladders */
.pf-ladders { columns: 3; column-gap: 16px; }
.pf-ladder { break-inside: avoid; margin-bottom: 16px; }
.pf-rung { display: flex; align-items: center; gap: 9px; padding: 6px 8px 6px 6px; border-bottom: 1px solid var(--pf-line); }
.pf-rung:last-child { border-bottom: 0; }
.pf-rung .pf-grip { color: var(--pf-fg-3); width: 14px; height: 14px; cursor: grab; }
.pf-rung .pf-rk { width: 26px; height: 26px; border-radius: 6px; display: inline-flex; align-items: center; justify-content: center; font-family: var(--pf-font-display); font-weight: 800; font-size: 14px; background: var(--pf-bg-3); border: 1px solid var(--pf-line-2); color: var(--pf-fg-2); flex-shrink: 0; }
.pf-rung.pf-starter .pf-rk { background: #38bdf8; color: #06202b; border-color: #38bdf8; box-shadow: 0 0 16px rgba(56, 189, 248, .7); }
.pf-rung.pf-starter { background: linear-gradient(90deg, rgba(56, 189, 248, .08), transparent 60%); }
.pf-rung .pf-nm { font-weight: 600; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pf-rung .pf-meta { display: flex; gap: 4px; align-items: center; margin-top: 1px; overflow: hidden; white-space: nowrap; }
.pf-rung .pf-txt { min-width: 0; flex: 1; }
.pf-rung .pf-tag { margin-left: auto; flex-shrink: 0; font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--pf-fg-3); font-weight: 800; font-family: var(--pf-font-display); white-space: nowrap; }
.pf-rung.pf-starter .pf-tag { color: #7dd3fc; }
.pf-rung.pf-skip .pf-nm { text-decoration: line-through; color: var(--pf-fg-3); }
.pf-rung.pf-skip .pf-tag { color: var(--pf-danger); }
.pf-showmore { display: block; text-align: center; padding: 7px; font-size: 12px; color: var(--pf-fg-2); border-top: 1px dashed var(--pf-line-2); font-weight: 600; text-decoration: none; width: 100%; background: none; border-left: 0; border-right: 0; border-bottom: 0; cursor: pointer; }
.pf-showmore:hover { color: var(--pf-fg); }

/* Depth chart drag/keyboard reorder (site-redesign Slice 5). Same raw
   palette values as lineup_timeline.css's drop-ok/override/flash treatment
   (sky-500, amber-500) -- colors stay outside `data-theme` on purpose (see
   lineup_timeline.css's own header comment) so the two pages match
   regardless of theme. Design principle #3: drag must disable text
   selection or the page's own text highlights along with the drag. */
.pf-ladders, #pf-drag-ghost { user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
.pf-rung { cursor: default; }
.pf-rung:focus-visible { outline: 2px solid rgb(14 165 233 / .9); outline-offset: -2px; }
.pf-rung[aria-pressed="true"] { box-shadow: inset 0 0 0 2px rgb(14 165 233 / .9); background: rgb(14 165 233 / .1); }
.pf-rung.pf-dragging { opacity: .35; }
#pf-drag-ghost { box-shadow: 0 12px 30px rgba(0, 0, 0, .45); transform: rotate(-1deg); background: var(--pf-bg-2); border-radius: var(--pf-radius-sm); will-change: transform; }
/* Drag-time layout discipline (see depth_chart_ladder.js's header): the
   ladders are a balanced multi-column flow, so the drop line must never be
   in-flow -- it is absolutely positioned in the body and moved with
   `transform`, so a pointermove changes nothing the column balancer sees. */
.pf-ladder-body { position: relative; }
.pf-drop-line { position: absolute; left: 0; right: 0; top: 0; height: 2px; border-radius: 2px; background: rgb(14 165 233 / .9); box-shadow: 0 0 8px rgb(14 165 233 / .6); pointer-events: none; will-change: transform; }
.pf-ladder-body[aria-busy="true"] { pointer-events: none; opacity: .7; }
.pf-rung-extra { display: none; }
.pf-ladder-body.pf-expanded .pf-rung-extra { display: flex; }
@keyframes pf-rung-flash {
  0% { box-shadow: inset 0 0 0 2px rgb(14 165 233 / .9); }
  100% { box-shadow: inset 0 0 0 2px rgb(14 165 233 / 0); }
}
.pf-rung.pf-flash { animation: pf-rung-flash 1.2s ease-out; }

/* Dashboard */
.pf-checklist { display: flex; flex-direction: column; }
.pf-checklist > div { display: flex; align-items: center; gap: 9px; padding: 7px 0; border-bottom: 1px solid var(--pf-line); font-size: 13px; }
.pf-checklist > div:last-child { border-bottom: 0; }
.pf-checklist .pf-ic { width: 16px; height: 16px; }
.pf-checklist .pf-ok { color: var(--pf-ok); }
.pf-checklist .pf-warn { color: var(--pf-warn); }
.pf-checklist .pf-todo { color: var(--pf-fg-3); }
.pf-checklist .pf-go { margin-left: auto; }
.pf-feed { display: flex; flex-direction: column; }
.pf-feed > div { display: flex; gap: 10px; padding: 7px 0; border-bottom: 1px solid var(--pf-line); font-size: 12.5px; line-height: 1.35; }
.pf-feed > div:last-child { border-bottom: 0; }
.pf-feed .pf-when { color: var(--pf-fg-3); font-family: var(--pf-font-mono); font-size: 10.5px; width: 44px; flex-shrink: 0; padding-top: 2px; }
.pf-sched { display: flex; gap: 6px; overflow: hidden; }
.pf-sched .pf-wkc { flex: 0 0 auto; width: 66px; padding: 6px 4px; border-radius: 8px; border: 1px solid var(--pf-line); background: var(--pf-bg-3); text-align: center; }
.pf-sched .pf-wkc b { display: block; font-family: var(--pf-font-display); font-size: 12px; letter-spacing: .06em; }
.pf-sched .pf-wkc small { display: block; font-size: 10px; color: var(--pf-fg-3); margin-top: 2px; white-space: nowrap; }
.pf-sched .pf-wkc.pf-now { border-color: var(--pf-live); box-shadow: 0 0 14px rgba(56, 189, 248, .35); }
.pf-sched .pf-wkc.pf-done { opacity: .55; }
.pf-hero-actions { display: flex; gap: 8px; flex-wrap: wrap; }

/* DEMO placeholder */
.pf-demo { position: relative; border-radius: var(--pf-radius); overflow: hidden; border: 1px solid var(--pf-line); }
.pf-demo img { display: block; width: 100%; height: auto; }
.pf-demo::after {
  content: 'DEMO'; position: absolute; top: 18px; right: -34px; z-index: 2; pointer-events: none;
  transform: rotate(45deg); transform-origin: center; width: 160px; text-align: center;
  background: var(--pf-warn); color: #1a1300; font-family: var(--pf-font-display);
  font-weight: 800; letter-spacing: .18em; font-size: 12px; padding: 4px 0;
  box-shadow: 0 2px 10px rgba(0, 0, 0, .4);
}

/* Simple modal used by the points-breakdown dialog (no DaisyUI .modal here) */
.pf-modal::backdrop { background: rgba(4, 5, 10, .7); }
.pf-modal { background: var(--pf-bg-2); color: var(--pf-fg); border: 1px solid var(--pf-line); border-radius: var(--pf-radius); padding: 0; max-width: 30rem; width: calc(100% - 2rem); }
.pf-modal .pf-card-b { max-height: 70vh; overflow-y: auto; }

/* ---------- Top bar: anonymous visitor actions (Log in / Sign up) ---------- */
.pf-topbar-auth { display: flex; align-items: center; gap: 8px; }

/* ---------- Auth pages (templates/auth/*, via components/_pf_auth_card.html) ----------
 * Same card chrome as every league page; the form controls below are the
 * pf- equivalents of DaisyUI's input/label so these pages stop being the
 * one DaisyUI-skinned island a visitor lands on first. */
.pf-auth { display: flex; justify-content: center; padding: 40px 16px 56px; }
.pf-auth-card { width: 100%; max-width: 26rem; }
.pf-auth-card .pf-card-h h2 { font-size: 20px; }
.pf-auth-card .pf-card-b { padding: 16px 18px 18px; display: flex; flex-direction: column; gap: 14px; }
.pf-auth-card form { display: flex; flex-direction: column; gap: 14px; }
.pf-auth-card .pf-alert { margin: 0; }
.pf-field { display: flex; flex-direction: column; gap: 5px; }
.pf-label { font-family: var(--pf-font-display); font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--pf-fg-3); }
.pf-input { width: 100%; padding: 9px 11px; border-radius: var(--pf-radius-sm); border: 1px solid var(--pf-line-2); background: var(--pf-bg); color: var(--pf-fg); font-family: var(--pf-font-body); font-size: 14px; line-height: 1.3; }
.pf-input::placeholder { color: var(--pf-fg-3); }
.pf-input:focus { outline: none; border-color: var(--pf-live); box-shadow: 0 0 0 3px rgba(56, 189, 248, .18); }
.pf-input-wrap { position: relative; }
.pf-input-wrap .pf-input { padding-right: 40px; }
.pf-input-affix { position: absolute; top: 0; bottom: 0; right: 0; display: inline-flex; align-items: center; padding: 0 11px; background: transparent; border: 0; color: var(--pf-fg-3); cursor: pointer; }
.pf-input-affix:hover { color: var(--pf-fg); }
.pf-input-affix .pf-ic { width: 18px; height: 18px; }
.pf-link { color: #7dd3fc; text-decoration: none; font-weight: 600; }
.pf-link:hover { text-decoration: underline; }
.pf-auth-aside { display: flex; justify-content: flex-end; font-size: 12px; margin-top: -6px; }
.pf-auth-divider { display: flex; align-items: center; gap: 10px; font-family: var(--pf-font-display); font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--pf-fg-3); }
.pf-auth-divider::before, .pf-auth-divider::after { content: ''; flex: 1; height: 1px; background: var(--pf-line-2); }
.pf-auth-card p { margin: 0; color: var(--pf-fg-2); font-size: 13px; line-height: 1.45; }
.pf-btn-lg { padding: 11px 20px; font-size: 14px; }

/* ---------- Public landing page (templates/landing.html) ----------
 * Coarse layout lives here (not Tailwind utilities) so the page reads as one
 * piece with the rest of the pf- shell; the sky art from pf-theme.css sits
 * behind the hero exactly as it does behind every league page. */
.pf-landing { max-width: 1120px; margin: 0 auto; padding: 56px 24px 72px; }
.pf-hero { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); gap: 40px; align-items: center; margin-bottom: 64px; }
.pf-kicker { display: inline-flex; align-items: center; gap: 8px; font-family: var(--pf-font-display); font-size: 12px; font-weight: 800; letter-spacing: .16em; text-transform: uppercase; color: #7dd3fc; margin-bottom: 14px; }
.pf-kicker .pf-dot { width: 7px; height: 7px; }
.pf-hero-title { font-family: var(--pf-font-display); font-weight: 800; font-size: 58px; line-height: .95; letter-spacing: -.01em; text-transform: uppercase; margin: 0 0 18px; }
.pf-hero-title em { font-style: normal; color: var(--pf-accent); text-shadow: 0 0 24px rgba(245, 217, 10, .35); }
.pf-lead { font-size: 17px; line-height: 1.5; color: var(--pf-fg-2); max-width: 34rem; margin: 0 0 26px; }
.pf-lead b { color: var(--pf-fg); font-weight: 600; }
.pf-hero-cta { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.pf-hero-cta .pf-btn { padding: 11px 20px; font-size: 14px; }
.pf-hero-demo .pf-card-b { padding: 8px 10px 10px; }
.pf-hero-demo .pf-caption { display: flex; gap: 14px; flex-wrap: wrap; padding: 8px 4px 0; font-size: 11.5px; color: var(--pf-fg-3); }
.pf-hero-demo .pf-caption i { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 5px; vertical-align: -1px; }

.pf-section { margin-bottom: 64px; }
.pf-section-head { margin-bottom: 20px; }
.pf-section-head .pf-h1 { font-size: 26px; }
.pf-section-head p { margin: 8px 0 0 14px; color: var(--pf-fg-2); font-size: 14px; max-width: 40rem; }
.pf-features { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
.pf-feature { background: rgba(13, 17, 24, .96); border: 1px solid var(--pf-line); border-radius: var(--pf-radius); padding: 20px 18px 22px; box-shadow: 0 8px 24px rgba(0, 0, 0, .35); display: flex; flex-direction: column; gap: 10px; }
/* Icon + title sit on one row at every width -- .pf-feature itself stays a
   column (icon+title row, then the paragraph, then .pf-fx) so only this row
   needs its own flex axis. */
.pf-feature .pf-feature-head { display: flex; align-items: center; gap: 12px; }
.pf-feature .pf-fi { width: 40px; height: 40px; flex-shrink: 0; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--pf-live) 14%, transparent); border: 1px solid color-mix(in srgb, var(--pf-live) 45%, transparent); color: #7dd3fc; box-shadow: 0 0 16px rgba(56, 189, 248, .2); }
.pf-feature .pf-fi .pf-ic { width: 22px; height: 22px; }
.pf-feature h3 { margin: 0; font-family: var(--pf-font-display); font-size: 20px; font-weight: 800; letter-spacing: .02em; text-transform: uppercase; line-height: 1.05; }
.pf-feature p { margin: 0; color: var(--pf-fg-2); font-size: 13.5px; line-height: 1.5; }
.pf-feature .pf-fx { margin-top: auto; padding-top: 6px; font-size: 12px; color: var(--pf-fg-3); }
.pf-feature .pf-fx b { color: #7dd3fc; font-weight: 700; }

.pf-steps { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; counter-reset: pf-step; }
.pf-step { position: relative; padding: 16px 16px 16px 54px; border: 1px solid var(--pf-line); border-radius: var(--pf-radius); background: rgba(13, 17, 24, .8); }
.pf-step::before { counter-increment: pf-step; content: counter(pf-step); position: absolute; left: 14px; top: 14px; width: 28px; height: 28px; border-radius: 6px; display: inline-flex; align-items: center; justify-content: center; font-family: var(--pf-font-display); font-weight: 800; font-size: 15px; background: var(--pf-accent); color: var(--pf-accent-fg); box-shadow: 0 0 14px rgba(245, 217, 10, .35); }
.pf-step b { display: block; font-family: var(--pf-font-display); font-size: 15px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; margin-bottom: 4px; }
.pf-step span { font-size: 12.5px; color: var(--pf-fg-2); line-height: 1.45; }

.pf-cta-band { text-align: center; padding: 36px 20px; border: 1px solid rgba(56, 189, 248, .4); border-radius: var(--pf-radius); background: linear-gradient(90deg, rgba(56, 189, 248, .10), transparent 45%, rgba(245, 217, 10, .08)), var(--pf-bg-2); }
.pf-cta-band h2 { margin: 0 0 8px; font-family: var(--pf-font-display); font-size: 30px; font-weight: 800; text-transform: uppercase; line-height: 1; }
.pf-cta-band p { margin: 0 auto 18px; color: var(--pf-fg-2); font-size: 14px; max-width: 34rem; }
.pf-cta-band .pf-hero-cta { justify-content: center; }
/* Headset chip above the CTA heading (landing2.html) -- same treatment as
   the feature-card icon chips (.pf-feature .pf-fi) so it reads as an accent,
   not a logo. */
.pf-cta-band .pf-cta-icon { width: 48px; height: 48px; margin: 0 auto 14px; border-radius: 10px; display: flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--pf-live) 14%, transparent); border: 1px solid color-mix(in srgb, var(--pf-live) 45%, transparent); color: #7dd3fc; box-shadow: 0 0 18px rgba(56, 189, 248, .25); }
.pf-cta-band .pf-cta-icon .pf-ic { width: 26px; height: 26px; }
/* "Sideline scenarios" FAQ (landing2.html, the live homepage): two-column grid of
   situation -> what happens. Headings are the situation in plain prose, so
   they stay sentence case rather than the display-uppercase used elsewhere. */
.pf-faq { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.pf-faq-item { position: relative; padding: 16px 18px 18px 22px; border: 1px solid var(--pf-line); border-radius: var(--pf-radius); background: rgba(13, 17, 24, .8); }
.pf-faq-item::before { content: ''; position: absolute; left: 0; top: 14px; bottom: 14px; width: 4px; border-radius: 2px; background: var(--pf-warn); box-shadow: 0 0 10px rgba(245, 158, 11, .4); }
.pf-faq-item h3 { margin: 0 0 8px; font-family: var(--pf-font-display); font-size: 22px; font-weight: 800; letter-spacing: .01em; text-transform: uppercase; line-height: 1.05; text-wrap: balance; color: var(--pf-fg); }
.pf-faq-item p { margin: 0; font-size: 15px; font-weight: 600; line-height: 1.4; color: var(--pf-accent); }

/* "Where other leagues stop" comparison table; stacks into one card per row on phones (see breakpoint below) */
.pf-compare { width: 100%; border-collapse: separate; border-spacing: 0; border: 1px solid var(--pf-line); border-radius: var(--pf-radius); overflow: hidden; background: rgba(13, 17, 24, .8); font-size: 13.5px; }
.pf-compare th, .pf-compare td { padding: 12px 16px; text-align: left; vertical-align: top; line-height: 1.4; border-top: 1px solid var(--pf-line); }
.pf-compare thead th, .pf-compare thead td { border-top: 0; font-family: var(--pf-font-display); font-size: 13px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--pf-fg-3); }
.pf-compare thead .pf-compare-us { color: var(--pf-accent); }
.pf-compare tbody th { width: 26%; font-weight: 700; color: var(--pf-fg); }
.pf-compare tbody td { width: 37%; color: var(--pf-fg-3); }
.pf-compare tbody td:last-child { color: var(--pf-fg); background: color-mix(in srgb, var(--pf-accent) 6%, transparent); border-left: 1px solid color-mix(in srgb, var(--pf-accent) 30%, transparent); }
.pf-compare thead .pf-compare-us { background: color-mix(in srgb, var(--pf-accent) 10%, transparent); border-left: 1px solid color-mix(in srgb, var(--pf-accent) 30%, transparent); }

/* "Everything else you'd expect": the table-stakes league features */
.pf-basics { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 12px; }
.pf-basics li { display: flex; flex-direction: column; gap: 4px; padding: 14px 14px 16px; border: 1px solid var(--pf-line); border-radius: var(--pf-radius); background: rgba(13, 17, 24, .8); }
.pf-basics .pf-basics-ic { width: 26px; height: 26px; margin-bottom: 4px; border-radius: 6px; display: inline-flex; align-items: center; justify-content: center; color: var(--pf-ok); background: color-mix(in srgb, var(--pf-ok) 14%, transparent); }
.pf-basics .pf-basics-ic .pf-ic { width: 16px; height: 16px; }
.pf-basics b { font-family: var(--pf-font-display); font-size: 15px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; }
.pf-basics li > span:last-child { font-size: 12.5px; color: var(--pf-fg-2); line-height: 1.45; }

/* Phones: three comparison columns don't fit at 390px, so each row becomes a
   card -- situation as its heading, both answers labelled from data-label. */
@media (max-width: 640px) {
  .pf-compare, .pf-compare tbody, .pf-compare tr, .pf-compare th, .pf-compare td { display: block; width: auto; }
  .pf-compare thead { display: none; }
  .pf-compare tbody tr + tr { border-top: 1px solid var(--pf-line); }
  .pf-compare th, .pf-compare td { border: 0; }
  .pf-compare tbody th { width: auto; padding-bottom: 4px; }
  .pf-compare tbody td { width: auto; padding-top: 6px; padding-bottom: 6px; }
  .pf-compare tbody td:last-child { border-left: 0; margin: 0 10px 12px; border-radius: var(--pf-radius-sm); padding-left: 6px; }
  .pf-compare td::before { content: attr(data-label); display: block; font-family: var(--pf-font-display); font-size: 11px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--pf-fg-3); }
  .pf-compare td:last-child::before { color: var(--pf-accent); }
  /* .pf-landing scope: outranks the later 1023px block's 2-column rule */
  .pf-landing .pf-basics { grid-template-columns: 1fr; }
}

.pf-landing-foot { margin-top: 32px; text-align: center; font-size: 12px; color: var(--pf-fg-3); }

/* Phone breakpoint (mockups' 390px frame informs this; real breakpoint is Tailwind's lg, 1024px) */
@media (max-width: 1023px) {
  .pf-landing { padding: 28px 16px 48px; }
  .pf-hero { grid-template-columns: 1fr; gap: 24px; margin-bottom: 40px; }
  .pf-hero-title { font-size: 40px; }
  .pf-lead { font-size: 15px; }
  .pf-features { grid-template-columns: 1fr; }
  .pf-steps { grid-template-columns: 1fr; }
  .pf-faq { grid-template-columns: 1fr; }
  .pf-basics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pf-section { margin-bottom: 40px; }
  .pf-section-head .pf-h1 { font-size: 22px; }
  .pf-cta-band h2 { font-size: 24px; }
  .pf-auth { padding: 20px 12px 40px; }
  .pf-rail { display: none; }
  .pf-content { padding: 12px 12px 20px; }
  /* Phone top bar: brand + clock chip only (matches the mockup's phone
     frame) -- the league switcher and username text don't fit at 390px
     alongside them. The anonymous top bar (pf-topbar-auth: just brand +
     Log in/Sign up, no league chip/clock/username) has room to spare at
     the same width, so it keeps the wordmark -- :not(:has(...)) scopes the
     hide to a topbar that actually needs the space back. */
  .pf-topbar { padding: 0 12px; gap: 8px; }
  .pf-topbar:not(:has(.pf-topbar-auth)) .pf-brand span:not(.pf-mark) { display: none; }
  .pf-ctx { display: none; }
  .pf-userchip .pf-uname { display: none; }
  .pf-h1 { font-size: 24px; }
  .pf-pagehead { margin-bottom: 10px; column-gap: 8px; }
  .pf-grid { gap: 10px; }
  .pf-timeline .tspan { padding: 4px 5px; min-height: 42px; }
  .pf-timeline .tspan .nm { font-size: 11.5px; }
  .pf-timeline .tspan .meta .pill, .pf-timeline .tspan .meta .pos { font-size: 9px; line-height: 13px; padding: 0 4px; }
  .pf-timeline .tspan .from { display: none; }
  .pf-timeline .trow { padding: 4px 6px; gap: 6px; }
  .pf-timeline .slot { width: 30px; font-size: 10.5px; }
  .pf-timeline .qhead div { font-size: 10.5px; }
  .pf-timeline .qhead div small { font-size: 8px; }
  .pf-timeline .cell { min-height: 42px; }
  .pf-timeline .chip { font-size: 11px; padding: 3px 8px 3px 5px; }
  .pf-timeline .chip .pill { display: none; }
  .pf-ladders { columns: 1; }
  .pf-ladder { margin-bottom: 10px; }
  table.pf-t { font-size: 12px; }
  table.pf-t td { padding: 6px 6px; }
  /* At phone width the 26px score eats ~165px of ~305px, starving the two
     name columns; shrink it so wrapped names get ~80px each instead of
     ~58px. */
  .pf-matchup { gap: 8px; }
  .pf-matchup .pf-sc { font-size: 21px; gap: 6px; padding: 6px 2px; }
  .pf-matchup:not(.pf-compact) .pf-tm .pf-nm { font-size: 14px; }
  .pf-matchup .pf-tm .pf-nm { font-size: 13px; }
}
@media (min-width: 1024px) {
  .pf-bottombar { display: none; }
  body:has(.pf-bottombar) .pf-content { padding-bottom: 28px; }
  /* Command-rail shell has ~860px of content: two ladder columns, not three. */
  .pf-ladders { columns: 2; }
}

/* ---------- Error pages (templates/errors/*, via pfs_web/error_pages.py) ----------
 * Same centered-card shape as the auth pages. The storm-heat "electrified"
 * frame on the status code lives in pf-theme.css alongside the other shock
 * frames. */
.pf-err-wrap { display: flex; justify-content: center; padding: 56px 16px 72px; }
.pf-err-card { width: 100%; max-width: 30rem; text-align: center; }
.pf-err-card .pf-card-b { padding: 30px 24px 26px; display: flex; flex-direction: column; align-items: center; gap: 12px; }
.pf-err-code { font-family: var(--pf-font-display); font-weight: 800; font-size: 96px; line-height: 1; letter-spacing: -.01em; padding: 6px 24px; margin-bottom: 14px; border-radius: 8px; background: var(--pf-bg); }
.pf-err-heading { margin: 0; font-family: var(--pf-font-display); font-weight: 800; font-size: 26px; line-height: 1.1; letter-spacing: .02em; text-transform: uppercase; }
.pf-err-msg { margin: 0; max-width: 24rem; color: var(--pf-fg-2); font-size: 14px; line-height: 1.5; }
.pf-err-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 10px; }
@media (max-width: 640px) {
  .pf-err-wrap { padding: 32px 12px 48px; }
  .pf-err-code { font-size: 72px; }
  .pf-err-heading { font-size: 22px; }
}

/* ---------- Waiver wire (templates/league/_waivers_body.html) ----------
 * Two columns on a wide screen -- your roster (the drop side) beside the
 * free-agent pool (the add side) -- collapsing to one stacked column below
 * the command rail's breakpoint, where they read as "roster, then pool".
 * The action bar is sticky to the bottom of the viewport because the pool
 * is hundreds of rows long: the manager picks an add somewhere deep in the
 * list and must still be able to see, and submit, the move. */
.pf-wv { display: grid; grid-template-columns: minmax(0, 340px) minmax(0, 1fr); gap: 16px; align-items: start; }
@media (max-width: 1023px) { .pf-wv { grid-template-columns: minmax(0, 1fr); } }

/* Both panels scroll internally rather than growing the page, so the two
 * lists stay side by side instead of one running a thousand pixels past
 * the other. */
.pf-wv-scroll { max-height: 60vh; overflow-y: auto; }
@media (max-width: 1023px) { .pf-wv-scroll { max-height: 26rem; } }

/* Whole row is the radio's hit target -- a 13px circle is not a tap target. */
.pf-wv-pick { cursor: pointer; }
.pf-wv-pick input[type="radio"] { accent-color: var(--pf-accent); width: 15px; height: 15px; cursor: pointer; vertical-align: -2px; }
table.pf-t tr.pf-wv-chosen > td { background: color-mix(in srgb, var(--pf-accent) 12%, transparent); }
table.pf-t tr.pf-wv-hidden { display: none; }

/* Filter strip above the pool: search box plus one toggle per position. */
.pf-wv-filters { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 10px; }
.pf-wv-filters .pf-input { width: auto; flex: 1 1 12rem; min-width: 9rem; padding: 6px 10px; font-size: 13px; }
.pf-wv-poscount { font-size: 11.5px; color: var(--pf-fg-3); margin-left: auto; white-space: nowrap; }

.pf-wv-bar { position: sticky; bottom: 0; z-index: 3; margin-top: 16px; display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center; padding: 12px 14px; border: 1px solid var(--pf-line-2); border-radius: var(--pf-radius); background: var(--pf-bg-3); box-shadow: 0 -6px 20px rgba(0, 0, 0, .35); }
.pf-wv-bar .pf-wv-summary { font-size: 13px; line-height: 1.4; min-width: 0; flex: 1 1 16rem; }
.pf-wv-bar .pf-wv-summary b { font-weight: 700; }
@media (max-width: 1023px) {
  /* Clear of the phone tab bar (.pf-bottombar) so the submit button is
   * never sitting underneath it. */
  .pf-wv-bar { bottom: 66px; }
}
/* Why the move can't be submitted yet (roster full, position cap). */
.pf-wv-blocked { color: var(--pf-warn); font-weight: 600; }

/* ---------- Coming-soon page (templates/league/trades.html) ----------
 * One centered card: kicker, headline, an animated "swap" of two players
 * between the viewer's team and a rival (they cross under a lightning bolt,
 * pause, then swap back -- nothing is official yet), a COMING SOON stamp,
 * a scrolling rumor ticker, and the way out. One layout at every width;
 * the phone rules below only tighten type and spacing. Every animation is
 * off under prefers-reduced-motion, where the chips just sit in place and
 * the ticker becomes a plain list. */
.pf-soon { display: flex; justify-content: center; padding: 12px 0 24px; }
.pf-soon-card { width: 100%; max-width: 42rem; }
.pf-soon-card .pf-card-b { padding: 26px 28px 24px; display: flex; flex-direction: column; gap: 14px; }
.pf-soon-kicker { align-self: flex-start; display: inline-flex; align-items: center; gap: 8px; padding: 4px 10px; border-radius: var(--pf-radius-pill); border: 1px solid color-mix(in srgb, var(--pf-live) 50%, transparent); background: color-mix(in srgb, var(--pf-live) 10%, transparent); color: #7dd3fc; font-family: var(--pf-font-mono); font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.pf-soon-ring { width: 7px; height: 7px; border-radius: 50%; background: var(--pf-live); animation: pf-soon-ring 1.4s ease-out infinite; }
@keyframes pf-soon-ring { 0% { box-shadow: 0 0 0 0 rgba(56, 189, 248, .7); } 100% { box-shadow: 0 0 0 9px rgba(56, 189, 248, 0); } }
.pf-soon-title { margin: 0; font-family: var(--pf-font-display); font-weight: 800; font-size: 40px; line-height: 1; letter-spacing: .01em; text-transform: uppercase; }
.pf-soon-msg { margin: 0; color: var(--pf-fg-2); font-size: 14.5px; line-height: 1.55; max-width: 34rem; }
.pf-soon-msg b { color: var(--pf-fg); }

/* Two team plates on top, the swap lane underneath. */
.pf-soon-stage { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 10px 64px; margin-top: 6px; padding: 14px 14px 38px; border: 1px solid var(--pf-line-2); border-radius: var(--pf-radius); background: radial-gradient(ellipse at 50% 70%, rgba(56, 189, 248, .12), transparent 65%), var(--pf-bg); }
.pf-soon-team { min-width: 0; padding: 8px 10px; border-radius: var(--pf-radius-sm); background: var(--pf-bg-3); border: 1px solid var(--pf-line-2); box-shadow: inset 3px 0 0 var(--pf-accent); }
.pf-soon-team.pf-soon-theirs { text-align: right; box-shadow: inset -3px 0 0 var(--pf-live); }
.pf-soon-team small { display: block; font-family: var(--pf-font-mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--pf-fg-3); }
.pf-soon-team b { display: block; font-family: var(--pf-font-display); font-size: 18px; font-weight: 800; letter-spacing: .02em; text-transform: uppercase; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* The chips travel the full lane width; `left` and `translateX` move in
 * step so 0%/100% sit flush with the lane edges whatever the chip width. */
.pf-soon-lane { grid-column: 1 / -1; position: relative; height: 92px; }
.pf-soon-chip { position: absolute; display: inline-flex; align-items: center; gap: 6px; max-width: 46%; padding: 5px 9px 5px 6px; border-radius: var(--pf-radius-sm); background: var(--pf-bg-3); border: 1px solid var(--pf-line-2); box-shadow: 0 6px 16px rgba(0, 0, 0, .45); font-weight: 700; font-size: 13px; white-space: nowrap; animation: 6s ease-in-out infinite; }
.pf-soon-chip-nm { overflow: hidden; text-overflow: ellipsis; }
.pf-soon-a { top: 0; left: 0; border-color: rgba(245, 217, 10, .55); animation-name: pf-soon-a; }
.pf-soon-b { bottom: 0; left: 100%; transform: translateX(-100%); border-color: rgba(56, 189, 248, .55); animation-name: pf-soon-b; }
@keyframes pf-soon-a {
  0%, 15% { left: 0; transform: translate(0, 0); }
  32.5% { left: 50%; transform: translate(-50%, -6px) rotate(-4deg); }
  50%, 65% { left: 100%; transform: translate(-100%, 0); }
  82.5% { left: 50%; transform: translate(-50%, -6px) rotate(4deg); }
  100% { left: 0; transform: translate(0, 0); }
}
@keyframes pf-soon-b {
  0%, 15% { left: 100%; transform: translate(-100%, 0); }
  32.5% { left: 50%; transform: translate(-50%, 6px) rotate(4deg); }
  50%, 65% { left: 0; transform: translate(0, 0); }
  82.5% { left: 50%; transform: translate(-50%, 6px) rotate(-4deg); }
  100% { left: 100%; transform: translate(-100%, 0); }
}
/* Strikes as the chips cross: they meet at 1.95s and 4.95s of their 6s loop, 3s
 * apart, so a 3s loop peaking at 50% (1.5s) needs a -2.55s offset to land on 1.95s. */
.pf-soon-bolt { position: absolute; left: 50%; top: 50%; width: 30px; height: 30px; margin: -15px 0 0 -15px; color: var(--pf-accent); opacity: .35; filter: drop-shadow(0 0 6px rgba(245, 217, 10, .6)); animation: pf-soon-bolt 3s ease-in-out -2.55s infinite; }
@keyframes pf-soon-bolt {
  0%, 35%, 65%, 100% { opacity: .35; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.45); filter: drop-shadow(0 0 14px rgba(245, 217, 10, 1)) drop-shadow(0 0 28px rgba(56, 189, 248, .8)); }
}

/* The stage's bottom padding is the stamp's room: it never covers a resting chip. */
.pf-soon-stamp { position: absolute; right: 12px; bottom: -14px; z-index: 2; padding: 4px 12px; border: 3px double var(--pf-accent); border-radius: var(--pf-radius-sm); background: rgba(6, 8, 13, .85); color: var(--pf-accent); font-family: var(--pf-font-display); font-weight: 800; font-size: 18px; letter-spacing: .14em; text-transform: uppercase; transform: rotate(-7deg); text-shadow: 0 0 12px rgba(245, 217, 10, .5); animation: pf-soon-stamp .45s cubic-bezier(.2, 1.6, .4, 1) .6s both; }
@keyframes pf-soon-stamp { from { opacity: 0; transform: rotate(-7deg) scale(2.4); } to { opacity: 1; transform: rotate(-7deg) scale(1); } }

/* Rumor ticker: the list is rendered twice so a -50% slide loops seamlessly;
 * the window clips it so it never widens the page. */
.pf-soon-ticker { display: flex; align-items: stretch; margin-top: 10px; border: 1px solid var(--pf-line-2); border-radius: var(--pf-radius-sm); background: var(--pf-bg-3); overflow: hidden; }
.pf-soon-tag { flex-shrink: 0; display: flex; align-items: center; padding: 6px 10px; background: var(--pf-danger); color: #fff; font-family: var(--pf-font-display); font-weight: 800; font-size: 13px; letter-spacing: .08em; text-transform: uppercase; white-space: nowrap; }
.pf-soon-win { flex: 1; min-width: 0; overflow: hidden; }
.pf-soon-track { display: flex; width: max-content; margin: 0; padding: 0; list-style: none; animation: pf-soon-ticker 48s linear infinite; }
.pf-soon-ticker:hover .pf-soon-track { animation-play-state: paused; }
.pf-soon-track li { padding: 7px 0; font-size: 13px; color: var(--pf-fg-2); white-space: nowrap; }
.pf-soon-track li::after { content: '\26A1'; margin: 0 16px; color: var(--pf-accent); }
@keyframes pf-soon-ticker { to { transform: translateX(-50%); } }

.pf-soon-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 4px; }

@media (max-width: 640px) {
  .pf-soon { padding: 4px 0 12px; }
  .pf-soon-card .pf-card-b { padding: 18px 14px; gap: 12px; }
  .pf-soon-title { font-size: 30px; }
  .pf-soon-msg { font-size: 14px; }
  .pf-soon-stage { gap: 8px 28px; padding: 10px 10px 36px; }
  .pf-soon-team b { font-size: 15px; }
  .pf-soon-lane { height: 84px; }
  .pf-soon-chip { max-width: 58%; font-size: 12px; }
  .pf-soon-stamp { font-size: 15px; right: 8px; }
  .pf-soon-tag { font-size: 11px; padding: 6px 8px; }
  .pf-soon-actions .pf-btn { flex: 1 1 100%; padding-top: 12px; padding-bottom: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  .pf-soon-ring, .pf-soon-chip, .pf-soon-bolt, .pf-soon-stamp, .pf-soon-track { animation: none; }
  .pf-soon-bolt { opacity: 1; }
  .pf-soon-track { width: auto; flex-direction: column; padding: 4px 10px; }
  .pf-soon-track li { white-space: normal; padding: 3px 0; }
  .pf-soon-track li::after { content: none; }
  .pf-soon-track li.pf-soon-dup { display: none; }
}
