diff --git a/_includes/head.html b/_includes/head.html index d94b9f0f10..409023403a 100644 --- a/_includes/head.html +++ b/_includes/head.html @@ -2,72 +2,68 @@ {{ page.title }} - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + {% if page.layout == 'api' %} + + {% endif %} + + + + + + + {% if page.authors %} {%- for author in page.authors %} - + {%- endfor %} {% else %} - + {% endif %} - - + + {% if page.image %} - + {% else %} - + {% endif %} + + - - - - {% if page contains "image" %} - + + + + {% if page.image %} + {% else %} - + {% endif %} - - - - - - - \ No newline at end of file + + + + + diff --git a/css/langs/de.css b/assets/css/langs/de.css similarity index 100% rename from css/langs/de.css rename to assets/css/langs/de.css diff --git a/css/langs/en.css b/assets/css/langs/en.css similarity index 100% rename from css/langs/en.css rename to assets/css/langs/en.css diff --git a/css/langs/es.css b/assets/css/langs/es.css similarity index 100% rename from css/langs/es.css rename to assets/css/langs/es.css diff --git a/css/langs/fr.css b/assets/css/langs/fr.css similarity index 100% rename from css/langs/fr.css rename to assets/css/langs/fr.css diff --git a/css/langs/it.css b/assets/css/langs/it.css similarity index 100% rename from css/langs/it.css rename to assets/css/langs/it.css diff --git a/css/langs/ja.css b/assets/css/langs/ja.css similarity index 100% rename from css/langs/ja.css rename to assets/css/langs/ja.css diff --git a/css/langs/ko.css b/assets/css/langs/ko.css similarity index 100% rename from css/langs/ko.css rename to assets/css/langs/ko.css diff --git a/css/langs/pt-br.css b/assets/css/langs/pt-br.css similarity index 100% rename from css/langs/pt-br.css rename to assets/css/langs/pt-br.css diff --git a/css/langs/zh-cn.css b/assets/css/langs/zh-cn.css similarity index 100% rename from css/langs/zh-cn.css rename to assets/css/langs/zh-cn.css diff --git a/css/langs/zh-tw.css b/assets/css/langs/zh-tw.css similarity index 100% rename from css/langs/zh-tw.css rename to assets/css/langs/zh-tw.css diff --git a/css/sintax.css b/assets/css/sintax.css similarity index 100% rename from css/sintax.css rename to assets/css/sintax.css diff --git a/css/style.css b/assets/css/style.css similarity index 93% rename from css/style.css rename to assets/css/style.css index 1226c519a8..3f40ef74c6 100644 --- a/css/style.css +++ b/assets/css/style.css @@ -1,1738 +1,1739 @@ -* { - box-sizing: border-box; - -webkit-tap-highlight-color: transparent; - scroll-behavior: smooth; -} - -/* handle header offset with scroll-margin */ -h1, h2, h3, h4, h5, h6, -[id] { - scroll-margin-top: 60px; -} - -/* Respect user motion preferences for access */ -@media (prefers-reduced-motion: reduce) { - html { - scroll-behavior: auto; - } -} - -body { - font: 400 14px/1.6 "Open Sans", sans-serif; - background: var(--bg); - margin: 0; - padding: 0; - color: var(--fg); - display: grid; - grid-template-areas: - 'header' - 'i18n' - 'content' - 'footer' -} - -header { - grid-area: header; -} - -.content { - grid-area: content; -} - -footer { - grid-area: footer; -} - -body.no-scroll{ - overflow: hidden; -} - -h1 { - font-size: 30px; - line-height: 36px; -} - -#intro h2, #api-doc h1 { - font-weight: normal; -} - -h1, h2, h3 { - margin: 5px 0; - color: var(--card-fg); - -webkit-font-smoothing: antialiased; - -} - -.content h1 { - margin-bottom: 20px; -} - -.content table a.ignore-underline { - text-decoration: none; -} - -p em { - font-weight: bold; - color: var(--card-fg); -} - -p { - margin: 10px 0; - line-height: 1.35em; -} - -strong, th { - color: var(--card-fg); -} - -#overlay { - position: fixed; - left: 0; - top: 0; - opacity: 0.6; - width: 100%; - height: 100%; - display: none; - z-index: 1; - background-color: var(--bg); -} - -main.home { - max-width: 75rem; - margin: 40px auto 2%; - padding-inline: 5%; - grid-area: content; -} - -#home-content { - display: flex; -} - -#homepage-leftpane { - min-width: 500px; - margin-right: 30px; - font-size: 90%; - padding-top: 13px; -} - -#homepage-rightpane { - min-width: 500px; - padding: 25px 30px 0px 0px; -} - -#homepage-rightpane iframe { - min-width: 100%; - min-height: 273px; -} - -#announcements { - margin-top: 40px; - padding: 0 16px; - background: var(--notice-bg); - border: 1px solid var(--notice-accent); - border-radius: 3px; - font-size: 0.9em; - & a { - color: var(--notice-accent); - text-decoration: underline; - } -} - -#announcements ul { - padding-left: 0; -} - -#announcements li { - list-style: none; - margin-bottom: 16px; -} - -#announcements p { - margin: 6px 0; -} - -#announcements time { - font-weight: normal; - margin-right: 12px; -} - -.announcement-title { - font-weight: bold; - margin-bottom: 11px; - display: flex; - align-items: center; - column-gap: 8px -} - -.install-command { - font-family: Consolas, Monaco, "Andale Mono", monospace; - padding: 10px; - border: 1px solid var(--border); - border-radius: 3px; - max-width: 375px; - background-color: inherit; - - code { - background-color: inherit; - } -} - -.content { - display: flex; - flex-direction: row-reverse; - padding-inline-start: 1rem; - margin-block-start: 3.5rem; -} - -.content main { - max-width: 900px; - margin-inline: auto; -} - -.flex-row-content { - flex-direction: row; -} - -span.block-section { - display: block; -} - -#intro h2 { - font-size: 25px; - margin-bottom: 10px; -} - -#api-doc section { - padding-left: 20px; -} - -#api-doc > h3 { - padding-top: 10px; - padding-bottom: 5px; - font-weight: bold; - font-size: 24px; - color: var(--menu-grey) -} - -#api-doc h2 { - font-weight: bold; - font-size: 29px; - margin: 40px 0 20px; -} - -#api-doc section h3 { - padding-top: 10px; - padding-bottom: 5px; - font-weight: bold; - font-size: 18px; -} - -#api-doc h4 { - font-size: 16px; - font-weight: bold; -} - -#api-doc h5 { - font-size: 14px; - font-weight: bold; - color: var(--menu-grey) -} - -/* scroll */ - -*::-webkit-scrollbar { - background-color: opacity(var(--box-fg), 0.145); - width: 16px; -} - -*::-webkit-scrollbar-thumb { - border-radius: 8px; - border: 4px solid transparent; - background-clip: content-box; - background-color: var(--menu-grey); -} - -*::-webkit-scrollbar-thumb:hover { - background-color: var(--hover-bg); -} - -*::-webkit-scrollbar-thumb:active { - background-color: var(--menu-grey); -} - -/* links */ - -a { - color: var(--link); - text-decoration: underline; -} - -.h2:target { - display: block; - padding-top: 40px; -} - - -/* logo */ -.logo-container a { - text-decoration: none; - display: flex; - justify-content: center; - align-items : center; -} - -.express-logo { - fill : var(--card-fg); -} - -#description .express { - display: block; - font: 4.5em "Helvetica Neue", "Open Sans", sans-serif; - font-weight: 100; - margin-bottom: .25em; -} - -#description .express > span { - color: var(--card-fg); -} - -#description .express a#express-version { - font-size: 0.2em; - margin-left: 0.5em; - color: var(--link); - font-weight: 400; - text-decoration: underline; -} - -#description { - margin-bottom: 43px; - -webkit-font-smoothing: antialiased; -} - -#description .description { - position: relative; - top: -5px; - font: 100 4.1em "Helvetica Neue", "Open Sans", sans-serif; - color: var(--menu-grey); - line-height: .87; - margin: unset -} - -#description .description a { - text-decoration-thickness: 1px; - text-underline-offset: 3px; -} - -.header-right { - display: flex; - align-items: center; - gap: 20px; -} - -header { - background: var(--card-bg); - height: 57px; - display: flex; - align-items: center; - justify-content: space-between; - padding-inline: 1rem; - border-bottom: 1px solid var(--hover-fg); -} - -.scroll header { - box-shadow: 0 0 4px var(--card-bg); -} - -/* code */ - -code { - background-color: var(--code-bg); - color: var(--card-fg); - margin-block: -.125rem; - font-size: 13px; - padding: .125rem .375rem; - border-radius: 6px; -} - -pre { - padding: 16px; - border-radius: 3px; - border: 1px solid var(--border); - background-color: var(--code-bg); -/* keyboard focus offset improve visibility */ - &:focus { - border-color: var(--hover-border); - } -} - -pre code { - padding: 0; -} - -pre:has(code) { - position: relative; - - &:is(:hover, :focus) { - button { - display: flex; - } - } - /* focus copy btn by keyboard */ - &:focus-within button { - display: flex; - } -} - -pre:has(code) button { - position: absolute; - top: 5px; - right: 5px; - border: none; - z-index: 100; - display: none; - cursor: pointer; - background-color: inherit; - padding: 2px; - border-radius: 5px; - - &::after { - content: ""; - background-color: var(--card-fg); - mask-image: url("/images/copy-btn.svg"); - mask-size: 1.5rem; - mask-repeat: no-repeat; - width: 1.5rem; - height: 1.5rem; - } - - &:is(:hover, :focus) { - background-color: var(--hover-bg); - outline: 2px solid var(--hover-border); - } - - @media all and (max-width: 370px) { - padding: 1px; - - &::after { - mask-size: 1rem; - width: 1rem; - height: 1rem; - } - } -} - -pre:has(code) button.copied { - outline-color: var(--supported-fg); - - &::after { - background-color: var(--supported-fg); - } - - &::before { - font-size: 0.85rem; - position: absolute; - left: -58px; - content: "copied!"; - - width: fit-content; - height: fit-content; - padding: 4px; - border-radius: 2px; - color: var(--card-fg); - background-color: var(--card-bg); - outline: 1px solid var(--supported-fg); - } - - @media all and (max-width: 400px) { - &::before { - left: -50px; - font-size: 0.7rem; - padding: 3px; - } - } -} - -pre:has(code) button.failed { - outline-color: var(--eol-fg); - - &::after { - background-color: var(--eol-fg); - } - - &::before { - font-size: 0.85rem; - position: absolute; - left: -58px; - content: "failed!"; - - width: fit-content; - height: fit-content; - padding: 4px; - border-radius: 2px; - color: var(--card-fg); - background-color: var(--card-bg); - outline: 1px solid var(--eol-fg); - } - - @media all and (max-width: 400px) { - &::before { - left: -50px; - font-size: 0.7rem; - padding: 3px; - } - } -} - -/* scroll to top button */ - -.scroll #top { - opacity: .5; - display: initial -} - -.scroll #top:hover { - opacity: 1; -} - -#top { - line-height: 0; - border-radius: 2px; - position: fixed; - bottom: 15px; - right: 15px; - padding: 8px; - text-decoration: none; - opacity: 0; - transition: opacity 300ms; - border: 1px solid var(--border); - background-color: var(--card-bg); - color: var(--card-fg); - display: none; -} - -/* clearfix */ - -.clearfix:after { - content: "."; - display: block; - clear: both; - visibility: hidden; - line-height: 0; - height: 0; -} - -.clearfix { - display: inline-block; -} - -html[xmlns] .clearfix { - display: block; -} - -* html .clearfix { - height: 1%; -} - -/* boxes */ - -#boxes { - display: grid; - grid-template-columns: repeat(4, 1fr); - row-gap: 20px; - column-gap: 50px; - margin-top: 30px; -} - -#boxes h2 { - line-height: 1.25em; - color: var(--card-fg); - background: none; - margin-top: 0; - padding-top: 0; -} - -#boxes h2 a { - text-decoration: none; - color: var(--card-fg); -} - -#boxes div { - list-style: none; -} - -/* tables specific */ - -table { - margin: 1em 0; - border: 1px solid var(--border); - border-collapse: collapse; - width: 100%; - @media screen and (max-width:600px) { - font-size: smaller; - } -} - -table td, table th { - padding: 7px; - line-height: 120%; - vertical-align: top; - border: 1px solid var(--border); -} - -table tr th { - background: var(--card-bg); - font-size: 110%; -} - -table td p:first-child { - margin-top: 0; -} - -table td p, li p { - width: 100% !important; -} - -table ul { - margin: 20px 0 -} - -/* doc boxes */ - -.doc-box { - padding: 16px; - color: var(--box-fg); - border-radius: 0 6px 6px 0; - margin-bottom: 1rem; -} - -.doc-box p { - margin: 0 0 8px 0; -} - -.doc-box p:last-child { - margin: 0; -} - -.doc-title { - display: flex; - align-items: center; - gap: 3px; - font-weight: 600; -} - -/* i18n box */ -.doc-notice { - padding-block: 1rem; - padding-inline: 2.5rem; - color: var(--box-fg); - border-radius: 0 6px 6px 0; - background: var(--notice-bg); - border-left: 3px solid var(--notice-accent); - margin-inline: auto; - margin-block-start: 2rem; - position: relative; - grid-area: i18n; - display: block; -} - -.doc-notice a{ - color: var(--notice-accent); - text-decoration: underline; -} - -.doc-notice[hidden] { - display: none; -} - -.doc-info { - background: var(--info-bg); - border-left: 3px solid var(--info-accent); -} - -.doc-info a{ - color: var(--info-accent); - text-decoration: underline; -} - -.doc-warn { - background: var(--warn-bg); - border-left: 3px solid var(--warn-accent); -} - -.doc-warn a { - color: var(--warn-accent); - text-decoration: underline; -} - -#close-i18n-notice-box { - position: absolute; - top: 3px; - right: 9px; - color: var(--notice-accent); - cursor: pointer; -} - -/* general */ - -#app-settings-property { - width: 200px; -} - -div.header-btn { - display: flex; - padding: 3px; - border-radius: 3px; - cursor: pointer; - color: var(--box-fg); -} - -a.edit-github-btn{ - display: flex; - gap: 0.5rem; - align-items: center; - width: fit-content; - padding: 0.5rem; - border-radius: 0.3rem; - - &:is(:hover, :active, :focus) { - color: var(--fg); - background-color: var(--hover-bg); - outline: 1px solid var(--card-fg); - } -} - -#mobile-menu { - display: none; - position: relative; -} - -pre, code { - white-space: pre-wrap !important; -} - -/* footer */ - -footer { - font-size: 12px; - display: flex; - gap: 24px; - flex-direction: column; - padding-block: 2rem; - padding-inline: 3rem; - - @media screen and (max-width : 360px) { - padding: 1rem; - } -} - -#footer-content { - width: 100%; - justify-content: space-between; - gap: 32px; - display: flex; -} - -#footer-copyright { - display: flex; - flex-direction: column; - justify-content: center; - gap: 20px; -} - -#footer-policy { - display: flex; - flex-wrap: wrap; - column-gap: 20px; - row-gap: 8px; - justify-content: center; - font-size: 15px; -} - -#footer-links { - display: flex; - gap: 20px; - flex-wrap: wrap; - align-items: center; - justify-content: center; -} - -.footer-social { - display: flex; - gap: 20px; -} - -.footer-social a { - color: inherit; -} - -/* icons */ -a.openjs-logo { - display: inline-block; - width: 125px; - height: 39px; - cursor: pointer; -} - -/* theme and lang btn */ -button.theme-btn { - width: 2rem; - height: 2rem; - border: none; - cursor: pointer; - color: var(--fg); - background-color: inherit; - display: flex; - justify-content: center; - align-items: center; -} - -#icon-moon, -#icon-sun { - display: none; - align-self: center; -} -html.light-mode #icon-moon { - display: inline; -} - -button.lang-btn { - appearance: none; - background-color: inherit; - border: 0; - cursor: pointer; - color: var(--card-fg); - padding: 0.2rem; - width: fit-content; - aspect-ratio: 1; -} - -div.desktop-lang-switcher { - position: relative; - - > ul.lang-list { - display: none; - opacity: 0; - position: absolute; - list-style: none; - visibility: hidden; - left: -75px; - z-index: 100; - background-color: var(--card-bg); - border: 1px solid; - border-radius: 10px; - padding: 0px; - min-width: max-content; - - li a { - display: block; - padding: 5px 20px 5px 20px; - text-decoration: none; - color: var(--card-fg); - &:is(:hover, :focus) { - background: var(--hover-bg); - } - } - - > li:first-child > a { - border-start-start-radius: 10px; - border-start-end-radius: 10px; - } - - > li:last-child > a { - border-end-start-radius: 10px; - border-end-end-radius: 10px; - } - } - - > ul.lang-list.open { - display: block; - opacity: 1; - visibility: visible; - } -} - -/* navigation */ -#navbar { - line-height: 30px; - display: flex; - align-items: center; -} - -#navbar a { - color: var(--card-fg); - text-decoration: none; -} - -#navbar a.active { - font-weight: bold; -} - -#navbar ul { - list-style: none; -} - -#navmenu { - display: flex; - gap: 20px; -} - -/* content doc */ - -#blog-doc { - padding: 0.5rem; - width: fit-content; -} - -/* dropdown menu */ - -.submenu { - position: relative; - list-style: none; -} - -.submenu-content { - position: absolute; - top: 100%; - left: 50%; - transform: translate(-50%); - margin: auto; - box-shadow: 1px 2px var(--hover-fg); - z-index: 1000; - min-width: max-content; - width: fit-content; - border: 1px solid var(--border); - border-radius: 12px; - background-color: var(--bg); - padding: 0; - display: none; -} - -.submenu-content li:first-child a { - border-radius: 12px 12px 0 0; -} - -.submenu-content li:last-child a { - border-radius: 0px 0px 12px 12px; -} - -.submenu.open .submenu-content { - display: initial; -} - -#navmenu { - padding: 0; - margin: 0; - right: 0px; - z-index: 1000; - margin-right: 15px; -} - -.submenu-content li a { - display: block; - padding: 2px 20px 2px 20px; -} - -#navbar .submenu-content a:hover { - background: var(--hover-bg); - text-decoration: none; -} - - -/* TOC side menu */ - -.toc-container { - position: sticky; - top: 100px; - width: 270px -} - -#menu { - min-width: 13rem; - padding-inline: 0.5rem; - font-size: 1rem; - overflow-y: auto; - max-height: 65vh; - padding-block-end: 0.5rem; - margin-block: 0; -} - -#menu.blog-side-menu { - max-width: 20rem; - max-height: fit-content; -} - -#menu ul a, -#menu > li > a { - display: block; - color: var(--menu-grey); - padding-inline: 0.5rem; - text-decoration: none; - - &:is(:hover,:active,:focus) { - border-radius: 0.3rem; - color: var(--fg); - outline: 1px solid var(--card-fg); - } -} - -#menu ul a.active { - border-radius: 0.3rem; - color: var(--fg); - outline: 1px solid var(--card-fg); -} - -#menu em { - font-weight: bold; - color: var(--menu-em); - font-size: 1rem; -} - -#menu li { - cursor: pointer; - list-style: none; - margin-block-start: 0.3rem; -} - -#menu ul, -ul#side-menu { - display: none; - opacity: 0; - height: 0; - overflow: hidden; -} - -#menu ul.active, -ul#side-menu.active { - height: auto; - padding-inline: 0.5rem; - display: block; - opacity: 1; - padding-block: 0.5rem; -} - -#menu > li > a { - font-weight: bold; - font-size: 1rem; - padding-inline-start: 1rem; -} - -/* can't find this in proj*/ -h2 a { - color: var(--card-fg) !important; -} - -/* search */ - -#q { - display: none; - height: 2.5em; - max-width: 100%; - padding: 5px; -} - -.algolia-autocomplete { - max-width: 9em; - > input { - color: var(--fg); - background-color: var(--bg); - } - > input::placeholder { - color: var(--fg); - } - #q { - display: initial; - border-radius: 8px; - border: 1px solid var(--border); - transition: color .3s ease; - padding-inline: 12px; - outline: none; - &:focus-visible, - &:focus { - border-color: var(--hover-border); - border-width: 2px; - } - } -} - - #navbar { - .ds-dropdown-menu .ds-dataset-1 { - background-color: var(--bg); - .ds-suggestions { - /* background-color: var(--bg); */ - color: var(--fg); - } - .ds-suggestion a { - background-color: var(--bg); - color: var(--fg); - } - .ds-suggestion a { - background-color: var(--bg); - color: var(--fg); - } - .algolia-docsearch-suggestion--category-header { - color: var(--fg); - } - .algolia-docsearch-suggestion--wrapper { - background-color: var(--bg); - .algolia-docsearch-suggestion--subcategory-column { - color: var(--menu-grey); - - } - .algolia-docsearch-suggestion--title, - .algolia-docsearch-suggestion--text { - color: var(--fg); - } - .algolia-docsearch-suggestion--highlight { - color: var(--link); - background-color: initial; - } - } - .algolia-docsearch-suggestion { - background-color: initial; - } - .algolia-docsearch-suggestion--content .algolia-docsearch-suggestion--no-results{ - background-color: initial; - } - - } - .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--title, - .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content { - background-color: var(--hover-bg); - } - } - - -.content-404 { - height: 70vh; - padding: 153px 32px 7%; - text-align: center; - display: flex; - justify-content: center; - flex-direction: column; - grid-area: content; -} - -.content-404 p { - font-size: 16px; -} - -/* search-bar desktop re-sizing */ -@media all and (min-width: 950px) { - .algolia-autocomplete { - margin-right:15px; - max-width: 12em; - } -} - -/* toc title */ -.toc-heading { - display: block; - cursor: default; - padding-inline-start: 1rem; - & > em { - font-weight: bold; - color: var(--menu-em); - font-size: 1rem; - } -} - - -/* TOC btn */ - -#menu-toggle { - cursor: pointer; - display: none; - font-size: 1rem; - padding: 0.5rem; - opacity: 0; - width: fit-content; - border: 1px solid #000; - border-radius: 0.3rem; - color: #000; - background-color: #fff; - - &::after { - content: ""; - display: block; - width: 0.8em; - height: 0.5em; - background-color: var(--card-bg); - clip-path: polygon(100% 0%, 0 0%, 50% 100%); - cursor: pointer; - pointer-events: none; - transition: transform 0.2s ease-in-out; - transform: rotate(-90deg); - } - - &:is(:hover, :active, :focus) { - background-color: #ebf2f5; - } -} - -/* routing methods columns */ -.methods-columns { - display: flex; - gap: 2rem; - justify-content: space-between; - flex-wrap: wrap; - - @media screen and (max-width: 460px) { - flex-direction: column; - gap: 0.3rem; - } -} - -/* responsive */ - -@media all and (max-width: 1440px) { - #menu{ - top: 75px; - } -} - -@media all and (max-width: 1110px) { - #boxes { - grid-template-columns: 1fr 1fr; - } - - #home-content { - flex-direction: column; - } - - .install-command { - display: none; - } - - #home-content .pane { - min-width: auto; - font-size: 74%; - } - - #homepage-leftpane { - padding-top: 0px; - } - - #homepage-rightpane { - padding-top: 0; - padding-right: 0; - } - - .table-scroller { - width: 100%; - overflow: scroll; - scrollbar-width: thin; - } - - code { - word-break: break-all; - } - - ul { - padding-left: 5%; - } - - h1 { - font-size: 22px; - line-height: 26px; - } - - h2 { - font-size: 18px; - line-height: 25px; - } - - h3 { - font-size: 16px; - line-height: 23px; - word-break: break-all; - } - - h4 { - font-size: 16px; - line-height: 18px; - font-weight: normal; - } - - #home-content { - margin: 60px 0 0 5%; - padding-right: 5%; - } - - #description { - margin-bottom: 35px; - } - - #description .description { - font-size: 3em; - line-height: .9em; - font-weight: 200; - } - - .logo-container { - margin-inline: auto; - } - - #home-menu { - display: block; - position: absolute; - top: 7px; - } - - #overlay.blurs{ - display: block; - } - - .menu ul { - display: block; - } - - #footer-content { - flex-wrap: wrap; - justify-content: center; - } - - #footer-copyright > a { - width: 100%; - display: flex; - justify-content: center; - } - - .header-right { - display: flex; - gap: 8px; - } -} - -/* TOC responsive */ -@media all and (max-width: 800px) { - .content { - flex-direction: column; - padding-inline-start : 0; - margin-block-start: 1rem; - } - - .content main { - padding-inline: 1rem; - width: 100vw; - margin-top: 0; - margin-inline: 0; - } - - #api-doc, - #blog-doc, - #page-doc { - width: 100%; - } - - #api-doc section { - padding-left: 0; - } - - .toc-container { - display: flex; - flex-direction: column; - gap: 0; - padding: 1rem; - } - - #menu { - display: none; - opacity: 0; - max-height: 0; - background-color: var(--card-bg); - min-width: 100%; - } - - #menu.open { - display: block; - opacity: 1; - max-height: 35vh; - padding-inline: 1rem; - border-left: 2px solid var(--border); - margin-top: 0.3rem; - border-bottom-right-radius: 0.5rem; - border-top-right-radius: 0.5rem; - } - - .toc-container { - width: 100%; - } - - #menu-toggle.show { - display: flex; - gap: 0.5rem; - align-items: center; - opacity: 1; - } - - #menu-toggle.show.rotate::after { - transform: rotate(0deg); - } - - #menu > li > a, - #menu ul a { - padding: 0.5rem; - &:is(:hover,:active,:focus) { - background: var(--hover-bg); - } - } - - #menu li ul li > em { - font-size: 0.8rem; - padding-inline: 1rem; - padding-block: 0.3rem; - background-color: var(--hover-bg); - border-radius: 0.3rem; - } - - .toc-heading{ - display: none; - } -} - - -@media all and (max-width: 540px) { - #boxes { - grid-template-columns: 1fr; - } -} - -@media all and (max-width: 420px) { - #app-settings-property { - width: auto; - } -} - - -@media print { - - header { - position: absolute; - } -} - -/* For image callouts in writing-middleware.md */ - -.callout {position: relative;} - -#mw-fig { - border-collapse: separate; - padding: 0; - border: 0; - width: 960px; - margin-bottom: 20px; -} -#mw-fig-imgcell { - margin: 0; - padding: 0px; - border: 0; - width: 410px; -} -#mw-fig-img { - margin: 0px; - padding: 0px; - width: 410px; - height: 308px; -} - -.mw-fig-callouts { - margin: 0; - padding: 0 0 0 5px; - border: 0; - width: 550px; -} - -/* Blog page styles*/ -#blog-doc { - margin: 0 1rem; - @media all and (max-width: 800px) { - margin: 0; - } -} -#blog-doc:has(> h1#express-blog), -#blog-doc:has(> h1#write-a-blog-post) { - min-height: 300px; -} -#blog-doc .blog-details ~ p > img { - width: 200px; - float: right; - margin: 0.5rem; -} -#blog-doc p { - font-size: 1.1em; -} -.blog-posts { - display: flex; - flex-direction: column; - row-gap: 10px; -} -.blog-post { - width: 100%; - background-color: var(--card-bg); - display: flex; - padding: 10px; - flex-direction: column; - justify-content: space-between; - border-radius: 5px; - border: 1px solid var(--border); - box-shadow: 2px 3px var(--hover-fg); - transition: 0.3s; -} -.blog-post:hover { - background-color: var(--hover-bg); - border: 1px solid var(--hover-border); - box-shadow: 2px 3px var(--menu-grey); -} -.blog-post img { - max-width: 100%; - max-height: 100%; - object-fit: cover; -} -.blog-post .blog-details { - display: flex; - flex-direction: column; -} -.blog-details div:first-child { - margin-bottom: 5px; -} -.blog-tag { - font-size: 12px; -} -.blog-title { - font-size: 1.3rem; - line-height: 1.5rem; - font-weight: 500; - padding-right: .2em; -} -.blog-title a { - color: var(--card-fg) -} -.blog-excerpt { - font-size: .75rem; -} -.blog-img { - max-width: 100%; - margin: auto; -} -.blog-authors { - font-style: italic; -} -.blog-author-link { - color: inherit; - margin-left: 0.5ch; - text-decoration: none; -} -.blog-author-link-label { - text-decoration: underline; -} -.blog-author-avatar { - border-radius: 50%; - display: inline-block; - vertical-align: middle; - width: 1.5em; - height: 1.5em; -} -.blog-date { - font-weight: bold; - font-size: 85%; -} -/* mobile-only */ -@media (max-width: 500px) { - #blog-doc { - display: flex; - flex-wrap: wrap; - flex-direction: column; - align-items: center; - margin-right: 0; - padding-right: 10px; - } - #blog-doc .blog-details + p > img { - margin-bottom: 15px; - } -} - - - -/* blog tablet and up*/ -@media (min-width: 768px) { - .blog-post { - margin: auto; - } - .blog-tags { - margin-bottom: 20px; - } - .blog-title { - font-size: 1.3rem; - margin-bottom: 20px; - line-height: 1.5rem; - } - .blog-post .blog-details { - display: flex; - flex-direction: row; - margin-left: 1rem; - font-size: 90%; - } - .blog-post .blog-details div:first-child { - margin-right: 20px; - } - .blog-details { - font-size: 1rem; - } - .blog-excerpt { - line-height: initial; - font-size: .85rem; - font-weight: 300; - margin-top: auto; - margin-bottom: 10px; - max-width: 80%; - } -} - -strong.supported { - color: var(--supported-fg) ; -} -strong.eol { - color: var(--eol-fg) ; -} - -.logo-table { - display: flex; - flex-wrap: wrap; - row-gap: 8px; - column-gap: 48px; -} - -.logo-table h3{ - margin-bottom: 12px; -} - -blockquote { - margin-left: 0; - font-weight: 600; - font-style: italic; - padding-left: 1.2em; - border-left: .25rem solid var(--border); -} - -@media all and (max-width: 1110px) { - .algolia-autocomplete { - display: none !important; - } - - #mobile-menu { - display: block; - } - - #navbar { - padding: 0; - top: 1px; - position: static; - } - - #navmenu>li:first-child { - display: none; - } - - #navmenu>li { - border-bottom: 1px solid var(--border); - margin: 0; - min-height: 47px; - background: var(--card-bg); - cursor: pointer; - display: flex; - align-items: center; - } - - #navmenu>li.open:hover { - background: var(--card-bg); - } - #navmenu>li:hover { - background: var(--hover-bg); - & ul { - background-color: var(--card-bg); - } - } - - #navmenu { - left: 0; - padding: 0; - top: 57px; - width: 100%; - position: absolute; - display: none; - } - - #navmenu.opens { - display: block; - } - - #navbar a { - font-size: 19px; - margin: 0; - width: 100%; - height: 100%; - padding-left: 5%; - } - - #navbar .submenu.open { - flex-direction: column; - align-items: initial; - > a { - border-bottom: 1px solid var(--border); - } - } - - .submenu.open > a { - display: flex; - align-items: center; - min-height: 47px; - } - - .submenu-content { - width: 100%; - position: static; - display: none; - margin-top: 7px; - background-color: var(--card-bg); - padding: 0; - margin: 0; - border: none; - border-radius: 0; - box-shadow: none; - max-height: 190px; - overflow-y: auto; - overflow-x: hidden; - transform: none; - cursor: pointer; - } - - .submenu-content li > a { - width: 100%; - } - - .submenu-content li:first-child a { - border-radius: 0; - } - - .submenu-content li:last-child { - border-bottom: 0; - } - - .submenu-content li:last-child a { - border-radius: 0; - } - - .submenu-content.open { - display: inline-block; - } - - #navbar .submenu-content li a { - font-size: 16px; - padding: 5px 5px 5px 5%; - padding-left: 10%; - } - - .submenu-content li { - border-bottom: 1px solid var(--border); - } -} +* { + box-sizing: border-box; + -webkit-tap-highlight-color: transparent; + scroll-behavior: smooth; +} + +/* handle header offset with scroll-margin */ +h1, h2, h3, h4, h5, h6, +[id] { + scroll-margin-top: 60px; +} + +/* Respect user motion preferences for access */ +@media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } +} + +body { + font: 400 14px/1.6 "Open Sans", sans-serif; + background: var(--bg); + margin: 0; + padding: 0; + color: var(--fg); + display: grid; + grid-template-areas: + 'header' + 'i18n' + 'content' + 'footer' +} + +header { + grid-area: header; +} + +.content { + grid-area: content; +} + +footer { + grid-area: footer; +} + +body.no-scroll{ + overflow: hidden; +} + +h1 { + font-size: 30px; + line-height: 36px; +} + +#intro h2, #api-doc h1 { + font-weight: normal; +} + +h1, h2, h3 { + margin: 5px 0; + color: var(--card-fg); + -webkit-font-smoothing: antialiased; + +} + +.content h1 { + margin-bottom: 20px; +} + +.content table a.ignore-underline { + text-decoration: none; +} + +p em { + font-weight: bold; + color: var(--card-fg); +} + +p { + margin: 10px 0; + line-height: 1.35em; +} + +strong, th { + color: var(--card-fg); +} + +#overlay { + position: fixed; + left: 0; + top: 0; + opacity: 0.6; + width: 100%; + height: 100%; + display: none; + z-index: 1; + background-color: var(--bg); +} + +main.home { + max-width: 75rem; + margin: 40px auto 2%; + padding-inline: 5%; + grid-area: content; +} + +#home-content { + display: flex; +} + +#homepage-leftpane { + min-width: 500px; + margin-right: 30px; + font-size: 90%; + padding-top: 13px; +} + +#homepage-rightpane { + min-width: 500px; + padding: 25px 30px 0px 0px; +} + +#homepage-rightpane iframe { + min-width: 100%; + min-height: 273px; +} + +#announcements { + margin-top: 40px; + padding: 0 16px; + background: var(--notice-bg); + border: 1px solid var(--notice-accent); + border-radius: 3px; + font-size: 0.9em; + & a { + color: var(--notice-accent); + text-decoration: underline; + } +} + +#announcements ul { + padding-left: 0; +} + +#announcements li { + list-style: none; + margin-bottom: 16px; +} + +#announcements p { + margin: 6px 0; +} + +#announcements time { + font-weight: normal; + margin-right: 12px; +} + +.announcement-title { + font-weight: bold; + margin-bottom: 11px; + display: flex; + align-items: center; + column-gap: 8px +} + +.install-command { + font-family: Consolas, Monaco, "Andale Mono", monospace; + padding: 10px; + border: 1px solid var(--border); + border-radius: 3px; + max-width: 375px; + background-color: inherit; + + code { + background-color: inherit; + } +} + +.content { + display: flex; + flex-direction: row-reverse; + padding-inline-start: 1rem; + margin-block-start: 3.5rem; +} + +.content main { + max-width: 900px; + margin-inline: auto; +} + +.flex-row-content { + flex-direction: row; +} + +span.block-section { + display: block; +} + +#intro h2 { + font-size: 25px; + margin-bottom: 10px; +} + +#api-doc section { + padding-left: 20px; +} + +#api-doc > h3 { + padding-top: 10px; + padding-bottom: 5px; + font-weight: bold; + font-size: 24px; + color: var(--menu-grey) +} + +#api-doc h2 { + font-weight: bold; + font-size: 29px; + margin: 40px 0 20px; +} + +#api-doc section h3 { + padding-top: 10px; + padding-bottom: 5px; + font-weight: bold; + font-size: 18px; +} + +#api-doc h4 { + font-size: 16px; + font-weight: bold; +} + +#api-doc h5 { + font-size: 14px; + font-weight: bold; + color: var(--menu-grey) +} + +/* scroll */ + +*::-webkit-scrollbar { + background-color: opacity(var(--box-fg), 0.145); + width: 16px; +} + +*::-webkit-scrollbar-thumb { + border-radius: 8px; + border: 4px solid transparent; + background-clip: content-box; + background-color: var(--menu-grey); +} + +*::-webkit-scrollbar-thumb:hover { + background-color: var(--hover-bg); +} + +*::-webkit-scrollbar-thumb:active { + background-color: var(--menu-grey); +} + +/* links */ + +a { + color: var(--link); + text-decoration: underline; +} + +.h2:target { + display: block; + padding-top: 40px; +} + + +/* logo */ +.logo-container a { + text-decoration: none; + display: flex; + justify-content: center; + align-items : center; +} + +.express-logo { + fill : var(--card-fg); +} + +#description .express { + display: block; + font: 4.5em "Helvetica Neue", "Open Sans", sans-serif; + font-weight: 100; + margin-bottom: .25em; +} + +#description .express > span { + color: var(--card-fg); +} + +#description .express a#express-version { + font-size: 0.2em; + margin-left: 0.5em; + color: var(--link); + font-weight: 400; + text-decoration: underline; +} + +#description { + margin-bottom: 43px; + -webkit-font-smoothing: antialiased; +} + +#description .description { + position: relative; + top: -5px; + font: 100 4.1em "Helvetica Neue", "Open Sans", sans-serif; + color: var(--menu-grey); + line-height: .87; + margin: unset +} + +#description .description a { + text-decoration-thickness: 1px; + text-underline-offset: 3px; +} + +.header-right { + display: flex; + align-items: center; + gap: 20px; +} + +header { + background: var(--card-bg); + height: 57px; + display: flex; + align-items: center; + justify-content: space-between; + padding-inline: 1rem; + border-bottom: 1px solid var(--hover-fg); +} + +.scroll header { + box-shadow: 0 0 4px var(--card-bg); +} + +/* code */ + +code { + background-color: var(--code-bg); + color: var(--card-fg); + margin-block: -.125rem; + font-size: 13px; + padding: .125rem .375rem; + border-radius: 6px; +} + +pre { + padding: 16px; + border-radius: 3px; + border: 1px solid var(--border); + background-color: var(--code-bg); +/* keyboard focus offset improve visibility */ + &:focus { + border-color: var(--hover-border); + } +} + +pre code { + padding: 0; +} + +pre:has(code) { + position: relative; + + &:is(:hover, :focus) { + button { + display: flex; + } + } + /* focus copy btn by keyboard */ + &:focus-within button { + display: flex; + } +} + +pre:has(code) button { + position: absolute; + top: 5px; + right: 5px; + border: none; + z-index: 100; + display: none; + cursor: pointer; + background-color: inherit; + padding: 2px; + border-radius: 5px; + + &::after { + content: ""; + background-color: var(--card-fg); + mask-image: url("/assets/images/copy-btn.svg"); + mask-size: 1.5rem; + mask-repeat: no-repeat; + width: 1.5rem; + height: 1.5rem; + } + + &:is(:hover, :focus) { + background-color: var(--hover-bg); + outline: 2px solid var(--hover-border); + } + + @media all and (max-width: 370px) { + padding: 1px; + + &::after { + mask-size: 1rem; + width: 1rem; + height: 1rem; + } + } +} + +pre:has(code) button.copied { + outline-color: var(--supported-fg); + + &::after { + background-color: var(--supported-fg); + } + + &::before { + font-size: 0.85rem; + position: absolute; + left: -58px; + content: "copied!"; + + width: fit-content; + height: fit-content; + padding: 4px; + border-radius: 2px; + color: var(--card-fg); + background-color: var(--card-bg); + outline: 1px solid var(--supported-fg); + } + + @media all and (max-width: 400px) { + &::before { + left: -50px; + font-size: 0.7rem; + padding: 3px; + } + } +} + +pre:has(code) button.failed { + outline-color: var(--eol-fg); + + &::after { + background-color: var(--eol-fg); + } + + &::before { + font-size: 0.85rem; + position: absolute; + left: -58px; + content: "failed!"; + + width: fit-content; + height: fit-content; + padding: 4px; + border-radius: 2px; + color: var(--card-fg); + background-color: var(--card-bg); + outline: 1px solid var(--eol-fg); + } + + @media all and (max-width: 400px) { + &::before { + left: -50px; + font-size: 0.7rem; + padding: 3px; + } + } +} + +/* scroll to top button */ + +.scroll #top { + opacity: .5; + display: initial +} + +.scroll #top:hover { + opacity: 1; +} + +#top { + line-height: 0; + border-radius: 2px; + position: fixed; + bottom: 15px; + right: 15px; + padding: 8px; + text-decoration: none; + opacity: 0; + transition: opacity 300ms; + border: 1px solid var(--border); + background-color: var(--card-bg); + color: var(--card-fg); + display: none; + z-index: 200; +} + +/* clearfix */ + +.clearfix:after { + content: "."; + display: block; + clear: both; + visibility: hidden; + line-height: 0; + height: 0; +} + +.clearfix { + display: inline-block; +} + +html[xmlns] .clearfix { + display: block; +} + +* html .clearfix { + height: 1%; +} + +/* boxes */ + +#boxes { + display: grid; + grid-template-columns: repeat(4, 1fr); + row-gap: 20px; + column-gap: 50px; + margin-top: 30px; +} + +#boxes h2 { + line-height: 1.25em; + color: var(--card-fg); + background: none; + margin-top: 0; + padding-top: 0; +} + +#boxes h2 a { + text-decoration: none; + color: var(--card-fg); +} + +#boxes div { + list-style: none; +} + +/* tables specific */ + +table { + margin: 1em 0; + border: 1px solid var(--border); + border-collapse: collapse; + width: 100%; + @media screen and (max-width:600px) { + font-size: smaller; + } +} + +table td, table th { + padding: 7px; + line-height: 120%; + vertical-align: top; + border: 1px solid var(--border); +} + +table tr th { + background: var(--card-bg); + font-size: 110%; +} + +table td p:first-child { + margin-top: 0; +} + +table td p, li p { + width: 100% !important; +} + +table ul { + margin: 20px 0 +} + +/* doc boxes */ + +.doc-box { + padding: 16px; + color: var(--box-fg); + border-radius: 0 6px 6px 0; + margin-bottom: 1rem; +} + +.doc-box p { + margin: 0 0 8px 0; +} + +.doc-box p:last-child { + margin: 0; +} + +.doc-title { + display: flex; + align-items: center; + gap: 3px; + font-weight: 600; +} + +/* i18n box */ +.doc-notice { + padding-block: 1rem; + padding-inline: 2.5rem; + color: var(--box-fg); + border-radius: 0 6px 6px 0; + background: var(--notice-bg); + border-left: 3px solid var(--notice-accent); + margin-inline: auto; + margin-block-start: 2rem; + position: relative; + grid-area: i18n; + display: block; +} + +.doc-notice a{ + color: var(--notice-accent); + text-decoration: underline; +} + +.doc-notice[hidden] { + display: none; +} + +.doc-info { + background: var(--info-bg); + border-left: 3px solid var(--info-accent); +} + +.doc-info a{ + color: var(--info-accent); + text-decoration: underline; +} + +.doc-warn { + background: var(--warn-bg); + border-left: 3px solid var(--warn-accent); +} + +.doc-warn a { + color: var(--warn-accent); + text-decoration: underline; +} + +#close-i18n-notice-box { + position: absolute; + top: 3px; + right: 9px; + color: var(--notice-accent); + cursor: pointer; +} + +/* general */ + +#app-settings-property { + width: 200px; +} + +div.header-btn { + display: flex; + padding: 3px; + border-radius: 3px; + cursor: pointer; + color: var(--box-fg); +} + +a.edit-github-btn{ + display: flex; + gap: 0.5rem; + align-items: center; + width: fit-content; + padding: 0.5rem; + border-radius: 0.3rem; + + &:is(:hover, :active, :focus) { + color: var(--fg); + background-color: var(--hover-bg); + outline: 1px solid var(--card-fg); + } +} + +#mobile-menu { + display: none; + position: relative; +} + +pre, code { + white-space: pre-wrap !important; +} + +/* footer */ + +footer { + font-size: 12px; + display: flex; + gap: 24px; + flex-direction: column; + padding-block: 2rem; + padding-inline: 3rem; + + @media screen and (max-width : 360px) { + padding: 1rem; + } +} + +#footer-content { + width: 100%; + justify-content: space-between; + gap: 32px; + display: flex; +} + +#footer-copyright { + display: flex; + flex-direction: column; + justify-content: center; + gap: 20px; +} + +#footer-policy { + display: flex; + flex-wrap: wrap; + column-gap: 20px; + row-gap: 8px; + justify-content: center; + font-size: 15px; +} + +#footer-links { + display: flex; + gap: 20px; + flex-wrap: wrap; + align-items: center; + justify-content: center; +} + +.footer-social { + display: flex; + gap: 20px; +} + +.footer-social a { + color: inherit; +} + +/* icons */ +a.openjs-logo { + display: inline-block; + width: 125px; + height: 39px; + cursor: pointer; +} + +/* theme and lang btn */ +button.theme-btn { + width: 2rem; + height: 2rem; + border: none; + cursor: pointer; + color: var(--fg); + background-color: inherit; + display: flex; + justify-content: center; + align-items: center; +} + +#icon-moon, +#icon-sun { + display: none; + align-self: center; +} +html.light-mode #icon-moon { + display: inline; +} + +button.lang-btn { + appearance: none; + background-color: inherit; + border: 0; + cursor: pointer; + color: var(--card-fg); + padding: 0.2rem; + width: fit-content; + aspect-ratio: 1; +} + +div.desktop-lang-switcher { + position: relative; + + > ul.lang-list { + display: none; + opacity: 0; + position: absolute; + list-style: none; + visibility: hidden; + left: -75px; + z-index: 100; + background-color: var(--card-bg); + border: 1px solid; + border-radius: 10px; + padding: 0px; + min-width: max-content; + + li a { + display: block; + padding: 5px 20px 5px 20px; + text-decoration: none; + color: var(--card-fg); + &:is(:hover, :focus) { + background: var(--hover-bg); + } + } + + > li:first-child > a { + border-start-start-radius: 10px; + border-start-end-radius: 10px; + } + + > li:last-child > a { + border-end-start-radius: 10px; + border-end-end-radius: 10px; + } + } + + > ul.lang-list.open { + display: block; + opacity: 1; + visibility: visible; + } +} + +/* navigation */ +#navbar { + line-height: 30px; + display: flex; + align-items: center; +} + +#navbar a { + color: var(--card-fg); + text-decoration: none; +} + +#navbar a.active { + font-weight: bold; +} + +#navbar ul { + list-style: none; +} + +#navmenu { + display: flex; + gap: 20px; +} + +/* content doc */ + +#blog-doc { + padding: 0.5rem; + width: fit-content; +} + +/* dropdown menu */ + +.submenu { + position: relative; + list-style: none; +} + +.submenu-content { + position: absolute; + top: 100%; + left: 50%; + transform: translate(-50%); + margin: auto; + box-shadow: 1px 2px var(--hover-fg); + z-index: 1000; + min-width: max-content; + width: fit-content; + border: 1px solid var(--border); + border-radius: 12px; + background-color: var(--bg); + padding: 0; + display: none; +} + +.submenu-content li:first-child a { + border-radius: 12px 12px 0 0; +} + +.submenu-content li:last-child a { + border-radius: 0px 0px 12px 12px; +} + +.submenu.open .submenu-content { + display: initial; +} + +#navmenu { + padding: 0; + margin: 0; + right: 0px; + z-index: 1000; + margin-right: 15px; +} + +.submenu-content li a { + display: block; + padding: 2px 20px 2px 20px; +} + +#navbar .submenu-content a:hover { + background: var(--hover-bg); + text-decoration: none; +} + + +/* TOC side menu */ + +.toc-container { + position: sticky; + top: 100px; + width: 270px +} + +#menu { + min-width: 13rem; + padding-inline: 0.5rem; + font-size: 1rem; + overflow-y: auto; + max-height: 65vh; + padding-block-end: 0.5rem; + margin-block: 0; +} + +#menu.blog-side-menu { + max-width: 20rem; + max-height: fit-content; +} + +#menu ul a, +#menu > li > a { + display: block; + color: var(--menu-grey); + padding-inline: 0.5rem; + text-decoration: none; + + &:is(:hover,:active,:focus) { + border-radius: 0.3rem; + color: var(--fg); + outline: 1px solid var(--card-fg); + } +} + +#menu ul a.active { + border-radius: 0.3rem; + color: var(--fg); + outline: 1px solid var(--card-fg); +} + +#menu em { + font-weight: bold; + color: var(--menu-em); + font-size: 1rem; +} + +#menu li { + cursor: pointer; + list-style: none; + margin-block-start: 0.3rem; +} + +#menu ul, +ul#side-menu { + display: none; + opacity: 0; + height: 0; + overflow: hidden; +} + +#menu ul.active, +ul#side-menu.active { + height: auto; + padding-inline: 0.5rem; + display: block; + opacity: 1; + padding-block: 0.5rem; +} + +#menu > li > a { + font-weight: bold; + font-size: 1rem; + padding-inline-start: 1rem; +} + +/* can't find this in proj*/ +h2 a { + color: var(--card-fg) !important; +} + +/* search */ + +#q { + display: none; + height: 2.5em; + max-width: 100%; + padding: 5px; +} + +.algolia-autocomplete { + max-width: 9em; + > input { + color: var(--fg); + background-color: var(--bg); + } + > input::placeholder { + color: var(--fg); + } + #q { + display: initial; + border-radius: 8px; + border: 1px solid var(--border); + transition: color .3s ease; + padding-inline: 12px; + outline: none; + &:focus-visible, + &:focus { + border-color: var(--hover-border); + border-width: 2px; + } + } +} + + #navbar { + .ds-dropdown-menu .ds-dataset-1 { + background-color: var(--bg); + .ds-suggestions { + /* background-color: var(--bg); */ + color: var(--fg); + } + .ds-suggestion a { + background-color: var(--bg); + color: var(--fg); + } + .ds-suggestion a { + background-color: var(--bg); + color: var(--fg); + } + .algolia-docsearch-suggestion--category-header { + color: var(--fg); + } + .algolia-docsearch-suggestion--wrapper { + background-color: var(--bg); + .algolia-docsearch-suggestion--subcategory-column { + color: var(--menu-grey); + + } + .algolia-docsearch-suggestion--title, + .algolia-docsearch-suggestion--text { + color: var(--fg); + } + .algolia-docsearch-suggestion--highlight { + color: var(--link); + background-color: initial; + } + } + .algolia-docsearch-suggestion { + background-color: initial; + } + .algolia-docsearch-suggestion--content .algolia-docsearch-suggestion--no-results{ + background-color: initial; + } + + } + .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--title, + .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content { + background-color: var(--hover-bg); + } + } + + +.content-404 { + height: 70vh; + padding: 153px 32px 7%; + text-align: center; + display: flex; + justify-content: center; + flex-direction: column; + grid-area: content; +} + +.content-404 p { + font-size: 16px; +} + +/* search-bar desktop re-sizing */ +@media all and (min-width: 950px) { + .algolia-autocomplete { + margin-right:15px; + max-width: 12em; + } +} + +/* toc title */ +.toc-heading { + display: block; + cursor: default; + padding-inline-start: 1rem; + & > em { + font-weight: bold; + color: var(--menu-em); + font-size: 1rem; + } +} + + +/* TOC btn */ + +#menu-toggle { + cursor: pointer; + display: none; + font-size: 1rem; + padding: 0.5rem; + opacity: 0; + width: fit-content; + border: 1px solid #000; + border-radius: 0.3rem; + color: #000; + background-color: #fff; + + &::after { + content: ""; + display: block; + width: 0.8em; + height: 0.5em; + background-color: var(--card-bg); + clip-path: polygon(100% 0%, 0 0%, 50% 100%); + cursor: pointer; + pointer-events: none; + transition: transform 0.2s ease-in-out; + transform: rotate(-90deg); + } + + &:is(:hover, :active, :focus) { + background-color: #ebf2f5; + } +} + +/* routing methods columns */ +.methods-columns { + display: flex; + gap: 2rem; + justify-content: space-between; + flex-wrap: wrap; + + @media screen and (max-width: 460px) { + flex-direction: column; + gap: 0.3rem; + } +} + +/* responsive */ + +@media all and (max-width: 1440px) { + #menu{ + top: 75px; + } +} + +@media all and (max-width: 1110px) { + #boxes { + grid-template-columns: 1fr 1fr; + } + + #home-content { + flex-direction: column; + } + + .install-command { + display: none; + } + + #home-content .pane { + min-width: auto; + font-size: 74%; + } + + #homepage-leftpane { + padding-top: 0px; + } + + #homepage-rightpane { + padding-top: 0; + padding-right: 0; + } + + .table-scroller { + width: 100%; + overflow: scroll; + scrollbar-width: thin; + } + + code { + word-break: break-all; + } + + ul { + padding-left: 5%; + } + + h1 { + font-size: 22px; + line-height: 26px; + } + + h2 { + font-size: 18px; + line-height: 25px; + } + + h3 { + font-size: 16px; + line-height: 23px; + word-break: break-all; + } + + h4 { + font-size: 16px; + line-height: 18px; + font-weight: normal; + } + + #home-content { + margin: 60px 0 0 5%; + padding-right: 5%; + } + + #description { + margin-bottom: 35px; + } + + #description .description { + font-size: 3em; + line-height: .9em; + font-weight: 200; + } + + .logo-container { + margin-inline: auto; + } + + #home-menu { + display: block; + position: absolute; + top: 7px; + } + + #overlay.blurs{ + display: block; + } + + .menu ul { + display: block; + } + + #footer-content { + flex-wrap: wrap; + justify-content: center; + } + + #footer-copyright > a { + width: 100%; + display: flex; + justify-content: center; + } + + .header-right { + display: flex; + gap: 8px; + } +} + +/* TOC responsive */ +@media all and (max-width: 800px) { + .content { + flex-direction: column; + padding-inline-start : 0; + margin-block-start: 1rem; + } + + .content main { + padding-inline: 1rem; + width: 100vw; + margin-top: 0; + margin-inline: 0; + } + + #api-doc, + #blog-doc, + #page-doc { + width: 100%; + } + + #api-doc section { + padding-left: 0; + } + + .toc-container { + display: flex; + flex-direction: column; + gap: 0; + padding: 1rem; + } + + #menu { + display: none; + opacity: 0; + max-height: 0; + background-color: var(--card-bg); + min-width: 100%; + } + + #menu.open { + display: block; + opacity: 1; + max-height: 35vh; + padding-inline: 1rem; + border-left: 2px solid var(--border); + margin-top: 0.3rem; + border-bottom-right-radius: 0.5rem; + border-top-right-radius: 0.5rem; + } + + .toc-container { + width: 100%; + } + + #menu-toggle.show { + display: flex; + gap: 0.5rem; + align-items: center; + opacity: 1; + } + + #menu-toggle.show.rotate::after { + transform: rotate(0deg); + } + + #menu > li > a, + #menu ul a { + padding: 0.5rem; + &:is(:hover,:active,:focus) { + background: var(--hover-bg); + } + } + + #menu li ul li > em { + font-size: 0.8rem; + padding-inline: 1rem; + padding-block: 0.3rem; + background-color: var(--hover-bg); + border-radius: 0.3rem; + } + + .toc-heading{ + display: none; + } +} + + +@media all and (max-width: 540px) { + #boxes { + grid-template-columns: 1fr; + } +} + +@media all and (max-width: 420px) { + #app-settings-property { + width: auto; + } +} + + +@media print { + + header { + position: absolute; + } +} + +/* For image callouts in writing-middleware.md */ + +.callout {position: relative;} + +#mw-fig { + border-collapse: separate; + padding: 0; + border: 0; + width: 960px; + margin-bottom: 20px; +} +#mw-fig-imgcell { + margin: 0; + padding: 0px; + border: 0; + width: 410px; +} +#mw-fig-img { + margin: 0px; + padding: 0px; + width: 410px; + height: 308px; +} + +.mw-fig-callouts { + margin: 0; + padding: 0 0 0 5px; + border: 0; + width: 550px; +} + +/* Blog page styles*/ +#blog-doc { + margin: 0 1rem; + @media all and (max-width: 800px) { + margin: 0; + } +} +#blog-doc:has(> h1#express-blog), +#blog-doc:has(> h1#write-a-blog-post) { + min-height: 300px; +} +#blog-doc .blog-details ~ p > img { + width: 200px; + float: right; + margin: 0.5rem; +} +#blog-doc p { + font-size: 1.1em; +} +.blog-posts { + display: flex; + flex-direction: column; + row-gap: 10px; +} +.blog-post { + width: 100%; + background-color: var(--card-bg); + display: flex; + padding: 10px; + flex-direction: column; + justify-content: space-between; + border-radius: 5px; + border: 1px solid var(--border); + box-shadow: 2px 3px var(--hover-fg); + transition: 0.3s; +} +.blog-post:hover { + background-color: var(--hover-bg); + border: 1px solid var(--hover-border); + box-shadow: 2px 3px var(--menu-grey); +} +.blog-post img { + max-width: 100%; + max-height: 100%; + object-fit: cover; +} +.blog-post .blog-details { + display: flex; + flex-direction: column; +} +.blog-details div:first-child { + margin-bottom: 5px; +} +.blog-tag { + font-size: 12px; +} +.blog-title { + font-size: 1.3rem; + line-height: 1.5rem; + font-weight: 500; + padding-right: .2em; +} +.blog-title a { + color: var(--card-fg) +} +.blog-excerpt { + font-size: .75rem; +} +.blog-img { + max-width: 100%; + margin: auto; +} +.blog-authors { + font-style: italic; +} +.blog-author-link { + color: inherit; + margin-left: 0.5ch; + text-decoration: none; +} +.blog-author-link-label { + text-decoration: underline; +} +.blog-author-avatar { + border-radius: 50%; + display: inline-block; + vertical-align: middle; + width: 1.5em; + height: 1.5em; +} +.blog-date { + font-weight: bold; + font-size: 85%; +} +/* mobile-only */ +@media (max-width: 500px) { + #blog-doc { + display: flex; + flex-wrap: wrap; + flex-direction: column; + align-items: center; + margin-right: 0; + padding-right: 10px; + } + #blog-doc .blog-details + p > img { + margin-bottom: 15px; + } +} + + + +/* blog tablet and up*/ +@media (min-width: 768px) { + .blog-post { + margin: auto; + } + .blog-tags { + margin-bottom: 20px; + } + .blog-title { + font-size: 1.3rem; + margin-bottom: 20px; + line-height: 1.5rem; + } + .blog-post .blog-details { + display: flex; + flex-direction: row; + margin-left: 1rem; + font-size: 90%; + } + .blog-post .blog-details div:first-child { + margin-right: 20px; + } + .blog-details { + font-size: 1rem; + } + .blog-excerpt { + line-height: initial; + font-size: .85rem; + font-weight: 300; + margin-top: auto; + margin-bottom: 10px; + max-width: 80%; + } +} + +strong.supported { + color: var(--supported-fg) ; +} +strong.eol { + color: var(--eol-fg) ; +} + +.logo-table { + display: flex; + flex-wrap: wrap; + row-gap: 8px; + column-gap: 48px; +} + +.logo-table h3{ + margin-bottom: 12px; +} + +blockquote { + margin-left: 0; + font-weight: 600; + font-style: italic; + padding-left: 1.2em; + border-left: .25rem solid var(--border); +} + +@media all and (max-width: 1110px) { + .algolia-autocomplete { + display: none !important; + } + + #mobile-menu { + display: block; + } + + #navbar { + padding: 0; + top: 1px; + position: static; + } + + #navmenu>li:first-child { + display: none; + } + + #navmenu>li { + border-bottom: 1px solid var(--border); + margin: 0; + min-height: 47px; + background: var(--card-bg); + cursor: pointer; + display: flex; + align-items: center; + } + + #navmenu>li.open:hover { + background: var(--card-bg); + } + #navmenu>li:hover { + background: var(--hover-bg); + & ul { + background-color: var(--card-bg); + } + } + + #navmenu { + left: 0; + padding: 0; + top: 57px; + width: 100%; + position: absolute; + display: none; + } + + #navmenu.opens { + display: block; + } + + #navbar a { + font-size: 19px; + margin: 0; + width: 100%; + height: 100%; + padding-left: 5%; + } + + #navbar .submenu.open { + flex-direction: column; + align-items: initial; + > a { + border-bottom: 1px solid var(--border); + } + } + + .submenu.open > a { + display: flex; + align-items: center; + min-height: 47px; + } + + .submenu-content { + width: 100%; + position: static; + display: none; + margin-top: 7px; + background-color: var(--card-bg); + padding: 0; + margin: 0; + border: none; + border-radius: 0; + box-shadow: none; + max-height: 190px; + overflow-y: auto; + overflow-x: hidden; + transform: none; + cursor: pointer; + } + + .submenu-content li > a { + width: 100%; + } + + .submenu-content li:first-child a { + border-radius: 0; + } + + .submenu-content li:last-child { + border-bottom: 0; + } + + .submenu-content li:last-child a { + border-radius: 0; + } + + .submenu-content.open { + display: inline-block; + } + + #navbar .submenu-content li a { + font-size: 16px; + padding: 5px 5px 5px 5%; + padding-left: 10%; + } + + .submenu-content li { + border-bottom: 1px solid var(--border); + } +} diff --git a/css/variables.css b/assets/css/variables.css similarity index 79% rename from css/variables.css rename to assets/css/variables.css index 5680810934..d4c402830d 100644 --- a/css/variables.css +++ b/assets/css/variables.css @@ -50,3 +50,25 @@ --supported-fg:#299009; --eol-fg: #ff1a1a; } + +html.dark-mode { + + #icon-sun { + display: inline; + } + + .submenu-content { + box-shadow: 1px 2px var(--hover-bg); + background-color: var(--card-bg); + } + + #navmenu>li:hover { + ul { + background-color: var(--card-bg); + } + } + + .blog-excerpt { + color: var(--notice-accent); + } +} \ No newline at end of file diff --git a/fonts/ko/pretendard.css b/assets/fonts/ko/pretendard.css similarity index 100% rename from fonts/ko/pretendard.css rename to assets/fonts/ko/pretendard.css diff --git a/fonts/ko/woff/Pretendard-Black.woff b/assets/fonts/ko/woff/Pretendard-Black.woff similarity index 100% rename from fonts/ko/woff/Pretendard-Black.woff rename to assets/fonts/ko/woff/Pretendard-Black.woff diff --git a/fonts/ko/woff/Pretendard-Bold.woff b/assets/fonts/ko/woff/Pretendard-Bold.woff similarity index 100% rename from fonts/ko/woff/Pretendard-Bold.woff rename to assets/fonts/ko/woff/Pretendard-Bold.woff diff --git a/fonts/ko/woff/Pretendard-ExtraBold.woff b/assets/fonts/ko/woff/Pretendard-ExtraBold.woff similarity index 100% rename from fonts/ko/woff/Pretendard-ExtraBold.woff rename to assets/fonts/ko/woff/Pretendard-ExtraBold.woff diff --git a/fonts/ko/woff/Pretendard-ExtraLight.woff b/assets/fonts/ko/woff/Pretendard-ExtraLight.woff similarity index 100% rename from fonts/ko/woff/Pretendard-ExtraLight.woff rename to assets/fonts/ko/woff/Pretendard-ExtraLight.woff diff --git a/fonts/ko/woff/Pretendard-Light.woff b/assets/fonts/ko/woff/Pretendard-Light.woff similarity index 100% rename from fonts/ko/woff/Pretendard-Light.woff rename to assets/fonts/ko/woff/Pretendard-Light.woff diff --git a/fonts/ko/woff/Pretendard-Medium.woff b/assets/fonts/ko/woff/Pretendard-Medium.woff similarity index 100% rename from fonts/ko/woff/Pretendard-Medium.woff rename to assets/fonts/ko/woff/Pretendard-Medium.woff diff --git a/fonts/ko/woff/Pretendard-Regular.woff b/assets/fonts/ko/woff/Pretendard-Regular.woff similarity index 100% rename from fonts/ko/woff/Pretendard-Regular.woff rename to assets/fonts/ko/woff/Pretendard-Regular.woff diff --git a/fonts/ko/woff/Pretendard-SemiBold.woff b/assets/fonts/ko/woff/Pretendard-SemiBold.woff similarity index 100% rename from fonts/ko/woff/Pretendard-SemiBold.woff rename to assets/fonts/ko/woff/Pretendard-SemiBold.woff diff --git a/fonts/ko/woff/Pretendard-Thin.woff b/assets/fonts/ko/woff/Pretendard-Thin.woff similarity index 100% rename from fonts/ko/woff/Pretendard-Thin.woff rename to assets/fonts/ko/woff/Pretendard-Thin.woff diff --git a/fonts/ko/woff2/Pretendard-Black.woff2 b/assets/fonts/ko/woff2/Pretendard-Black.woff2 similarity index 100% rename from fonts/ko/woff2/Pretendard-Black.woff2 rename to assets/fonts/ko/woff2/Pretendard-Black.woff2 diff --git a/fonts/ko/woff2/Pretendard-Bold.woff2 b/assets/fonts/ko/woff2/Pretendard-Bold.woff2 similarity index 100% rename from fonts/ko/woff2/Pretendard-Bold.woff2 rename to assets/fonts/ko/woff2/Pretendard-Bold.woff2 diff --git a/fonts/ko/woff2/Pretendard-ExtraBold.woff2 b/assets/fonts/ko/woff2/Pretendard-ExtraBold.woff2 similarity index 100% rename from fonts/ko/woff2/Pretendard-ExtraBold.woff2 rename to assets/fonts/ko/woff2/Pretendard-ExtraBold.woff2 diff --git a/fonts/ko/woff2/Pretendard-ExtraLight.woff2 b/assets/fonts/ko/woff2/Pretendard-ExtraLight.woff2 similarity index 100% rename from fonts/ko/woff2/Pretendard-ExtraLight.woff2 rename to assets/fonts/ko/woff2/Pretendard-ExtraLight.woff2 diff --git a/fonts/ko/woff2/Pretendard-Light.woff2 b/assets/fonts/ko/woff2/Pretendard-Light.woff2 similarity index 100% rename from fonts/ko/woff2/Pretendard-Light.woff2 rename to assets/fonts/ko/woff2/Pretendard-Light.woff2 diff --git a/fonts/ko/woff2/Pretendard-Medium.woff2 b/assets/fonts/ko/woff2/Pretendard-Medium.woff2 similarity index 100% rename from fonts/ko/woff2/Pretendard-Medium.woff2 rename to assets/fonts/ko/woff2/Pretendard-Medium.woff2 diff --git a/fonts/ko/woff2/Pretendard-Regular.woff2 b/assets/fonts/ko/woff2/Pretendard-Regular.woff2 similarity index 100% rename from fonts/ko/woff2/Pretendard-Regular.woff2 rename to assets/fonts/ko/woff2/Pretendard-Regular.woff2 diff --git a/fonts/ko/woff2/Pretendard-SemiBold.woff2 b/assets/fonts/ko/woff2/Pretendard-SemiBold.woff2 similarity index 100% rename from fonts/ko/woff2/Pretendard-SemiBold.woff2 rename to assets/fonts/ko/woff2/Pretendard-SemiBold.woff2 diff --git a/fonts/ko/woff2/Pretendard-Thin.woff2 b/assets/fonts/ko/woff2/Pretendard-Thin.woff2 similarity index 100% rename from fonts/ko/woff2/Pretendard-Thin.woff2 rename to assets/fonts/ko/woff2/Pretendard-Thin.woff2 diff --git a/fonts/open-sans/fonts.css b/assets/fonts/open-sans/fonts.css similarity index 100% rename from fonts/open-sans/fonts.css rename to assets/fonts/open-sans/fonts.css diff --git a/fonts/open-sans/woff/OpenSans-Italic.woff b/assets/fonts/open-sans/woff/OpenSans-Italic.woff similarity index 100% rename from fonts/open-sans/woff/OpenSans-Italic.woff rename to assets/fonts/open-sans/woff/OpenSans-Italic.woff diff --git a/fonts/open-sans/woff/OpenSans.woff b/assets/fonts/open-sans/woff/OpenSans.woff similarity index 100% rename from fonts/open-sans/woff/OpenSans.woff rename to assets/fonts/open-sans/woff/OpenSans.woff diff --git a/fonts/open-sans/woff2/open-sans-latin-wght-italic.woff2 b/assets/fonts/open-sans/woff2/open-sans-latin-wght-italic.woff2 similarity index 100% rename from fonts/open-sans/woff2/open-sans-latin-wght-italic.woff2 rename to assets/fonts/open-sans/woff2/open-sans-latin-wght-italic.woff2 diff --git a/fonts/open-sans/woff2/open-sans-latin-wght-normal.woff2 b/assets/fonts/open-sans/woff2/open-sans-latin-wght-normal.woff2 similarity index 100% rename from fonts/open-sans/woff2/open-sans-latin-wght-normal.woff2 rename to assets/fonts/open-sans/woff2/open-sans-latin-wght-normal.woff2 diff --git a/images/blogger.jpg b/assets/images/blogger.jpg similarity index 100% rename from images/blogger.jpg rename to assets/images/blogger.jpg diff --git a/images/brand/logo-dark.svg b/assets/images/brand/logo-dark.svg similarity index 100% rename from images/brand/logo-dark.svg rename to assets/images/brand/logo-dark.svg diff --git a/images/brand/logo-light.svg b/assets/images/brand/logo-light.svg similarity index 100% rename from images/brand/logo-light.svg rename to assets/images/brand/logo-light.svg diff --git a/images/brand/logotype-dark.svg b/assets/images/brand/logotype-dark.svg similarity index 100% rename from images/brand/logotype-dark.svg rename to assets/images/brand/logotype-dark.svg diff --git a/images/brand/logotype-light.svg b/assets/images/brand/logotype-light.svg similarity index 100% rename from images/brand/logotype-light.svg rename to assets/images/brand/logotype-light.svg diff --git a/images/clustering.png b/assets/images/clustering.png similarity index 100% rename from images/clustering.png rename to assets/images/clustering.png diff --git a/images/copy-btn.svg b/assets/images/copy-btn.svg similarity index 100% rename from images/copy-btn.svg rename to assets/images/copy-btn.svg diff --git a/images/express-mw.png b/assets/images/express-mw.png similarity index 100% rename from images/express-mw.png rename to assets/images/express-mw.png diff --git a/images/favicon.ico b/assets/images/favicon.ico old mode 100755 new mode 100644 similarity index 100% rename from images/favicon.ico rename to assets/images/favicon.ico diff --git a/images/favicon.png b/assets/images/favicon.png similarity index 100% rename from images/favicon.png rename to assets/images/favicon.png diff --git a/images/og.png b/assets/images/og.png similarity index 100% rename from images/og.png rename to assets/images/og.png diff --git a/assets/js/api.js b/assets/js/api.js new file mode 100644 index 0000000000..98a8dd5159 --- /dev/null +++ b/assets/js/api.js @@ -0,0 +1,92 @@ +// Note: Following code only used on api pages + +// highlight current Menu on scroll +const headings = Array.from(document.querySelectorAll("h2, h3")); +const menuLinks = document.querySelectorAll("#menu li a"); + +const observerOptions = { + root: null, + rootMargin: "-10% 0px -65% 0px", + threshold: 1, +}; + +const menuObserver = new IntersectionObserver((entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + const currentApiPrefix = entry.target.id.split(".")[0]; + const parentMenuSelector = `#${currentApiPrefix}-menu`; + const parentMenuEl = document.querySelector(parentMenuSelector); + + // open submenu on scroll + if (parentMenuEl) parentMenuEl.classList.add("active"); + + // Remove active class from last menu item + const lastActiveMenu = document.querySelector(".active[id$='-menu']"); + if (lastActiveMenu && lastActiveMenu.id !== parentMenuEl.id) { + lastActiveMenu.classList.remove("active"); + } + + // Update active link + menuLinks.forEach((link) => link.classList.remove("active")); + const activeLink = document.querySelector(`a[href="#${entry.target.id}"]`); + if (activeLink && !activeLink.classList.contains("active")) activeLink.classList.add("active"); + } + }); +}, observerOptions); + +headings.forEach((heading) => menuObserver.observe(heading)); + +// TOC +const toggleBtn = document.getElementById("menu-toggle"); +const tocList = document.getElementById("menu"); + +function updateTocVisibility() { + if (isTocScreen) { + toggleBtn?.classList.add("show"); + } else { + toggleBtn?.classList.remove("show"); + } +} + +// toc button on page load +updateTocVisibility(); + +// Listen for changes in screen size +tocScreen.addEventListener("change", (event) => { + isTocScreen = event.matches; + updateTocVisibility(); +}); + +// Toggle toc menu on button click +toggleBtn?.addEventListener("click", (e) => { + toggleBtn.classList.toggle("rotate"); + if (tocList?.classList.contains("open")) { + tocList.classList.remove("open"); + } else { + tocList.classList.add("open"); + } +}); + +// Open/Close sub TOC content on click +document.querySelectorAll("#menu > li > a").forEach((link) => { + link.addEventListener("click", function (event) { + event.preventDefault(); // stop navigation to submenu + + // Find the closest parent
  • + const closestLiParent = link.closest("li"); + const childUlSubMenu = closestLiParent.children[1]; + + // If submenu is already active, remove "active" class (toggle behavior) + if (childUlSubMenu?.classList.contains("active")) { + childUlSubMenu.classList.remove("active"); + } else { + // Remove "active" from all other submenus + document.querySelectorAll("#menu > li > ul").forEach((subMenu) => { + subMenu.classList.remove("active"); + }); + + // Add "active" to the clicked submenu + childUlSubMenu?.classList.add("active"); + } + }); +}); diff --git a/js/app.js b/assets/js/app.js similarity index 59% rename from js/app.js rename to assets/js/app.js index b8888e0642..9df3b25537 100644 --- a/js/app.js +++ b/assets/js/app.js @@ -19,42 +19,6 @@ const scrollObserver = new IntersectionObserver( if (scrollTarget) scrollObserver.observe(scrollTarget); -// heighlight current Menu on scroll -const headings = Array.from(document.querySelectorAll("h2, h3")); -const menuLinks = document.querySelectorAll("#menu li a"); - -const observerOptions = { - root: null, - rootMargin: "-10% 0px -65% 0px", - threshold: 1, -}; - -const menuObserver = new IntersectionObserver((entries) => { - entries.forEach((entry) => { - if (entry.isIntersecting) { - const currentApiPrefix = entry.target.id.split(".")[0]; - const parentMenuSelector = `#${currentApiPrefix}-menu`; - const parentMenuEl = document.querySelector(parentMenuSelector); - - // open submenu on scroll - if (parentMenuEl) parentMenuEl.classList.add("active"); - - // Remove active class from last menu item - const lastActiveMenu = document.querySelector(".active[id$='-menu']"); - if (lastActiveMenu && lastActiveMenu.id !== parentMenuEl.id) { - lastActiveMenu.classList.remove("active"); - } - - // Update active link - menuLinks.forEach((link) => link.classList.remove("active")); - const activeLink = document.querySelector(`a[href="#${entry.target.id}"]`); - if (activeLink && !activeLink.classList.contains("active")) activeLink.classList.add("active"); - } - }); -}, observerOptions); - -headings.forEach((heading) => menuObserver.observe(heading)); - // i18n message box : this box appears hidden for all page.lang != 'en' const isI18nCookie = readCookie('i18nClose'); if (i18nMsgBox && !isI18nCookie) { diff --git a/js/copycode.js b/assets/js/copycode.js similarity index 96% rename from js/copycode.js rename to assets/js/copycode.js index 2174710746..2f68f67763 100644 --- a/js/copycode.js +++ b/assets/js/copycode.js @@ -1,59 +1,59 @@ -const codeBlocks = document.querySelectorAll("pre:has(code)"); - -codeBlocks.forEach((block) => { - // Only add button if browser supports Clipboard API - if (!navigator.clipboard) return; - - const button = createCopyButton(); - block.appendChild(button); - block.setAttribute("tabindex", 0); // Add keyboard a11y for
    
    -
    -  button.addEventListener("click", async () => {
    -    await copyCode(block, button);
    -  });
    -});
    -
    -function createCopyButton() {
    -  const button = document.createElement("button");
    -  setButtonAttributes(button, {
    -    type: "button", // button doesn't act as a submit button
    -    title: "copy code",
    -    "aria-label": "click to copy code",
    -  });
    -  return button;
    -}
    -
    -function setButtonAttributes(button, attributes) {
    -  for (const [key, value] of Object.entries(attributes)) {
    -    button.setAttribute(key, value);
    -  }
    -}
    -
    -async function copyCode(block, button) {
    -  const code = block.querySelector("code");
    -  let text = code.innerText;
    -  // remove "$" and space if exists at the beginning of the code
    -  text = text.replace(/^\$\s?/,"");
    -
    -  try {
    -    await navigator.clipboard.writeText(text);
    -    updateButtonState(button, "copied", "code is copied!");
    -  } catch {
    -    updateButtonState(button, "failed", "failed!");
    -  }
    -}
    -
    -function updateButtonState(button, statusClass, ariaLabel) {
    -  button.setAttribute("aria-live", "polite");
    -  button.setAttribute("aria-label", ariaLabel);
    -  button.classList.add(statusClass);
    -
    -  // Clear any existing timer
    -  if (button.dataset.timerId) clearTimeout(Number(button.dataset.timerId));
    -  const timer = setTimeout(() => {
    -    button.classList.remove(statusClass);
    -    button.setAttribute("aria-label", "click to copy code");
    -  }, 1000);
    -
    -  button.dataset.timerId = timer;
    -}
    +const codeBlocks = document.querySelectorAll("pre:has(code)");
    +
    +codeBlocks.forEach((block) => {
    +  // Only add button if browser supports Clipboard API
    +  if (!navigator.clipboard) return;
    +
    +  const button = createCopyButton();
    +  block.appendChild(button);
    +  block.setAttribute("tabindex", 0); // Add keyboard a11y for 
    
    +
    +  button.addEventListener("click", async () => {
    +    await copyCode(block, button);
    +  });
    +});
    +
    +function createCopyButton() {
    +  const button = document.createElement("button");
    +  setButtonAttributes(button, {
    +    type: "button", // button doesn't act as a submit button
    +    title: "copy code",
    +    "aria-label": "click to copy code",
    +  });
    +  return button;
    +}
    +
    +function setButtonAttributes(button, attributes) {
    +  for (const [key, value] of Object.entries(attributes)) {
    +    button.setAttribute(key, value);
    +  }
    +}
    +
    +async function copyCode(block, button) {
    +  const code = block.querySelector("code");
    +  let text = code.innerText;
    +  // remove "$" and space if exists at the beginning of the code
    +  text = text.replace(/^\$\s?/,"");
    +
    +  try {
    +    await navigator.clipboard.writeText(text);
    +    updateButtonState(button, "copied", "code is copied!");
    +  } catch {
    +    updateButtonState(button, "failed", "failed!");
    +  }
    +}
    +
    +function updateButtonState(button, statusClass, ariaLabel) {
    +  button.setAttribute("aria-live", "polite");
    +  button.setAttribute("aria-label", ariaLabel);
    +  button.classList.add(statusClass);
    +
    +  // Clear any existing timer
    +  if (button.dataset.timerId) clearTimeout(Number(button.dataset.timerId));
    +  const timer = setTimeout(() => {
    +    button.classList.remove(statusClass);
    +    button.setAttribute("aria-label", "click to copy code");
    +  }, 1000);
    +
    +  button.dataset.timerId = timer;
    +}
    diff --git a/js/menu.js b/assets/js/menu.js
    similarity index 72%
    rename from js/menu.js
    rename to assets/js/menu.js
    index 5ee91a6016..5ebaeb641f 100644
    --- a/js/menu.js
    +++ b/assets/js/menu.js
    @@ -64,7 +64,6 @@ for (const el of itemsMenu) {
     	});
     }
     
    -// Mobile Menu and Language Picker
     const langBtn = document.getElementById("langBtn");
     const langList = document.getElementById("langList");
     const linkItemsMenu = document.querySelectorAll(".submenu > a");
    @@ -138,58 +137,3 @@ function removeActiveFromDrawers(navDrawers) {
     function addActiveToDrawer(drawer) {
     	drawer.querySelector('a').classList.add('active')
     }
    -
    -// TOC 
    -const toggleBtn = document.getElementById("menu-toggle");
    -const tocList = document.getElementById("menu");
    -
    -function updateTocVisibility() {
    -	if (isTocScreen) {
    -	  toggleBtn?.classList.add("show");
    -	} else {
    -	  toggleBtn?.classList.remove("show");
    -	}
    -  }
    -
    -// toc button on page load
    -updateTocVisibility();
    -
    -// Listen for changes in screen size
    -tocScreen.addEventListener("change", (event) => {
    -  isTocScreen = event.matches;
    -  updateTocVisibility();
    -});
    -
    -// Toggle toc menu on button click
    -toggleBtn?.addEventListener("click", (e) => {
    -	toggleBtn.classList.toggle("rotate");
    -  if(tocList?.classList.contains("open")) {
    -	tocList.classList.remove("open");
    -  } else {
    -	tocList.classList.add("open");
    -  }
    -});
    -  
    -// Open/Close sub TOC content on click
    -document.querySelectorAll("#menu > li > a").forEach((link) => {
    -	link.addEventListener("click", function (event) {
    -      event.preventDefault(); // stop navigation to submenu
    -
    -	  // Find the closest parent 
  • - const closestLiParent = link.closest("li"); - const childUlSubMenu = closestLiParent.children[1]; - - // If submenu is already active, remove "active" class (toggle behavior) - if (childUlSubMenu?.classList.contains("active")) { - childUlSubMenu.classList.remove("active"); - } else { - // Remove "active" from all other submenus - document.querySelectorAll("#menu > li > ul").forEach((subMenu) => { - subMenu.classList.remove("active"); - }); - - // Add "active" to the clicked submenu - childUlSubMenu?.classList.add("active"); - } - }); - }); diff --git a/js/theme.js b/assets/js/theme.js similarity index 100% rename from js/theme.js rename to assets/js/theme.js diff --git a/css/search.css b/css/search.css deleted file mode 100644 index cb60915c73..0000000000 --- a/css/search.css +++ /dev/null @@ -1,22 +0,0 @@ -#q { - display: none; - height: 2.5em; - min-width: 100%; - padding: 5px; -} - -.algolia-autocomplete { - min-width: 12em; - max-width: 12em; - top: -0.2em; -} - -.algolia-autocomplete #q { - display: initial -} - -@media all and (max-width: 899px) { - .algolia-autocomplete { - display: none !important; - } -} diff --git a/css/themes/dark-theme.css b/css/themes/dark-theme.css deleted file mode 100644 index 0c6a563696..0000000000 --- a/css/themes/dark-theme.css +++ /dev/null @@ -1,21 +0,0 @@ -html.dark-mode { - - #icon-sun { - display: inline; - } - - .submenu-content { - box-shadow: 1px 2px var(--hover-bg); - background-color: var(--card-bg); - } - - #navmenu>li:hover { - ul { - background-color: var(--card-bg); - } - } - - .blog-excerpt { - color: var(--notice-accent); - } -} \ No newline at end of file diff --git a/en/advanced/best-practice-performance.md b/en/advanced/best-practice-performance.md index d23e8ee392..4c0c4d6ba5 100644 --- a/en/advanced/best-practice-performance.md +++ b/en/advanced/best-practice-performance.md @@ -250,7 +250,7 @@ For more information on systemd, see the [systemd reference (man page)](http://w In a multi-core system, you can increase the performance of a Node app by many times by launching a cluster of processes. A cluster runs multiple instances of the app, ideally one instance on each CPU core, thereby distributing the load and tasks among the instances. -![Balancing between application instances using the cluster API](/images/clustering.png) +![Balancing between application instances using the cluster API](/assets/images/clustering.png) IMPORTANT: Since the app instances run as separate processes, they do not share the same memory space. That is, objects are local to each instance of the app. Therefore, you cannot maintain state in the application code. However, you can use an in-memory datastore like [Redis](http://redis.io/) to store session-related data and state. This caveat applies to essentially all forms of horizontal scaling, whether clustering with multiple processes or multiple physical servers. diff --git a/en/blog/write-post.md b/en/blog/write-post.md index 21cfc5b4b3..9607180ba7 100644 --- a/en/blog/write-post.md +++ b/en/blog/write-post.md @@ -6,7 +6,7 @@ menu: blog redirect_from: "/blog/write.html" --- -![Blogger]({{site.url}}/images/blogger.jpg) +![Blogger](/assets/images/blogger.jpg) If you have an idea for a blog post, follow these steps to propose it and potentially get it published! diff --git a/en/guide/writing-middleware.md b/en/guide/writing-middleware.md index 0b02f20312..7c7c2b414b 100755 --- a/en/guide/writing-middleware.md +++ b/en/guide/writing-middleware.md @@ -26,7 +26,7 @@ The following figure shows the elements of a middleware function call:
    -Elements of a middleware function call +Elements of a middleware function call
    HTTP method for which the middleware function applies.