/* ============================================================
   Zallixor — ui.css
   Visual refresh layer. Loads AFTER style.css / gifts.css /
   market.css / programs.css and re-tunes the surface only:
   colour, type, spacing, chrome, motion.

   It changes no markup contract and no behaviour. Every rule
   here targets a class the app already renders, so removing
   this file returns the app to its previous look exactly.

   Direction — "Obsidian & Signal":
     · Near-black base so photos and video are the only light
       in the frame (the old ink-navy tinted every thumbnail).
     · Borders become white alphas, which resolve as true 1px
       hairlines at any pixel density instead of muddy navy.
     · Chrome goes flat and quiet. Glow is spent in exactly two
       places — the create button and a liked heart.
     · Counts are tabular so they don't jitter as they tick up.
   ============================================================ */

/* ── 1. Tokens ───────────────────────────────────────────── */

:root {
  --bg:        #05070c;
  --bg-2:      #02040a;
  --panel:     #0e131d;
  --panel-2:   #151b28;
  --panel-3:   #1e2637;
  --line:      rgba(255,255,255,.07);
  --line-2:    rgba(255,255,255,.13);
  --text:      #f5f7fb;
  --muted:     #98a2b8;
  --muted-2:   #6b7488;
  --accent-a:  #7c5cff;
  --accent-b:  #22d3ee;
  --accent-soft: rgba(124,92,255,.16);
  --hot:       #ff3b6b;               /* likes, hearts, live   */
  --danger:    #ff4f6b;
  --ok:        #2ee6a8;
  --amber:     #fbbf3c;

  /* Chrome on glass: the exact fill used by the top bar, the
     bottom nav and every floating overlay pill. */
  --glass:     rgba(8,11,18,.72);
  --glass-2:   rgba(8,11,18,.55);
  --on-glass:  #ffffff;

  --radius:    18px;
  --radius-sm: 12px;
  --radius-lg: 24px;

  --shadow:    0 20px 50px -12px rgba(0,0,0,.72);
  --shadow-nav: 0 -1px 0 rgba(255,255,255,.05);
  --glow:      0 6px 20px rgba(124,92,255,.30);

  --nav-h:     60px;
  --top-h:     54px;

  --dur-fast:  .12s;
  --dur-med:   .2s;
  --dur-slow:  .34s;
  --ease-out:  cubic-bezier(.2,.8,.2,1);
  --ease-spring: cubic-bezier(.34,1.56,.64,1);
}

:root[data-theme="light"] {
  --bg:        #ffffff;
  --bg-2:      #f5f6f9;
  --panel:     #ffffff;
  --panel-2:   #f2f4f8;
  --panel-3:   #e7eaf1;
  --line:      rgba(10,14,24,.09);
  --line-2:    rgba(10,14,24,.16);
  --text:      #0b0e17;
  --muted:     #5c6478;
  --muted-2:   #8d95a8;
  --accent-soft: rgba(124,92,255,.12);
  --glass:     rgba(255,255,255,.82);
  --glass-2:   rgba(255,255,255,.66);
  --on-glass:  #0b0e17;
  --shadow:    0 20px 50px -14px rgba(16,22,40,.18);
  --shadow-nav: 0 -1px 0 rgba(10,14,24,.06);
}

/* The aurora wash was strong enough to read as a purple haze over
   the whole top of the app. Kept, but at a level you notice only
   when you look for it. */
:root {
  --aurora: radial-gradient(ellipse at 22% -10%, rgba(124,92,255,.13), transparent 60%),
            radial-gradient(ellipse at 88% 0%,  rgba(34,211,238,.07), transparent 55%);
}
:root[data-theme="light"] {
  --aurora: radial-gradient(ellipse at 22% -10%, rgba(124,92,255,.07), transparent 60%),
            radial-gradient(ellipse at 88% 0%,  rgba(34,211,238,.05), transparent 55%);
}

/* ── 2. Base + type ──────────────────────────────────────── */

