Skip to content

fix(web): respect iOS safe areas across mobile chrome#2392

Open
jappyjan wants to merge 1 commit intopingdotgg:mainfrom
jappyjan:fix/mobile-safe-area
Open

fix(web): respect iOS safe areas across mobile chrome#2392
jappyjan wants to merge 1 commit intopingdotgg:mainfrom
jappyjan:fix/mobile-safe-area

Conversation

@jappyjan
Copy link
Copy Markdown

@jappyjan jappyjan commented Apr 28, 2026

Summary

`viewport-fit=cover` was already in place, but no element in the codebase honored `env(safe-area-inset-*)`. On iPhone the chat header / hamburger sat under the Dynamic Island, the composer hid behind the home indicator, and the mobile sidebar drawer ran under the camera in landscape.

Approach

  • Define four `@utility` classes (`pt-safe`, `pb-safe`, `pl-safe`, `pr-safe`) in `apps/web/src/index.css`. Each resolves to `max(env(safe-area-inset-*), 0px)`, so the value is 0 on devices without safe areas — desktop and Android are unaffected.
  • Apply the bare `*-safe` utilities on the mobile sidebar drawer's inner wrapper, where there's no other padding to combine with.
  • For the chat top bar (`ChatView.tsx`) and the composer wrapper (`ChatView.tsx`), use inline `pt-[calc(env(safe-area-inset-top)+0.5rem)]` etc. The existing `px-3 sm:px-5` base padding has to be preserved on devices without safe areas; bare `pl-safe`/`pr-safe` would override those due to Tailwind's specificity-collision resolution and zero them out.
  • The Electron branch in `ChatView.tsx`'s header is left as-is — it already uses its own `wco:h-[env(titlebar-area-height)]` sizing.

Test plan

  • iPhone portrait: chat title and hamburger fully visible below Dynamic Island
  • iPhone portrait: composer + send button sit above home indicator
  • iPhone landscape: sidebar drawer not clipped by camera
  • iPhone: open sidebar — its content not under the island
  • Desktop / non-iOS mobile: no visible padding change

Screenshots / video

6ACF9EC7-E508-4E77-AA80-4B007D45CAF0_1_102_o

Note

Respect iOS safe areas in mobile Chrome for chat header and sidebar

  • Adds pt-safe, pb-safe, pl-safe, and pr-safe Tailwind utilities in index.css that apply env(safe-area-inset-*) padding with a max(..., 0px) guard, requiring viewport-fit=cover.
  • Updates ChatView.tsx so the header and input bar use these inset-aware paddings on non-Electron web, with Electron retaining explicit horizontal padding.
  • Updates sidebar.tsx to wrap mobile sheet content with safe-area padding on all four sides, applying left or right inset based on which side the sidebar opens from.

Macroscope summarized 62ee822.


Note

Low Risk
Low risk: CSS/layout-only changes that adjust padding on iOS devices with safe-area insets; primary risk is unintended spacing regressions in mobile layouts.

Overview
Improves iOS viewport-fit=cover behavior by adding Tailwind @utility classes (pt-safe, pb-safe, pl-safe, pr-safe) that map padding to env(safe-area-inset-*).

Updates ChatView to apply safe-area-aware padding to the non-Electron chat header and composer container (including bottom inset for the input bar), and updates the mobile sidebar sheet wrapper to include safe-area padding so drawer content avoids notches and the home indicator.

Reviewed by Cursor Bugbot for commit 62ee822. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Improved layout spacing and alignment on the chat interface and mobile navigation sidebar for devices with notches, Dynamic Island, and other display safe-area features, ensuring proper positioning across all modern mobile devices.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

📝 Walkthrough

Walkthrough

Adds safe-area inset CSS utility classes and applies them across layout components (header, input bar, sidebar) to properly reserve space for device notches, Dynamic Island, and home indicator regions on iOS.

Changes

Cohort / File(s) Summary
Safe-Area CSS Utilities
apps/web/src/index.css
Introduces four new utility classes (pt-safe, pb-safe, pl-safe, pr-safe) using CSS env(safe-area-inset-*) variables for device-aware spacing.
Layout Component Updates
apps/web/src/components/ChatView.tsx, apps/web/src/components/ui/sidebar.tsx
Applies safe-area-aware padding to header, input bar, and mobile sidebar container; replaces fixed padding with computed values based on safe-area insets and conditional logic.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A notch-aware warren, at last!
Safe spaces emerge from the CSS vast,
Where padding respects each device's decree,
Dynamic Islands and notches now flee,
The sidebar hops safely, with spacing so wise,
No content lost under those iOS skies! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: adding support for iOS safe areas in the mobile UI, which is the primary focus of the changeset.
Description check ✅ Passed The description covers all required sections: what changed (summary of the problem), why (approach and reasoning), and UI changes (screenshot included). The content is complete and well-structured.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Apr 28, 2026
Comment thread apps/web/src/components/ui/sidebar.tsx Outdated
The viewport already opted into viewport-fit=cover but no element
honored env(safe-area-inset-*), so on an iPhone the chat header sat
under the Dynamic Island, the composer hid behind the home indicator,
and the mobile sidebar drawer ran under the camera in landscape.

