UI refinements and New features#3
Conversation
- Explicitly set turbopack.root in next.config.ts to resolve workspace detection warnings and OS error 1450. - Added sliding arrow animations and hover effects to primary buttons in globals.css. - Integrated yeni assets and UI updates in page.tsx.
WalkthroughThis PR redesigns the Tectonic EVM Web UI landing page and supporting infrastructure. It updates project documentation with real branding and getting-started steps, configures Turbopack, introduces a comprehensive global design system with animations and interactive components, and restructures the home page with new helper components for animated text and number rendering, along with redesigned content sections including features, deployments, and community panels. ChangesLanding Page Redesign with Design System Updates
Sequence DiagramsequenceDiagram
participant User
participant Page as Home Page
participant TypewriterComp as Typewriter Helper
participant Observer as IntersectionObserver
participant CountUpComp as CountUpValue Helper
User->>Page: Load landing page
Page->>Observer: Set up feature card observer
Page->>Page: Render features, deployments, stats
User->>User: Scroll to features section
Observer->>Observer: Detect features in viewport
Observer->>Page: Trigger feature card animations
Page->>Page: Fade/translate feature cards in
User->>User: Scroll to StableCoin section
TypewriterComp->>TypewriterComp: Detect heading in viewport
TypewriterComp->>TypewriterComp: Reveal text character by character
User->>User: Scroll to deployments section
CountUpComp->>CountUpComp: Animate protocol stats 0 → final value
Page->>Page: Render deployments table with reserve bars
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested labels
🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/page.tsx (1)
1-638:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftExternalize user-visible strings for internationalization.
All user-facing text throughout this component is hardcoded in English (e.g., "Why Tectonic?", "Join the Community", "Connect Wallet"). This violates the internationalization guideline that requires externalizing user-visible strings to resource files (i18n).
Consider integrating an i18n solution such as
next-intlorreact-i18nextto support multiple languages.As per coding guidelines, user-visible strings should be externalized to resource files (i18n).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/page.tsx` around lines 1 - 638, Hardcoded user-facing strings in the Home component (and child usage of Typewriter) must be externalized for i18n: install and configure an i18n library (e.g., next-intl or react-i18next) and wrap the app with the provider, move all user-visible strings into resource files (JSON) and replace literal strings in Home, Typewriter, the features array, deployments array, protocolStats labels, nav links, hero/title/subtitle, buttons, section headings like "Why Tectonic?", "Join the Community", and footer text with translation keys accessed via the library's hook (e.g., t('nav.home'), t('hero.title'), t('features.forcedRedemptions.title'), etc. Ensure Typewriter receives translated text from the t(...) call, and update any server/client boundary (app root or layout) to load locale messages so Home and its arrays use the localized strings at render time.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/globals.css`:
- Around line 288-293: The .how-connector visibility rules conflict: it's hidden
by default, shown in `@media` (min-width: 768px), but later re-shown in `@media`
(max-width: 640px), producing unintended visibility on very small and large
screens but hidden on 641–767px; fix by removing or adjusting the `@media`
(max-width: 640px) rule that sets .how-connector to display:block (or change it
to match the desktop breakpoint), so only the intended breakpoints control
visibility—update references to .how-connector and the two media queries (`@media`
(min-width: 768px) and `@media` (max-width: 640px)) accordingly.
- Around line 519-571: The CSS uses high-specificity contextual selectors and
several !important rules for the arrow animation (.glassy-navbar
.btn-primary.btn-hero, .btn-primary .btn-arrow, .btn-primary:hover .btn-arrow);
refactor by introducing a dedicated modifier class (e.g., .btn-with-arrow or
.btn-hero-arrow) applied directly to the button element and update all rules to
target .btn-with-arrow and its child .btn-arrow (remove contextual
.glassy-navbar dependency), then eliminate unnecessary !important declarations
and redundant transitions so rules like the text shift, arrow initial state, and
hover transitions are controlled only by .btn-with-arrow span and
.btn-with-arrow .btn-arrow and .btn-with-arrow:hover .btn-arrow.
- Around line 18-23: The global CSS currently forces .font-serif to use the sans
stack via "!important"; instead remove this override and update components that
still apply .font-serif to use the correct sans class (or remove the class).
Search the codebase for usages of the "font-serif" class, update those
components to use the project's sans utility (or delete the class where not
needed), and then remove the .font-serif rule from globals.css so no
"!important" override remains (identify the .font-serif selector in globals.css
to delete it).
- Around line 620-626: Rename the keyframe identifier from fadeUp to kebab-case
fade-up and update its usage in the CSS class .animate-fade-up so the `@keyframes`
definition and the animation declaration match (replace animation: fadeUp ...
with animation: fade-up ... and change the `@keyframes` name to fade-up).
In `@app/page.tsx`:
- Around line 428-433: Add an inline comment next to the reserve bar width
expression Math.max(60, deployment.ratio - 55) that explains the scaling logic:
document that deployment.ratio is converted to a percent width with a floor of
60% to keep the bar visible, and why 55 is subtracted (e.g., to offset baseline
or map the raw ratio into the visible range), and state the intended
min/max/edge-case behavior so future readers understand the magic numbers used.
- Around line 179-182: The nav anchors currently use hardcoded
http://localhost:3000/ URLs for Home, Deployments and Docs; update their hrefs
to relative/hash paths instead (e.g., "/" or "/#deployments" or "`#docs`") to
avoid localhost in production while keeping the external Github anchor (the <a>
elements with className "nav-link px-2 py-2 text-lg font-medium" and link text
Home/Deployments/Docs/Github) unchanged except for its absolute URL and existing
target/rel attributes.
- Around line 7-45: The Typewriter component leaks the interval because the id
is scoped inside the IntersectionObserver callback and not cleared on unmount;
update the useEffect in Typewriter to store the interval id in a ref (e.g.,
intervalRef = useRef<number | null>(null)), assign the id when calling
setInterval, clearInterval(intervalRef.current) in the useEffect cleanup, and
also clear and null out intervalRef.current when the typing finishes (where
clearInterval(id) currently occurs) so the interval is always cleared on unmount
or completion.
- Around line 328-333: Remove the incorrect TypeScript suppression comment that
precedes the Typewriter usage: delete the `@ts-ignore-next-line` directive that
is above the <Typewriter .../> component in app/page.tsx; since this file starts
with "use client" and the Typewriter component is defined in the same file, no
suppression is needed and ESLint prefers not using `@ts-ignore` (use
`@ts-expect-error` only when truly required). Ensure the Typewriter JSX remains
unchanged and run the linter to confirm the ban-ts-comment warning is resolved.
In `@next.config.ts`:
- Around line 3-8: The config currently uses __dirname for turbopack.root which
can break under ESM; change turbopack.root assignment in nextConfig to derive
the directory from import.meta.url instead (e.g., compute a projectRoot from new
URL('.', import.meta.url) or via fileURLToPath(import.meta.url) and then
path.resolve(projectRoot)). Update the turbopack.root value in the nextConfig
object (referencing nextConfig and turbopack.root) to use that computed ESM-safe
directory instead of __dirname.
---
Outside diff comments:
In `@app/page.tsx`:
- Around line 1-638: Hardcoded user-facing strings in the Home component (and
child usage of Typewriter) must be externalized for i18n: install and configure
an i18n library (e.g., next-intl or react-i18next) and wrap the app with the
provider, move all user-visible strings into resource files (JSON) and replace
literal strings in Home, Typewriter, the features array, deployments array,
protocolStats labels, nav links, hero/title/subtitle, buttons, section headings
like "Why Tectonic?", "Join the Community", and footer text with translation
keys accessed via the library's hook (e.g., t('nav.home'), t('hero.title'),
t('features.forcedRedemptions.title'), etc. Ensure Typewriter receives
translated text from the t(...) call, and update any server/client boundary (app
root or layout) to load locale messages so Home and its arrays use the localized
strings at render time.
🪄 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: Path: .coderabbit.yml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 29f041e8-6bf3-4b83-a14c-df0cf487f284
⛔ Files ignored due to path filters (2)
public/Logo.svgis excluded by!**/*.svgpublic/undraw_crypto-portfolio_mf2i (1).svgis excluded by!**/*.svg
📒 Files selected for processing (4)
README.mdapp/globals.cssapp/page.tsxnext.config.ts
| /* Ensure any use of the `font-serif` utility renders with the site's sans stack | ||
| so remaining components that still include `font-serif` will match the | ||
| standardized typography. */ | ||
| .font-serif { | ||
| font-family: var(--font-sans) !important; | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoff
Consider removing .font-serif usage instead of forcing override.
Using !important to override .font-serif suggests that components are still using this class when they shouldn't. A cleaner approach would be to update those components to use the correct class directly.
♻️ Better approach
Search for .font-serif usage across the codebase and update those instances to use the appropriate sans-serif class or remove the class entirely.
#!/bin/bash
# Find all uses of font-serif class
rg -n 'font-serif' --glob '*.{tsx,jsx,ts,js}' -C2🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/globals.css` around lines 18 - 23, The global CSS currently forces
.font-serif to use the sans stack via "!important"; instead remove this override
and update components that still apply .font-serif to use the correct sans class
(or remove the class). Search the codebase for usages of the "font-serif" class,
update those components to use the project's sans utility (or delete the class
where not needed), and then remove the .font-serif rule from globals.css so no
"!important" override remains (identify the .font-serif selector in globals.css
to delete it).
| /* HOW IT WORKS connector (dotted curved path behind cards) */ | ||
| .how-connector { display: none; } | ||
| @media (min-width: 768px) { | ||
| /* position connector relative to container center and push it up for behind-cards placement */ | ||
| .how-connector { display: block; position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-80px); width: 100%; height: 160px; pointer-events: none; z-index: 0; } | ||
| } |
There was a problem hiding this comment.
Verify mobile display logic for .how-connector.
The .how-connector is hidden by default (line 289), then shown on desktop with @media (min-width: 768px) (lines 290-293), but then shown again on mobile with @media (max-width: 640px) (line 702). This creates contradictory visibility rules where the connector would be visible on very small screens (≤640px) and larger screens (≥768px), but hidden on medium screens (641-767px). This is likely unintentional.
🔧 Suggested fix
If the connector should only show on desktop, remove line 702. If it should show everywhere except medium screens, clarify with a comment.
`@media` (max-width: 640px) {
- .how-connector { display: block; position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-80px); width: 100%; height: 160px; pointer-events: none; z-index: 0; }
.glassy-navbar .animated-word { gap: 0.12rem !important; font-size: 0.95rem !important; }Also applies to: 702-702
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/globals.css` around lines 288 - 293, The .how-connector visibility rules
conflict: it's hidden by default, shown in `@media` (min-width: 768px), but later
re-shown in `@media` (max-width: 640px), producing unintended visibility on very
small and large screens but hidden on 641–767px; fix by removing or adjusting
the `@media` (max-width: 640px) rule that sets .how-connector to display:block (or
change it to match the desktop breakpoint), so only the intended breakpoints
control visibility—update references to .how-connector and the two media queries
(`@media` (min-width: 768px) and `@media` (max-width: 640px)) accordingly.
| .glassy-navbar .btn-primary.btn-hero span { | ||
| display: inline-block; | ||
| transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1); | ||
| /* Force text to stay centered by default */ | ||
| transform: translateX(0); | ||
| } | ||
|
|
||
| .glassy-navbar .btn-primary.btn-hero .btn-arrow { | ||
| width: 16px !important; | ||
| height: 16px !important; | ||
| position: absolute; | ||
| /* Position it off-screen to the right by default */ | ||
| right: 20px; | ||
| opacity: 0; | ||
| transform: translateX(20px); | ||
| transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.2s ease; | ||
| margin-left: 0; | ||
| pointer-events: none; | ||
| } | ||
|
|
||
| .glassy-navbar .btn-primary.btn-hero:hover span { | ||
| /* Shift text left to make room for arrow */ | ||
| transform: translateX(-12px); | ||
| } | ||
|
|
||
| .glassy-navbar .btn-primary.btn-hero:hover .btn-arrow { | ||
| opacity: 1 !important; | ||
| /* Slide arrow in from the right to its final position */ | ||
| transform: translateX(0) !important; | ||
| } | ||
|
|
||
| /* Arrow that slides in on hover for primary buttons */ | ||
| .btn-primary { | ||
| position: relative; | ||
| overflow: visible; | ||
| } | ||
|
|
||
| .btn-arrow { | ||
| display: inline-block; | ||
| margin-left: 6px; | ||
| font-weight: 700; /* bolder arrow glyph */ | ||
| transform: translateX(-10px) scale(0.98); | ||
| opacity: 0; | ||
| transition: transform 640ms cubic-bezier(.16,.84,.24,1), opacity 360ms ease; | ||
| will-change: transform, opacity; | ||
| } | ||
|
|
||
| .btn-primary:hover .btn-arrow, | ||
| .btn-primary:focus .btn-arrow { | ||
| transform: translateX(0) scale(1) !important; | ||
| opacity: 1 !important; | ||
| } | ||
|
|
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoff
Simplify button arrow animation selectors to reduce specificity complexity.
The button arrow animation system uses multiple nested selectors and !important declarations, which can make it harder to maintain and extend. Consider using more specific class names instead of relying on contextual selectors.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/globals.css` around lines 519 - 571, The CSS uses high-specificity
contextual selectors and several !important rules for the arrow animation
(.glassy-navbar .btn-primary.btn-hero, .btn-primary .btn-arrow,
.btn-primary:hover .btn-arrow); refactor by introducing a dedicated modifier
class (e.g., .btn-with-arrow or .btn-hero-arrow) applied directly to the button
element and update all rules to target .btn-with-arrow and its child .btn-arrow
(remove contextual .glassy-navbar dependency), then eliminate unnecessary
!important declarations and redundant transitions so rules like the text shift,
arrow initial state, and hover transitions are controlled only by
.btn-with-arrow span and .btn-with-arrow .btn-arrow and .btn-with-arrow:hover
.btn-arrow.
| @keyframes fadeUp { | ||
| from { opacity: 0; transform: translateY(10px); } | ||
| to { opacity: 1; transform: translateY(0); } | ||
| } | ||
| .animate-fade-up { | ||
| animation: fadeUp 520ms cubic-bezier(.22,.98,.38,.99) both; | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | 💤 Low value
Use kebab-case for keyframe names to follow CSS conventions.
The keyframe name fadeUp should be fade-up to match CSS naming conventions and satisfy the stylelint rule.
♻️ Proposed fix
-@keyframes fadeUp {
+@keyframes fade-up {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.animate-fade-up {
- animation: fadeUp 520ms cubic-bezier(.22,.98,.38,.99) both;
+ animation: fade-up 520ms cubic-bezier(.22,.98,.38,.99) both;
}🧰 Tools
🪛 Stylelint (17.12.0)
[error] 620-620: Expected keyframe name "fadeUp" to be kebab-case (keyframes-name-pattern)
(keyframes-name-pattern)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/globals.css` around lines 620 - 626, Rename the keyframe identifier from
fadeUp to kebab-case fade-up and update its usage in the CSS class
.animate-fade-up so the `@keyframes` definition and the animation declaration
match (replace animation: fadeUp ... with animation: fade-up ... and change the
`@keyframes` name to fade-up).
| <div className="w-full max-w-[130px]"> | ||
| <div className="mb-2 text-sm font-semibold text-emerald-600">{deployment.reserve}</div> | ||
| <div className="h-2 rounded-full bg-slate-200"> | ||
| <div className="h-2 rounded-full bg-emerald-500" style={{ width: `${Math.max(60, deployment.ratio - 55)}%` }} /> | ||
| </div> | ||
| </div> |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | 💤 Low value
Consider adding comment to explain reserve ratio bar width calculation.
The formula Math.max(60, deployment.ratio - 55) uses magic numbers that make the scaling logic unclear. A brief comment explaining the min/max range and why 55 is subtracted would improve maintainability.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@app/page.tsx` around lines 428 - 433, Add an inline comment next to the
reserve bar width expression Math.max(60, deployment.ratio - 55) that explains
the scaling logic: document that deployment.ratio is converted to a percent
width with a floor of 60% to keep the bar visible, and why 55 is subtracted
(e.g., to offset baseline or map the raw ratio into the visible range), and
state the intended min/max/edge-case behavior so future readers understand the
magic numbers used.
| import path from "path"; | ||
|
|
||
| const nextConfig: NextConfig = { | ||
| /* config options here */ | ||
| turbopack: { | ||
| root: path.resolve(__dirname), | ||
| }, |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check package.json for type: module and verify config runs successfully
cat package.json | jq -r '.type // "commonjs"'
# Check if tsconfig has module settings that would affect this
cat tsconfig.json | jq -r '.compilerOptions.module // "not set"'
# Try to find any Next.js documentation about __dirname in config
rg -i '__dirname' --glob 'next.config.*' -C2Repository: StabilityNexus/Tectonic-EVM-WebUI
Length of output: 259
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== package.json relevant fields =="
jq '{type, name, private}' package.json
echo
echo "== tsconfig.json compilerOptions.module =="
jq '.compilerOptions.module, .compilerOptions' tsconfig.json | head -n 80
echo
echo "== next.config.ts top =="
ls -la next.config.ts
sed -n '1,80p' next.config.ts | nl -ba
echo
echo "== any next config loader hints (next.config.* / scripts) =="
rg -n "next\.config\.(js|cjs|mjs|ts|cts|mts)" -S . || trueRepository: StabilityNexus/Tectonic-EVM-WebUI
Length of output: 821
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== package.json type + next version =="
jq '{type, dependencies, devDependencies, nextVersion: (.dependencies.next // .devDependencies.next)}' package.json
echo
echo "== next.config.ts contents (with line numbers) =="
cat -n next.config.ts | sed -n '1,120p'
echo
echo "== any ts/esm config hints =="
rg -n "\"type\"\\s*:\\s*\"module\"" package.json || true
rg -n "ts-node|esm|type: module|next.config\\." package.json **/package.json 2>/dev/null || trueRepository: StabilityNexus/Tectonic-EVM-WebUI
Length of output: 853
🌐 Web query:
Next.js 16 next.config.ts __dirname availability ESM CommonJS jiti how Next loads next.config.ts
💡 Result:
In Next.js 16, the handling of next.config.ts depends on the Node.js version and the project's module system. Availability of dirname In ESM environments ("type": "module" in package.json), the standard Node.js dirname variable is not available by default because it is a CommonJS-specific global [1]. Attempts to use bare dirname in ESM next.config.ts typically result in undefined [1]. When using ESM-compliant patterns such as import.meta.url or import.meta.dirname (in Node 20.11+), behavior can be inconsistent across development, build, and production deployment environments [1][2]. Specifically, some users have reported that import.meta.dirname may resolve correctly in preview but fail in production due to differences in how Next.js transpiles or adapts the config for different environments [1]. How Next.js Loads next.config.ts Next.js 16 uses a two-fold strategy for loading next.config.ts based on the Node.js environment: 1. Native Node.js Resolution (Recommended): Next.js 16 detects the Node.js native TypeScript resolver (introduced in Node.js 22.7.0 and enabled by default in 22.18.0+) via the process.features.typescript flag [3][4][5]. When this feature is detected, Next.js uses Node's native capabilities to resolve the configuration file, enabling support for ESM syntax such as top-level await and dynamic import [3][5]. 2. Legacy/Transpilation Fallback: For older Node.js versions or when the native resolver is not available, Next.js employs an internal transpilation process [6]. Historically, this process often involved a require-hook that limited module resolution to CommonJS, which could cause issues with ESM-only packages [3][7][4]. Recommendations - For projects using "type": "module", you can write next.config.ts using ESM syntax [3][5]. - If you encounter issues with ESM/CommonJS interoperability or native path resolution, it is recommended to use next.config.mts (the.mts extension explicitly signals an ESM module to Node.js, even in CommonJS-default projects) [3][5]. - Avoid relying on dirname in ESM configurations. Instead, prefer modern ESM path manipulation: import { fileURLToPath } from 'url'; import { dirname } from 'path'; const dirname = dirname(fileURLToPath(import.meta.url)); Note: Next.js 16 introduced optimizations to how the configuration is loaded during next dev [8][9]. In some cases, checking for specific process.argv flags (like 'dev') within the config file may no longer return true, and you should rely on NODE_ENV or the phase constant instead [8][9].
Citations:
- 1: modifyConfig crashes production build with ERR_INVALID_ARG_TYPE when turbopack.root uses import.meta.dirname in ESM next.config.ts (works on preview) vercel/vercel#16405
- 2:
__dirnameis/ROOT/...instead of real path in Turbopack vercel/next.js#86476 - 3: https://nextjs.org/docs/pages/api-reference/config/typescript
- 4: feat: use Node.js native TS resolver for
next.config.tsvercel/next.js#83240 - 5: https://nextjs.org/docs/app/api-reference/config/typescript
- 6: https://github.com/vercel/next.js/blob/canary/packages/next/src/server/config.ts
- 7: https://chris.lu/web_development/tutorials/next-js-static-first-mdx-starterkit/next-config
- 8: https://nextjs.org/docs/app/guides/upgrading/version-16
- 9: https://github.com/vercel/next.js/blob/v16.2.1/docs/01-app/02-guides/upgrading/version-16.mdx
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== package.json top (first 40 lines) =="
sed -n '1,80p' package.json | cat
echo
echo "== explicit presence of type field =="
rg -n '"type"\s*:' package.json || trueRepository: StabilityNexus/Tectonic-EVM-WebUI
Length of output: 682
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== package.json top (first 80 lines) =="
sed -n '1,80p' package.json | cat
echo
echo "== explicit presence of type field =="
rg -n '"type"\s*:' package.json || trueRepository: StabilityNexus/Tectonic-EVM-WebUI
Length of output: 682
Avoid relying on __dirname for turbopack.root in next.config.ts.
package.json has no "type": "module" (default CommonJS), so __dirname should generally be available for Next 16 config loading. Still, since tsconfig.json uses "module": "esnext", switching to an ESM-safe approach (derive the directory from import.meta.url) prevents possible __dirname is not defined errors if the config is evaluated as ESM.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@next.config.ts` around lines 3 - 8, The config currently uses __dirname for
turbopack.root which can break under ESM; change turbopack.root assignment in
nextConfig to derive the directory from import.meta.url instead (e.g., compute a
projectRoot from new URL('.', import.meta.url) or via
fileURLToPath(import.meta.url) and then path.resolve(projectRoot)). Update the
turbopack.root value in the nextConfig object (referencing nextConfig and
turbopack.root) to use that computed ESM-safe directory instead of __dirname.
- Fix memory leak in Typewriter by cleaning up setInterval on unmount. - Remove hardcoded localhost URLs in footer and navigation. - Remove unnecessary @ts-expect-error and misleading comments.
Description
This PR focuses on refining the overall UI and improving the user experience across the application.
Changes Made
Impact
These changes improve the overall look and feel of the application, enhance usability, and provide a smoother and more user-friendly experience while maintaining existing functionality.
new.mp4
Summary by CodeRabbit
New Features
Style
Documentation