body {
  font-size: 15px;
  line-height: 1.48;
  letter-spacing: -.006em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h2 { letter-spacing: -.032em; font-weight: 700; }
h3 { letter-spacing: -.024em; font-weight: 650; }
h4 { letter-spacing: .085em; font-size: .72rem; color: var(--muted-2); }

.small { font-size: .795rem; letter-spacing: -.002em; }
.muted { color: var(--muted); }

/* Every number in the product — like counts, follower counts, coin
   balances, timers — sits on a fixed-width figure so it can't shuffle
   its neighbours when it changes. */
.react-summary, .post-summary, .reel-rail-label, .nav-badge, .bell-badge,
.points-bar, .count, .trend-count {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

/* Names carry the weight; handles and timestamps recede. This split is
   what makes a feed scan quickly. */
.name-row { font-weight: 650; letter-spacing: -.017em; }
.name-row.big { font-weight: 720; letter-spacing: -.028em; }

a { color: var(--accent-b); }

/* Keyboard focus was invisible against the dark panels. */
:focus-visible {
  outline: 2px solid var(--accent-b);
  outline-offset: 2px;
  border-radius: 8px;
}
.btn:focus-visible, .icon-btn:focus-visible, .nav-item:focus-visible {
  outline-offset: 3px;
}

/* ── 3. Top bar ──────────────────────────────────────────── */

.topbar {
  height: calc(var(--top-h) + var(--safe-top));
  background: var(--glass);
  /* Was blur(22px): this bar is sticky and stays composited through every
     scroll frame, so the browser was re-sampling a large blur kernel
     across its full width continuously while content scrolled underneath
     — a real cost on mid/low-end phones. 10px keeps the frosted-glass look
     (barely distinguishable from 22px at this bar's height) for a fraction
     of the per-frame cost. Same change below for .bottom-nav and
     .exp-head — the other two bars that are visible through every scroll. */
  backdrop-filter: blur(10px) saturate(1.6);
  -webkit-backdrop-filter: blur(10px) saturate(1.6);
  border-bottom: 1px solid var(--line);
  padding-left: 14px;
  padding-right: 6px;
}
.wordmark { letter-spacing: -.045em; font-weight: 700; }
.wordmark.sm { font-size: 1.22rem; }

/* Six actions in one row needs even rhythm more than it needs size.
   Uniform 36px targets, uniform 20px glyphs, 2px between. */
.topbar-right { gap: 2px; }
.topbar-right .icon-btn { width: 36px; height: 36px; border-radius: 12px; }
.icon-btn { color: var(--text); transition: background var(--dur-fast), transform var(--dur-fast); }
.icon-btn svg { width: 21px; height: 21px; stroke-width: 1.9; }
.icon-btn:active { background: var(--panel-2); transform: scale(.92); }
.icon-btn.tb { background: var(--panel-2); border: 1px solid var(--line); }

/* Unread markers: a small solid pip, not a bordered chip. */
.bell-badge, .nav-badge {
  min-width: 16px; height: 16px; padding: 0 4px;
  background: var(--hot); color: #fff;
  font-size: .62rem; font-weight: 800; line-height: 1;
  border-radius: 999px; border: 2px solid var(--bg);
  box-shadow: none;
}
.bell-badge { top: 2px; right: 2px; }

/* ── 4. Bottom nav — flush bar + the create button ───────── */

/* The floating pill read as a component sitting on the app rather
   than part of it. Every phone-native social app anchors this bar to
   the bottom edge, which also gives the feed ~14px more height. */
.bottom-nav {
  left: 0; right: 0; bottom: 0;
  transform: none;
  width: 100%; max-width: none;
  height: calc(var(--nav-h) + var(--safe-bottom));
  padding: 0 max(6px, calc((100vw - var(--maxw)) / 2)) var(--safe-bottom);
  display: flex; align-items: center; justify-content: space-around;
  background: var(--glass);
  /* See .topbar for why this dropped from 24px — same always-visible,
     every-scroll-frame cost. */
  backdrop-filter: blur(10px) saturate(1.6);
  -webkit-backdrop-filter: blur(10px) saturate(1.6);
  border: 0;
  border-top: 1px solid var(--line);
  border-radius: 0;
  box-shadow: none;
}

.nav-item {
  gap: 3px; padding: 4px 0 3px;
  color: var(--muted-2);
  transition: color var(--dur-med) var(--ease-out);
}
.nav-item .nav-icon svg { width: 23px; height: 23px; stroke-width: 1.9; }
/* Labels are back on. With six destinations the icons alone were
   guesswork — "Explore" and "Watch" both read as generic shapes. */
.nav-item .nav-label {
  display: block;
  font-size: .61rem; font-weight: 600; letter-spacing: .004em;
  line-height: 1; opacity: .95;
}
.nav-item.active { color: var(--text); }
.nav-item.active .nav-icon { transform: none; }
.nav-item.active .nav-icon svg { stroke-width: 2.4; }
.nav-item.active .nav-label { font-weight: 700; }
/* The glowing dot fought the labels for the same 4px of space. */
.nav-item.active::after { display: none; }
.nav-item:active .nav-icon { transform: scale(.88); }
.nav-item .nav-icon { transition: transform var(--dur-fast) var(--ease-spring); }

/* ── Signature: the create button ──
   Two chroma slabs — brand violet and brand cyan — offset behind a
   solid core, so the plus reads as slightly out of register. It is
   the one loud object in the shell, and it points at the thing this
   whole product runs on: someone making something. Press pushes the
   slabs further apart, then they snap back. */
/* ── Signature: the create button ──
   The one gradient fill anywhere in the chrome, running the same
   violet→cyan axis as the wordmark, the story rings and avatar
   fallbacks. Because nothing else in the shell is filled with a
   gradient, this button carries the emphasis on its own — no glow,
   no outline, no raised pedestal needed.

   The fullwidth ＋ in the markup is a thin glyph that reads soft at
   this size, so the button hides it and draws a crisp plus instead.
   The button keeps its aria-label, so nothing changes for a screen
   reader. */
.nav-create {
  position: relative;
  flex: 0 0 44px;
  width: 44px; height: 34px;
  margin-top: 0;
  border-radius: 13px;
  background: linear-gradient(135deg, #8b6cff 0%, #6d5cff 45%, #22d3ee 100%);
  color: #fff;
  box-shadow: none;
  display: grid; place-items: center;
  font-size: 0;
  transition: transform var(--dur-fast) var(--ease-spring), filter var(--dur-fast);
}
.nav-create::before {
  content: "+";
  font-family: "Inter", system-ui, sans-serif;
  font-size: 23px; font-weight: 500; line-height: 1;
}
.nav-create:active { transform: scale(.92); filter: brightness(1.1); }

/* "Create" is one object across the app: the composer's pen button
   carries the same gradient so the action is recognisable wherever
   it appears. */
.composer-pen {
  background: linear-gradient(135deg, #8b6cff 0%, #6d5cff 45%, #22d3ee 100%);
  box-shadow: none;
}

/* ── 5. Buttons, chips, fields ───────────────────────────── */

/* Primary buttons had the violet glow on every instance, which made
   nothing look important because everything did. Flat fill now; the
   glow is reserved for the create button and a liked heart. */
.btn {
  border-radius: 12px; padding: 11px 16px;
  font-weight: 650; font-size: .9rem; letter-spacing: -.008em;
  transition: transform var(--dur-fast) var(--ease-spring), filter var(--dur-fast), background var(--dur-fast);
}
.btn:active { transform: scale(.965); }
.btn-primary { background: var(--accent-a); color: #fff; box-shadow: none; }
.btn-primary:active { filter: brightness(1.12); }
.btn-ghost { background: var(--panel-2); border: 1px solid var(--line); }
.btn-danger { background: rgba(255,79,107,.12); color: var(--danger); border: 1px solid rgba(255,79,107,.26); }
.btn-sm { padding: 7px 14px; font-size: .8rem; border-radius: 999px; }
.btn-google { border-radius: 12px; font-weight: 650; }

.chip {
  border-radius: 999px; padding: 7px 14px;
  font-size: .82rem; font-weight: 600;
  background: var(--panel-2); border: 1px solid var(--line);
  transition: background var(--dur-fast), color var(--dur-fast);
}
.chip.active { background: var(--text); color: var(--bg); border-color: transparent; font-weight: 700; }

.seg {
  border-radius: 12px; font-weight: 650; font-size: .86rem;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--muted);
}
.seg.active { background: var(--text); color: var(--bg); border-color: transparent; }

.field input, .field-input, .search-input, .comment-input, .chat-input, textarea, select {
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 12px;
  font-size: .94rem;
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast), background var(--dur-fast);
}
.field input:focus, .field-input:focus, textarea:focus, select:focus, .search-input:focus {
  border-color: var(--accent-a);
  box-shadow: 0 0 0 3px var(--accent-soft);
  background: var(--panel);
}
.field label { font-size: .76rem; font-weight: 600; letter-spacing: .01em; color: var(--muted); }

.composer { border-radius: var(--radius); border: 1px solid var(--line); background: var(--panel); }
.composer-pen { border-radius: 14px; }
.composer-btn { font-size: .8rem; font-weight: 650; border-radius: 10px; }

/* ── 6. Stories ──────────────────────────────────────────── */

.stories-row { gap: 14px; padding: 4px 2px 2px; }
.story-tile { width: 68px; gap: 7px; }
/* A conic sweep starting at the brand violet — it reads as a ring
   rather than the diagonal wash a linear gradient gives, and the
   seam lands at the bottom where the avatar's shadow hides it. */
.story-ring {
  padding: 2.5px;
  background: conic-gradient(from 200deg,
    #7c5cff 0deg, #22d3ee 95deg, #2ee6a8 160deg,
    #fbbf3c 235deg, #ff3b6b 300deg, #7c5cff 360deg);
  transition: transform var(--dur-fast) var(--ease-spring);
}
.story-tile:active .story-ring { transform: scale(.93); }
.story-ring .avatar { border: 2.5px solid var(--bg); }
/* Seen stories keep the ring's shape but drop all colour, so "new"
   is legible at a glance without reading names. */
.story-tile.seen .story-ring { background: var(--line-2); }
.story-name { font-size: .69rem; font-weight: 550; max-width: 68px; color: var(--muted); }
.story-tile:not(.seen) .story-name { color: var(--text); font-weight: 600; }
.story-tile.add .story-add-plus {
  width: 21px; height: 21px; bottom: 21px; right: 5px;
  background: var(--accent-a); border: 2.5px solid var(--bg); font-weight: 700;
}

/* Story viewer: progress bars sharpened to hairlines. */
.story-bar { background: rgba(255,255,255,.28); height: 2.5px; border-radius: 999px; overflow: hidden; }
.story-bar i { background: #fff; }

/* ── 7. Feed ─────────────────────────────────────────────── */

.feed { gap: 8px; }

.post-card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 15px 8px;
}

/* On a phone the card frame is pure overhead: it steals 30px of width
   from every photo to draw a line the eye already infers from the gap.
   Below 700px the feed runs edge to edge and posts are divided by a
   single hairline. */
@media (max-width: 700px) {
  .feed { gap: 0; }
  .feed > .post-card {
    margin-inline: -14px;
    border-radius: 0;
    border-left: 0; border-right: 0; border-top: 0;
    border-bottom: 1px solid var(--line);
    padding: 14px 14px 6px;
  }
  /* Media inside a full-bleed card goes full-bleed too. */
  .feed > .post-card > .post-media-wrap {
    margin-inline: -14px;
    border-radius: 0;
    border-left: 0; border-right: 0;
  }
}

.post-head { gap: 11px; align-items: center; }
.post-head-meta .muted.small { font-size: .755rem; letter-spacing: 0; color: var(--muted-2); }
.post-menu { color: var(--muted); }

.post-body { margin: 9px 0 10px; font-size: .945rem; line-height: 1.5; }
.hashtag, .mention { color: var(--accent-b); font-weight: 600; }

.post-media-wrap {
  border-radius: 14px;
  border: 1px solid var(--line);
  margin: 4px 0 2px;
  background: var(--bg-2);
}
.post-media { max-height: 560px; }

/* IG's most-copied detail: the like count as bold body text, not a
   caption. It's the social proof, so it gets the weight. */
.post-summary {
  padding: 9px 1px 8px;
  font-size: .82rem;
  border-bottom: 1px solid var(--line);
}
.react-summary { font-weight: 700; color: var(--text); gap: 5px; align-items: center; }
.react-summary.tappable { cursor: pointer; }
.post-summary .muted.small { font-weight: 550; }

.post-actions { gap: 0; padding-top: 2px; }
.post-action {
  font-size: .795rem; font-weight: 650; letter-spacing: -.005em;
  padding: 10px 4px; border-radius: 10px; color: var(--muted);
  transition: color var(--dur-fast), transform var(--dur-fast) var(--ease-spring), background var(--dur-fast);
}
.post-action .icon.inline { width: 15px; height: 15px; vertical-align: -3px; margin-right: 3px; }
.post-action:active { transform: scale(.93); background: transparent; }
.post-action.active { color: var(--accent-b); }
.react-btn.active { color: var(--hot); }

.react-picker {
  border-radius: 999px; padding: 6px 8px;
  background: var(--panel-3); border: 1px solid var(--line-2);
  box-shadow: var(--shadow);
}
.react-opt { transition: transform var(--dur-fast) var(--ease-spring); }

.post-card.sponsored { border-color: rgba(251,191,60,.24); }
.pinned-tag { color: var(--amber); font-size: .7rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }

/* ── 8. Comments ─────────────────────────────────────────── */

.comment-thread { border-top: 1px solid var(--line); padding-top: 12px; margin-top: 4px; }
.comment-bubble { background: var(--panel-2); border-radius: 14px; padding: 8px 12px 9px; }
.comment-author { font-weight: 650; font-size: .8rem; }
.comment-text { font-size: .89rem; line-height: 1.45; }
.comment-meta { font-size: .74rem; gap: 12px; color: var(--muted-2); margin-top: 5px; }
.comment-input { border-radius: 999px; padding-inline: 15px; }

/* ── 9. Zall Clips ───────────────────────────────────────── */

.reels-screen { bottom: calc(var(--nav-h) + var(--safe-bottom)); background: #000; }

/* The Live / Zall Clips switcher was rendered behind the fixed reels
   surface, so on the Clips tab there was no visible way back to Live.
   It now floats over the video as a glass pill — which is also where
   a viewer expects to find it. */
.watch-tabs {
  position: fixed;
  top: calc(var(--top-h) + var(--safe-top) + 10px);
  left: 50%; transform: translateX(-50%);
  z-index: 14;
  width: auto; padding: 3px; gap: 2px;
  background: var(--glass-2);
  backdrop-filter: blur(18px) saturate(1.5);
  -webkit-backdrop-filter: blur(18px) saturate(1.5);
  border: 1px solid rgba(255,255,255,.14);
  border-radius: 999px;
  box-shadow: 0 6px 24px rgba(0,0,0,.4);
}
.watch-tabs .seg {
  flex: 0 0 auto;
  padding: 6px 15px;
  border: 0; background: transparent;
  color: rgba(255,255,255,.72);
  border-radius: 999px; font-size: .82rem; font-weight: 650;
}
.watch-tabs .seg.active { background: #fff; color: #05070c; font-weight: 700; }
/* Live tab content scrolls under the floating pill — give it room. */
.watch-body { padding-top: 50px; }

/* Legibility scrims. Without these, white overlay text disappears the
   moment a clip cuts to a bright frame. Two gradients, no boxes. */
.reel::before, .reel::after {
  content: ""; position: absolute; left: 0; right: 0;
  pointer-events: none; z-index: 2;
}
.reel::before { top: 0; height: 130px; background: linear-gradient(to bottom, rgba(0,0,0,.45), transparent); }
.reel::after  { bottom: 0; height: 260px; background: linear-gradient(to top, rgba(0,0,0,.62), rgba(0,0,0,.22) 42%, transparent); }
.reel-empty::before, .reel-empty::after { display: none; }

/* Action rail: the boxed, bordered buttons made a video look like a
   toolbar. Glyph and count only, sitting directly on the footage. */
.reel-rail { right: 6px; bottom: 86px; gap: 15px; }
.reel-rail-btn {
  background: transparent; border: 0; backdrop-filter: none;
  width: 46px; padding: 0; gap: 4px;
  color: #fff;
  filter: drop-shadow(0 2px 6px rgba(0,0,0,.5));
  transition: transform var(--dur-fast) var(--ease-spring);
}
.reel-rail-btn .icon { width: 27px; height: 27px; stroke-width: 1.9; }
.reel-rail-btn:active { transform: scale(.85); }
.reel-rail-label {
  font-size: .655rem; font-weight: 650; color: #fff;
  font-variant-numeric: tabular-nums; letter-spacing: -.01em;
}
.reel-rail-btn.liked {
  color: var(--hot); border: 0; box-shadow: none;
  filter: drop-shadow(0 2px 10px rgba(255,59,107,.55));
}
.reel-rail-btn.liked .icon { fill: var(--hot); stroke: var(--hot); }
/* A like should feel like it landed. */
.reel-rail-btn.liked .icon { animation: likePop .34s var(--ease-spring); }
@keyframes likePop { 0% { transform: scale(.7); } 55% { transform: scale(1.28); } 100% { transform: scale(1); } }

.reel-heart-burst .icon { fill: var(--hot); filter: drop-shadow(0 8px 30px rgba(255,59,107,.6)); }

/* Caption block: name loud, handle quiet, caption clamped to two
   lines so it never creeps up the frame. */
.reel-meta { left: 14px; right: 62px; bottom: 16px; gap: 9px; text-shadow: none; }
.reel-author-name { font-size: 1rem; font-weight: 720; letter-spacing: -.02em; }
.reel-meta .muted.small { color: rgba(255,255,255,.66); font-size: .74rem; }
.reel-desc {
  font-size: .87rem; line-height: 1.4; color: rgba(255,255,255,.94);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; max-height: none;
}
.reel-follow { border-radius: 999px; padding: 6px 15px; font-size: .78rem; }

/* Music row: a real pill with a disc that turns while the clip runs. */
.reel-music {
  background: rgba(0,0,0,.32);
  border: 1px solid rgba(255,255,255,.16);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: #fff; font-size: .755rem; font-weight: 550;
  padding: 5px 13px 5px 7px; gap: 7px;
}
.reel-music-icon {
  width: 20px; height: 20px; border-radius: 50%;
  background: linear-gradient(135deg, var(--accent-a), var(--accent-b));
  display: grid; place-items: center; flex: 0 0 auto;
  animation: discSpin 4s linear infinite;
}
.reel-music-icon .icon { width: 11px; height: 11px; color: #fff; }
@keyframes discSpin { to { transform: rotate(360deg); } }
.reel-music-title { max-width: 190px; }

.reel-progress { height: 2.5px; background: rgba(255,255,255,.16); }
.reel-progress-fill { background: #fff; box-shadow: none; }

.reels-create-btn {
  top: 10px; left: 12px;
  width: 40px; height: 40px; border-radius: 999px;
  background: var(--glass-2);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid rgba(255,255,255,.16);
  box-shadow: none;
  z-index: 15;
}
/* Clear of the floating Live / Zall Clips pill, which sits in the same
   horizontal band as the top-right watermark. */
.reel-watermark { top: 54px; }
.reel-watermark-app { letter-spacing: -.02em; }

.reel-comments-sheet { border-radius: 20px 20px 0 0; border-top: 1px solid var(--line-2); }

/* ── 10. Profile ─────────────────────────────────────────── */

.profile-cover { height: 176px; }
.profile-avatar-wrap {
  padding: 3px;
  background: conic-gradient(from 200deg, #7c5cff, #22d3ee 130deg, #7c5cff 360deg);
}
.profile-avatar-wrap .avatar { border: 3px solid var(--bg); }
.profile-head { gap: 14px; margin-top: -46px; }
.profile-bio { font-size: .92rem; line-height: 1.5; }

.profile-tabs {
  gap: 0; padding: 0 6px;
  border-bottom: 1px solid var(--line);
  background: var(--glass);
  backdrop-filter: blur(20px) saturate(1.5);
  -webkit-backdrop-filter: blur(20px) saturate(1.5);
}
.ptab {
  padding: 13px 13px;
  font-size: .845rem; font-weight: 650; letter-spacing: -.012em;
  color: var(--muted-2);
  border-bottom: 2px solid transparent;
  transition: color var(--dur-fast), border-color var(--dur-fast);
}
/* Active tab underlines in text colour, not accent — the accent line
   read as a second brand element competing with the create button. */
.ptab.active { color: var(--text); border-bottom-color: var(--text); }

/* ── 11. Messages ────────────────────────────────────────── */

.conv-list { gap: 0; }
.conv-row { padding: 10px 12px; border-radius: 14px; gap: 13px; }
.conv-row:active { background: var(--panel-2); }
.conv-top .name-row { font-weight: 600; font-size: .95rem; }
.conv-row.conv-unread .conv-top .name-row { font-weight: 750; }
.conv-preview .muted { font-size: .84rem; color: var(--muted); }
.conv-row.conv-unread .conv-preview .muted:first-of-type { color: var(--text); font-weight: 600; }
.conv-top .muted.small { font-size: .725rem; color: var(--muted-2); flex: 0 0 auto; font-variant-numeric: tabular-nums; }
.unread-badge {
  background: var(--accent-a); color: #fff;
  font-size: .66rem; font-weight: 800; line-height: 1;
  min-width: 19px; height: 19px; padding: 0 6px;
  border-radius: 999px; display: grid; place-items: center; flex: 0 0 auto;
}
.conv-section-label { font-size: .68rem; letter-spacing: .1em; color: var(--muted-2); }

.chat-header {
  background: var(--glass);
  backdrop-filter: blur(20px) saturate(1.5);
  -webkit-backdrop-filter: blur(20px) saturate(1.5);
  border-bottom: 1px solid var(--line);
}
.chat-name { font-weight: 650; letter-spacing: -.015em; }
.chat-messages { gap: 2px; padding: 14px 12px; }
.chat-composer { border-top: 1px solid var(--line); background: var(--glass); }
.chat-pill { background: var(--panel-2); border: 1px solid var(--line); border-radius: 999px; }
.chat-pill .icon-btn { color: var(--accent-b); }

.assistant-ondevice-badge {
  display: flex; align-items: center; gap: 5px; flex: 0 0 auto;
  padding: 6px 10px; border-radius: 999px; margin-left: auto;
  background: rgba(46,230,168,.14); border: 1px solid rgba(46,230,168,.30);
  color: #38e5ad; font-size: .74rem; font-weight: 650;
}
.assistant-ondevice-badge .icon { width: 13px; height: 13px; }
.assistant-ondevice-badge:active { background: rgba(46,230,168,.22); }
.typing-indicator { background: var(--panel-2); border: 1px solid var(--line); }

/* ── 12. Overlays: sheets, modals, toasts ────────────────── */

.sheet-overlay, .create-sheet-overlay, .modal-overlay {
  background: rgba(2,4,9,.62);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.sheet, .create-sheet {
  border-radius: 22px 22px 0 0;
  border-top: 1px solid var(--line-2);
  background: var(--panel);
  box-shadow: var(--shadow);
  animation: sheetUp var(--dur-slow) var(--ease-out);
}
.create-sheet-handle { background: var(--line-2); width: 36px; height: 4px; }
.create-sheet-title { font-size: 1.1rem; letter-spacing: -.025em; }
.create-opt { border-radius: 14px; transition: background var(--dur-fast); }
.create-opt:active { background: var(--panel-2); }
.create-opt-title { font-weight: 650; }
.create-opt-sub { font-size: .78rem; color: var(--muted); }
.sheet-item { font-weight: 550; border-radius: 12px; }

.modal {
  border-radius: 20px;
  border: 1px solid var(--line-2);
  background: var(--panel);
  box-shadow: var(--shadow);
}

.toast {
  background: var(--panel-3);
  border: 1px solid var(--line-2);
  border-radius: 999px;
  padding: 10px 18px;
  font-size: .85rem; font-weight: 600;
  box-shadow: var(--shadow);
}
/* ── Error toast ──
   `color` is PINNED here on purpose. .toast sets `color: var(--text)`,
   which flips with the theme, while this rule pins a dark background
   that does not. In light mode that put near-black text on a dark
   maroon fill: contrast 1.10, where 1.00 is the same colour exactly.
   The error was rendering the whole time and could only be read by
   selecting it with the cursor.

   An element that pins its own background must pin its own text
   colour too, and needs a light-theme pair. Measured after this fix:
   13.52 dark, 8.45 light, against a 4.50 minimum. */
.toast-error {
  background: #2a121c;
  border-color: rgba(255, 79, 107, .45);
  color: #ffd9df;
}
[data-theme="light"] .toast-error {
  background: #fdecef;
  border-color: rgba(214, 45, 73, .35);
  color: #8a1024;
}
.refresh-hint {
  background: var(--text); color: var(--bg);
  font-weight: 700; font-size: .76rem; box-shadow: var(--shadow);
}

/* ── 13. Loading + empty states ──────────────────────────── */

.skel-block { background: var(--panel-2); }
.empty-state { padding: 52px 24px; gap: 10px; }
.empty-icon { opacity: .45; }
.empty-icon .icon { width: 36px; height: 36px; }
.empty-state h3 { font-size: 1.02rem; }
.empty-state p { font-size: .875rem; color: var(--muted); max-width: 30ch; }

.boot-logo { filter: drop-shadow(0 10px 28px rgba(124,92,255,.4)); }
.boot-word { letter-spacing: -.045em; }
.boot-progress { background: var(--line-2); }

/* ── 14. Avatars ─────────────────────────────────────────── */

.avatar { background: var(--panel-2); }
.avatar-fallback { background: linear-gradient(140deg, var(--accent-a), var(--accent-b)); letter-spacing: -.02em; }

/* ── 15. Wider screens ───────────────────────────────────── */

@media (min-width: 701px) {
  .post-card { border-radius: var(--radius); }
  .feed { gap: 12px; }
  .icon-btn:hover { background: var(--panel-2); }
  .post-action:hover { color: var(--text); }
  .conv-row:hover { background: var(--panel-2); }
  .nav-item:hover { color: var(--text); }
}

/* ── 16. Motion preferences ──────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .boot-logo { animation: none; }
  .boot-ring { animation: none; }
  .boot-inner { animation: none; }
  .reel-music-icon { animation: none; }
}

/* ── 17. Refinements from visual review ─────────────────── */

/* Home stacks greeting + composer + stories + trending before the first
   post. Tightening the rhythm buys roughly one more post above the fold
   without removing anything from the page. */
.page { padding: 12px 14px; gap: 12px; }
.greeting h2 { font-size: 1.3rem; line-height: 1.22; }
.greeting-name { font-weight: 750; }
.points-bar { font-size: .8rem; padding: 5px 11px; }
.composer { padding: 13px 14px; }
.composer-actions { margin-top: 11px; padding-top: 11px; }
.trending-label { font-size: .84rem; }
.trend-chip { padding: 8px 13px; border-radius: 14px; min-width: 108px; }
.trend-tag { font-size: .84rem; }
.trend-count { font-size: .69rem; color: var(--muted-2); }

/* The Live / Zall Clips pill was wide enough to collide with the
   watermark in the opposite corner. Text alone identifies both tabs. */
.watch-tabs .seg .icon { display: none; }
.watch-tabs .seg { padding: 6px 18px; }

/* Rail labels were sitting flush against the screen edge. */
.reel-rail { right: 8px; gap: 14px; }

/* Cyan at full brightness fails contrast on a white background. Link
   and hashtag colour darkens in light mode; the accent itself, which is
   only ever used as a fill behind white text, stays as it is. */
:root[data-theme="light"] a,
:root[data-theme="light"] .hashtag,
:root[data-theme="light"] .mention,
:root[data-theme="light"] .link-inline,
:root[data-theme="light"] .post-action.active,
:root[data-theme="light"] .cm-react-btn.active { color: #0b8ea8; }
:root[data-theme="light"] .chat-pill .icon-btn { color: #0b8ea8; }

/* The action row relied on inline layout, so "Comment" broke onto a
   second line under its own icon on narrow phones and knocked the whole
   row out of alignment. Each action is now a centred flex row that
   never wraps. */
.post-action {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 5px; white-space: nowrap; font-size: .775rem;
  min-width: 0;
}
.post-action .icon.inline {
  width: 16px; height: 16px;
  margin-right: 0; vertical-align: 0; flex: 0 0 auto;
}
@media (max-width: 360px) {
  .post-action { font-size: .715rem; gap: 4px; padding-inline: 2px; }
  .post-action .icon.inline { width: 15px; height: 15px; }
}

/* Six top-bar actions plus the wordmark do not fit a 320px screen at
   full size. style.css already shrank them there; this restores that
   fallback, which the sizing above would otherwise have cancelled. */
@media (max-width: 380px) {
  .topbar { padding-left: 10px; padding-right: 2px; }
  .topbar-left { gap: 6px; }
  .topbar .wordmark.sm { font-size: 1.02rem; }
  .topbar-right { gap: 0; }
  .topbar-right .icon-btn { width: 31px; height: 31px; border-radius: 10px; }
  .topbar-right .icon-btn svg { width: 18px; height: 18px; }
  .nav-item .nav-label { font-size: .585rem; }
}

/* ── 18. Profile QR code ───────────────────────────────────
   Entry point on Explore, the sheet itself, and the scan result. */

/* ── The sheet ── */
.qr-overlay {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(2,4,9,.66);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  display: flex; align-items: flex-end; justify-content: center;
}
.qr-sheet {
  width: 100%; max-width: var(--maxw);
  background: var(--panel);
  border-top: 1px solid var(--line-2);
  border-radius: 24px 24px 0 0;
  padding: 10px 16px calc(20px + var(--safe-bottom));
  max-height: 94dvh; overflow-y: auto;
  box-shadow: var(--shadow);
  animation: sheetUp var(--dur-slow) var(--ease-out);
}
.qr-sheet-head { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; }
.qr-tabs {
  flex: 1; display: flex; gap: 2px; padding: 3px;
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 999px;
}
.qr-tab {
  flex: 1; padding: 8px 10px; border: 0; border-radius: 999px;
  background: transparent; color: var(--muted);
  font-size: .85rem; font-weight: 650; letter-spacing: -.01em;
  transition: background var(--dur-fast), color var(--dur-fast);
}
.qr-tab.active { background: var(--text); color: var(--bg); font-weight: 700; }
.qr-close { flex: 0 0 auto; }

/* ── "My code" card ── */
.qr-card {
  background: linear-gradient(160deg, rgba(124,92,255,.16), rgba(34,211,238,.10)), var(--panel-2);
  border: 1px solid var(--line-2);
  border-radius: var(--radius-lg);
  padding: 20px 18px 18px;
  display: flex; flex-direction: column; align-items: center; gap: 16px;
}
.qr-person { display: flex; flex-direction: column; align-items: center; gap: 9px; text-align: center; }
.qr-person-name {
  font-family: var(--font-display); font-size: 1.12rem; font-weight: 720;
  letter-spacing: -.025em; display: inline-flex; align-items: center; gap: 5px;
}
.qr-person-handle { font-size: .85rem; color: var(--muted); }
/* The code sits on white regardless of theme: inverted QR codes are read
   by fewer scanners, and a white field is what a camera expects. */
.qr-frame {
  background: #fff; border-radius: 20px; padding: 14px;
  width: 100%; max-width: 300px;
  box-shadow: 0 12px 34px rgba(0,0,0,.28);
}
.qr-canvas { width: 100%; height: auto; display: block; image-rendering: pixelated; }
.qr-hint { margin: 0; font-size: .82rem; color: var(--muted); text-align: center; max-width: 34ch; }
.qr-actions { display: flex; gap: 10px; margin-top: 14px; }
.qr-actions .btn { flex: 1; }
.qr-privacy { display: block; margin: 12px 2px 0; text-align: center; line-height: 1.45; }

/* ── Scanner ── */
.qr-scan-stage {
  position: relative; width: 100%; aspect-ratio: 1 / 1;
  max-height: 62dvh; margin: 0 auto;
  background: #000; border-radius: var(--radius-lg); overflow: hidden;
}
.qr-video { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Corner brackets rather than a full frame — they mark the target area
   without hiding any of the code the camera is trying to read. */
.qr-reticle { position: absolute; inset: 16%; pointer-events: none; }
.qr-reticle::before, .qr-reticle::after {
  content: ""; position: absolute; width: 34px; height: 34px;
  border: 3px solid #fff; border-radius: 6px;
}
.qr-reticle::before { top: 0; left: 0; border-right: 0; border-bottom: 0; }
.qr-reticle::after { bottom: 0; right: 0; border-left: 0; border-top: 0; }
.qr-scan-stage + .qr-hint { margin-top: 14px; }

/* ── Scan result ── */
.qr-result {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  text-align: center; padding: 26px 20px 20px; max-width: 340px;
}
.qr-result-name {
  font-family: var(--font-display); font-size: 1.18rem; font-weight: 720;
  letter-spacing: -.025em; display: inline-flex; align-items: center; gap: 5px;
}
.qr-result-bio { margin: 4px 0 6px; line-height: 1.45; }
.qr-result .btn { width: 100%; margin-top: 4px; }

@media (prefers-reduced-motion: reduce) { .qr-sheet { animation: none; } }

/* ── 19. Explore ───────────────────────────────────────────
   The tab was ten stacked boxes of equal weight — a scroll of cards
   rather than a place to discover anything. It now has one hero (the
   mosaic), rails instead of stacks for topics and creators, and a
   header that stays put so you can always see what you're filtering by. */

.page-discover { padding-top: 0; gap: 22px; }
/* .page sets overflow-x:hidden, which silently makes the element a scroll
   container: position:sticky inside then resolves against .page's own
   scrollport instead of the viewport, so the header both refused to stick
   and sat 54px too low. body already clips horizontal overflow, so this
   element doesn't need to. */
.page-discover { overflow: visible; }

/* ── Sticky header ── */
.exp-head {
  position: sticky;
  top: calc(var(--top-h) + var(--safe-top));
  z-index: 12;
  margin: 0 -14px;
  padding: 12px 14px 10px;
  background: var(--glass);
  /* See .topbar for why this dropped from 22px — same always-visible,
     every-scroll-frame cost. */
  backdrop-filter: blur(10px) saturate(1.6);
  -webkit-backdrop-filter: blur(10px) saturate(1.6);
  border-bottom: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 11px;
}
.exp-head-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.exp-head-top h2 { font-size: 1.5rem; letter-spacing: -.038em; }

.exp-search-row { display: flex; gap: 8px; align-items: stretch; }
.disc-search {
  flex: 1; min-width: 0;
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 999px; padding: 11px 16px; gap: 9px;
  color: var(--muted);
}
.disc-search .icon { width: 18px; height: 18px; }
.disc-search-ph { font-size: .88rem; font-weight: 500; }
.exp-scan {
  flex: 0 0 46px; width: 46px; border-radius: 999px; border: 0;
  display: grid; place-items: center; color: #fff;
  background: linear-gradient(135deg, #8b6cff 0%, #6d5cff 45%, #22d3ee 100%);
  transition: transform var(--dur-fast) var(--ease-spring);
}
.exp-scan:active { transform: scale(.92); }
.exp-scan .icon { width: 21px; height: 21px; }

.page-discover .chip-row { margin: 0 -14px; padding: 0 14px 2px; }

/* ── Section furniture ── */
.exp-section { display: flex; flex-direction: column; gap: 11px; }
.exp-h { margin: 0; font-size: 1.02rem; font-weight: 700; letter-spacing: -.028em; }
.exp-h-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.exp-h-note {
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 999px; padding: 3px 11px; font-weight: 650; color: var(--muted);
}

/* ── Trending rail ── */
.topic-rail {
  display: flex; gap: 10px; overflow-x: auto;
  scrollbar-width: none; margin: 0 -14px; padding: 2px 14px;
  scroll-snap-type: x proximity;
}
.topic-rail::-webkit-scrollbar { display: none; }
.topic-rail .topic-card {
  flex: 0 0 auto; width: 148px; scroll-snap-align: start;
  display: flex; flex-direction: column; gap: 3px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 16px; padding: 13px 14px 12px;
  position: relative; overflow: hidden; cursor: pointer;
}
.topic-rail .topic-card::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(140deg, rgba(124,92,255,.20), transparent 62%);
  pointer-events: none;
}
/* Each card takes a different hue off the brand wheel, so a rail of six
   reads as six things rather than one thing repeated. */
.topic-rail .topic-card:nth-child(6n+2)::before { background: linear-gradient(140deg, rgba(34,211,238,.20), transparent 62%); }
.topic-rail .topic-card:nth-child(6n+3)::before { background: linear-gradient(140deg, rgba(255,59,107,.18), transparent 62%); }
.topic-rail .topic-card:nth-child(6n+4)::before { background: linear-gradient(140deg, rgba(46,230,168,.18), transparent 62%); }
.topic-rail .topic-card:nth-child(6n+5)::before { background: linear-gradient(140deg, rgba(251,191,60,.18), transparent 62%); }
.topic-rank {
  position: relative; font-size: .66rem; font-weight: 800;
  color: var(--muted-2); letter-spacing: .04em;
}
.topic-rail .topic-card strong {
  position: relative; font-family: var(--font-display);
  font-size: .96rem; font-weight: 700; letter-spacing: -.02em; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.topic-rail .topic-card span.muted { position: relative; font-size: .72rem; }

/* ── Hero mosaic ──
   Three columns, but every seventh tile runs 2x2. The grid stays a
   perfect rectangle because the double tile consumes exactly the four
   cells its neighbours would have filled. */
.popular-grid.mosaic {
  display: grid; grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 1fr; gap: 4px;
  /* Dense is required, not cosmetic: once a big tile is pinned to the
     right-hand columns, sparse placement cannot go back and fill the cell
     to its left, so the grid grew an extra row with a hole in it. */
  grid-auto-flow: row dense;
  margin: 0 -14px; padding: 0;
}
.popular-grid.mosaic > .popular-cell { border-radius: 0; aspect-ratio: 1; }
/* Period of six: one 2x2 (four cells) plus five singles fills exactly
   three rows of three, so the grid never leaves a hole. A seven-item
   period does not divide evenly and left ragged gaps down the page. */
.popular-grid.mosaic > .popular-cell:nth-child(6n + 1) { grid-column: span 2; grid-row: span 2; }
/* Alternate which side the big tile sits on, so the rhythm reads as
   deliberate rather than as a column that happens to be wider. */
.popular-grid.mosaic > .popular-cell:nth-child(12n + 7) { grid-column: 2 / span 2; }
.popular-cell { position: relative; background: var(--panel-2); overflow: hidden; cursor: pointer; }
.popular-cell img, .popular-cell video { width: 100%; height: 100%; object-fit: cover; }
/* A text-only post still deserves a readable tile rather than a grey box. */
.popular-text {
  padding: 12px; font-size: .78rem; line-height: 1.4; color: var(--text);
  background: linear-gradient(150deg, var(--panel-3), var(--panel-2));
  height: 100%; display: -webkit-box; -webkit-line-clamp: 5;
  -webkit-box-orient: vertical; overflow: hidden;
}
.popular-likes {
  position: absolute; left: 7px; bottom: 6px;
  display: inline-flex; align-items: center; gap: 3px;
  font-size: .7rem; font-weight: 700; color: #fff;
  background: none; padding: 0; border-radius: 0;
  text-shadow: 0 1px 4px rgba(0,0,0,.8);
  font-variant-numeric: tabular-nums;
}
.popular-likes .icon { width: 13px; height: 13px; fill: #fff; }
/* Enough scrim to keep the count legible over a bright photo. */
.popular-cell::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 44px;
  background: linear-gradient(to top, rgba(0,0,0,.42), transparent);
  pointer-events: none;
}
.popular-cell:has(.popular-text)::after { display: none; }

/* ── Creator rail ── */
.creator-rail {
  display: flex; gap: 10px; overflow-x: auto; scrollbar-width: none;
  margin: 0 -14px; padding: 2px 14px; scroll-snap-type: x proximity;
}
.creator-rail::-webkit-scrollbar { display: none; }
.creator-card {
  flex: 0 0 auto; width: 138px; scroll-snap-align: start;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 18px; padding: 16px 12px 13px; cursor: pointer;
  text-align: center;
}
.creator-name {
  font-weight: 650; font-size: .86rem; letter-spacing: -.015em;
  display: inline-flex; align-items: center; gap: 3px;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.creator-handle { font-size: .74rem; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.creator-card .btn { width: 100%; margin-top: 4px; }
.creator-card.skel-card { gap: 8px; align-items: center; }

/* ── Shortcuts ── */
.exp-shortcuts { display: flex; gap: 8px; }
.exp-shortcut {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 16px; padding: 14px 8px 12px;
  color: var(--text); font-size: .78rem; font-weight: 650;
  transition: background var(--dur-fast);
}
.exp-shortcut:active { background: var(--panel-2); }
.exp-shortcut-ico {
  width: 38px; height: 38px; border-radius: 12px;
  display: grid; place-items: center; color: #fff;
}
.exp-shortcut-ico .icon { width: 19px; height: 19px; }
.sc-pages  { background: linear-gradient(140deg, #6d5cff, #8b6cff); }
.sc-comms  { background: linear-gradient(140deg, #22d3ee, #2ee6a8); }
.sc-market { background: linear-gradient(140deg, #fbbf3c, #ff8a3c); }

/* ── Fresh media ── */
.explore-grid { gap: 4px; margin: 0 -14px; }
.explore-cell { border-radius: 0; }

/* ── Communities ── */
.comm-list { display: flex; flex-direction: column; gap: 6px; }
.mini-comm {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 14px; padding: 12px 14px; align-items: center;
}
.mini-comm strong { font-weight: 650; letter-spacing: -.015em; }

@media (min-width: 701px) {
  .exp-head { margin: 0; border-radius: 0 0 var(--radius) var(--radius); }
  .popular-grid.mosaic, .explore-grid { margin: 0; border-radius: var(--radius); overflow: hidden; }
  .creator-rail, .topic-rail, .page-discover .chip-row { margin: 0; padding-inline: 0; }
  .exp-shortcut:hover, .mini-comm:hover { background: var(--panel-2); }
}

/* Empty states and fallback messages are children of the grids and rails,
   so without this they inherit a 1:1 tile and get squeezed into a single
   column. Let them span the full width and size to their content. */
.popular-grid > .empty-state, .explore-grid > .empty-state,
.popular-grid > .muted, .explore-grid > .muted {
  grid-column: 1 / -1; aspect-ratio: auto; border-radius: 0;
}
.popular-grid > .empty-state::after, .explore-grid > .empty-state::after { display: none; }
.topic-rail > .muted, .creator-rail > .muted, .comm-list > .empty-state {
  flex: 1 1 auto; padding: 14px 2px;
}
.creator-rail > .empty-state, .topic-rail > .empty-state { flex: 1 1 100%; }

/* On white, a 20% alpha wash all but disappears. Light mode gets a solid
   tinted fill and a matching border instead, so the rail still reads as
   six distinct topics rather than six blank cards. */
:root[data-theme="light"] .topic-rail .topic-card { background: #f4f2ff; border-color: rgba(124,92,255,.22); }
:root[data-theme="light"] .topic-rail .topic-card::before { background: linear-gradient(140deg, rgba(124,92,255,.16), transparent 70%); }
:root[data-theme="light"] .topic-rail .topic-card:nth-child(6n+2) { background: #eafaff; border-color: rgba(14,165,190,.22); }
:root[data-theme="light"] .topic-rail .topic-card:nth-child(6n+3) { background: #fff0f4; border-color: rgba(255,59,107,.20); }
:root[data-theme="light"] .topic-rail .topic-card:nth-child(6n+4) { background: #eafaf3; border-color: rgba(16,185,129,.20); }
:root[data-theme="light"] .topic-rail .topic-card:nth-child(6n+5) { background: #fff7e8; border-color: rgba(217,146,17,.24); }
:root[data-theme="light"] .topic-rail .topic-card:nth-child(6n) { background: #f1f2ff; border-color: rgba(99,102,241,.20); }

/* Recovery link on the sign-in form. */
.auth-forgot { text-align: right; margin: -6px 2px 0; font-size: .82rem; }
.auth-forgot a { color: var(--muted); font-weight: 600; }
.auth-forgot a:hover { color: var(--accent-b); }

/* ── 20. Account switcher ──────────────────────────────────
   Sessions live in Firebase's own store, one per account; this is only
   the list that picks between them. */

.acc-overlay {
  position: fixed; inset: 0; z-index: 92;
  background: rgba(2,4,9,.66);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  display: flex; align-items: flex-end; justify-content: center;
}
.acc-sheet {
  width: 100%; max-width: var(--maxw);
  background: var(--panel);
  border-top: 1px solid var(--line-2);
  border-radius: 24px 24px 0 0;
  padding: 10px 14px calc(18px + var(--safe-bottom));
  box-shadow: var(--shadow);
  animation: sheetUp var(--dur-slow) var(--ease-out);
  max-height: 88dvh; overflow-y: auto;
}
.acc-handle-bar { width: 36px; height: 4px; border-radius: 999px; background: var(--line-2); margin: 2px auto 12px; }
.acc-title { font-size: 1.08rem; letter-spacing: -.026em; margin: 0 4px 12px; }
.acc-list { display: flex; flex-direction: column; gap: 4px; }

.acc-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; border-radius: 16px; cursor: pointer;
  border: 1px solid transparent;
  transition: background var(--dur-fast);
}
.acc-row:active { background: var(--panel-2); }
/* The account you're on is stated outright rather than implied — on a
   phone that has three of them, "which am I posting as" is the whole
   question this sheet exists to answer. */
.acc-row.active { background: var(--accent-soft); border-color: rgba(124,92,255,.28); }
.acc-meta { flex: 1; min-width: 0; }
.acc-name {
  font-weight: 650; letter-spacing: -.015em;
  display: inline-flex; align-items: center; gap: 4px;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.acc-handle { font-size: .78rem; }
.acc-current { flex: 0 0 auto; color: var(--accent-a); display: inline-flex; }
.acc-current .icon { width: 21px; height: 21px; }
.acc-switch-hint { flex: 0 0 auto; font-weight: 650; color: var(--muted-2); }

.acc-add-btn {
  width: 100%; display: flex; align-items: center; gap: 12px;
  background: transparent; border: 1px dashed var(--line-2);
  border-radius: 16px; padding: 13px 12px; margin-top: 10px;
  color: var(--text); font-size: .9rem; font-weight: 650;
}
.acc-add-btn:active { background: var(--panel-2); }
.acc-add-ico {
  width: 46px; height: 46px; border-radius: 50%; flex: 0 0 auto;
  display: grid; place-items: center; color: var(--accent-a);
  background: var(--panel-2); border: 1px solid var(--line);
}
.acc-add-ico .icon { width: 20px; height: 20px; }
.acc-note { display: block; margin: 12px 4px 0; line-height: 1.45; }

/* ── Add-account dialog ── */
.acc-add { display: flex; flex-direction: column; gap: 10px; max-width: 380px; }
.acc-add h3 { margin: 0; }
.acc-add p.muted { margin: 0 0 4px; line-height: 1.45; }
.acc-error {
  margin: 0; font-size: .82rem; font-weight: 600; color: var(--danger);
  background: rgba(255,79,107,.10); border: 1px solid rgba(255,79,107,.26);
  border-radius: 10px; padding: 9px 12px;
}
.acc-or {
  display: flex; align-items: center; gap: 10px;
  color: var(--muted-2); font-size: .76rem; margin: 2px 0;
}
.acc-or::before, .acc-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }

@media (prefers-reduced-motion: reduce) { .acc-sheet { animation: none; } }

/* ── 21. Menu (Settings) ───────────────────────────────────
   Fourteen sections of identical grey rows behind one flat profile row.
   The page now opens with a hero and the four things people actually
   come here to do, and every section carries its own colour so the list
   can be scanned instead of read. */

.page-settings { gap: 16px; }
.settings-title { font-size: 1.5rem; letter-spacing: -.038em; margin: 2px 2px 2px; }

/* ── Hero ── */
.settings-hero {
  position: relative; overflow: hidden;
  width: 100%; text-align: left;
  background: var(--panel); border: 1px solid var(--line-2);
  border-radius: var(--radius-lg); padding: 16px;
  color: var(--text);
  display: flex; flex-direction: column; gap: 14px;
  transition: transform var(--dur-fast) var(--ease-spring);
}
.settings-hero:active { transform: scale(.985); }
/* A single brand wash across the top, clipped by the card. Cheap to
   paint and it stops the card reading as one more grey row. */
.sh-wash {
  position: absolute; inset: 0 0 auto; height: 96px;
  background:
    radial-gradient(120% 120% at 12% 0%, rgba(124,92,255,.42), transparent 62%),
    radial-gradient(100% 120% at 88% 0%, rgba(34,211,238,.30), transparent 60%);
  pointer-events: none;
}
.sh-top { position: relative; display: flex; align-items: center; gap: 13px; }
.sh-id { flex: 1; min-width: 0; }
.sh-name {
  font-family: var(--font-display); font-size: 1.14rem; font-weight: 720;
  letter-spacing: -.028em; display: inline-flex; align-items: center; gap: 5px;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sh-handle { font-size: .85rem; color: var(--muted); margin-top: 1px; }
.sh-chev { flex: 0 0 auto; color: var(--muted); display: inline-flex; }
.sh-chev .icon { width: 20px; height: 20px; }
.sh-stats {
  position: relative; display: flex; gap: 22px;
  padding-top: 13px; border-top: 1px solid var(--line);
}
.sh-stat { display: flex; align-items: baseline; gap: 5px; }
.sh-stat strong { font-size: 1.02rem; font-weight: 750; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }

/* ── Quick tiles ── */
/* ── Settings search bar ── */
.settings-search {
  position: relative; display: flex; align-items: center;
  margin: 4px 2px 14px;
}
.settings-search-icon {
  position: absolute; left: 14px; display: flex; color: var(--muted-2);
  pointer-events: none;
}
.settings-search-icon .icon, .settings-search-icon svg { width: 17px; height: 17px; }
.settings-search-input {
  width: 100%; padding: 11px 14px 11px 40px; border-radius: 14px;
  background: var(--panel); border: 1px solid var(--line);
  color: var(--text); font-size: .92rem; font-weight: 500;
}
.settings-search-input::placeholder { color: var(--muted-2); }
.settings-search-input:focus { outline: none; border-color: var(--accent-b); }
.settings-search-input::-webkit-search-cancel-button { cursor: pointer; }
.settings-search-empty { text-align: center; padding: 18px 0 4px; }

.why-seeing-list { margin: 4px 0 12px; padding-left: 20px; display: flex; flex-direction: column; gap: 8px; }
.why-seeing-list li { font-size: .9rem; line-height: 1.4; }

.settings-quick { display: flex; gap: 8px; }
.settings-quick-tile {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 16px; padding: 13px 6px 11px;
  color: var(--text);
  transition: background var(--dur-fast), transform var(--dur-fast) var(--ease-spring);
}
.settings-quick-tile:active { transform: scale(.94); background: var(--panel-2); }
.qt-ico {
  width: 38px; height: 38px; border-radius: 12px;
  display: grid; place-items: center; color: #fff;
}
.qt-ico .icon { width: 19px; height: 19px; }
.qt-label { font-size: .74rem; font-weight: 650; letter-spacing: -.005em; }
.qt-wallet .qt-ico { background: linear-gradient(140deg, #fbbf3c, #ff8a3c); }
.qt-saved  .qt-ico { background: linear-gradient(140deg, #6d5cff, #8b6cff); }
.qt-stats  .qt-ico { background: linear-gradient(140deg, #22d3ee, #2ee6a8); }
.qt-switch .qt-ico { background: linear-gradient(140deg, #ff3b6b, #b04cff); }
.qt-scan   .qt-ico { background: linear-gradient(140deg, #2ee6a8, #22d3ee); }

/* ── Sections ── */
.settings-section { margin: 0 0 6px; }
.settings-section-head { gap: 9px; margin: 0 4px 9px; }
.settings-section-icon {
  width: 30px; height: 30px; border-radius: 10px;
  background: var(--panel-2); border: 1px solid var(--line);
}
.settings-section-icon .icon { width: 16px; height: 16px; }
.settings-section h4 { font-size: .7rem; letter-spacing: .1em; color: var(--muted-2); font-weight: 700; }

/* One hue per section. The tint is carried on the chip only, so the rows
   underneath stay quiet and the colour acts as a bookmark, not decoration. */
.ss-coin        { background: rgba(251,191,60,.14); border-color: rgba(251,191,60,.30); }
.ss-coin .icon  { color: #fbbf3c; }
.ss-gem         { background: rgba(176,76,255,.14); border-color: rgba(176,76,255,.30); }
.ss-gem .icon   { color: #c07cff; }
.ss-user        { background: rgba(124,92,255,.14); border-color: rgba(124,92,255,.30); }
.ss-user .icon  { color: #9b83ff; }
.ss-sun         { background: rgba(255,138,60,.14); border-color: rgba(255,138,60,.30); }
.ss-sun .icon   { color: #ff9d55; }
.ss-lock        { background: rgba(34,211,238,.14); border-color: rgba(34,211,238,.30); }
.ss-lock .icon  { color: #3fdcf0; }
.ss-shield      { background: rgba(46,230,168,.14); border-color: rgba(46,230,168,.30); }
.ss-shield .icon{ color: #38e5ad; }
.ss-volume2     { background: rgba(99,102,241,.16); border-color: rgba(99,102,241,.32); }
.ss-volume2 .icon { color: #8b8dff; }
.ss-bell        { background: rgba(255,59,107,.14); border-color: rgba(255,59,107,.30); }
.ss-bell .icon  { color: #ff6b90; }
.ss-shieldAlert { background: rgba(255,79,107,.14); border-color: rgba(255,79,107,.30); }
.ss-shieldAlert .icon { color: #ff7590; }
.ss-ban         { background: rgba(148,163,184,.16); border-color: rgba(148,163,184,.30); }
.ss-ban .icon   { color: #a7b2c6; }
.ss-image       { background: rgba(34,211,238,.14); border-color: rgba(34,211,238,.30); }
.ss-image .icon { color: #3fdcf0; }
.ss-box         { background: rgba(124,92,255,.14); border-color: rgba(124,92,255,.30); }
.ss-box .icon   { color: #9b83ff; }
.ss-info        { background: rgba(148,163,184,.14); border-color: rgba(148,163,184,.28); }
.ss-info .icon  { color: #a7b2c6; }
.ss-arrowLeft   { background: rgba(255,79,107,.14); border-color: rgba(255,79,107,.30); }
.ss-arrowLeft .icon { color: #ff7590; }
.ss-accessibility { background: rgba(56,189,248,.14); border-color: rgba(56,189,248,.30); }
.ss-accessibility .icon { color: #6fd4fb; }
.ss-sparkles    { background: rgba(233,120,255,.14); border-color: rgba(233,120,255,.30); }
.ss-sparkles .icon { color: #e97cff; }

/* ── Rows ── */
.settings-section > :not(.settings-section-head) { background: var(--panel); }
.settings-section > :not(.settings-section-head):first-of-type { border-top-left-radius: 16px; border-top-right-radius: 16px; }
.settings-section > :not(.settings-section-head):last-child { border-bottom-left-radius: 16px; border-bottom-right-radius: 16px; }
.settings-row {
  padding: 13px 14px; font-size: .92rem; font-weight: 550;
  border-bottom: 1px solid var(--line);
  transition: background var(--dur-fast);
}
.settings-section > .settings-row:last-of-type,
.settings-section > .link-row:last-of-type { border-bottom: 0; }
.link-row:active { background: var(--panel-2); }
.settings-row .info-val, .settings-chevron { font-size: .86rem; }
.settings-chevron .icon { width: 16px; height: 16px; }
.settings-row .no-tap, .settings-row:disabled { opacity: 1; }

.settings-note { border-radius: 16px; padding: 13px 14px; }
.settings-note-icon .icon { color: var(--accent-a); }

/* "You can change this again in N days" caption under Name/Username */
.settings-cooldown-note { padding: 0 14px 12px; margin: -6px 0 0; font-size: .78rem; }

/* ── Username edit modal: live availability indicator ── */
.un-modal { width: 100%; max-width: 360px; padding: 20px; display: flex; flex-direction: column; gap: 14px; }
.un-field { gap: 6px; }
.un-input-row {
  display: flex; align-items: center; gap: 8px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 13px;
  padding: 4px 12px;
}
.un-input-row:focus-within { border-color: var(--accent-a); box-shadow: 0 0 0 3px var(--accent-soft); }
.un-at { color: var(--muted); font-weight: 600; }
.un-input { background: transparent; border: 0; padding: 9px 0; box-shadow: none !important; }
.un-input:focus { border: 0; box-shadow: none !important; }
.un-status-icon { display: flex; align-items: center; justify-content: center; width: 20px; height: 20px; flex: 0 0 auto; }
.un-status-icon .icon { width: 20px; height: 20px; }
.un-ok { color: #2ecc71; }
.un-bad { color: var(--danger); }
.un-status-text { min-height: 1.1em; margin: 0; padding-left: 2px; }
.un-ok-text { color: #2ecc71; }
.un-bad-text { color: var(--danger); }
.un-spinner {
  width: 15px; height: 15px; border-radius: 50%; display: inline-block;
  border: 2px solid var(--line-2); border-top-color: var(--accent-a);
  animation: spin .6s linear infinite;
}

/* The delete control is the one destructive thing on the page; give it
   room so it can't be hit while aiming for Sign out. */
.settings-section > .btn-danger { margin-top: 10px; }
.contacts { line-height: 1.5; padding: 12px 14px 4px; }

@media (min-width: 701px) {
  .settings-quick-tile:hover, .link-row:hover { background: var(--panel-2); }
}

/* ── Plus & verification cards ──
   Two offers that must not be mistaken for each other, built on one
   shape so they still read as a pair. What changes between them is the
   mark and the accent — gold crown for the subscription, the real badge
   seal for verification — because that is the single thing a person
   needs to tell apart before reading a word. Everything else (type
   scale, tick column, spacing) is shared.

   Replaces .plus-card, which was a section title sitting above a card
   that repeated the same title. */
.upsell-card {
  position: relative; overflow: hidden;
  border-radius: 20px !important;
  padding: 16px 16px 14px;
  display: flex; flex-direction: column; gap: 14px;
  border: 1px solid var(--line);
}
.settings-section > .upsell-card + .upsell-card { margin-top: 10px; }
.uc-plus   { border-color: rgba(245,180,41,.30); }
.uc-verify { border-color: rgba(47,216,164,.26); }

/* The only decorative element on either card, and it is carrying
   information: which of the two you are looking at. */
.uc-wash { position: absolute; inset: 0; pointer-events: none; }
.uc-plus .uc-wash {
  background:
    radial-gradient(118% 140% at 92% -12%, rgba(245,180,41,.20), transparent 60%),
    radial-gradient(110% 130% at 0% 110%, rgba(124,92,255,.20), transparent 58%);
}
.uc-verify .uc-wash {
  background:
    radial-gradient(118% 140% at 92% -12%, rgba(47,216,164,.17), transparent 60%),
    radial-gradient(110% 130% at 0% 110%, rgba(34,199,224,.15), transparent 58%);
}

.uc-head { position: relative; display: flex; align-items: flex-start; gap: 12px; }
.uc-mark {
  width: 44px; height: 44px; border-radius: 14px; flex: 0 0 auto;
  display: grid; place-items: center;
}
.uc-mark-plus   { background: rgba(245,180,41,.14); border: 1px solid rgba(245,180,41,.34); }
.uc-mark-verify { background: rgba(47,216,164,.12); border: 1px solid rgba(47,216,164,.30); }
.uc-mark .plus-crown-icon, .uc-mark .verified-badge { width: 24px; height: 24px; }
.uc-headline { flex: 1 1 auto; min-width: 0; padding-top: 2px; }
.uc-title { font-family: var(--font-display); font-size: 1.1rem; font-weight: 720; letter-spacing: -.028em; }
.uc-sub { font-size: .8rem; color: var(--muted); margin-top: 3px; line-height: 1.35; }

/* Term now, status later: one chip carries "30 days", "Active" and
   "Under review", so the card never has to grow a new element when the
   pending-request lookup lands. */
.uc-flag {
  flex: 0 0 auto; align-self: flex-start; white-space: nowrap;
  font-size: .67rem; font-weight: 700; letter-spacing: .03em;
  padding: 4px 9px; border-radius: 999px;
  background: var(--panel-2); border: 1px solid var(--line-2); color: var(--muted);
}
.uc-flag-on   { background: rgba(47,216,164,.14); border-color: rgba(47,216,164,.34); color: var(--ok); }
.uc-flag-wait { background: rgba(246,181,69,.14); border-color: rgba(246,181,69,.34); color: var(--amber); }

.uc-perks { position: relative; list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.uc-perks li { display: flex; align-items: center; gap: 10px; font-size: .875rem; line-height: 1.32; }
.uc-perk-ico {
  flex: 0 0 auto; width: 27px; height: 27px; border-radius: 9px;
  display: grid; place-items: center;
  background: var(--panel-2); border: 1px solid var(--line);
}
.uc-perk-ico .icon { width: 14px; height: 14px; }
.uc-plus   .uc-perk-ico .icon { color: #f5b429; }
.uc-verify .uc-perk-ico .icon { color: var(--ok); }
.uc-perk-text { flex: 1 1 auto; min-width: 0; }
.uc-perk-done { flex: 0 0 auto; display: inline-flex; color: var(--ok); }
.uc-perk-done .icon { width: 15px; height: 15px; stroke-width: 2.6; }

.uc-cta { position: relative; margin: 0; }
.uc-foot { position: relative; margin: 0; text-align: center; line-height: 1.45; }

/* The free route out of a paid card. It belongs inside the verification
   card rather than in a section of its own: it answers the same question
   ("can I have a badge"), just differently. */
.uc-alt {
  position: relative; display: flex; align-items: center; gap: 11px; width: 100%;
  text-align: left; padding: 11px 12px; border-radius: 14px;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
  font-size: inherit; transition: background var(--dur-fast);
}
.uc-alt:active { background: var(--panel-3); }
.uc-alt-mark { flex: 0 0 auto; display: inline-flex; }
.uc-alt-mark .verified-badge { width: 20px; height: 20px; }
.uc-alt-text { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.uc-alt-title { font-size: .84rem; font-weight: 640; }
.uc-alt-chev { flex: 0 0 auto; display: inline-flex; color: var(--muted-2); }
.uc-alt-chev .icon { width: 16px; height: 16px; }

@media (min-width: 701px) {
  .uc-alt:hover { background: var(--panel-3); }
}

/* ── 22. Profile ───────────────────────────────────────────
   The page had the right content in the wrong order of importance:
   a flat cover, an avatar the same size as a post avatar, and six
   stats crushed into one row. Rebuilt around a proper masthead. */

.page-profile { padding: 0 0 8px; gap: 0; }

/* ── Cover ──
   Taller, and when there's no photo it gets a branded mesh instead of a
   flat grey panel — an empty profile shouldn't look broken. */
.profile-cover {
  height: 196px;
  background:
    radial-gradient(120% 130% at 15% 0%, rgba(124,92,255,.55), transparent 60%),
    radial-gradient(110% 120% at 85% 10%, rgba(34,211,238,.40), transparent 58%),
    radial-gradient(90% 110% at 60% 100%, rgba(255,59,107,.22), transparent 62%),
    var(--panel-2);
  background-size: cover; background-position: center;
  position: relative;
}
/* Two scrims: one to lift the buttons off a bright photo, one to hand the
   cover over to the page background so the avatar has something to sit on. */
.profile-cover::before {
  content: ""; position: absolute; inset: 0 0 auto; height: 84px;
  background: linear-gradient(to bottom, rgba(0,0,0,.34), transparent);
  pointer-events: none;
}
.profile-cover::after {
  background: linear-gradient(180deg, transparent 38%, color-mix(in srgb, var(--bg) 62%, transparent) 72%, var(--bg) 100%);
}
.cover-edit, .profile-settings-btn {
  background: rgba(8,11,18,.46); border: 1px solid rgba(255,255,255,.16);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  color: #fff; border-radius: 999px; width: 38px; height: 38px;
  display: grid; place-items: center;
  transition: transform var(--dur-fast) var(--ease-spring);
}
.cover-edit:active, .profile-settings-btn:active { transform: scale(.9); }
.cover-edit .icon, .profile-settings-btn .icon { width: 18px; height: 18px; }

/* ── Masthead ── */
.profile-head { align-items: flex-end; gap: 14px; padding: 0 16px; margin-top: -54px; }
.profile-avatar-wrap {
  padding: 3.5px; border-radius: 50%;
  background: conic-gradient(from 200deg, #7c5cff, #22d3ee 120deg, #ff3b6b 240deg, #7c5cff 360deg);
  box-shadow: 0 12px 30px -8px rgba(0,0,0,.6);
}
.profile-avatar-wrap .avatar { border: 3.5px solid var(--bg); }
.profile-id { padding-bottom: 2px; }
.name-row.big { font-size: 1.34rem; font-weight: 760; letter-spacing: -.034em; }
.profile-id > .muted { font-size: .88rem; margin-top: 1px; }
.level-badge {
  margin-top: 7px; font-size: .68rem; font-weight: 700;
  letter-spacing: .03em; text-transform: uppercase;
  background: linear-gradient(135deg, rgba(124,92,255,.22), rgba(34,211,238,.18));
  border: 1px solid rgba(124,92,255,.34); color: var(--text);
  padding: 4px 10px; border-radius: 999px;
  display: inline-flex; align-items: center; gap: 4px;
}
.level-badge .icon { width: 12px; height: 12px; color: var(--amber); }

/* ── Actions ──
   Was: style.css set each button to width:100% (block, stacked) while this
   file added margin-left:8px to every button after the first — a 100%-wide
   block plus a left margin has nowhere to go but past the right edge. Fixed
   by making the row an actual flex column and using `gap` for spacing
   instead of margins, so buttons stay full-width AND inside the container. */
.profile-cta-row { padding: 14px 16px 0; display: flex; flex-direction: column; gap: 8px; }
.profile-cta { display: flex; gap: 8px; }
.profile-cta .btn, .profile-cta-row > .btn { flex: 1; width: 100%; }
.profile-cta-row .btn-sm { padding: 10px 14px; font-size: .85rem; border-radius: 12px; }

.profile-bio { padding: 14px 16px 0; font-size: .92rem; line-height: 1.5; }
.profile-links, .about-row { padding: 8px 16px 0; }
.profile-link { color: var(--accent-b); }

/* ── Stats ──
   Three headline figures in a card, the rest as chips underneath. */
.stats-wrap { padding: 16px; display: flex; flex-direction: column; gap: 10px; }
.stats-row {
  display: grid; grid-template-columns: repeat(3, 1fr);
  padding: 14px 4px; gap: 0;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 18px;
  justify-content: initial;
}
.stats-row .stat {
  gap: 3px; padding: 0 6px; border-radius: 0;
  border-right: 1px solid var(--line);
}
.stats-row .stat:last-child { border-right: 0; }
.stat strong { font-size: 1.3rem; font-weight: 760; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
.stat span { font-size: .655rem; letter-spacing: .09em; color: var(--muted-2); font-weight: 700; }
.stat.clickable:active { background: transparent; opacity: .55; }

.stats-chips { display: flex; gap: 7px; flex-wrap: wrap; }
.stat-chip {
  display: inline-flex; align-items: baseline; gap: 5px;
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 999px; padding: 6px 12px;
}
.stat-chip strong { font-size: .86rem; font-weight: 750; font-variant-numeric: tabular-nums; }
.stat-chip span { font-size: .74rem; color: var(--muted); font-weight: 550; }
.stat-chip.clickable { cursor: pointer; }
.stat-chip.clickable:active { background: var(--panel-3); }

/* ── Cards below the masthead ── */
.streak-box, .ach-section, .ai-about {
  margin: 0 16px 12px; padding: 16px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 18px;
}
.streak-head strong { font-size: 1rem; letter-spacing: -.02em; display: inline-flex; align-items: center; gap: 6px; }
.streak-head strong .icon { color: #ff8a3c; }
.streak-day.on::before {
  background: linear-gradient(140deg, #8b6cff, #22d3ee);
  border-color: transparent; box-shadow: 0 0 12px rgba(124,92,255,.45);
}
.ach-section h4, .ai-about h4 { margin: 0 0 12px; font-size: .7rem; letter-spacing: .1em; color: var(--muted-2); }
.ach-badge.locked { opacity: .34; filter: grayscale(1); }
.ach-icon {
  width: 44px; height: 44px; border-radius: 14px;
  background: var(--panel-2); border: 1px solid var(--line);
  display: grid; place-items: center;
}
.ach-badge:not(.locked) .ach-icon {
  background: linear-gradient(140deg, rgba(124,92,255,.20), rgba(34,211,238,.14));
  border-color: rgba(124,92,255,.32);
}
.ach-label { font-size: .66rem; font-weight: 650; }

.quick-tiles { padding: 0 16px 12px; gap: 8px; }

@media (min-width: 701px) {
  .stat.clickable:hover { opacity: .7; }
  .stat-chip.clickable:hover { background: var(--panel-3); }
}

/* ── Profile: fixes from the first render ── */

/* Both cover controls belong together at the top. Bottom-right put the
   camera in the same band as the avatar and name, which read as clutter
   attached to the person rather than a control on the photo. */
.cover-edit { top: 10px; right: 56px; bottom: auto; }

/* "Get verified" wrapped onto two lines and knocked the row out of
   alignment. Buttons keep their label on one line and wrap as whole
   buttons instead. */
.profile-cta { flex-wrap: wrap; gap: 8px; }
.profile-cta > * { flex: 1 1 auto; min-width: 104px; }
.profile-cta .btn, .profile-cta-row .btn {
  white-space: nowrap; font-size: .82rem; padding: 10px 12px;
}

/* Five achievements at a fixed 72px overflowed a 390px screen, so the
   last one sat off the edge looking cut off rather than scrollable.
   A five-column grid fits them all at any width. */
.ach-row { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; overflow: visible; }
.ach-badge { width: auto; gap: 7px; }
.ach-badge .ach-icon { width: 100%; max-width: 54px; aspect-ratio: 1; height: auto; border-radius: 15px; }
.ach-badge .ach-icon .icon { width: 24px; height: 24px; }
.ach-badge .ach-label { font-size: .63rem; text-align: center; line-height: 1.2; }

/* ── 23. Menu drawer ───────────────────────────────────────
   Slides in from the right so the hamburger, which lives at the top
   right, opens toward itself rather than across the screen. */

.menu-overlay {
  position: fixed; inset: 0; z-index: 95;
  background: rgba(2,4,9,.62);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  display: flex; justify-content: flex-end;
  animation: menuFade var(--dur-med) ease;
}
.menu-overlay.closing { animation: menuFade var(--dur-med) ease reverse forwards; }
@keyframes menuFade { from { opacity: 0; } to { opacity: 1; } }

.menu-panel {
  width: min(88vw, 380px); height: 100%;
  background: var(--bg);
  border-left: 1px solid var(--line-2);
  box-shadow: -24px 0 60px -20px rgba(0,0,0,.7);
  padding: calc(10px + var(--safe-top)) 16px calc(20px + var(--safe-bottom));
  overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 16px;
  animation: menuIn var(--dur-slow) var(--ease-out);
}
.menu-panel.closing { animation: menuOut var(--dur-med) var(--ease-out) forwards; }
@keyframes menuIn { from { transform: translateX(100%); } to { transform: none; } }
@keyframes menuOut { from { transform: none; } to { transform: translateX(100%); } }

.menu-head { display: flex; align-items: center; justify-content: space-between; }
.menu-title { font-family: var(--font-display); font-size: 1.32rem; font-weight: 750; letter-spacing: -.035em; }

/* ── Who you're acting as ── */
.menu-me { display: flex; gap: 8px; align-items: stretch; }
.menu-me-main {
  flex: 1; min-width: 0;
  display: flex; align-items: center; gap: 12px; text-align: left;
  background: var(--panel); border: 1px solid var(--line-2);
  border-radius: 18px; padding: 11px 13px; color: var(--text);
  position: relative; overflow: hidden;
}
.menu-me-main::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(110% 130% at 8% 0%, rgba(124,92,255,.20), transparent 62%);
}
.menu-me-main > * { position: relative; }
.menu-me-main:active { background: var(--panel-2); }
.menu-me-meta { flex: 1; min-width: 0; }
.menu-me-name {
  font-weight: 680; letter-spacing: -.018em;
  display: inline-flex; align-items: center; gap: 4px;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.menu-me-handle { margin-top: 1px; }
.menu-me-switch {
  flex: 0 0 52px; border-radius: 18px;
  background: var(--panel); border: 1px solid var(--line-2);
  color: var(--accent-a); display: grid; place-items: center;
  transition: background var(--dur-fast);
}
.menu-me-switch:active { background: var(--panel-2); }
.menu-me-switch .icon { width: 21px; height: 21px; }

/* ── Shortcut grid ── */
.menu-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.menu-tile {
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 16px; padding: 13px 6px 11px;
  color: var(--text);
  transition: background var(--dur-fast), transform var(--dur-fast) var(--ease-spring);
}
.menu-tile:active { transform: scale(.94); background: var(--panel-2); }
.menu-tile-ico {
  width: 36px; height: 36px; border-radius: 12px;
  display: grid; place-items: center; color: #fff;
}
.menu-tile-ico .icon { width: 18px; height: 18px; }
.menu-tile-label {
  font-size: .71rem; font-weight: 650; letter-spacing: -.005em;
  text-align: center; line-height: 1.2;
}
/* Four tones rather than twelve: the colour groups related destinations
   (money, selling, your stuff, community) instead of decorating each one. */
.mi-amber  { background: linear-gradient(140deg, #fbbf3c, #ff8a3c); }
.mi-violet { background: linear-gradient(140deg, #6d5cff, #8b6cff); }
.mi-cyan   { background: linear-gradient(140deg, #22d3ee, #3b9dff); }
.mi-mint   { background: linear-gradient(140deg, #2ee6a8, #22d3ee); }
.mi-rose   { background: linear-gradient(140deg, #ff3b6b, #ff6b90); }
.mi-slate  { background: linear-gradient(140deg, #64748b, #94a3b8); }
.mi-gold   { background: linear-gradient(140deg, #c07cff, #b04cff); }

/* ── List rows ── */
.menu-list {
  display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 18px; overflow: hidden;
}
.menu-row {
  display: flex; align-items: center; gap: 12px;
  padding: 13px 14px; background: transparent; border: 0;
  border-bottom: 1px solid var(--line);
  color: var(--text); font-size: .9rem; font-weight: 600; text-align: left;
  transition: background var(--dur-fast);
}
.menu-row:last-child { border-bottom: 0; }
.menu-row:active { background: var(--panel-2); }
.menu-row-ico { flex: 0 0 auto; display: inline-flex; color: var(--muted); }
.menu-row-ico .icon { width: 19px; height: 19px; }
.menu-row-label { flex: 1; min-width: 0; }
.menu-row-chev { flex: 0 0 auto; color: var(--muted-2); display: inline-flex; }
.menu-row-chev .icon { width: 16px; height: 16px; }
.menu-row-danger { color: var(--danger); }
.menu-row-danger .menu-row-ico { color: var(--danger); }

.menu-foot { text-align: center; margin: auto 0 0; padding-top: 8px; }

@media (min-width: 701px) {
  .menu-tile:hover, .menu-row:hover, .menu-me-main:hover { background: var(--panel-2); }
}
@media (prefers-reduced-motion: reduce) {
  .menu-panel, .menu-overlay { animation: none !important; }
}

/* ── 24. Chat ──────────────────────────────────────────────
   Rebuilt on WhatsApp's structure: a patterned wallpaper instead of a
   flat panel, bubbles with real tails, the time and ticks tucked inside
   the bubble, and a circular send button outside the pill.

   The accent moves from Messenger blue (#0084ff, which the chat used
   throughout and which clashed with everything else in the app) to the
   brand violet. Copying WhatsApp's green would have made this one screen
   look borrowed from a different product. */

.chat-screen { background: var(--bg); }

/* ── Wallpaper ──
   Built from three tiny repeating gradients rather than an image: it
   costs no request, scales to any density, and stays under the text at
   ~3% contrast so it reads as texture, never as noise. */
.chat-messages {
  background-color: var(--bg-2);
  background-image:
    radial-gradient(circle at 12% 18%, rgba(255,255,255,.030) 0 2px, transparent 2px),
    radial-gradient(circle at 62% 48%, rgba(255,255,255,.024) 0 2px, transparent 2px),
    radial-gradient(circle at 84% 78%, rgba(124,92,255,.045) 0 3px, transparent 3px);
  background-size: 92px 92px, 124px 124px, 156px 156px;
  padding: 14px 10px 16px;
  gap: 2px;
}
:root[data-theme="light"] .chat-messages {
  background-color: #efeae2;   /* the warm paper tone chat screens use */
  background-image:
    radial-gradient(circle at 12% 18%, rgba(10,14,24,.030) 0 2px, transparent 2px),
    radial-gradient(circle at 62% 48%, rgba(10,14,24,.022) 0 2px, transparent 2px),
    radial-gradient(circle at 84% 78%, rgba(124,92,255,.055) 0 3px, transparent 3px);
}

/* ── Bubbles ── */
.bubble {
  max-width: 82%; padding: 7px 10px 6px;
  border-radius: 14px; font-size: .935rem; line-height: 1.4;
  box-shadow: 0 1px 1px rgba(0,0,0,.18);
}
.bubble.mine {
  background: linear-gradient(180deg, #5b46e0, #4c39c9);
  color: #fff; border-bottom-right-radius: 4px;
}
.bubble.theirs {
  background: var(--panel); color: var(--text);
  border-bottom-left-radius: 4px;
}
:root[data-theme="light"] .bubble.theirs { background: #ffffff; }
:root[data-theme="light"] .bubble { box-shadow: 0 1px 1px rgba(10,14,24,.10); }

/* The tail. Only the last bubble in a run gets one — a tail on every
   bubble is what makes a stacked conversation look serrated. */
/* Drawn with borders, not clip-path: path() — that renders as a square
   nub in several engines and is not worth the risk on a screen this
   central. Two borders make a clean triangle everywhere. */
.bubble::after {
  content: ""; position: absolute; bottom: 0;
  width: 0; height: 0; pointer-events: none;
}
.bubble.mine::after {
  right: -7px;
  border-left: 8px solid #4c39c9;
  border-bottom: 7px solid transparent;
}
.bubble.theirs::after {
  left: -7px;
  border-right: 8px solid var(--panel);
  border-bottom: 7px solid transparent;
}
:root[data-theme="light"] .bubble.theirs::after { border-right-color: #ffffff; }
/* Hide the tail on any bubble immediately followed by one from the same
   side, so only the run's final bubble points at the speaker. */
.bubble.mine:has(+ .bubble.mine)::after,
.bubble.theirs:has(+ .bubble.theirs)::after { display: none; }
.bubble.mine:has(+ .bubble.mine) { border-bottom-right-radius: 14px; }
.bubble.theirs:has(+ .bubble.theirs) { border-bottom-left-radius: 14px; }
.bubble + .bubble { margin-top: 2px; }

.bubble-sender { font-size: .75rem; font-weight: 700; margin-bottom: 3px; color: var(--accent-b); }
.bubble-meta { font-size: .62rem; margin: 4px 0 -1px 10px; opacity: .68; }
.bubble.mine .bubble-meta { opacity: .82; }
.bubble-ticks .icon { width: 14px; height: 14px; }
.bubble-ticks.seen { color: #4fd6ff; opacity: 1; }
.bubble.mine .bubble-ticks.seen { color: #86e6ff; }
.bubble-img { border-radius: 9px; }
.bubble-media { padding: 3px 3px 4px; }
.bubble-pinned { box-shadow: 0 0 0 2px var(--accent-a); }
@keyframes bubble-flash { 0%, 100% { box-shadow: none; } 20%, 60% { box-shadow: 0 0 0 3px var(--accent-a); } }

.bubble.mine .msg-reaction-chip { background: rgba(255,255,255,.22); }
.msg-reaction-chip.mine { border-color: var(--accent-a); }

/* ── Day divider ── */
.chat-day-divider span {
  background: var(--panel-3); color: var(--muted);
  border: 1px solid var(--line);
  font-size: .69rem; font-weight: 650; letter-spacing: .02em;
  padding: 4px 12px; border-radius: 999px;
  box-shadow: 0 1px 2px rgba(0,0,0,.2);
}

/* ── Header ── */
.chat-header {
  padding: 8px 6px 8px 2px; gap: 4px;
  background: var(--glass);
  border-bottom: 1px solid var(--line);
}
.chat-name { font-size: 1rem; font-weight: 680; letter-spacing: -.018em; }
.chat-presence { font-size: .73rem; }
.chat-presence.is-online { color: var(--ok); font-weight: 600; }

/* ── Composer ── */
.chat-composer { background: var(--bg); border-top: 1px solid var(--line); gap: 7px; }
.chat-pill {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 24px; padding: 2px 4px;
}
/* 44px, was 38 - see the matching note in style.css. This copy is the
   one that actually applies, because ui.css loads last. */
.chat-pill .icon-btn { color: var(--muted); width: 44px; height: 44px; }
.chat-pill .icon-btn:active { color: var(--accent-a); }
.chat-input { font-size: .94rem; padding: 10px 4px; }
.send-btn { background: var(--accent-a); color: #fff; box-shadow: 0 4px 14px rgba(124,92,255,.35); }
.send-btn:active { transform: scale(.92); }
.mic-btn { background: var(--panel); border: 1px solid var(--line); color: var(--accent-a); }
.send-btn, .mic-btn { transition: transform var(--dur-fast) var(--ease-spring); }

.pin-banner { background: color-mix(in srgb, var(--accent-a) 12%, var(--panel)); }
.pin-banner .icon { color: var(--accent-a); }
.typing-indicator { background: var(--panel); border: 1px solid var(--line); box-shadow: 0 1px 1px rgba(0,0,0,.18); }

/* ── 25. Assistant floating button ── */
.ai-fab {
  position: fixed; right: 16px;
  bottom: calc(var(--nav-h) + var(--safe-bottom) + 16px);
  z-index: 38;
  width: 54px; height: 54px; border-radius: 50%; border: 0;
  display: grid; place-items: center;
  background: linear-gradient(140deg, #8b6cff 0%, #6d5cff 45%, #22d3ee 100%);
  color: #fff;
  box-shadow: 0 10px 26px -6px rgba(109,92,255,.62), 0 2px 8px rgba(0,0,0,.4);
  transition: transform var(--dur-fast) var(--ease-spring), opacity var(--dur-med);
}
.ai-fab:active { transform: scale(.9); }
.ai-fab-ico { display: grid; place-items: center; }
.ai-fab-ico .icon { width: 24px; height: 24px; }
/* A slow halo so the button reads as alive without animating constantly
   in the corner of the eye. Motion-reduced users get a static ring. */
.ai-fab-glow {
  position: absolute; inset: -4px; border-radius: 50%;
  border: 2px solid rgba(139,108,255,.45);
  animation: aiPulse 2.8s ease-in-out infinite;
  pointer-events: none;
}
@keyframes aiPulse {
  0%, 100% { transform: scale(1); opacity: .55; }
  50% { transform: scale(1.14); opacity: 0; }
}

/* Out of the way where it would cover content or duplicate an action:
   full-screen video, and any open chat (which has its own composer). */
:root.vt-fullscreen .ai-fab,
:root.lv-room-open .ai-fab,
:root.chat-open .ai-fab { opacity: 0; pointer-events: none; transform: scale(.7); }

@media (prefers-reduced-motion: reduce) {
  .ai-fab-glow { animation: none; opacity: .5; }
}

/* ── 26. Reaction picker ───────────────────────────────────
   Tap the Like button to like; press and hold to open this. */

/* Twelve reactions do not fit one row on a phone (12 x 40px = 480px), and
   scrolling sideways inside a popup you are still pressing is a gesture
   fight. Six per row, two rows, everything reachable without moving. */
.react-picker {
  display: grid; grid-template-columns: repeat(6, 1fr);
  gap: 2px; padding: 8px 10px;
  bottom: 48px; left: 0;
  width: max-content; max-width: calc(100vw - 28px);
  background: var(--panel-3);
  border: 1px solid var(--line-2);
  border-radius: 24px;
  box-shadow: 0 14px 34px -8px rgba(0,0,0,.66);
  transform-origin: 20% bottom;
  animation: reactIn .22s var(--ease-spring);
  z-index: 20;
}
@keyframes reactIn {
  from { transform: scale(.6) translateY(10px); opacity: 0; }
  to   { transform: scale(1) translateY(0); opacity: 1; }
}
.react-opt {
  width: 40px; height: 40px; padding: 0;
  font-size: 1.6rem; line-height: 1;
  border-radius: 50%;
  display: grid; place-items: center;
  background: transparent; border: 0;
  transition: transform var(--dur-fast) var(--ease-spring);
}
/* Each emoji lands a beat after the one before it, so the row unfurls
   instead of appearing all at once. */
.react-picker .react-opt { animation: reactPop .26s var(--ease-spring) backwards; }
.react-picker .react-opt:nth-child(1) { animation-delay: .00s; }
.react-picker .react-opt:nth-child(2) { animation-delay: .02s; }
.react-picker .react-opt:nth-child(3) { animation-delay: .04s; }
.react-picker .react-opt:nth-child(4) { animation-delay: .06s; }
.react-picker .react-opt:nth-child(5) { animation-delay: .08s; }
.react-picker .react-opt:nth-child(6) { animation-delay: .10s; }
.react-picker .react-opt:nth-child(7)  { animation-delay: .12s; }
.react-picker .react-opt:nth-child(8)  { animation-delay: .14s; }
.react-picker .react-opt:nth-child(9)  { animation-delay: .16s; }
.react-picker .react-opt:nth-child(10) { animation-delay: .18s; }
.react-picker .react-opt:nth-child(11) { animation-delay: .20s; }
.react-picker .react-opt:nth-child(n+12) { animation-delay: .22s; }
@keyframes reactPop {
  from { transform: scale(.3) translateY(8px); opacity: 0; }
  to   { transform: scale(1) translateY(0); opacity: 1; }
}
.react-opt:hover, .react-opt:active { transform: scale(1.32) translateY(-4px); background: transparent; }

/* The picker on a comment is smaller and opens just below the link. */
.cm-react-wrap .react-picker { bottom: auto; top: 24px; left: -6px; padding: 5px 7px; }
.cm-react-wrap .react-opt { width: 34px; height: 34px; font-size: 1.32rem; }

/* The button keeps whatever colour its reaction carries (set inline from
   the REACTIONS table), so the class must not override it. */
.react-btn.active, .cm-react-btn.active { color: inherit; }
.react-btn { transition: color var(--dur-fast); }
/* Long-press shouldn't select the label text on the way. */
.react-btn, .cm-react-btn, .react-opt { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }

@media (prefers-reduced-motion: reduce) {
  .react-picker, .react-picker .react-opt { animation: none; }
}

/* ── 27. Friends on the profile ────────────────────────────
   users/{uid}.friends is owner-read only, so this rail exists on your
   own profile only; other people's profiles keep the count they always
   had. */

.friends-section {
  margin: 0 16px 12px; padding: 16px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 18px;
}
.fr-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.fr-head h4 { margin: 0; font-size: .7rem; letter-spacing: .1em; color: var(--muted-2); font-weight: 700; }
.fr-all {
  background: transparent; border: 0; padding: 0;
  color: var(--accent-b); font-size: .8rem; font-weight: 650;
}
.fr-rail {
  display: flex; gap: 12px; overflow-x: auto;
  scrollbar-width: none; padding-bottom: 2px;
  scroll-snap-type: x proximity;
}
.fr-rail::-webkit-scrollbar { display: none; }
.fr-card {
  flex: 0 0 auto; width: 62px; scroll-snap-align: start;
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-spring);
}
.fr-card:active { transform: scale(.93); }
.fr-name {
  font-size: .71rem; font-weight: 600; text-align: center;
  max-width: 62px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 2px; justify-content: center;
}
.fr-name .verified-badge { width: 11px; height: 11px; }
/* The overflow card counts what the rail can't show, so the rail never
   silently hides friends. */
.fr-more-ico {
  width: 56px; height: 56px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--panel-2); border: 1px dashed var(--line-2);
  color: var(--accent-a); font-weight: 750; font-size: .9rem;
  font-variant-numeric: tabular-nums;
}
.fr-empty { margin: 0; line-height: 1.45; }
.fr-card.skel-card { gap: 8px; align-items: center; }

/* ── 28. Viewport stability ────────────────────────────────
   Switching from Zall Clips to a tab made the whole shell jump.

   Cause: the Clips surface is position:fixed, so the document has no
   scrollable content while it is up (scrollHeight == viewport). Opening
   a tab makes the document scrollable again. On a phone that flips the
   browser's dynamic viewport as the URL bar collapses, and 100dvh —
   which the shell's height is measured in — re-resolves underneath
   everything. On desktop a scrollbar appears and narrows the page. Both
   read as the layout shuddering. */

/* svh is the SMALL viewport height: the value with the URL bar showing.
   Unlike dvh it does not change as the bar hides, so the shell keeps one
   height for the whole session. */
.view {
  min-height: calc(100svh - var(--top-h) - var(--safe-top) - var(--nav-h) - var(--safe-bottom));
}
/* Reserve the scrollbar's width whether or not one is showing, so a page
   becoming scrollable can't shove the layout sideways. */
html { scrollbar-gutter: stable; }

/* content-visibility:auto skips off-screen cards and sizes them from
   contain-intrinsic-size — a flat 200px guess. As you scrolled, each card
   resolved to its real height and moved everything below it, which is the
   second half of the judder. The `auto` keyword makes the browser
   remember each element's last real size and reuse it, so a card that has
   been measured once never guesses again. */
.post-card, .conv-row, .user-row, .group-card, .notif-row {
  contain-intrinsic-size: auto 200px;
}

/* The Clips surface is fixed and self-contained; nothing behind it should
   scroll or bounce while it is up. */
:root[data-route="watch"] { overscroll-behavior-y: none; }

/* ── 29. Desktop hover hints ───────────────────────────────
   Only ever created on a mouse device — see js/tooltip.js. */

.tooltip {
  position: fixed; z-index: 200;
  /* max-content sizes to one line whenever the label fits, and only wraps
     once it exceeds max-width — so short hints never break awkwardly and
     long ones never run off the screen. */
  width: max-content;
  max-width: min(240px, calc(100vw - 24px));
  padding: 6px 10px;
  background: var(--panel-3);
  color: var(--text);
  border: 1px solid var(--line-2);
  border-radius: 9px;
  font-size: .76rem; font-weight: 600; letter-spacing: -.005em;
  line-height: 1.35;
  box-shadow: 0 10px 26px -8px rgba(0,0,0,.7);
  pointer-events: none;            /* never intercept the hover it describes */
  opacity: 0; transform: translateY(3px);
  transition: opacity .13s ease, transform .13s ease;
}
.tooltip.show { opacity: 1; transform: none; }
/* A small pointer so it reads as attached to the control rather than
   floating near it. Flips with the tooltip when it opens downward. */
.tooltip::after {
  content: ""; position: absolute; left: 50%; margin-left: -5px;
  border: 5px solid transparent;
}
.tooltip:not(.below)::after { top: 100%; border-top-color: var(--panel-3); }
.tooltip.below::after { bottom: 100%; border-bottom-color: var(--panel-3); }

/* NB: `text-wrap: balance` must NOT be set here. `white-space` is a
   shorthand that includes text-wrap-mode, so any later text-wrap
   declaration silently re-enables wrapping and breaks short labels
   across two lines. max-content sizing above handles this instead. */
@media (max-width: 380px) { .tooltip { display: none; } }

@media (prefers-reduced-motion: reduce) {
  .tooltip { transition: none; }
}

/* ── 30. Media loading ─────────────────────────────────────
   The feed should never show a hole where a picture is about to be. */

.post-media-wrap {
  position: relative;
  overflow: hidden;
  background-color: var(--panel-2);
  background-size: cover;
  background-position: center;
  /* The blurred placeholder is a 32px image stretched over the whole box;
     without this it looks like low-res pixels rather than an out-of-focus
     photo. Scaling slightly past the edges hides the soft border blur
     leaves behind. */
  background-repeat: no-repeat;
}
.post-media-wrap::before {
  content: ""; position: absolute; inset: -6%;
  background: inherit; background-size: cover; background-position: center;
  filter: blur(12px) saturate(1.15);
  transform: scale(1.06);
  transition: opacity .4s ease;
}
/* Once the real picture is up, drop the placeholder so it isn't sitting
   underneath costing compositing work on every scroll. */
.post-media-wrap.media-ready::before { opacity: 0; }

.post-media-wrap > .post-media {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  max-height: none;
  opacity: 0;
  transition: opacity .32s ease;
  animation: none;              /* overrides the global lazy-img fade */
}
.post-media-wrap.media-ready > .post-media { opacity: 1; }

/* Videos keep their own intrinsic sizing — a video element reports its
   dimensions from metadata, so it never collapsed the way an image did. */
.post-video-wrap { aspect-ratio: auto !important; background-image: none !important; }
.post-video-wrap::before { display: none; }
.post-video-wrap > .post-video { position: static; height: auto;
  /* Videos never get the .media-ready class the image fade-in relies on
     (only the <img> load handler adds it), so without this override every
     video inherits opacity:0 from the shared .post-media rule above and
     plays invisibly — audio with no picture. Videos show themselves via
     their own poster frame, so they don't need the fade-in at all. */
  opacity: 1 !important; }

/* Grid cells reserve their square up front for the same reason. */
.explore-cell, .popular-cell { background-color: var(--panel-2); }
.explore-cell img, .popular-cell img { opacity: 0; transition: opacity .28s ease; }
.explore-cell img.loaded, .popular-cell img.loaded,
.explore-cell img[src]:not([src=""]), .popular-cell img[src]:not([src=""]) { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .post-media-wrap::before, .post-media-wrap > .post-media { transition: none; }
}

/* ── 31. Share sheet ───────────────────────────────────────
   Share now means more than "copy a link": a chat, a community you're
   in, or a page you run. */

.share-sheet { padding: 10px 14px calc(18px + var(--safe-bottom)); }
.share-title { margin: 2px 4px 12px; font-size: 1.08rem; letter-spacing: -.026em; }
.share-list { display: flex; flex-direction: column; }
.share-row {
  display: flex; align-items: center; gap: 13px;
  padding: 13px 10px; background: transparent; border: 0;
  border-bottom: 1px solid var(--line);
  color: var(--text); text-align: left;
  transition: background var(--dur-fast);
}
.share-row:last-child { border-bottom: 0; }
.share-row:active { background: var(--panel-2); }
.share-row-ico {
  width: 42px; height: 42px; border-radius: 13px; flex: 0 0 auto;
  display: grid; place-items: center;
  background: var(--panel-2); border: 1px solid var(--line);
  color: var(--accent-a);
}
.share-row-ico .icon { width: 20px; height: 20px; }
.share-row-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.share-row-meta strong { font-weight: 650; letter-spacing: -.015em; }
.share-row-chev { flex: 0 0 auto; color: var(--muted-2); display: inline-flex; }
.share-row-chev .icon { width: 16px; height: 16px; }

/* ── Destination picker ── */
.share-picker { max-width: 380px; display: flex; flex-direction: column; gap: 12px; }
.share-picker h3 { margin: 0; }
.share-picker-list {
  display: flex; flex-direction: column; gap: 4px;
  max-height: 46dvh; overflow-y: auto;
}
.share-target {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 10px; border-radius: 14px;
  background: transparent; border: 0; color: var(--text); text-align: left;
  transition: background var(--dur-fast);
}
.share-target:active { background: var(--panel-2); }
.share-target:disabled { opacity: .5; }
.share-target-ico {
  width: 40px; height: 40px; border-radius: 12px; flex: 0 0 auto;
  display: grid; place-items: center;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--accent-b);
}
.share-target-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.share-target-meta strong {
  font-weight: 650; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.share-send {
  flex: 0 0 auto; font-size: .78rem; font-weight: 700;
  color: var(--accent-a); padding: 5px 12px;
  border: 1px solid rgba(124,92,255,.34); border-radius: 999px;
}
.share-empty { padding: 16px 4px; line-height: 1.5; }

@media (min-width: 701px) {
  .share-row:hover, .share-target:hover { background: var(--panel-2); }
}

/* ── 32. From Zallixor Team ────────────────────────────────
   Company identity at the foot of the menu: who makes the app, and the
   other app they make. */

.menu-brand { margin-top: 6px; display: flex; flex-direction: column; gap: 8px; }
.menu-brand-head {
  font-size: .68rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted-2);
  margin: 4px 4px 2px;
}
.menu-brand-card {
  display: block; overflow: hidden;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 16px; color: var(--text); text-decoration: none;
  transition: background var(--dur-fast);
}
.menu-brand-card:active { background: var(--panel-2); }
/* The banner is the brand's own artwork, so it is shown at its real
   aspect rather than cropped to a strip — but capped in height so it
   introduces the company without taking over the menu. */
.menu-brand-banner {
  /* Taller, and biased down the artwork: at 96px centred, `cover` cut the
     ZALLIXOR wordmark clean in half. The logo and wordmark sit slightly
     below centre in the source, so the frame follows them. */
  height: 118px;
  background-size: cover; background-position: center 58%;
  background-color: var(--panel-2);
  border-bottom: 1px solid var(--line);
}
.menu-brand-row { display: flex; align-items: center; gap: 12px; padding: 11px 13px; }
.menu-brand-logo {
  width: 44px; height: 44px; border-radius: 12px; flex: 0 0 auto;
  object-fit: cover; background: var(--panel-2);
}
.menu-brand-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.menu-brand-meta strong { font-weight: 680; letter-spacing: -.018em; }
.menu-brand-meta .muted {
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.menu-brand-go { flex: 0 0 auto; color: var(--muted-2); display: inline-flex; }
.menu-brand-go .icon { width: 17px; height: 17px; }

@media (min-width: 701px) {
  .menu-brand-card:hover { background: var(--panel-2); }
}

/* ── 33. Report a group ────────────────────────────────────
   A 1:1 chat has always had a report control; a group chat had none, so
   the only way to flag abuse in a group was to leave it. */

.report-group { display: flex; flex-direction: column; gap: 10px; max-width: 380px; }
.report-group h3 { margin: 0; }
.report-group p.muted { margin: 0 0 2px; line-height: 1.45; }
.report-group-people { display: flex; flex-direction: column; gap: 2px; max-height: 34dvh; overflow-y: auto; }
.rg-label { display: block; padding: 8px 2px 4px; }
.report-group-person {
  display: flex; align-items: center; gap: 11px;
  padding: 8px 10px; border-radius: 12px;
  background: transparent; border: 0; color: var(--text); text-align: left;
  transition: background var(--dur-fast);
}
.report-group-person:active { background: var(--panel-2); }
.rg-name {
  flex: 1; min-width: 0; font-weight: 600; font-size: .9rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rg-flag { flex: 0 0 auto; font-weight: 650; color: var(--danger); }
@media (min-width: 701px) { .report-group-person:hover { background: var(--panel-2); } }

/* ── Fix: sticky search bar (and profile tabs) landing too far down ──
   .page sets overflow-x:hidden (style.css) to stop wide content from
   causing horizontal scroll. Per spec, pairing overflow-x with a
   "visible" overflow-y forces the browser to auto-compute overflow-y
   as "auto" too — so .page silently became its own scroll container.
   That hijacks position:sticky's frame of reference for any sticky
   child: instead of sticking `top-h` below the *topbar*, it sticks
   `top-h` below the top of *.page itself* — double-counting the header
   height and shoving .search-head (and .profile-tabs, same pattern)
   down by roughly one header's worth of extra space.
   Restoring normal (visible) overflow on these two containers fixes the
   sticky offset; horizontal clipping isn't needed on either — search
   results and profile tabs don't produce wide content the way a media
   feed can. */
.page-search, .page-profile { overflow: visible; }

/* ═══════════════════════════════════════════════════════════════
   i18n — language picker + right-to-left languages (js/i18n.js)
   ═══════════════════════════════════════════════════════════════ */
.auth-lang {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  margin-top: 14px; padding-top: 12px;
  border-top: 1px solid var(--line, rgba(255,255,255,.08));
  color: var(--muted, #8b8f9c);
}

/* Arabic, Urdu, Persian, Hebrew: mirror the layout. Anything that uses
   logical properties already flips; these cover the physical-side rules. */
html[dir="rtl"] body { direction: rtl; }
html[dir="rtl"] .settings-chevron,
html[dir="rtl"] .auth-back svg,
html[dir="rtl"] .chevron { transform: scaleX(-1); }
html[dir="rtl"] input[type="tel"],
html[dir="rtl"] input[type="email"],
html[dir="rtl"] input[type="url"],
html[dir="rtl"] input[type="password"] { direction: ltr; text-align: right; }

/* ── Language picker sheet (I18n.openPicker) ── */
.lang-sheet { padding: 0 0 env(safe-area-inset-bottom, 0); height: 82vh; max-height: 82dvh;
  display: flex; flex-direction: column; }
.lang-overlay.closing { animation: fadeOut .18s ease forwards; }
.lang-overlay.closing .lang-sheet { animation: sheetDown .18s ease-in forwards; }
@keyframes fadeOut { to { opacity: 0; } }
@keyframes sheetDown { to { transform: translateY(100%); } }
.lang-handle { width: 36px; height: 4px; border-radius: 2px; background: var(--line-2); margin: 10px auto 4px; flex: none; }
.lang-head { display: flex; align-items: center; justify-content: space-between; padding: 6px 8px 6px 18px; flex: none; }
.lang-title { font-family: var(--font-display); font-size: 1.12rem; font-weight: 720; letter-spacing: -.02em; }
.lang-search-wrap { position: relative; padding: 4px 14px 10px; flex: none; }
.lang-search-ico { position: absolute; left: 26px; top: 14px; color: var(--muted); pointer-events: none; }
.lang-search-ico svg { width: 16px; height: 16px; }
.lang-search { width: 100%; padding: 11px 14px 11px 38px; border-radius: 12px; border: 1px solid var(--line);
  background: var(--panel-2); color: var(--text); font-size: .95rem; }
.lang-search:focus { outline: none; border-color: var(--accent-b); }
.lang-list { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 0 8px 12px; overscroll-behavior: contain; }
.lang-row { display: flex; align-items: center; justify-content: space-between; width: 100%; background: transparent;
  border: 0; color: var(--text); text-align: left; padding: 13px 12px; border-radius: 12px; cursor: pointer; }
.lang-row:active { background: var(--panel-2); }
.lang-row.hidden { display: none; }
.lang-row.busy { opacity: .6; pointer-events: none; }
.lang-row-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.lang-row-native { font-size: 1rem; font-weight: 600; }
.lang-row-name { font-size: .78rem; color: var(--muted); }
.lang-row-tick { color: var(--accent-b); opacity: 0; width: 22px; height: 22px; flex: none; }
.lang-row-tick svg { width: 22px; height: 22px; }
.lang-row.current .lang-row-tick { opacity: 1; }
.lang-row.current .lang-row-native { color: var(--accent-b); }
.lang-empty { text-align: center; padding: 24px; }
.lang-empty.hidden { display: none; }
html[dir="rtl"] .lang-row { text-align: right; }
html[dir="rtl"] .lang-search { padding: 11px 38px 11px 14px; }
html[dir="rtl"] .lang-search-ico { left: auto; right: 26px; }

/* Trigger on the login card */
.lang-btn { display: inline-flex; align-items: center; gap: 8px; padding: 8px 14px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--panel-2); color: var(--muted); font-size: .88rem; cursor: pointer; }
.lang-btn svg { width: 15px; height: 15px; }
.lang-btn:active { background: var(--panel); }
.lang-btn-label { color: var(--text); font-weight: 550; }
.settings-value { margin-left: auto; margin-right: 6px; font-size: .9rem; }
html[dir="rtl"] .settings-value { margin-left: 6px; margin-right: auto; }

/* ══════════════════════════════════════════════════════════════════
   LOW-END DEVICE TIER
   Added on <html> by detectDeviceTier() in app.js when the device
   reports little RAM or few cores. See that function for what counts.

   The expensive thing on a budget Android is not the number of
   animations — it is backdrop-filter. Every blurred surface here is
   fixed and sits over scrolling content, so the GPU re-blurs that
   region on every single frame of every scroll, for the whole
   session. Killing the blur is the single biggest win available and
   it costs almost nothing visually, because each of those surfaces
   already declares a --glass background behind the blur.

   Those tokens are semi-transparent, though — without the blur they
   would just let the feed show through and make the top bar
   unreadable. So the tokens are redefined as the opaque panel colour
   rather than the blur being removed on its own. One override, and
   all ~35 blurred surfaces stay legible in both light and dark.

   Looping ambient animations go too: they are cheap individually but
   run continuously. Gift animations are deliberately NOT touched —
   they are short, user-triggered, and a paid feature.
   ══════════════════════════════════════════════════════════════════ */
/* The theme tokens are set on :root[data-theme="light"] / [data-theme]
   selectors, which outrank a plain html.low-end no matter that this
   block comes later in the file — specificity beats source order. The
   theme-qualified selectors below are listed so this override actually
   wins in BOTH palettes; without them the blur would be removed while
   the glass stayed translucent, which is the one combination that looks
   broken. */
:root.low-end,
:root.low-end[data-theme="dark"],
:root.low-end[data-theme="light"] {
  --glass:   var(--panel);
  --glass-2: var(--panel);
}
html.low-end *,
html.low-end *::before,
html.low-end *::after {
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
/* Ambient loops only — the shimmer on loading skeletons and the
   pulsing presence dot. Both keep their static appearance. */
html.low-end .skel-block::after { animation: none !important; }
html.low-end .online-dot { animation: none !important; }

/* ════════════════════════════════════════════════════════════════
   DECLUTTER + VIDEO TAB + LIVE (TikTok / Bigo style)
   ════════════════════════════════════════════════════════════════ */

/* Compact Facebook-style composer */
.composer-compact { padding: 10px 12px; }
.composer-compact .composer-top { display: flex; align-items: center; gap: 10px; }
.composer-compact .composer-fake { flex: 1; text-align: left; border-radius: 999px; padding: 11px 16px; }
.composer-photo { width: 40px; height: 40px; border-radius: 12px; border: 0; display: grid; place-items: center;
  background: rgba(47,216,164,.14); color: var(--ok); cursor: pointer; }
.composer-photo svg { width: 20px; height: 20px; }

/* Messages: slim Assistant row */
.msg-head { margin-bottom: 4px; }
.assistant-row { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left; cursor: pointer;
  padding: 10px 12px; margin: 8px 0 4px; border-radius: var(--radius-sm); border: 1px solid var(--line);
  background: var(--panel); color: var(--text); }
.assistant-row-text { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.assistant-row-pin { color: var(--accent-a); }
.assistant-row-pin svg { width: 18px; height: 18px; }

/* Upgrades sheet + profile link */
.upgrades-sheet { display: flex; flex-direction: column; gap: 8px; }
.upgrade-row { display: flex; align-items: center; gap: 12px; width: 100%; padding: 12px; text-align: left; cursor: pointer;
  border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--panel-2); color: var(--text); }
.upgrade-row-ico { width: 38px; height: 38px; border-radius: 12px; display: grid; place-items: center; flex: 0 0 auto; }
.upgrade-row-ico svg { width: 20px; height: 20px; }
.upgrade-row-text { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.upgrade-row-go { color: var(--muted); }
.profile-upgrade-link { background: transparent; border: 0; color: var(--accent-a); font-weight: 650; cursor: pointer; }
.settings-quick-2 { grid-template-columns: repeat(2, 1fr) !important; }

/* Clips: sound moves to a small corner button */
.reel-mute-corner { position: absolute; top: 150px; right: 14px; z-index: 6; width: 36px; height: 36px; border-radius: 50%;
  background: rgba(0,0,0,.45); display: grid; place-items: center; border: 0; color: #fff; }
.reel-mute-corner svg { width: 18px; height: 18px; }

/* ── Video tab ── */
.vt-screen { display: flex; flex-direction: column; min-height: 100%; }
.vt-head { display: flex; align-items: center; justify-content: space-between; padding: 12px 14px 4px; }
.vt-head h2 { margin: 0; }
.vt-chips { display: flex; gap: 8px; padding: 6px 14px 10px; overflow-x: auto; scrollbar-width: none; position: sticky;
  top: 0; z-index: 5; background: var(--bg); }
.vt-chips::-webkit-scrollbar { display: none; }
.vt-chip { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px; padding: 7px 14px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--panel-2); color: var(--text); font-weight: 650; font-size: .85rem; cursor: pointer; }
.vt-chip.active { background: var(--text); color: var(--bg); border-color: var(--text); }
.vt-live-dot { width: 8px; height: 8px; border-radius: 50%; background: #ff2d55; display: inline-block;
  box-shadow: 0 0 0 0 rgba(255,45,85,.6); animation: vtPulse 1.6s infinite; }
@keyframes vtPulse { 0% { box-shadow: 0 0 0 0 rgba(255,45,85,.6); } 70% { box-shadow: 0 0 0 7px rgba(255,45,85,0); } 100% { box-shadow: 0 0 0 0 rgba(255,45,85,0); } }
.vt-body { flex: 1; min-height: 0; }
.vt-feed { display: flex; flex-direction: column; gap: 10px; padding-bottom: 20px; }

/* Clips tab = full screen: page header hides, chips float over the video */
:root.vt-fullscreen .vt-head { display: none; }
:root.vt-fullscreen .vt-chips { position: fixed; top: calc(var(--top-h) + var(--safe-top) + 10px); left: 50%;
  transform: translateX(-50%); z-index: 14; background: rgba(0,0,0,.35); backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px); border-radius: 999px; padding: 4px; gap: 2px; max-width: calc(100% - 24px); }
:root.vt-fullscreen .vt-chip { background: transparent; border: 0; color: rgba(255,255,255,.8); padding: 6px 11px; font-size: .8rem; }
:root.vt-fullscreen .vt-chip.active { background: #fff; color: #05070c; }
:root.vt-fullscreen .reels-create-btn { top: 64px; }

/* Video card (Facebook Watch style) */
.vcard { background: var(--panel); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); padding: 12px 0 4px; }
.vcard-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 0 14px; }
.vcard-author { display: flex; align-items: center; gap: 10px; cursor: pointer; min-width: 0; }
.vcard-caption { padding: 8px 14px 10px; line-height: 1.45; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.vcard-media { position: relative; background: #000; cursor: pointer; aspect-ratio: 16 / 9; }
.vcard-media.vertical { aspect-ratio: 4 / 5; }
.vcard-video { width: 100%; height: 100%; object-fit: contain; display: block; background: #000; }
.vcard-views { position: absolute; left: 10px; bottom: 10px; color: #fff; font-size: .78rem; font-weight: 700;
  background: rgba(0,0,0,.5); padding: 3px 8px; border-radius: 999px; }
.vcard-sound { position: absolute; right: 10px; bottom: 10px; width: 34px; height: 34px; border-radius: 50%; border: 0;
  background: rgba(0,0,0,.5); color: #fff; display: grid; place-items: center; cursor: pointer; }
.vcard-sound svg { width: 17px; height: 17px; }
.vcard-stats { display: flex; justify-content: space-between; padding: 9px 14px; }
.vcard-actions { display: flex; border-top: 1px solid var(--line); margin: 0 10px; }
.vcard-act { flex: 1; background: transparent; border: 0; color: var(--muted); font-weight: 650; padding: 10px 4px; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px; border-radius: 10px; }
.vcard-act:hover { background: var(--panel-2); }
.vcard-act.on { color: #ff3b6b; }

/* Clips shelf + saved grid */
.vt-shelf { padding: 10px 0; background: var(--panel); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.vt-shelf-head { display: flex; align-items: center; justify-content: space-between; padding: 0 14px 8px; gap: 6px; }
.vt-shelf-head strong { display: inline-flex; align-items: center; gap: 7px; }
.vt-shelf-row { display: flex; gap: 8px; overflow-x: auto; padding: 0 14px; scrollbar-width: none; }
.vt-shelf-row::-webkit-scrollbar { display: none; }
.vt-clip { position: relative; flex: 0 0 auto; width: 118px; aspect-ratio: 9 / 16; border-radius: 12px; overflow: hidden;
  background: #111; border: 0; padding: 0; cursor: pointer; }
.vt-clip video { width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
.vt-clip::after { content: ""; position: absolute; inset: 0; background: linear-gradient(transparent 55%, rgba(0,0,0,.7)); }
.vt-clip-views { position: absolute; top: 7px; left: 7px; z-index: 1; color: #fff; font-size: .72rem; font-weight: 700; }
.vt-clip-cap { position: absolute; left: 7px; right: 7px; bottom: 7px; z-index: 1; color: #fff; font-size: .74rem; font-weight: 600;
  text-align: left; line-height: 1.25; }
.vt-saved-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; padding: 0 4px; }
.vt-saved-grid .vt-clip { width: auto; border-radius: 8px; }

/* "Live now" strip */
.vt-liverow { padding: 8px 0 10px; }
.vt-liverow-list { display: flex; gap: 14px; overflow-x: auto; padding: 0 14px; scrollbar-width: none; }
.vt-livebubble { position: relative; display: flex; flex-direction: column; align-items: center; gap: 4px; background: none;
  border: 0; color: var(--text); cursor: pointer; width: 70px; }
.vt-livebubble-ring { padding: 3px; border-radius: 50%; background: linear-gradient(135deg, #ff2d55, #ff8a00); }
.vt-livebubble-ring > * { border: 2px solid var(--bg); border-radius: 50%; }
.vt-livebubble-tag { position: absolute; top: 52px; background: #ff2d55; color: #fff; font-size: .6rem; font-weight: 800;
  padding: 1px 6px; border-radius: 4px; letter-spacing: .05em; }
.vt-livebubble-name { font-size: .74rem; margin-top: 6px; max-width: 70px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Live hub (Bigo-style grid) ── */
.lv-hub { padding: 0 10px 20px; }
.lv-hub-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 2px 4px 10px; }
.lv-cats { display: flex; gap: 16px; }
.lv-cat { background: none; border: 0; color: var(--muted); font-weight: 700; font-size: .95rem; padding: 4px 0; cursor: pointer;
  border-bottom: 2px solid transparent; }
.lv-cat.active { color: var(--text); border-color: #ff2d55; }
.lv-golive { border: 0; border-radius: 999px; padding: 8px 14px; font-weight: 800; color: #fff; cursor: pointer;
  background: linear-gradient(135deg, #ff2d55, #ff7a00); box-shadow: 0 6px 18px rgba(255,45,85,.35);
  display: inline-flex; align-items: center; gap: 6px; }
.lv-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
.lv-empty { grid-column: 1 / -1; }
.lv-card { position: relative; aspect-ratio: 3 / 4; border-radius: 14px; overflow: hidden; border: 0; padding: 0; cursor: pointer;
  background: linear-gradient(160deg, #2b1d52, #0e1830); color: #fff; text-align: left; }
.lv-card-bg { position: absolute; inset: 0; background-size: cover; background-position: center; transform: scale(1.02); }
.lv-card-shade { position: absolute; inset: 0; background: linear-gradient(rgba(0,0,0,.25), transparent 30%, transparent 55%, rgba(0,0,0,.8)); }
.lv-badge { display: inline-flex; align-items: center; gap: 5px; background: #ff2d55; color: #fff; font-size: .68rem; font-weight: 800;
  letter-spacing: .06em; padding: 3px 7px; border-radius: 6px; }
.lv-card .lv-badge { position: absolute; top: 8px; left: 8px; }
.lv-badge-bars { width: 9px; height: 9px; background:
  linear-gradient(#fff,#fff) 0 100%/2px 60% no-repeat, linear-gradient(#fff,#fff) 50% 100%/2px 100% no-repeat, linear-gradient(#fff,#fff) 100% 100%/2px 40% no-repeat;
  animation: lvBars 1s infinite alternate; }
@keyframes lvBars { to { background-size: 2px 100%, 2px 45%, 2px 90%; } }
.lv-count { position: absolute; top: 8px; right: 8px; background: rgba(0,0,0,.45); color: #fff; font-size: .72rem; font-weight: 700;
  padding: 3px 8px; border-radius: 999px; }
.lv-card-meta { position: absolute; left: 9px; right: 9px; bottom: 9px; display: flex; flex-direction: column; gap: 4px; }
.lv-card-title { font-weight: 750; font-size: .9rem; line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lv-card-host { display: flex; align-items: center; gap: 6px; font-size: .75rem; opacity: .9; }

/* ── Live room (TikTok LIVE style) ── */
:root.lv-room-open body { overflow: hidden; }
.lv-room-overlay { position: fixed; inset: 0; z-index: 200; background: #000; }
.lv-room { position: absolute; inset: 0; margin: 0 auto; max-width: 520px; overflow: hidden; color: #fff; background: #000; }
.lv-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; background: #000; }
.lv-shade { position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(rgba(0,0,0,.45), transparent 22%, transparent 55%, rgba(0,0,0,.65)); }
.lv-tap { position: absolute; inset: 0; }
.lv-top { position: absolute; top: calc(var(--safe-top, 0px) + 10px); left: 10px; right: 10px; display: flex; align-items: center; gap: 8px; z-index: 3; }
.lv-host { display: flex; align-items: center; gap: 8px; background: rgba(0,0,0,.35); border-radius: 999px; padding: 3px 4px 3px 3px; cursor: pointer; min-width: 0; }
.lv-host-meta { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
.lv-host-meta strong { font-size: .85rem; max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lv-viewcount { font-size: .7rem; opacity: .85; }
.lv-follow { width: 30px; height: 30px; border-radius: 50%; border: 0; background: #ff2d55; color: #fff; display: grid; place-items: center; cursor: pointer; }
.lv-follow svg { width: 16px; height: 16px; }
.lv-viewers { margin-left: auto; display: flex; align-items: center; }
.lv-viewers > .avatar, .lv-viewers > img, .lv-viewers > div:not(.lv-viewers-n) { margin-left: -8px; border: 2px solid rgba(0,0,0,.4); border-radius: 50%; }
.lv-viewers-n { margin-left: 6px; background: rgba(0,0,0,.35); border-radius: 999px; padding: 4px 9px; font-size: .75rem; font-weight: 700; }
.lv-close { width: 34px; height: 34px; border-radius: 50%; border: 0; background: rgba(0,0,0,.35); color: #fff; display: grid; place-items: center; cursor: pointer; }
.lv-close svg { width: 18px; height: 18px; }
.lv-subtop { position: absolute; top: calc(var(--safe-top, 0px) + 58px); left: 12px; right: 12px; display: flex; align-items: center; gap: 8px; z-index: 3; }
.lv-title { font-size: .8rem; background: rgba(0,0,0,.3); padding: 3px 9px; border-radius: 999px; max-width: 70%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lv-giftbanner { position: absolute; top: 34%; left: 10px; z-index: 3; display: flex; flex-direction: column; gap: 6px; pointer-events: none; }
.lv-giftrow { display: flex; align-items: center; gap: 8px; padding: 4px 12px 4px 4px; border-radius: 999px;
  background: linear-gradient(90deg, rgba(255,45,85,.85), rgba(255,138,0,.55)); font-size: .82rem; animation: lvSlide .35s ease-out; }
.lv-giftx { font-size: 1.1rem; color: #ffe066; font-style: italic; }
@keyframes lvSlide { from { transform: translateX(-110%); } to { transform: none; } }
.lv-chat { position: absolute; left: 10px; right: 90px; bottom: calc(var(--safe-bottom, 0px) + 68px); max-height: 34%; z-index: 3;
  overflow-y: auto; display: flex; flex-direction: column; gap: 5px; scrollbar-width: none;
  -webkit-mask-image: linear-gradient(transparent, #000 22%); mask-image: linear-gradient(transparent, #000 22%); }
.lv-chat::-webkit-scrollbar { display: none; }
.lv-line { display: flex; align-items: flex-start; gap: 6px; font-size: .84rem; line-height: 1.3; align-self: flex-start;
  background: rgba(0,0,0,.28); padding: 4px 10px 4px 4px; border-radius: 14px; max-width: 100%; word-break: break-word; }
.lv-line b { color: #ffd9a8; font-weight: 700; }
.lv-sys { padding: 4px 10px; color: rgba(255,255,255,.85); font-size: .78rem; }
.lv-bottom { position: absolute; left: 10px; right: 10px; bottom: calc(var(--safe-bottom, 0px) + 12px); display: flex; align-items: center; gap: 8px; z-index: 4; }
.lv-input { flex: 1; min-width: 0; border: 0; border-radius: 999px; padding: 11px 15px; background: rgba(255,255,255,.18); color: #fff; font-size: .9rem; }
.lv-input::placeholder { color: rgba(255,255,255,.75); }
.lv-btn { width: 42px; height: 42px; flex: 0 0 auto; border-radius: 50%; border: 0; background: rgba(255,255,255,.18); color: #fff;
  display: grid; place-items: center; cursor: pointer; }
.lv-btn svg { width: 20px; height: 20px; }
.lv-gift { background: linear-gradient(135deg, #ff2d55, #ff8a00); }
.lv-like { color: #ff5d8a; }
.lv-end { width: auto; padding: 0 16px; border-radius: 999px; background: #ff2d55; font-weight: 800; }
.lv-hearts { position: absolute; right: 22px; bottom: calc(var(--safe-bottom, 0px) + 66px); width: 40px; height: 60%; pointer-events: none; z-index: 3; }
.lv-heart { position: absolute; bottom: 0; left: 8px; animation: lvFloat 1.6s ease-out forwards; }
.lv-heart svg { width: 28px; height: 28px; fill: currentColor; }
@keyframes lvFloat { 0% { transform: translate(0,0) scale(.6); opacity: 0; } 15% { opacity: 1; transform: translate(0,-20px) scale(1.1); }
  100% { transform: translate(var(--dx), -320px) scale(.9); opacity: 0; } }
.lv-swipehint { position: absolute; left: 50%; top: 46%; transform: translateX(-50%); font-size: .8rem; font-weight: 650;
  background: rgba(0,0,0,.4); padding: 6px 14px; border-radius: 999px; z-index: 2; pointer-events: none;
  animation: lvHint 4s ease forwards; }
@keyframes lvHint { 0%, 70% { opacity: .9; } 100% { opacity: 0; } }
.lv-ended { position: absolute; inset: 0; z-index: 6; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; background: rgba(0,0,0,.82); text-align: center; padding: 24px; }
.lv-ended.hidden { display: none; }
@media (prefers-reduced-motion: reduce) { .lv-heart, .vt-live-dot, .lv-badge-bars, .lv-giftrow { animation: none; } }

/* ════════════════ COMMUNITIES (Facebook Groups style) ════════════════ */
.cm-avatar { border-radius: 22%; display: grid; place-items: center; color: #fff; font-weight: 800;
  background-size: cover; background-position: center; flex: 0 0 auto; }
.cm-faces { display: flex; align-items: center; }
.cm-faces > * { margin-left: -8px; border: 2px solid var(--panel); border-radius: 50%; }
.cm-faces > *:first-child { margin-left: 0; }

/* list */
.cm-search { margin: 4px 0 12px; border-radius: 999px; padding-left: 16px; }
.cm-section-title { font-size: 1rem; margin: 14px 2px 10px; }
.cm-mine-row { display: flex; gap: 14px; overflow-x: auto; padding-bottom: 6px; scrollbar-width: none; }
.cm-mine-row::-webkit-scrollbar { display: none; }
.cm-chip { display: flex; flex-direction: column; align-items: center; gap: 6px; background: none; border: 0; color: var(--text);
  cursor: pointer; width: 76px; flex: 0 0 auto; }
.cm-chip-name { font-size: .75rem; font-weight: 650; text-align: center; max-width: 76px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cm-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }
.cm-card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; display: flex; flex-direction: column; }
.cm-card-cover { height: 86px; background-size: cover; background-position: center; cursor: pointer; }
.cm-card-body { padding: 0 14px 10px; cursor: pointer; flex: 1; }
.cm-card-avatar { margin-top: -26px; margin-bottom: 6px; }
.cm-card-avatar .cm-avatar { border: 3px solid var(--panel); }
.cm-card-name { display: block; font-size: 1rem; }
.cm-card-meta { display: flex; align-items: center; gap: 8px; margin-top: 4px; }
.cm-card-desc { margin: 8px 0 0; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.cm-card-foot { padding: 0 14px 14px; }

/* community page */
.cm-screen .cm-cover { height: 190px; background-size: cover; background-position: center; position: relative; }
.cm-photo-btn { position: absolute; right: 12px; bottom: 12px; border: 0; border-radius: 10px; padding: 7px 12px; font-weight: 650;
  background: rgba(0,0,0,.5); color: #fff; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
.cm-head { padding: 0 16px 6px; position: relative; }
.cm-head-avatar { position: relative; display: inline-block; margin-top: -46px; }
.cm-head-avatar .cm-avatar { border: 4px solid var(--bg); box-shadow: 0 6px 20px rgba(0,0,0,.18); }
.cm-head-avatar .avatar-edit { position: absolute; right: -6px; bottom: -4px; }
.cm-name { margin: 10px 0 4px; font-size: 1.45rem; line-height: 1.2; }
.cm-sub { display: flex; align-items: center; gap: 6px; font-size: .9rem; }
.cm-faces-btn { background: none; border: 0; padding: 0; margin-top: 10px; cursor: pointer; }
.cm-desc { margin: 10px 0 0; line-height: 1.5; }
.cm-actions { display: flex; align-items: center; gap: 8px; margin-top: 14px; flex-wrap: wrap; }
.cm-actions .btn { display: inline-flex; align-items: center; gap: 6px; }
.cm-tabs { display: flex; gap: 4px; padding: 0 12px; border-bottom: 1px solid var(--line); margin-top: 12px; position: sticky; top: 0; background: var(--bg); z-index: 2; }
.cm-tab { background: none; border: 0; padding: 12px 14px; font-weight: 700; color: var(--muted); cursor: pointer; border-bottom: 3px solid transparent; }
.cm-tab.active { color: var(--accent-a); border-bottom-color: var(--accent-a); }
.cm-panel { padding: 12px 12px 30px; display: flex; flex-direction: column; gap: 12px; }
.cm-composer { display: flex; align-items: center; gap: 10px; background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 12px; }
.cm-composer .composer-fake { flex: 1; text-align: left; border-radius: 999px; padding: 11px 16px; }
.cm-join-prompt { display: flex; align-items: center; justify-content: space-between; gap: 12px; background: var(--accent-soft);
  border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; }
.cm-join-prompt p { margin: 2px 0 0; }
.cm-about { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px; display: flex; flex-direction: column; gap: 10px; }
.cm-about h4, .cm-members-head h4 { margin: 0; }
.cm-about p { margin: 0; line-height: 1.5; }
.cm-about-row { display: flex; align-items: center; gap: 8px; color: var(--muted); }
.cm-about-owner { border-top: 1px solid var(--line); padding-top: 10px; }
.cm-members { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 6px 10px; }
.cm-members > * { position: relative; }
.cm-role { display: inline-block; margin-left: 6px; vertical-align: middle; font-size: .68rem; font-weight: 800;
  color: var(--accent-a); background: var(--accent-soft); padding: 3px 8px; border-radius: 999px; }

/* share menu */
.share-sheet { display: flex; flex-direction: column; gap: 14px; }
.share-copy-row { display: flex; gap: 8px; }
.share-copy-row .share-url { flex: 1; min-width: 0; }
.share-targets { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; }
.share-target { display: flex; flex-direction: column; align-items: center; gap: 6px; font-size: .75rem; font-weight: 650;
  color: var(--text); text-decoration: none; }
.share-target-ico { width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center; color: #fff; font-weight: 800; font-size: 1.1rem; }
.st-wa .share-target-ico { background: #25d366; }
.st-fb .share-target-ico { background: #1877f2; }
.st-x .share-target-ico { background: #111; }
.st-tg .share-target-ico { background: #29a9eb; }
.st-em .share-target-ico { background: #7c5cff; }

/* Live character count under name fields (usernames 3–20, display names ≤30) */
.name-counter { display: block; text-align: right; margin-top: 4px; font-variant-numeric: tabular-nums; }
.name-counter.at-limit { color: var(--amber); font-weight: 700; }

/* ════════════════ ADS CENTER + AD CARD ════════════════ */
.page-ads .page-head-row { display: flex; align-items: center; justify-content: space-between; }
.ads-hero { display: flex; gap: 14px; align-items: flex-start; padding: 16px; border-radius: var(--radius);
  background: linear-gradient(135deg, rgba(124,92,255,.14), rgba(34,199,224,.12)); border: 1px solid var(--line); }
.ads-hero p { margin: 4px 0 0; }
.ads-hero-ico { width: 44px; height: 44px; border-radius: 14px; display: grid; place-items: center; background: var(--grad); color: #fff; flex: 0 0 auto; }
.ads-hero-ico svg { width: 22px; height: 22px; }
.ads-section-title { font-size: 1rem; margin: 18px 2px 10px; }
.ads-info { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 4px 14px; }
.ads-list { display: flex; flex-direction: column; gap: 8px; }
.ads-row { display: flex; align-items: center; gap: 12px; padding: 10px; background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius-sm); }
.ads-thumb { width: 56px; height: 56px; border-radius: 10px; object-fit: cover; flex: 0 0 auto; background: var(--panel-2); }
.ads-thumb-empty { display: grid; place-items: center; color: var(--muted); }
.ads-row-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.ads-row-text strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ads-status { align-self: flex-start; font-size: .72rem; font-weight: 750; padding: 2px 8px; border-radius: 999px; background: var(--panel-2); color: var(--muted); }
.ads-status.wait { background: rgba(246,181,69,.16); color: var(--amber); }
.ads-status.live { background: rgba(47,216,164,.16); color: var(--ok); }
.ads-status.bad { background: rgba(255,93,115,.14); color: var(--danger); }
.ads-row-actions { display: flex; gap: 6px; flex: 0 0 auto; }

.ad-editor { max-width: 860px; width: calc(100% - 24px); }
.ad-editor-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; align-items: start; }
.ad-editor-form { display: flex; flex-direction: column; gap: 10px; }
.ad-editor-form .field { display: flex; flex-direction: column; gap: 5px; font-weight: 650; font-size: .85rem; }
.ad-editor-preview { display: flex; flex-direction: column; gap: 6px; position: sticky; top: 0; }
@media (max-width: 720px) { .ad-editor-grid { grid-template-columns: 1fr; } }

.adc { padding: 0; overflow: hidden; }
.adc-head { display: flex; align-items: center; gap: 10px; padding: 12px 14px 8px; }
.adc-text { padding: 0 14px 10px; line-height: 1.45; white-space: pre-wrap; }
.adc-media { display: block; width: 100%; max-height: 520px; object-fit: cover; background: #000; }
.adc-media-empty { display: grid; place-items: center; aspect-ratio: 16 / 10; background: var(--panel-2); color: var(--muted); font-size: .85rem; }
.adc-bar { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 14px; background: var(--panel-2); }
.adc-bar-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.adc-bar-text strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.adc-cta { flex: 0 0 auto; text-decoration: none; }

/* Pages tab */
.fp-cats { display: flex; gap: 8px; overflow-x: auto; padding: 0 0 6px; scrollbar-width: none; }
.fp-cats::-webkit-scrollbar { display: none; }
.create-opt.danger .create-opt-title, .create-opt.danger .create-opt-ico { color: var(--danger); }
/* Ad editor: never wider than the screen on a phone */
.ad-editor { box-sizing: border-box; overflow-x: hidden; }
.ad-editor-grid > *, .ad-editor-form .field { min-width: 0; }
.ad-editor-form .field-input { width: 100%; box-sizing: border-box; max-width: 100%; }
.ad-editor-preview .adc { max-width: 100%; }
.adc-cta, .adc-cta:visited { color: #fff !important; }
.ad-editor textarea { font-family: inherit; }

/* ════════════ COMPOSER + EDITOR (app-like, not form-like) ════════════ */
/* Browsers give <textarea> a monospace "typewriter" font by default —
   that was the "terminal" look. Every text box uses the app's own font. */
textarea, input, select, button { font-family: inherit; }

.cx { display: flex; flex-direction: column; gap: 12px; }
.cx-head { display: flex; align-items: center; justify-content: center; position: relative; padding-bottom: 10px; border-bottom: 1px solid var(--line); }
.cx-head h3 { margin: 0; font-size: 1.1rem; }
.cx-head .icon-btn { position: absolute; right: 0; top: 50%; transform: translateY(-60%); }
.cx-author { display: flex; align-items: center; gap: 10px; }
.cx-author-meta { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; }
.cx-author-meta .audience-select { border-radius: 8px; padding: 3px 26px 3px 10px; font-size: .78rem; font-weight: 650; min-height: 0; height: auto; width: auto; }
.cx .composer-textarea { border: 0 !important; background: transparent !important; box-shadow: none !important; outline: none;
  font-size: 1.2rem; line-height: 1.45; padding: 4px 2px; min-height: 120px; resize: none; color: var(--text); }
.cx .composer-textarea::placeholder { color: var(--muted); }
.cx .composer-textarea-bg { background: var(--grad) !important; font-size: 1.35rem; font-weight: 700; text-align: center; }
.cx-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 12px;
  border: 1px solid var(--line); border-radius: 14px; }
.cx-toolbar-label { font-weight: 650; font-size: .9rem; }
.cx-tools { display: flex; gap: 4px; }
.cx-tool { width: 38px; height: 38px; border-radius: 50%; border: 0; background: transparent; display: grid; place-items: center; cursor: pointer; }
.cx-tool:hover { background: var(--panel-2); }
.cx-tool svg { width: 22px; height: 22px; }
.cx-tool.t-photo { color: #2fbf71; }
.cx-tool.t-bg { color: #f0932b; }
.cx-tool.t-draft { color: var(--accent-b); }
.cx-chip { align-self: flex-start; border-radius: 999px !important; }
.cx-settings { font-size: .88rem; }
.cx-settings summary { cursor: pointer; color: var(--muted); font-weight: 650; padding: 2px 0; }
.cx-settings[open] summary { margin-bottom: 8px; }
.cx-post { font-size: 1rem; padding: 12px; }
.cx-note { margin: 0; text-align: center; }
.cx .composer-preview img, .cx .composer-preview video { border-radius: 12px; max-height: 320px; width: 100%; object-fit: cover; }
.cx .poll-fields { display: flex; flex-direction: column; gap: 8px; }
.cx .poll-opt { border-radius: 12px; }
.cx .poll-add { align-self: flex-start; }

/* ════════════ PROFILE (streamlined) ════════════ */
.stats-row { grid-template-columns: repeat(4, 1fr) !important; }
.pf-extras { display: flex; flex-wrap: wrap; gap: 8px; margin: 2px 0 4px; }
.pf-extras:empty { display: none; }
.pf-chip { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 999px;
  background: var(--panel); border: 1px solid var(--line); font-size: .82rem; font-weight: 650; color: var(--text); }
.pf-streak { color: #f0772b; }
.pf-badges { cursor: pointer; }
.pf-badge { display: inline-flex; }
.pf-badge svg { width: 22px; height: 22px; }
.pf-see-all { color: var(--accent-a); margin-left: 2px; }
.pf-badge-wall { max-height: 85vh; overflow-y: auto; display: flex; flex-direction: column; gap: 14px; }
/* Chips line up with the cards above and below them */
.page-profile .pf-extras, .pf-extras { margin-left: 16px; margin-right: 16px; }
/* Close buttons in pop-ups: a soft ring instead of a heavy box when focused */
.modal .icon-btn:focus, .cx-head .icon-btn:focus, .modal-head .icon-btn:focus { outline: none; box-shadow: none; }
.modal .icon-btn:focus-visible, .cx-head .icon-btn:focus-visible { outline: 2px solid var(--accent-soft); outline-offset: 2px; box-shadow: none; }
/* Presence line on profiles */
.pf-presence { font-size: .8rem; color: var(--muted); display: inline-flex; align-items: center; gap: 6px; margin-top: 2px; }
.pf-presence.on { color: var(--ok); font-weight: 650; }
.pf-presence.on::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--ok); }
/* Daily-limit notice */
.zx-busy { position: fixed; left: 50%; transform: translateX(-50%); top: calc(var(--top-h, 56px) + var(--safe-top, 0px) + 8px);
  z-index: 300; width: min(560px, calc(100% - 24px)); display: flex; align-items: center; gap: 10px; padding: 10px 12px;
  border-radius: 14px; background: #fff4df; color: #7a4b00; border: 1px solid #f3cf8a; box-shadow: 0 8px 24px rgba(0,0,0,.15); font-size: .88rem; }
.zx-busy .icon-btn { margin-left: auto; color: inherit; }

/* More ways to share */
.share-more { display: flex; flex-direction: column; }
.share-more[hidden] { display: none; }
.share-more-wrap { margin-top: 6px; }
.share-row-chev .icon { transition: transform .18s; }
.share-row-chev.open .icon { transform: rotate(180deg); }
.modal.share-sheet, .sheet.share-sheet { max-height: 88dvh; overflow-y: auto; }
.share-more-wrap .share-row, .share-more .share-row { width: 100%; }

/* Stories: composer, text stories, captions */
.story-composer { display: flex; flex-direction: column; gap: 10px; max-width: 380px; }
.story-composer h3 { margin: 0; }
.story-composer-preview img, .story-composer-preview video { width: 100%; max-height: 46dvh; object-fit: contain; border-radius: 14px; background: #000; display: block; }
.story-composer .composer-bg-picker { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
.story-text-card { display: grid; place-items: center; padding: 28px 20px; text-align: center; color: #fff; border-radius: 14px; min-height: 220px; width: 100%; box-sizing: border-box; }
.story-text-input { width: 100%; background: transparent; border: 0; outline: 0; resize: none; color: #fff; font: inherit; font-size: 1.4rem; font-weight: 700; text-align: center; }
.story-text-input::placeholder { color: rgba(255,255,255,.7); }
.story-stage { position: relative; }
.story-stage .story-text-card { height: 100%; min-height: 0; border-radius: 0; font-size: 1.6rem; font-weight: 700; }
.story-text-body { margin: 0; max-width: 92%; white-space: pre-wrap; overflow-wrap: anywhere; }
.story-caption { position: absolute; left: 0; right: 0; bottom: 0; padding: 44px 18px calc(18px + var(--safe-bottom, 0px)); background: linear-gradient(transparent, rgba(0,0,0,.65)); color: #fff; text-align: center; font-size: .98rem; line-height: 1.4; pointer-events: none; overflow-wrap: anywhere; }
.story-text-thumb { min-height: 0; height: 100%; aspect-ratio: 1; padding: 8px; font-size: .8rem; font-weight: 700; overflow: hidden; }

/* Zall Clip: video-shaped loading placeholders */
.skel-vcard .skel-vmedia { width: 100%; aspect-ratio: 16 / 9; border-radius: 0; margin: 10px 0; }
.skel-vcard .skel-head, .skel-vcard .skel-body, .skel-vcard .skel-actions { box-sizing: border-box; }
.vt-sentinel .skel-vcard { border-top: 0; }
.reel-skel { background: #0b0b0e; overflow: hidden; }
.reel-skel .skel-block { background: rgba(255,255,255,.1); }
.reel-skel-rail { position: absolute; right: 12px; bottom: 110px; display: flex; flex-direction: column; gap: 18px; }
.reel-skel-rail .skel-block { width: 44px; height: 44px; border-radius: 50%; }
.reel-skel-meta { position: absolute; left: 14px; right: 84px; bottom: 28px; display: flex; flex-direction: column; gap: 9px; }

/* Long display names: one line with "…", badges stay right after the name */
.name-row { min-width: 0; max-width: 100%; }
.name-row > .name-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Profile heading: may wrap onto two lines, with the badges after the last word */
.name-row.big { display: block; }
.name-row.big > .name-text { display: inline; white-space: normal; overflow: visible; overflow-wrap: anywhere; }
.name-row.big > :not(.name-text) { display: inline-flex; vertical-align: middle; margin-left: 4px; }
