feat(cv): implement fixed sidebar layout for segment_0

Move title bar, language switcher, photo, About Me and captcha into a
fixed left sidebar (280px). Main content scrolls independently with
margin-left offset. On mobile (<=768px) sidebar reverts to static flow
at the top. Reorder SegmentGeneral children: photo -> title/description
-> captcha. Photo uses object-fit: contain to prevent cropping.

Made-with: Cursor
master
sii42400 2026-04-17 13:05:29 +02:00
parent e4cd265281
commit 319a6a705c
2 changed files with 198 additions and 240 deletions

View File

@ -389,6 +389,16 @@ const SegmentGeneral = ({ segment }) => {
className="segment_image cover"
alt={segment.title}
/>
<div className="segment_header_middle">
<div className="segment_title segment_title_image">
{segment.description_title}
</div>
{segment.description && (
<div className="segment_description segment_description_general">
{segment.description}
</div>
)}
</div>
{!isVerified ? (
<SimpleCaptchaWrapper
onVerified={setIsVerified}
@ -418,16 +428,6 @@ const SegmentGeneral = ({ segment }) => {
)}
</div>
)}
<div className="segment_header_middle">
<div className="segment_title segment_title_image">
{segment.description_title}
</div>
{segment.description && (
<div className="segment_description segment_description_general">
{segment.description}
</div>
)}
</div>
</div>
);
};
@ -534,8 +534,9 @@ const IndexPage = () => {
}
return (
<>
<div className="global_segment">
<div className="page_layout">
<aside className="sidebar">
<div className="sidebar_header">
<div className="title_bar">
{content[0]["title"]}
</div>
@ -544,20 +545,25 @@ const IndexPage = () => {
{content_swapper}
</div>
</div>
</div>
<SegmentGeneral
key="general_sidebar"
segment={content[0]}
/>
</aside>
<main className="main_content">
{
content.map((value, index) => (
content.slice(1).map((value, index) => (
<Segment
key={`segment_${index}`}
index={index}
key={`segment_${index + 1}`}
index={index + 1}
segment={value}
/>
))
}
<div className="foot"></div>
</main>
</div>
<div className="foot">
</div>
</>
)
}

View File

@ -30,9 +30,149 @@ body {
src: url("../images/Lato-Regular.ttf");
}
.global_segment {
margin-left: auto;
margin-right: auto;
.page_layout {
display: flex;
flex-direction: row;
min-height: 100vh;
}
.sidebar {
position: fixed;
left: 0;
top: 0;
bottom: 0;
width: 280px;
overflow-y: auto;
background-color: darken($background_color, 3%);
padding: 20px 15px;
box-sizing: border-box;
z-index: 10;
border-right: 1px solid rgba($color, 0.1);
display: flex;
flex-direction: column;
&::-webkit-scrollbar {
width: 4px;
}
&::-webkit-scrollbar-track {
background: transparent;
}
&::-webkit-scrollbar-thumb {
background: rgba($color, 0.2);
border-radius: 2px;
}
.sidebar_header {
display: flex;
align-items: center;
margin-bottom: 20px;
}
.title_bar {
flex: 1;
text-align: left;
font-family: $title_font_family;
font-size: 18pt;
color: $color;
}
.language_bar {
text-align: right;
font-size: 18pt;
cursor: pointer;
}
.segment_general {
float: none;
margin-top: 0;
width: 100%;
position: static;
display: flex;
flex-direction: column;
.segment_image {
float: none;
width: 100%;
height: auto;
background-color: transparent;
}
.cover {
object-fit: contain;
object-position: top;
}
.segment_header_middle {
position: static;
left: auto;
right: auto;
width: 100%;
margin-top: 12px;
}
.segment_title_image {
float: none;
margin-left: 0;
width: 100%;
}
.segment_description_general {
clear: none;
float: none;
width: auto;
overflow: visible;
margin: 10px 0 0 0;
padding: 0;
font-size: 8.5pt;
text-align: justify;
}
}
.captcha-container {
float: none;
width: 100%;
margin-top: 15px;
.captcha-form {
width: 100%;
height: auto;
padding: 12px 10px;
box-sizing: border-box;
p {
margin-top: 10px;
margin-bottom: 10px;
font-size: 9pt;
}
form {
margin-top: 10px;
}
}
}
.segment_content_image {
float: none;
width: 100%;
height: auto;
padding: 12px 10px;
box-sizing: border-box;
font-size: $regular_image_font_size;
font-family: $regular_font_family;
font-weight: bold;
background-color: $div_background_color;
color: $color;
.segment_image_item {
margin-top: 5px;
}
}
}
.main_content {
margin-left: 280px;
max-width: 21cm;
width: 100%;
padding: 0 15px;
@ -63,23 +203,6 @@ body {
padding-top: 15px;
}
.title_bar {
margin-top: 20px;
width: 80%;
float: left;
text-align: left;
font-family: $title_font_family;
font-size: 24pt;
}
.language_bar {
margin-top: 20px;
width: 20%;
float: left;
text-align: right;
font-size: 24pt;
}
.segment_general {
float: left;
margin-top: 30px;
@ -341,48 +464,22 @@ body {
}
@media (max-width: 768px) {
.global_segment {
padding: 0 10px;
.title_bar {
font-size: 18pt;
width: 75%;
.page_layout {
flex-direction: column;
}
.language_bar {
width: 25%;
font-size: 18pt;
}
.segment_general {
.segment_image {
width: 140px;
height: 170px;
}
.segment_content_image {
width: 120px;
height: 150px;
.sidebar {
position: static;
width: 100%;
height: auto;
overflow: visible;
border-right: none;
padding: 10px;
font-size: 6pt;
}
.segment_header_middle {
left: 140px;
right: 150px;
}
.segment_title_image {
margin-left: -20px;
padding-top: 12.5px;
padding-bottom: 7.5px;
height: 30px;
}
.segment_description_general {
font-size: 8pt;
}
}
.main_content {
margin-left: 0;
padding: 0 10px;
.segment_title {
width: 200px;
@ -424,36 +521,10 @@ body {
margin: 6px 0 6px 14px;
}
}
.captcha-container .captcha-form {
width: 140px;
height: 170px;
font-size: 8pt;
padding: 0 8px;
p {
margin-top: 8px;
margin-bottom: 8px;
font-size: 8pt;
}
form {
margin-top: 8px;
}
.captcha-input {
margin-bottom: 8px;
}
.captcha-input, .captcha-button {
padding: 5px;
font-size: 7pt;
}
}
}
@media (max-width: 500px) {
.global_segment {
.sidebar {
.title_bar {
font-size: 15pt;
}
@ -461,38 +532,9 @@ body {
.language_bar {
font-size: 15pt;
}
.segment_general {
.segment_image {
width: 100px;
height: 125px;
}
.segment_content_image {
width: 90px;
height: 110px;
padding: 8px;
font-size: 4pt;
}
.segment_header_middle {
left: 95px;
right: 108px;
}
.segment_title_image {
margin-left: -10px;
padding-top: 10px;
padding-bottom: 0px;
height: 33px;
}
.segment_description_general {
font-size: 6.5pt;
margin: 6px 6px 6px 14px;
}
}
.main_content {
.segment_title {
width: 160px;
font-size: 13pt;
@ -531,44 +573,12 @@ body {
font-size: 7.5pt;
margin: 6px 0 6px 14px;
}
.captcha-container .captcha-form {
width: 100px;
height: 125px;
font-size: 7pt;
padding: 0 6px;
p {
margin-top: 5px;
margin-bottom: 5px;
font-size: 6.25pt;
}
a {
padding-left: 22px;
padding-right: 22px;
font-size: 6pt;
}
form {
margin-top: 2px;
}
.captcha-input {
margin-bottom: 2px;
}
.captcha-input, .captcha-button {
padding: 4px;
font-size: 6pt;
}
}
}
}
@media (max-width: 415px) {
.global_segment {
padding: 0 6px;
.sidebar {
padding: 6px;
.title_bar {
font-size: 11pt;
@ -577,36 +587,10 @@ body {
.language_bar {
font-size: 11pt;
}
.segment_general {
.segment_image {
width: 80px;
height: 100px;
}
.segment_content_image {
width: 75px;
height: 95px;
padding: 6px;
font-size: 2.5pt;
}
.segment_header_middle {
left: 75px;
right: 90px;
}
.segment_title_image {
margin-left: -8px;
height: 26px;
font-size: 10pt;
}
.segment_description_general {
font-size: 4.5pt;
margin: 4px 4px 4px 10px;
}
}
.main_content {
padding: 0 6px;
.segment_title {
width: 130px;
@ -655,37 +639,5 @@ body {
font-size: 4.5pt;
margin: 4px 0 4px 10px;
}
.captcha-container .captcha-form {
width: 85px;
height: 105px;
font-size: 2.5pt;
padding: 0 5px;
p {
margin-top: 4px;
margin-bottom: 4px;
font-size: 4pt;
}
a {
padding-left: 24.25px;
padding-right: 24.25px;
font-size: 4pt;
}
form {
margin-top: 2px;
}
.captcha-input {
margin-bottom: 2px;
}
.captcha-input, .captcha-button {
padding: 3px;
font-size: 5pt;
}
}
}
}