/* Shared utility + layout layer. Loaded LAST, after page CSS - these classes
 * replace inline styles, which nothing could override, so they must win too.
 *
 * Two sections: `u-` prefixed single-property primitives, then multi-property
 * layout components. The `u-` prefix is deliberate - Tailwind's JIT generates a
 * utility the moment a template uses its name, and it never generates `u-*`, so
 * these can't collide. Component names below are checked against Tailwind and
 * the existing CSS; see the collision list in the frontend-dashboard skill.
 *
 * Scope: mechanical layout, spacing and type scales only. One-off decoration
 * (custom hex colours, shadows, transforms, grid templates) belongs in a
 * per-page CSS file under a semantic name, not here.
 *
 * Every rule here replaces an inline style verbatim. Do not add declarations to
 * an existing class - add a new one, or every page using it shifts.
 */

/* ============================ primitives ============================ */

/* display */
.u-flex{display:flex;}
.u-iflex{display:inline-flex;}
.u-grid{display:grid;}
.u-block{display:block;}
.u-iblock{display:inline-block;}
.u-inline{display:inline;}
/* No hidden-state class on purpose. The page JS reveals elements with
 * `el.style.display = ''`, which clears the inline rule and would then fall
 * through to a class that still says display:none - so an element that starts
 * hidden keeps `style="display:none"` inline. That is state, not styling. */

/* flexbox */
.u-col{flex-direction:column;}
.u-row{flex-direction:row;}
.u-wrap{flex-wrap:wrap;}
.u-grow{flex:1;}
.u-noshrink{flex-shrink:0;}
.u-ai-center{align-items:center;}
.u-ai-start{align-items:flex-start;}
.u-ai-end{align-items:flex-end;}
.u-ai-stretch{align-items:stretch;}
.u-jc-center{justify-content:center;}
.u-jc-between{justify-content:space-between;}
.u-jc-end{justify-content:flex-end;}

/* gap */
.u-gap-2{gap:2px;}
.u-gap-4{gap:4px;}
.u-gap-6{gap:6px;}
.u-gap-7{gap:7px;}
.u-gap-8{gap:8px;}
.u-gap-9{gap:9px;}
.u-gap-10{gap:10px;}
.u-gap-11{gap:11px;}
.u-gap-12{gap:12px;}
.u-gap-14{gap:14px;}
.u-gap-16{gap:16px;}
.u-gap-18{gap:18px;}

/* width - most of these are <th> column widths in data tables */
.u-w-full{width:100%;}
.u-w-13{width:13px;}
.u-w-18{width:18px;}
.u-w-28{width:28px;}
.u-w-30{width:30px;}
.u-w-32{width:32px;}
.u-w-36{width:36px;}
.u-w-38{width:38px;}
.u-w-40{width:40px;}
.u-w-44{width:44px;}
.u-w-46{width:46px;}
.u-w-48{width:48px;}
.u-w-52{width:52px;}
.u-w-56{width:56px;}
.u-w-64{width:64px;}
.u-w-72{width:72px;}
.u-w-76{width:76px;}
.u-w-80{width:80px;}
.u-w-90{width:90px;}
.u-w-96{width:96px;}
.u-w-112{width:112px;}
.u-w-128{width:128px;}
.u-w-140{width:140px;}
.u-w-144{width:144px;}
.u-w-150{width:150px;}
.u-w-160{width:160px;}
.u-w-168{width:168px;}
.u-w-176{width:176px;}
.u-w-200{width:200px;}
.u-w-224{width:224px;}

/* height */
.u-h-full{height:100%;}
.u-h-1em{height:1em;}
.u-h-4{height:4px;}
.u-h-11{height:11px;}
.u-h-18{height:18px;}
.u-h-28{height:28px;}
.u-h-30{height:30px;}
.u-h-32{height:32px;}
.u-h-36{height:36px;}
.u-h-38{height:38px;}
.u-h-40{height:40px;}
.u-h-46{height:46px;}
.u-h-48{height:48px;}
.u-h-64{height:64px;}
.u-h-76{height:76px;}
.u-h-80{height:80px;}
.u-h-96{height:96px;}

/* min / max sizing */
.u-minw-0{min-width:0;}
.u-minw-170{min-width:170px;}
.u-minw-200{min-width:200px;}
.u-minw-220{min-width:220px;}
.u-minw-240{min-width:240px;}
.u-minw-260{min-width:260px;}
.u-minw-280{min-width:280px;}
.u-minh-80{min-height:80px;}
.u-minh-60vh{min-height:60vh;}
.u-mw-none{max-width:none;}
.u-mw-280{max-width:280px;}
.u-mw-300{max-width:300px;}
.u-mw-380{max-width:380px;}
.u-mw-420{max-width:420px;}
.u-mw-520{max-width:520px;}
.u-mw-640{max-width:640px;}
.u-mw-1100{max-width:1100px;}
.u-mw-26rem{max-width:26rem;}
.u-mw-28rem{max-width:28rem;}
.u-mw-36rem{max-width:36rem;}

