/* browse.css — /browse hub styling (extracted from inline <style> block, sans body/nav globals
   which the shell provides). Loaded via shell ctx.css. */
.brw{width:100%;padding:22px 40px 40px}
/* hero play button (operator 2026-07-09): floats centered on the cover so
   there's an obvious "play this whole list" affordance, since the mini-
   player's own ▶ just resumes whatever was already loaded from an earlier,
   unrelated page. .me is position:relative (paper.css), so this anchors to
   the cover itself, not the wider .mhero box.
   Floating-glass style (operator: the flat dark circle blended into dark
   photo areas, "خفن"-tier glassmorphism wanted instead): blur + a bright
   rim reads consistently regardless of what's behind it, unlike relying on
   plain color contrast. @supports fallback for browsers without
   backdrop-filter, so it degrades to a plain translucent disc, not an
   invisible one. */
.brw .mheroplay{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:62px;height:62px;border-radius:50%;background:rgba(255,255,255,.16);border:1.5px solid rgba(255,255,255,.5);box-shadow:0 10px 28px rgba(0,0,0,.32),inset 0 1px 1px rgba(255,255,255,.4);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;z-index:3;transition:transform .15s,background .15s}
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  .brw .mheroplay{backdrop-filter:blur(1px) saturate(.6);-webkit-backdrop-filter:blur(1px) saturate(.6)}
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .brw .mheroplay{background:rgba(40,40,40,.55)}
}
.brw .mheroplay:hover{background:rgba(255,255,255,.26);transform:translate(-50%,-50%) scale(1.07)}
.brw .mheroplay svg{width:27px;height:27px;margin-inline-start:3px;filter:drop-shadow(0 1px 4px rgba(0,0,0,.5))}
/* play/pause faces (operator 2026-07-09: the icon never reflected real
   playback state, driven by ui.js syncQueueUI() toggling .playing on the
   button once THIS list's queue key is the one actually playing). */
.brw .mheroplay .pa{display:none;margin-inline-start:0}
.brw .mheroplay.playing .pp{display:none}
.brw .mheroplay.playing .pa{display:block}
.brw h1{font-size:clamp(1.5rem,5vw,2.1rem);font-weight:800}
.brw .sub{opacity:.6;margin-top:4px;font-size:.9rem}
.brw .sec{margin-top:30px}
.brw .sec.bare{border-top:1px solid rgba(255,255,255,.1);padding-top:26px;margin-top:26px}
.brw .sectitle{font-size:1.05rem;font-weight:800;margin-bottom:14px;opacity:.92}
.brw .subsec{margin-top:16px;padding-inline-start:13px;border-inline-start:2px solid rgba(255,255,255,.09)}
.brw .subtitle{font-size:.9rem;font-weight:700;opacity:.66;margin-bottom:10px}
/* one card style everywhere: .tile matches .grouptile — square, cover hero, WHITE
   label, same font (operator 2026-07-05: unify all browse cards, no second style). */
