/* ============================================ GrubFlip — Chat & Messages Styles Mobile-first responsive design Uses brand tokens from styles.css ============================================ */ /* --- Messages Inbox Page --- */ .messages-inbox { padding-top: 0.5rem; padding-bottom: 5rem; /* space for bottom nav */ } .chat-search { position: relative; margin: 0.75rem 1rem; } .chat-search__icon { position: absolute; left: 0.875rem; top: 50%; transform: translateY(-50%); color: var(--gf-neutral-400); pointer-events: none; } .chat-search__input { width: 100%; padding: 0.625rem 0.875rem 0.625rem 2.5rem; border: 1.5px solid var(--gf-neutral-200); border-radius: var(--gf-radius-full); background: var(--gf-bg-muted); font-family: var(--gf-font-body); font-size: 0.875rem; color: var(--gf-neutral-900); transition: border-color 0.15s ease, background 0.15s ease; } .chat-search__input:focus { outline: none; border-color: var(--gf-primary); background: var(--gf-bg); box-shadow: 0 0 0 3px rgba(255, 107, 53, 0.1); } .chat-search__input::placeholder { color: var(--gf-neutral-400); } /* Trade Context Banner */ .trade-context-banner { display: flex; align-items: center; gap: 0.5rem; margin: 0 1rem 0.5rem; padding: 0.5rem 0.75rem; background: var(--gf-primary-bg); border-radius: var(--gf-radius-md); font-family: var(--gf-font-body); font-size: 0.8125rem; font-weight: 600; color: var(--gf-primary-dark); } .trade-context-banner svg { color: var(--gf-primary); flex-shrink: 0; } /* Conversation List */ .conversation-list { list-style: none; margin: 0; padding: 0; } .conversation-item { border-bottom: 1px solid var(--gf-neutral-100); } .conversation-item:last-child { border-bottom: none; } .conversation-item__link { display: flex; align-items: flex-start; gap: 0.75rem; padding: 0.875rem 1rem; text-decoration: none; color: inherit; transition: background 0.12s ease; } .conversation-item__link:active { background: var(--gf-neutral-50); } /* Avatar */ .conversation-item__avatar { position: relative; flex-shrink: 0; } .conversation-item__avatar img { width: 48px; height: 48px; border-radius: var(--gf-radius-full); object-fit: cover; background: var(--gf-neutral-200); } .conversation-item__online { position: absolute; bottom: 1px; right: 1px; width: 12px; height: 12px; background: var(--gf-success); border: 2px solid var(--gf-bg); border-radius: var(--gf-radius-full); } /* Content */ .conversation-item__content { flex: 1; min-width: 0; } .conversation-item__header { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 0.125rem; } .conversation-item__name { font-family: var(--gf-font-heading); font-size: 0.9375rem; font-weight: 700; color: var(--gf-neutral-900); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .conversation-item--unread .conversation-item__name { color: var(--gf-neutral-900); } .conversation-item__time { font-family: var(--gf-font-body); font-size: 0.75rem; color: var(--gf-neutral-400); flex-shrink: 0; margin-left: 0.5rem; } .conversation-item--unread .conversation-item__time { color: var(--gf-primary); font-weight: 600; } .conversation-item__preview { font-family: var(--gf-font-body); font-size: 0.8125rem; color: var(--gf-neutral-500); line-height: 1.4; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-bottom: 0.25rem; } .conversation-item--unread .conversation-item__preview { color: var(--gf-neutral-700); font-weight: 500; } .conversation-item__meta { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; } .conversation-item__trade-tag { font-family: var(--gf-font-body); font-size: 0.6875rem; color: var(--gf-neutral-500); background: var(--gf-neutral-100); padding: 0.125rem 0.5rem; border-radius: var(--gf-radius-full); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 200px; } .conversation-item__trade-tag--complete { background: var(--gf-success-bg); color: #1a8a4a; } .conversation-item__trade-tag--expired { background: var(--gf-neutral-100); color: var(--gf-neutral-400); } .conversation-item__badge { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 0.375rem; background: var(--gf-primary); color: #fff; font-family: var(--gf-font-body); font-size: 0.6875rem; font-weight: 700; border-radius: var(--gf-radius-full); flex-shrink: 0; } /* ============================================ Chat View (Individual Conversation) ============================================ */ .chat-view { display: flex; flex-direction: column; height: 100dvh; height: 100vh; /* fallback */ overflow: hidden; } /* Chat Header */ .chat-header { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0.75rem; background: var(--gf-bg); border-bottom: 1px solid var(--gf-neutral-100); position: sticky; top: 0; z-index: 100; min-height: 56px; } .chat-header__back { display: flex; align-items: center; justify-content: center; width: 36px; height: 36px; color: var(--gf-neutral-700); text-decoration: none; border-radius: var(--gf-radius-full); transition: background 0.12s ease; flex-shrink: 0; } .chat-header__back:active { background: var(--gf-neutral-100); } .chat-header__user { display: flex; align-items: center; gap: 0.625rem; flex: 1; min-width: 0; } .chat-header__avatar { position: relative; flex-shrink: 0; } .chat-header__avatar img { width: 36px; height: 36px; border-radius: var(--gf-radius-full); object-fit: cover; background: var(--gf-neutral-200); } .chat-header__online { position: absolute; bottom: 0; right: 0; width: 10px; height: 10px; background: var(--gf-success); border: 2px solid var(--gf-bg); border-radius: var(--gf-radius-full); } .chat-header__info { min-width: 0; } .chat-header__name { font-family: var(--gf-font-heading); font-size: 0.9375rem; font-weight: 700; color: var(--gf-neutral-900); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .chat-header__status { font-family: var(--gf-font-body); font-size: 0.6875rem; color: var(--gf-neutral-400); } /* Icon button (shared) */ .btn-icon { display: flex; align-items: center; justify-content: center; width: 36px; height: 36px; background: none; border: none; color: var(--gf-neutral-600); border-radius: var(--gf-radius-full); cursor: pointer; transition: background 0.12s ease; flex-shrink: 0; } .btn-icon:active { background: var(--gf-neutral-100); } /* Trade Context Card */ .trade-context-card { background: var(--gf-bg); border-bottom: 1px solid var(--gf-neutral-100); padding: 0.625rem 1rem; } .trade-context-card__meals { display: flex; align-items: center; justify-content: center; gap: 0.5rem; margin-bottom: 0.5rem; } .trade-context-card__meal { display: flex; align-items: center; gap: 0.375rem; background: var(--gf-neutral-50); padding: 0.375rem 0.625rem; border-radius: var(--gf-radius-lg); flex: 1; min-width: 0; } .trade-context-card__emoji { font-size: 1.25rem; flex-shrink: 0; } .trade-context-card__label { font-family: var(--gf-font-body); font-size: 0.75rem; font-weight: 600; color: var(--gf-neutral-800); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .trade-context-card__owner { font-family: var(--gf-font-body); font-size: 0.625rem; color: var(--gf-neutral-400); margin-left: auto; flex-shrink: 0; } .trade-context-card__arrow { color: var(--gf-primary); flex-shrink: 0; } .trade-context-card__status { display: flex; align-items: center; justify-content: center; gap: 0.75rem; margin-bottom: 0.5rem; font-family: var(--gf-font-body); } .trade-status { font-size: 0.6875rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; padding: 0.125rem 0.5rem; border-radius: var(--gf-radius-full); } .trade-status--pending { background: var(--gf-warning-bg); color: #b47d00; } .trade-status--accepted { background: var(--gf-success-bg); color: #1a8a4a; } .trade-status--confirmed { background: var(--gf-info-bg); color: #1a6fb5; } .trade-context-card__expires { font-size: 0.6875rem; color: var(--gf-neutral-400); } .trade-context-card__actions { display: flex; gap: 0.5rem; justify-content: center; } .trade-context-card__actions .btn { font-size: 0.75rem; padding: 0.375rem 0.875rem; } /* Button variants for chat */ .btn--secondary-outline { background: none; border: 1.5px solid var(--gf-secondary); color: var(--gf-secondary); border-radius: var(--gf-radius-full); font-family: var(--gf-font-body); font-weight: 600; cursor: pointer; transition: all 0.15s ease; } .btn--secondary-outline:active { background: var(--gf-secondary-bg); } /* ============================================ Chat Messages Area ============================================ */ .chat-messages { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 0.75rem 0.75rem 1rem; background: var(--gf-bg-subtle); -webkit-overflow-scrolling: touch; } /* Date Separator */ .chat-date-separator { display: flex; align-items: center; justify-content: center; margin: 0.75rem 0; } .chat-date-separator span { font-family: var(--gf-font-body); font-size: 0.6875rem; font-weight: 600; color: var(--gf-neutral-400); background: var(--gf-neutral-100); padding: 0.1875rem 0.75rem; border-radius: var(--gf-radius-full); } /* System Messages */ .chat-system-msg { display: flex; align-items: center; justify-content: center; gap: 0.375rem; font-family: var(--gf-font-body); font-size: 0.6875rem; color: var(--gf-neutral-400); text-align: center; margin: 0.5rem 1rem; padding: 0.375rem 0; } .chat-system-msg svg { flex-shrink: 0; } .chat-system-msg--success { color: #1a8a4a; } /* ============================================ Message Bubbles ============================================ */ .chat-msg { display: flex; align-items: flex-end; gap: 0.375rem; margin-bottom: 0.25rem; max-width: 85%; } /* Incoming */ .chat-msg--in { align-self: flex-start; margin-right: auto; } .chat-msg--in .chat-msg__bubble { background: var(--gf-bg); color: var(--gf-neutral-800); border-radius: var(--gf-radius-lg) var(--gf-radius-lg) var(--gf-radius-lg) 0.25rem; box-shadow: var(--gf-shadow-sm); } /* Outgoing */ .chat-msg--out { flex-direction: row-reverse; align-self: flex-end; margin-left: auto; } .chat-msg--out .chat-msg__bubble { background: var(--gf-primary); color: #fff; border-radius: var(--gf-radius-lg) var(--gf-radius-lg) 0.25rem var(--gf-radius-lg); } .chat-msg--out .chat-msg__time { color: rgba(255, 255, 255, 0.7); } /* Avatar */ .chat-msg__avatar { width: 32px; height: 32px; border-radius: var(--gf-radius-full); object-fit: cover; flex-shrink: 0; background: var(--gf-neutral-200); } /* Bubble */ .chat-msg__bubble { padding: 0.5rem 0.75rem; max-width: 100%; } .chat-msg__bubble p { font-family: var(--gf-font-body); font-size: 0.875rem; line-height: 1.45; word-wrap: break-word; overflow-wrap: break-word; } .chat-msg__time { display: block; font-family: var(--gf-font-body); font-size: 0.625rem; color: var(--gf-neutral-400); margin-top: 0.25rem; text-align: right; } /* Consecutive messages from same sender — tighten spacing */ .chat-msg + .chat-msg--in, .chat-msg + .chat-msg--out { margin-top: 0.125rem; } /* Typing indicator */ .chat-msg--typing .chat-msg__bubble { padding: 0.625rem 0.875rem; } .typing-dots { display: flex; gap: 0.25rem; align-items: center; height: 1rem; } .typing-dots span { width: 6px; height: 6px; background: var(--gf-neutral-300); border-radius: var(--gf-radius-full); animation: typingBounce 1.4s infinite ease-in-out; } .typing-dots span:nth-child(2) { animation-delay: 0.2s; } .typing-dots span:nth-child(3) { animation-delay: 0.4s; } @keyframes typingBounce { 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; } 30% { transform: translateY(-4px); opacity: 1; } } /* ============================================ Chat Input Bar ============================================ */ .chat-input-bar { display: flex; align-items: flex-end; gap: 0.375rem; padding: 0.5rem 0.625rem; background: var(--gf-bg); border-top: 1px solid var(--gf-neutral-100); /* Safe area for notch phones */ padding-bottom: calc(0.5rem + env(safe-area-inset-bottom, 0px)); } .chat-input-bar__attach { display: flex; align-items: center; justify-content: center; width: 36px; height: 36px; background: none; border: none; color: var(--gf-neutral-500); cursor: pointer; border-radius: var(--gf-radius-full); flex-shrink: 0; transition: color 0.12s ease; } .chat-input-bar__attach:active { color: var(--gf-primary); background: var(--gf-primary-bg); } .chat-input-bar__field { flex: 1; min-width: 0; } .chat-input-bar__textarea { width: 100%; padding: 0.5rem 0.75rem; border: 1.5px solid var(--gf-neutral-200); border-radius: 1.125rem; background: var(--gf-bg-muted); font-family: var(--gf-font-body); font-size: 0.875rem; color: var(--gf-neutral-900); line-height: 1.4; resize: none; max-height: 120px; overflow-y: auto; transition: border-color 0.15s ease; } .chat-input-bar__textarea:focus { outline: none; border-color: var(--gf-primary); background: var(--gf-bg); } .chat-input-bar__textarea::placeholder { color: var(--gf-neutral-400); } .chat-input-bar__send { display: flex; align-items: center; justify-content: center; width: 36px; height: 36px; background: var(--gf-primary); border: none; color: #fff; border-radius: var(--gf-radius-full); cursor: pointer; flex-shrink: 0; transition: all 0.15s ease; } .chat-input-bar__send:disabled { background: var(--gf-neutral-200); color: var(--gf-neutral-400); cursor: default; } .chat-input-bar__send:not(:disabled):active { background: var(--gf-primary-dark); transform: scale(0.94); } /* ============================================ Quick Actions Panel ============================================ */ .chat-quick-actions { display: flex; gap: 0.5rem; padding: 0.75rem 1rem; background: var(--gf-bg); border-top: 1px solid var(--gf-neutral-100); overflow-x: auto; -webkit-overflow-scrolling: touch; } .chat-quick-action { display: flex; align-items: center; gap: 0.375rem; padding: 0.5rem 0.75rem; background: var(--gf-neutral-50); border: 1.5px solid var(--gf-neutral-200); border-radius: var(--gf-radius-full); font-family: var(--gf-font-body); font-size: 0.75rem; font-weight: 500; color: var(--gf-neutral-700); white-space: nowrap; cursor: pointer; transition: all 0.12s ease; } .chat-quick-action:active { background: var(--gf-primary-bg); border-color: var(--gf-primary-light); color: var(--gf-primary-dark); } /* ============================================ Bottom Nav Badge (for unread count) ============================================ */ .gf-bottom-nav__badge { position: absolute; top: 2px; right: calc(50% - 20px); min-width: 16px; height: 16px; padding: 0 0.25rem; background: var(--gf-primary); color: #fff; font-family: var(--gf-font-body); font-size: 0.625rem; font-weight: 700; border-radius: var(--gf-radius-full); display: flex; align-items: center; justify-content: center; } /* ============================================ Slide-in Menu / Navigation ============================================ */ .slide-menu-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.4); z-index: 999; opacity: 0; visibility: hidden; transition: opacity 0.25s ease, visibility 0.25s ease; } .slide-menu-overlay--active { opacity: 1; visibility: visible; } .slide-menu { position: fixed; top: 0; left: 0; bottom: 0; width: 80%; max-width: 320px; background: var(--gf-bg); z-index: 1000; transform: translateX(-100%); transition: transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94); display: flex; flex-direction: column; overflow-y: auto; -webkit-overflow-scrolling: touch; } .slide-menu--active { transform: translateX(0); } .slide-menu__header { padding: 1.25rem 1rem; border-bottom: 1px solid var(--gf-neutral-100); } .slide-menu__user { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.5rem; } .slide-menu__user img { width: 48px; height: 48px; border-radius: var(--gf-radius-full); object-fit: cover; background: var(--gf-neutral-200); } .slide-menu__user-name { font-family: var(--gf-font-heading); font-size: 1rem; font-weight: 700; color: var(--gf-neutral-900); } .slide-menu__user-handle { font-family: var(--gf-font-body); font-size: 0.75rem; color: var(--gf-neutral-400); } .slide-menu__stats { display: flex; gap: 1rem; font-family: var(--gf-font-body); font-size: 0.75rem; color: var(--gf-neutral-500); } .slide-menu__stats strong { color: var(--gf-neutral-800); font-weight: 700; } .slide-menu__nav { padding: 0.5rem 0; flex: 1; } .slide-menu__link { display: flex; align-items: center; gap: 0.75rem; padding: 0.75rem 1rem; text-decoration: none; font-family: var(--gf-font-body); font-size: 0.9375rem; font-weight: 500; color: var(--gf-neutral-700); transition: background 0.12s ease; } .slide-menu__link:active { background: var(--gf-neutral-50); } .slide-menu__link--active { color: var(--gf-primary); font-weight: 600; background: var(--gf-primary-bg); } .slide-menu__link svg { width: 22px; height: 22px; flex-shrink: 0; } .slide-menu__divider { height: 1px; background: var(--gf-neutral-100); margin: 0.375rem 0; } .slide-menu__footer { padding: 1rem; border-top: 1px solid var(--gf-neutral-100); } .slide-menu__footer-link { font-family: var(--gf-font-body); font-size: 0.8125rem; color: var(--gf-neutral-400); text-decoration: none; } /* ============================================ Responsive — Tablet & Desktop ============================================ */ @media (min-width: 768px) { .chat-msg { max-width: 65%; } .messages-inbox .container { max-width: 640px; margin: 0 auto; } .chat-header { padding: 0.5rem 1.5rem; } .chat-messages { padding: 1rem 1.5rem; } .chat-input-bar { padding: 0.625rem 1.5rem; } .slide-menu { max-width: 360px; } .conversation-item__trade-tag { max-width: 280px; } } @media (min-width: 1024px) { .chat-msg { max-width: 50%; } .messages-inbox .container { max-width: 720px; } }