/* margin. Shorthands decompose as `u-m-0` + a directional class - the
 * directional rules come later in this file, so they win the tie. */
.u-m-0{margin:0;}
.u-m-0-auto{margin:0 auto;}
.u-mx-5{margin-left:5px;margin-right:5px;}
.u-mx-6{margin-left:6px;margin-right:6px;}
.u-ml-auto{margin-left:auto;}
.u-ml-4{margin-left:4px;}
.u-ml-6{margin-left:6px;}
.u-mr-4{margin-right:4px;}
.u-mr-5{margin-right:5px;}
.u-mr-6{margin-right:6px;}
.u-mr-8{margin-right:8px;}
.u-mb-0{margin-bottom:0;}
.u-mb-3{margin-bottom:3px;}
.u-mb-4{margin-bottom:4px;}
.u-mb-6{margin-bottom:6px;}
.u-mb-8{margin-bottom:8px;}
.u-mb-10{margin-bottom:10px;}
.u-mb-12{margin-bottom:12px;}
.u-mb-14{margin-bottom:14px;}
.u-mb-16{margin-bottom:16px;}
.u-mb-18{margin-bottom:18px;}
.u-mb-20{margin-bottom:20px;}
.u-mb-26{margin-bottom:26px;}
.u-mt-0{margin-top:0;}
.u-mt-2{margin-top:2px;}
.u-mt-3{margin-top:3px;}
.u-mt-4{margin-top:4px;}
.u-mt-5{margin-top:5px;}
.u-mt-8{margin-top:8px;}
.u-mt-10{margin-top:10px;}
.u-mt-12{margin-top:12px;}
.u-mt-14{margin-top:14px;}
.u-mt-16{margin-top:16px;}
.u-mt-18{margin-top:18px;}
.u-mt-20{margin-top:20px;}
.u-mt-n8{margin-top:-8px;}

/* padding */
.u-p-0{padding:0;}
.u-p-6{padding:6px;}
.u-p-8{padding:8px;}
.u-p-12{padding:12px;}
.u-p-18{padding:18px;}
.u-p-20{padding:20px;}
.u-p-24{padding:24px;}
.u-p-28{padding:28px;}
.u-px-16{padding:0 16px;}
.u-p-4-7{padding:4px 7px;}
.u-p-5-11{padding:5px 11px;}
.u-p-6-9{padding:6px 9px;}
.u-p-6-11{padding:6px 11px;}
.u-p-7-10{padding:7px 10px;}
.u-p-10-14{padding:10px 14px;}
.u-p-12-14{padding:12px 14px;}
.u-p-16-20{padding:16px 20px;}
.u-p-48-20{padding:48px 20px;}
.u-pt-2{padding-top:2px;}
.u-pt-10{padding-top:10px;}
.u-pt-12{padding-top:12px;}
.u-pb-6{padding-bottom:6px;}
.u-pl-18{padding-left:18px;}
.u-pl-34{padding-left:34px;}

/* type */
.u-fs-7{font-size:7px;}
.u-fs-9{font-size:9px;}
.u-fs-10{font-size:10px;}
.u-fs-10-5{font-size:10.5px;}
.u-fs-11{font-size:11px;}
.u-fs-11-5{font-size:11.5px;}
.u-fs-12{font-size:12px;}
.u-fs-12-5{font-size:12.5px;}
.u-fs-13{font-size:13px;}
.u-fs-13-5{font-size:13.5px;}
.u-fs-14{font-size:14px;}
.u-fs-15{font-size:15px;}
.u-fs-16{font-size:16px;}
.u-fs-17{font-size:17px;}
.u-fs-18{font-size:18px;}
.u-fs-19{font-size:19px;}
.u-fs-21{font-size:21px;}
.u-fs-22{font-size:22px;}
.u-fs-23{font-size:23px;}
.u-fs-24{font-size:24px;}
.u-fs-26{font-size:26px;}
.u-fs-34{font-size:34px;}
.u-fs-49{font-size:49px;}
.u-fw-400{font-weight:400;}
.u-fw-600{font-weight:600;}
.u-fw-700{font-weight:700;}
.u-fw-800{font-weight:800;}
.u-ls-4{letter-spacing:.4px;}
.u-ls-5{letter-spacing:.5px;}
.u-ls-6{letter-spacing:.6px;}
.u-lh-115{line-height:1.15;}
.u-lh-15{line-height:1.5;}
.u-lh-155{line-height:1.55;}
.u-lh-16{line-height:1.6;}
.u-upper{text-transform:uppercase;}
.u-center{text-align:center;}
.u-right{text-align:right;}
.u-nowrap{white-space:nowrap;}
.u-mono{font-family:monospace;}
.u-mono-ui{font-family:ui-monospace,monospace;}