.brw .tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:14px}
.brw .tile{position:relative;border-radius:18px;padding:14px 16px;aspect-ratio:1;display:flex;align-items:flex-end;font-weight:800;overflow:hidden;box-shadow:0 14px 30px -12px rgba(0,0,0,.7);transition:transform .2s;color:#fff}
.brw .tile:hover{transform:translateY(-4px)}
.brw .tile .tbg{position:absolute;inset:0;background-size:cover;background-position:center;opacity:.26;z-index:0}
.brw .tile::after{content:"";position:absolute;inset:0;z-index:1;background:linear-gradient(160deg,rgba(255,255,255,.14),transparent 45%,rgba(0,0,0,.4))}
.brw .tile .lbl{position:relative;z-index:2;color:#fff;font-size:1.18rem;font-weight:800;text-shadow:0 2px 12px rgba(0,0,0,.85)}

/* GROUP tiles: single hero cover, big title. Background color, cover image, and cover opacity
   are all admin-editable per row (browse_cats.color / .cover_url / .cover_opacity) with sensible
   defaults (palette-hashed color, first-house auto cover, 26% opacity to match the .tile look). */
.brw .gtiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:14px;margin-top:14px}
.brw .grouptile{position:relative;display:block;aspect-ratio:1;border-radius:18px;overflow:hidden;box-shadow:0 14px 30px -12px rgba(0,0,0,.7);transition:transform .2s;color:#fff;background:#15151c}
.brw .grouptile:hover{transform:translateY(-4px)}
.brw .grouptile .hero{position:absolute;inset:0;background-size:cover;background-position:center;z-index:0}
.brw .grouptile .gicn{position:absolute;top:12px;inset-inline-start:14px;z-index:2;font-size:1.05rem;opacity:.78;text-shadow:0 2px 8px rgba(0,0,0,.7);line-height:1}
.brw .grouptile .ginfo{position:absolute;inset-inline-start:0;bottom:10px;max-width:calc(100% - 10px);width:fit-content;padding:2px 7px;z-index:2}
.brw .grouptile .gtitle{display:block;font-size:1.1rem;font-weight:800;line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* تازه‌ها: new-albums grid (2026-07-09), same square-cover card as the homepage's
   top-albums strip (.albtile/.alcov), but a responsive GRID like .tiles/.gtiles
   instead of a fixed-width horizontal strip, matching how every other browse
   grid on this page behaves. */
.brw .albgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:14px}
/* min-width:0: grid/flex items default to min-width:auto, which refuses to shrink
   below their CONTENT's intrinsic width. .alt/.als/.tt/.ta are all white-space:
   nowrap, so a long title ("Mituni Mage (Ft Erfan, Catchybeatz, Koorosh, & Vinak)")
   forced its whole track wider than 150px, and with auto-fill that collapsed the
   row to ~5 columns instead of filling it (operator 2026-07-09: wrapped after
   track 5 on desktop, wanted the same full-row packing as the albums grid). */
.brw .albtile{display:block;min-width:0;color:#fff}
/* .alcov is a bare <span> (no text content): without display:block it stays the
   browser default display:inline, which ignores width/aspect-ratio entirely and
   collapses to a sliver. Bit me live (2026-07-09, operator: "استایل کاورها لود نمیشه"). */
.brw .albtile .alcov{display:block;width:100%;aspect-ratio:1;border-radius:11px;background:#1b1b24 center/cover no-repeat;box-shadow:0 10px 20px -10px rgba(0,0,0,.6);margin-bottom:7px;transition:transform .2s}
.brw .albtile:hover .alcov{transform:translateY(-3px)}
.brw .albtile .alt{font-size:.94rem;font-weight:700;line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.brw .albtile .als{font-size:.78rem;opacity:.58;margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* the load-more tile sits INSIDE the grid as its own last card (operator 2026-07-09:
   "کارت آخر رو با همون استایل قبلی‌ها"), not a button below it: reuses .albtile/
   .alcov (or .trow/.th) for identical sizing, .loadmore-ic just swaps the cover
   for a dashed "+" affordance instead of a photo. <button> needs its default
   chrome reset since .albtile/.trow are normally <a>. */
.brw .loadmore-tile{cursor:pointer;background:none;border:none;font:inherit;color:inherit;text-align:inherit;padding:0;width:100%}
.brw .loadmore-tile:disabled{opacity:.5;cursor:default}
.brw .loadmore-ic{display:flex;align-items:center;justify-content:center;font-size:2.2rem;line-height:1;opacity:.5;background:none}

/* تک‌آهنگ‌ها as big-cover tiles too (operator 2026-07-09: "مثل آلبوم‌ها... کاور
   درشت و پشت‌سرهم افقی"). Keeps the EXACT .tlist[data-queue-key] > .trow markup
   (ui.js's B-01 contract builds the play queue from this: switching to .albtile
   markup would silently break click-to-play-as-queue), just restyles .trow's
   internals from a flex row to a stacked big-cover card when the list carries
   the .albgrid modifier class. */
/* shell.css sets a site-wide .tlist{direction:ltr;text-align:left} for the
   classic narrow row (track lists read better LTR: durations, mixed-script
   titles). Right for that layout, wrong for this one: .tlist.albgrid is meant
   to flow the same right-to-left as the .albgrid it sits under, so it opts
   back out (found live: computed direction was ltr, so DOM order 1 rendered
   leftmost instead of rightmost, opposite of the albums row next to it). */
.brw .tlist.albgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:14px;max-width:none;direction:rtl;text-align:right}
.brw .tlist.albgrid .trow{display:block;min-width:0;position:relative;padding:0;border-radius:0}
.brw .tlist.albgrid .trow:hover{background:none}
.brw .tlist.albgrid .trow:hover .th{transform:translateY(-3px)}
/* min-width:0 here too: .albtile's cover is a bare <span> (no intrinsic size), but
   .th is a real <img>, and a replaced element's OWN intrinsic pixel size (the
   source photo, way over 150px) still counts toward its min-content contribution
   even with width:100% set, forcing wider/fewer grid tracks than .albgrid got
   (operator 2026-07-09: wrapped after 5, unlike the albums row next to it). */
.brw .tlist.albgrid .trow .th{display:block;width:100%;height:auto;min-width:0;max-width:100%;aspect-ratio:1;border-radius:11px;margin-bottom:7px;box-shadow:0 10px 20px -10px rgba(0,0,0,.6);transition:transform .2s}
.brw .tlist.albgrid .trow .meta{flex:none;min-width:0}
/* light frosted badge, not dark: paper skin colors .rlike ink-dark (rgba(31,31,31,.4)
   via paper.css), a dark circle here would hide it. */
.brw .tlist.albgrid .trow .rlike{position:absolute;top:6px;inset-inline-start:6px;background:rgba(251,250,245,.8);border-radius:50%;color:#fff}

@media (max-width:640px){
  .brw{padding:14px 16px 28px}
  .brw .gtiles,.brw .tiles,.brw .albgrid,.brw .tlist.albgrid{grid-template-columns:1fr 1fr;gap:10px}
  .brw .gtiles{margin-top:12px}
  .brw .grouptile,.brw .tile{border-radius:14px}
  .brw .grouptile .gicn{top:10px;inset-inline-start:11px;font-size:.95rem}
  .brw .grouptile .ginfo{inset-inline-start:0;bottom:7px;max-width:calc(100% - 7px);padding:2px 6px}
  .brw .grouptile .gtitle,.brw .tile .lbl{font-size:1rem;line-height:1.2}
}

.brw .backlink{display:inline-flex;align-items:center;gap:6px;margin:0 0 14px;padding:6px 14px;border-radius:24px;background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.1);font-size:.84rem;opacity:.85;transition:opacity .15s,background .15s}
.brw .backlink:hover{opacity:1;background:rgba(255,255,255,.1)}

.brw .tlist{display:flex;flex-direction:column;gap:2px;margin-top:10px;max-width:960px}
.brw .trow{display:flex;align-items:center;gap:13px;padding:9px 10px;border-radius:13px;color:inherit;transition:background .15s}
.brw .trow:hover{background:rgba(255,255,255,.05)}
.brw .trow .th{width:52px;height:52px;border-radius:10px;object-fit:cover;background:#15151c;flex-shrink:0;box-shadow:0 6px 16px rgba(0,0,0,.4)}
.brw .trow .meta{flex:1;min-width:0}
.brw .trow .tt{font-weight:600;font-size:.94rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.brw .trow .ta{font-size:.78rem;opacity:.58;margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.brw .rlike{background:none;border:none;color:rgba(255,255,255,.4);cursor:pointer;padding:7px;flex-shrink:0;display:flex}
.brw .rlike svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2;stroke-linejoin:round}
.brw .rlike.isliked{color:#ff4d6d}
.brw .rlike.isliked svg{fill:currentColor;stroke:none}
.brw .empty{opacity:.5;padding:40px 0;text-align:center}
.brw .qptools{display:flex;gap:10px;margin:14px 0 2px;flex-wrap:wrap}
.brw .qpbtn{display:inline-flex;align-items:center;gap:8px;background:var(--accent,#e7c873);color:#fff;border:none;border-radius:30px;padding:11px 22px;font:inherit;font-weight:800;font-size:.92rem;cursor:pointer}
.brw .qpbtn.save{background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.16);color:#fff}
.brw .pager{display:flex;align-items:center;justify-content:center;gap:14px;margin:28px 0 4px}
.brw .pager a{padding:9px 18px;border-radius:30px;background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.14);font-weight:700;font-size:.9rem}
.brw .pager a.disabled{opacity:.32;pointer-events:none}
.brw .pager .pinfo{opacity:.6;font-size:.86rem;font-variant-numeric:tabular-nums}
