/* Jamyvo 2.3 polish: fixes from the full-app audit. Loaded last. */
/* Profiles of other people: no empty story row. */
.story-strip:empty{display:none}
/* Old Jamyvo pink left in selection states: use the Jamyvo accent. */
::selection{background:rgba(66,230,129,.35)}
.radio:has(input:checked){border-color:rgba(66,230,129,.65)}
.tag{background:rgba(66,230,129,.14)}
.nudge-glow{box-shadow:0 0 0 0 rgba(66,230,129,.5);animation:jamiify-glow 2.4s ease-out 3}
@keyframes jamiify-glow{0%{box-shadow:0 0 0 0 rgba(66,230,129,.5)}70%{box-shadow:0 0 0 12px rgba(66,230,129,0)}100%{box-shadow:0 0 0 0 rgba(66,230,129,0)}}
.cam-seg-done{box-shadow:0 4px 14px rgba(66,230,129,.35)}
.quick-progress progress{accent-color:var(--accent)}
/* Home feed tabs scroll sideways: fade the edges so a clipped tab reads as "more this way". */
.home-feed-tabs{-webkit-mask-image:linear-gradient(90deg,transparent 0,#000 14px,#000 calc(100% - 18px),transparent);mask-image:linear-gradient(90deg,transparent 0,#000 14px,#000 calc(100% - 18px),transparent);padding-inline:14px 18px;scroll-padding-inline:24px}
/* A loading placeholder's margin must never push the whole screen down while a page opens
   (a top margin on #main's first child collapses through #main and moves the body). */
#main>.spinner.show{margin-top:0;position:relative;top:48px;margin-bottom:96px}
/* 2.3: a silent moving preview on the video tile most in view (Explore, Long posts, search). */
.tile-media .tile-preview{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;transition:opacity .3s ease;pointer-events:none}
.tile-media .tile-preview.on{opacity:1}
@media (prefers-reduced-motion:reduce){.tile-media .tile-preview{display:none}}
/* 2.3: controls behave like an app's: a long press doesn't select their text or pop up a link preview. */
.tabbar,.rail-nav,.btn,.chip,.icon-btn,.act,.home-feed-tabs,.p-tabs,.tile,.reel .actions,.reel .stage-tools,.sub-head,.feed-top{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
.profile-post-vis{display:inline-flex;align-items:center;gap:3px;color:#cfcfcf}.profile-post-vis svg.i{width:11px;height:11px}
/* 2.3: the "saved" line under Profile privacy keeps its space, so the sections below never move when it appears. */
#profile-privacy-status{min-height:1.4em}
/* 2.3.1: iPhone bottom bar. It used to float a full home-indicator height (34 px) above the bottom edge;
   now it sits just above the home indicator, like Android, and screens above it extend to match.
   Phones without a bottom safe area (Android) and tablets/desktops (side rail) are unchanged. */
:root{--tab-lift:max(0px,calc(var(--safe-b) - 20px))}
@media(max-width:767px){
 .tabbar{bottom:max(6px,var(--tab-lift))}
 #main{padding-bottom:calc(var(--tabbar-h) + var(--tab-lift))}
 .feed-page{bottom:calc(var(--tabbar-h) + var(--tab-lift))}
 .page.chat{height:calc(var(--viewport-h) - var(--tabbar-h) - var(--tab-lift))}
 .page.chat.message-thread{height:calc(var(--viewport-h,100dvh) - var(--tabbar-h) - var(--tab-lift))}
 html.keyboard-open .page.chat,html.keyboard-open .page.chat.message-thread{height:var(--viewport-h,100dvh)}
 #toast{bottom:calc(var(--tabbar-h) + var(--tab-lift) + 14px)}
 .lesson-cta{bottom:calc(var(--tabbar-h) + var(--tab-lift) + 150px)}
 .story-feed-page{padding-bottom:calc(var(--tabbar-h) + var(--tab-lift) + 20px)}
 .group-compose{bottom:calc(var(--tabbar-h) + var(--tab-lift))}
}
/* 2.3.1: while a profile tab's list is on its way, the current list dims in place (nothing moves). */
.profile-stream.switching{opacity:.45;transition:opacity .12s ease;pointer-events:none}
/* 2.3.1: chats size themselves to end exactly at the bottom bar (or the keyboard), so the page padding meant
   for scrolling screens no longer leaves an empty band under the message box (82 px on iPhone, 48 px on Android). */
#main.page.chat{padding-bottom:0}
/* 2.3.2: on the narrowest phones the owner's background button is a round icon so it never covers the photo. */
@media(max-width:360px){.profile-cover-edit{font-size:0!important;gap:0;width:44px;padding:0!important;justify-content:center}.profile-cover-edit svg.i{width:20px;height:20px;margin:0}}
/* 2.3.2: College and area tabs show real names; long ones are shortened so the tab row keeps its size. */
.home-feed-tabs>a.named>.tab-name{display:inline-block;max-width:9.5em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:bottom}
/* 2.7.0: sideways swipes never change screens. The page itself only scrolls up and down (rows that scroll sideways
   keep their own sideways scrolling), and a sideways overscroll never becomes the browser's Back or Forward. */
html,body,.reels,.chat-scroll{touch-action:pan-y pinch-zoom}html,body{overscroll-behavior-x:none}
/* 2.4.1: on your own profile the camera on your picture and Edit background appear when you tap your picture
   or the background area, and hide again a few seconds later (profile.js). */
.profile-identity #p-photo,.profile-identity #p-cover{opacity:0;pointer-events:none;transform:scale(.9);transition:opacity .18s ease,transform .18s ease}
.profile-identity.show-photo-edit #p-photo,.profile-identity.show-cover-edit #p-cover,.profile-identity #p-photo:focus-visible,.profile-identity #p-cover:focus-visible{opacity:1;pointer-events:auto;transform:none}
@media(hover:hover) and (pointer:fine){.profile-identity:hover #p-cover,.profile-identity .p-avatar:hover #p-photo{opacity:1;pointer-events:auto;transform:none}}
@media(prefers-reduced-motion:reduce){.profile-identity #p-photo,.profile-identity #p-cover{transition:none}}
/* 2.4.1: pressing and holding doesn't select or copy text, pictures or videos anywhere in the app; fields you
   type in still work as usual (and messages can still be copied from their menu). */
html{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
img,video,a{-webkit-touch-callout:none;-webkit-user-drag:none}
input,textarea,select,[contenteditable],[contenteditable] *{-webkit-user-select:text;user-select:text;-webkit-touch-callout:default}
/* 2.4: the account picture at the bottom of the computer menu kept its initials centred (a menu rule meant for its
   name and @username also reset the picture's layout). */
.rail-me>.avatar{display:inline-grid}
/* 2.4.1: your account at the bottom of the left menu is your profile's place in it, so it shows when you're there. */
.rail-me.active{background:#42e68112}.rail-me.active strong{color:#42e681}

/* 2.7.0: when a screen has to wait for the network (nothing kept or fetched ahead), a thin bar at the top says it is
   loading. There is no frozen picture of the old screen. */
html.screen-loading body::before{content:"";position:fixed;z-index:4000;top:0;left:0;height:2px;width:40%;background:#42e681;border-radius:0 2px 2px 0;animation:screen-loading 1s ease-in-out infinite;pointer-events:none}
@keyframes screen-loading{0%{transform:translateX(-100%)}100%{transform:translateX(250%)}}
@media(prefers-reduced-motion:reduce){html.screen-loading body::before{animation:none;width:100%;opacity:.6}}
/* 2.7.0: colleges near you (Edit profile and College stories) and the OpenStreetMap credit under found places. */
.college-near{display:grid;gap:8px;margin:-4px 0 12px}.college-near>.btn{justify-self:start}.college-near [data-college-status]:empty{display:none}
.college-list{display:grid;gap:6px;max-height:min(46vh,320px);overflow:auto;overscroll-behavior:contain}
.college-choice{display:grid;gap:2px;text-align:left;padding:10px 12px;border-radius:12px;background:#ffffff0d;border:1px solid #ffffff1c;color:#fff}
.college-choice small{color:var(--muted,#9a9a9a)}.college-choice.chosen{border-color:#42e681;background:#42e68114}
.osm-credit{display:block;margin-top:4px;font-size:11.5px}.osm-credit a{color:inherit;text-decoration:underline}

/* 2.8.0: Admin › Legal requests */
.legal-request { gap: 8px; }
.legal-request.overdue { border-color: var(--danger); }
.legal-fields { display: grid; grid-template-columns: max-content 1fr; gap: 4px 12px; margin: 4px 0; font-size: 14px; }
.legal-fields dt { color: var(--muted, #9a9a9a); }
.legal-fields dd { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.legal-targets { list-style: none; padding: 0; margin: 4px 0; display: grid; gap: 6px; }
.legal-request .row-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.admin-tabs .count.urgent { background: var(--danger); color: #fff; }
@media (max-width: 420px) { .legal-fields { grid-template-columns: 1fr; } .legal-fields dt { margin-top: 6px; } }

/* 2.8.2: screen changes swap in a single frame once the next screen is drawn, as a phone app's tabs do (main.js
   smoothRender); no fade that would mix the two screens. The bottom bar and side menu stay put. */
::view-transition-old(root),::view-transition-new(root){animation:none}
.tabbar{view-transition-name:jamiify-tabbar}
.rail-nav{view-transition-name:jamiify-rail}
::view-transition-group(jamiify-tabbar),::view-transition-group(jamiify-rail),::view-transition-new(jamiify-tabbar),::view-transition-new(jamiify-rail){animation:none}
::view-transition-old(jamiify-tabbar),::view-transition-old(jamiify-rail){display:none}
@media (prefers-reduced-motion:reduce){::view-transition-group(*),::view-transition-old(*),::view-transition-new(*){animation:none!important}}
/* 2.11.0: sensitive posts are blurred until the viewer chooses to see them (sensitive.js). */
.sensitive-media{filter:blur(30px) saturate(.75) brightness(.85)!important}
.reel.is-sensitive .stage .media-slot,.reel.is-sensitive .stage>.backdrop,.reel.is-sensitive .stage .text-media-slot,.reel.is-sensitive .stage .player{filter:blur(30px) saturate(.75) brightness(.85)}
.reel.is-sensitive .big-play{display:none}
.sensitive-gate{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:6;width:min(300px,78%);display:grid;justify-items:center;gap:8px;padding:18px 16px;border-radius:18px;background:rgba(14,12,22,.72);color:#fff;text-align:center;font-size:13px;line-height:1.35;backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);box-shadow:0 10px 30px rgba(0,0,0,.35)}
.sensitive-gate strong{font-size:15px}.sensitive-gate span{color:rgba(255,255,255,.82)}
.sensitive-gate .btn{min-height:40px;margin-top:4px;padding:0 18px;border-radius:999px;background:#fff;color:#111;font-weight:700}
.profile-post .sensitive-gate{top:45%}
/* 2.11.0: Translate (translate.js). */
.translate-btn{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:600;padding:2px 0;opacity:.9}
.translate-btn .i{width:14px;height:14px}
.caption .translate-btn{color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.5);pointer-events:auto}
.translation{margin:6px 0 2px;padding:8px 10px;border-radius:12px;background:rgba(127,127,127,.12);font-size:14px;line-height:1.4}
.translation small{display:block;margin-bottom:2px;font-size:11px}
.translation p{margin:0;white-space:pre-wrap}
.bubble-row.mine .translation{margin-left:auto}
.translation-sheet p{white-space:pre-wrap}.translation-sheet .translation-title{font-weight:700}