/* colour - design tokens only, one-off hex goes in page CSS */
.u-accent{color:var(--accent-primary);}
.u-text{color:var(--text-primary);}
.u-text-2{color:var(--text-secondary);}
.u-text-3{color:var(--text-tertiary);}
.u-text-error{color:var(--error-text);}
.u-text-danger{color:var(--danger-main);}
.u-text-white{color:#fff;}
.u-scheme-dark{color-scheme:dark;}
.u-bg-3{background:var(--bg-tertiary);}
.u-bg-card{background:var(--bg-card);}
.u-bg-container{background:var(--bg-container);}
.u-bg-accent{background:var(--accent-primary);}
.u-bg-gold{background:var(--gold);}
.u-bg-error{background:var(--error-bg);}
.u-bg-none{background:transparent;}

/* misc */
.u-clip{overflow:hidden;}
.u-scroll-y{overflow-y:auto;}
.u-ellip{text-overflow:ellipsis;}
.u-contain{object-fit:contain;}
.u-rounded-4{border-radius:4px;}
.u-rounded-6{border-radius:6px;}
.u-rounded-7{border-radius:7px;}
.u-rounded-8{border-radius:8px;}
.u-rounded-10{border-radius:10px;}
.u-rounded-12{border-radius:12px;}
.u-rounded-14{border-radius:14px;}
.u-rounded-16{border-radius:16px;}
.u-pill{border-radius:9999px;}
.u-border{border:1px solid var(--border-color);}
.u-border-0{border:none;}
.u-border-b{border-bottom:1px solid var(--border-color);}
.u-border-t{border-top:1px solid var(--border-color);}
.u-border-l{border-left:1px solid var(--border-color);}
.u-pointer{cursor:pointer;}
.u-no-drop{cursor:not-allowed;}
.u-list-none{list-style:none;}
.u-select-all{user-select:all;}
.u-mid{vertical-align:middle;}
.u-relative{position:relative;}
.u-resize-y{resize:vertical;}
.u-pe-none{pointer-events:none;}
.u-pe-auto{pointer-events:auto;}
.u-op-50{opacity:.5;}

/* ============================ components ============================ */

/* Flex rows / stacks. Compose with .u-gap-* and .u-wrap. */
.row-center{display:flex;align-items:center;}
.row-end{margin-left:auto;display:flex;align-items:center;flex-wrap:wrap;}
.row-between{display:flex;justify-content:space-between;}
.stack{display:flex;flex-direction:column;}

/* Filter/search bar above a table: inputs bottom-aligned, wraps when narrow. */
.filter-form{display:flex;align-items:flex-end;flex-wrap:wrap;gap:12px;}
.field-grow{flex:1;min-width:220px;}

/* Truncation. min-width:0 is what makes it work inside a flex parent. */
.ellipsis{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.ellipsis-soft{min-width:0;overflow:hidden;text-overflow:ellipsis;}

/* Full-height centred panel: "nothing here yet" and gated-page notices. */
.center-viewport{display:flex;min-height:60vh;align-items:center;justify-content:center;padding:0 16px;}

.section-title{margin:8px 0 6px;font-size:19px;font-weight:700;color:var(--text-primary);}
.tile-head{font-size:16px;font-weight:700;margin-bottom:3px;}
.hint-accent{color:var(--accent-primary);font-size:12px;}

/* Square icon tile, 76px, centred glyph. */
.icon-tile-lg{width:76px;height:76px;flex-shrink:0;display:flex;align-items:center;
    justify-content:center;background:var(--bg-tertiary);border-radius:12px;}

/* Chart legend swatch: grey fill with a solid underline matching the series. */
.legend-swatch{display:inline-block;width:18px;height:11px;border-radius:2px;
    background:rgba(158,156,153,0.14);border-bottom:2px solid rgba(158,156,153,0.55);}

/* Slide-over drawer (manage/users linked panel, player compare drawer). Starts
 * off-canvas; the page's JS clears the transform to open it. Distinct from the
 * `.oc-*` off-canvas in dashboard.css, which is toggled by a wrapper class. */
.slideover-backdrop{background:rgba(0,0,0,.6);}
.slideover-panel{background:var(--bg-container);box-shadow:-8px 0 40px rgba(0,0,0,.4);
    transform:translateX(100%);transition:transform .25s ease;}

/* Amber highlight - crowns, "main league" markers. Not a theme token: it stays
 * amber under every accent. */
.u-amber{color:#f59e0b;}
.chip-amber{color:#fcd34d;background:rgba(245,158,11,.12);}
.chip-amber-strong{color:#f59e0b;background:rgba(245,158,11,.15);}

/* Visibility state, toggled from JS via classList - replaces inline
   style="display:none" so templates carry no CSS. !important so it wins over a
   component's own display (.pet-grid is display:grid, etc). */
.u-hide{display:none !important;}

/* Added while removing inline styles from templates. */
.u-ml-5{margin-left:5px;}
.u-tar{text-align:right;}
.tag-tight{padding:1px 7px;}
.u-fs-25{font-size:25px;}
.u-lh-18{line-height:1.8;}
.u-italic{font-style:italic;}
.u-op-75{opacity:.75;}
.u-inline-block{display:inline-block;}
.u-va-mid{vertical-align:middle;}
.u-success{color:var(--success-main);}
.u-tt-none{text-transform:none;letter-spacing:normal;}
.u-pad-5-8{padding:5px 8px;}
