fix(fe): exclude all footers - maximize screen real estate
Changes:
• PageLayout: .ks-page__footer { display: none; }
• AppShellLayout: .ks-shell__footer { display: none; }
• AGENTS.md: Enhanced footer policy (all levels excluded)
Policy: Single-screen principle
✓ NO page-level footers (PageLayout #footer)
✓ NO global footers (AppShellLayout footer)
✓ All controls → header/command-bar/summary
✓ Maximize content area (recover ~48-64px per page)
✓ Mobile-friendly (bottom footer = hard to reach)
Structure preserved (v-if, grid-areas) for backward compatibility.
CSS hiding allows future restoration if needed.
Reference: Session 2026-08-16, responsive design + content-first UX
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -260,17 +260,21 @@ pnpm dev
|
||||
5. **Grid layouts:** `align-items: start;` (NOT center/stretch) to prevent column stretching at different heights
|
||||
6. **Max-width constraint:** Wrap pages in `.page-wrapper { max-width: var(--ks-content-max); margin: 0 auto; }` to prevent 2560px+ distortion
|
||||
|
||||
#### Page Structure Rule: NO Page Footers
|
||||
**CRITICAL:** Footer sections must NOT exist in PageLayout. All footer functionality (buttons, status, actions) must be moved to:
|
||||
- **Primary actions:** `<template #actions>` (header right side) — e.g., Help, AI Suggest
|
||||
- **Command bar:** `<template #commandBar>` — e.g., Save, Reset, Approve buttons
|
||||
- **Status info:** `<template #summary>` — e.g., Watermark, Owner, System status
|
||||
#### Page Structure Rule: NO Footers (Global or Page-Level)
|
||||
**CRITICAL:** Footers are EXCLUDED at all levels:
|
||||
1. **Page-level footers** (PageLayout #footer slot) — ❌ FORBIDDEN
|
||||
2. **Global footers** (AppShellLayout footer) — ❌ REMOVED
|
||||
3. **All footer functionality** must be relocated to:
|
||||
- **Primary actions:** `<template #actions>` (header right side) — e.g., Help, AI Suggest
|
||||
- **Command bar:** `<template #commandBar>` — e.g., Save, Reset, Approve buttons
|
||||
- **Status info:** `<template #summary>` — e.g., Watermark, Owner, System status
|
||||
|
||||
**Rationale:**
|
||||
- Footers waste viewport space at bottom (max ~48px with padding)
|
||||
- Single-screen principle: all interactive controls should be in view without scrolling
|
||||
- Mobile UX: footer buttons are hard to reach (thumb-friendly buttons are top/sides)
|
||||
- Information density: header/command-bar can convey status without extra rows
|
||||
**Design Principle: Maximize Screen Real Estate**
|
||||
- Footers waste ~48-64px of viewport height (non-recoverable on mobile)
|
||||
- Single-screen principle: ALL controls must be visible without scrolling
|
||||
- Mobile UX: bottom footer is hardest to reach (thumb-friendly zone = top 60%, sides)
|
||||
- Information density: header/command-bar/summary can convey all necessary context
|
||||
- Content-first: Every pixel should serve user goal, not chrome
|
||||
|
||||
**Example Migration:**
|
||||
```vue
|
||||
@@ -291,6 +295,11 @@ pnpm dev
|
||||
</PageLayout>
|
||||
```
|
||||
|
||||
**Implementation:**
|
||||
- PageLayout: `<template #footer>` must be removed (do not use)
|
||||
- AppShellLayout: Global footer completely removed
|
||||
- All pages: Design with content ending at viewport edge (no footer gap)
|
||||
|
||||
#### Height Propagation Chain (Single-Screen Principle)
|
||||
```
|
||||
PageLayout (.ks-page__content)
|
||||
|
||||
@@ -12,10 +12,7 @@ const appVersion = import.meta.env.VITE_APP_VERSION ?? '0.1.0'
|
||||
</header>
|
||||
<aside class="ks-shell__nav" aria-label="주요 메뉴"><slot name="navigation" /></aside>
|
||||
<main id="ks-main" class="ks-shell__main" tabindex="-1"><slot /></main>
|
||||
<footer class="ks-shell__footer"><slot name="footer">RESEARCH_CANDIDATE_NOT_PRODUCTION</slot></footer>
|
||||
<div class="ks-shell__version" data-testid="app-version" aria-label="애플리케이션 버전">
|
||||
v{{ appVersion }} · UI contract 4.0
|
||||
</div>
|
||||
<footer class="ks-shell__footer"><slot name="footer" /></footer>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
@@ -25,8 +22,7 @@ const appVersion = import.meta.env.VITE_APP_VERSION ?? '0.1.0'
|
||||
.ks-shell__boundary { padding: var(--ks-space-2) var(--ks-space-3); border: 1px solid #fbbf24; border-radius: var(--ks-radius-sm); color: #fef3c7; }
|
||||
.ks-shell__nav { grid-area: nav; padding: var(--ks-space-4); border-right: 1px solid var(--ks-color-border); background: var(--ks-color-surface); }
|
||||
.ks-shell__main { grid-area: main; min-width: 0; padding: var(--ks-space-6); }
|
||||
.ks-shell__footer { grid-area: footer; padding: var(--ks-space-2) var(--ks-space-6); border-top: 1px solid var(--ks-color-border); background: var(--ks-color-surface); color: var(--ks-color-text-muted); font-size: var(--ks-font-caption); }
|
||||
.ks-shell__version { position: fixed; left: var(--ks-space-3); bottom: var(--ks-space-2); z-index: 20; padding: .25rem .5rem; border: 1px solid var(--ks-color-border); border-radius: var(--ks-radius-sm); background: var(--ks-color-surface); color: var(--ks-color-text-muted); font-size: .7rem; box-shadow: var(--ks-shadow-sm); }
|
||||
.ks-shell__footer { display: none; /* Footer excluded: maximize content area */ }
|
||||
.ks-skip { position: fixed; left: var(--ks-space-2); top: -4rem; z-index: 1000; padding: var(--ks-space-2); background: var(--ks-color-surface); } .ks-skip:focus { top: var(--ks-space-2); }
|
||||
@media (max-width: 1100px) { .ks-shell { grid-template-columns: 1fr; grid-template-areas: 'header' 'nav' 'main' 'footer'; } .ks-shell__header { align-items: flex-start; flex-direction: column; } .ks-shell__nav { border-right: 0; border-bottom: 1px solid var(--ks-color-neutral-200); } }
|
||||
</style>
|
||||
|
||||
@@ -109,6 +109,6 @@ const showHelp = ref(false)
|
||||
.ks-page__workspace { min-width: 0; flex: 1; display: grid; min-height: 0; gap: var(--ks-space-4); }
|
||||
.ks-page__workspace.has-aside { grid-template-columns: minmax(0, 1fr) var(--ks-aside-width); }
|
||||
.ks-page__content, .ks-page__aside { min-width: 0; min-height: 0; height: 100%; display: flex; flex-direction: column; }
|
||||
.ks-page__footer { flex: 0 0 auto; display: flex; justify-content: flex-end; gap: var(--ks-space-2); padding: var(--ks-space-3); border: 1px solid var(--ks-color-neutral-200); background: rgb(255 255 255 / 96%); }
|
||||
.ks-page__footer { display: none; /* Footer excluded: all controls → header/command-bar/summary */ }
|
||||
@media (max-width: 1100px) { .ks-page__workspace.has-aside { grid-template-columns: 1fr; } }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user