style(mobile): responsive sweep across Phase 7D pages + exam — 7F.3
This commit is contained in:
@@ -688,6 +688,10 @@ const Title = styled.h1`
|
||||
font-weight: 600;
|
||||
line-height: 1.15;
|
||||
letter-spacing: -0.04em;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
font-size: clamp(24px, 7vw, 30px);
|
||||
}
|
||||
`;
|
||||
|
||||
const Subtitle = styled.p`
|
||||
@@ -729,6 +733,10 @@ const StatsGrid = styled.section`
|
||||
@media (max-width: ${theme.breakpoint.desktop}) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
@media (max-width: ${theme.breakpoint.mobile}) {
|
||||
gap: ${theme.space.md};
|
||||
}
|
||||
`;
|
||||
|
||||
const baseMetricCard = css`
|
||||
@@ -819,6 +827,12 @@ const AccuracyMain = styled.div`
|
||||
align-items: center;
|
||||
gap: ${theme.space.md};
|
||||
min-height: 132px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.mobile}) {
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
min-height: auto;
|
||||
}
|
||||
`;
|
||||
|
||||
const AccuracyValue = styled.div`
|
||||
@@ -888,6 +902,7 @@ const SparklineBars = styled.div`
|
||||
gap: 6px;
|
||||
height: 44px;
|
||||
opacity: 0.92;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const SparkBar = styled.div<{ $active: boolean }>`
|
||||
@@ -1028,6 +1043,11 @@ const SectionHead = styled.div`
|
||||
justify-content: space-between;
|
||||
gap: ${theme.space.md};
|
||||
margin-bottom: 20px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.mobile}) {
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
}
|
||||
`;
|
||||
|
||||
const SectionTitleRow = styled.div`
|
||||
|
||||
@@ -500,6 +500,12 @@ const NavInner = styled.div`
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
flex-wrap: wrap;
|
||||
padding-top: 0.75rem;
|
||||
padding-bottom: 0.75rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const BrandLink = styled(Link)`
|
||||
@@ -563,6 +569,20 @@ const NavActions = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
width: 100%;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
@media (max-width: ${theme.breakpoint.mobile}) {
|
||||
justify-content: stretch;
|
||||
|
||||
a,
|
||||
button {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const LoginLink = styled(Link)`
|
||||
@@ -575,6 +595,16 @@ const LoginLink = styled(Link)`
|
||||
&:hover {
|
||||
color: ${theme.color.textBright};
|
||||
}
|
||||
|
||||
@media (max-width: ${theme.breakpoint.mobile}) {
|
||||
min-height: 44px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: ${theme.radius.md};
|
||||
border: 1px solid ${theme.color.borderSoftAlpha};
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
}
|
||||
`;
|
||||
|
||||
const Main = styled.main`
|
||||
@@ -582,6 +612,11 @@ const Main = styled.main`
|
||||
z-index: 1;
|
||||
padding-top: 8rem;
|
||||
padding-bottom: 6rem;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
padding-top: 6rem;
|
||||
padding-bottom: 4rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const HeroSection = styled.section`
|
||||
@@ -592,6 +627,11 @@ const HeroSection = styled.section`
|
||||
padding-top: 4rem;
|
||||
padding-bottom: 6rem;
|
||||
text-align: center;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
padding-top: 2rem;
|
||||
padding-bottom: 4rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const HeroBadge = styled.div`
|
||||
@@ -631,6 +671,8 @@ const HeroTitle = styled.h1`
|
||||
}
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
font-size: clamp(2.5rem, 12vw, 4rem);
|
||||
|
||||
br {
|
||||
display: block;
|
||||
}
|
||||
@@ -897,6 +939,10 @@ const Section = styled.section`
|
||||
const SectionHeader = styled.div`
|
||||
margin-bottom: 4rem;
|
||||
text-align: center;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const SectionTitle = styled.h2`
|
||||
@@ -911,6 +957,10 @@ const SectionBody = styled.p`
|
||||
color: ${theme.color.textSub};
|
||||
font-size: 1.125rem;
|
||||
line-height: 1.7;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
font-size: 1rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const FeatureGrid = styled.div`
|
||||
@@ -932,6 +982,10 @@ const FeatureCard = styled(Card)`
|
||||
border-color: rgba(124, 58, 237, 0.3);
|
||||
transform: translateY(-8px);
|
||||
}
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const FeatureIconWrap = styled.div`
|
||||
@@ -1061,6 +1115,10 @@ const StatsGrid = styled.div`
|
||||
@media (min-width: ${theme.breakpoint.tablet}) {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
gap: 1.5rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const StatBlock = styled.div``;
|
||||
@@ -1201,6 +1259,7 @@ const FaqItem = styled.div`
|
||||
border: 1px solid ${theme.color.borderSoftAlpha};
|
||||
border-radius: 0.875rem;
|
||||
background: ${theme.color.surfaceDeep};
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const FaqButton = styled.button`
|
||||
@@ -1265,6 +1324,10 @@ const FooterInner = styled.div`
|
||||
@media (min-width: ${theme.breakpoint.tablet}) {
|
||||
grid-template-columns: 1.2fr 2fr;
|
||||
}
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
gap: 2rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const FooterBrandColumn = styled.div`
|
||||
|
||||
@@ -631,6 +631,12 @@ const NavInner = styled.div`
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 1rem;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
flex-wrap: wrap;
|
||||
padding-top: 0.75rem;
|
||||
padding-bottom: 0.75rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const BrandLink = styled(Link)`
|
||||
@@ -695,6 +701,11 @@ const NavActions = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
width: 100%;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
`;
|
||||
|
||||
const LoginLink = styled(Link)`
|
||||
@@ -714,6 +725,11 @@ const Main = styled.main`
|
||||
z-index: 1;
|
||||
padding-top: 7rem;
|
||||
padding-bottom: 6rem;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
padding-top: 6rem;
|
||||
padding-bottom: 4rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const HeroSection = styled.section`
|
||||
@@ -785,6 +801,16 @@ const BillingToggle = styled.div`
|
||||
border: 1px solid ${theme.color.borderBrightAlpha};
|
||||
border-radius: ${theme.radius.pill};
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@media (max-width: ${theme.breakpoint.mobile}) {
|
||||
flex-wrap: wrap;
|
||||
border-radius: 20px;
|
||||
}
|
||||
`;
|
||||
|
||||
const ToggleButton = styled.button<{ $active: boolean }>`
|
||||
@@ -800,6 +826,11 @@ const ToggleButton = styled.button<{ $active: boolean }>`
|
||||
font-weight: 700;
|
||||
transition: background 0.2s ease, color 0.2s ease;
|
||||
cursor: pointer;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.mobile}) {
|
||||
justify-content: center;
|
||||
min-width: calc(50% - 0.25rem);
|
||||
}
|
||||
`;
|
||||
|
||||
const DiscountBadge = styled.span<{ $visible: boolean }>`
|
||||
@@ -850,6 +881,10 @@ const SectionBody = styled.p`
|
||||
margin: 1rem 0 0;
|
||||
color: ${theme.color.textSub};
|
||||
line-height: 1.75;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
font-size: 14px;
|
||||
}
|
||||
`;
|
||||
|
||||
const PricingGrid = styled.div`
|
||||
|
||||
@@ -831,6 +831,10 @@ const Title = styled.h1`
|
||||
line-height: 1.05;
|
||||
letter-spacing: -0.04em;
|
||||
color: ${theme.color.textBright};
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
font-size: clamp(24px, 7vw, 30px);
|
||||
}
|
||||
`;
|
||||
|
||||
const SubTitle = styled.p`
|
||||
@@ -844,6 +848,10 @@ const StatusText = styled.div`
|
||||
font-family: ${theme.font.mono};
|
||||
font-size: 12px;
|
||||
color: ${theme.color.textMute};
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
const MainGrid = styled.div`
|
||||
@@ -853,7 +861,7 @@ const MainGrid = styled.div`
|
||||
grid-template-columns: minmax(0, 1.45fr) minmax(300px, 0.85fr);
|
||||
gap: 24px;
|
||||
|
||||
@media (max-width: 1120px) {
|
||||
@media (max-width: ${theme.breakpoint.desktop}) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
`;
|
||||
@@ -889,6 +897,11 @@ const CardHeader = styled.div`
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
margin-bottom: 22px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.mobile}) {
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
}
|
||||
`;
|
||||
|
||||
const CardTitle = styled.h2`
|
||||
@@ -1101,6 +1114,7 @@ const SliderValue = styled.div`
|
||||
const SliderShell = styled.div`
|
||||
position: relative;
|
||||
padding-top: 28px;
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const SliderValueBubble = styled.div<{ $value: number }>`
|
||||
@@ -1362,6 +1376,10 @@ const HeatmapGrid = styled.div`
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
gap: 6px;
|
||||
}
|
||||
`;
|
||||
|
||||
const HeatCell = styled.div<{ $active: boolean; $level: 0 | 1 | 2 | 3 | 4 }>`
|
||||
@@ -1380,6 +1398,11 @@ const HeatCell = styled.div<{ $active: boolean; $level: 0 | 1 | 2 | 3 | 4 }>`
|
||||
}};
|
||||
box-shadow: ${({ $level }) =>
|
||||
$level === 4 ? '0 0 12px rgba(34, 197, 94, 0.25)' : 'none'};
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
min-height: 32px;
|
||||
border-radius: 7px;
|
||||
}
|
||||
`;
|
||||
|
||||
const HeatmapLegend = styled.div`
|
||||
|
||||
@@ -689,6 +689,10 @@ const Content = styled.main`
|
||||
padding: 40px 24px 64px;
|
||||
gap: 28px;
|
||||
}
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
padding: 20px 16px 104px;
|
||||
}
|
||||
`;
|
||||
|
||||
const FocusHeader = styled.header`
|
||||
@@ -708,6 +712,12 @@ const FocusHeader = styled.header`
|
||||
@media (min-width: ${theme.breakpoint.tablet}) {
|
||||
padding: 0 28px;
|
||||
}
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
height: 64px;
|
||||
gap: 10px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
const HeaderButton = styled.button`
|
||||
@@ -754,6 +764,10 @@ const LogoText = styled.span`
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.03em;
|
||||
color: ${theme.color.textBright};
|
||||
|
||||
@media (max-width: ${theme.breakpoint.mobile}) {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const FocusBadge = styled.span`
|
||||
@@ -767,6 +781,11 @@ const FocusBadge = styled.span`
|
||||
color: #a5b4fc;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.mobile}) {
|
||||
padding: 6px 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
`;
|
||||
|
||||
const TopPanel = styled.section`
|
||||
@@ -794,6 +813,10 @@ const PageTitle = styled.h1`
|
||||
line-height: 1.05;
|
||||
letter-spacing: -0.04em;
|
||||
color: ${theme.color.textBright};
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
font-size: clamp(24px, 7vw, 32px);
|
||||
}
|
||||
`;
|
||||
|
||||
const DayBadge = styled.span`
|
||||
@@ -843,6 +866,10 @@ const HintStrip = styled.div`
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const HintChip = styled.div`
|
||||
@@ -858,6 +885,11 @@ const StackStage = styled.section`
|
||||
position: relative;
|
||||
min-height: 480px;
|
||||
padding-top: 28px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
min-height: auto;
|
||||
padding-top: 20px;
|
||||
}
|
||||
`;
|
||||
|
||||
const sharedCardSurface = css`
|
||||
@@ -885,6 +917,10 @@ const GhostCard = styled.div<{ $depth: 1 | 2 }>`
|
||||
transform: translateY(32px) scale(0.955);
|
||||
opacity: 0.28;
|
||||
`}
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const GhostMeta = styled.div`
|
||||
@@ -922,6 +958,12 @@ const ActiveCard = styled.article`
|
||||
@media (min-width: ${theme.breakpoint.tablet}) {
|
||||
padding: 32px;
|
||||
}
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
min-height: auto;
|
||||
padding: 24px 20px;
|
||||
border-radius: 24px;
|
||||
}
|
||||
`;
|
||||
|
||||
const CardHeader = styled.div`
|
||||
@@ -1115,7 +1157,7 @@ const ActionGrid = styled.section`
|
||||
const ActionButton = styled.button<{
|
||||
$tone: 'incorrect' | 'partial' | 'correct' | 'skip';
|
||||
}>`
|
||||
min-height: 78px;
|
||||
min-height: 56px;
|
||||
padding: 18px 16px;
|
||||
border-radius: 20px;
|
||||
border: 1px solid;
|
||||
@@ -1136,6 +1178,11 @@ const ActionButton = styled.button<{
|
||||
opacity: 0.45;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
min-height: 56px;
|
||||
padding: 16px 14px;
|
||||
}
|
||||
`;
|
||||
|
||||
const ActionLabel = styled.span`
|
||||
|
||||
@@ -917,6 +917,10 @@ const PageTitle = styled.h1`
|
||||
font-size: clamp(28px, 4vw, 36px);
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.04em;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
font-size: clamp(24px, 7vw, 30px);
|
||||
}
|
||||
`;
|
||||
|
||||
const PageSubtitle = styled.p`
|
||||
@@ -934,6 +938,11 @@ const RangeSelector = styled.div`
|
||||
background: rgba(21, 21, 28, 0.84);
|
||||
gap: 4px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
overflow-x: auto;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
`;
|
||||
|
||||
const RangeButton = styled.button<{ $active: boolean }>`
|
||||
@@ -1060,6 +1069,10 @@ const HeatmapShell = styled.div`
|
||||
grid-template-columns: 28px minmax(560px, 1fr);
|
||||
gap: ${theme.space.sm};
|
||||
min-width: 0;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
min-width: 620px;
|
||||
}
|
||||
`;
|
||||
|
||||
const HeatmapAxis = styled.div`
|
||||
@@ -1238,6 +1251,10 @@ const ChartArea = styled.div`
|
||||
position: relative;
|
||||
width: 100%;
|
||||
min-height: 320px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
min-height: 260px;
|
||||
}
|
||||
`;
|
||||
|
||||
const TooltipBubble = styled.div<{ $x: number; $y: number }>`
|
||||
|
||||
@@ -335,7 +335,7 @@ export default function ExamPage() {
|
||||
건너뛰기
|
||||
</SubtleButton>
|
||||
<MobileOnlyButton type="button" onClick={() => setMobileNavOpen(true)}>
|
||||
답안 번호판
|
||||
문항 {problems[0]?.number ?? 1}-{problems[problems.length - 1]?.number ?? problems.length}
|
||||
</MobileOnlyButton>
|
||||
</CenterActions>
|
||||
|
||||
@@ -483,6 +483,10 @@ const BackButton = styled.button`
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: ${theme.color.textSub};
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
min-height: 44px;
|
||||
}
|
||||
`;
|
||||
|
||||
const TopTitle = styled.h1`
|
||||
@@ -490,12 +494,16 @@ const TopTitle = styled.h1`
|
||||
font-size: 18px;
|
||||
line-height: 1.35;
|
||||
color: ${theme.color.textBright};
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
grid-column: 1 / -1;
|
||||
order: 3;
|
||||
text-align: left;
|
||||
font-size: 16px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -543,6 +551,10 @@ const Surface = css`
|
||||
const PassageCard = styled.section`
|
||||
${Surface};
|
||||
padding: 20px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
padding: 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
const PassageHeader = styled.div`
|
||||
@@ -560,11 +572,19 @@ const PassageBody = styled.div`
|
||||
white-space: pre-wrap;
|
||||
line-height: 1.9;
|
||||
color: ${theme.color.textMain};
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
max-height: 200px;
|
||||
}
|
||||
`;
|
||||
|
||||
const ProblemCard = styled.section`
|
||||
${Surface};
|
||||
padding: 24px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
padding: 18px 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
const ProblemHeader = styled.div`
|
||||
@@ -573,6 +593,11 @@ const ProblemHeader = styled.div`
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-bottom: 18px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
}
|
||||
`;
|
||||
|
||||
const ProblemNumber = styled.div`
|
||||
@@ -601,6 +626,10 @@ const ProblemTitle = styled.h2`
|
||||
margin-bottom: 14px;
|
||||
font-size: 22px;
|
||||
line-height: 1.5;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
font-size: 18px;
|
||||
}
|
||||
`;
|
||||
|
||||
const ProblemBody = styled.div`
|
||||
@@ -622,6 +651,7 @@ const ChoiceButton = styled.button<{ $selected: boolean }>`
|
||||
gap: 14px;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
min-height: 56px;
|
||||
padding: 16px;
|
||||
border-radius: 20px;
|
||||
border: 1px solid
|
||||
@@ -666,6 +696,11 @@ const BottomBar = styled.div`
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
`;
|
||||
|
||||
const NavButton = styled.button`
|
||||
@@ -687,6 +722,10 @@ const CenterActions = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
display: contents;
|
||||
}
|
||||
`;
|
||||
|
||||
const SubtleButton = styled.button`
|
||||
@@ -714,6 +753,11 @@ const FinishButton = styled.button`
|
||||
color: white;
|
||||
font-weight: 800;
|
||||
box-shadow: ${theme.shadow.glowIndigo};
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
grid-column: 1 / -1;
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
const Sidebar = styled.aside`
|
||||
@@ -779,6 +823,7 @@ const GridButton = styled.button<{
|
||||
: 'rgba(255, 255, 255, 0.02)'};
|
||||
color: ${({ $skipped }) => ($skipped ? theme.color.textMute : theme.color.textBright)};
|
||||
font-weight: 800;
|
||||
min-height: 48px;
|
||||
|
||||
${({ $current }) =>
|
||||
$current &&
|
||||
|
||||
@@ -124,6 +124,10 @@ const Page = styled.div`
|
||||
background:
|
||||
radial-gradient(circle at top right, rgba(79, 70, 229, 0.2), transparent 24%),
|
||||
linear-gradient(180deg, #0f1016 0%, #141824 100%);
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
padding: 16px 16px 96px;
|
||||
}
|
||||
`;
|
||||
|
||||
const Wrap = styled.div`
|
||||
@@ -144,6 +148,10 @@ const Surface = css`
|
||||
const HeroCard = styled.section`
|
||||
${Surface};
|
||||
padding: 28px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
padding: 20px 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
const HeroEyebrow = styled.div`
|
||||
@@ -159,6 +167,10 @@ const HeroTitle = styled.h1`
|
||||
color: ${theme.color.textBright};
|
||||
font-size: 28px;
|
||||
line-height: 1.35;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
font-size: 22px;
|
||||
}
|
||||
`;
|
||||
|
||||
const HeroScore = styled.div`
|
||||
@@ -167,6 +179,10 @@ const HeroScore = styled.div`
|
||||
font-size: 40px;
|
||||
font-family: ${theme.font.display};
|
||||
font-weight: 900;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
font-size: 30px;
|
||||
}
|
||||
`;
|
||||
|
||||
const HeroSub = styled.p`
|
||||
@@ -214,6 +230,10 @@ const ButtonRow = styled.div`
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
margin-top: 24px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
flex-direction: column;
|
||||
}
|
||||
`;
|
||||
|
||||
const PrimaryButton = styled.button`
|
||||
@@ -263,6 +283,11 @@ const ReviewTop = styled.div`
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.mobile}) {
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
}
|
||||
`;
|
||||
|
||||
const ReviewNumber = styled.div`
|
||||
|
||||
@@ -341,6 +341,40 @@ function HistoryBody() {
|
||||
</HistoryTable>
|
||||
</TableScroll>
|
||||
|
||||
<MobileCardList>
|
||||
{pageItems.map((log) => (
|
||||
<HistoryMobileCard key={log.id}>
|
||||
<MobileCardTop>
|
||||
<MobileItemTitle>{log.title}</MobileItemTitle>
|
||||
<ResultChip $result={log.result}>
|
||||
<Icon name={resultIcon(log.result)} size={14} weight="bold" />
|
||||
{resultLabel(log.result)}
|
||||
</ResultChip>
|
||||
</MobileCardTop>
|
||||
|
||||
<SubjectTagStack>
|
||||
<SubjectBadge $color={log.subject?.color ?? theme.color.brandIndigo}>
|
||||
{log.subject?.name ?? '미분류'}
|
||||
</SubjectBadge>
|
||||
<TagText>{log.tag?.name ?? '태그 없음'}</TagText>
|
||||
</SubjectTagStack>
|
||||
|
||||
<MobileMetaRow>
|
||||
<MobileMetaLabel>학습일</MobileMetaLabel>
|
||||
<DatePrimary>{formatDateTime(log.studiedAt)}</DatePrimary>
|
||||
</MobileMetaRow>
|
||||
<MobileMetaRow>
|
||||
<MobileMetaLabel>경과</MobileMetaLabel>
|
||||
<DateSecondary>{timeAgo(log.studiedAt)}</DateSecondary>
|
||||
</MobileMetaRow>
|
||||
<MobileMetaRow>
|
||||
<MobileMetaLabel>기록</MobileMetaLabel>
|
||||
<ConfidenceValue>{formatDuration(log.timeSpent)}</ConfidenceValue>
|
||||
</MobileMetaRow>
|
||||
</HistoryMobileCard>
|
||||
))}
|
||||
</MobileCardList>
|
||||
|
||||
<PaginationBar>
|
||||
<PaginationMeta>
|
||||
총 {filteredLogs.length}개 항목 중 {(currentPage - 1) * PAGE_SIZE + 1}-
|
||||
@@ -637,6 +671,11 @@ const ToolbarBottom = styled.div`
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
`;
|
||||
|
||||
const SearchField = styled.label`
|
||||
@@ -740,6 +779,12 @@ const ResultTabRow = styled.div`
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
overflow-x: auto;
|
||||
flex-wrap: nowrap;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
`;
|
||||
|
||||
const ResultTab = styled.button<{ $active: boolean }>`
|
||||
@@ -768,6 +813,10 @@ const TableCard = styled.section`
|
||||
|
||||
const TableScroll = styled.div`
|
||||
overflow-x: auto;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const HistoryTable = styled.table`
|
||||
@@ -776,6 +825,54 @@ const HistoryTable = styled.table`
|
||||
border-collapse: collapse;
|
||||
`;
|
||||
|
||||
const MobileCardList = styled.div`
|
||||
display: none;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding: 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
const HistoryMobileCard = styled.article`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding: 16px;
|
||||
border-radius: 18px;
|
||||
border: 1px solid ${theme.color.borderSoftAlpha};
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
`;
|
||||
|
||||
const MobileCardTop = styled.div`
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
`;
|
||||
|
||||
const MobileItemTitle = styled.div`
|
||||
color: ${theme.color.textBright};
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 1.4;
|
||||
flex: 1;
|
||||
`;
|
||||
|
||||
const MobileMetaRow = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
`;
|
||||
|
||||
const MobileMetaLabel = styled.span`
|
||||
color: ${theme.color.textMute};
|
||||
font-size: 12px;
|
||||
`;
|
||||
|
||||
const TableHeadRow = styled.tr`
|
||||
background: rgba(255, 255, 255, 0.02);
|
||||
border-bottom: 1px solid ${theme.color.borderSoftAlpha};
|
||||
|
||||
@@ -505,6 +505,12 @@ const ModeTabs = styled.div`
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
overflow-x: auto;
|
||||
flex-wrap: nowrap;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
`;
|
||||
|
||||
const TabBtn = styled.button<{ $active: boolean }>`
|
||||
@@ -568,16 +574,19 @@ const FieldFrame = styled.div`
|
||||
`;
|
||||
|
||||
const FieldInput = styled(Input)`
|
||||
width: 100%;
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border-color: ${theme.color.borderSoftAlpha};
|
||||
`;
|
||||
|
||||
const FieldSelect = styled(Select)`
|
||||
width: 100%;
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border-color: ${theme.color.borderSoftAlpha};
|
||||
`;
|
||||
|
||||
const FieldTextarea = styled(Textarea)`
|
||||
width: 100%;
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border-color: ${theme.color.borderSoftAlpha};
|
||||
`;
|
||||
@@ -680,7 +689,7 @@ const ProblemSetGrid = styled.div`
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: ${theme.space.md};
|
||||
|
||||
@media (max-width: ${theme.breakpoint.desktop}) {
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
`;
|
||||
@@ -700,6 +709,10 @@ const CardTop = styled.div`
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.mobile}) {
|
||||
flex-direction: column;
|
||||
}
|
||||
`;
|
||||
|
||||
const CardTags = styled.div`
|
||||
|
||||
@@ -921,6 +921,12 @@ const TabsRow = styled.div`
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
overflow-x: auto;
|
||||
flex-wrap: nowrap;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
`;
|
||||
|
||||
const TabButton = styled.button<{ $active: boolean }>`
|
||||
@@ -978,6 +984,10 @@ const SubjectCard = styled.section`
|
||||
background:
|
||||
linear-gradient(180deg, rgba(21, 21, 28, 0.94) 0%, rgba(17, 19, 29, 0.98) 100%);
|
||||
box-shadow: ${theme.shadow.cardElevated};
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
border-radius: 20px;
|
||||
}
|
||||
`;
|
||||
|
||||
const SubjectCardHeader = styled.div`
|
||||
@@ -992,6 +1002,7 @@ const SubjectCardHeader = styled.div`
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
padding: 18px 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -1131,6 +1142,7 @@ const TagRow = styled.div`
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
gap: 12px;
|
||||
padding: 14px 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -1162,6 +1174,10 @@ const PValueText = styled.div`
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
order: 2;
|
||||
}
|
||||
|
||||
@media (max-width: ${theme.breakpoint.mobile}) {
|
||||
margin-top: -2px;
|
||||
}
|
||||
`;
|
||||
|
||||
const BarCell = styled.div`
|
||||
|
||||
@@ -266,6 +266,10 @@ const Page = styled.main`
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 32px 20px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
padding: 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
const GlowOrb = styled.div`
|
||||
@@ -294,7 +298,7 @@ const Shell = styled.div`
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
max-width: 420px;
|
||||
max-width: 480px;
|
||||
`;
|
||||
|
||||
const BrandBlock = styled.header`
|
||||
@@ -355,6 +359,7 @@ const BrandSub = styled.p`
|
||||
`;
|
||||
|
||||
const AuthSurface = styled(Card)`
|
||||
width: 100%;
|
||||
background: rgba(21, 21, 28, 0.88);
|
||||
border: 1px solid ${theme.color.borderSoftAlpha};
|
||||
box-shadow: ${theme.shadow.cardElevated};
|
||||
@@ -365,6 +370,10 @@ const AuthSurface = styled(Card)`
|
||||
padding: 28px;
|
||||
border-radius: 24px;
|
||||
}
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
padding: 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
const TabRail = styled.div`
|
||||
@@ -377,6 +386,10 @@ const TabRail = styled.div`
|
||||
border-radius: 18px;
|
||||
background: rgba(0, 0, 0, 0.22);
|
||||
border: 1px solid rgba(255, 255, 255, 0.04);
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
const TabIndicator = styled.div<{ $tab: AuthTab }>`
|
||||
@@ -396,7 +409,7 @@ const TabIndicator = styled.div<{ $tab: AuthTab }>`
|
||||
const TabButton = styled.button<{ $active: boolean }>`
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
min-height: 44px;
|
||||
min-height: 48px;
|
||||
border: 0;
|
||||
border-radius: 14px;
|
||||
background: transparent;
|
||||
@@ -538,9 +551,10 @@ const PrimaryButton = styled(Button).attrs({
|
||||
`;
|
||||
|
||||
const DemoButton = styled.button`
|
||||
width: fit-content;
|
||||
width: 100%;
|
||||
margin: -2px auto 0;
|
||||
padding: 4px 8px;
|
||||
min-height: 44px;
|
||||
padding: 8px 12px;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: ${theme.color.textMute};
|
||||
|
||||
@@ -164,6 +164,10 @@ const HeroCard = styled(Card)`
|
||||
linear-gradient(145deg, rgba(21, 21, 28, 0.94) 0%, rgba(15, 15, 20, 0.98) 100%);
|
||||
box-shadow: ${theme.shadow.cardElevated};
|
||||
text-align: center;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
padding: 24px 20px;
|
||||
}
|
||||
`;
|
||||
|
||||
const WelcomeEyebrow = styled.p`
|
||||
@@ -239,6 +243,11 @@ const StepCard = styled.div<{ $enabled: boolean; $completed: boolean }>`
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
transition: transform 0.16s ease, border-color 0.16s ease, background 0.16s ease;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
${({ $completed, $enabled }) => {
|
||||
if ($completed) {
|
||||
return css`
|
||||
|
||||
@@ -64,6 +64,7 @@ export default function AppShell({ children, requireOnboarding = true }: Props)
|
||||
const Layout = styled.div`
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
overflow-x: clip;
|
||||
`;
|
||||
|
||||
const Main = styled.main<{ $withNav: boolean }>`
|
||||
@@ -76,8 +77,8 @@ const Main = styled.main<{ $withNav: boolean }>`
|
||||
min-width: 0;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
padding: ${theme.space.md};
|
||||
padding-bottom: ${({ $withNav }) => ($withNav ? '80px' : theme.space.md)};
|
||||
padding: 16px;
|
||||
padding-bottom: ${({ $withNav }) => ($withNav ? '88px' : '16px')};
|
||||
}
|
||||
|
||||
@media (min-width: ${theme.breakpoint.desktop}) {
|
||||
|
||||
@@ -4,14 +4,15 @@ import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import styled from 'styled-components';
|
||||
import { Icon } from '@/components/ui/Icon';
|
||||
import { theme } from '@/styles/theme';
|
||||
|
||||
const TABS = [
|
||||
{ href: '/dashboard', label: '대시', icon: '🏠' },
|
||||
{ href: '/review', label: '복습', icon: '📖' },
|
||||
{ href: '/study', label: '학습', icon: '✏️' },
|
||||
{ href: '/stats', label: '통계', icon: '📊' },
|
||||
{ href: '/profile', label: '프로필', icon: '👤' },
|
||||
{ href: '/dashboard', label: '대시보드', icon: 'squares-four' as const },
|
||||
{ href: '/review', label: '복습', icon: 'arrows-clockwise' as const },
|
||||
{ href: '/study', label: '학습', icon: 'pencil-simple' as const },
|
||||
{ href: '/subjects', label: '과목', icon: 'folders' as const },
|
||||
{ href: '/stats', label: '통계', icon: 'trend-up' as const },
|
||||
];
|
||||
|
||||
export default function BottomNav() {
|
||||
@@ -22,7 +23,14 @@ export default function BottomNav() {
|
||||
const active = pathname.startsWith(t.href);
|
||||
return (
|
||||
<Tab key={t.href} href={t.href} $active={active}>
|
||||
<Icon>{t.icon}</Icon>
|
||||
<IconWrap>
|
||||
<Icon
|
||||
name={t.icon}
|
||||
size={18}
|
||||
weight={active ? 'fill' : 'regular'}
|
||||
color="currentColor"
|
||||
/>
|
||||
</IconWrap>
|
||||
<Label>{t.label}</Label>
|
||||
</Tab>
|
||||
);
|
||||
@@ -40,8 +48,9 @@ const Nav = styled.nav`
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: ${theme.color.surface};
|
||||
border-top: 1px solid ${theme.color.border};
|
||||
background: rgba(21, 21, 28, 0.96);
|
||||
border-top: 1px solid ${theme.color.borderSoftAlpha};
|
||||
backdrop-filter: blur(18px);
|
||||
z-index: 100;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
@@ -49,22 +58,29 @@ const Nav = styled.nav`
|
||||
|
||||
const Tab = styled(Link)<{ $active: boolean }>`
|
||||
flex: 1;
|
||||
min-height: 64px;
|
||||
min-height: 72px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 3px;
|
||||
color: ${({ $active }) => ($active ? theme.color.accent : theme.color.textMute)};
|
||||
transition: color 0.15s;
|
||||
border-top: 2px solid ${({ $active }) => ($active ? theme.color.accent : 'transparent')};
|
||||
gap: 6px;
|
||||
padding: 10px 8px;
|
||||
color: ${({ $active }) => ($active ? theme.color.textBright : theme.color.textMute)};
|
||||
transition: color 0.15s ease;
|
||||
border-top: 2px solid
|
||||
${({ $active }) => ($active ? theme.color.brandIndigo : 'transparent')};
|
||||
`;
|
||||
|
||||
const Icon = styled.span`
|
||||
font-size: 20px;
|
||||
const IconWrap = styled.span`
|
||||
min-width: 24px;
|
||||
min-height: 24px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
`;
|
||||
|
||||
const Label = styled.span`
|
||||
font-size: 10px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user