diff --git a/assets/css/input.css b/assets/css/input.css index b21a793..04fc90b 100644 --- a/assets/css/input.css +++ b/assets/css/input.css @@ -75,13 +75,30 @@ .snake-cell { background: #16213e; border: 1px solid rgba(255,255,255,0.03); - transition: background 0.05s; + transition: background 130ms ease-in-out, box-shadow 130ms ease-out; +} +.snake-cell.snake-head { + border-radius: 4px; + animation: head-pop 130ms ease-out; +} +@keyframes head-pop { + 0% { transform: scale(0.6); } + 50% { transform: scale(1.08); } + 100% { transform: scale(1); } } .snake-cell.snake-food { background: #ff6b6b; border-radius: 50%; box-shadow: 0 0 6px rgba(255,107,107,0.6); + animation: food-pulse 1.2s ease-in-out infinite alternate; +} +@keyframes food-pulse { + from { box-shadow: 0 0 6px rgba(255,107,107,0.4); transform: scale(0.85); } + to { box-shadow: 0 0 12px rgba(255,107,107,0.9); transform: scale(1); } +} +.snake-cell.snake-dead { + opacity: 0.35; + filter: grayscale(0.5); + transition: opacity 400ms ease-out, background 130ms ease-in-out; } -.snake-cell.snake-head { border-radius: 4px; } -.snake-cell.snake-dead { opacity: 0.35; } .snake-wrapper:focus { outline: none; } diff --git a/assets/css/output.css b/assets/css/output.css index f2e04e2..1d26e00 100644 --- a/assets/css/output.css +++ b/assets/css/output.css @@ -1,1763 +1,2 @@ /*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */ -@layer properties; -@layer theme, base, components, utilities; -@layer theme { - :root, :host { - --font-sans: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', - 'Noto Color Emoji'; - --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', - monospace; - --color-gray-800: oklch(27.8% 0.033 256.848); - --color-black: #000; - --color-white: #fff; - --spacing: 0.25rem; - --container-sm: 24rem; - --container-md: 28rem; - --text-xs: 0.75rem; - --text-xs--line-height: calc(1 / 0.75); - --text-sm: 0.875rem; - --text-sm--line-height: calc(1.25 / 0.875); - --text-lg: 1.125rem; - --text-lg--line-height: calc(1.75 / 1.125); - --text-xl: 1.25rem; - --text-xl--line-height: calc(1.75 / 1.25); - --text-3xl: 1.875rem; - --text-3xl--line-height: calc(2.25 / 1.875); - --font-weight-bold: 700; - --radius-lg: 0.5rem; - --default-transition-duration: 150ms; - --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); - --default-font-family: var(--font-sans); - --default-mono-font-family: var(--font-mono); - } -} -@layer base { - *, ::after, ::before, ::backdrop, ::file-selector-button { - box-sizing: border-box; - margin: 0; - padding: 0; - border: 0 solid; - } - html, :host { - line-height: 1.5; - -webkit-text-size-adjust: 100%; - tab-size: 4; - font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'); - font-feature-settings: var(--default-font-feature-settings, normal); - font-variation-settings: var(--default-font-variation-settings, normal); - -webkit-tap-highlight-color: transparent; - } - hr { - height: 0; - color: inherit; - border-top-width: 1px; - } - abbr:where([title]) { - -webkit-text-decoration: underline dotted; - text-decoration: underline dotted; - } - h1, h2, h3, h4, h5, h6 { - font-size: inherit; - font-weight: inherit; - } - a { - color: inherit; - -webkit-text-decoration: inherit; - text-decoration: inherit; - } - b, strong { - font-weight: bolder; - } - code, kbd, samp, pre { - font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace); - font-feature-settings: var(--default-mono-font-feature-settings, normal); - font-variation-settings: var(--default-mono-font-variation-settings, normal); - font-size: 1em; - } - 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; - } - table { - text-indent: 0; - border-color: inherit; - border-collapse: collapse; - } - :-moz-focusring { - outline: auto; - } - progress { - vertical-align: baseline; - } - summary { - display: list-item; - } - ol, ul, menu { - list-style: none; - } - img, svg, video, canvas, audio, iframe, embed, object { - display: block; - vertical-align: middle; - } - img, video { - max-width: 100%; - height: auto; - } - button, input, select, optgroup, textarea, ::file-selector-button { - font: inherit; - font-feature-settings: inherit; - font-variation-settings: inherit; - letter-spacing: inherit; - color: inherit; - border-radius: 0; - background-color: transparent; - opacity: 1; - } - :where(select:is([multiple], [size])) optgroup { - font-weight: bolder; - } - :where(select:is([multiple], [size])) optgroup option { - padding-inline-start: 20px; - } - ::file-selector-button { - margin-inline-end: 4px; - } - ::placeholder { - opacity: 1; - } - @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) { - ::placeholder { - color: currentcolor; - @supports (color: color-mix(in lab, red, red)) { - color: color-mix(in oklab, currentcolor 50%, transparent); - } - } - } - textarea { - resize: vertical; - } - ::-webkit-search-decoration { - -webkit-appearance: none; - } - ::-webkit-date-and-time-value { - min-height: 1lh; - text-align: inherit; - } - ::-webkit-datetime-edit { - display: inline-flex; - } - ::-webkit-datetime-edit-fields-wrapper { - padding: 0; - } - ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field { - padding-block: 0; - } - ::-webkit-calendar-picker-indicator { - line-height: 1; - } - :-moz-ui-invalid { - box-shadow: none; - } - button, input:where([type='button'], [type='reset'], [type='submit']), ::file-selector-button { - appearance: button; - } - ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { - height: auto; - } - [hidden]:where(:not([hidden='until-found'])) { - display: none !important; - } -} -@layer utilities { - .tab { - @layer daisyui.l1.l2.l3 { - position: relative; - display: inline-flex; - cursor: pointer; - appearance: none; - flex-wrap: wrap; - align-items: center; - justify-content: center; - text-align: center; - webkit-user-select: none; - user-select: none; - &:hover { - @media (hover: hover) { - color: var(--color-base-content); - } - } - --tab-p: 0.75rem; - --tab-bg: var(--color-base-100); - --tab-border-color: var(--color-base-300); - --tab-radius-ss: 0; - --tab-radius-se: 0; - --tab-radius-es: 0; - --tab-radius-ee: 0; - --tab-order: 0; - --tab-radius-min: calc(0.75rem - var(--border)); - --tab-radius-limit: min(var(--radius-field), var(--tab-radius-min)); - --tab-radius-grad: #0000 calc(69% - var(--border)), - var(--tab-border-color) calc(calc(69% - var(--border)) + 0.25px), - var(--tab-border-color) calc(calc(69% - var(--border)) + var(--border)), - var(--tab-bg) calc(calc(69% - var(--border)) + var(--border) + 0.25px); - border-color: #0000; - order: var(--tab-order); - height: var(--tab-height); - font-size: 0.875rem; - padding-inline-start: var(--tab-p); - padding-inline-end: var(--tab-p); - &:is(input[type="radio"]) { - min-width: fit-content; - &:after { - --tw-content: attr(aria-label); - content: var(--tw-content); - } - } - &:is(label) { - position: relative; - input { - position: absolute; - inset: calc(0.25rem * 0); - cursor: pointer; - appearance: none; - opacity: 0%; - } - } - &:checked, &:is(label:has(:checked)), &:is(.tab-active, [aria-selected="true"], [aria-current="true"], [aria-current="page"]) { - & + .tab-content { - display: block; - } - } - &:not( :checked, label:has(:checked), :hover, .tab-active, [aria-selected="true"], [aria-current="true"], [aria-current="page"] ) { - color: var(--color-base-content); - @supports (color: color-mix(in lab, red, red)) { - color: color-mix(in oklab, var(--color-base-content) 50%, transparent); - } - } - &:not(input):empty { - flex-grow: 1; - cursor: default; - } - &:focus { - --tw-outline-style: none; - outline-style: none; - @media (forced-colors: active) { - outline: 2px solid transparent; - outline-offset: 2px; - } - } - &:focus-visible, &:is(label:has(:checked:focus-visible)) { - outline: 2px solid currentColor; - outline-offset: -5px; - } - &[disabled] { - pointer-events: none; - opacity: 40%; - } - } - } - .btn { - :where(&) { - @layer daisyui.l1.l2.l3 { - width: unset; - } - } - @layer daisyui.l1.l2.l3 { - display: inline-flex; - flex-shrink: 0; - cursor: pointer; - flex-wrap: nowrap; - align-items: center; - justify-content: center; - gap: calc(0.25rem * 1.5); - text-align: center; - vertical-align: middle; - outline-offset: 2px; - webkit-user-select: none; - user-select: none; - padding-inline: var(--btn-p); - color: var(--btn-fg); - --tw-prose-links: var(--btn-fg); - height: var(--size); - font-size: var(--fontsize, 0.875rem); - font-weight: 600; - outline-color: var(--btn-color, var(--color-base-content)); - transition-property: color, background-color, border-color, box-shadow; - transition-timing-function: cubic-bezier(0, 0, 0.2, 1); - transition-duration: 0.2s; - border-start-start-radius: var(--join-ss, var(--radius-field)); - border-start-end-radius: var(--join-se, var(--radius-field)); - border-end-start-radius: var(--join-es, var(--radius-field)); - border-end-end-radius: var(--join-ee, var(--radius-field)); - background-color: var(--btn-bg); - background-size: auto, calc(var(--noise) * 100%); - background-image: none, var(--btn-noise); - border-width: var(--border); - border-style: solid; - border-color: var(--btn-border); - text-shadow: 0 0.5px oklch(100% 0 0 / calc(var(--depth) * 0.15)); - touch-action: manipulation; - box-shadow: 0 0.5px 0 0.5px oklch(100% 0 0 / calc(var(--depth) * 6%)) inset, var(--btn-shadow); - --size: calc(var(--size-field, 0.25rem) * 10); - --btn-bg: var(--btn-color, var(--color-base-200)); - --btn-fg: var(--color-base-content); - --btn-p: 1rem; - --btn-border: var(--btn-bg); - @supports (color: color-mix(in lab, red, red)) { - --btn-border: color-mix(in oklab, var(--btn-bg), #000 calc(var(--depth) * 5%)); - } - --btn-shadow: 0 3px 2px -2px var(--btn-bg), - 0 4px 3px -2px var(--btn-bg); - @supports (color: color-mix(in lab, red, red)) { - --btn-shadow: 0 3px 2px -2px color-mix(in oklab, var(--btn-bg) calc(var(--depth) * 30%), #0000), - 0 4px 3px -2px color-mix(in oklab, var(--btn-bg) calc(var(--depth) * 30%), #0000); - } - --btn-noise: var(--fx-noise); - @media (hover: hover) { - &:hover { - --btn-bg: var(--btn-color, var(--color-base-200)); - @supports (color: color-mix(in lab, red, red)) { - --btn-bg: color-mix(in oklab, var(--btn-color, var(--color-base-200)), #000 7%); - } - } - } - &:focus-visible, &:has(:focus-visible) { - outline-width: 2px; - outline-style: solid; - isolation: isolate; - } - &:active:not(.btn-active) { - translate: 0 0.5px; - --btn-bg: var(--btn-color, var(--color-base-200)); - @supports (color: color-mix(in lab, red, red)) { - --btn-bg: color-mix(in oklab, var(--btn-color, var(--color-base-200)), #000 5%); - } - --btn-border: var(--btn-color, var(--color-base-200)); - @supports (color: color-mix(in lab, red, red)) { - --btn-border: color-mix(in oklab, var(--btn-color, var(--color-base-200)), #000 7%); - } - --btn-shadow: 0 0 0 0 oklch(0% 0 0/0), 0 0 0 0 oklch(0% 0 0/0); - } - &:is(input[type="checkbox"], input[type="radio"]) { - appearance: none; - &[aria-label]::after { - --tw-content: attr(aria-label); - content: var(--tw-content); - } - } - &:where(input:checked:not(.filter .btn)) { - --btn-color: var(--color-primary); - --btn-fg: var(--color-primary-content); - isolation: isolate; - } - } - &:disabled { - @layer daisyui.l1.l2 { - &:not(.btn-link, .btn-ghost) { - background-color: var(--color-base-content); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--color-base-content) 10%, transparent); - } - box-shadow: none; - } - pointer-events: none; - --btn-border: #0000; - --btn-noise: none; - --btn-fg: var(--color-base-content); - @supports (color: color-mix(in lab, red, red)) { - --btn-fg: color-mix(in oklch, var(--color-base-content) 20%, #0000); - } - } - } - &[disabled] { - @layer daisyui.l1.l2 { - &:not(.btn-link, .btn-ghost) { - background-color: var(--color-base-content); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--color-base-content) 10%, transparent); - } - box-shadow: none; - } - pointer-events: none; - --btn-border: #0000; - --btn-noise: none; - --btn-fg: var(--color-base-content); - @supports (color: color-mix(in lab, red, red)) { - --btn-fg: color-mix(in oklch, var(--color-base-content) 20%, #0000); - } - } - } - } - .countdown { - &.countdown { - line-height: 1em; - } - @layer daisyui.l1.l2.l3 { - display: inline-flex; - & > * { - visibility: hidden; - position: relative; - display: inline-block; - overflow-y: clip; - transition: width 0.4s ease-out 0.2s; - height: 1em; - --value-v: calc(mod(max(0, var(--value)), 1000)); - --value-hundreds: calc(round(to-zero, var(--value-v) / 100, 1)); - --value-tens: calc(round(to-zero, mod(var(--value-v), 100) / 10, 1)); - --value-ones: calc(mod(var(--value-v), 100)); - --show-hundreds: clamp(clamp(0, var(--digits, 1) - 2, 1), var(--value-hundreds), 1); - --show-tens: clamp( - clamp(0, var(--digits, 1) - 1, 1), - var(--value-tens) + var(--show-hundreds), - 1 - ); - --first-digits: calc(round(to-zero, var(--value-v) / 10, 1)); - width: calc(1ch + var(--show-tens) * 1ch + var(--show-hundreds) * 1ch); - direction: ltr; - &:before, &:after { - visibility: visible; - position: absolute; - overflow-x: clip; - --tw-content: "00\A 01\A 02\A 03\A 04\A 05\A 06\A 07\A 08\A 09\A 10\A 11\A 12\A 13\A 14\A 15\A 16\A 17\A 18\A 19\A 20\A 21\A 22\A 23\A 24\A 25\A 26\A 27\A 28\A 29\A 30\A 31\A 32\A 33\A 34\A 35\A 36\A 37\A 38\A 39\A 40\A 41\A 42\A 43\A 44\A 45\A 46\A 47\A 48\A 49\A 50\A 51\A 52\A 53\A 54\A 55\A 56\A 57\A 58\A 59\A 60\A 61\A 62\A 63\A 64\A 65\A 66\A 67\A 68\A 69\A 70\A 71\A 72\A 73\A 74\A 75\A 76\A 77\A 78\A 79\A 80\A 81\A 82\A 83\A 84\A 85\A 86\A 87\A 88\A 89\A 90\A 91\A 92\A 93\A 94\A 95\A 96\A 97\A 98\A 99\A"; - content: var(--tw-content); - font-variant-numeric: tabular-nums; - white-space: pre; - text-align: end; - direction: rtl; - transition: all 1s cubic-bezier(1, 0, 0, 1), width 0.2s ease-out 0.2s, opacity 0.2s ease-out 0.2s; - } - &:before { - width: calc(1ch + var(--show-hundreds) * 1ch); - top: calc(var(--first-digits) * -1em); - inset-inline-end: 0; - opacity: var(--show-tens); - } - &:after { - width: 1ch; - top: calc(var(--value-ones) * -1em); - inset-inline-start: 0; - } - } - } - } - .input { - @layer daisyui.l1.l2.l3 { - cursor: text; - border: var(--border) solid #0000; - position: relative; - display: inline-flex; - flex-shrink: 1; - appearance: none; - align-items: center; - gap: calc(0.25rem * 2); - background-color: var(--color-base-100); - padding-inline: calc(0.25rem * 3); - vertical-align: middle; - white-space: nowrap; - width: clamp(3rem, 20rem, 100%); - height: var(--size); - font-size: max(var(--font-size, 0.875rem), 0.875rem); - touch-action: manipulation; - border-start-start-radius: var(--join-ss, var(--radius-field)); - border-start-end-radius: var(--join-se, var(--radius-field)); - border-end-start-radius: var(--join-es, var(--radius-field)); - border-end-end-radius: var(--join-ee, var(--radius-field)); - border-color: var(--input-color); - box-shadow: 0 1px var(--input-color) inset, 0 -1px oklch(100% 0 0 / calc(var(--depth) * 0.1)) inset; - @supports (color: color-mix(in lab, red, red)) { - box-shadow: 0 1px color-mix(in oklab, var(--input-color) calc(var(--depth) * 10%), #0000) inset, 0 -1px oklch(100% 0 0 / calc(var(--depth) * 0.1)) inset; - } - --size: calc(var(--size-field, 0.25rem) * 10); - --input-color: var(--color-base-content); - @supports (color: color-mix(in lab, red, red)) { - --input-color: color-mix(in oklab, var(--color-base-content) 20%, #0000); - } - &:where(input) { - display: inline-flex; - } - :where(input) { - display: inline-flex; - height: 100%; - width: 100%; - appearance: none; - background-color: transparent; - border: none; - &:focus, &:focus-within { - --tw-outline-style: none; - outline-style: none; - @media (forced-colors: active) { - outline: 2px solid transparent; - outline-offset: 2px; - } - } - } - :where(input[type="url"]), :where(input[type="email"]) { - direction: ltr; - } - :where(input[type="date"]) { - display: inline-flex; - } - &:focus, &:focus-within { - --input-color: var(--color-base-content); - box-shadow: 0 1px var(--input-color); - @supports (color: color-mix(in lab, red, red)) { - box-shadow: 0 1px color-mix(in oklab, var(--input-color) calc(var(--depth) * 10%), #0000); - } - outline: 2px solid var(--input-color); - outline-offset: 2px; - isolation: isolate; - z-index: 1; - } - @media (pointer: coarse) { - @supports (-webkit-touch-callout: none) { - &:focus, &:focus-within { - --font-size: 1rem; - } - } - } - &:has(> input[disabled]), &:is(:disabled, [disabled]), fieldset:disabled & { - cursor: not-allowed; - border-color: var(--color-base-200); - background-color: var(--color-base-200); - color: var(--color-base-content); - @supports (color: color-mix(in lab, red, red)) { - color: color-mix(in oklab, var(--color-base-content) 40%, transparent); - } - &::placeholder { - color: var(--color-base-content); - @supports (color: color-mix(in lab, red, red)) { - color: color-mix(in oklab, var(--color-base-content) 20%, transparent); - } - } - box-shadow: none; - } - &:has(> input[disabled]) > input[disabled] { - cursor: not-allowed; - } - &::-webkit-date-and-time-value { - text-align: inherit; - } - &[type="number"] { - &::-webkit-inner-spin-button { - margin-block: calc(0.25rem * -3); - margin-inline-end: calc(0.25rem * -3); - } - } - &::-webkit-calendar-picker-indicator { - position: absolute; - inset-inline-end: 0.75em; - } - &:has(> input[type="date"]) { - :where(input[type="date"]) { - display: inline-flex; - webkit-appearance: none; - appearance: none; - } - input[type="date"]::-webkit-calendar-picker-indicator { - position: absolute; - inset-inline-end: 0.75em; - width: 1em; - height: 1em; - cursor: pointer; - } - } - } - } - .range { - @layer daisyui.l1.l2.l3 { - appearance: none; - webkit-appearance: none; - --range-thumb: var(--color-base-100); - --range-thumb-size: calc(var(--size-selector, 0.25rem) * 6); - --range-progress: currentColor; - --range-fill: 1; - --range-p: 0.25rem; - --range-bg: currentColor; - @supports (color: color-mix(in lab, red, red)) { - --range-bg: color-mix(in oklab, currentColor 10%, #0000); - } - cursor: pointer; - overflow: hidden; - background-color: transparent; - vertical-align: middle; - width: clamp(3rem, 20rem, 100%); - --radius-selector-max: calc( - var(--radius-selector) + var(--radius-selector) + var(--radius-selector) - ); - border-radius: calc(var(--radius-selector) + min(var(--range-p), var(--radius-selector-max))); - border: none; - height: var(--range-thumb-size); - [dir="rtl"] & { - --range-dir: -1; - } - &:focus { - outline: none; - } - &:focus-visible { - outline: 2px solid; - outline-offset: 2px; - } - &::-webkit-slider-runnable-track { - width: 100%; - background-color: var(--range-bg); - border-radius: var(--radius-selector); - height: calc(var(--range-thumb-size) * 0.5); - } - @media (forced-colors: active) { - &::-webkit-slider-runnable-track { - border: 1px solid; - } - } - @media (forced-colors: active) { - &::-moz-range-track { - border: 1px solid; - } - } - &::-webkit-slider-thumb { - position: relative; - box-sizing: border-box; - border-radius: calc(var(--radius-selector) + min(var(--range-p), var(--radius-selector-max))); - background-color: var(--range-thumb); - height: var(--range-thumb-size); - width: var(--range-thumb-size); - border: var(--range-p) solid; - appearance: none; - webkit-appearance: none; - top: 50%; - color: var(--range-progress); - transform: translateY(-50%); - box-shadow: 0 -1px oklch(0% 0 0 / calc(var(--depth) * 0.1)) inset, 0 8px 0 -4px oklch(100% 0 0 / calc(var(--depth) * 0.1)) inset, 0 1px currentColor, 0 0 0 2rem var(--range-thumb) inset, calc((var(--range-dir, 1) * -100rem) - (var(--range-dir, 1) * var(--range-thumb-size) / 2)) 0 0 calc(100rem * var(--range-fill)); - @supports (color: color-mix(in lab, red, red)) { - box-shadow: 0 -1px oklch(0% 0 0 / calc(var(--depth) * 0.1)) inset, 0 8px 0 -4px oklch(100% 0 0 / calc(var(--depth) * 0.1)) inset, 0 1px color-mix(in oklab, currentColor calc(var(--depth) * 10%), #0000), 0 0 0 2rem var(--range-thumb) inset, calc((var(--range-dir, 1) * -100rem) - (var(--range-dir, 1) * var(--range-thumb-size) / 2)) 0 0 calc(100rem * var(--range-fill)); - } - } - &::-moz-range-track { - width: 100%; - background-color: var(--range-bg); - border-radius: var(--radius-selector); - height: calc(var(--range-thumb-size) * 0.5); - } - &::-moz-range-thumb { - position: relative; - box-sizing: border-box; - border-radius: calc(var(--radius-selector) + min(var(--range-p), var(--radius-selector-max))); - background-color: currentColor; - height: var(--range-thumb-size); - width: var(--range-thumb-size); - border: var(--range-p) solid; - top: 50%; - color: var(--range-progress); - box-shadow: 0 -1px oklch(0% 0 0 / calc(var(--depth) * 0.1)) inset, 0 8px 0 -4px oklch(100% 0 0 / calc(var(--depth) * 0.1)) inset, 0 1px currentColor, 0 0 0 2rem var(--range-thumb) inset, calc((var(--range-dir, 1) * -100rem) - (var(--range-dir, 1) * var(--range-thumb-size) / 2)) 0 0 calc(100rem * var(--range-fill)); - @supports (color: color-mix(in lab, red, red)) { - box-shadow: 0 -1px oklch(0% 0 0 / calc(var(--depth) * 0.1)) inset, 0 8px 0 -4px oklch(100% 0 0 / calc(var(--depth) * 0.1)) inset, 0 1px color-mix(in oklab, currentColor calc(var(--depth) * 10%), #0000), 0 0 0 2rem var(--range-thumb) inset, calc((var(--range-dir, 1) * -100rem) - (var(--range-dir, 1) * var(--range-thumb-size) / 2)) 0 0 calc(100rem * var(--range-fill)); - } - } - &:disabled { - cursor: not-allowed; - opacity: 30%; - } - } - } - .select { - @layer daisyui.l1.l2.l3 { - border: var(--border) solid #0000; - position: relative; - display: inline-flex; - flex-shrink: 1; - appearance: none; - align-items: center; - gap: calc(0.25rem * 1.5); - background-color: var(--color-base-100); - padding-inline-start: calc(0.25rem * 3); - padding-inline-end: calc(0.25rem * 7); - vertical-align: middle; - width: clamp(3rem, 20rem, 100%); - height: var(--size); - font-size: 0.875rem; - touch-action: manipulation; - border-start-start-radius: var(--join-ss, var(--radius-field)); - border-start-end-radius: var(--join-se, var(--radius-field)); - border-end-start-radius: var(--join-es, var(--radius-field)); - border-end-end-radius: var(--join-ee, var(--radius-field)); - background-image: linear-gradient(45deg, #0000 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, #0000 50%); - background-position: calc(100% - 20px) calc(1px + 50%), calc(100% - 16.1px) calc(1px + 50%); - background-size: 4px 4px, 4px 4px; - background-repeat: no-repeat; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - box-shadow: 0 1px var(--input-color) inset, 0 -1px oklch(100% 0 0 / calc(var(--depth) * 0.1)) inset; - @supports (color: color-mix(in lab, red, red)) { - box-shadow: 0 1px color-mix(in oklab, var(--input-color) calc(var(--depth) * 10%), #0000) inset, 0 -1px oklch(100% 0 0 / calc(var(--depth) * 0.1)) inset; - } - border-color: var(--input-color); - --input-color: var(--color-base-content); - @supports (color: color-mix(in lab, red, red)) { - --input-color: color-mix(in oklab, var(--color-base-content) 20%, #0000); - } - --size: calc(var(--size-field, 0.25rem) * 10); - [dir="rtl"] & { - background-position: calc(0% + 12px) calc(1px + 50%), calc(0% + 16px) calc(1px + 50%); - &::picker(select), select::picker(select) { - translate: 0.5rem 0; - } - } - &[multiple] { - height: auto; - overflow: auto; - padding-block: calc(0.25rem * 3); - padding-inline-end: calc(0.25rem * 3); - background-image: none; - } - select { - margin-inline-start: calc(0.25rem * -3); - margin-inline-end: calc(0.25rem * -7); - width: calc(100% + 2.75rem); - appearance: none; - padding-inline-start: calc(0.25rem * 3); - padding-inline-end: calc(0.25rem * 7); - height: calc(100% - calc(var(--border) * 2)); - align-items: center; - background: inherit; - border-radius: inherit; - border-style: none; - &:focus, &:focus-within { - --tw-outline-style: none; - outline-style: none; - @media (forced-colors: active) { - outline: 2px solid transparent; - outline-offset: 2px; - } - } - &:not(:last-child) { - margin-inline-end: calc(0.25rem * -5.5); - background-image: none; - } - } - &:focus, &:focus-within { - --input-color: var(--color-base-content); - box-shadow: 0 1px var(--input-color); - @supports (color: color-mix(in lab, red, red)) { - box-shadow: 0 1px color-mix(in oklab, var(--input-color) calc(var(--depth) * 10%), #0000); - } - outline: 2px solid var(--input-color); - outline-offset: 2px; - isolation: isolate; - z-index: 1; - } - &:has(> select[disabled]), &:is(:disabled, [disabled]), fieldset:disabled & { - cursor: not-allowed; - border-color: var(--color-base-200); - background-color: var(--color-base-200); - color: var(--color-base-content); - @supports (color: color-mix(in lab, red, red)) { - color: color-mix(in oklab, var(--color-base-content) 40%, transparent); - } - &::placeholder { - color: var(--color-base-content); - @supports (color: color-mix(in lab, red, red)) { - color: color-mix(in oklab, var(--color-base-content) 20%, transparent); - } - } - } - &:has(> select[disabled]) > select[disabled] { - cursor: not-allowed; - } - &, & select { - @supports (appearance: base-select) { - appearance: base-select; - } - @supports (appearance: base-select) { - &::picker(select) { - appearance: base-select; - } - } - &::picker(select) { - color: inherit; - max-height: min(24rem, 70dvh); - margin-inline: 0.5rem; - translate: -0.5rem 0; - border: var(--border) solid var(--color-base-200); - margin-block: calc(0.25rem * 2); - border-radius: var(--radius-box); - padding: calc(0.25rem * 2); - background-color: inherit; - box-shadow: 0 2px calc(var(--depth) * 3px) -2px oklch(0% 0 0/0.2); - box-shadow: 0 20px 25px -5px rgb(0 0 0 / calc(var(--depth) * 0.1)), 0 8px 10px -6px rgb(0 0 0 / calc(var(--depth) * 0.1)); - } - &::picker-icon { - display: none; - } - optgroup { - padding-top: 0.5em; - option { - &:nth-child(1) { - margin-top: 0.5em; - } - } - } - option { - border-radius: var(--radius-field); - padding-inline: calc(0.25rem * 3); - padding-block: calc(0.25rem * 1.5); - transition-property: color, background-color; - transition-duration: 0.2s; - transition-timing-function: cubic-bezier(0, 0, 0.2, 1); - white-space: normal; - &:not(:disabled) { - &:hover, &:focus-visible { - cursor: pointer; - background-color: var(--color-base-content); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--color-base-content) 10%, transparent); - } - --tw-outline-style: none; - outline-style: none; - @media (forced-colors: active) { - outline: 2px solid transparent; - outline-offset: 2px; - } - } - &:active { - background-color: var(--color-neutral); - color: var(--color-neutral-content); - box-shadow: 0 2px calc(var(--depth) * 3px) -2px var(--color-neutral); - } - } - } - } - } - } - .progress { - @layer daisyui.l1.l2.l3 { - position: relative; - height: calc(0.25rem * 2); - width: 100%; - appearance: none; - overflow: hidden; - border-radius: var(--radius-box); - background-color: currentcolor; - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, currentcolor 20%, transparent); - } - color: var(--color-base-content); - &:indeterminate { - background-image: repeating-linear-gradient( 90deg, currentColor -1%, currentColor 10%, #0000 10%, #0000 90% ); - background-size: 200%; - background-position-x: 15%; - @media (prefers-reduced-motion: no-preference) { - animation: progress 5s ease-in-out infinite; - } - @supports (-moz-appearance: none) { - &::-moz-progress-bar { - background-color: transparent; - @media (prefers-reduced-motion: no-preference) { - animation: progress 5s ease-in-out infinite; - background-image: repeating-linear-gradient( 90deg, currentColor -1%, currentColor 10%, #0000 10%, #0000 90% ); - background-size: 200%; - background-position-x: 15%; - } - } - } - } - @supports (-moz-appearance: none) { - &::-moz-progress-bar { - border-radius: var(--radius-box); - background-color: currentcolor; - } - } - @supports (-webkit-appearance: none) { - &::-webkit-progress-bar { - border-radius: var(--radius-box); - background-color: transparent; - } - &::-webkit-progress-value { - border-radius: var(--radius-box); - background-color: currentColor; - } - } - } - } - .mx-auto { - margin-inline: auto; - } - .my-2 { - margin-block: calc(var(--spacing) * 2); - } - .my-4 { - margin-block: calc(var(--spacing) * 4); - } - .label { - @layer daisyui.l1.l2.l3 { - display: inline-flex; - align-items: center; - gap: calc(0.25rem * 1.5); - white-space: nowrap; - color: currentcolor; - @supports (color: color-mix(in lab, red, red)) { - color: color-mix(in oklab, currentcolor 60%, transparent); - } - &:has(input) { - cursor: pointer; - } - &:is(.input > *, .select > *) { - display: flex; - height: calc(100% - 0.5rem); - align-items: center; - padding-inline: calc(0.25rem * 3); - white-space: nowrap; - font-size: inherit; - &:first-child { - margin-inline-start: calc(0.25rem * -3); - margin-inline-end: calc(0.25rem * 3); - border-inline-end: var(--border) solid currentColor; - @supports (color: color-mix(in lab, red, red)) { - border-inline-end: var(--border) solid color-mix(in oklab, currentColor 10%, #0000); - } - } - &:last-child { - margin-inline-start: calc(0.25rem * 3); - margin-inline-end: calc(0.25rem * -3); - border-inline-start: var(--border) solid currentColor; - @supports (color: color-mix(in lab, red, red)) { - border-inline-start: var(--border) solid color-mix(in oklab, currentColor 10%, #0000); - } - } - } - } - } - .tabs-box { - @layer daisyui.l1.l2 { - background-color: var(--color-base-200); - padding: calc(0.25rem * 1); - --tabs-box-radius: calc(3 * var(--radius-field)); - border-radius: calc( min(calc(var(--tab-height) / 2), var(--radius-field)) + min(0.25rem, var(--tabs-box-radius)) ); - box-shadow: 0 -0.5px oklch(100% 0 0 / calc(var(--depth) * 0.1)) inset, 0 0.5px oklch(0% 0 0 / calc(var(--depth) * 0.05)) inset; - > .tab { - border-radius: var(--radius-field); - border-style: none; - &:focus-visible, &:is(label:has(:checked:focus-visible)) { - outline-offset: 2px; - } - } - > :is(.tab-active, [aria-selected="true"], [aria-current="true"], [aria-current="page"]):not( .tab-disabled, [disabled] ), > :is(input:checked), > :is(label:has(:checked)) { - background-color: var(--tab-bg, var(--color-base-100)); - box-shadow: 0 1px oklch(100% 0 0 / calc(var(--depth) * 0.1)) inset, 0 1px 1px -1px var(--color-neutral), 0 1px 6px -4px var(--color-neutral); - @supports (color: color-mix(in lab, red, red)) { - box-shadow: 0 1px oklch(100% 0 0 / calc(var(--depth) * 0.1)) inset, 0 1px 1px -1px color-mix(in oklab, var(--color-neutral) calc(var(--depth) * 50%), #0000), 0 1px 6px -4px color-mix(in oklab, var(--color-neutral) calc(var(--depth) * 100%), #0000); - } - @media (forced-colors: active) { - border: 1px solid; - } - } - > .tab-content { - margin-top: calc(0.25rem * 1); - height: calc(100% - var(--tab-height) + var(--border) - 0.5rem); - border-radius: calc( min(calc(var(--tab-height) / 2), var(--radius-field)) + min(0.25rem, var(--tabs-box-radius)) - var(--border) ); - } - } - } - .mt-2 { - margin-top: calc(var(--spacing) * 2); - } - .mt-4 { - margin-top: calc(var(--spacing) * 4); - } - .mt-6 { - margin-top: calc(var(--spacing) * 6); - } - .mt-8 { - margin-top: calc(var(--spacing) * 8); - } - .mb-2 { - margin-bottom: calc(var(--spacing) * 2); - } - .mb-4 { - margin-bottom: calc(var(--spacing) * 4); - } - .mb-6 { - margin-bottom: calc(var(--spacing) * 6); - } - .ml-4 { - margin-left: calc(var(--spacing) * 4); - } - .status { - @layer daisyui.l1.l2.l3 { - display: inline-block; - aspect-ratio: 1 / 1; - width: calc(0.25rem * 2); - height: calc(0.25rem * 2); - border-radius: var(--radius-selector); - background-color: var(--color-base-content); - @supports (color: color-mix(in lab, red, red)) { - background-color: color-mix(in oklab, var(--color-base-content) 20%, transparent); - } - background-position: center; - background-repeat: no-repeat; - vertical-align: middle; - color: color-mix(in srgb, #000 30%, transparent); - @supports (color: color-mix(in lab, red, red)) { - color: color-mix(in oklab, var(--color-black) 30%, transparent); - } - background-image: radial-gradient( circle at 35% 30%, oklch(1 0 0 / calc(var(--depth) * 0.5)), #0000 ); - box-shadow: 0 2px 3px -1px currentColor; - @supports (color: color-mix(in lab, red, red)) { - box-shadow: 0 2px 3px -1px color-mix(in oklab, currentColor calc(var(--depth) * 100%), #0000); - } - } - } - .tabs { - @layer daisyui.l1.l2.l3 { - display: flex; - flex-wrap: wrap; - --tabs-height: auto; - --tabs-direction: row; - --tab-height: calc(var(--size-field, 0.25rem) * 10); - height: var(--tabs-height); - flex-direction: var(--tabs-direction); - } - } - .alert { - border-width: var(--border); - border-color: var(--alert-border-color, var(--color-base-200)); - @layer daisyui.l1.l2.l3 { - border-style: solid; - --alert-border-color: var(--color-base-200); - display: grid; - align-items: center; - gap: calc(0.25rem * 4); - border-radius: var(--radius-box); - padding-inline: calc(0.25rem * 4); - padding-block: calc(0.25rem * 3); - color: var(--color-base-content); - background-color: var(--alert-color, var(--color-base-200)); - justify-content: start; - justify-items: start; - grid-auto-flow: column; - grid-template-columns: auto; - text-align: start; - font-size: 0.875rem; - line-height: 1.25rem; - background-size: auto, calc(var(--noise) * 100%); - background-image: none, var(--fx-noise); - box-shadow: 0 3px 0 -2px oklch(100% 0 0 / calc(var(--depth) * 0.08)) inset, 0 1px #000, 0 4px 3px -2px oklch(0% 0 0 / calc(var(--depth) * 0.08)); - @supports (color: color-mix(in lab, red, red)) { - box-shadow: 0 3px 0 -2px oklch(100% 0 0 / calc(var(--depth) * 0.08)) inset, 0 1px color-mix( in oklab, color-mix(in oklab, #000 20%, var(--alert-color, var(--color-base-200))) calc(var(--depth) * 20%), #0000 ), 0 4px 3px -2px oklch(0% 0 0 / calc(var(--depth) * 0.08)); - } - &:has(:nth-child(2)) { - grid-template-columns: auto minmax(auto, 1fr); - } - } - } - .fieldset { - @layer daisyui.l1.l2.l3 { - display: grid; - gap: calc(0.25rem * 1.5); - padding-block: calc(0.25rem * 1); - font-size: 0.75rem; - grid-template-columns: 1fr; - grid-auto-rows: max-content; - } - } - .join { - display: inline-flex; - align-items: stretch; - --join-ss: 0; - --join-se: 0; - --join-es: 0; - --join-ee: 0; - :where(.join-item) { - border-start-start-radius: var(--join-ss, 0); - border-start-end-radius: var(--join-se, 0); - border-end-start-radius: var(--join-es, 0); - border-end-end-radius: var(--join-ee, 0); - * { - --join-ss: var(--radius-field); - --join-se: var(--radius-field); - --join-es: var(--radius-field); - --join-ee: var(--radius-field); - } - } - > .join-item:where(:first-child) { - --join-ss: var(--radius-field); - --join-se: 0; - --join-es: var(--radius-field); - --join-ee: 0; - } - :first-child:not(:last-child) { - :where(.join-item) { - --join-ss: var(--radius-field); - --join-se: 0; - --join-es: var(--radius-field); - --join-ee: 0; - } - } - > .join-item:where(:last-child) { - --join-ss: 0; - --join-se: var(--radius-field); - --join-es: 0; - --join-ee: var(--radius-field); - } - :last-child:not(:first-child) { - :where(.join-item) { - --join-ss: 0; - --join-se: var(--radius-field); - --join-es: 0; - --join-ee: var(--radius-field); - } - } - > .join-item:where(:only-child) { - --join-ss: var(--radius-field); - --join-se: var(--radius-field); - --join-es: var(--radius-field); - --join-ee: var(--radius-field); - } - :only-child { - :where(.join-item) { - --join-ss: var(--radius-field); - --join-se: var(--radius-field); - --join-es: var(--radius-field); - --join-ee: var(--radius-field); - } - } - } - .flex { - display: flex; - } - .grid { - display: grid; - } - .btn-square { - @layer daisyui.l1.l2 { - padding-inline: calc(0.25rem * 0); - width: var(--size); - height: var(--size); - } - } - .w-full { - width: 100%; - } - .max-w-md { - max-width: var(--container-md); - } - .max-w-sm { - max-width: var(--container-sm); - } - .flex-1 { - flex: 1; - } - .link { - @layer daisyui.l1.l2.l3 { - cursor: pointer; - text-decoration-line: underline; - &:focus { - --tw-outline-style: none; - outline-style: none; - @media (forced-colors: active) { - outline: 2px solid transparent; - outline-offset: 2px; - } - } - &:focus-visible { - outline: 2px solid currentColor; - outline-offset: 2px; - } - } - } - .flex-col { - flex-direction: column; - } - .flex-wrap { - flex-wrap: wrap; - } - .items-center { - align-items: center; - } - .justify-between { - justify-content: space-between; - } - .justify-center { - justify-content: center; - } - .gap-1 { - gap: calc(var(--spacing) * 1); - } - .gap-2 { - gap: calc(var(--spacing) * 2); - } - .gap-4 { - gap: calc(var(--spacing) * 4); - } - .gap-8 { - gap: calc(var(--spacing) * 8); - } - .rounded-lg { - border-radius: var(--radius-lg); - } - .border-none { - --tw-border-style: none; - border-style: none; - } - .bg-base-200 { - background-color: var(--color-base-200); - } - .bg-white { - background-color: var(--color-white); - } - .p-2 { - padding: calc(var(--spacing) * 2); - } - .p-3 { - padding: calc(var(--spacing) * 3); - } - .p-4 { - padding: calc(var(--spacing) * 4); - } - .px-2 { - padding-inline: calc(var(--spacing) * 2); - } - .py-1 { - padding-block: calc(var(--spacing) * 1); - } - .text-center { - text-align: center; - } - .text-left { - text-align: left; - } - .font-mono { - font-family: var(--font-mono); - } - .text-3xl { - font-size: var(--text-3xl); - line-height: var(--tw-leading, var(--text-3xl--line-height)); - } - .text-lg { - font-size: var(--text-lg); - line-height: var(--tw-leading, var(--text-lg--line-height)); - } - .text-sm { - font-size: var(--text-sm); - line-height: var(--tw-leading, var(--text-sm--line-height)); - } - .text-xl { - font-size: var(--text-xl); - line-height: var(--tw-leading, var(--text-xl--line-height)); - } - .text-xs { - font-size: var(--text-xs); - line-height: var(--tw-leading, var(--text-xs--line-height)); - } - .font-bold { - --tw-font-weight: var(--font-weight-bold); - font-weight: var(--font-weight-bold); - } - .break-all { - word-break: break-all; - } - .alert-error { - @layer daisyui.l1.l2 { - color: var(--color-error-content); - --alert-border-color: var(--color-error); - --alert-color: var(--color-error); - } - } - .alert-info { - @layer daisyui.l1.l2 { - color: var(--color-info-content); - --alert-border-color: var(--color-info); - --alert-color: var(--color-info); - } - } - .alert-success { - @layer daisyui.l1.l2 { - color: var(--color-success-content); - --alert-border-color: var(--color-success); - --alert-color: var(--color-success); - } - } - .alert-warning { - @layer daisyui.l1.l2 { - color: var(--color-warning-content); - --alert-border-color: var(--color-warning); - --alert-color: var(--color-warning); - } - } - .text-base-content { - color: var(--color-base-content); - } - .text-gray-800 { - color: var(--color-gray-800); - } - .text-success { - color: var(--color-success); - } - .no-underline { - text-decoration-line: none; - } - .opacity-40 { - opacity: 40%; - } - .opacity-60 { - opacity: 60%; - } - .btn-ghost { - @layer daisyui.l1 { - &:not(.btn-active, :hover, :active:focus, :focus-visible, input:checked:not(.filter .btn)) { - --btn-shadow: ""; - --btn-bg: #0000; - --btn-border: #0000; - --btn-noise: none; - &:not(:disabled, [disabled], .btn-disabled) { - outline-color: currentcolor; - --btn-fg: var(--btn-color, currentColor); - } - } - @media (hover: none) { - &:not(.btn-active, :active, :focus-visible, input:checked:not(.filter .btn)):hover { - outline-color: currentcolor; - --btn-shadow: ""; - --btn-bg: #0000; - --btn-fg: var(--btn-color, currentColor); - --btn-border: #0000; - --btn-noise: none; - } - } - } - } - .transition-colors { - transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to; - transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); - transition-duration: var(--tw-duration, var(--default-transition-duration)); - } - .btn-sm { - @layer daisyui.l1.l2 { - --fontsize: 0.75rem; - --btn-p: 0.75rem; - --size: calc(var(--size-field, 0.25rem) * 8); - } - } - .btn-primary { - @layer daisyui.l1.l2.l3 { - --btn-color: var(--color-primary); - --btn-fg: var(--color-primary-content); - } - } - .btn-secondary { - @layer daisyui.l1.l2.l3 { - --btn-color: var(--color-secondary); - --btn-fg: var(--color-secondary-content); - } - } - .hover\:bg-base-300 { - &:hover { - @media (hover: hover) { - background-color: var(--color-base-300); - } - } - } - .hover\:btn-error { - &:hover { - @media (hover: hover) { - @layer daisyui.l1.l2.l3 { - --btn-color: var(--color-error); - --btn-fg: var(--color-error-content); - } - } - } - } -} -.board { - display: flex; - gap: 8px; - background: #2563eb; - padding: 16px; - border-radius: 12px; -} -.column { - display: flex; - flex-direction: column; - gap: 8px; - padding: 4px; - border-radius: 8px; -} -.column.clickable { - cursor: pointer; -} -.column.clickable:hover { - background: rgba(255,255,255,0.15); -} -.cell { - width: 48px; - height: 48px; - border-radius: 50%; - background: #1e40af; - transition: background 0.2s; -} -.cell.red { - background: #dc2626; -} -.cell.yellow { - background: #facc15; -} -.cell.winning { - animation: pulse 0.5s ease-in-out infinite alternate; -} -@keyframes pulse { - from { - transform: scale(1); - box-shadow: 0 0 10px rgba(255,255,255,0.5); - } - to { - transform: scale(1.1); - box-shadow: 0 0 20px rgba(255,255,255,0.8); - } -} -.player-chip { - width: 20px; - height: 20px; - border-radius: 50%; - background: #666; -} -.player-chip.red { - background: #dc2626; -} -.player-chip.yellow { - background: #facc15; -} -.snake-board { - display: inline-grid; - gap: 0; - background: #1a1a2e; - border-radius: 8px; - overflow: hidden; - border: 3px solid #333; -} -.snake-row { - display: contents; -} -.snake-cell { - background: #16213e; - border: 1px solid rgba(255,255,255,0.03); - transition: background 0.05s; -} -.snake-cell.snake-food { - background: #ff6b6b; - border-radius: 50%; - box-shadow: 0 0 6px rgba(255,107,107,0.6); -} -.snake-cell.snake-head { - border-radius: 4px; -} -.snake-cell.snake-dead { - opacity: 0.35; -} -.snake-wrapper:focus { - outline: none; -} -@layer base { - :where(:root),:root:has(input.theme-controller[value=light]:checked),[data-theme=light] { - color-scheme: light; - --color-base-100: oklch(100% 0 0); - --color-base-200: oklch(98% 0 0); - --color-base-300: oklch(95% 0 0); - --color-base-content: oklch(21% 0.006 285.885); - --color-primary: oklch(45% 0.24 277.023); - --color-primary-content: oklch(93% 0.034 272.788); - --color-secondary: oklch(65% 0.241 354.308); - --color-secondary-content: oklch(94% 0.028 342.258); - --color-accent: oklch(77% 0.152 181.912); - --color-accent-content: oklch(38% 0.063 188.416); - --color-neutral: oklch(14% 0.005 285.823); - --color-neutral-content: oklch(92% 0.004 286.32); - --color-info: oklch(74% 0.16 232.661); - --color-info-content: oklch(29% 0.066 243.157); - --color-success: oklch(76% 0.177 163.223); - --color-success-content: oklch(37% 0.077 168.94); - --color-warning: oklch(82% 0.189 84.429); - --color-warning-content: oklch(41% 0.112 45.904); - --color-error: oklch(71% 0.194 13.428); - --color-error-content: oklch(27% 0.105 12.094); - --radius-selector: 0.5rem; - --radius-field: 0.25rem; - --radius-box: 0.5rem; - --size-selector: 0.25rem; - --size-field: 0.25rem; - --border: 1px; - --depth: 1; - --noise: 0; - } -} -@layer base { - @media (prefers-color-scheme: dark) { - :root:not([data-theme]) { - color-scheme: dark; - --color-base-100: oklch(25.33% 0.016 252.42); - --color-base-200: oklch(23.26% 0.014 253.1); - --color-base-300: oklch(21.15% 0.012 254.09); - --color-base-content: oklch(97.807% 0.029 256.847); - --color-primary: oklch(58% 0.233 277.117); - --color-primary-content: oklch(96% 0.018 272.314); - --color-secondary: oklch(65% 0.241 354.308); - --color-secondary-content: oklch(94% 0.028 342.258); - --color-accent: oklch(77% 0.152 181.912); - --color-accent-content: oklch(38% 0.063 188.416); - --color-neutral: oklch(14% 0.005 285.823); - --color-neutral-content: oklch(92% 0.004 286.32); - --color-info: oklch(74% 0.16 232.661); - --color-info-content: oklch(29% 0.066 243.157); - --color-success: oklch(76% 0.177 163.223); - --color-success-content: oklch(37% 0.077 168.94); - --color-warning: oklch(82% 0.189 84.429); - --color-warning-content: oklch(41% 0.112 45.904); - --color-error: oklch(71% 0.194 13.428); - --color-error-content: oklch(27% 0.105 12.094); - --radius-selector: 0.5rem; - --radius-field: 0.25rem; - --radius-box: 0.5rem; - --size-selector: 0.25rem; - --size-field: 0.25rem; - --border: 1px; - --depth: 1; - --noise: 0; - } - } -} -@layer base { - :root:has(input.theme-controller[value=light]:checked),[data-theme=light] { - color-scheme: light; - --color-base-100: oklch(100% 0 0); - --color-base-200: oklch(98% 0 0); - --color-base-300: oklch(95% 0 0); - --color-base-content: oklch(21% 0.006 285.885); - --color-primary: oklch(45% 0.24 277.023); - --color-primary-content: oklch(93% 0.034 272.788); - --color-secondary: oklch(65% 0.241 354.308); - --color-secondary-content: oklch(94% 0.028 342.258); - --color-accent: oklch(77% 0.152 181.912); - --color-accent-content: oklch(38% 0.063 188.416); - --color-neutral: oklch(14% 0.005 285.823); - --color-neutral-content: oklch(92% 0.004 286.32); - --color-info: oklch(74% 0.16 232.661); - --color-info-content: oklch(29% 0.066 243.157); - --color-success: oklch(76% 0.177 163.223); - --color-success-content: oklch(37% 0.077 168.94); - --color-warning: oklch(82% 0.189 84.429); - --color-warning-content: oklch(41% 0.112 45.904); - --color-error: oklch(71% 0.194 13.428); - --color-error-content: oklch(27% 0.105 12.094); - --radius-selector: 0.5rem; - --radius-field: 0.25rem; - --radius-box: 0.5rem; - --size-selector: 0.25rem; - --size-field: 0.25rem; - --border: 1px; - --depth: 1; - --noise: 0; - } -} -@layer base { - :root:has(input.theme-controller[value=dark]:checked),[data-theme=dark] { - color-scheme: dark; - --color-base-100: oklch(25.33% 0.016 252.42); - --color-base-200: oklch(23.26% 0.014 253.1); - --color-base-300: oklch(21.15% 0.012 254.09); - --color-base-content: oklch(97.807% 0.029 256.847); - --color-primary: oklch(58% 0.233 277.117); - --color-primary-content: oklch(96% 0.018 272.314); - --color-secondary: oklch(65% 0.241 354.308); - --color-secondary-content: oklch(94% 0.028 342.258); - --color-accent: oklch(77% 0.152 181.912); - --color-accent-content: oklch(38% 0.063 188.416); - --color-neutral: oklch(14% 0.005 285.823); - --color-neutral-content: oklch(92% 0.004 286.32); - --color-info: oklch(74% 0.16 232.661); - --color-info-content: oklch(29% 0.066 243.157); - --color-success: oklch(76% 0.177 163.223); - --color-success-content: oklch(37% 0.077 168.94); - --color-warning: oklch(82% 0.189 84.429); - --color-warning-content: oklch(41% 0.112 45.904); - --color-error: oklch(71% 0.194 13.428); - --color-error-content: oklch(27% 0.105 12.094); - --radius-selector: 0.5rem; - --radius-field: 0.25rem; - --radius-box: 0.5rem; - --size-selector: 0.25rem; - --size-field: 0.25rem; - --border: 1px; - --depth: 1; - --noise: 0; - } -} -@layer base { - :root { - --fx-noise: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.34' numOctaves='4' stitchTiles='stitch'%3E%3C/feTurbulence%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23a)' opacity='0.2'%3E%3C/rect%3E%3C/svg%3E"); - } -} -@layer base { - :root { - scrollbar-color: currentColor #0000; - @supports (color: color-mix(in lab, red, red)) { - scrollbar-color: color-mix(in oklch, currentColor 35%, #0000) #0000; - } - } -} -@layer base { - @property --radialprogress { - syntax: ""; - inherits: true; - initial-value: 0%; - } -} -@layer base { - :root:not(span) { - overflow: var(--page-overflow); - } -} -@layer base { - :root { - --page-scroll-bg-on: linear-gradient(var(--root-bg), var(--root-bg)) - var(--root-bg); - @supports (color: color-mix(in lab, red, red)) { - --page-scroll-bg-on: linear-gradient(var(--root-bg), var(--root-bg)) - color-mix(in srgb, var(--root-bg), oklch(0% 0 0) calc(var(--page-has-backdrop, 0) * 40%)); - } - --page-scroll-transition-on: background-color 0.3s ease-out; - transition: var(--page-scroll-transition); - scrollbar-gutter: var(--page-scroll-gutter, unset); - scrollbar-gutter: if(style(--page-has-scroll: 1): var(--page-scroll-gutter, unset) ; else: unset); - } - :root:root { - background: var(--page-scroll-bg, var(--root-bg, var(--color-base-100))); - } - @keyframes set-page-has-scroll { - 0%, to { - --page-has-scroll: 1; - } - } -} -@layer base { - :root, [data-theme] { - background-color: var(--root-bg, var(--color-base-100)); - color: var(--color-base-content); - } - :where(:root, [data-theme]) { - --root-bg: var(--color-base-100); - } -} -@keyframes rating { - 0%, 40% { - scale: 1.1; - filter: brightness(1.05) contrast(1.05); - } -} -@keyframes dropdown { - 0% { - opacity: 0; - } -} -@keyframes radio { - 0% { - padding: 5px; - } - 50% { - padding: 3px; - } -} -@keyframes toast { - 0% { - scale: 0.9; - opacity: 0; - } - 100% { - scale: 1; - opacity: 1; - } -} -@keyframes rotator { - 89.9999%, 100% { - --first-item-position: 0 0%; - } - 90%, 99.9999% { - --first-item-position: 0 calc(var(--items) * 100%); - } - 100% { - translate: 0 -100%; - } -} -@keyframes skeleton { - 0% { - background-position: 150%; - } - 100% { - background-position: -50%; - } -} -@keyframes menu { - 0% { - opacity: 0; - } -} -@keyframes progress { - 50% { - background-position-x: -115%; - } -} -@layer base { - :where(:root),:root:has(input.theme-controller[value=connect4]:checked),[data-theme="connect4"] { - color-scheme: light; - --color-base-100: oklch(98% 0.005 90); - --color-base-200: oklch(95% 0.01 90); - --color-base-300: oklch(90% 0.015 85); - --color-base-content: oklch(25% 0.02 50); - --color-primary: oklch(60% 0.22 30); - --color-primary-content: oklch(98% 0.005 90); - --color-secondary: oklch(82% 0.17 85); - --color-secondary-content: oklch(25% 0.02 50); - --color-accent: oklch(65% 0.19 250); - --color-accent-content: oklch(98% 0.005 90); - --color-neutral: oklch(35% 0.03 260); - --color-neutral-content: oklch(95% 0.01 90); - --color-success: oklch(72% 0.19 155); - --color-success-content: oklch(20% 0.04 155); - --color-warning: oklch(82% 0.17 85); - --color-warning-content: oklch(25% 0.04 85); - --color-error: oklch(60% 0.22 30); - --color-error-content: oklch(97% 0.01 30); - --color-info: oklch(70% 0.15 240); - --color-info-content: oklch(20% 0.04 240); - --radius-selector: 0.5rem; - --radius-field: 0.5rem; - --radius-box: 0.75rem; - --border: 1px; - --depth: 1; - --noise: 0; - } -} -@property --tw-font-weight { - syntax: "*"; - inherits: false; -} -@keyframes pulse { - 50% { - opacity: 0.5; - } -} -@layer properties { - @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) { - *, ::before, ::after, ::backdrop { - --tw-font-weight: initial; - } - } -} +@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-font-weight:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-gray-800:oklch(27.8% .033 256.848);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25/1.875);--font-weight-bold:700;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:where(:root),:root:has(input.theme-controller[value=light]:checked),[data-theme=light]{color-scheme:light;--color-base-100:oklch(100% 0 0);--color-base-200:oklch(98% 0 0);--color-base-300:oklch(95% 0 0);--color-base-content:oklch(21% .006 285.885);--color-primary:oklch(45% .24 277.023);--color-primary-content:oklch(93% .034 272.788);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}@media (prefers-color-scheme:dark){:root:not([data-theme]){color-scheme:dark;--color-base-100:oklch(25.33% .016 252.42);--color-base-200:oklch(23.26% .014 253.1);--color-base-300:oklch(21.15% .012 254.09);--color-base-content:oklch(97.807% .029 256.847);--color-primary:oklch(58% .233 277.117);--color-primary-content:oklch(96% .018 272.314);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}}:root:has(input.theme-controller[value=light]:checked),[data-theme=light]{color-scheme:light;--color-base-100:oklch(100% 0 0);--color-base-200:oklch(98% 0 0);--color-base-300:oklch(95% 0 0);--color-base-content:oklch(21% .006 285.885);--color-primary:oklch(45% .24 277.023);--color-primary-content:oklch(93% .034 272.788);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}:root:has(input.theme-controller[value=dark]:checked),[data-theme=dark]{color-scheme:dark;--color-base-100:oklch(25.33% .016 252.42);--color-base-200:oklch(23.26% .014 253.1);--color-base-300:oklch(21.15% .012 254.09);--color-base-content:oklch(97.807% .029 256.847);--color-primary:oklch(58% .233 277.117);--color-primary-content:oklch(96% .018 272.314);--color-secondary:oklch(65% .241 354.308);--color-secondary-content:oklch(94% .028 342.258);--color-accent:oklch(77% .152 181.912);--color-accent-content:oklch(38% .063 188.416);--color-neutral:oklch(14% .005 285.823);--color-neutral-content:oklch(92% .004 286.32);--color-info:oklch(74% .16 232.661);--color-info-content:oklch(29% .066 243.157);--color-success:oklch(76% .177 163.223);--color-success-content:oklch(37% .077 168.94);--color-warning:oklch(82% .189 84.429);--color-warning-content:oklch(41% .112 45.904);--color-error:oklch(71% .194 13.428);--color-error-content:oklch(27% .105 12.094);--radius-selector:.5rem;--radius-field:.25rem;--radius-box:.5rem;--size-selector:.25rem;--size-field:.25rem;--border:1px;--depth:1;--noise:0}:root{--fx-noise:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='a'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.34' numOctaves='4' stitchTiles='stitch'%3E%3C/feTurbulence%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23a)' opacity='0.2'%3E%3C/rect%3E%3C/svg%3E");scrollbar-color:currentColor #0000}@supports (color:color-mix(in lab, red, red)){:root{scrollbar-color:color-mix(in oklch,currentColor 35%,#0000)#0000}}@property --radialprogress{syntax: ""; inherits: true; initial-value: 0%;}:root:not(span){overflow:var(--page-overflow)}:root{--page-scroll-bg-on:linear-gradient(var(--root-bg),var(--root-bg))var(--root-bg)}@supports (color:color-mix(in lab, red, red)){:root{--page-scroll-bg-on:linear-gradient(var(--root-bg),var(--root-bg))color-mix(in srgb,var(--root-bg),oklch(0% 0 0) calc(var(--page-has-backdrop,0)*40%))}}:root{--page-scroll-transition-on:background-color .3s ease-out;transition:var(--page-scroll-transition);scrollbar-gutter:var(--page-scroll-gutter,unset);scrollbar-gutter:if(style(--page-has-scroll: 1): var(--page-scroll-gutter,unset); else: unset)}:root:root{background:var(--page-scroll-bg,var(--root-bg,var(--color-base-100)))}@keyframes set-page-has-scroll{0%,to{--page-has-scroll:1}}:root,[data-theme]{background-color:var(--root-bg,var(--color-base-100));color:var(--color-base-content)}:where(:root,[data-theme]){--root-bg:var(--color-base-100)}:where(:root),:root:has(input.theme-controller[value=connect4]:checked),[data-theme=connect4]{color-scheme:light;--color-base-100:oklch(98% .005 90);--color-base-200:oklch(95% .01 90);--color-base-300:oklch(90% .015 85);--color-base-content:oklch(25% .02 50);--color-primary:oklch(60% .22 30);--color-primary-content:oklch(98% .005 90);--color-secondary:oklch(82% .17 85);--color-secondary-content:oklch(25% .02 50);--color-accent:oklch(65% .19 250);--color-accent-content:oklch(98% .005 90);--color-neutral:oklch(35% .03 260);--color-neutral-content:oklch(95% .01 90);--color-success:oklch(72% .19 155);--color-success-content:oklch(20% .04 155);--color-warning:oklch(82% .17 85);--color-warning-content:oklch(25% .04 85);--color-error:oklch(60% .22 30);--color-error-content:oklch(97% .01 30);--color-info:oklch(70% .15 240);--color-info-content:oklch(20% .04 240);--radius-selector:.5rem;--radius-field:.5rem;--radius-box:.75rem;--border:1px;--depth:1;--noise:0}}@layer components;@layer utilities{@layer daisyui.l1.l2.l3{.tab{cursor:pointer;appearance:none;text-align:center;webkit-user-select:none;-webkit-user-select:none;user-select:none;flex-wrap:wrap;justify-content:center;align-items:center;display:inline-flex;position:relative}@media (hover:hover){.tab:hover{color:var(--color-base-content)}}.tab{--tab-p:.75rem;--tab-bg:var(--color-base-100);--tab-border-color:var(--color-base-300);--tab-radius-ss:0;--tab-radius-se:0;--tab-radius-es:0;--tab-radius-ee:0;--tab-order:0;--tab-radius-min:calc(.75rem - var(--border));--tab-radius-limit:min(var(--radius-field),var(--tab-radius-min));--tab-radius-grad:#0000 calc(69% - var(--border)),var(--tab-border-color)calc(calc(69% - var(--border)) + .25px),var(--tab-border-color)calc(calc(69% - var(--border)) + var(--border)),var(--tab-bg)calc(calc(69% - var(--border)) + var(--border) + .25px);order:var(--tab-order);height:var(--tab-height);border-color:#0000;padding-inline-start:var(--tab-p);padding-inline-end:var(--tab-p);font-size:.875rem}.tab:is(input[type=radio]){min-width:fit-content}.tab:is(input[type=radio]):after{--tw-content:attr(aria-label);content:var(--tw-content)}.tab:is(label){position:relative}.tab:is(label) input{cursor:pointer;appearance:none;opacity:0;position:absolute;inset:0}:is(.tab:checked,.tab:is(label:has(:checked)),.tab:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]))+.tab-content{display:block}.tab:not(:checked,label:has(:checked),:hover,.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]){color:var(--color-base-content)}@supports (color:color-mix(in lab, red, red)){.tab:not(:checked,label:has(:checked),:hover,.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]){color:color-mix(in oklab,var(--color-base-content)50%,transparent)}}.tab:not(input):empty{cursor:default;flex-grow:1}.tab:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.tab:focus{outline-offset:2px;outline:2px solid #0000}}.tab:focus-visible,.tab:is(label:has(:checked:focus-visible)){outline-offset:-5px;outline:2px solid}.tab[disabled]{pointer-events:none;opacity:.4}:where(.btn){width:unset}.btn{cursor:pointer;text-align:center;vertical-align:middle;outline-offset:2px;webkit-user-select:none;-webkit-user-select:none;user-select:none;padding-inline:var(--btn-p);color:var(--btn-fg);--tw-prose-links:var(--btn-fg);height:var(--size);font-size:var(--fontsize,.875rem);outline-color:var(--btn-color,var(--color-base-content));background-color:var(--btn-bg);background-size:auto,calc(var(--noise)*100%);background-image:none,var(--btn-noise);border-width:var(--border);border-style:solid;border-color:var(--btn-border);text-shadow:0 .5px oklch(100% 0 0/calc(var(--depth)*.15));touch-action:manipulation;box-shadow:0 .5px 0 .5px oklch(100% 0 0/calc(var(--depth)*6%))inset,var(--btn-shadow);--size:calc(var(--size-field,.25rem)*10);--btn-bg:var(--btn-color,var(--color-base-200));--btn-fg:var(--color-base-content);--btn-p:1rem;--btn-border:var(--btn-bg);border-start-start-radius:var(--join-ss,var(--radius-field));border-start-end-radius:var(--join-se,var(--radius-field));border-end-end-radius:var(--join-ee,var(--radius-field));border-end-start-radius:var(--join-es,var(--radius-field));flex-wrap:nowrap;flex-shrink:0;justify-content:center;align-items:center;gap:.375rem;font-weight:600;transition-property:color,background-color,border-color,box-shadow;transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1);display:inline-flex}@supports (color:color-mix(in lab, red, red)){.btn{--btn-border:color-mix(in oklab,var(--btn-bg),#000 calc(var(--depth)*5%))}}.btn{--btn-shadow:0 3px 2px -2px var(--btn-bg),0 4px 3px -2px var(--btn-bg)}@supports (color:color-mix(in lab, red, red)){.btn{--btn-shadow:0 3px 2px -2px color-mix(in oklab,var(--btn-bg)calc(var(--depth)*30%),#0000),0 4px 3px -2px color-mix(in oklab,var(--btn-bg)calc(var(--depth)*30%),#0000)}}.btn{--btn-noise:var(--fx-noise)}@media (hover:hover){.btn:hover{--btn-bg:var(--btn-color,var(--color-base-200))}@supports (color:color-mix(in lab, red, red)){.btn:hover{--btn-bg:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 7%)}}}.btn:focus-visible,.btn:has(:focus-visible){isolation:isolate;outline-width:2px;outline-style:solid}.btn:active:not(.btn-active){--btn-bg:var(--btn-color,var(--color-base-200));translate:0 .5px}@supports (color:color-mix(in lab, red, red)){.btn:active:not(.btn-active){--btn-bg:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 5%)}}.btn:active:not(.btn-active){--btn-border:var(--btn-color,var(--color-base-200))}@supports (color:color-mix(in lab, red, red)){.btn:active:not(.btn-active){--btn-border:color-mix(in oklab,var(--btn-color,var(--color-base-200)),#000 7%)}}.btn:active:not(.btn-active){--btn-shadow:0 0 0 0 oklch(0% 0 0/0),0 0 0 0 oklch(0% 0 0/0)}.btn:is(input[type=checkbox],input[type=radio]){appearance:none}.btn:is(input[type=checkbox],input[type=radio])[aria-label]:after{--tw-content:attr(aria-label);content:var(--tw-content)}.btn:where(input:checked:not(.filter .btn)){--btn-color:var(--color-primary);--btn-fg:var(--color-primary-content);isolation:isolate}.countdown{display:inline-flex}.countdown>*{visibility:hidden;--value-v:calc(mod(max(0,var(--value)),1000));--value-hundreds:calc(round(to-zero,var(--value-v)/100,1));--value-tens:calc(round(to-zero,mod(var(--value-v),100)/10,1));--value-ones:calc(mod(var(--value-v),100));--show-hundreds:clamp(clamp(0,var(--digits,1) - 2,1),var(--value-hundreds),1);--show-tens:clamp(clamp(0,var(--digits,1) - 1,1),var(--value-tens) + var(--show-hundreds),1);--first-digits:calc(round(to-zero,var(--value-v)/10,1));height:1em;width:calc(1ch + var(--show-tens)*1ch + var(--show-hundreds)*1ch);direction:ltr;transition:width .4s ease-out .2s;display:inline-block;position:relative;overflow-y:clip}.countdown>:before,.countdown>:after{visibility:visible;--tw-content:"00\a 01\a 02\a 03\a 04\a 05\a 06\a 07\a 08\a 09\a 10\a 11\a 12\a 13\a 14\a 15\a 16\a 17\a 18\a 19\a 20\a 21\a 22\a 23\a 24\a 25\a 26\a 27\a 28\a 29\a 30\a 31\a 32\a 33\a 34\a 35\a 36\a 37\a 38\a 39\a 40\a 41\a 42\a 43\a 44\a 45\a 46\a 47\a 48\a 49\a 50\a 51\a 52\a 53\a 54\a 55\a 56\a 57\a 58\a 59\a 60\a 61\a 62\a 63\a 64\a 65\a 66\a 67\a 68\a 69\a 70\a 71\a 72\a 73\a 74\a 75\a 76\a 77\a 78\a 79\a 80\a 81\a 82\a 83\a 84\a 85\a 86\a 87\a 88\a 89\a 90\a 91\a 92\a 93\a 94\a 95\a 96\a 97\a 98\a 99\a ";content:var(--tw-content);font-variant-numeric:tabular-nums;white-space:pre;text-align:end;direction:rtl;transition:all 1s cubic-bezier(1,0,0,1),width .2s ease-out .2s,opacity .2s ease-out .2s;position:absolute;overflow-x:clip}.countdown>:before{width:calc(1ch + var(--show-hundreds)*1ch);top:calc(var(--first-digits)*-1em);opacity:var(--show-tens);inset-inline-end:0}.countdown>:after{width:1ch;top:calc(var(--value-ones)*-1em);inset-inline-start:0}.input{cursor:text;border:var(--border)solid #0000;appearance:none;background-color:var(--color-base-100);vertical-align:middle;white-space:nowrap;width:clamp(3rem,20rem,100%);height:var(--size);font-size:max(var(--font-size,.875rem),.875rem);touch-action:manipulation;border-color:var(--input-color);box-shadow:0 1px var(--input-color)inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1))inset;border-start-start-radius:var(--join-ss,var(--radius-field));border-start-end-radius:var(--join-se,var(--radius-field));border-end-end-radius:var(--join-ee,var(--radius-field));border-end-start-radius:var(--join-es,var(--radius-field));flex-shrink:1;align-items:center;gap:.5rem;padding-inline:.75rem;display:inline-flex;position:relative}@supports (color:color-mix(in lab, red, red)){.input{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000)inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1))inset}}.input{--size:calc(var(--size-field,.25rem)*10);--input-color:var(--color-base-content)}@supports (color:color-mix(in lab, red, red)){.input{--input-color:color-mix(in oklab,var(--color-base-content)20%,#0000)}}.input:where(input){display:inline-flex}.input :where(input){appearance:none;background-color:#0000;border:none;width:100%;height:100%;display:inline-flex}.input :where(input):focus,.input :where(input):focus-within{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.input :where(input):focus,.input :where(input):focus-within{outline-offset:2px;outline:2px solid #0000}}.input :where(input[type=url]),.input :where(input[type=email]){direction:ltr}.input :where(input[type=date]){display:inline-flex}.input:focus,.input:focus-within{--input-color:var(--color-base-content);box-shadow:0 1px var(--input-color)}@supports (color:color-mix(in lab, red, red)){.input:focus,.input:focus-within{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000)}}.input:focus,.input:focus-within{outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate;z-index:1}@media (pointer:coarse){@supports (-webkit-touch-callout:none){.input:focus,.input:focus-within{--font-size:1rem}}}.input:has(>input[disabled]),.input:is(:disabled,[disabled]),fieldset:disabled .input{cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);color:var(--color-base-content)}@supports (color:color-mix(in lab, red, red)){.input:has(>input[disabled]),.input:is(:disabled,[disabled]),fieldset:disabled .input{color:color-mix(in oklab,var(--color-base-content)40%,transparent)}}:is(.input:has(>input[disabled]),.input:is(:disabled,[disabled]),fieldset:disabled .input)::placeholder{color:var(--color-base-content)}@supports (color:color-mix(in lab, red, red)){:is(.input:has(>input[disabled]),.input:is(:disabled,[disabled]),fieldset:disabled .input)::placeholder{color:color-mix(in oklab,var(--color-base-content)20%,transparent)}}.input:has(>input[disabled]),.input:is(:disabled,[disabled]),fieldset:disabled .input{box-shadow:none}.input:has(>input[disabled])>input[disabled]{cursor:not-allowed}.input::-webkit-date-and-time-value{text-align:inherit}.input[type=number]::-webkit-inner-spin-button{margin-block:-.75rem;margin-inline-end:-.75rem}.input::-webkit-calendar-picker-indicator{position:absolute;inset-inline-end:.75em}.input:has(>input[type=date]) :where(input[type=date]){webkit-appearance:none;appearance:none;display:inline-flex}.input:has(>input[type=date]) input[type=date]::-webkit-calendar-picker-indicator{cursor:pointer;width:1em;height:1em;position:absolute;inset-inline-end:.75em}.steps{counter-reset:step;grid-auto-columns:1fr;grid-auto-flow:column;display:inline-grid;overflow:auto hidden}.steps .step{text-align:center;--step-bg:var(--color-base-300);--step-fg:var(--color-base-content);grid-template-rows:40px 1fr;grid-template-columns:auto;place-items:center;min-width:4rem;display:grid}.steps .step:before{width:100%;height:.5rem;color:var(--step-bg);background-color:var(--step-bg);content:"";border:1px solid;grid-row-start:1;grid-column-start:1;margin-inline-start:-100%;top:0}.steps .step>.step-icon,.steps .step:not(:has(.step-icon)):after{--tw-content:counter(step);content:var(--tw-content);counter-increment:step;z-index:1;color:var(--step-fg);background-color:var(--step-bg);border:1px solid var(--step-bg);border-radius:3.40282e38px;grid-row-start:1;grid-column-start:1;place-self:center;place-items:center;width:2rem;height:2rem;display:grid;position:relative}.steps .step:first-child:before{--tw-content:none;content:var(--tw-content)}.steps .step[data-content]:after{--tw-content:attr(data-content);content:var(--tw-content)}.range{appearance:none;webkit-appearance:none;--range-thumb:var(--color-base-100);--range-thumb-size:calc(var(--size-selector,.25rem)*6);--range-progress:currentColor;--range-fill:1;--range-p:.25rem;--range-bg:currentColor}@supports (color:color-mix(in lab, red, red)){.range{--range-bg:color-mix(in oklab,currentColor 10%,#0000)}}.range{cursor:pointer;vertical-align:middle;--radius-selector-max:calc(var(--radius-selector) + var(--radius-selector) + var(--radius-selector));border-radius:calc(var(--radius-selector) + min(var(--range-p),var(--radius-selector-max)));width:clamp(3rem,20rem,100%);height:var(--range-thumb-size);background-color:#0000;border:none;overflow:hidden}[dir=rtl] .range{--range-dir:-1}.range:focus{outline:none}.range:focus-visible{outline-offset:2px;outline:2px solid}.range::-webkit-slider-runnable-track{background-color:var(--range-bg);border-radius:var(--radius-selector);width:100%;height:calc(var(--range-thumb-size)*.5)}@media (forced-colors:active){.range::-webkit-slider-runnable-track{border:1px solid}.range::-moz-range-track{border:1px solid}}.range::-webkit-slider-thumb{box-sizing:border-box;border-radius:calc(var(--radius-selector) + min(var(--range-p),var(--radius-selector-max)));background-color:var(--range-thumb);height:var(--range-thumb-size);width:var(--range-thumb-size);border:var(--range-p)solid;appearance:none;webkit-appearance:none;color:var(--range-progress);box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1))inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1))inset,0 1px currentColor,0 0 0 2rem var(--range-thumb)inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2))0 0 calc(100rem*var(--range-fill));position:relative;top:50%;transform:translateY(-50%)}@supports (color:color-mix(in lab, red, red)){.range::-webkit-slider-thumb{box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1))inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1))inset,0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000),0 0 0 2rem var(--range-thumb)inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2))0 0 calc(100rem*var(--range-fill))}}.range::-moz-range-track{background-color:var(--range-bg);border-radius:var(--radius-selector);width:100%;height:calc(var(--range-thumb-size)*.5)}.range::-moz-range-thumb{box-sizing:border-box;border-radius:calc(var(--radius-selector) + min(var(--range-p),var(--radius-selector-max)));height:var(--range-thumb-size);width:var(--range-thumb-size);border:var(--range-p)solid;color:var(--range-progress);box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1))inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1))inset,0 1px currentColor,0 0 0 2rem var(--range-thumb)inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2))0 0 calc(100rem*var(--range-fill));background-color:currentColor;position:relative;top:50%}@supports (color:color-mix(in lab, red, red)){.range::-moz-range-thumb{box-shadow:0 -1px oklch(0% 0 0/calc(var(--depth)*.1))inset,0 8px 0 -4px oklch(100% 0 0/calc(var(--depth)*.1))inset,0 1px color-mix(in oklab,currentColor calc(var(--depth)*10%),#0000),0 0 0 2rem var(--range-thumb)inset,calc((var(--range-dir,1)*-100rem) - (var(--range-dir,1)*var(--range-thumb-size)/2))0 0 calc(100rem*var(--range-fill))}}.range:disabled{cursor:not-allowed;opacity:.3}.select{border:var(--border)solid #0000;appearance:none;background-color:var(--color-base-100);vertical-align:middle;width:clamp(3rem,20rem,100%);height:var(--size);touch-action:manipulation;white-space:nowrap;text-overflow:ellipsis;box-shadow:0 1px var(--input-color)inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1))inset;background-image:linear-gradient(45deg,#0000 50%,currentColor 50%),linear-gradient(135deg,currentColor 50%,#0000 50%);background-position:calc(100% - 20px) calc(1px + 50%),calc(100% - 16.1px) calc(1px + 50%);background-repeat:no-repeat;background-size:4px 4px,4px 4px;border-start-start-radius:var(--join-ss,var(--radius-field));border-start-end-radius:var(--join-se,var(--radius-field));border-end-end-radius:var(--join-ee,var(--radius-field));border-end-start-radius:var(--join-es,var(--radius-field));flex-shrink:1;align-items:center;gap:.375rem;padding-inline:.75rem 1.75rem;font-size:.875rem;display:inline-flex;position:relative;overflow:hidden}@supports (color:color-mix(in lab, red, red)){.select{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000)inset,0 -1px oklch(100% 0 0/calc(var(--depth)*.1))inset}}.select{border-color:var(--input-color);--input-color:var(--color-base-content)}@supports (color:color-mix(in lab, red, red)){.select{--input-color:color-mix(in oklab,var(--color-base-content)20%,#0000)}}.select{--size:calc(var(--size-field,.25rem)*10)}[dir=rtl] .select{background-position:12px calc(1px + 50%),16px calc(1px + 50%)}[dir=rtl] .select::picker(select){translate:.5rem}[dir=rtl] .select select::picker(select){translate:.5rem}.select[multiple]{background-image:none;height:auto;padding-block:.75rem;padding-inline-end:.75rem;overflow:auto}.select select{appearance:none;width:calc(100% + 2.75rem);height:calc(100% - calc(var(--border)*2));background:inherit;border-radius:inherit;border-style:none;align-items:center;margin-inline:-.75rem -1.75rem;padding-inline:.75rem 1.75rem}.select select:focus,.select select:focus-within{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.select select:focus,.select select:focus-within{outline-offset:2px;outline:2px solid #0000}}.select select:not(:last-child){background-image:none;margin-inline-end:-1.375rem}.select:focus,.select:focus-within{--input-color:var(--color-base-content);box-shadow:0 1px var(--input-color)}@supports (color:color-mix(in lab, red, red)){.select:focus,.select:focus-within{box-shadow:0 1px color-mix(in oklab,var(--input-color)calc(var(--depth)*10%),#0000)}}.select:focus,.select:focus-within{outline:2px solid var(--input-color);outline-offset:2px;isolation:isolate;z-index:1}.select:has(>select[disabled]),.select:is(:disabled,[disabled]),fieldset:disabled .select{cursor:not-allowed;border-color:var(--color-base-200);background-color:var(--color-base-200);color:var(--color-base-content)}@supports (color:color-mix(in lab, red, red)){.select:has(>select[disabled]),.select:is(:disabled,[disabled]),fieldset:disabled .select{color:color-mix(in oklab,var(--color-base-content)40%,transparent)}}:is(.select:has(>select[disabled]),.select:is(:disabled,[disabled]),fieldset:disabled .select)::placeholder{color:var(--color-base-content)}@supports (color:color-mix(in lab, red, red)){:is(.select:has(>select[disabled]),.select:is(:disabled,[disabled]),fieldset:disabled .select)::placeholder{color:color-mix(in oklab,var(--color-base-content)20%,transparent)}}.select:has(>select[disabled])>select[disabled]{cursor:not-allowed}@supports (appearance:base-select){.select,.select select{appearance:base-select}:is(.select,.select select)::picker(select){appearance:base-select}}:is(.select,.select select)::picker(select){color:inherit;border:var(--border)solid var(--color-base-200);border-radius:var(--radius-box);background-color:inherit;max-height:min(24rem,70dvh);box-shadow:0 2px calc(var(--depth)*3px)-2px oklch(0% 0 0/.2);box-shadow:0 20px 25px -5px rgb(0 0 0/calc(var(--depth)*.1)),0 8px 10px -6px rgb(0 0 0/calc(var(--depth)*.1));margin-block:.5rem;margin-inline:.5rem;padding:.5rem;translate:-.5rem}:is(.select,.select select)::picker-icon{display:none}:is(.select,.select select) optgroup{padding-top:.5em}:is(.select,.select select) optgroup option:first-child{margin-top:.5em}:is(.select,.select select) option{border-radius:var(--radius-field);white-space:normal;padding-block:.375rem;padding-inline:.75rem;transition-property:color,background-color;transition-duration:.2s;transition-timing-function:cubic-bezier(0,0,.2,1)}:is(.select,.select select) option:not(:disabled):hover,:is(.select,.select select) option:not(:disabled):focus-visible{cursor:pointer;background-color:var(--color-base-content)}@supports (color:color-mix(in lab, red, red)){:is(.select,.select select) option:not(:disabled):hover,:is(.select,.select select) option:not(:disabled):focus-visible{background-color:color-mix(in oklab,var(--color-base-content)10%,transparent)}}:is(.select,.select select) option:not(:disabled):hover,:is(.select,.select select) option:not(:disabled):focus-visible{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){:is(.select,.select select) option:not(:disabled):hover,:is(.select,.select select) option:not(:disabled):focus-visible{outline-offset:2px;outline:2px solid #0000}}:is(.select,.select select) option:not(:disabled):active{background-color:var(--color-neutral);color:var(--color-neutral-content);box-shadow:0 2px calc(var(--depth)*3px)-2px var(--color-neutral)}.progress{appearance:none;border-radius:var(--radius-box);background-color:currentColor;width:100%;height:.5rem;position:relative;overflow:hidden}@supports (color:color-mix(in lab, red, red)){.progress{background-color:color-mix(in oklab,currentcolor 20%,transparent)}}.progress{color:var(--color-base-content)}.progress:indeterminate{background-image:repeating-linear-gradient(90deg,currentColor -1% 10%,#0000 10% 90%);background-position-x:15%;background-size:200%}@media (prefers-reduced-motion:no-preference){.progress:indeterminate{animation:5s ease-in-out infinite progress}}@supports ((-moz-appearance:none)){.progress:indeterminate::-moz-progress-bar{background-color:#0000}@media (prefers-reduced-motion:no-preference){.progress:indeterminate::-moz-progress-bar{background-image:repeating-linear-gradient(90deg,currentColor -1% 10%,#0000 10% 90%);background-position-x:15%;background-size:200%;animation:5s ease-in-out infinite progress}}.progress::-moz-progress-bar{border-radius:var(--radius-box);background-color:currentColor}}@supports ((-webkit-appearance:none)){.progress::-webkit-progress-bar{border-radius:var(--radius-box);background-color:#0000}.progress::-webkit-progress-value{border-radius:var(--radius-box);background-color:currentColor}}.label{white-space:nowrap;color:currentColor;align-items:center;gap:.375rem;display:inline-flex}@supports (color:color-mix(in lab, red, red)){.label{color:color-mix(in oklab,currentcolor 60%,transparent)}}.label:has(input){cursor:pointer}.label:is(.input>*,.select>*){white-space:nowrap;height:calc(100% - .5rem);font-size:inherit;align-items:center;padding-inline:.75rem;display:flex}.label:is(.input>*,.select>*):first-child{border-inline-end:var(--border)solid currentColor;margin-inline:-.75rem .75rem}@supports (color:color-mix(in lab, red, red)){.label:is(.input>*,.select>*):first-child{border-inline-end:var(--border)solid color-mix(in oklab,currentColor 10%,#0000)}}.label:is(.input>*,.select>*):last-child{border-inline-start:var(--border)solid currentColor;margin-inline:.75rem -.75rem}@supports (color:color-mix(in lab, red, red)){.label:is(.input>*,.select>*):last-child{border-inline-start:var(--border)solid color-mix(in oklab,currentColor 10%,#0000)}}.status{aspect-ratio:1;border-radius:var(--radius-selector);background-color:var(--color-base-content);width:.5rem;height:.5rem;display:inline-block}@supports (color:color-mix(in lab, red, red)){.status{background-color:color-mix(in oklab,var(--color-base-content)20%,transparent)}}.status{vertical-align:middle;color:#0000004d;background-position:50%;background-repeat:no-repeat}@supports (color:color-mix(in lab, red, red)){.status{color:color-mix(in oklab,var(--color-black)30%,transparent)}}.status{background-image:radial-gradient(circle at 35% 30%,oklch(1 0 0/calc(var(--depth)*.5)),#0000);box-shadow:0 2px 3px -1px}@supports (color:color-mix(in lab, red, red)){.status{box-shadow:0 2px 3px -1px color-mix(in oklab,currentColor calc(var(--depth)*100%),#0000)}}.tabs{--tabs-height:auto;--tabs-direction:row;--tab-height:calc(var(--size-field,.25rem)*10);height:var(--tabs-height);flex-wrap:wrap;flex-direction:var(--tabs-direction);display:flex}.alert{--alert-border-color:var(--color-base-200);border-radius:var(--radius-box);color:var(--color-base-content);background-color:var(--alert-color,var(--color-base-200));text-align:start;background-size:auto,calc(var(--noise)*100%);background-image:none,var(--fx-noise);box-shadow:0 3px 0 -2px oklch(100% 0 0/calc(var(--depth)*.08))inset,0 1px #000,0 4px 3px -2px oklch(0% 0 0/calc(var(--depth)*.08));border-style:solid;grid-template-columns:auto;grid-auto-flow:column;justify-content:start;place-items:center start;gap:1rem;padding-block:.75rem;padding-inline:1rem;font-size:.875rem;line-height:1.25rem;display:grid}@supports (color:color-mix(in lab, red, red)){.alert{box-shadow:0 3px 0 -2px oklch(100% 0 0/calc(var(--depth)*.08))inset,0 1px color-mix(in oklab,color-mix(in oklab,#000 20%,var(--alert-color,var(--color-base-200)))calc(var(--depth)*20%),#0000),0 4px 3px -2px oklch(0% 0 0/calc(var(--depth)*.08))}}.alert:has(:nth-child(2)){grid-template-columns:auto minmax(auto,1fr)}.fieldset{grid-template-columns:1fr;grid-auto-rows:max-content;gap:.375rem;padding-block:.25rem;font-size:.75rem;display:grid}.link{cursor:pointer;text-decoration-line:underline}.link:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.link:focus{outline-offset:2px;outline:2px solid #0000}}.link:focus-visible{outline-offset:2px;outline:2px solid}.btn-primary{--btn-color:var(--color-primary);--btn-fg:var(--color-primary-content)}.btn-secondary{--btn-color:var(--color-secondary);--btn-fg:var(--color-secondary-content)}}@layer daisyui.l1.l2{.btn:disabled:not(.btn-link,.btn-ghost){background-color:var(--color-base-content)}@supports (color:color-mix(in lab, red, red)){.btn:disabled:not(.btn-link,.btn-ghost){background-color:color-mix(in oklab,var(--color-base-content)10%,transparent)}}.btn:disabled:not(.btn-link,.btn-ghost){box-shadow:none}.btn:disabled{pointer-events:none;--btn-border:#0000;--btn-noise:none;--btn-fg:var(--color-base-content)}@supports (color:color-mix(in lab, red, red)){.btn:disabled{--btn-fg:color-mix(in oklch,var(--color-base-content)20%,#0000)}}.btn[disabled]:not(.btn-link,.btn-ghost){background-color:var(--color-base-content)}@supports (color:color-mix(in lab, red, red)){.btn[disabled]:not(.btn-link,.btn-ghost){background-color:color-mix(in oklab,var(--color-base-content)10%,transparent)}}.btn[disabled]:not(.btn-link,.btn-ghost){box-shadow:none}.btn[disabled]{pointer-events:none;--btn-border:#0000;--btn-noise:none;--btn-fg:var(--color-base-content)}@supports (color:color-mix(in lab, red, red)){.btn[disabled]{--btn-fg:color-mix(in oklch,var(--color-base-content)20%,#0000)}}.steps .step-neutral+.step-neutral:before,.steps .step-neutral:after,.steps .step-neutral>.step-icon{--step-bg:var(--color-neutral);--step-fg:var(--color-neutral-content)}.steps .step-primary+.step-primary:before,.steps .step-primary:after,.steps .step-primary>.step-icon{--step-bg:var(--color-primary);--step-fg:var(--color-primary-content)}.steps .step-secondary+.step-secondary:before,.steps .step-secondary:after,.steps .step-secondary>.step-icon{--step-bg:var(--color-secondary);--step-fg:var(--color-secondary-content)}.steps .step-accent+.step-accent:before,.steps .step-accent:after,.steps .step-accent>.step-icon{--step-bg:var(--color-accent);--step-fg:var(--color-accent-content)}.steps .step-info+.step-info:before,.steps .step-info:after,.steps .step-info>.step-icon{--step-bg:var(--color-info);--step-fg:var(--color-info-content)}.steps .step-success+.step-success:before,.steps .step-success:after,.steps .step-success>.step-icon{--step-bg:var(--color-success);--step-fg:var(--color-success-content)}.steps .step-warning+.step-warning:before,.steps .step-warning:after,.steps .step-warning>.step-icon{--step-bg:var(--color-warning);--step-fg:var(--color-warning-content)}.steps .step-error+.step-error:before,.steps .step-error:after,.steps .step-error>.step-icon{--step-bg:var(--color-error);--step-fg:var(--color-error-content)}.tabs-box{background-color:var(--color-base-200);--tabs-box-radius:calc(3*var(--radius-field));border-radius:calc(min(calc(var(--tab-height)/2),var(--radius-field)) + min(.25rem,var(--tabs-box-radius)));box-shadow:0 -.5px oklch(100% 0 0/calc(var(--depth)*.1))inset,0 .5px oklch(0% 0 0/calc(var(--depth)*.05))inset;padding:.25rem}.tabs-box>.tab{border-radius:var(--radius-field);border-style:none}.tabs-box>.tab:focus-visible,.tabs-box>.tab:is(label:has(:checked:focus-visible)){outline-offset:2px}.tabs-box>:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]),.tabs-box>:is(input:checked),.tabs-box>:is(label:has(:checked)){background-color:var(--tab-bg,var(--color-base-100));box-shadow:0 1px oklch(100% 0 0/calc(var(--depth)*.1))inset,0 1px 1px -1px var(--color-neutral),0 1px 6px -4px var(--color-neutral)}@supports (color:color-mix(in lab, red, red)){.tabs-box>:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]),.tabs-box>:is(input:checked),.tabs-box>:is(label:has(:checked)){box-shadow:0 1px oklch(100% 0 0/calc(var(--depth)*.1))inset,0 1px 1px -1px color-mix(in oklab,var(--color-neutral)calc(var(--depth)*50%),#0000),0 1px 6px -4px color-mix(in oklab,var(--color-neutral)calc(var(--depth)*100%),#0000)}}@media (forced-colors:active){.tabs-box>:is(.tab-active,[aria-selected=true],[aria-current=true],[aria-current=page]):not(.tab-disabled,[disabled]),.tabs-box>:is(input:checked),.tabs-box>:is(label:has(:checked)){border:1px solid}}.tabs-box>.tab-content{height:calc(100% - var(--tab-height) + var(--border) - .5rem);border-radius:calc(min(calc(var(--tab-height)/2),var(--radius-field)) + min(.25rem,var(--tabs-box-radius)) - var(--border));margin-top:.25rem}.btn-square{width:var(--size);height:var(--size);padding-inline:0}.alert-error{color:var(--color-error-content);--alert-border-color:var(--color-error);--alert-color:var(--color-error)}.alert-info{color:var(--color-info-content);--alert-border-color:var(--color-info);--alert-color:var(--color-info)}.alert-success{color:var(--color-success-content);--alert-border-color:var(--color-success);--alert-color:var(--color-success)}.alert-warning{color:var(--color-warning-content);--alert-border-color:var(--color-warning);--alert-color:var(--color-warning)}.btn-sm{--fontsize:.75rem;--btn-p:.75rem;--size:calc(var(--size-field,.25rem)*8)}}.countdown.countdown{line-height:1em}.mx-auto{margin-inline:auto}.my-2{margin-block:calc(var(--spacing)*2)}.my-4{margin-block:calc(var(--spacing)*4)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-6{margin-top:calc(var(--spacing)*6)}.mt-8{margin-top:calc(var(--spacing)*8)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.ml-4{margin-left:calc(var(--spacing)*4)}.alert{border-width:var(--border);border-color:var(--alert-border-color,var(--color-base-200))}.join{--join-ss:0;--join-se:0;--join-es:0;--join-ee:0;align-items:stretch;display:inline-flex}.join :where(.join-item){border-start-start-radius:var(--join-ss,0);border-start-end-radius:var(--join-se,0);border-end-end-radius:var(--join-ee,0);border-end-start-radius:var(--join-es,0)}.join :where(.join-item) *{--join-ss:var(--radius-field);--join-se:var(--radius-field);--join-es:var(--radius-field);--join-ee:var(--radius-field)}.join>.join-item:where(:first-child),.join :first-child:not(:last-child) :where(.join-item){--join-ss:var(--radius-field);--join-se:0;--join-es:var(--radius-field);--join-ee:0}.join>.join-item:where(:last-child),.join :last-child:not(:first-child) :where(.join-item){--join-ss:0;--join-se:var(--radius-field);--join-es:0;--join-ee:var(--radius-field)}.join>.join-item:where(:only-child),.join :only-child :where(.join-item){--join-ss:var(--radius-field);--join-se:var(--radius-field);--join-es:var(--radius-field);--join-ee:var(--radius-field)}.flex{display:flex}.grid{display:grid}.w-full{width:100%}.max-w-md{max-width:var(--container-md)}.max-w-sm{max-width:var(--container-sm)}.flex-1{flex:1}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing)*1)}.gap-2{gap:calc(var(--spacing)*2)}.gap-4{gap:calc(var(--spacing)*4)}.gap-8{gap:calc(var(--spacing)*8)}.rounded-lg{border-radius:var(--radius-lg)}.border-none{--tw-border-style:none;border-style:none}.bg-base-200{background-color:var(--color-base-200)}.bg-white{background-color:var(--color-white)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.px-2{padding-inline:calc(var(--spacing)*2)}.py-1{padding-block:calc(var(--spacing)*1)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.break-all{word-break:break-all}.text-base-content{color:var(--color-base-content)}.text-gray-800{color:var(--color-gray-800)}.text-success{color:var(--color-success)}.no-underline{text-decoration-line:none}.opacity-40{opacity:.4}.opacity-60{opacity:.6}@layer daisyui.l1{.btn-ghost:not(.btn-active,:hover,:active:focus,:focus-visible,input:checked:not(.filter .btn)){--btn-shadow:"";--btn-bg:#0000;--btn-border:#0000;--btn-noise:none}.btn-ghost:not(.btn-active,:hover,:active:focus,:focus-visible,input:checked:not(.filter .btn)):not(:disabled,[disabled],.btn-disabled){--btn-fg:var(--btn-color,currentColor);outline-color:currentColor}@media (hover:none){.btn-ghost:not(.btn-active,:active,:focus-visible,input:checked:not(.filter .btn)):hover{--btn-shadow:"";--btn-bg:#0000;--btn-fg:var(--btn-color,currentColor);--btn-border:#0000;--btn-noise:none;outline-color:currentColor}}}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media (hover:hover){.hover\:bg-base-300:hover{background-color:var(--color-base-300)}@layer daisyui.l1.l2.l3{.hover\:btn-error:hover{--btn-color:var(--color-error);--btn-fg:var(--color-error-content)}}}}.board{background:#2563eb;border-radius:12px;gap:8px;padding:16px;display:flex}.column{border-radius:8px;flex-direction:column;gap:8px;padding:4px;display:flex}.column.clickable{cursor:pointer}.column.clickable:hover{background:#ffffff26}.cell{background:#1e40af;border-radius:50%;width:48px;height:48px;transition:background .2s}.cell.red{background:#dc2626}.cell.yellow{background:#facc15}.cell.winning{animation:.5s ease-in-out infinite alternate pulse}@keyframes pulse{50%{opacity:.5}}.player-chip{background:#666;border-radius:50%;width:20px;height:20px}.player-chip.red{background:#dc2626}.player-chip.yellow{background:#facc15}.snake-board{background:#1a1a2e;border:3px solid #333;border-radius:8px;gap:0;display:inline-grid;overflow:hidden}.snake-row{display:contents}.snake-cell{background:#16213e;border:1px solid #ffffff08;transition:background .13s ease-in-out,box-shadow .13s ease-out}.snake-cell.snake-head{border-radius:4px;animation:.13s ease-out head-pop}@keyframes head-pop{0%{transform:scale(.6)}50%{transform:scale(1.08)}to{transform:scale(1)}}.snake-cell.snake-food{background:#ff6b6b;border-radius:50%;animation:1.2s ease-in-out infinite alternate food-pulse;box-shadow:0 0 6px #ff6b6b99}@keyframes food-pulse{0%{transform:scale(.85);box-shadow:0 0 6px #ff6b6b66}to{transform:scale(1);box-shadow:0 0 12px #ff6b6be6}}.snake-cell.snake-dead{opacity:.35;filter:grayscale(.5);transition:opacity .4s ease-out,background .13s ease-in-out}.snake-wrapper:focus{outline:none}@keyframes rating{0%,40%{filter:brightness(1.05)contrast(1.05);scale:1.1}}@keyframes dropdown{0%{opacity:0}}@keyframes radio{0%{padding:5px}50%{padding:3px}}@keyframes toast{0%{opacity:0;scale:.9}to{opacity:1;scale:1}}@keyframes rotator{89.9999%,to{--first-item-position:0 0%}90%,99.9999%{--first-item-position:0 calc(var(--items)*100%)}to{translate:0 -100%}}@keyframes skeleton{0%{background-position:150%}to{background-position:-50%}}@keyframes menu{0%{opacity:0}}@keyframes progress{50%{background-position-x:-115%}}@property --tw-font-weight{syntax:"*";inherits:false} \ No newline at end of file diff --git a/deploy/c4.service b/deploy/c4.service new file mode 100644 index 0000000..f1aa7c9 --- /dev/null +++ b/deploy/c4.service @@ -0,0 +1,24 @@ +[Unit] +Description=C4 Game Lobby +After=network.target + +[Service] +Type=simple +User=games +Group=games +WorkingDirectory=/opt/c4 +ExecStart=/opt/c4/c4 +Restart=on-failure +RestartSec=5 + +Environment=PORT=8080 + +# Hardening +NoNewPrivileges=true +ProtectSystem=strict +ProtectHome=true +ReadWritePaths=/opt/c4 +PrivateTmp=true + +[Install] +WantedBy=multi-user.target diff --git a/deploy/deploy.sh b/deploy/deploy.sh new file mode 100755 index 0000000..4834fc9 --- /dev/null +++ b/deploy/deploy.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# Deploy the c4 binary to /opt/c4, then restart the service. +# Works from the repo (builds first) or from an extracted tarball (pre-built binary). +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)" +INSTALL_DIR="/opt/c4" +BINARY="$ROOT_DIR/c4" + +# If Go is available and we have source, build fresh +if [[ -f "$ROOT_DIR/go.mod" ]] && command -v go &>/dev/null; then + echo "Building CSS..." + (cd "$ROOT_DIR" && go tool gotailwind -i assets/css/input.css -o assets/css/output.css --minify) + + echo "Building binary..." + (cd "$ROOT_DIR" && CGO_ENABLED=0 go build -o c4 .) +fi + +if [[ ! -f "$BINARY" ]]; then + echo "ERROR: Binary not found at $BINARY" >&2 + exit 1 +fi + +echo "Installing to $INSTALL_DIR..." +install -o games -g games -m 755 "$BINARY" "$INSTALL_DIR/c4" + +echo "Restarting service..." +systemctl restart c4.service + +echo "Done. Status:" +systemctl status c4.service --no-pager diff --git a/deploy/package.sh b/deploy/package.sh new file mode 100755 index 0000000..add6a3e --- /dev/null +++ b/deploy/package.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +# Build the c4 binary, bundle it with deploy files into a tarball, +# base64-encode it, and split into 25MB chunks for transfer. +set -euo pipefail + +REPO_DIR="$(cd "$(dirname "$0")/.." && pwd)" +cd "$REPO_DIR" + +TIMESTAMP=$(date +%Y%m%d-%H%M%S) +TARBALL="c4-deploy-${TIMESTAMP}.tar.gz" +BASE64_FILE="c4-deploy-${TIMESTAMP}_b64.txt" + +#============================================================================== +# Clean previous artifacts +#============================================================================== +echo "--- Cleaning old artifacts ---" +rm -f ./c4 c4-deploy-*.tar.gz c4-deploy-*_b64*.txt + +#============================================================================== +# Build +#============================================================================== +echo "--- Building CSS ---" +go tool gotailwind -i assets/css/input.css -o assets/css/output.css --minify + +echo "--- Building binary (linux/amd64) ---" +CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o c4 . + +#============================================================================== +# Verify required files +#============================================================================== +echo "--- Verifying files ---" +REQUIRED_FILES=( + c4 + deploy/setup.sh + deploy/deploy.sh + deploy/reassemble.sh + deploy/c4.service +) +for f in "${REQUIRED_FILES[@]}"; do + if [[ ! -f "$f" ]]; then + echo "ERROR: Missing required file: $f" >&2 + exit 1 + fi + echo " OK $f" +done + +#============================================================================== +# Create tarball +#============================================================================== +echo "--- Creating tarball ---" +tar -czf "/tmp/${TARBALL}" --transform 's,^,c4/,' \ + c4 \ + deploy/setup.sh \ + deploy/deploy.sh \ + deploy/reassemble.sh \ + deploy/c4.service + +mv "/tmp/${TARBALL}" . +echo " -> ${TARBALL} ($(du -h "${TARBALL}" | cut -f1))" + +#============================================================================== +# Base64 encode and split +#============================================================================== +echo "--- Base64 encoding ---" +base64 "${TARBALL}" > "${BASE64_FILE}" +echo " -> ${BASE64_FILE} ($(du -h "${BASE64_FILE}" | cut -f1))" + +echo "--- Splitting into 25MB chunks ---" +split -b 25M -d --additional-suffix=.txt "${BASE64_FILE}" "c4-deploy-${TIMESTAMP}_b64_part" +rm -f "${BASE64_FILE}" + +CHUNKS=(c4-deploy-${TIMESTAMP}_b64_part*.txt) +echo " -> ${#CHUNKS[@]} chunk(s):" +for chunk in "${CHUNKS[@]}"; do + echo " $chunk ($(du -h "$chunk" | cut -f1))" +done + +#============================================================================== +# Done +#============================================================================== +echo "" +echo "=== Package Complete ===" +echo "" +echo "Transfer the chunk files to the target server, then run:" +echo " ./reassemble.sh" +echo " cd ~/c4 && sudo ./deploy/setup.sh # first time only" +echo " cd ~/c4 && sudo ./deploy/deploy.sh" diff --git a/deploy/reassemble.sh b/deploy/reassemble.sh new file mode 100755 index 0000000..73127ee --- /dev/null +++ b/deploy/reassemble.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash +# Reassembles base64 chunks and extracts the c4 deployment tarball. +# Expects chunk files in the current directory. +set -euo pipefail + +cd "$HOME" + +echo "=== C4 Deployment Reassembler ===" +echo "Working directory: $HOME" +echo "" + +#============================================================================== +# Find and validate chunk files +#============================================================================== +echo "--- Finding chunk files ---" + +CHUNKS=($(ls -1 c4-deploy-*_b64_part*.txt 2>/dev/null | sort)) + +if [[ ${#CHUNKS[@]} -eq 0 ]]; then + echo "ERROR: No chunk files found matching c4-deploy-*_b64_part*.txt" + exit 1 +fi + +echo "Found ${#CHUNKS[@]} chunks:" +for chunk in "${CHUNKS[@]}"; do + echo " - $chunk ($(du -h "$chunk" | cut -f1))" +done + +#============================================================================== +# Reassemble and decode +#============================================================================== +echo "" +echo "--- Reassembling chunks ---" + +TIMESTAMP=$(echo "${CHUNKS[0]}" | sed -E 's/c4-deploy-([0-9]+-[0-9]+)_b64_part.*/\1/') +TARBALL="c4-deploy-${TIMESTAMP}.tar.gz" +COMBINED="combined_b64.txt" + +echo "Concatenating chunks..." +cat "${CHUNKS[@]}" > "$COMBINED" +echo " -> Created $COMBINED ($(du -h "$COMBINED" | cut -f1))" + +echo "Decoding base64..." +base64 -d "$COMBINED" > "$TARBALL" +echo " -> Created $TARBALL ($(du -h "$TARBALL" | cut -f1))" + +echo "Verifying tarball..." +if tar -tzf "$TARBALL" > /dev/null 2>&1; then + echo " -> Tarball is valid" +else + echo "ERROR: Tarball verification failed" + exit 1 +fi + +#============================================================================== +# Archive existing source +#============================================================================== +echo "" +echo "--- Archiving existing source ---" + +if [[ -d c4 ]]; then + rm -rf c4.bak + mv c4 c4.bak + echo " -> Moved c4 -> c4.bak" +else + echo " -> No existing c4 directory" +fi + +#============================================================================== +# Extract +#============================================================================== +echo "" +echo "--- Extracting tarball ---" + +tar -xzf "$TARBALL" +echo " -> Extracted to ~/c4" + +#============================================================================== +# Cleanup +#============================================================================== +echo "" +echo "--- Cleaning up ---" + +rm -f "$COMBINED" "$TARBALL" "${CHUNKS[@]}" +echo " -> Removed chunks, combined base64, and tarball" + +#============================================================================== +# Next steps +#============================================================================== +echo "" +echo "=== Reassembly Complete ===" +echo "" +echo "Next steps:" +echo " cd ~/c4" +echo " sudo ./deploy/setup.sh # first time only" +echo " sudo ./deploy/deploy.sh" diff --git a/deploy/setup.sh b/deploy/setup.sh new file mode 100755 index 0000000..920dde2 --- /dev/null +++ b/deploy/setup.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# One-time setup: create the games user, install directory, and systemd unit. +# Run as root (or with sudo). +set -euo pipefail + +if [[ $EUID -ne 0 ]]; then + echo "Run as root: sudo $0" >&2 + exit 1 +fi + +# Create system user if it doesn't exist +if ! id -u games &>/dev/null; then + useradd --system --shell /usr/sbin/nologin --home-dir /opt/c4 --create-home games + echo "Created system user: games" +else + echo "User 'games' already exists" +fi + +# Ensure install directory exists with correct ownership +install -d -o games -g games -m 755 /opt/c4 +install -d -o games -g games -m 755 /opt/c4/data + +# Install systemd unit +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +cp "$SCRIPT_DIR/c4.service" /etc/systemd/system/c4.service +systemctl daemon-reload +systemctl enable c4.service + +echo "Setup complete. Run deploy.sh to build and start the service." diff --git a/main.go b/main.go index 4346e43..480ad7d 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( _ "embed" "log" "net/http" + "os" "github.com/google/uuid" @@ -20,9 +21,11 @@ import ( "github.com/ryanhamamura/via/vianats" ) -var store = game.NewGameStore() -var snakeStore = snake.NewSnakeStore() -var queries *gen.Queries +var ( + store = game.NewGameStore() + snakeStore = snake.NewSnakeStore() + queries *gen.Queries +) //go:embed assets/css/output.css var daisyUICSS []byte @@ -35,6 +38,13 @@ func DaisyUIPlugin(v *via.V) { v.AppendToHead(h.Link(h.Rel("stylesheet"), h.Href("/_plugins/daisyui/style.css"))) } +func port() string { + if p := os.Getenv("PORT"); p != "" { + return p + } + return "7331" +} + func main() { if err := db.Init("c4.db"); err != nil { log.Fatal(err) @@ -60,7 +70,7 @@ func main() { v.Config(via.Options{ LogLevel: via.LogLevelDebug, DocumentTitle: "Game Lobby", - ServerAddress: ":7331", + ServerAddress: ":" + port(), SessionManager: sessionManager, PubSub: ns, Plugins: []via.Plugin{DaisyUIPlugin}, diff --git a/ui/snakeboard.go b/ui/snakeboard.go index f4076c3..56c2f7a 100644 --- a/ui/snakeboard.go +++ b/ui/snakeboard.go @@ -64,8 +64,9 @@ func SnakeBoard(sg *snake.SnakeGame) h.H { case ci.snakeIdx >= 0: s := state.Snakes[ci.snakeIdx] colorIdx := ci.snakeIdx + bg := "" if colorIdx < len(snake.SnakeColors) { - bg := snake.SnakeColors[colorIdx] + bg = snake.SnakeColors[colorIdx] style += fmt.Sprintf("background:%s;", bg) } if !s.Alive { @@ -73,6 +74,9 @@ func SnakeBoard(sg *snake.SnakeGame) h.H { } if ci.isHead { class += " snake-head" + if bg != "" { + style += fmt.Sprintf("box-shadow:0 0 8px %s;", bg) + } } }