Add pt-safe / pb-safe / pl-safe / pr-safe @Utility classes for the
sidebar drawer (no other padding to combine with) and use inline
calc() with env(safe-area-inset-*) on the chat top bar and the
composer wrapper, where the existing px/py values must be preserved
on devices without safe areas. Insets resolve to 0 on non-iOS, so
desktop and Android layouts are unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jappyjan jappyjan force-pushed the fix/mobile-safe-area branch from f9955bb to 62ee822 Compare April 28, 2026 21:54
@jappyjan jappyjan marked this pull request as ready for review April 28, 2026 21:56
@jappyjan
Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 28, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/web/src/index.css`:
- Around line 65-76: The Stylelint config is flagging Tailwind v4's custom
at-rule "@utility" in apps/web/src/index.css; update .stylelintrc.json to allow
it by adding or merging a rule entry for "at-rule-no-unknown" that supplies an
ignoreAtRules array including "utility" (and any other Tailwind at-rules you
use), e.g. add "rules": { "at-rule-no-unknown": [true, { "ignoreAtRules":
["utility"] }] } so the `@utility` declarations in index.css (padding-safe
utilities) are not treated as unknown at-rules.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 9fb2038b-732c-4a48-ac8c-83238e731845

📥 Commits

Reviewing files that changed from the base of the PR and between dbebc38 and 62ee822.

📒 Files selected for processing (3)
  • apps/web/src/components/ChatView.tsx
  • apps/web/src/components/ui/sidebar.tsx
  • apps/web/src/index.css

Comment thread apps/web/src/index.css
Comment on lines +65 to +76
@utility pt-safe {
padding-top: max(env(safe-area-inset-top), 0px);
}
@utility pb-safe {
padding-bottom: max(env(safe-area-inset-bottom), 0px);
}
@utility pl-safe {
padding-left: max(env(safe-area-inset-left), 0px);
}
@utility pr-safe {
padding-right: max(env(safe-area-inset-right), 0px);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Stylelint config files =="
fd -HI 'stylelint' .

echo
echo "== at-rule rule definitions / ignoreAtRules =="
rg -n --iglob '*stylelint*' 'scss/at-rule-no-unknown|at-rule-no-unknown|ignoreAtRules|utility|theme|variant|custom-variant|source'

echo
echo "== package.json stylelint references =="
rg -n '"stylelint"|stylelint' package.json

Repository: pingdotgg/t3code

Length of output: 157


🏁 Script executed:

cat .stylelintrc.json

Repository: pingdotgg/t3code

Length of output: 1420


Stylelint config must be updated to allow Tailwind v4 @utility at-rules.

The current .stylelintrc.json extends stylelint-config-standard-scss without configuring ignoreAtRules for Tailwind v4's custom at-rules. The @utility declarations at Lines 65, 68, 71, and 74 are valid Tailwind v4 syntax but will be flagged as unknown at-rules by stylelint, blocking CI.

Update .stylelintrc.json to add exception rules:

Configuration fix
{
  "extends": ["stylelint-config-standard-scss"],
  "rules": {
+   "scss/at-rule-no-unknown": [true, {
+     "ignoreAtRules": ["theme", "variant", "custom-variant", "utility", "source"]
+   }],
    "selector-id-pattern": null,
    ...
  }
}
🧰 Tools
🪛 Stylelint (17.9.0)

[error] 65-65: Unexpected unknown at-rule "@Utility" (scss/at-rule-no-unknown)

(scss/at-rule-no-unknown)


[error] 68-68: Unexpected unknown at-rule "@Utility" (scss/at-rule-no-unknown)

(scss/at-rule-no-unknown)


[error] 71-71: Unexpected unknown at-rule "@Utility" (scss/at-rule-no-unknown)

(scss/at-rule-no-unknown)


[error] 74-74: Unexpected unknown at-rule "@Utility" (scss/at-rule-no-unknown)

(scss/at-rule-no-unknown)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/index.css` around lines 65 - 76, The Stylelint config is
flagging Tailwind v4's custom at-rule "@utility" in apps/web/src/index.css;
update .stylelintrc.json to allow it by adding or merging a rule entry for
"at-rule-no-unknown" that supplies an ignoreAtRules array including "utility"
(and any other Tailwind at-rules you use), e.g. add "rules": {
"at-rule-no-unknown": [true, { "ignoreAtRules": ["utility"] }] } so the `@utility`
declarations in index.css (padding-safe utilities) are not treated as unknown
at-rules.

@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented Apr 28, 2026

Approvability

Verdict: Approved

Pure CSS changes adding iOS safe-area-inset support for mobile browsers. The utilities use standard env() values that fall back to 0 on non-iOS devices, making this a low-risk styling fix with no runtime logic changes.

You can customize Macroscope's approvability policy. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant