summaryrefslogtreecommitdiffhomepage
path: root/cloud/web/src/ui/style
diff options
context:
space:
mode:
authorFrank <[email protected]>2025-08-08 13:22:54 -0400
committerFrank <[email protected]>2025-08-08 13:24:32 -0400
commit183e0911b76025a1f2a82e979d9834fec2131d0e (patch)
tree9987c1753bd64d1ce1d174ab397f1a8c681f642c /cloud/web/src/ui/style
parentc7bb19ad0712469063eab35589aa5d3602b0c5b1 (diff)
downloadopencode-183e0911b76025a1f2a82e979d9834fec2131d0e.tar.gz
opencode-183e0911b76025a1f2a82e979d9834fec2131d0e.zip
wip: gateway
Diffstat (limited to 'cloud/web/src/ui/style')
-rw-r--r--cloud/web/src/ui/style/component/button.css78
-rw-r--r--cloud/web/src/ui/style/component/dialog.css84
-rw-r--r--cloud/web/src/ui/style/component/input.css34
-rw-r--r--cloud/web/src/ui/style/component/label.css17
-rw-r--r--cloud/web/src/ui/style/component/title-bar.css32
-rw-r--r--cloud/web/src/ui/style/index.css50
-rw-r--r--cloud/web/src/ui/style/token/animation.css23
-rw-r--r--cloud/web/src/ui/style/token/color.css88
-rw-r--r--cloud/web/src/ui/style/token/font.css20
-rw-r--r--cloud/web/src/ui/style/token/reset.css212
-rw-r--r--cloud/web/src/ui/style/token/space.css38
11 files changed, 676 insertions, 0 deletions
diff --git a/cloud/web/src/ui/style/component/button.css b/cloud/web/src/ui/style/component/button.css
new file mode 100644
index 000000000..9604f9865
--- /dev/null
+++ b/cloud/web/src/ui/style/component/button.css
@@ -0,0 +1,78 @@
+[data-component="button"] {
+ width: fit-content;
+ display: flex;
+ line-height: 1;
+ align-items: center;
+ justify-content: center;
+ gap: var(--space-2);
+ font-size: var(--font-size-md);
+ text-transform: uppercase;
+ height: var(--space-11);
+ outline: none;
+ font-weight: 500;
+ padding: 0 var(--space-4);
+ border-width: 2px;
+ border-color: var(--color-border);
+ cursor: pointer;
+
+ &:disabled {
+ opacity: 0.5;
+ cursor: default;
+ }
+
+ &[data-color="primary"] {
+ background-color: var(--color-text);
+ border-color: var(--color-text);
+ color: var(--color-text-invert);
+
+ &:active {
+ border-color: var(--color-accent);
+ }
+ }
+
+ &[data-color="secondary"] {
+ &:active {
+ border-color: var(--color-accent);
+ }
+ }
+
+ &[data-color="ghost"] {
+ border: none;
+ text-decoration: underline;
+
+ &:active {
+ color: var(--color-text-accent);
+ }
+ }
+
+ &:has([data-slot="icon"]) {
+ padding-left: var(--space-3);
+ padding-right: var(--space-3);
+ }
+
+ &[data-size="sm"] {
+ height: var(--space-8);
+ padding: var(--space-3);
+ font-size: var(--font-size-xs);
+
+ [data-slot="icon"] {
+ width: var(--space-3-5);
+ height: var(--space-3-5);
+ }
+
+ &:has([data-slot="icon"]) {
+ padding-left: var(--space-2);
+ padding-right: var(--space-2);
+ }
+ }
+
+ [data-slot="icon"] {
+ width: var(--space-4);
+ height: var(--space-4);
+ transition: transform 0.2s ease;
+ }
+
+ &[data-rotate] [data-slot="icon"] {
+ transform: rotate(180deg);
+ }
+}
diff --git a/cloud/web/src/ui/style/component/dialog.css b/cloud/web/src/ui/style/component/dialog.css
new file mode 100644
index 000000000..59867818f
--- /dev/null
+++ b/cloud/web/src/ui/style/component/dialog.css
@@ -0,0 +1,84 @@
+[data-component="dialog-overlay"] {
+ pointer-events: none !important;
+ position: fixed;
+ inset: 0;
+ animation-name: fadeOut;
+ animation-duration: 200ms;
+ animation-timing-function: ease;
+ opacity: 0;
+ backdrop-filter: blur(2px);
+
+ &[data-expanded] {
+ animation-name: fadeIn;
+ opacity: 1;
+ pointer-events: auto !important;
+ }
+}
+
+[data-component="dialog-center"] {
+ position: fixed;
+ inset: 0;
+ padding-top: 10vh;
+ justify-content: center;
+ pointer-events: none;
+
+ [data-slot="content"] {
+ width: 45rem;
+ margin: 0 auto;
+ transition: 150ms width;
+ background-color: var(--color-bg);
+ border-width: 2px;
+ border-color: var(--color-border);
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-3);
+ outline: none;
+ animation-duration: 1ms;
+ animation-name: zoomOut;
+ animation-timing-function: ease;
+
+ box-shadow: 8px 8px 0px 0px var(--color-gray-4);
+
+ &[data-expanded] {
+ animation-name: zoomIn;
+ }
+
+ &[data-transition] {
+ animation-duration: 200ms;
+ }
+
+ &[data-size="sm"] {
+ width: 30rem;
+ }
+
+ [data-slot="header"] {
+ display: flex;
+ padding: var(--space-4) var(--space-4) 0;
+
+ [data-slot="title"] {
+ }
+ }
+
+ [data-slot="main"] {
+ padding: 0 var(--space-4);
+
+ &:has([data-slot="options"]) {
+ padding: 0;
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-4);
+ }
+ }
+
+ [data-slot="input"] {
+ }
+
+ [data-slot="footer"] {
+ padding: var(--space-4);
+ display: flex;
+ gap: var(--space-4);
+ justify-content: end;
+ }
+ }
+}
diff --git a/cloud/web/src/ui/style/component/input.css b/cloud/web/src/ui/style/component/input.css
new file mode 100644
index 000000000..59535d763
--- /dev/null
+++ b/cloud/web/src/ui/style/component/input.css
@@ -0,0 +1,34 @@
+[data-component="input"] {
+ font-size: var(--font-size-md);
+ background: transparent;
+ caret-color: var(--color-accent);
+ font-family: var(--font-mono);
+ height: var(--space-11);
+ padding: 0 var(--space-4);
+ width: 100%;
+ resize: none;
+ border: 2px solid var(--color-border);
+
+ &::placeholder {
+ color: var(--color-text-dimmed);
+ opacity: 0.75;
+ }
+
+ &:focus {
+ outline: 0;
+ }
+
+ &[data-size="sm"] {
+ height: var(--space-9);
+ padding: 0 var(--space-3);
+ font-size: var(--font-size-xs);
+ }
+
+ &[data-size="md"] {
+ }
+
+ &[data-size="lg"] {
+ height: var(--space-12);
+ font-size: var(--font-size-lg);
+ }
+}
diff --git a/cloud/web/src/ui/style/component/label.css b/cloud/web/src/ui/style/component/label.css
new file mode 100644
index 000000000..e0dd5fef4
--- /dev/null
+++ b/cloud/web/src/ui/style/component/label.css
@@ -0,0 +1,17 @@
+[data-component="label"] {
+ letter-spacing: -0.03125rem;
+ text-transform: uppercase;
+ color: var(--color-text-dimmed);
+ font-weight: 500;
+ font-size: var(--font-size-md);
+
+ &[data-size="sm"] {
+ font-size: var(--font-size-sm);
+ }
+ &[data-size="md"] {
+ }
+ &[data-size="lg"] {
+ font-size: var(--font-size-lg);
+ }
+}
+
diff --git a/cloud/web/src/ui/style/component/title-bar.css b/cloud/web/src/ui/style/component/title-bar.css
new file mode 100644
index 000000000..7ee32bfdc
--- /dev/null
+++ b/cloud/web/src/ui/style/component/title-bar.css
@@ -0,0 +1,32 @@
+[data-component="title-bar"] {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ height: 72px;
+ padding: 0 var(--space-4);
+ border-bottom: 2px solid var(--color-border);
+
+ [data-slot="left"] {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-1-5);
+
+ h1 {
+ letter-spacing: -0.03125rem;
+ font-size: var(--font-size-xl);
+ text-transform: uppercase;
+ font-weight: 600;
+ }
+
+ p {
+ color: var(--color-text-dimmed);
+ }
+ }
+
+}
+
+@media (max-width: 40rem) {
+ [data-component="title-bar"] {
+ display: none;
+ }
+}
diff --git a/cloud/web/src/ui/style/index.css b/cloud/web/src/ui/style/index.css
new file mode 100644
index 000000000..117f596d0
--- /dev/null
+++ b/cloud/web/src/ui/style/index.css
@@ -0,0 +1,50 @@
+/* tokens */
+@import "./token/color.css";
+@import "./token/reset.css";
+@import "./token/animation.css";
+@import "./token/font.css";
+@import "./token/space.css";
+
+/* components */
+@import "./component/label.css";
+@import "./component/input.css";
+@import "./component/button.css";
+@import "./component/dialog.css";
+@import "./component/title-bar.css";
+
+body {
+ font-family: var(--font-mono);
+ line-height: 1;
+ color: var(--color-text);
+ background-color: var(--color-bg);
+ cursor: default;
+ user-select: none;
+ text-underline-offset: 0.1875rem;
+}
+
+a {
+ text-decoration: underline;
+ &:active {
+ color: var(--color-text-accent);
+ }
+}
+
+::selection {
+ background-color: var(--color-text-accent-invert);
+}
+
+/* Responsive utilities */
+[data-max-width] {
+ width: 100%;
+
+ & > * {
+ max-width: 90rem;
+ margin-left: auto;
+ margin-right: auto;
+ width: 100%;
+ }
+
+ &[data-max-width-64] > * {
+ max-width: 64rem;
+ }
+}
diff --git a/cloud/web/src/ui/style/token/animation.css b/cloud/web/src/ui/style/token/animation.css
new file mode 100644
index 000000000..a8edfeff5
--- /dev/null
+++ b/cloud/web/src/ui/style/token/animation.css
@@ -0,0 +1,23 @@
+@keyframes zoomIn {
+ from {
+ opacity: 0;
+ transform: scale(0.95);
+ }
+
+ to {
+ opacity: 1;
+ transform: scale(1);
+ }
+}
+
+@keyframes zoomOut {
+ from {
+ opacity: 1;
+ transform: scale(1);
+ }
+
+ to {
+ opacity: 0;
+ transform: scale(0.95);
+ }
+}
diff --git a/cloud/web/src/ui/style/token/color.css b/cloud/web/src/ui/style/token/color.css
new file mode 100644
index 000000000..af0c46f3b
--- /dev/null
+++ b/cloud/web/src/ui/style/token/color.css
@@ -0,0 +1,88 @@
+:root {
+ --color-white: hsl(0, 0%, 100%);
+ --color-gray-1: hsl(224, 20%, 94%);
+ --color-gray-2: hsl(224, 6%, 77%);
+ --color-gray-3: hsl(224, 6%, 56%);
+ --color-gray-4: hsl(224, 7%, 36%);
+ --color-gray-5: hsl(224, 10%, 23%);
+ --color-gray-6: hsl(224, 14%, 16%);
+ --color-black: hsl(224, 10%, 10%);
+
+ --hue-orange: 41;
+ --color-orange-low: hsl(var(--hue-orange), 39%, 22%);
+ --color-orange: hsl(var(--hue-orange), 82%, 63%);
+ --color-orange-high: hsl(var(--hue-orange), 82%, 87%);
+ --hue-green: 101;
+ --color-green-low: hsl(var(--hue-green), 39%, 22%);
+ --color-green: hsl(var(--hue-green), 82%, 63%);
+ --color-green-high: hsl(var(--hue-green), 82%, 80%);
+ --hue-blue: 234;
+ --color-blue-low: hsl(var(--hue-blue), 54%, 20%);
+ --color-blue: hsl(var(--hue-blue), 100%, 60%);
+ --color-blue-high: hsl(var(--hue-blue), 100%, 87%);
+ --hue-purple: 281;
+ --color-purple-low: hsl(var(--hue-purple), 39%, 22%);
+ --color-purple: hsl(var(--hue-purple), 82%, 63%);
+ --color-purple-high: hsl(var(--hue-purple), 82%, 89%);
+ --hue-red: 339;
+ --color-red-low: hsl(var(--hue-red), 39%, 22%);
+ --color-red: hsl(var(--hue-red), 82%, 63%);
+ --color-red-high: hsl(var(--hue-red), 82%, 87%);
+
+ --color-accent-low: hsl(13, 75%, 30%);
+ --color-accent: hsl(13, 88%, 57%);
+ --color-accent-high: hsl(13, 100%, 78%);
+
+ --color-text: var(--color-gray-1);
+ --color-text-dimmed: var(--color-gray-3);
+ --color-text-accent: var(--color-accent);
+ --color-text-invert: var(--color-black);
+ --color-text-accent-invert: var(--color-accent-high);
+ --color-bg: var(--color-black);
+ --color-bg-surface: var(--color-gray-5);
+ --color-bg-accent: var(--color-accent-high);
+ --color-border: var(--color-gray-2);
+
+ --color-backdrop-overlay: hsla(223, 13%, 10%, 0.66);
+}
+
+:root[data-color-mode="light"] {
+ --color-white: hsl(224, 10%, 10%);
+ --color-gray-1: hsl(224, 14%, 16%);
+ --color-gray-2: hsl(224, 10%, 23%);
+ --color-gray-3: hsl(224, 7%, 36%);
+ --color-gray-4: hsl(224, 6%, 56%);
+ --color-gray-5: hsl(224, 6%, 77%);
+ --color-gray-6: hsl(224, 20%, 94%);
+ --color-gray-7: hsl(224, 19%, 97%);
+ --color-black: hsl(0, 0%, 100%);
+
+ --color-orange-high: hsl(var(--hue-orange), 80%, 25%);
+ --color-orange: hsl(var(--hue-orange), 90%, 60%);
+ --color-orange-low: hsl(var(--hue-orange), 90%, 88%);
+ --color-green-high: hsl(var(--hue-green), 80%, 22%);
+ --color-green: hsl(var(--hue-green), 90%, 46%);
+ --color-green-low: hsl(var(--hue-green), 85%, 90%);
+ --color-blue-high: hsl(var(--hue-blue), 80%, 30%);
+ --color-blue: hsl(var(--hue-blue), 90%, 60%);
+ --color-blue-low: hsl(var(--hue-blue), 88%, 90%);
+ --color-purple-high: hsl(var(--hue-purple), 90%, 30%);
+ --color-purple: hsl(var(--hue-purple), 90%, 60%);
+ --color-purple-low: hsl(var(--hue-purple), 80%, 90%);
+ --color-red-high: hsl(var(--hue-red), 80%, 30%);
+ --color-red: hsl(var(--hue-red), 90%, 60%);
+ --color-red-low: hsl(var(--hue-red), 80%, 90%);
+
+ --color-accent-high: hsl(13, 75%, 26%);
+ --color-accent: hsl(13, 88%, 60%);
+ --color-accent-low: hsl(13, 100%, 89%);
+
+ --color-text-accent: var(--color-accent);
+ --color-text-dimmed: var(--color-gray-4);
+ --color-text-invert: var(--color-black);
+ --color-text-accent-invert: var(--color-accent-low);
+ --color-bg-surface: var(--color-gray-6);
+ --color-bg-accent: var(--color-accent);
+
+ --color-backdrop-overlay: hsla(225, 9%, 36%, 0.66);
+}
diff --git a/cloud/web/src/ui/style/token/font.css b/cloud/web/src/ui/style/token/font.css
new file mode 100644
index 000000000..24b2db3f2
--- /dev/null
+++ b/cloud/web/src/ui/style/token/font.css
@@ -0,0 +1,20 @@
+:root {
+ --font-size-2xs: 0.6875rem;
+ --font-size-xs: 0.75rem;
+ --font-size-sm: 0.8125rem;
+ --font-size-md: 0.9375rem;
+ --font-size-lg: 1.125rem;
+ --font-size-xl: 1.25rem;
+ --font-size-2xl: 1.5rem;
+ --font-size-3xl: 1.875rem;
+ --font-size-4xl: 2.25rem;
+ --font-size-5xl: 3rem;
+ --font-size-6xl: 3.75rem;
+ --font-size-7xl: 4.5rem;
+ --font-size-8xl: 6rem;
+ --font-size-9xl: 8rem;
+ --font-mono: IBM Plex Mono, monospace;
+ --font-sans: Rubik, sans-serif;
+
+ --font-line-height: 1.75;
+}
diff --git a/cloud/web/src/ui/style/token/reset.css b/cloud/web/src/ui/style/token/reset.css
new file mode 100644
index 000000000..f4aa1a0a9
--- /dev/null
+++ b/cloud/web/src/ui/style/token/reset.css
@@ -0,0 +1,212 @@
+* {
+ margin: 0;
+ padding: 0;
+ font: inherit;
+}
+
+*,
+*::before,
+*::after {
+ box-sizing: border-box;
+ border-width: 0;
+ border-style: solid;
+ border-color: var(--global-color-border, currentColor);
+}
+
+html {
+ line-height: 1.5;
+ --font-fallback: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
+ "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
+ "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
+ -webkit-text-size-adjust: 100%;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -moz-tab-size: 4;
+ tab-size: 4;
+ font-family: var(--global-font-body, var(--font-fallback));
+}
+
+hr {
+ height: 0;
+ color: inherit;
+ border-top-width: 1px;
+}
+
+body {
+ height: 100%;
+ line-height: inherit;
+}
+
+img {
+ border-style: none;
+}
+
+img,
+svg,
+video,
+canvas,
+audio,
+iframe,
+embed,
+object {
+ display: block;
+ vertical-align: middle;
+}
+
+img,
+video {
+ max-width: 100%;
+ height: auto;
+}
+
+p,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ overflow-wrap: break-word;
+}
+
+ol,
+ul {
+ list-style: none;
+}
+
+code,
+kbd,
+pre,
+samp {
+ font-size: 1em;
+}
+
+button,
+[type="button"],
+[type="reset"],
+[type="submit"] {
+ -webkit-appearance: button;
+ background-color: transparent;
+ background-image: none;
+}
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ color: inherit;
+}
+
+button,
+select {
+ text-transform: none;
+}
+
+table {
+ text-indent: 0;
+ border-color: inherit;
+ border-collapse: collapse;
+}
+
+input::placeholder,
+textarea::placeholder {
+ opacity: 1;
+ color: var(--global-color-placeholder, #9ca3af);
+}
+
+textarea {
+ resize: vertical;
+}
+
+summary {
+ display: list-item;
+}
+
+small {
+ font-size: 80%;
+}
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+sup {
+ top: -0.5em;
+}
+
+dialog {
+ padding: 0;
+}
+
+a {
+ color: inherit;
+ text-decoration: inherit;
+}
+
+abbr:where([title]) {
+ text-decoration: underline dotted;
+}
+
+b,
+strong {
+ font-weight: bolder;
+}
+
+code,
+kbd,
+samp,
+pre {
+ font-size: 1em;
+ --font-mono-fallback: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
+ "Liberation Mono", "Courier New";
+ font-family: var(--global-font-mono, var(--font-fallback));
+}
+
+input[type="text"],
+input[type="email"],
+input[type="search"],
+input[type="password"] {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+}
+
+input[type="search"] {
+ -webkit-appearance: textfield;
+ outline-offset: -2px;
+}
+
+::-webkit-search-decoration,
+::-webkit-search-cancel-button {
+ -webkit-appearance: none;
+}
+
+::-webkit-file-upload-button {
+ -webkit-appearance: button;
+ font: inherit;
+}
+
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+ height: auto;
+}
+
+input[type="number"] {
+ -moz-appearance: textfield;
+}
+
+:-moz-ui-invalid {
+ box-shadow: none;
+}
+
+:-moz-focusring {
+ outline: auto;
+}
diff --git a/cloud/web/src/ui/style/token/space.css b/cloud/web/src/ui/style/token/space.css
new file mode 100644
index 000000000..b1e492f49
--- /dev/null
+++ b/cloud/web/src/ui/style/token/space.css
@@ -0,0 +1,38 @@
+:root {
+ --space-0: 0;
+ --space-px: 1px;
+ --space-0-5: 0.125rem;
+ --space-1: 0.25rem;
+ --space-1-5: 0.375rem;
+ --space-2: 0.5rem;
+ --space-2-5: 0.625rem;
+ --space-3: 0.75rem;
+ --space-3-5: 0.875rem;
+ --space-4: 1rem;
+ --space-4-5: 1.125rem;
+ --space-5: 1.25rem;
+ --space-6: 1.5rem;
+ --space-7: 1.75rem;
+ --space-8: 2rem;
+ --space-9: 2.25rem;
+ --space-10: 2.5rem;
+ --space-11: 2.75rem;
+ --space-12: 3rem;
+ --space-14: 3.5rem;
+ --space-16: 4rem;
+ --space-20: 5rem;
+ --space-24: 6rem;
+ --space-28: 7rem;
+ --space-32: 8rem;
+ --space-36: 9rem;
+ --space-40: 10rem;
+ --space-44: 11rem;
+ --space-48: 12rem;
+ --space-52: 13rem;
+ --space-56: 14rem;
+ --space-60: 15rem;
+ --space-64: 16rem;
+ --space-72: 18rem;
+ --space-80: 20rem;
+ --space-96: 24rem;
+}