From 564c16e431c484c37d541d0774ba125abeb747ea Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Thu, 12 Mar 2026 13:41:08 -0700 Subject: [PATCH] feat(responsive): adaptive tablet/fold breakpoints, touch/pen parity, pointer events drag Add intermediate breakpoints (960px, 1024px, 900px, 640px, 600px) for tablets and fold devices across all 12 rApp components. Add touch-action: manipulation and -webkit-tap-highlight-color to eliminate 300ms tap delay. Fix undersized tap targets (<36px) in rtasks, rfiles, rinbox, and rcart. Replace HTML5 drag API with pointer events in rtasks kanban and rchoices ranking for touch/pen/mouse parity. Replace mouseenter/ mouseleave with pointerenter/pointerleave in rchoices spider chart with click toggle. Co-Authored-By: Claude Opus 4.6 --- modules/rcal/components/folk-calendar-view.ts | 13 ++- .../rcart/components/folk-group-buy-page.ts | 16 ++-- modules/rcart/components/folk-payment-page.ts | 8 +- .../rcart/components/folk-payment-request.ts | 7 +- .../components/folk-choices-dashboard.ts | 76 ++++++++++------- .../rfiles/components/folk-file-browser.ts | 5 +- .../rforum/components/folk-forum-dashboard.ts | 3 +- .../rinbox/components/folk-inbox-client.ts | 10 +-- modules/rnotes/components/folk-notes-app.ts | 6 +- modules/rtasks/components/folk-tasks-board.ts | 82 ++++++++++--------- .../rvote/components/folk-vote-dashboard.ts | 7 +- .../rwallet/components/folk-wallet-viewer.ts | 7 +- 12 files changed, 150 insertions(+), 90 deletions(-) diff --git a/modules/rcal/components/folk-calendar-view.ts b/modules/rcal/components/folk-calendar-view.ts index ea6492f..1ffe4e0 100644 --- a/modules/rcal/components/folk-calendar-view.ts +++ b/modules/rcal/components/folk-calendar-view.ts @@ -2298,8 +2298,9 @@ class FolkCalendarView extends HTMLElement { private getStyles(): string { return ` - :host { display: block; font-family: system-ui, -apple-system, sans-serif; color: var(--rs-text-primary); padding: 0.5rem; } + :host { display: block; font-family: system-ui, -apple-system, sans-serif; color: var(--rs-text-primary); padding: 0.5rem; -webkit-tap-highlight-color: transparent; } * { box-sizing: border-box; } + button, a, input, select, textarea, [role="button"] { touch-action: manipulation; } .error { color: var(--rs-error); text-align: center; padding: 8px; } @@ -2606,6 +2607,16 @@ class FolkCalendarView extends HTMLElement { .kbd-hint { text-align: center; font-size: 10px; color: var(--rs-text-muted); margin-top: 12px; padding-top: 8px; border-top: 1px solid var(--rs-border-subtle); } .kbd-hint kbd { padding: 1px 4px; background: var(--rs-bg-surface); border: 1px solid var(--rs-border); border-radius: 3px; font-family: inherit; font-size: 9px; } + /* ── Tablet/Adaptive ── */ + @media (max-width: 1024px) { + .main-layout--docked { grid-template-columns: 1fr auto 320px; } + } + @media (max-width: 900px) and (min-width: 769px) { + .main-layout--docked { grid-template-columns: 1fr; } + .zoom-bar--middle { display: none; } + .ev-label { display: none; } + .day { min-height: 64px; } + } /* ── Mobile ── */ @media (max-width: 768px) { :host { padding: 0.25rem; } diff --git a/modules/rcart/components/folk-group-buy-page.ts b/modules/rcart/components/folk-group-buy-page.ts index 7b7383d..f09ea68 100644 --- a/modules/rcart/components/folk-group-buy-page.ts +++ b/modules/rcart/components/folk-group-buy-page.ts @@ -436,8 +436,9 @@ class FolkGroupBuyPage extends HTMLElement { private getStyles(): string { return ` - :host { display: block; padding: 2rem 1.5rem; width: 100%; max-width: 960px; } + :host { display: block; padding: 2rem 1.5rem; width: 100%; max-width: 960px; -webkit-tap-highlight-color: transparent; } * { box-sizing: border-box; } + button, a, input, select, textarea, [role="button"] { touch-action: manipulation; } .loading { text-align: center; padding: 3rem; color: var(--rs-text-secondary); } .error { background: rgba(239,68,68,0.1); border: 1px solid var(--rs-error); border-radius: 8px; padding: 1.5rem; color: #fca5a5; text-align: center; } @@ -585,7 +586,7 @@ class FolkGroupBuyPage extends HTMLElement { } .btn-pledge:hover { background: linear-gradient(135deg, #16a34a, #15803d); box-shadow: 0 4px 12px rgba(34,197,94,0.4); } .btn-pledge:disabled { opacity: 0.5; cursor: not-allowed; } - .btn-sm { padding: 0.375rem 0.75rem; font-size: 0.8125rem; } + .btn-sm { padding: 0.375rem 0.75rem; font-size: 0.8125rem; min-height: 36px; min-width: 36px; } .btn-lg { padding: 0.875rem; font-size: 1rem; width: 100%; } .pledge-disclaimer { color: var(--rs-text-muted); font-size: 0.6875rem; text-align: center; margin: 0; line-height: 1.4; } @@ -628,6 +629,11 @@ class FolkGroupBuyPage extends HTMLElement { .commons-stat-projected .commons-stat-value { color: #a855f7; } .commons-stat-arrow { color: var(--rs-text-muted); font-size: 1.25rem; } + @media (max-width: 960px) and (min-width: 769px) { + .main-grid { grid-template-columns: 1fr 280px; } + .hero-img { width: 160px; height: 160px; } + .tier-commons { display: none; } + } @media (max-width: 768px) { :host { padding: 1.25rem 1rem; } .hero { flex-direction: column; padding: 1.25rem; } @@ -638,6 +644,9 @@ class FolkGroupBuyPage extends HTMLElement { .commons-stats { flex-wrap: wrap; gap: 0.5rem; } .fill-visual { flex-direction: column; align-items: center; } .fill-visual__marker-label { display: none; } + .sim-controls { flex-direction: column; align-items: stretch; gap: 0.5rem; } + .sim-label { white-space: normal; } + .commons-controls { flex-direction: column; align-items: stretch; gap: 0.5rem; } } @media (max-width: 480px) { :host { padding: 1rem 0.75rem; } @@ -649,9 +658,6 @@ class FolkGroupBuyPage extends HTMLElement { .tier-row { padding: 0.625rem 0.75rem; gap: 0.5rem; } .tier-qty { font-size: 0.8125rem; min-width: 2.5rem; } .tier-price { font-size: 0.8125rem; } - .sim-controls { flex-direction: column; align-items: stretch; gap: 0.5rem; } - .sim-label { white-space: normal; } - .commons-controls { flex-direction: column; align-items: stretch; gap: 0.5rem; } .pledge-panel { padding: 1rem; } h3 { font-size: 0.9375rem; } } diff --git a/modules/rcart/components/folk-payment-page.ts b/modules/rcart/components/folk-payment-page.ts index 80d2ee7..65b8caa 100644 --- a/modules/rcart/components/folk-payment-page.ts +++ b/modules/rcart/components/folk-payment-page.ts @@ -651,8 +651,9 @@ class FolkPaymentPage extends HTMLElement { private getStyles(): string { return ` - :host { display: block; padding: 1.5rem; width: 100%; max-width: 560px; } + :host { display: block; padding: 1.5rem; width: 100%; max-width: 560px; -webkit-tap-highlight-color: transparent; } * { box-sizing: border-box; } + button, a, input, select, textarea, [role="button"] { touch-action: manipulation; } .payment-page { } @@ -739,7 +740,7 @@ class FolkPaymentPage extends HTMLElement { .terminal-msg { text-align: center; padding: 2rem; color: var(--rs-text-muted); font-size: 0.875rem; } .transak-container { border-radius: 8px; overflow: hidden; border: 1px solid var(--rs-border); } - .transak-iframe { width: 100%; height: 600px; border: none; } + .transak-iframe { width: 100%; height: clamp(400px, 72vh, 600px); border: none; } .footer { margin-top: 2rem; border-top: 1px solid var(--rs-border); padding-top: 1.5rem; } .qr-section { display: flex; flex-direction: column; align-items: center; gap: 1rem; } @@ -750,6 +751,9 @@ class FolkPaymentPage extends HTMLElement { .loading { text-align: center; padding: 3rem; color: var(--rs-text-secondary); } .error { text-align: center; padding: 3rem; color: #f87171; } + @media (max-width: 600px) { + :host { padding: 1.25rem 1rem; } + } @media (max-width: 480px) { :host { padding: 1rem; } .header { flex-direction: column; align-items: flex-start; gap: 0.5rem; } diff --git a/modules/rcart/components/folk-payment-request.ts b/modules/rcart/components/folk-payment-request.ts index 092687d..a17eb20 100644 --- a/modules/rcart/components/folk-payment-request.ts +++ b/modules/rcart/components/folk-payment-request.ts @@ -614,8 +614,9 @@ class FolkPaymentRequest extends HTMLElement { private getStyles(): string { return ` - :host { display: block; padding: 1.5rem; width: 100%; max-width: 520px; } + :host { display: block; padding: 1.5rem; width: 100%; max-width: 520px; -webkit-tap-highlight-color: transparent; } * { box-sizing: border-box; } + button, a, input, select, textarea, [role="button"] { touch-action: manipulation; } .page-title { color: var(--rs-text-primary); font-size: 1.5rem; font-weight: 700; margin: 0 0 0.25rem; text-align: center; } .page-subtitle { color: var(--rs-text-secondary); font-size: 0.9375rem; text-align: center; margin: 0 0 2rem; } @@ -695,6 +696,10 @@ class FolkPaymentRequest extends HTMLElement { .share-input { flex: 1; padding: 0.5rem 0.75rem; border-radius: 8px; border: 1px solid var(--rs-input-border); background: var(--rs-input-bg); color: var(--rs-input-text); font-size: 0.75rem; font-family: monospace; } .action-row { display: flex; gap: 0.5rem; justify-content: center; flex-wrap: wrap; } + @media (max-width: 600px) { + .toggle-btn { font-size: 0.75rem; } + .method-desc { display: none; } + } @media (max-width: 480px) { .field-row { flex-direction: column; } .action-row { flex-direction: column; } diff --git a/modules/rchoices/components/folk-choices-dashboard.ts b/modules/rchoices/components/folk-choices-dashboard.ts index ea12111..ffc2696 100644 --- a/modules/rchoices/components/folk-choices-dashboard.ts +++ b/modules/rchoices/components/folk-choices-dashboard.ts @@ -94,7 +94,8 @@ class FolkChoicesDashboard extends HTMLElement { this.shadow.innerHTML = `