diff --git a/layout/assets/bg-pattern-bottom-desktop.svg b/layout/assets/bg-pattern-bottom-desktop.svg new file mode 100644 index 0000000..a9ab79c --- /dev/null +++ b/layout/assets/bg-pattern-bottom-desktop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/layout/assets/bg-pattern-bottom-mobile.svg b/layout/assets/bg-pattern-bottom-mobile.svg new file mode 100644 index 0000000..f42595f --- /dev/null +++ b/layout/assets/bg-pattern-bottom-mobile.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/layout/assets/bg-pattern-top-desktop.svg b/layout/assets/bg-pattern-top-desktop.svg new file mode 100644 index 0000000..8bd11f8 --- /dev/null +++ b/layout/assets/bg-pattern-top-desktop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/layout/assets/bg-pattern-top-mobile.svg b/layout/assets/bg-pattern-top-mobile.svg new file mode 100644 index 0000000..7f19323 --- /dev/null +++ b/layout/assets/bg-pattern-top-mobile.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/layout/assets/favicon-32x32.png b/layout/assets/favicon-32x32.png new file mode 100644 index 0000000..1e2df7f Binary files /dev/null and b/layout/assets/favicon-32x32.png differ diff --git a/layout/assets/icon-star.svg b/layout/assets/icon-star.svg new file mode 100644 index 0000000..eb84b44 --- /dev/null +++ b/layout/assets/icon-star.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/layout/assets/image-anne.jpg b/layout/assets/image-anne.jpg new file mode 100644 index 0000000..3824a1c Binary files /dev/null and b/layout/assets/image-anne.jpg differ diff --git a/layout/assets/image-colton.jpg b/layout/assets/image-colton.jpg new file mode 100644 index 0000000..8102530 Binary files /dev/null and b/layout/assets/image-colton.jpg differ diff --git a/layout/assets/image-irene.jpg b/layout/assets/image-irene.jpg new file mode 100644 index 0000000..4a9653a Binary files /dev/null and b/layout/assets/image-irene.jpg differ diff --git a/social-proof-section-master/style.css b/layout/jeonghu/jeonghu_layout.css similarity index 100% rename from social-proof-section-master/style.css rename to layout/jeonghu/jeonghu_layout.css diff --git a/social-proof-section-master/index.html b/layout/jeonghu/jeonghu_layout.html similarity index 98% rename from social-proof-section-master/index.html rename to layout/jeonghu/jeonghu_layout.html index 8899fa9..4064915 100644 --- a/social-proof-section-master/index.html +++ b/layout/jeonghu/jeonghu_layout.html @@ -7,9 +7,9 @@ rel="icon" type="image/png" sizes="32x32" - href="./images/favicon-32x32.png" + href="../assets/favicon-32x32.png" /> - + Frontend Mentor | Social proof section @@ -138,7 +138,7 @@
Colton @@ -156,7 +156,7 @@
- Irene + Irene
Irene Roberts
Verified Buyer
@@ -171,7 +171,7 @@
- Anne + Anne
Anne Wallace
Verified Buyer
diff --git "a/media query \354\213\244\354\212\265/index.html" "b/media query \354\213\244\354\212\265/index.html" deleted file mode 100644 index e2fceb5..0000000 --- "a/media query \354\213\244\354\212\265/index.html" +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - Document - - - - - - - - diff --git "a/media query \354\213\244\354\212\265/style.css" "b/media query \354\213\244\354\212\265/style.css" deleted file mode 100644 index 5e8666f..0000000 --- "a/media query \354\213\244\354\212\265/style.css" +++ /dev/null @@ -1,139 +0,0 @@ -body{ - margin:0; - color: #d4b996; - font-family: "Noto Sans KR", sans-serif; -} -.footer{ - position: absolute; - bottom:0 ; - background-color: #392305; - width: 100%; -} -.footer-container{ - padding: 60px -} -.first-line{ - display: flex; - justify-content: space-between; - padding-bottom: 40px; - align-items:flex-start; -} - - -ul{ - display: flex; - list-style: none; - margin:0; - padding:0; -} -.sns-icon{ - width: 40px; - height: 40px; - background-color: #6d523b; - border-radius: 50%; - display: flex; - justify-content: center; - align-items: center; - margin-right: 30px; -} - -.second-line{ - display: flex; - justify-content: space-between; -} -.second-line-container{ - width: 75%; -} -.menus{ - margin-bottom:20px; -} -.menus li{ - margin-right:30px; - font-weight:bold; -} -.company-info li{ - margin-right: 20px; - font-size: 14px; -} -.company-contact li{ - margin-right: 20px; - font-size: 14px; -} - -.second-line-container-bottom{ - color: #776854; - font-size: 13px; - margin: 20px 0; -} -.second-line-container-bottom div{ - margin:5px 0 -} -.info{ - margin-right:20px -} -.phone-number{ - font-weight: bold; - font-size:28px ; - margin-bottom: 10px; -} -.work-hour li{ - margin: 10px 0; -} -.work-hour span{ - margin-right:10px -} -.slogan{ - font-weight: bold; - display: none; - font-size: 24px; -} - -@media ( max-width:992px){ - .info{ - display:none; - } - .first-line{ - display:block; - text-align: center; - } - .sns-area{ - justify-content: center; - margin-top: 20px; - } - .last{ - margin-right:0; - } - .second-line-container{ - width: 100%; - } - - .menus{ - display: flex; - justify-content: space-between; - } -} - -@media(max-width:738px){ - .menus{ - display:block; - } - .menus li{ - margin-top: 10px; - margin-right: 0; - } - .footer-container{ - text-align: center; - } - .company-info{ - display:block; - } - .company-contact{ - display:none; - } - .vision{ - display:none; - } - .slogan{ - display:block; - } -} \ No newline at end of file diff --git a/recipe/assets/fonts/outfit/OFL.txt b/recipe/assets/fonts/outfit/OFL.txt new file mode 100644 index 0000000..556e431 --- /dev/null +++ b/recipe/assets/fonts/outfit/OFL.txt @@ -0,0 +1,93 @@ +Copyright 2021 The Outfit Project Authors (https://github.com/Outfitio/Outfit-Fonts) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/recipe/assets/fonts/outfit/Outfit-VariableFont_wght.ttf b/recipe/assets/fonts/outfit/Outfit-VariableFont_wght.ttf new file mode 100644 index 0000000..96106f0 Binary files /dev/null and b/recipe/assets/fonts/outfit/Outfit-VariableFont_wght.ttf differ diff --git a/recipe/assets/fonts/outfit/README.txt b/recipe/assets/fonts/outfit/README.txt new file mode 100644 index 0000000..702665a --- /dev/null +++ b/recipe/assets/fonts/outfit/README.txt @@ -0,0 +1,71 @@ +Outfit Variable Font +==================== + +This download contains Outfit as both a variable font and static fonts. + +Outfit is a variable font with this axis: + wght + +This means all the styles are contained in a single file: + Outfit-VariableFont_wght.ttf + +If your app fully supports variable fonts, you can now pick intermediate styles +that aren’t available as static fonts. Not all apps support variable fonts, and +in those cases you can use the static font files for Outfit: + static/Outfit-Thin.ttf + static/Outfit-ExtraLight.ttf + static/Outfit-Light.ttf + static/Outfit-Regular.ttf + static/Outfit-Medium.ttf + static/Outfit-SemiBold.ttf + static/Outfit-Bold.ttf + static/Outfit-ExtraBold.ttf + static/Outfit-Black.ttf + +Get started +----------- + +1. Install the font files you want to use + +2. Use your app's font picker to view the font family and all the +available styles + +Learn more about variable fonts +------------------------------- + + https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts + https://variablefonts.typenetwork.com + https://medium.com/variable-fonts + +In desktop apps + + https://theblog.adobe.com/can-variable-fonts-illustrator-cc + https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts + +Online + + https://developers.google.com/fonts/docs/getting_started + https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide + https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts + +Installing fonts + + MacOS: https://support.apple.com/en-us/HT201749 + Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux + Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows + +Android Apps + + https://developers.google.com/fonts/docs/android + https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts + +License +------- +Please read the full license text (OFL.txt) to understand the permissions, +restrictions and requirements for usage, redistribution, and modification. + +You can use them in your products & projects – print or digital, +commercial or otherwise. + +This isn't legal advice, please consider consulting a lawyer and see the full +license for all details. diff --git a/recipe/assets/fonts/outfit/static/Outfit-Black.ttf b/recipe/assets/fonts/outfit/static/Outfit-Black.ttf new file mode 100644 index 0000000..487752b Binary files /dev/null and b/recipe/assets/fonts/outfit/static/Outfit-Black.ttf differ diff --git a/recipe/assets/fonts/outfit/static/Outfit-Bold.ttf b/recipe/assets/fonts/outfit/static/Outfit-Bold.ttf new file mode 100644 index 0000000..0a081bc Binary files /dev/null and b/recipe/assets/fonts/outfit/static/Outfit-Bold.ttf differ diff --git a/recipe/assets/fonts/outfit/static/Outfit-ExtraBold.ttf b/recipe/assets/fonts/outfit/static/Outfit-ExtraBold.ttf new file mode 100644 index 0000000..0977ed5 Binary files /dev/null and b/recipe/assets/fonts/outfit/static/Outfit-ExtraBold.ttf differ diff --git a/recipe/assets/fonts/outfit/static/Outfit-ExtraLight.ttf b/recipe/assets/fonts/outfit/static/Outfit-ExtraLight.ttf new file mode 100644 index 0000000..938fe31 Binary files /dev/null and b/recipe/assets/fonts/outfit/static/Outfit-ExtraLight.ttf differ diff --git a/recipe/assets/fonts/outfit/static/Outfit-Light.ttf b/recipe/assets/fonts/outfit/static/Outfit-Light.ttf new file mode 100644 index 0000000..c18b0c1 Binary files /dev/null and b/recipe/assets/fonts/outfit/static/Outfit-Light.ttf differ diff --git a/recipe/assets/fonts/outfit/static/Outfit-Medium.ttf b/recipe/assets/fonts/outfit/static/Outfit-Medium.ttf new file mode 100644 index 0000000..7ae796b Binary files /dev/null and b/recipe/assets/fonts/outfit/static/Outfit-Medium.ttf differ diff --git a/recipe/assets/fonts/outfit/static/Outfit-Regular.ttf b/recipe/assets/fonts/outfit/static/Outfit-Regular.ttf new file mode 100644 index 0000000..826899c Binary files /dev/null and b/recipe/assets/fonts/outfit/static/Outfit-Regular.ttf differ diff --git a/recipe/assets/fonts/outfit/static/Outfit-SemiBold.ttf b/recipe/assets/fonts/outfit/static/Outfit-SemiBold.ttf new file mode 100644 index 0000000..6b37eeb Binary files /dev/null and b/recipe/assets/fonts/outfit/static/Outfit-SemiBold.ttf differ diff --git a/recipe/assets/fonts/outfit/static/Outfit-Thin.ttf b/recipe/assets/fonts/outfit/static/Outfit-Thin.ttf new file mode 100644 index 0000000..7d84201 Binary files /dev/null and b/recipe/assets/fonts/outfit/static/Outfit-Thin.ttf differ diff --git a/recipe/assets/fonts/young-serif/OFL.txt b/recipe/assets/fonts/young-serif/OFL.txt new file mode 100644 index 0000000..8a46387 --- /dev/null +++ b/recipe/assets/fonts/young-serif/OFL.txt @@ -0,0 +1,93 @@ +Copyright 2023 The Young Serif Project Authors (https://github.com/noirblancrouge/YoungSerif) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/recipe/assets/fonts/young-serif/YoungSerif-Regular.ttf b/recipe/assets/fonts/young-serif/YoungSerif-Regular.ttf new file mode 100644 index 0000000..f454fbe Binary files /dev/null and b/recipe/assets/fonts/young-serif/YoungSerif-Regular.ttf differ diff --git a/recipe/assets/images/favicon-32x32.png b/recipe/assets/images/favicon-32x32.png new file mode 100644 index 0000000..1e2df7f Binary files /dev/null and b/recipe/assets/images/favicon-32x32.png differ diff --git a/recipe/assets/images/image-omelette.jpeg b/recipe/assets/images/image-omelette.jpeg new file mode 100644 index 0000000..dac3a46 Binary files /dev/null and b/recipe/assets/images/image-omelette.jpeg differ diff --git a/recipe-page-main/style.css b/recipe/jeonghu/jeonghu_recipe.css similarity index 100% rename from recipe-page-main/style.css rename to recipe/jeonghu/jeonghu_recipe.css diff --git a/recipe-page-main/index.html b/recipe/jeonghu/jeonghu_recipe.html similarity index 96% rename from recipe-page-main/index.html rename to recipe/jeonghu/jeonghu_recipe.html index 2949ab0..5631913 100644 --- a/recipe-page-main/index.html +++ b/recipe/jeonghu/jeonghu_recipe.html @@ -3,12 +3,12 @@ - + Frontend Mentor | Recipe page - + @@ -16,7 +16,7 @@
- omelette + omelette

Simple Omelette Recipe

diff --git a/todo/assets/bg-desktop-dark.jpg b/todo/assets/bg-desktop-dark.jpg new file mode 100644 index 0000000..394ebb9 Binary files /dev/null and b/todo/assets/bg-desktop-dark.jpg differ diff --git a/todo/assets/bg-desktop-light.jpg b/todo/assets/bg-desktop-light.jpg new file mode 100644 index 0000000..1b5f3bb Binary files /dev/null and b/todo/assets/bg-desktop-light.jpg differ diff --git a/todo/assets/bg-mobile-dark.jpg b/todo/assets/bg-mobile-dark.jpg new file mode 100644 index 0000000..3285a35 Binary files /dev/null and b/todo/assets/bg-mobile-dark.jpg differ diff --git a/todo/assets/bg-mobile-light.jpg b/todo/assets/bg-mobile-light.jpg new file mode 100644 index 0000000..9df5c53 Binary files /dev/null and b/todo/assets/bg-mobile-light.jpg differ diff --git a/todo/assets/favicon-32x32.png b/todo/assets/favicon-32x32.png new file mode 100644 index 0000000..1e2df7f Binary files /dev/null and b/todo/assets/favicon-32x32.png differ diff --git a/todo/assets/icon-check.svg b/todo/assets/icon-check.svg new file mode 100644 index 0000000..61e7384 --- /dev/null +++ b/todo/assets/icon-check.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/todo/assets/icon-cross.svg b/todo/assets/icon-cross.svg new file mode 100644 index 0000000..cdf9c7c --- /dev/null +++ b/todo/assets/icon-cross.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/todo/assets/icon-moon.svg b/todo/assets/icon-moon.svg new file mode 100644 index 0000000..60c2ace --- /dev/null +++ b/todo/assets/icon-moon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/todo/assets/icon-sun.svg b/todo/assets/icon-sun.svg new file mode 100644 index 0000000..24f69f3 --- /dev/null +++ b/todo/assets/icon-sun.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/todo/jeonghu/jeonghu_todo.css b/todo/jeonghu/jeonghu_todo.css new file mode 100644 index 0000000..85f9f0a --- /dev/null +++ b/todo/jeonghu/jeonghu_todo.css @@ -0,0 +1,241 @@ +.attribution { font-size: 11px; text-align: center; } + +body { + width: 100%; + font-family: "Josefin Sans", sans-serif; + display: flex; + align-items: center; + flex-direction: column; +} + +#background-image { + position:absolute; + background-image: url("../assets/bg-desktop-light.jpg"); + background-position: center; + top: 0; + left: 0px; + width: 100%; + height: 300px; + z-index: -1; + background-repeat: no-repeat; + background-size: cover; +} + +.header-container{ + width: 541px; + height: 48px; + flex-shrink: 0; + margin-top: 70px; + display: flex; + justify-content: space-between; +} + +.header{ + color: #FFF; + font-size: 40px; + font-style: normal; + font-weight: 700; + line-height: normal; + letter-spacing: 15px; + margin: 0; +} + + +.input-container{ + max-width: 540px; + width: 90%; + height: 64px; + margin-top: 40px; + flex-shrink: 0; + border-radius: 5px; + background: #FFF; + box-shadow: 0px 35px 50px -15px rgba(194, 195, 214, 0.50); + display: flex; + align-items: center; + flex-direction: row; +} + +.oval{ + width: 24px; + height: 24px; + fill: #FFF; +} + +.todo-item .oval:hover circle{ + stroke:#5df; +} + + + + +#input-text{ + color: #9495A5; + font-size: 18px; + font-style: normal; + font-weight: 400; + line-height: normal; + letter-spacing: -0.25px; + border: none; + outline: none; +} + +.input-box{ + display: inline-flex; + justify-content: center; + align-items: center; + gap: 24px; + margin-left: 24px; +} + +.main-container{ + max-width: 540px; + width: 90%; + max-height: 439px; + min-height: 0px; + flex-shrink: 0; + display: flex; + flex-direction: column; + align-items: center; + border-radius: 5px; + background: #FFF; + box-shadow: 0px 35px 50px -15px rgba(194, 195, 214, 0.50); + margin-top: 24px; +} + +.bottom-container{ + max-width: 540px; + width: 90%; + max-height: 439px; + min-height: 50px; + flex-shrink: 0; + display: flex; + border-radius: 5px; + background: #FFF; + box-shadow: 0px 35px 50px -15px rgba(194, 195, 214, 0.50); + display: flex; + justify-content: space-between; + align-items: center; + margin-top: auto; + margin-bottom: 16px; + padding: 0 24px; + box-sizing: border-box; +} + +.toggle { + background: none; /* 배경을 없애거나 단색으로 설정 */ + border: none; /* 테두리 없애기 */ + box-shadow: none; /* 그림자 없애기 */ + padding: 0; /* 기본 여백 없애기 */ + outline: none; /* 클릭 시 외곽선 없애기 */ + cursor: pointer; /* 포인터 변경 */ +} + +.interaction-container{ + width: 116px; + height: 14px; + display: inline-flex; + padding-bottom: 4px; + justify-content: center; + align-items: flex-start; + gap: 19px; + color: #9495A5; + font-size: 14px; + font-style: normal; + font-weight: 700; + line-height: normal; + letter-spacing: -0.194px; + margin-left: 40px; +} + +.bottom{ + color: #9495A5; + text-align: right; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; + letter-spacing: -0.194px; +} + + + +.footer{ + margin-top: 49px; + color: #9495A5; + text-align: center; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; + letter-spacing: -0.194px; +} + +.todo-item{ + display: flex; + width: 492px; + height: 24px; + flex-shrink: 0; + align-items: center; + margin-top: 20px; +} + +.todo-text{ + margin-left: 24px; + color: #494C6B; + font-size: 18px; + font-style: normal; + font-weight: 400; + line-height: normal; + letter-spacing: -0.25px; +} + +.line{ + margin-top: 20px; + width: 540px; + height: 1px; + flex-shrink: 0; + background: #E3E4F1; +} + +.cross-line{ + margin-left: auto; + display: none; +} + +/* todo-item에 마우스를 올렸을 때만 cross-line 보이기 */ +.todo-item:hover .cross-line { + display: block; +} + +.hover:hover{ + color: #494C6B; +} + + +.filter-button{ + border: none; + outline: none; + background: none; + color: #9495A5; + font-family: "Josefin Sans"; + font-size: 14px; + font-style: normal; + font-weight: 700; + line-height: normal; + letter-spacing: -0.194px; +} + +.clear{ + color: #9495A5; + text-align: right; + font-family: "Josefin Sans"; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: normal; + letter-spacing: -0.194px; +} + +.filter-button.active { + color: #3A7CFD; +} \ No newline at end of file diff --git a/todo/jeonghu/jeonghu_todo.html b/todo/jeonghu/jeonghu_todo.html new file mode 100644 index 0000000..b9776d4 --- /dev/null +++ b/todo/jeonghu/jeonghu_todo.html @@ -0,0 +1,53 @@ + + + + + + + + + Frontend Mentor | Todo app + + + + + + + + + +
+ +
+
TODO
+ +
+ +
+
+
+ +
+
+ +
+
+
items left
+
+ + + +
+ +
+ + + + + \ No newline at end of file diff --git a/todo/jeonghu/jeonghu_todo.js b/todo/jeonghu/jeonghu_todo.js new file mode 100644 index 0000000..8a52229 --- /dev/null +++ b/todo/jeonghu/jeonghu_todo.js @@ -0,0 +1,414 @@ +// 주요 DOM 요소 가져오기 +const themeToggle = document.querySelector('.toggle'); // 테마 전환 버튼 +const themeIcon = document.getElementById('icon'); // 테마 아이콘 +const background = document.getElementById('background-image'); // 배경 이미지 +const newTodoInput = document.getElementById('input-text'); // 새로운 할 일 입력 필드 +const mainContainer = document.querySelector('.main-container'); // 할 일 목록이 표시될 메인 컨테이너 +const itemsLeft = document.querySelector('.remain-item'); // 남은 할 일 수 표시 +const clearCompletedButton = document.querySelector('.clear'); // 완료된 할 일 삭제 버튼 +const filterButtons = document.querySelectorAll('.filter-button'); // 필터 버튼들 +const addTodoOval = document.querySelector('.oval'); // 할 일 추가 버튼의 Oval +const inputContainer = document.querySelector('.input-container'); // 입력 컨테이너 +const bottomContainer = document.querySelector('.bottom-container'); // 하단 컨테이너 + + +let todos = []; + +let draggedIndex = null; + +// Oval 상태 로컬 스토리지에서 가져오기 +let ovalState = localStorage.getItem('ovalState') || 'light'; + +// 기본, hover, 완료 상태 SVG +const lightOvalSVG = ` + + + `; + +const darkOvalSVG = ` + + + `; + +const clickedOval = ` + + + + + + + + + + + `; + +const hoverOval = ` + + + + + + + + + + + + + + + + + `; + + +// Oval 업데이트 함수 +function updateAddTodoOval() { + const isDark = document.body.classList.contains('dark'); + addTodoOval.innerHTML = isDark ? darkOvalSVG : lightOvalSVG; +} + +// 테마 전환 함수에서 line과 텍스트 색상 업데이트 추가 +const toggleTheme = () => { + document.body.classList.toggle('dark'); + const isDark = document.body.classList.contains('dark'); + + // 아이콘과 배경 이미지 변경 + themeIcon.src = isDark ? '../assets/icon-sun.svg' : '../assets/icon-moon.svg'; + background.style.backgroundImage = isDark + ? 'url(../assets/bg-desktop-dark.jpg)' + : 'url(../assets/bg-desktop-light.jpg)'; + + // 낮/밤 모드에 따른 배경색 변경 + document.body.style.background = isDark ? '#171823' : '#FAFAFA'; + + // 주요 컨테이너 배경색 + const containerBgColor = isDark ? '#25273D' : '#FFFFFF'; + inputContainer.style.background = containerBgColor; + newTodoInput.style.background = containerBgColor; + mainContainer.style.background = containerBgColor; + bottomContainer.style.background = containerBgColor; + + // line 및 텍스트 색상 업데이트 + document.querySelectorAll('.line').forEach(line => { + line.style.background = isDark ? '#393A4B' : '#E3E4F1'; + }); + document.querySelectorAll('.todo-text').forEach(text => { + text.style.color = isDark ? '#C8CBE7' : '#494C6B'; + }); + + // 로컬 스토리지에 테마 상태 저장 + localStorage.setItem('theme', isDark ? 'dark' : 'light'); + + // Oval 상태 업데이트 + ovalState = isDark ? 'dark' : 'light'; + localStorage.setItem('ovalState', ovalState); + updateAddTodoOval(); + updateTodoList(); +}; + +// 초기 로딩 시 테마 및 할 일 설정 +document.addEventListener('DOMContentLoaded', function () { + const savedTheme = localStorage.getItem('theme'); + const isDark = savedTheme === 'dark'; + + if (isDark) { + document.body.classList.add('dark'); + themeIcon.src = '../assets/icon-sun.svg'; + background.style.backgroundImage = 'url(../assets/bg-desktop-dark.jpg)'; + document.body.style.background = '#171823'; + const containerBgColor = '#25273D'; + inputContainer.style.background = containerBgColor; + newTodoInput.style.background = containerBgColor; + mainContainer.style.background = containerBgColor; + bottomContainer.style.background = containerBgColor; + } else { + document.body.classList.remove('dark'); + themeIcon.src = '../assets/icon-moon.svg'; + background.style.backgroundImage = 'url(../assets/bg-desktop-light.jpg)'; + document.body.style.background = '#FAFAFA'; + const containerBgColor = '#FFFFFF'; + inputContainer.style.background = containerBgColor; + newTodoInput.style.background = containerBgColor; + mainContainer.style.background = containerBgColor; + bottomContainer.style.background = containerBgColor; + + } + + updateAddTodoOval(); + + const allButton = document.getElementById('all'); + allButton.classList.add('active'); + filterTodos('all'); + + const savedTodos = JSON.parse(localStorage.getItem('todos')); + if (savedTodos) { + todos = savedTodos; + updateAddTodoOval(); + updateTodoList(); + } +}); + +// 테마 토글 버튼 이벤트 +themeToggle.addEventListener('click', toggleTheme); + +// 새로운 할 일 추가 +newTodoInput.addEventListener('keypress', (e) => { + if (e.key === 'Enter' && newTodoInput.value.trim()) { + addTodo(newTodoInput.value); + newTodoInput.value = ''; + } +}); + +// 할 일 추가 함수 +function addTodo(text) { + const todo = { text, completed: false }; + todos.push(todo); + updateTodoList(); + saveTodosToLocalStorage(); +} + +function handleDragStart(event) { + draggedIndex = event.target.getAttribute('data-index'); + event.dataTransfer.effectAllowed = "move"; +} + +function handleDragOver(event) { + event.preventDefault(); // 드롭을 허용하기 위해 필요 + event.dataTransfer.dropEffect = "move"; +} + +function handleDrop(event) { + event.preventDefault(); + const targetIndex = event.target.closest('.todo-item').getAttribute('data-index'); + + // todos 배열을 드래그한 항목과 드롭한 대상의 위치에 맞게 재정렬 + if (draggedIndex !== null && targetIndex !== null && draggedIndex !== targetIndex) { + const movedItem = todos.splice(draggedIndex, 1)[0]; + todos.splice(targetIndex, 0, movedItem); + + updateTodoList(); + saveTodosToLocalStorage(); + } + draggedIndex = null; +} + +// updateTodoList 함수에서 새로 생성되는 항목의 색상 설정 +function updateTodoList() { + mainContainer.innerHTML = ''; // 기존 목록 초기화 + const isDark = document.body.classList.contains('dark'); + + todos.forEach((todo, index) => { + const todoItem = document.createElement('div'); + todoItem.className = 'todo-item'; + todoItem.draggable = true; + todoItem.setAttribute('data-index', index); + + + todoItem.innerHTML = ` +
+ ${todo.completed ? clickedOval : isDark ? darkOvalSVG : lightOvalSVG} +
+ + ${todo.text} + +
+ + + +
+ `; + + const oval = todoItem.querySelector('.oval'); + const todoText = todoItem.querySelector('.todo-text'); + + if (todo.completed) { + todoText.style.textDecoration = 'line-through'; + todoText.style.color = isDark ? '#4D5067' : '#9495A5'; + oval.innerHTML = clickedOval; + } + + oval.addEventListener('click', () => toggleComplete(index)); + todoText.addEventListener('click', () => toggleComplete(index)); + + mainContainer.appendChild(todoItem); + + const line = document.createElement('div'); + line.className = 'line'; + line.style.background = isDark ? '#393A4B' : '#E3E4F1'; + mainContainer.appendChild(line); + }); +} + + +// 할 일 목록 업데이트 함수 (드래그 앤 드롭 통합) +function updateTodoList() { + mainContainer.innerHTML = ''; // 기존 목록 초기화 + const isDark = document.body.classList.contains('dark'); + + todos.forEach((todo, index) => { + const todoItem = document.createElement('div'); + todoItem.className = 'todo-item'; + todoItem.draggable = true; // 드래그 가능하도록 설정 + todoItem.setAttribute('data-index', index); + + todoItem.innerHTML = ` +
+ ${todo.completed ? clickedOval : isDark ? darkOvalSVG : lightOvalSVG} +
+ + ${todo.text} + +
+ + + +
+ `; + + const oval = todoItem.querySelector('.oval'); + const todoText = todoItem.querySelector('.todo-text'); + const cancelButton = todoItem.querySelector('.cross-line'); + + // 완료된 할 일 텍스트 스타일 적용 + if (todo.completed) { + todoText.style.textDecoration = 'line-through'; + todoText.style.color = isDark ? '#4D5067' : '#9495A5'; + oval.innerHTML = clickedOval; + } + + // 드래그 앤 드롭 이벤트 추가 + todoItem.addEventListener('dragstart', handleDragStart); + todoItem.addEventListener('dragover', handleDragOver); + todoItem.addEventListener('drop', handleDrop); + + oval.addEventListener('click', () => toggleComplete(index)); + todoText.addEventListener('click', () => toggleComplete(index)); + cancelButton.addEventListener('click', (e) => { + e.stopPropagation(); + deleteTodo(index); + }); + + mainContainer.appendChild(todoItem); + + const line = document.createElement('div'); + line.className = 'line'; + line.style.background = isDark ? '#393A4B' : '#E3E4F1'; + mainContainer.appendChild(line); + }); + + updateItemsLeft(); +} + + +// 할 일 삭제 함수 +function deleteTodo(index) { + todos.splice(index, 1); + updateTodoList(); + saveTodosToLocalStorage(); +} + +// 완료 상태 토글 함수 +function toggleComplete(index) { + todos[index].completed = !todos[index].completed; + updateTodoList(); + saveTodosToLocalStorage(); +} + +// 남은 할 일 수 업데이트 +function updateItemsLeft() { + const remainingItems = todos.filter(todo => !todo.completed).length; + itemsLeft.textContent = `${remainingItems} items left`; +} + +// 필터 버튼 이벤트 +filterButtons.forEach(button => { + button.addEventListener('click', () => { + filterButtons.forEach(btn => btn.classList.remove('active')); + button.classList.add('active'); + filterTodos(button.dataset.filter); + }); +}); + +// 필터링 함수에서 완료된 항목 스타일 수정 +function filterTodos(filter) { + mainContainer.innerHTML = ''; // 기존 목록 초기화 + + const filteredTodos = filter === 'all' + ? todos + : todos.filter(todo => filter === 'active' ? !todo.completed : todo.completed); + + // 필터링된 항목으로 목록 재구성 + filteredTodos.forEach((todo, index) => { + const todoItem = document.createElement('div'); + todoItem.className = 'todo-item'; + todoItem.setAttribute('data-index', index); // 재정렬된 인덱스 적용 + todoItem.innerHTML = ` +
+ ${todo.completed ? clickedOval : (document.body.classList.contains('dark') ? darkOvalSVG : lightOvalSVG)} +
+ + ${todo.text} + + `; + + const oval = todoItem.querySelector('.oval'); + const todoText = todoItem.querySelector('.todo-text'); + + // 완료 상태 스타일 적용 + if (todo.completed) { + todoText.style.textDecoration = 'line-through'; + todoText.style.color = document.body.classList.contains('dark') ? '#4D5067' : '#9495A5'; + } + + // 이벤트 핸들러 추가 + oval.addEventListener('click', () => toggleComplete(index)); + todoText.addEventListener('click', () => toggleComplete(index)); + + mainContainer.appendChild(todoItem); + + // 라인 추가 + const line = document.createElement('div'); + line.className = 'line'; + line.style.background = document.body.classList.contains('dark') ? '#393A4B' : '#E3E4F1'; + mainContainer.appendChild(line); + }); + + updateItemsLeft(); // 남은 항목 수 갱신 +} + + + +// 완료된 할 일 삭제 +clearCompletedButton.addEventListener('click', () => { + console.log("Before Clear:", todos); // Clear 전 todos 배열 확인 + todos = todos.filter(todo => !todo.completed); // 완료된 항목 제거 + console.log("After Clear:", todos); // Clear 후 todos 배열 확인 + + saveTodosToLocalStorage(); // 로컬 스토리지 저장 + + // 현재 활성화된 필터에 따라 목록 재구성 + const activeFilter = document.querySelector('.filter-button.active').dataset.filter; + updateTodoList(); // 전체 목록 먼저 업데이트 + filterTodos(activeFilter); // 활성화된 필터 조건에 따라 표시 +}); + + + + +// 로컬 스토리지 저장 +function saveTodosToLocalStorage() { + localStorage.setItem('todos', JSON.stringify(todos)); +} + +// 필터 버튼 스타일 설정 + +// 필터 버튼 이벤트 +filterButtons.forEach(button => { + button.addEventListener('click', () => { + filterButtons.forEach(btn => btn.classList.remove('active')); + button.classList.add('active'); + filterTodos(button.dataset.filter); + }); +});