From b8b44d62fdfd6a690885bdd6ad7b76a97764b2ff Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Fri, 11 Jul 2025 18:09:10 +0800 Subject: wip --- app.css | 313 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 313 insertions(+) create mode 100644 app.css (limited to 'app.css') diff --git a/app.css b/app.css new file mode 100644 index 0000000..6104a97 --- /dev/null +++ b/app.css @@ -0,0 +1,313 @@ +/** + * CSS Reset + */ + +*, +*::before, +*::after { + box-sizing: border-box; +} + +* { + margin: 0; +} + +@media (prefers-reduced-motion: no-preference) { + html { + interpolate-size: allow-keywords; + } +} + +body { + line-height: 1.5; + -webkit-font-smoothing: antialiased; +} + +img, +picture, +video, +canvas, +svg { + display: block; + max-width: 100%; +} + +input, +button, +textarea, +select { + font: inherit; +} + +p, +h1, +h2, +h3, +h4, +h5, +h6 { + overflow-wrap: break-word; +} + +p { + text-wrap: pretty; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + text-wrap: balance; +} + +fieldset { + padding: 0; + border: 0; +} + +/** + * Application + */ + +:root { + --color-white: #fff; + --color-zinc-50: #fafafa; + --color-zinc-100: #f4f4f5; + --color-zinc-200: #e4e4e7; + --color-zinc-300: #d4d4d8; + --color-zinc-400: #9f9fa9; + --color-zinc-500: #71717b; + --color-zinc-600: #52525c; + --color-zinc-700: #3f3f46; + --color-zinc-800: #27272a; + --color-zinc-900: #18181b; + --color-zinc-950: #09090b; +} + +body { + display: grid; + justify-content: center; + font-family: "Inter", sans-serif; + color: var(--color-white); + background: var(--color-zinc-950) url(assets/airmx-pro.png) no-repeat center bottom / auto 10rem; +} + +@media (min-width: 768px) { + body { + grid: max-content max-content 4.5rem / 40rem; + } +} + +.page__header { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + margin-block-start: 4.5rem; +} + +.container { + position: relative; + margin-block-start: 3rem; + grid-row: 2; + padding: 3rem 4rem 4rem; + background: linear-gradient(324deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.06)); + border-radius: 0.375rem; +} + +.form { + display: none; +} + +.form--active { + display: block; +} + +.form__header { + margin-block-end: 3rem; + text-align: center; +} + +.form__indicator { + display: block; + margin-inline: auto; + margin-block-end: 1.5rem; + width: 6rem; + height: 6rem; +} + +.form__title { + font-weight: 500; + font-size: 1.5rem; + line-height: 1.2; + color: var(--title-color); +} + +.form__title--gradient { + background-image: linear-gradient(var(--color-zinc-50), var(--color-zinc-400)); + background-clip: text; + -webkit-text-fill-color: transparent; +} + +.form__description { + margin-block-start: 1rem; + font-size: 0.875rem; + line-height: 1.5; + color: var(--color-zinc-500); +} + +.form__text { + font-size: 0.9375rem; + line-height: 1.5; + color: var(--color-zinc-200); +} + +.form__text+.form__text { + margin-block-start: 1.5rem; +} + +.form__footer { + margin-block-start: 4rem; +} + +.button { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + gap: .625rem; + padding: 0 1.25rem; + font-size: .9375rem; + line-height: 3.25rem; + color: var(--color-zinc-50); + background-color: transparent; + border: 0; + border-radius: .25rem; + width: 100%; + height: 3.25rem; + cursor: pointer; + transition: 150ms linear background-color; +} + +.button:hover { + background-color: rgba(255, 255, 255, 0.05); +} + +.button__icon { + transition: 150ms linear transform; +} + +.button:hover .button__icon { + transform: translateX(0.5rem); +} + +.input { + display: block; + padding: 0.5rem 1rem; + font-size: 0.9375rem; + line-height: 2.25rem; + color: var(--color-zinc-500); + background-color: var(--color-zinc-900); + border: 1px solid var(--color-zinc-800); + border-radius: 0.25rem; + width: 100%; + height: 2.25rem; + transition: 50ms linear border-color, 50ms linear outline; +} + +.input:focus { + border-color: transparent; + outline: 1px solid var(--color-zinc-500); +} + +.form__text+.input { + margin-block-start: 2rem; +} + +.input+.input { + margin-block-start: 1.5rem; +} + +.input-group { + display: flex; + flex-direction: row; + align-items: center; + gap: 1rem; + margin-block-start: 2rem; + padding-inline-end: 0.5rem; + background-color: var(--color-zinc-900); + border: 1px solid var(--color-zinc-800); + border-radius: 0.25rem; + height: 3rem; +} + +.input-group .input { + flex: 1; + background-color: transparent; + border: 0; + outline: none; +} + +.input-group .inout:focus { + outline: 0; +} + +.input-group .button { + flex: 0; + padding-inline: 1.5rem; + font-weight: 500; + font-size: 0.875rem; + line-height: 2.25rem; + background-color: var(--color-zinc-700); + border-radius: 0.5rem; + height: 2.25rem; +} + +.input-group .button:hover { + background-color: var(--color-zinc-800); +} + +.physical-button { + margin-inline: 0.5rem; + vertical-align: middle; +} + +.physical-button { + display: inline-flex; + flex-direction: row; + align-items: center; + justify-content: center; + width: 1.5rem; + height: 1.5rem; + background: linear-gradient(0deg, rgba(24, 24, 27, 0.3), rgba(24, 24, 27, 0.3)), linear-gradient(135.86deg, rgba(212, 212, 216, 0.32) 5.24%, rgba(24, 24, 27, 0.2) 51.01%); + border-radius: 100%; +} + +.physical-button__ai { + display: block; + width: 10px; + height: 8px; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='8' fill='none'%3E%3Cpath fill='%2308A61E' d='M1.995 7.503H.645L3.103.52h1.56l2.462 6.982h-1.35L3.91 1.953h-.054l-1.861 5.55Zm.044-2.738H5.72v1.016H2.039V4.765ZM9.309.521v6.982H8.046V.52H9.31Z'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: center; +} + +.physical-button__fan { + display: block; + width: 11px; + height: 11px; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='11' fill='none'%3E%3Cpath fill='%2317A33C' d='M6.894 7.245c.566.66.528 1.645-.087 2.26l-.367.367a1.471 1.471 0 0 1-2.08-2.08l.552-.554c.313-.312.488-.735.488-1.176v-.56l1.494 1.743Z'/%3E%3Cpath fill='%2317A33C' d='M7.143 4.009a1.665 1.665 0 0 1 2.26.087l.366.366a1.471 1.471 0 0 1-2.08 2.08l-.553-.552a1.665 1.665 0 0 0-1.177-.488H5.4L3.658 6.996a1.665 1.665 0 0 1-2.26-.087l-.367-.366a1.471 1.471 0 0 1 2.08-2.08l.553.552c.312.312.736.487 1.178.487H5.4L7.143 4.01Z'/%3E%3Cpath fill='%2317A33C' d='M4.36 1.133a1.471 1.471 0 0 1 2.08 2.08l-.552.554A1.666 1.666 0 0 0 5.4 4.944v.558L3.906 3.76a1.665 1.665 0 0 1 .087-2.26l.367-.367Z'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: center; +} + +.physical-button__b-circle { + display: block; + width: 15px; + height: 15px; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='15' height='15' fill='none'%3E%3Ccircle cx='8' cy='7.502' r='5.4' stroke='%2317A33C' stroke-linecap='round' stroke-linejoin='round' stroke-width='.9'/%3E%3Cpath stroke='%2317A33C' stroke-linecap='round' stroke-linejoin='round' stroke-width='.9' d='M6.5 7.502v-2.4h2.203c1.315 0 1.5 1.955.273 2.4m-2.476 0v2.4h2.203c1.315 0 1.5-1.954.273-2.4m-2.476 0h2.476'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: center; +} -- cgit v1.2.3 From 4ba55c31c693b26c630a245b845cd4e85de6b639 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Fri, 11 Jul 2025 21:16:24 +0800 Subject: validate wi-fi credentials --- app.css | 6 ++++++ main.mjs | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) (limited to 'app.css') diff --git a/app.css b/app.css index 6104a97..905eedf 100644 --- a/app.css +++ b/app.css @@ -269,6 +269,12 @@ body { background-color: var(--color-zinc-800); } +.help-text { + margin-top: 1rem; + font-size: 0.875rem; + color: var(--color-zinc-600); +} + .physical-button { margin-inline: 0.5rem; vertical-align: middle; diff --git a/main.mjs b/main.mjs index e19400e..56862f4 100644 --- a/main.mjs +++ b/main.mjs @@ -266,6 +266,8 @@ class WelcomeForm extends ProgressibleForm { } class WifiCredentialsForm extends ProgressibleForm { + #submitCallback = null + constructor(id) { super(id) this.form.addEventListener('submit', this.handleSubmit.bind(this)) @@ -273,7 +275,51 @@ class WifiCredentialsForm extends ProgressibleForm { handleSubmit(event) { event.preventDefault() - this.nextForm() + const { elements } = event.target + try { + const [ssid, password] = this.validate(elements.ssid.value, elements.password.value) + if (this.#submitCallback) { + this.#submitCallback({ ssid, password }) + } + this.nextForm() + } catch (error) { + this.alert(error.message) + } + } + + validate(ssid, password) { + if (ssid === '' ) { + throw new Error('SSID cannot be empty.') + } + + if (ssid.length > 32) { + throw new Error('SSID cannot be longer than 32 characters.') + } + + if (password === '' ) { + throw new Error('Password cannot be empty.') + } + + if (password.length < 8 || password.length > 63) { + throw new Error('Password must be between 8 and 63 characters long.') + } + + return [ssid, password] + } + + alert(message) { + this.form.querySelector('.help-text')?.remove() + + const element = document.createElement('div') + element.classList.add('help-text', 'help-text--danger') + element.textContent = message + + this.form.querySelector('.form__footer').before(element) + } + + onSubmit(callback) { + this.#submitCallback = callback + return this } } @@ -292,6 +338,7 @@ class PairingActivationForm extends ProgressibleForm { class CommunicationForm extends Form { #successForm = null #failureForm = null + #wifiCredentials = null succeedTo(form) { this.#successForm = form @@ -302,6 +349,11 @@ class CommunicationForm extends Form { this.#failureForm = form return this } + + wifiCredentialsUsing(credentials) { + this.#wifiCredentials = credentials + return this + } } class Application { @@ -325,6 +377,9 @@ class Application { .nextTo(communicationForm) const wifiCredentialsForm = new WifiCredentialsForm('form-wifi-credentials') .nextTo(pairingActivationForm) + .onSubmit((credentials) => { + communicationForm.wifiCredentialsUsing(credentials) + }) const welcomeForm = new WelcomeForm('form-welcome') .nextTo(wifiCredentialsForm) -- cgit v1.2.3 From 6f15fb63da85f2d9d651c02f16dabd7fea33935c Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Fri, 11 Jul 2025 21:59:49 +0800 Subject: retry option --- app.css | 14 ++++++++++++++ index.html | 4 ++++ main.mjs | 43 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 59 insertions(+), 2 deletions(-) (limited to 'app.css') diff --git a/app.css b/app.css index 905eedf..d55b049 100644 --- a/app.css +++ b/app.css @@ -168,6 +168,12 @@ body { margin-block-start: 1.5rem; } +.form__link { + font-size: 0.9375rem; + line-height: 1.5; + color: var(--color-zinc-50); +} + .form__footer { margin-block-start: 4rem; } @@ -317,3 +323,11 @@ body { background-repeat: no-repeat; background-position: center; } + +.retry-message { + display: none; +} + +.retry-message--shown { + display: block; +} diff --git a/index.html b/index.html index 46b069a..86e3b8b 100644 --- a/index.html +++ b/index.html @@ -104,6 +104,10 @@

One more thing, let's choose the AIRMX Pro device from the Bluetooth scanning list.

+

+ 👀 The list has been dismissed. + Try again? +

diff --git a/main.mjs b/main.mjs index d02dba3..f1fb638 100644 --- a/main.mjs +++ b/main.mjs @@ -306,12 +306,31 @@ class CommunicationForm extends Form { #failureForm = null #wifiCredentials = null + #retryMessage = null + #retryMessageClassName = 'retry-message' + #retryMessageShownClassName = 'retry-message--shown' + + #retryLink = null + #retryLinkClassName = `retry-link` + constructor(id, device) { super(id) this.#device = device + this.#retryMessage = this.form.querySelector(`.${this.#retryMessageClassName}`) + if (this.#retryMessage) { + this.#retryLink = this.form.querySelector(`.${this.#retryLinkClassName}`) + this.#retryLink.addEventListener('click', () => { + this.hideRetryOption() + this.startPairing() + }) + } } - async onDisplay() { + onDisplay() { + this.startPairing() + } + + async startPairing() { if (this.#device === null) { return } @@ -320,7 +339,11 @@ class CommunicationForm extends Form { return } - await this.connect(this.#device, this.wifiCredentials) + try { + await this.connect(this.#device, this.wifiCredentials) + } catch { + this.showRetryOption() + } } async connect() { @@ -353,6 +376,22 @@ class CommunicationForm extends Form { console.log(`Received data from device: ${receivedBytes.join(' ')}`) } + showRetryOption() { + if (this.#retryMessage === null) { + return + } + + this.#retryMessage.classList.add(this.#retryMessageShownClassName) + } + + hideRetryOption() { + if (this.#retryMessage === null) { + return + } + + this.#retryMessage.classList.remove(this.#retryMessageShownClassName) + } + succeedTo(form) { this.#successForm = form return this -- cgit v1.2.3 From 9f80e84fa0c82cf8b7a683393051318b4923b372 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sat, 12 Jul 2025 16:48:26 +0800 Subject: communicate progress --- app.css | 40 ++++++++++++++++++++++ index.html | 1 + main.mjs | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 149 insertions(+), 3 deletions(-) (limited to 'app.css') diff --git a/app.css b/app.css index d55b049..aa6c1ec 100644 --- a/app.css +++ b/app.css @@ -324,6 +324,46 @@ body { background-position: center; } +.progress { + margin-block-start: 2rem; + padding-inline: 3rem 1rem; +} + +.progress__item { + position: relative; + font-size: 0.875rem; + line-height: 2.25rem; + color: var(--color-zinc-700); + list-style: none; +} + +.progress__item::before { + position: absolute; + display: block; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none'%3E%3Crect width='16' height='16' y='.002' fill='%233F3F46' rx='8'/%3E%3C/svg%3E"); + width: 1rem; + height: 1rem; + left: -2rem; + top: 0.625rem; + content: ''; +} + +.progress__item[data-current] { + color: var(--color-zinc-300); +} + +.progress__item[data-current]::before { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none'%3E%3Crect width='16' height='16' y='.002' fill='%233F3F46' rx='8'/%3E%3Crect width='6.4' height='6.4' x='4.8' y='4.802' fill='%239F9FA9' rx='3.2'/%3E%3C/svg%3E"); +} + +.progress__item[data-complete] { + color: var(--color-zinc-300); +} + +.progress__item[data-complete]::before { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none'%3E%3Crect width='16' height='16' y='.002' fill='%2314532D' rx='8'/%3E%3Cpath fill='%2386EFAC' d='m6.873 9.231-1.485-1.48-.638.635 2.123 2.116 4.377-4.364-.638-.636-3.74 3.729Z'/%3E%3C/svg%3E"); +} + .retry-message { display: none; } diff --git a/index.html b/index.html index 86e3b8b..4371271 100644 --- a/index.html +++ b/index.html @@ -108,6 +108,7 @@ 👀 The list has been dismissed. Try again?

+
    diff --git a/main.mjs b/main.mjs index 5c74731..9d0d025 100644 --- a/main.mjs +++ b/main.mjs @@ -563,6 +563,9 @@ class CommunicationForm extends Form { /** @type {string} */ #descriptionText + /** @type {Progress} */ + #progress + #handshakeCommand #wifiCredentialsCommand #identityCommand @@ -590,6 +593,7 @@ class CommunicationForm extends Form { this.#messages = new IncomingMessageHandler() this.#messages.onMessage(this.handleMessage.bind(this)) this.#setupCounter() + this.#setupProgress() this.#handshakeCommand = new HandshakeCommand() this.#wifiCredentialsCommand = new ConfigureWifiCommand('', '') this.#identityCommand = new RequestIdentityCommand() @@ -611,25 +615,40 @@ class CommunicationForm extends Form { this.#description = this.form.querySelector('.form__description') this.#descriptionText = this.#description ? this.#description.textContent : '' this.#countdown = new Countdown(this.#description, 10) - this.#countdown.onComplete(this.transitToFailureResultForm.bind(this)) + this.#countdown.onComplete(() => { + this.#progress.clear() + this.disconnectIfNeeded() + this.transitToFailureResultForm() + }) this.#countdown.onStop(() => { this.#description.textContent = this.#descriptionText }) } + #setupProgress() { + const el = this.form.querySelector('[data-slot="progress"]') + this.#progress = new Progress(el, [ + { id: 'handshake', name: 'Say a hello to the machine' }, + { id: 'wifi', name: 'Send Wi-Fi credentials' }, + { id: 'identity', name: 'Receive the device\'s identity' } + ]) + } + async startPairing() { try { await this.connect() } catch { this.showRetryOption() - } finally { - this.disconnectIfNeeded() } } async connect() { await this.#handler.connect() + this.#countdown.start() + this.#progress.render() + + this.#progress.markAsCurrent('handshake') await this.#handler.dispatch(this.#handshakeCommand) } @@ -661,6 +680,8 @@ class CommunicationForm extends Form { * @param {CompleteMessage} message */ handleHandshakeMessage(message) { + this.#progress.markAsComplete('handshake') + this.#progress.markAsCurrent('wifi') this.#handler.dispatch(this.#wifiCredentialsCommand) } @@ -668,6 +689,8 @@ class CommunicationForm extends Form { * @param {CompleteMessage} message */ handleWifiCredentialsMessage(message) { + this.#progress.markAsComplete('wifi') + this.#progress.markAsCurrent('identity') this.#handler.dispatch(this.#identityCommand) } @@ -676,6 +699,9 @@ class CommunicationForm extends Form { */ handleIdentityMessage(message) { this.#countdown.stop() + this.#progress.markAsComplete('identity') + this.#progress.clear() + this.disconnectIfNeeded() this.transitToSuccessResultForm() } @@ -733,6 +759,85 @@ class FailureForm extends ProgressibleForm { } } +class Progress { + #el + #steps + + /** + * @param {HTMLElement|null} el - The HTML element to display the progress. + * @param {{ id: string, name: string }[]} steps - The progress steps. + */ + constructor(el, steps) { + this.#el = el + this.#steps = steps + if (this.#el === null) { + throw new Error('The HTML element could not be found to mount the progress.') + } + } + + render() { + if (! this.#el.classList.contains('progress')) { + this.#el.classList.add('progress') + } + + for (const step of this.#steps) { + const el = document.createElement('li') + el.innerText = step.name + el.classList.add('progress__item') + el.dataset.progress = step.id + this.#el.appendChild(el) + } + } + + clear() { + this.#el.innerHTML = '' + } + + /** + * @param {string} step - The step ID. + */ + markAsCurrent(step) { + this.markAsDefault(step) + + const el = this.#stepElement(step) + el.dataset.current = '' + } + + /** + * @param {string} step - The step ID. + */ + markAsComplete(step) { + this.markAsDefault(step) + + const el = this.#stepElement(step) + el.dataset.complete = '' + } + + /** + * @param {string} step - The step ID. + */ + markAsDefault(step) { + const el = this.#stepElement(step) + if ('current' in el.dataset) { + delete el.dataset.current + } + if ('complete' in el.dataset) { + delete el.dataset.complete + } + } + + /** + * @param {string} id - The step ID. + */ + #stepElement(id) { + const el = this.#el.querySelector(`[data-progress="${id}"]`) + if (! el) { + throw new Error(`Progress step "${step}" does not exist.`) + } + return el + } +} + class Application { static supportBluetoothApi() { return 'bluetooth' in navigator -- cgit v1.2.3 From a7c267c39bfd53d3b2e991fc531dc273ac725c2b Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Sat, 12 Jul 2025 18:16:40 +0800 Subject: doctype --- app.css | 1 + index.html | 1 + 2 files changed, 2 insertions(+) (limited to 'app.css') diff --git a/app.css b/app.css index aa6c1ec..8d4c683 100644 --- a/app.css +++ b/app.css @@ -92,6 +92,7 @@ body { font-family: "Inter", sans-serif; color: var(--color-white); background: var(--color-zinc-950) url(assets/airmx-pro.png) no-repeat center bottom / auto 10rem; + min-height: 100vh; } @media (min-width: 768px) { diff --git a/index.html b/index.html index 1676422..2f6c920 100644 --- a/index.html +++ b/index.html @@ -1,3 +1,4 @@ + Setup AIRMX device -- cgit v1.2.3 From 1d0a01683b58470dc682df1f4a104f07b33338e1 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Tue, 15 Jul 2025 07:48:12 +0800 Subject: wip: responsive ui --- app.css | 25 +++++++++++++++++-------- index.html | 1 + 2 files changed, 18 insertions(+), 8 deletions(-) (limited to 'app.css') diff --git a/app.css b/app.css index 8d4c683..4fe0c88 100644 --- a/app.css +++ b/app.css @@ -88,6 +88,7 @@ fieldset { body { display: grid; + grid: max-content max-content 4.5rem / auto; justify-content: center; font-family: "Inter", sans-serif; color: var(--color-white); @@ -95,25 +96,19 @@ body { min-height: 100vh; } -@media (min-width: 768px) { - body { - grid: max-content max-content 4.5rem / 40rem; - } -} - .page__header { display: flex; flex-direction: row; align-items: center; justify-content: center; - margin-block-start: 4.5rem; + margin-block-start: 2rem; } .container { position: relative; margin-block-start: 3rem; grid-row: 2; - padding: 3rem 4rem 4rem; + padding: 2rem 1.5rem 3rem; background: linear-gradient(324deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.06)); border-radius: 0.375rem; } @@ -372,3 +367,17 @@ body { .retry-message--shown { display: block; } + +@media (min-width: 768px) { + body { + grid: max-content max-content 4.5rem / 40rem; + } + + .page__header { + margin-block-start: 4.5rem; + } + + .container { + padding: 3rem 4rem 4rem; + } +} diff --git a/index.html b/index.html index 0f229ff..85c2849 100644 --- a/index.html +++ b/index.html @@ -2,6 +2,7 @@ Setup AIRMX device + -- cgit v1.2.3 From 2d19c893e14700022ec8786de43f0b2766ff7776 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Tue, 15 Jul 2025 19:53:59 +0800 Subject: tweak styles --- app.css | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'app.css') diff --git a/app.css b/app.css index 4fe0c88..8d181e0 100644 --- a/app.css +++ b/app.css @@ -88,7 +88,7 @@ fieldset { body { display: grid; - grid: max-content max-content 4.5rem / auto; + grid: max-content max-content 7.5rem / auto; justify-content: center; font-family: "Inter", sans-serif; color: var(--color-white); @@ -107,6 +107,7 @@ body { .container { position: relative; margin-block-start: 3rem; + margin-inline: 1.25rem; grid-row: 2; padding: 2rem 1.5rem 3rem; background: linear-gradient(324deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.06)); @@ -236,7 +237,6 @@ body { display: flex; flex-direction: row; align-items: center; - gap: 1rem; margin-block-start: 2rem; padding-inline-end: 0.5rem; background-color: var(--color-zinc-900); @@ -370,7 +370,7 @@ body { @media (min-width: 768px) { body { - grid: max-content max-content 4.5rem / 40rem; + grid-template-columns: 40rem; } .page__header { @@ -379,5 +379,6 @@ body { .container { padding: 3rem 4rem 4rem; + margin-inline: 0; } } -- cgit v1.2.3 From 61e08f1aebcbd4562bad659b9d079bbbd9704270 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Tue, 15 Jul 2025 19:59:01 +0800 Subject: logical margin --- app.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app.css') diff --git a/app.css b/app.css index 8d181e0..a613c06 100644 --- a/app.css +++ b/app.css @@ -272,7 +272,7 @@ body { } .help-text { - margin-top: 1rem; + margin-block-start: 1rem; font-size: 0.875rem; color: var(--color-zinc-600); } -- cgit v1.2.3 From 4556f01f7ba735c1367719554a34ec868f5aa961 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Tue, 15 Jul 2025 20:02:00 +0800 Subject: tweak styles --- app.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app.css') diff --git a/app.css b/app.css index a613c06..95f27c3 100644 --- a/app.css +++ b/app.css @@ -88,7 +88,7 @@ fieldset { body { display: grid; - grid: max-content max-content 7.5rem / auto; + grid: max-content max-content 10rem / auto; justify-content: center; font-family: "Inter", sans-serif; color: var(--color-white); -- cgit v1.2.3 From d1a7e0690fc2e5921246c723b0489d7f04ed3703 Mon Sep 17 00:00:00 2001 From: Li Zhineng Date: Tue, 15 Jul 2025 20:04:52 +0800 Subject: fix css variable --- app.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app.css') diff --git a/app.css b/app.css index 95f27c3..ce31a3f 100644 --- a/app.css +++ b/app.css @@ -139,7 +139,7 @@ body { font-weight: 500; font-size: 1.5rem; line-height: 1.2; - color: var(--title-color); + color: var(--color-white); } .form__title--gradient { -- cgit v1.2.3