1"use strict";(globalThis.webpackChunkmotore_temp=globalThis.webpackChunkmotore_temp||[]).push([[8819],{1470:(e,n,t)=>{t.d(n,{A:()=>w});var i=t(6540),r=t(4164),a=t(7559),s=t(3104),o=t(6347),l=t(205),c=t(7485),d=t(1682),u=t(679);function h(e){return i.Children.toArray(e).filter(e=>"\n"!==e).map(e=>{if(!e||(0,i.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)})?.filter(Boolean)??[]}function p(e){const{values:n,children:t}=e;return(0,i.useMemo)(()=>{const e=n??function(e){return h(e).map(({props:{value:e,label:n,attributes:t,default:i}})=>({value:e,label:n,attributes:t,default:i}))}(t);return function(e){const n=(0,d.XI)(e,(e,n)=>e.value===n.value);if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map(e=>e.value).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e},[n,t])}function m({value:e,tabValues:n}){return n.some(n=>n.value===e)}function x({queryString:e=!1,groupId:n}){const t=(0,o.W6)(),r=function({queryString:e=!1,groupId:n}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!n)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:e,groupId:n});return[(0,c.aZ)(r),(0,i.useCallback)(e=>{if(!r)return;const n=new URLSearchParams(t.location.search);n.set(r,e),t.replace({...t.location,search:n.toString()})},[r,t])]}function v(e){const{defaultValue:n,queryString:t=!1,groupId:r}=e,a=p(e),[s,o]=(0,i.useState)(()=>function({defaultValue:e,tabValues:n}){if(0===n.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!m({value:e,tabValues:n}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${n.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}const t=n.find(e=>e.default)??n[0];if(!t)throw new Error("Unexpected error: 0 tabValues");return t.value}({defaultValue:n,tabValues:a})),[c,d]=x({queryString:t,groupId:r}),[h,v]=function({groupId:e}){const n=function(e){return e?`docusaurus.tab.${e}`:null}(e),[t,r]=(0,u.Dv)(n);return[t,(0,i.useCallback)(e=>{n&&r.set(e)},[n,r])]}({groupId:r}),f=(()=>{const e=c??h;return m({value:e,tabValues:a})?e:null})();(0,l.A)(()=>{f&&o(f)},[f]);return{selectedValue:s,selectValue:(0,i.useCallback)(e=>{if(!m({value:e,tabValues:a}))throw new Error(`Can't select invalid tab value=${e}`);o(e),d(e),v(e)},[d,v,a]),tabValues:a}}var f=t(2303);const b={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var g=t(4848);function k({className:e,block:n,selectedValue:t,selectValue:i,tabValues:a}){const o=[],{blockElementScrollPositionUntilNextRender:l}=(0,s.a_)(),c=e=>{const n=e.currentTarget,r=o.indexOf(n),s=a[r].value;s!==t&&(l(n),i(s))},d=e=>{let n=null;switch(e.key){case"Enter":c(e);break;case"ArrowRight":{const t=o.indexOf(e.currentTarget)+1;n=o[t]??o[0];break}case"ArrowLeft":{const t=o.indexOf(e.currentTarget)-1;n=o[t]??o[o.length-1];break}}n?.focus()};return(0,g.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.A)("tabs",{"tabs--block":n},e),children:a.map(({value:e,label:n,attributes:i})=>(0,g.jsx)("li",{role:"tab",tabIndex:t===e?0:-1,"aria-selected":t===e,ref:e=>{o.push(e)},onKeyDown:d,onClick:c,...i,className:(0,r.A)("tabs__item",b.tabItem,i?.className,{"tabs__item--active":t===e}),children:n??e},e))})}function y({lazy:e,children:n,selectedValue:t}){const a=(Array.isArray(n)?n:[n]).filter(Boolean);if(e){const e=a.find(e=>e.props.value===t);return e?(0,i.cloneElement)(e,{className:(0,r.A)("margin-top--md",e.props.className)}):null}return(0,g.jsx)("div",{className:"margin-top--md",children:a.map((e,n)=>(0,i.cloneElement)(e,{key:n,hidden:e.props.value!==t}))})}function j(e){const n=v(e);return(0,g.jsxs)("div",{className:(0,r.A)(a.G.tabs.container,"tabs-container",b.tabList),
1children:[(0,g.jsx)(k,{...n,...e}),(0,g.jsx)(y,{...n,...e})]})}function w(e){const n=(0,f.A)();return(0,g.jsx)(j,{...e,children:h(e.children)},String(n))}},3668:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>p,frontMatter:()=>l,metadata:()=>i,toc:()=>u});const i=JSON.parse('{"id":"path/html-css/piano/README","title":"Piano","description":"Written on August 4, 2025","source":"@site/docs/02-path/html-css/piano/README.mdx","sourceDirName":"02-path/html-css/piano","slug":"/path/html-css/piano/","permalink":"/docs/path/html-css/piano/","draft":false,"unlisted":false,"tags":[],"version":"current","sidebarPosition":13,"frontMatter":{"sidebar_position":13,"sidebar_label":"Piano","title":"Piano"},"sidebar":"tutorialSidebar","previous":{"title":"Cat Painting","permalink":"/docs/path/html-css/cat-painting/"},"next":{"title":"Technical Documentation Page \u2605","permalink":"/docs/path/html-css/technical-documentation-page/"}}');var r=t(4848),a=t(8453),s=t(1470),o=t(9365);const l={sidebar_position:13,sidebar_label:"Piano",title:"Piano"},c="Piano",d={},u=[{value:"The Project",id:"the-project",level:2},{value:"Source Code",id:"source-code",level:2},{value:"The Development Experience",id:"the-development-experience",level:2},{value:"The Connection with Refactoring UI",id:"the-connection-with-refactoring-ui",level:2},{value:"The Discovered Principle",id:"the-discovered-principle",level:2},{value:"Analogy That Struck Me",id:"analogy-that-struck-me",level:2},{value:"Concrete Example from the Project",id:"concrete-example-from-the-project",level:2},{value:"What I Learned",id:"what-i-learned",level:2},{value:"Reflection",id:"reflection",level:2}];function h(e){const n={code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)("p",{className:"article-meta",children:(0,r.jsx)("time",{dateTime:"2025-08-04",children:"Written on August 4, 2025"})}),"\n",(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"piano",children:"Piano"})}),"\n",(0,r.jsx)(n.h2,{id:"the-project",children:"The Project"}),"\n",(0,r.jsx)(n.p,{children:"Interactive piano developed with responsive CSS, where the number of keys automatically adapts to screen size using media queries."}),"\n",(0,r.jsx)(n.h2,{id:"source-code",children:"Source Code"}),"\n",(0,r.jsxs)(s.A,{children:[(0,r.jsx)(o.A,{value:"html",label:"index.html",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-html",children:'<!DOCTYPE html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <title>Piano</title>\n <meta name="viewport" content="width=device-width, initial-scale=1.0" />\n <link rel="stylesheet" href="styles.css">\n </head>\n <body>\n <div id="piano">\n <img class="logo" src="https://cdn.freecodecamp.org/platform/universal/fcc_primary.svg" alt="freeCodeCamp Logo" />\n <div class="keys">\n <div class="key"></div>\n <div class="key black--key"></div>\n <div class="key black--key"></div>\n <div class="key"></div>\n <div class="key black--key"></div>\n <div class="key black--key"></div>\n <div class="key black--key"></div>\n\n <div class="key"></div>\n <div class="key black--key"></div>\n <div class="key black--key"></div>\n <div class="key"></div>\n <div class="key black--key"></div>\n <div class="key black--key"></div>\n <div class="key black--key"></div>\n\n <div class="key"></div>\n <div class="key black--key"></div>\n <div class="key black--key"></div>\n <div class="key"></div>\n <div class="key black--key"></div>\n <div class="key black--key"></div>\n <div class="key black--key"></div>\n </div>\n </div>\n </body>\n</html>\n'})})}),(0,r.jsx)(o.A,{value:"css",label:"styles.css",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-css",children:'html {\n box-sizing: border-box;\n}\n\n*, *::before, *::after {\n box-sizing: inherit;\n}\n\n#piano {\n background-color: #00471b;\n width: 992px;\n height: 290px;\n margin: 80px auto;\n padding: 90px 20px 0 20px;\n position: relative;\n border-radius: 10px;\n}\n\n.keys {\n background-color: #040404;\n width: 949px;\n height: 180px;\n padding-left: 2px;\n overflow: hidden;\n}\n\n.key {\n background-color: #ffffff;\n position: relative;\n width: 41px;\n height: 175px;\n margin: 2px;\n float: left;\n border-radius: 0 0 3px 3px;\n}\n\n.key.black--key::after {\n background-color: #1d1e22;\n content: "";\n position: absolute;\n left: -18px;\n width: 32px;\n height: 100px;\n border-radius: 0 0 3px 3px;\n}\n\n.logo {\n width: 200px;\n position: absolute;\n top: 23px;\n}\n\n@media (max-width: 768px) {\n #piano {\n width: 358px;\n }\n\n .keys {\n width: 318px;\n }\n\n .logo {\n width: 150px;\n }\n}\n\n@media (max-width: 1199px) and (min-width: 769px) {\n #piano {width: 675px;}\n .keys {width: 633px;}\n}\n'})})})]}),"\n",(0,r.jsx)(n.h2,{id:"the-development-experience",children:"The Development Experience"}),"\n",(0,r.jsx)(n.p,{children:'It was very quick and at the same time extremely useful regarding the responsive side (not coincidentally the course is called "Responsive Web Design"). Indeed, the number of piano keys varies based on screen size.'}),"\n",(0,r.jsx)(n.h2,{id:"the-connection-with-refactoring-ui",children:"The Connection with Refactoring UI"}),"\n",(0,r.jsxs)(n.p,{children:["I connected this project with a fundamental concept from Refactoring UI that I'm studying: ",(0,r.jsx)(n.strong,{children:"perfect proportions change with context"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"The revelation:"}
1),' It\'s not enough to "shrink everything" for mobile. Each screen has ITS optimal proportions!']}),"\n",(0,r.jsx)(n.h2,{id:"the-discovered-principle",children:"The Discovered Principle"}),"\n",(0,r.jsxs)(n.p,{children:["\u274c ",(0,r.jsx)(n.strong,{children:"Wrong thinking:"}),' "If desktop has a 2.5x proportion, mobile must have 2.5x"']}),"\n",(0,r.jsxs)(n.p,{children:["\u2705 ",(0,r.jsx)(n.strong,{children:"Right thinking:"}),' "Each screen has ITS optimal proportions"']}),"\n",(0,r.jsx)(n.h2,{id:"analogy-that-struck-me",children:"Analogy That Struck Me"}),"\n",(0,r.jsxs)(n.p,{children:["It's like the difference between speaking in a ",(0,r.jsx)(n.strong,{children:"large room"})," vs a ",(0,r.jsx)(n.strong,{children:"small room"}),":"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Desktop (large room):"})," Shout loud for the title (48px), speak normally for text (16px)"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Mobile (small room):"})," Speak loud but don't shout for the title (24px), whisper for text (14px)"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"concrete-example-from-the-project",children:"Concrete Example from the Project"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-css",children:"/* Desktop - lots of available space */\n#piano { width: 992px; }\n.keys { width: 949px; }\n\n/* Mobile - limited space */\n@media (max-width: 768px) {\n #piano { width: 358px; }\n .keys { width: 318px; }\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["It's not just \"smaller\", it's ",(0,r.jsx)(n.strong,{children:"proportionally different"})," for each context."]}),"\n",(0,r.jsx)(n.h2,{id:"what-i-learned",children:"What I Learned"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Media queries"})," for responsive design"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Float and positioning"})," for key layout"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Pseudo-elements"})," (::after) to create black keys"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"The principle of contextual proportions"})," from Refactoring UI"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Overflow hidden"})," to manage layout"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"reflection",children:"Reflection"}),"\n",(0,r.jsxs)(n.p,{children:["This project solidified a fundamental understanding: responsive design isn't just a technical matter, but about ",(0,r.jsx)(n.strong,{children:"intelligent proportions"})," that adapt to the context of use."]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Next Project"}),": Technical Documentation Page (Certification Project)"]})]})}function p(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>o});var i=t(6540);const r={},a=i.createContext(r);function s(e){const n=i.useContext(a);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(a.Provider,{value:n},e.children)}},9365:(e,n,t)=>{t.d(n,{A:()=>s});t(6540);var i=t(4164);const r={tabItem:"tabItem_Ymn6"};var a=t(4848);function s({children:e,hidden:n,className:t}){return(0,a.jsx)("div",{role:"tabpanel",className:(0,i.A)(r.tabItem,t),hidden:n,children:e})}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.