diff --git a/frontend/css/styles.css b/frontend/css/styles.css index 9dea1b1..e02c30c 100644 --- a/frontend/css/styles.css +++ b/frontend/css/styles.css @@ -39,6 +39,8 @@ --text-xl: 1.25rem; --text-2xl: 1.5rem; --text-3xl: 1.875rem; + /* W3C Accessibility*/ + --min-interactive-element-size: 44px; } * { @@ -62,7 +64,7 @@ main { max-width: 80rem; margin: 0 auto; width: 100%; - padding: 1.5rem; + padding: 1rem; } ::selection { @@ -99,6 +101,7 @@ main { opacity: 0; transform: translateY(4px); } + to { opacity: 1; transform: translateY(0); @@ -109,6 +112,7 @@ main { from { transform: rotate(0deg); } + to { transform: rotate(360deg); } @@ -119,6 +123,7 @@ main { transform: translateX(100%); opacity: 0; } + to { transform: translateX(0); opacity: 1; @@ -148,9 +153,7 @@ main { /* ============================================ NAVBAR ============================================ */ - .navbar { - height: 56px; border-bottom: 1px solid var(--color-border); background-color: rgba(9, 9, 11, 0.8); backdrop-filter: blur(12px); @@ -159,7 +162,7 @@ main { z-index: 50; display: flex; align-items: center; - padding: 0 1.5rem; + padding: 1rem; justify-content: space-between; } @@ -176,6 +179,8 @@ main { text-decoration: none; color: var(--color-text); font-weight: 500; + min-width: max-content; + min-height: var(--min-interactive-element-size); } .navbar__brand:hover { @@ -194,11 +199,12 @@ main { } .navbar__brand-name { + font-size: var(--text-lg); color: var(--color-subtle); } .navbar__breadcrumb { - display: flex; + display: none; align-items: center; gap: 0.5rem; } @@ -214,6 +220,7 @@ main { } .navbar__breadcrumb-separator { + display: none; color: var(--color-border); } @@ -225,15 +232,28 @@ main { .navbar__search { display: flex; align-items: center; - gap: 0.5rem; - padding: 0.25rem 0.5rem; - border-radius: 4px; + gap: 0.75rem; + padding: 0.5rem 0.75rem; + border-radius: 8px; border: 1px solid var(--color-border); background-color: var(--color-surface); color: var(--color-subtle); - font-size: var(--text-xs); + font-size: var(--text-sm); cursor: pointer; - transition: border-color 0.2s; + min-height: var(--min-interactive-element-size); + min-width: var(--min-interactive-element-size); + place-content: center; +} + +.navbar__search span { + display: none; + flex: 1; + text-align: left; +} + +.navbar__search svg { + color: var(--color-text-muted); + flex-shrink: 0; } .navbar__search:hover { @@ -244,20 +264,19 @@ main { height: 24px; width: 1px; background-color: var(--color-border); - margin: 0 4px; } .navbar__action { background: none; border: none; color: var(--color-subtle); - font-size: var(--text-xs); + font-size: var(--text-sm); font-weight: 500; cursor: pointer; transition: color 0.2s; text-decoration: none; - display: flex; - align-items: center; + min-width: var(--min-interactive-element-size); + min-height: var(--min-interactive-element-size); gap: 0.25rem; } @@ -330,7 +349,7 @@ main { } .btn--destructive { - background-color: #dc2626; + background-color: var(--color-danger); color: white; } @@ -1073,7 +1092,7 @@ main { ============================================ */ .kbd { - display: inline-flex; + display: none; align-items: center; justify-content: center; padding: 0.125rem 0.375rem; @@ -1086,8 +1105,9 @@ main { } .kbd--sm { + gap: 0.125rem; padding: 0.0625rem 0.25rem; - font-size: var(--text-2xs); + font-size: var(--text-sm); } /* ============================================ @@ -1177,8 +1197,7 @@ main { .pagination { padding: 0.75rem 1rem; - display: flex; - flex-direction: row; + display: grid; justify-content: space-between; align-items: center; gap: 1rem; @@ -1279,7 +1298,7 @@ main { .layout-with-sidebar { display: grid; - grid-template-columns: 1fr 320px; + grid-template-columns: 1fr; gap: 24px; align-items: start; } @@ -1293,8 +1312,8 @@ main { ============================================ */ .docs-sidebar { - position: sticky; - top: 80px; + position: static; + max-height: none; background: var(--color-surface-30); border: 1px solid var(--color-border); border-radius: 8px; @@ -1467,7 +1486,7 @@ main { } .create-function-actions { - display: flex; + display: grid; gap: 0.5rem; margin-top: 2rem; } @@ -1478,7 +1497,6 @@ main { .template-cards { display: grid; - grid-template-columns: repeat(3, 1fr); gap: 1rem; } @@ -1594,19 +1612,24 @@ pre { .lua-kw { color: #c678dd; } + .lua-func { color: #61afef; } + .lua-str { color: #98c379; } + .lua-num { color: #d19a66; } + .lua-comment { color: #5c6370; font-style: italic; } + .lua-field { color: #e06c75; } @@ -1819,7 +1842,8 @@ pre { .card-maximized-overlay { position: fixed; - top: 56px; /* Account for navbar height */ + top: 56px; + /* Account for navbar height */ left: 0; right: 0; bottom: 0; @@ -1836,7 +1860,8 @@ pre { width: 100%; height: 100%; max-width: calc(100vw - 48px); - max-height: calc(100vh - 56px - 48px); /* Account for navbar */ + max-height: calc(100vh - 56px - 48px); + /* Account for navbar */ background: var(--color-surface); border: 1px solid var(--color-border); border-radius: 12px; @@ -1889,7 +1914,7 @@ pre { background: #0d1117; } -.card-maximized__content > * { +.card-maximized__content>* { flex: 1; min-height: 0; } @@ -1898,7 +1923,7 @@ pre { height: 100% !important; } -.card-maximized__content .code-editor-container > div { +.card-maximized__content .code-editor-container>div { height: 100% !important; } @@ -2713,7 +2738,7 @@ pre { } .code-viewer--no-border, -.card .card__content > .code-viewer { +.card .card__content>.code-viewer { border: none; border-radius: 0; } @@ -2836,7 +2861,7 @@ pre { margin-bottom: 2rem; } -.preview-section > h3 { +.preview-section>h3 { font-size: var(--text-sm); font-weight: 600; color: var(--color-text-muted); @@ -2875,28 +2900,6 @@ pre { border-radius: 4px; } -/* ============================================ - RESPONSIVE - ============================================ */ - -@media (max-width: 768px) { - .layout-with-sidebar { - grid-template-columns: 1fr; - } - - .docs-sidebar { - position: static; - max-height: none; - } - - .navbar { - padding: 0 1rem; - } - - main { - padding: 1rem; - } -} /* ============================================ COMMAND PALETTE @@ -3109,7 +3112,7 @@ pre { background: var(--color-background); } -.ai-request-viewer__expanded-row > td { +.ai-request-viewer__expanded-row>td { padding: 0; border-top: none; } @@ -3153,9 +3156,9 @@ pre { grid-template-columns: 1fr; } -@media (max-width: 768px) { +@media (min-width: 768px) { .ai-request-viewer__panels { - grid-template-columns: 1fr; + grid-template-columns: 1fr 1fr; } } @@ -3210,7 +3213,7 @@ pre { background: var(--color-background); } -.email-request-viewer__expanded-row > td { +.email-request-viewer__expanded-row>td { padding: 0; border-top: none; } @@ -3257,9 +3260,9 @@ pre { grid-template-columns: 1fr; } -@media (max-width: 768px) { +@media (min-width: 768px) { .email-request-viewer__panels { - grid-template-columns: 1fr; + grid-template-columns: 1fr 1fr; } } @@ -3274,15 +3277,19 @@ pre { .language-selector__toggle { display: flex; align-items: center; + justify-content: center; gap: 0.375rem; - padding: 0.25rem 0.5rem; background: transparent; border: 1px solid transparent; border-radius: 4px; + padding: 0 0.5rem; color: var(--color-subtle); - font-size: var(--text-xs); + font-size: var(--text-sm); cursor: pointer; transition: all 0.2s; + border-radius: 8px; + min-height: var(--min-interactive-element-size); + min-width: var(--min-interactive-element-size); } .language-selector__toggle:hover { @@ -3305,11 +3312,12 @@ pre { } .language-selector__label { + display: none; font-weight: 500; } .language-selector__chevron { - display: flex; + display: none; align-items: center; justify-content: center; width: 0.75rem; @@ -3438,3 +3446,59 @@ pre { border-color: var(--color-accent); box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2); } + +@media (min-width: 768px) { + .layout-with-sidebar { + grid-template-columns: 1fr 320px; + } + + .docs-sidebar { + position: sticky; + top: 80px; + max-height: calc(100vh - 120px); + overflow-y: auto; + } + + .navbar { + padding: 1rem 1.5rem; + } + + .navbar__search { + min-width: 240px; + place-content: unset; + } + + .navbar__search span { + display: flex; + } + + .navbar__search .kbd { + display: flex; + } + + .language-selector__label, + .language-selector__chevron { + display: flex; + } + + main { + padding: 1.5rem; + } + + .pagination { + display: flex; + } + + .navbar__breadcrumb-separator, + .navbar__breadcrumb { + display: flex; + } + + .template-cards { + grid-template-columns: repeat(3, 1fr); + } + + .create-function-actions { + display: flex; + } +} \ No newline at end of file diff --git a/frontend/js/components/navbar.js b/frontend/js/components/navbar.js index 7419111..6f9efcc 100644 --- a/frontend/js/components/navbar.js +++ b/frontend/js/components/navbar.js @@ -183,7 +183,11 @@ export const NavbarSearch = { class: className, onclick, }, - [m("span", placeholder), shortcut && m(Kbd, { small: true }, shortcut)], + [ + m.trust(icons.magnifyingGlass()), + m("span", placeholder), + shortcut && m(Kbd, { small: true }, shortcut), + ], ); }, }; @@ -272,19 +276,18 @@ export const Header = { const { breadcrumb, onLogout, onSearch } = vnode.attrs; return m(Navbar, [ - m(NavbarSection, [ - m(NavbarBrand, { name: t("nav.dashboard"), href: "#!/" }), - breadcrumb && - m( - "span.navbar__breadcrumb-separator", - { "aria-hidden": "true" }, - "/", - ), - breadcrumb && - m(NavbarBreadcrumb, { - items: [{ label: breadcrumb, active: true }], - }), - ]), + m(NavbarBrand, { name: t("nav.dashboard"), href: "#!/" }), + breadcrumb && + m( + "span.navbar__breadcrumb-separator", + { "aria-hidden": "true" }, + "/", + ), + breadcrumb && + m(NavbarBreadcrumb, { + items: [{ label: breadcrumb, active: true }], + }), + m(NavbarSection, [ m(NavbarSearch, { placeholder: t("nav.search"), diff --git a/frontend/js/icons.js b/frontend/js/icons.js index 513aba6..d78254f 100644 --- a/frontend/js/icons.js +++ b/frontend/js/icons.js @@ -206,6 +206,10 @@ export const icons = { /** Route/map-pin icon - for routing */ route: () => ``, + + /** Bars/burger icon - for mobile menu */ + bars3: () => + ``, }; /** diff --git a/frontend/js/views/function-create.js b/frontend/js/views/function-create.js index 3ee5342..47ab4ea 100644 --- a/frontend/js/views/function-create.js +++ b/frontend/js/views/function-create.js @@ -190,18 +190,18 @@ export const FunctionCreate = { m( Button, { - variant: ButtonVariant.GHOST, - href: "#!/functions", + variant: ButtonVariant.PRIMARY, + onclick: FunctionCreate.createFunction, }, - t("common.cancel"), + t("create.createButton"), ), m( Button, { - variant: ButtonVariant.PRIMARY, - onclick: FunctionCreate.createFunction, + variant: ButtonVariant.GHOST, + href: "#!/functions", }, - t("create.createButton"), + t("common.cancel"), ), ]), ]),