Free and open source ticket system written in python
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

📦 NEW: add dark/light theme switcher for unauthenticated users

+132 -401
+1 -1
paw/__init__.py
··· 1 1 from django import get_version 2 2 3 - VERSION = (0, 3, 0, "beta", 1) 3 + VERSION = (0, 3, 0, "beta", 3) 4 4 5 5 __version__ = get_version(VERSION)
+10 -2
paw/templates/base.html
··· 1 1 <!DOCTYPE html> 2 2 {% load static %} 3 - <html lang="en"{% if request.user.is_authenticated %}{% if request.user.use_darkmode %} data-theme="dark"{% else %} data-theme="light" {% endif %}{% endif %}> 3 + <html lang="en"{% if request.user.is_authenticated %}{% if request.user.use_darkmode %} data-theme="dark"{% else %} data-theme="light" {% endif %}{% else %} data-theme="light" {% endif %}> 4 4 <head> 5 5 <meta charset="UTF-8"> 6 6 <meta http-equiv="X-UA-Compatible" content="IE=edge"> ··· 17 17 <div class="navbar-center"></div> 18 18 <div class="navbar-end"> 19 19 <a class="btn mr-4" href="{% url 'all_tickets' %}">Tickets</a> 20 - <a class="btn" href="{% url 'incident-list' %}">Status</a> 20 + <a class="btn mr-4" href="{% url 'incident-list' %}">Status</a> 21 + {% if not request.user.is_authenticated %} 22 + <label class="swap swap-rotate"> 23 + <input type="checkbox" id="theme-switch" /> 24 + <svg xmlns="http://www.w3.org/2000/svg" class="swap-on stoke-current w-6 h-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-sun"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 12m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0" /><path d="M3 12h1m8 -9v1m8 8h1m-9 8v1m-6.4 -15.4l.7 .7m12.1 -.7l-.7 .7m0 11.4l.7 .7m-12.1 -.7l-.7 .7" /></svg> 25 + <svg xmlns="http://www.w3.org/2000/svg" class="swap-off stoke-current w-6 h-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" /></svg> 26 + </label> 27 + <script src="{% static 'js/theme_switch.js' %}"></script> 28 + {% endif %} 21 29 </div> 22 30 </div> 23 31 <div class="flex-grow flex">
+99 -398
static/css/paw.css
··· 866 866 color: var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity))); 867 867 } 868 868 869 - .menu li > *:not(ul, .menu-title, details, .btn):active, 870 - .menu li > *:not(ul, .menu-title, details, .btn).active, 871 - .menu li > details > summary:active { 872 - --tw-bg-opacity: 1; 873 - background-color: var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity))); 874 - --tw-text-opacity: 1; 875 - color: var(--fallback-nc,oklch(var(--nc)/var(--tw-text-opacity))); 876 - } 877 - 878 869 .table tr.hover:hover, 879 870 .table tr.hover:nth-child(even):hover { 880 871 --tw-bg-opacity: 1; ··· 1155 1146 background-color: var(--fallback-bc,oklch(var(--bc)/0.1)); 1156 1147 } 1157 1148 1158 - .dropdown { 1159 - position: relative; 1160 - display: inline-block; 1161 - } 1162 - 1163 - .dropdown > *:not(summary):focus { 1164 - outline: 2px solid transparent; 1165 - outline-offset: 2px; 1166 - } 1167 - 1168 - .dropdown .dropdown-content { 1169 - position: absolute; 1170 - } 1171 - 1172 - .dropdown:is(:not(details)) .dropdown-content { 1173 - visibility: hidden; 1174 - opacity: 0; 1175 - transform-origin: top; 1176 - --tw-scale-x: .95; 1177 - --tw-scale-y: .95; 1178 - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); 1179 - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; 1180 - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; 1181 - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; 1182 - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); 1183 - transition-timing-function: cubic-bezier(0, 0, 0.2, 1); 1184 - transition-duration: 200ms; 1185 - } 1186 - 1187 - .dropdown-end .dropdown-content { 1188 - inset-inline-end: 0px; 1189 - } 1190 - 1191 - .dropdown-left .dropdown-content { 1192 - bottom: auto; 1193 - inset-inline-end: 100%; 1194 - top: 0px; 1195 - transform-origin: right; 1196 - } 1197 - 1198 - .dropdown-right .dropdown-content { 1199 - bottom: auto; 1200 - inset-inline-start: 100%; 1201 - top: 0px; 1202 - transform-origin: left; 1203 - } 1204 - 1205 - .dropdown-bottom .dropdown-content { 1206 - bottom: auto; 1207 - top: 100%; 1208 - transform-origin: top; 1209 - } 1210 - 1211 - .dropdown-top .dropdown-content { 1212 - bottom: 100%; 1213 - top: auto; 1214 - transform-origin: bottom; 1215 - } 1216 - 1217 - .dropdown-end.dropdown-right .dropdown-content { 1218 - bottom: 0px; 1219 - top: auto; 1220 - } 1221 - 1222 - .dropdown-end.dropdown-left .dropdown-content { 1223 - bottom: 0px; 1224 - top: auto; 1225 - } 1226 - 1227 - .dropdown.dropdown-open .dropdown-content, 1228 - .dropdown:not(.dropdown-hover):focus .dropdown-content, 1229 - .dropdown:focus-within .dropdown-content { 1230 - visibility: visible; 1231 - opacity: 1; 1232 - } 1233 - 1234 1149 @media (hover: hover) { 1235 - .dropdown.dropdown-hover:hover .dropdown-content { 1236 - visibility: visible; 1237 - opacity: 1; 1238 - } 1239 - 1240 1150 .btn:hover { 1241 1151 --tw-border-opacity: 1; 1242 1152 border-color: var(--fallback-b3,oklch(var(--b3)/var(--tw-border-opacity))); ··· 1281 1191 } 1282 1192 } 1283 1193 1284 - .btn-outline.btn-secondary:hover { 1285 - --tw-text-opacity: 1; 1286 - color: var(--fallback-sc,oklch(var(--sc)/var(--tw-text-opacity))); 1287 - } 1288 - 1289 - @supports (color: color-mix(in oklab, black, black)) { 1290 - .btn-outline.btn-secondary:hover { 1291 - background-color: color-mix(in oklab, var(--fallback-s,oklch(var(--s)/1)) 90%, black); 1292 - border-color: color-mix(in oklab, var(--fallback-s,oklch(var(--s)/1)) 90%, black); 1293 - } 1294 - } 1295 - 1296 1194 .btn-outline.btn-accent:hover { 1297 1195 --tw-text-opacity: 1; 1298 1196 color: var(--fallback-ac,oklch(var(--ac)/var(--tw-text-opacity))); ··· 1357 1255 border-color: color-mix(in oklab, var(--fallback-p,oklch(var(--p)/1)) 90%, black); 1358 1256 } 1359 1257 } 1360 - 1361 - .dropdown.dropdown-hover:hover .dropdown-content { 1362 - --tw-scale-x: 1; 1363 - --tw-scale-y: 1; 1364 - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); 1365 - } 1366 - 1367 - :where(.menu li:not(.menu-title, .disabled) > *:not(ul, details, .menu-title)):not(.active, .btn):hover, :where(.menu li:not(.menu-title, .disabled) > details > summary:not(.menu-title)):not(.active, .btn):hover { 1368 - cursor: pointer; 1369 - outline: 2px solid transparent; 1370 - outline-offset: 2px; 1371 - } 1372 - 1373 - @supports (color: oklch(0 0 0)) { 1374 - :where(.menu li:not(.menu-title, .disabled) > *:not(ul, details, .menu-title)):not(.active, .btn):hover, :where(.menu li:not(.menu-title, .disabled) > details > summary:not(.menu-title)):not(.active, .btn):hover { 1375 - background-color: var(--fallback-bc,oklch(var(--bc)/0.1)); 1376 - } 1377 - } 1378 - } 1379 - 1380 - .dropdown:is(details) summary::-webkit-details-marker { 1381 - display: none; 1382 1258 } 1383 1259 1384 1260 .file-input { ··· 1574 1450 text-decoration-line: underline; 1575 1451 } 1576 1452 1577 - .menu { 1578 - display: flex; 1579 - flex-direction: column; 1580 - flex-wrap: wrap; 1581 - font-size: 0.875rem; 1582 - line-height: 1.25rem; 1583 - padding: 0.5rem; 1584 - } 1585 - 1586 - .menu :where(li ul) { 1587 - position: relative; 1588 - white-space: nowrap; 1589 - margin-inline-start: 1rem; 1590 - padding-inline-start: 0.5rem; 1591 - } 1592 - 1593 - .menu :where(li:not(.menu-title) > *:not(ul, details, .menu-title, .btn)), .menu :where(li:not(.menu-title) > details > summary:not(.menu-title)) { 1594 - display: grid; 1595 - grid-auto-flow: column; 1596 - align-content: flex-start; 1597 - align-items: center; 1598 - gap: 0.5rem; 1599 - grid-auto-columns: minmax(auto, max-content) auto max-content; 1600 - -webkit-user-select: none; 1601 - -moz-user-select: none; 1602 - user-select: none; 1603 - } 1604 - 1605 - .menu li.disabled { 1606 - cursor: not-allowed; 1607 - -webkit-user-select: none; 1608 - -moz-user-select: none; 1609 - user-select: none; 1610 - color: var(--fallback-bc,oklch(var(--bc)/0.3)); 1611 - } 1612 - 1613 - .menu :where(li > .menu-dropdown:not(.menu-dropdown-show)) { 1614 - display: none; 1615 - } 1616 - 1617 - :where(.menu li) { 1618 - position: relative; 1619 - display: flex; 1620 - flex-shrink: 0; 1621 - flex-direction: column; 1622 - flex-wrap: wrap; 1623 - align-items: stretch; 1624 - } 1625 - 1626 1453 :where(.menu li) .badge { 1627 1454 justify-self: end; 1628 1455 } ··· 1758 1585 min-width: 4rem; 1759 1586 } 1760 1587 1588 + .swap { 1589 + position: relative; 1590 + display: inline-grid; 1591 + -webkit-user-select: none; 1592 + -moz-user-select: none; 1593 + user-select: none; 1594 + place-content: center; 1595 + cursor: pointer; 1596 + } 1597 + 1598 + .swap > * { 1599 + grid-column-start: 1; 1600 + grid-row-start: 1; 1601 + transition-duration: 300ms; 1602 + transition-timing-function: cubic-bezier(0, 0, 0.2, 1); 1603 + transition-property: transform, opacity; 1604 + } 1605 + 1606 + .swap input { 1607 + -webkit-appearance: none; 1608 + -moz-appearance: none; 1609 + appearance: none; 1610 + } 1611 + 1612 + .swap .swap-on, 1613 + .swap .swap-indeterminate, 1614 + .swap input:indeterminate ~ .swap-on { 1615 + opacity: 0; 1616 + } 1617 + 1618 + .swap input:checked ~ .swap-off, 1619 + .swap-active .swap-off, 1620 + .swap input:indeterminate ~ .swap-off { 1621 + opacity: 0; 1622 + } 1623 + 1624 + .swap input:checked ~ .swap-on, 1625 + .swap-active .swap-on, 1626 + .swap input:indeterminate ~ .swap-indeterminate { 1627 + opacity: 1; 1628 + } 1629 + 1761 1630 .table { 1762 1631 position: relative; 1763 1632 width: 100%; ··· 1948 1817 border-color: var(--btn-color, var(--fallback-b2)); 1949 1818 } 1950 1819 1951 - .btn-secondary { 1952 - --btn-color: var(--fallback-s); 1953 - } 1954 - 1955 1820 .btn-accent { 1956 1821 --btn-color: var(--fallback-a); 1957 1822 } ··· 1974 1839 } 1975 1840 1976 1841 @supports (color: color-mix(in oklab, black, black)) { 1977 - .btn-outline.btn-secondary.btn-active { 1978 - background-color: color-mix(in oklab, var(--fallback-s,oklch(var(--s)/1)) 90%, black); 1979 - border-color: color-mix(in oklab, var(--fallback-s,oklch(var(--s)/1)) 90%, black); 1980 - } 1981 - 1982 1842 .btn-outline.btn-accent.btn-active { 1983 1843 background-color: color-mix(in oklab, var(--fallback-a,oklch(var(--a)/1)) 90%, black); 1984 1844 border-color: color-mix(in oklab, var(--fallback-a,oklch(var(--a)/1)) 90%, black); ··· 2007 1867 } 2008 1868 2009 1869 @supports (color: oklch(0 0 0)) { 2010 - .btn-secondary { 2011 - --btn-color: var(--s); 2012 - } 2013 - 2014 1870 .btn-accent { 2015 1871 --btn-color: var(--a); 2016 1872 } ··· 2032 1888 } 2033 1889 } 2034 1890 2035 - .btn-secondary { 2036 - --tw-text-opacity: 1; 2037 - color: var(--fallback-sc,oklch(var(--sc)/var(--tw-text-opacity))); 2038 - outline-color: var(--fallback-s,oklch(var(--s)/1)); 2039 - } 2040 - 2041 1891 .btn-accent { 2042 1892 --tw-text-opacity: 1; 2043 1893 color: var(--fallback-ac,oklch(var(--ac)/var(--tw-text-opacity))); ··· 2094 1944 .btn-ghost.btn-active { 2095 1945 border-color: transparent; 2096 1946 background-color: var(--fallback-bc,oklch(var(--bc)/0.2)); 2097 - } 2098 - 2099 - .btn-outline.btn-secondary { 2100 - --tw-text-opacity: 1; 2101 - color: var(--fallback-s,oklch(var(--s)/var(--tw-text-opacity))); 2102 - } 2103 - 2104 - .btn-outline.btn-secondary.btn-active { 2105 - --tw-text-opacity: 1; 2106 - color: var(--fallback-sc,oklch(var(--sc)/var(--tw-text-opacity))); 2107 1947 } 2108 1948 2109 1949 .btn-outline.btn-accent { ··· 2310 2150 gap: 1rem; 2311 2151 } 2312 2152 2313 - .dropdown.dropdown-open .dropdown-content, 2314 - .dropdown:focus .dropdown-content, 2315 - .dropdown:focus-within .dropdown-content { 2316 - --tw-scale-x: 1; 2317 - --tw-scale-y: 1; 2318 - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); 2319 - } 2320 - 2321 2153 .file-input-bordered { 2322 2154 --tw-border-opacity: 0.2; 2323 2155 } ··· 2446 2278 .link:focus-visible { 2447 2279 outline: 2px solid currentColor; 2448 2280 outline-offset: 2px; 2449 - } 2450 - 2451 - :where(.menu li:empty) { 2452 - --tw-bg-opacity: 1; 2453 - background-color: var(--fallback-bc,oklch(var(--bc)/var(--tw-bg-opacity))); 2454 - opacity: 0.1; 2455 - margin: 0.5rem 1rem; 2456 - height: 1px; 2457 - } 2458 - 2459 - .menu :where(li ul):before { 2460 - position: absolute; 2461 - bottom: 0.75rem; 2462 - inset-inline-start: 0px; 2463 - top: 0.75rem; 2464 - width: 1px; 2465 - --tw-bg-opacity: 1; 2466 - background-color: var(--fallback-bc,oklch(var(--bc)/var(--tw-bg-opacity))); 2467 - opacity: 0.1; 2468 - content: ""; 2469 - } 2470 - 2471 - .menu :where(li:not(.menu-title) > *:not(ul, details, .menu-title, .btn)), 2472 - .menu :where(li:not(.menu-title) > details > summary:not(.menu-title)) { 2473 - border-radius: var(--rounded-btn, 0.5rem); 2474 - padding-left: 1rem; 2475 - padding-right: 1rem; 2476 - padding-top: 0.5rem; 2477 - padding-bottom: 0.5rem; 2478 - text-align: start; 2479 - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; 2480 - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; 2481 - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; 2482 - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); 2483 - transition-timing-function: cubic-bezier(0, 0, 0.2, 1); 2484 - transition-duration: 200ms; 2485 - text-wrap: balance; 2486 - } 2487 - 2488 - :where(.menu li:not(.menu-title, .disabled) > *:not(ul, details, .menu-title)):not(summary, .active, .btn).focus, :where(.menu li:not(.menu-title, .disabled) > *:not(ul, details, .menu-title)):not(summary, .active, .btn):focus, :where(.menu li:not(.menu-title, .disabled) > *:not(ul, details, .menu-title)):is(summary):not(.active, .btn):focus-visible, :where(.menu li:not(.menu-title, .disabled) > details > summary:not(.menu-title)):not(summary, .active, .btn).focus, :where(.menu li:not(.menu-title, .disabled) > details > summary:not(.menu-title)):not(summary, .active, .btn):focus, :where(.menu li:not(.menu-title, .disabled) > details > summary:not(.menu-title)):is(summary):not(.active, .btn):focus-visible { 2489 - cursor: pointer; 2490 - background-color: var(--fallback-bc,oklch(var(--bc)/0.1)); 2491 - --tw-text-opacity: 1; 2492 - color: var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity))); 2493 - outline: 2px solid transparent; 2494 - outline-offset: 2px; 2495 - } 2496 - 2497 - .menu li > *:not(ul, .menu-title, details, .btn):active, 2498 - .menu li > *:not(ul, .menu-title, details, .btn).active, 2499 - .menu li > details > summary:active { 2500 - --tw-bg-opacity: 1; 2501 - background-color: var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity))); 2502 - --tw-text-opacity: 1; 2503 - color: var(--fallback-nc,oklch(var(--nc)/var(--tw-text-opacity))); 2504 - } 2505 - 2506 - .menu :where(li > details > summary)::-webkit-details-marker { 2507 - display: none; 2508 - } 2509 - 2510 - .menu :where(li > details > summary):after, 2511 - .menu :where(li > .menu-dropdown-toggle):after { 2512 - justify-self: end; 2513 - display: block; 2514 - margin-top: -0.5rem; 2515 - height: 0.5rem; 2516 - width: 0.5rem; 2517 - transform: rotate(45deg); 2518 - transition-property: transform, margin-top; 2519 - transition-duration: 0.3s; 2520 - transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); 2521 - content: ""; 2522 - transform-origin: 75% 75%; 2523 - box-shadow: 2px 2px; 2524 - pointer-events: none; 2525 - } 2526 - 2527 - .menu :where(li > details[open] > summary):after, 2528 - .menu :where(li > .menu-dropdown-toggle.menu-dropdown-show):after { 2529 - transform: rotate(225deg); 2530 - margin-top: 0; 2531 2281 } 2532 2282 2533 2283 .mockup-browser .mockup-browser-toolbar .input { ··· 2813 2563 color: var(--fallback-erc,oklch(var(--erc)/var(--tw-text-opacity))); 2814 2564 } 2815 2565 2566 + .swap-rotate .swap-on, 2567 + .swap-rotate .swap-indeterminate, 2568 + .swap-rotate input:indeterminate ~ .swap-on { 2569 + --tw-rotate: 45deg; 2570 + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); 2571 + } 2572 + 2573 + .swap-rotate input:checked ~ .swap-off, 2574 + .swap-active:where(.swap-rotate) .swap-off, 2575 + .swap-rotate input:indeterminate ~ .swap-off { 2576 + --tw-rotate: -45deg; 2577 + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); 2578 + } 2579 + 2580 + .swap-rotate input:checked ~ .swap-on, 2581 + .swap-active:where(.swap-rotate) .swap-on, 2582 + .swap-rotate input:indeterminate ~ .swap-indeterminate { 2583 + --tw-rotate: 0deg; 2584 + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); 2585 + } 2586 + 2587 + .swap-flip .swap-on, 2588 + .swap-flip .swap-indeterminate, 2589 + .swap-flip input:indeterminate ~ .swap-on { 2590 + transform: rotateY(180deg); 2591 + backface-visibility: hidden; 2592 + opacity: 1; 2593 + } 2594 + 2595 + .swap-flip input:checked ~ .swap-off, 2596 + .swap-active:where(.swap-flip) .swap-off, 2597 + .swap-flip input:indeterminate ~ .swap-off { 2598 + transform: rotateY(-180deg); 2599 + backface-visibility: hidden; 2600 + opacity: 1; 2601 + } 2602 + 2603 + .swap-flip input:checked ~ .swap-on, 2604 + .swap-active:where(.swap-flip) .swap-on, 2605 + .swap-flip input:indeterminate ~ .swap-indeterminate { 2606 + transform: rotateY(0deg); 2607 + } 2608 + 2816 2609 :is([dir="rtl"] .table) { 2817 2610 text-align: right; 2818 2611 } ··· 3072 2865 border-start-end-radius: inherit; 3073 2866 } 3074 2867 3075 - .menu-horizontal { 3076 - display: inline-flex; 3077 - flex-direction: row; 3078 - } 3079 - 3080 - .menu-horizontal > li:not(.menu-title) > details > ul { 3081 - position: absolute; 3082 - } 3083 - 3084 2868 .select-sm { 3085 2869 height: 2rem; 3086 2870 min-height: 2rem; ··· 3155 2939 margin-inline-start: -1px; 3156 2940 } 3157 2941 3158 - .menu-horizontal > li:not(.menu-title) > details > ul { 3159 - margin-inline-start: 0px; 3160 - margin-top: 1rem; 3161 - padding-top: 0.5rem; 3162 - padding-bottom: 0.5rem; 3163 - padding-inline-end: 0.5rem; 3164 - } 3165 - 3166 - .menu-horizontal > li > details > ul:before { 3167 - content: none; 3168 - } 3169 - 3170 - :where(.menu-horizontal > li:not(.menu-title) > details > ul) { 3171 - border-radius: var(--rounded-box, 1rem); 3172 - --tw-bg-opacity: 1; 3173 - background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity))); 3174 - --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); 3175 - --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color); 3176 - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); 3177 - } 3178 - 3179 - .menu-sm :where(li:not(.menu-title) > *:not(ul, details, .menu-title)), .menu-sm :where(li:not(.menu-title) > details > summary:not(.menu-title)) { 3180 - border-radius: var(--rounded-btn, 0.5rem); 3181 - padding-left: 0.75rem; 3182 - padding-right: 0.75rem; 3183 - padding-top: 0.25rem; 3184 - padding-bottom: 0.25rem; 3185 - font-size: 0.875rem; 3186 - line-height: 1.25rem; 3187 - } 3188 - 3189 - .menu-sm .menu-title { 3190 - padding-left: 0.75rem; 3191 - padding-right: 0.75rem; 3192 - padding-top: 0.5rem; 3193 - padding-bottom: 0.5rem; 3194 - } 3195 - 3196 2942 .steps-horizontal .step { 3197 2943 grid-template-rows: 40px 1fr; 3198 2944 grid-template-columns: auto; ··· 3244 2990 position: fixed; 3245 2991 } 3246 2992 3247 - .z-\[1\] { 3248 - z-index: 1; 3249 - } 3250 - 3251 2993 .order-first { 3252 2994 order: -9999; 3253 - } 3254 - 3255 - .m-4 { 3256 - margin: 1rem; 3257 2995 } 3258 2996 3259 2997 .mx-auto { ··· 3326 3064 margin-top: 2rem; 3327 3065 } 3328 3066 3329 - .mt-3 { 3330 - margin-top: 0.75rem; 3331 - } 3332 - 3333 3067 .block { 3334 3068 display: block; 3335 3069 } ··· 3382 3116 height: 100%; 3383 3117 } 3384 3118 3119 + .h-8 { 3120 + height: 2rem; 3121 + } 3122 + 3385 3123 .min-h-screen { 3386 3124 min-height: 100vh; 3387 3125 } ··· 3422 3160 width: 100%; 3423 3161 } 3424 3162 3425 - .w-52 { 3426 - width: 13rem; 3163 + .w-8 { 3164 + width: 2rem; 3427 3165 } 3428 3166 3429 - .max-w-2xl { 3430 - max-width: 42rem; 3167 + .max-w-3xl { 3168 + max-width: 48rem; 3431 3169 } 3432 3170 3433 3171 .max-w-4xl { ··· 3446 3184 max-width: 20rem; 3447 3185 } 3448 3186 3449 - .max-w-3xl { 3450 - max-width: 48rem; 3451 - } 3452 - 3453 3187 .flex-none { 3454 3188 flex: none; 3455 - } 3456 - 3457 - .flex-1 { 3458 - flex: 1 1 0%; 3459 3189 } 3460 3190 3461 3191 .shrink-0 { ··· 3490 3220 align-items: center; 3491 3221 } 3492 3222 3493 - .items-stretch { 3494 - align-items: stretch; 3495 - } 3496 - 3497 3223 .justify-start { 3498 3224 justify-content: flex-start; 3499 3225 } ··· 3546 3272 border-left-width: 2px; 3547 3273 } 3548 3274 3549 - .border-r-4 { 3550 - border-right-width: 4px; 3551 - } 3552 - 3553 3275 .border-l-8 { 3554 3276 border-left-width: 8px; 3555 3277 } ··· 3564 3286 border-color: var(--fallback-b3,oklch(var(--b3)/var(--tw-border-opacity))); 3565 3287 } 3566 3288 3567 - .border-success { 3289 + .border-error { 3568 3290 --tw-border-opacity: 1; 3569 - border-color: var(--fallback-su,oklch(var(--su)/var(--tw-border-opacity))); 3291 + border-color: var(--fallback-er,oklch(var(--er)/var(--tw-border-opacity))); 3570 3292 } 3571 3293 3572 - .border-error { 3294 + .border-success { 3573 3295 --tw-border-opacity: 1; 3574 - border-color: var(--fallback-er,oklch(var(--er)/var(--tw-border-opacity))); 3296 + border-color: var(--fallback-su,oklch(var(--su)/var(--tw-border-opacity))); 3575 3297 } 3576 3298 3577 3299 .bg-\[\#4285F4\] { ··· 3594 3316 background-color: var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity))); 3595 3317 } 3596 3318 3597 - .bg-base-100 { 3598 - --tw-bg-opacity: 1; 3599 - background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity))); 3319 + .fill-current { 3320 + fill: currentColor; 3600 3321 } 3601 3322 3602 3323 .stroke-current { ··· 3638 3359 padding-bottom: 0.5rem; 3639 3360 } 3640 3361 3641 - .px-1 { 3642 - padding-left: 0.25rem; 3643 - padding-right: 0.25rem; 3644 - } 3645 - 3646 - .px-4 { 3647 - padding-left: 1rem; 3648 - padding-right: 1rem; 3649 - } 3650 - 3651 3362 .text-center { 3652 3363 text-align: center; 3653 3364 } ··· 3754 3465 opacity: 0.7; 3755 3466 } 3756 3467 3757 - .shadow { 3758 - --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); 3759 - --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); 3760 - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); 3761 - } 3762 - 3763 3468 @media (min-width: 1024px) { 3764 3469 .lg\:btn-sm { 3765 3470 height: 2rem; ··· 3829 3534 3830 3535 .lg\:flex { 3831 3536 display: flex; 3832 - } 3833 - 3834 - .lg\:hidden { 3835 - display: none; 3836 3537 } 3837 3538 3838 3539 .lg\:w-72 {
+22
static/js/theme_switch.js
··· 1 + const themeSwitch = document.getElementById("theme-switch"); 2 + 3 + window.onload = checkTheme(); 4 + 5 + function checkTheme() { 6 + const localStorageTheme = localStorage.getItem("theme"); 7 + if (localStorageTheme === "dark") { 8 + document.documentElement.setAttribute("data-theme", "dark"); 9 + themeSwitch.checked = true; 10 + } 11 + } 12 + 13 + function switchTheme() { 14 + if (this.checked) { 15 + document.documentElement.setAttribute("data-theme", "dark"); 16 + localStorage.setItem("theme", "dark"); 17 + } else { 18 + document.documentElement.setAttribute("data-theme", "light"); 19 + localStorage.setItem("theme", "light"); 20 + } 21 + } 22 + themeSwitch.addEventListener("click", switchTheme);