Add more localization support and optimize container listing UI
1. Backend Changes:
- Renamed uploadimage.go to uploadcontainerimage.go.
- Removed unused `CreatedStr` field from HumanReadableContainer struct in `containers.go`.
- Added localization support by fetching localized YAML data to be used in the container manager UI.
2. HTML Template Updates:
- Replaced static titles and labels with dynamic localized strings in `containerlist.gohtml` and `manager.gohtml`.
- Modified error divs to use the HTML `hidden` attribute for cleaner HTML in `manager.gohtml`.
- Added table headers and made layout adjustments for better readability in `containerlist.gohtml`.
3. Localization:
- Added English and French translations for container management UI in `locstrings.yml`.- commit
- eb3ea65f67fe7dcd53b133bd66d25e19651c77b5
- author
- bnema · · 2023-10-04 14:29 UTC
- parent
- a3dc094
- signature
- unsigned
5 files · +83 -124
M internal/httpserve/handler/containers.go +5 -3
| @@ -118,8 +118,6 @@ func ContainerManagerComponent(c echo.Context, a *app.App) error { | |||
| 118 | 118 | ||
| 119 | 119 | for _, container := range containers { | |
| 120 | 120 | localContainer := container // Make a local copy | |
| 121 | - | createdTime := time.Unix(container.Created, 0) | |
| 122 | - | createdStr := humanize.TimeAgo(createdTime) | |
| 123 | 121 | sizeStr := humanize.BytesToReadableSize(container.SizeRw) | |
| 124 | 122 | stateColor := "green" | |
| 125 | 123 | ||
| @@ -136,7 +134,6 @@ func ContainerManagerComponent(c echo.Context, a *app.App) error { | |||
| 136 | 134 | name = name[1:] | |
| 137 | 135 | humanReadableContainers = append(humanReadableContainers, HumanReadableContainer{ | |
| 138 | 136 | Container: &localContainer, | |
| 139 | - | CreatedStr: createdStr, | |
| 140 | 137 | SizeStr: sizeStr, | |
| 141 | 138 | UpSince: humanize.TimeAgo(time.Unix(container.Created, 0)), | |
| 142 | 139 | StateColor: stateColor, | |
| @@ -145,7 +142,12 @@ func ContainerManagerComponent(c echo.Context, a *app.App) error { | |||
| 145 | 142 | }) | |
| 146 | 143 | } | |
| 147 | 144 | } | |
| 145 | + | yamlData, err := GetLocalizedData(c, a) | |
| 146 | + | if err != nil { | |
| 147 | + | return err | |
| 148 | + | } | |
| 148 | 149 | data := map[string]interface{}{ | |
| 150 | + | "Lang": yamlData["Lang"], | |
| 149 | 151 | "containers": humanReadableContainers, | |
| 150 | 152 | } | |
| 151 | 153 | ||
| @@ -118,8 +118,6 @@ func ContainerManagerComponent(c echo.Context, a *app.App) error { | |||||
| 118 | 118 | ||||
| 119 | for _, container := range containers { | 119 | for _, container := range containers { | ||
| 120 | localContainer := container // Make a local copy | 120 | localContainer := container // Make a local copy | ||
| 121 | - | createdTime := time.Unix(container.Created, 0) | |||
| 122 | - | createdStr := humanize.TimeAgo(createdTime) | |||
| 123 | sizeStr := humanize.BytesToReadableSize(container.SizeRw) | 121 | sizeStr := humanize.BytesToReadableSize(container.SizeRw) | ||
| 124 | stateColor := "green" | 122 | stateColor := "green" | ||
| 125 | 123 | ||||
| @@ -136,7 +134,6 @@ func ContainerManagerComponent(c echo.Context, a *app.App) error { | |||||
| 136 | name = name[1:] | 134 | name = name[1:] | ||
| 137 | humanReadableContainers = append(humanReadableContainers, HumanReadableContainer{ | 135 | humanReadableContainers = append(humanReadableContainers, HumanReadableContainer{ | ||
| 138 | Container: &localContainer, | 136 | Container: &localContainer, | ||
| 139 | - | CreatedStr: createdStr, | |||
| 140 | SizeStr: sizeStr, | 137 | SizeStr: sizeStr, | ||
| 141 | UpSince: humanize.TimeAgo(time.Unix(container.Created, 0)), | 138 | UpSince: humanize.TimeAgo(time.Unix(container.Created, 0)), | ||
| 142 | StateColor: stateColor, | 139 | StateColor: stateColor, | ||
| @@ -145,7 +142,12 @@ func ContainerManagerComponent(c echo.Context, a *app.App) error { | |||||
| 145 | }) | 142 | }) | ||
| 146 | } | 143 | } | ||
| 147 | } | 144 | } | ||
| 145 | + | yamlData, err := GetLocalizedData(c, a) | |||
| 146 | + | if err != nil { | |||
| 147 | + | return err | |||
| 148 | + | } | |||
| 148 | data := map[string]interface{}{ | 149 | data := map[string]interface{}{ | ||
| 150 | + | "Lang": yamlData["Lang"], | |||
| 149 | "containers": humanReadableContainers, | 151 | "containers": humanReadableContainers, | ||
| 150 | } | 152 | } | ||
| 151 | 153 | ||||
M internal/templates/models/html/admin/manager.gohtml +2 -2
| @@ -20,7 +20,7 @@ | |||
| 20 | 20 | hx-target-error="container-manager-error" | |
| 21 | 21 | hx-poll="5s" | |
| 22 | 22 | ></div> | |
| 23 | - | <div id="container-manager-error" style="display: none"></div> | |
| 23 | + | <div id="container-manager-error" hidden></div> | |
| 24 | 24 | <!-- List all the images --> | |
| 25 | 25 | <div | |
| 26 | 26 | id="image-manager" | |
| @@ -31,7 +31,7 @@ | |||
| 31 | 31 | hx-target-error="image-manager-error" | |
| 32 | 32 | hx-poll="5s" | |
| 33 | 33 | ></div> | |
| 34 | - | <div id="image-manager-error" style="display: none"></div> | |
| 34 | + | <div id="image-manager-error" hidden></div> | |
| 35 | 35 | </div> | |
| 36 | 36 | </div> | |
| 37 | 37 | ||
| @@ -20,7 +20,7 @@ | |||||
| 20 | hx-target-error="container-manager-error" | 20 | hx-target-error="container-manager-error" | ||
| 21 | hx-poll="5s" | 21 | hx-poll="5s" | ||
| 22 | ></div> | 22 | ></div> | ||
| 23 | - | <div id="container-manager-error" style="display: none"></div> | 23 | + | <div id="container-manager-error" hidden></div> |
| 24 | <!-- List all the images --> | 24 | <!-- List all the images --> | ||
| 25 | <div | 25 | <div | ||
| 26 | id="image-manager" | 26 | id="image-manager" | ||
| @@ -31,7 +31,7 @@ | |||||
| 31 | hx-target-error="image-manager-error" | 31 | hx-target-error="image-manager-error" | ||
| 32 | hx-poll="5s" | 32 | hx-poll="5s" | ||
| 33 | ></div> | 33 | ></div> | ||
| 34 | - | <div id="image-manager-error" style="display: none"></div> | 34 | + | <div id="image-manager-error" hidden></div> |
| 35 | </div> | 35 | </div> | ||
| 36 | </div> | 36 | </div> | ||
| 37 | 37 | ||||
M internal/templates/models/html/fragments/containerlist.gohtml +23 -22
| @@ -1,33 +1,34 @@ | |||
| 1 | 1 | <div class="flex flex-col p-4" hx-boost="true"> | |
| 2 | - | <h1 class="text-lg md:text-xl font-bold">Containers</h1> | |
| 3 | - | <table class="p-4 border-t-2" hx-ext="response-targets"> | |
| 4 | - | <!-- <thead> | |
| 5 | - | <tr> | |
| 6 | - | <th>Name</th> | |
| 7 | - | <th>Command</th> | |
| 8 | - | <th>Created</th> | |
| 9 | - | <th>Status</th> | |
| 10 | - | <th>Port</th> | |
| 11 | - | <th>State</th> | |
| 12 | - | <th>Action</th> | |
| 2 | + | <h1 class="text-lg md:text-xl font-bold"> | |
| 3 | + | {{index .Lang "manager" "content" "h1-containers"}} | |
| 4 | + | </h1> | |
| 5 | + | <table class="p-4 border-t-2 table-auto" hx-ext="response-targets"> | |
| 6 | + | <thead> | |
| 7 | + | <tr class="text-center text-gray-400"> | |
| 8 | + | <th>{{index .Lang "manager" "content" "thName"}}</th> | |
| 9 | + | <th>{{index .Lang "manager" "content" "thPorts"}}</th> | |
| 10 | + | <th>{{index .Lang "manager" "content" "thStatus"}}</th> | |
| 11 | + | <th>{{index .Lang "manager" "content" "thState"}}</th> | |
| 12 | + | <th>{{index .Lang "manager" "content" "thActions"}}</th> | |
| 13 | 13 | </tr> | |
| 14 | - | </thead> --> | |
| 14 | + | </thead> | |
| 15 | 15 | <tbody> | |
| 16 | + | {{ $Lang := .Lang }} | |
| 16 | 17 | {{ | |
| 17 | 18 | range.containers | |
| 18 | 19 | }} | |
| 19 | - | <tr id="container-{{.ID}}"> | |
| 20 | + | <tr id="container-{{.ID}}" class="text-center"> | |
| 20 | 21 | <td> | |
| 21 | - | <span title="{{.Container.ID}}">{{.Name}}</span> | |
| 22 | - | </td> | |
| 23 | - | <td class="command-container" style="text-decoration: underline"> | |
| 24 | - | <span title="{{.Command}}">{{.Command}}</span> | |
| 22 | + | <span | |
| 23 | + | title="{{.Container.ID}}" | |
| 24 | + | class="font-bold" | |
| 25 | + | >{{.Name}}</span | |
| 26 | + | > | |
| 25 | 27 | </td> | |
| 26 | - | <td>{{.CreatedStr}}</td> | |
| 27 | 28 | <td class="port-container">{{ .Ports }}</td> | |
| 28 | 29 | <td class="status-container">{{.Status}} (Up since {{.UpSince}})</td> | |
| 29 | 30 | <td style="color: {{.StateColor}};">{{.State}}</td> | |
| 30 | - | <td align="right"> | |
| 31 | + | <td> | |
| 31 | 32 | <!-- iconoir start --> | |
| 32 | 33 | <button | |
| 33 | 34 | id="start-button-{{.ID}}" | |
| @@ -46,7 +47,7 @@ | |||
| 46 | 47 | hx-target="#container-{{.ID}}" | |
| 47 | 48 | hx-target-*="#error-message-{{.ID}}" | |
| 48 | 49 | hx-swap="innerHTML" | |
| 49 | - | hx-confirm="Are you sure you want to stop this container?" | |
| 50 | + | hx-confirm="{{index $Lang "manager" "content" "confirm-container-stop"}}" | |
| 50 | 51 | class="py-2 px-4" | |
| 51 | 52 | > | |
| 52 | 53 | <span class="iconoir-system-shut text-xl font-bold"></span> | |
| @@ -70,7 +71,7 @@ | |||
| 70 | 71 | hx-target="#container-{{.ID}}" | |
| 71 | 72 | hx-target-*="#error-message-{{.ID}}" | |
| 72 | 73 | hx-swap="innerHTML" | |
| 73 | - | hx-confirm="Are you sure you want to delete this container image?" | |
| 74 | + | hx-confirm="{{index $Lang "manager" "content" "confirm-delete"}}" | |
| 74 | 75 | class="py-2 px-4" | |
| 75 | 76 | > | |
| 76 | 77 | <!-- iconoir trash --> | |
| @@ -90,7 +91,7 @@ | |||
| 90 | 91 | </tr> | |
| 91 | 92 | {{ else }} | |
| 92 | 93 | <tr> | |
| 93 | - | <td colspan="7" class="mt-2">No available containers.</td> | |
| 94 | + | <td colspan="7" class="mt-2">{{index $Lang "manager" "content" "no-containers"}}.</td> | |
| 94 | 95 | </tr> | |
| 95 | 96 | {{ | |
| 96 | 97 | end | |
| @@ -1,33 +1,34 @@ | |||||
| 1 | <div class="flex flex-col p-4" hx-boost="true"> | 1 | <div class="flex flex-col p-4" hx-boost="true"> | ||
| 2 | - | <h1 class="text-lg md:text-xl font-bold">Containers</h1> | 2 | + | <h1 class="text-lg md:text-xl font-bold"> |
| 3 | - | <table class="p-4 border-t-2" hx-ext="response-targets"> | 3 | + | {{index .Lang "manager" "content" "h1-containers"}} |
| 4 | - | <!-- <thead> | 4 | + | </h1> |
| 5 | - | <tr> | 5 | + | <table class="p-4 border-t-2 table-auto" hx-ext="response-targets"> |
| 6 | - | <th>Name</th> | 6 | + | <thead> |
| 7 | - | <th>Command</th> | 7 | + | <tr class="text-center text-gray-400"> |
| 8 | - | <th>Created</th> | 8 | + | <th>{{index .Lang "manager" "content" "thName"}}</th> |
| 9 | - | <th>Status</th> | 9 | + | <th>{{index .Lang "manager" "content" "thPorts"}}</th> |
| 10 | - | <th>Port</th> | 10 | + | <th>{{index .Lang "manager" "content" "thStatus"}}</th> |
| 11 | - | <th>State</th> | 11 | + | <th>{{index .Lang "manager" "content" "thState"}}</th> |
| 12 | - | <th>Action</th> | 12 | + | <th>{{index .Lang "manager" "content" "thActions"}}</th> |
| 13 | </tr> | 13 | </tr> | ||
| 14 | - | </thead> --> | 14 | + | </thead> |
| 15 | <tbody> | 15 | <tbody> | ||
| 16 | + | {{ $Lang := .Lang }} | |||
| 16 | {{ | 17 | {{ | ||
| 17 | range.containers | 18 | range.containers | ||
| 18 | }} | 19 | }} | ||
| 19 | - | <tr id="container-{{.ID}}"> | 20 | + | <tr id="container-{{.ID}}" class="text-center"> |
| 20 | <td> | 21 | <td> | ||
| 21 | - | <span title="{{.Container.ID}}">{{.Name}}</span> | 22 | + | <span |
| 22 | - | </td> | 23 | + | title="{{.Container.ID}}" |
| 23 | - | <td class="command-container" style="text-decoration: underline"> | 24 | + | class="font-bold" |
| 24 | - | <span title="{{.Command}}">{{.Command}}</span> | 25 | + | >{{.Name}}</span |
| 26 | + | > | |||
| 25 | </td> | 27 | </td> | ||
| 26 | - | <td>{{.CreatedStr}}</td> | |||
| 27 | <td class="port-container">{{ .Ports }}</td> | 28 | <td class="port-container">{{ .Ports }}</td> | ||
| 28 | <td class="status-container">{{.Status}} (Up since {{.UpSince}})</td> | 29 | <td class="status-container">{{.Status}} (Up since {{.UpSince}})</td> | ||
| 29 | <td style="color: {{.StateColor}};">{{.State}}</td> | 30 | <td style="color: {{.StateColor}};">{{.State}}</td> | ||
| 30 | - | <td align="right"> | 31 | + | <td> |
| 31 | <!-- iconoir start --> | 32 | <!-- iconoir start --> | ||
| 32 | <button | 33 | <button | ||
| 33 | id="start-button-{{.ID}}" | 34 | id="start-button-{{.ID}}" | ||
| @@ -46,7 +47,7 @@ | |||||
| 46 | hx-target="#container-{{.ID}}" | 47 | hx-target="#container-{{.ID}}" | ||
| 47 | hx-target-*="#error-message-{{.ID}}" | 48 | hx-target-*="#error-message-{{.ID}}" | ||
| 48 | hx-swap="innerHTML" | 49 | hx-swap="innerHTML" | ||
| 49 | - | hx-confirm="Are you sure you want to stop this container?" | 50 | + | hx-confirm="{{index $Lang "manager" "content" "confirm-container-stop"}}" |
| 50 | class="py-2 px-4" | 51 | class="py-2 px-4" | ||
| 51 | > | 52 | > | ||
| 52 | <span class="iconoir-system-shut text-xl font-bold"></span> | 53 | <span class="iconoir-system-shut text-xl font-bold"></span> | ||
| @@ -70,7 +71,7 @@ | |||||
| 70 | hx-target="#container-{{.ID}}" | 71 | hx-target="#container-{{.ID}}" | ||
| 71 | hx-target-*="#error-message-{{.ID}}" | 72 | hx-target-*="#error-message-{{.ID}}" | ||
| 72 | hx-swap="innerHTML" | 73 | hx-swap="innerHTML" | ||
| 73 | - | hx-confirm="Are you sure you want to delete this container image?" | 74 | + | hx-confirm="{{index $Lang "manager" "content" "confirm-delete"}}" |
| 74 | class="py-2 px-4" | 75 | class="py-2 px-4" | ||
| 75 | > | 76 | > | ||
| 76 | <!-- iconoir trash --> | 77 | <!-- iconoir trash --> | ||
| @@ -90,7 +91,7 @@ | |||||
| 90 | </tr> | 91 | </tr> | ||
| 91 | {{ else }} | 92 | {{ else }} | ||
| 92 | <tr> | 93 | <tr> | ||
| 93 | - | <td colspan="7" class="mt-2">No available containers.</td> | 94 | + | <td colspan="7" class="mt-2">{{index $Lang "manager" "content" "no-containers"}}.</td> |
| 94 | </tr> | 95 | </tr> | ||
| 95 | {{ | 96 | {{ | ||
| 96 | end | 97 | end | ||
M internal/templates/models/locstrings.yml +23 -1
| @@ -20,6 +20,17 @@ en: | |||
| 20 | 20 | title: Gordon - Container Engine Manager | |
| 21 | 21 | content: | |
| 22 | 22 | title: Container Engine Manager | |
| 23 | + | h1-containers: Containers | |
| 24 | + | h1-images: Images | |
| 25 | + | button-upload: Upload | |
| 26 | + | confirm-delete: Are you sure you want to delete this? | |
| 27 | + | confirm-container-stop: Are you sure you want to stop this container? | |
| 28 | + | no-containers: No available containers. | |
| 29 | + | thName: Name | |
| 30 | + | thPorts: Ports | |
| 31 | + | thStatus: Status | |
| 32 | + | thState: State | |
| 33 | + | thActions: Actions | |
| 23 | 34 | settings: | |
| 24 | 35 | meta: | |
| 25 | 36 | title: Gordon - Settings | |
| @@ -32,7 +43,7 @@ fr: | |||
| 32 | 43 | description: Interface d'administration pour Gordon | |
| 33 | 44 | keywords: gordon, admin, interface | |
| 34 | 45 | header: | |
| 35 | - | someKey: Bonjour le monde! | |
| 46 | + | someKey: Bonjour le monde ! | |
| 36 | 47 | navmenu: | |
| 37 | 48 | dashboard: Tableau de bord | |
| 38 | 49 | manager: Gestionnaire | |
| @@ -48,6 +59,17 @@ fr: | |||
| 48 | 59 | title: Gordon - Gestionnaire de moteur de conteneur | |
| 49 | 60 | content: | |
| 50 | 61 | title: Gestionnaire de moteur de conteneur | |
| 62 | + | h1-containers: Conteneurs | |
| 63 | + | h1-images: Images | |
| 64 | + | button-upload: Télécharger | |
| 65 | + | confirm-delete: Êtes-vous sûr de vouloir supprimer ceci? | |
| 66 | + | confirm-container-stop: Êtes-vous sûr de vouloir arrêter ce conteneur? | |
| 67 | + | no-containers: Aucun conteneur disponible. | |
| 68 | + | thName: Nom | |
| 69 | + | thPorts: Ports | |
| 70 | + | thStatus: Statut | |
| 71 | + | thState: État | |
| 72 | + | thActions: Actions | |
| 51 | 73 | settings: | |
| 52 | 74 | meta: | |
| 53 | 75 | title: Gordon - Paramètres | |
| @@ -20,6 +20,17 @@ en: | |||||
| 20 | title: Gordon - Container Engine Manager | 20 | title: Gordon - Container Engine Manager | ||
| 21 | content: | 21 | content: | ||
| 22 | title: Container Engine Manager | 22 | title: Container Engine Manager | ||
| 23 | + | h1-containers: Containers | |||
| 24 | + | h1-images: Images | |||
| 25 | + | button-upload: Upload | |||
| 26 | + | confirm-delete: Are you sure you want to delete this? | |||
| 27 | + | confirm-container-stop: Are you sure you want to stop this container? | |||
| 28 | + | no-containers: No available containers. | |||
| 29 | + | thName: Name | |||
| 30 | + | thPorts: Ports | |||
| 31 | + | thStatus: Status | |||
| 32 | + | thState: State | |||
| 33 | + | thActions: Actions | |||
| 23 | settings: | 34 | settings: | ||
| 24 | meta: | 35 | meta: | ||
| 25 | title: Gordon - Settings | 36 | title: Gordon - Settings | ||
| @@ -32,7 +43,7 @@ fr: | |||||
| 32 | description: Interface d'administration pour Gordon | 43 | description: Interface d'administration pour Gordon | ||
| 33 | keywords: gordon, admin, interface | 44 | keywords: gordon, admin, interface | ||
| 34 | header: | 45 | header: | ||
| 35 | - | someKey: Bonjour le monde! | 46 | + | someKey: Bonjour le monde ! |
| 36 | navmenu: | 47 | navmenu: | ||
| 37 | dashboard: Tableau de bord | 48 | dashboard: Tableau de bord | ||
| 38 | manager: Gestionnaire | 49 | manager: Gestionnaire | ||
| @@ -48,6 +59,17 @@ fr: | |||||
| 48 | title: Gordon - Gestionnaire de moteur de conteneur | 59 | title: Gordon - Gestionnaire de moteur de conteneur | ||
| 49 | content: | 60 | content: | ||
| 50 | title: Gestionnaire de moteur de conteneur | 61 | title: Gestionnaire de moteur de conteneur | ||
| 62 | + | h1-containers: Conteneurs | |||
| 63 | + | h1-images: Images | |||
| 64 | + | button-upload: Télécharger | |||
| 65 | + | confirm-delete: Êtes-vous sûr de vouloir supprimer ceci? | |||
| 66 | + | confirm-container-stop: Êtes-vous sûr de vouloir arrêter ce conteneur? | |||
| 67 | + | no-containers: Aucun conteneur disponible. | |||
| 68 | + | thName: Nom | |||
| 69 | + | thPorts: Ports | |||
| 70 | + | thStatus: Statut | |||
| 71 | + | thState: État | |||
| 72 | + | thActions: Actions | |||
| 51 | settings: | 73 | settings: | ||
| 52 | meta: | 74 | meta: | ||
| 53 | title: Gordon - Paramètres | 75 | title: Gordon - Paramètres | ||
M internal/webui/public/assets/css/tailwind.css +30 -96
| @@ -575,10 +575,6 @@ video { | |||
| 575 | 575 | } | |
| 576 | 576 | } | |
| 577 | 577 | ||
| 578 | - | .fixed { | |
| 579 | - | position: fixed; | |
| 580 | - | } | |
| 581 | - | ||
| 582 | 578 | .my-2 { | |
| 583 | 579 | margin-top: 0.5rem; | |
| 584 | 580 | margin-bottom: 0.5rem; | |
| @@ -676,24 +672,11 @@ video { | |||
| 676 | 672 | width: 100%; | |
| 677 | 673 | } | |
| 678 | 674 | ||
| 679 | - | .w-10 { | |
| 680 | - | width: 2.5rem; | |
| 681 | - | } | |
| 682 | - | ||
| 683 | 675 | .min-w-fit { | |
| 684 | 676 | min-width: -moz-fit-content; | |
| 685 | 677 | min-width: fit-content; | |
| 686 | 678 | } | |
| 687 | 679 | ||
| 688 | - | .max-w-fit { | |
| 689 | - | max-width: -moz-fit-content; | |
| 690 | - | max-width: fit-content; | |
| 691 | - | } | |
| 692 | - | ||
| 693 | - | .max-w-screen-lg { | |
| 694 | - | max-width: 1024px; | |
| 695 | - | } | |
| 696 | - | ||
| 697 | 680 | .flex-1 { | |
| 698 | 681 | flex: 1 1 0%; | |
| 699 | 682 | } | |
| @@ -702,6 +685,14 @@ video { | |||
| 702 | 685 | flex-grow: 1; | |
| 703 | 686 | } | |
| 704 | 687 | ||
| 688 | + | .table-auto { | |
| 689 | + | table-layout: auto; | |
| 690 | + | } | |
| 691 | + | ||
| 692 | + | .table-fixed { | |
| 693 | + | table-layout: fixed; | |
| 694 | + | } | |
| 695 | + | ||
| 705 | 696 | .flex-row { | |
| 706 | 697 | flex-direction: row; | |
| 707 | 698 | } | |
| @@ -730,10 +721,6 @@ video { | |||
| 730 | 721 | justify-content: space-between; | |
| 731 | 722 | } | |
| 732 | 723 | ||
| 733 | - | .justify-evenly { | |
| 734 | - | justify-content: space-evenly; | |
| 735 | - | } | |
| 736 | - | ||
| 737 | 724 | .justify-items-center { | |
| 738 | 725 | justify-items: center; | |
| 739 | 726 | } | |
| @@ -879,6 +866,14 @@ video { | |||
| 879 | 866 | padding-bottom: 1rem; | |
| 880 | 867 | } | |
| 881 | 868 | ||
| 869 | + | .text-left { | |
| 870 | + | text-align: left; | |
| 871 | + | } | |
| 872 | + | ||
| 873 | + | .text-center { | |
| 874 | + | text-align: center; | |
| 875 | + | } | |
| 876 | + | ||
| 882 | 877 | .align-middle { | |
| 883 | 878 | vertical-align: middle; | |
| 884 | 879 | } | |
| @@ -888,6 +883,11 @@ video { | |||
| 888 | 883 | line-height: 2rem; | |
| 889 | 884 | } | |
| 890 | 885 | ||
| 886 | + | .text-3xl { | |
| 887 | + | font-size: 1.875rem; | |
| 888 | + | line-height: 2.25rem; | |
| 889 | + | } | |
| 890 | + | ||
| 891 | 891 | .text-4xl { | |
| 892 | 892 | font-size: 2.25rem; | |
| 893 | 893 | line-height: 2.5rem; | |
| @@ -913,15 +913,14 @@ video { | |||
| 913 | 913 | line-height: 1.75rem; | |
| 914 | 914 | } | |
| 915 | 915 | ||
| 916 | - | .text-3xl { | |
| 917 | - | font-size: 1.875rem; | |
| 918 | - | line-height: 2.25rem; | |
| 919 | - | } | |
| 920 | - | ||
| 921 | 916 | .font-bold { | |
| 922 | 917 | font-weight: 700; | |
| 923 | 918 | } | |
| 924 | 919 | ||
| 920 | + | .font-light { | |
| 921 | + | font-weight: 300; | |
| 922 | + | } | |
| 923 | + | ||
| 925 | 924 | .font-semibold { | |
| 926 | 925 | font-weight: 600; | |
| 927 | 926 | } | |
| @@ -955,6 +954,11 @@ video { | |||
| 955 | 954 | color: rgb(243 244 246 / var(--tw-text-opacity)); | |
| 956 | 955 | } | |
| 957 | 956 | ||
| 957 | + | .text-gray-400 { | |
| 958 | + | --tw-text-opacity: 1; | |
| 959 | + | color: rgb(156 163 175 / var(--tw-text-opacity)); | |
| 960 | + | } | |
| 961 | + | ||
| 958 | 962 | .text-gray-500 { | |
| 959 | 963 | --tw-text-opacity: 1; | |
| 960 | 964 | color: rgb(107 114 128 / var(--tw-text-opacity)); | |
| @@ -990,10 +994,6 @@ video { | |||
| 990 | 994 | color: rgb(255 255 255 / var(--tw-text-opacity)); | |
| 991 | 995 | } | |
| 992 | 996 | ||
| 993 | - | .underline { | |
| 994 | - | text-decoration-line: underline; | |
| 995 | - | } | |
| 996 | - | ||
| 997 | 997 | .shadow { | |
| 998 | 998 | --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); | |
| 999 | 999 | --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); | |
| @@ -1154,50 +1154,18 @@ video { | |||
| 1154 | 1154 | display: flex; | |
| 1155 | 1155 | } | |
| 1156 | 1156 | ||
| 1157 | - | .md\:hidden { | |
| 1158 | - | display: none; | |
| 1159 | - | } | |
| 1160 | - | ||
| 1161 | 1157 | .md\:w-1\/2 { | |
| 1162 | 1158 | width: 50%; | |
| 1163 | 1159 | } | |
| 1164 | 1160 | ||
| 1165 | - | .md\:w-1\/5 { | |
| 1166 | - | width: 20%; | |
| 1167 | - | } | |
| 1168 | - | ||
| 1169 | 1161 | .md\:w-2\/6 { | |
| 1170 | 1162 | width: 33.333333%; | |
| 1171 | 1163 | } | |
| 1172 | 1164 | ||
| 1173 | - | .md\:w-full { | |
| 1174 | - | width: 100%; | |
| 1175 | - | } | |
| 1176 | - | ||
| 1177 | - | .md\:w-4\/5 { | |
| 1178 | - | width: 80%; | |
| 1179 | - | } | |
| 1180 | - | ||
| 1181 | - | .md\:w-72 { | |
| 1182 | - | width: 18rem; | |
| 1183 | - | } | |
| 1184 | - | ||
| 1185 | - | .md\:w-64 { | |
| 1186 | - | width: 16rem; | |
| 1187 | - | } | |
| 1188 | - | ||
| 1189 | - | .md\:max-w-screen-lg { | |
| 1190 | - | max-width: 1024px; | |
| 1191 | - | } | |
| 1192 | - | ||
| 1193 | 1165 | .md\:flex-row { | |
| 1194 | 1166 | flex-direction: row; | |
| 1195 | 1167 | } | |
| 1196 | 1168 | ||
| 1197 | - | .md\:flex-col { | |
| 1198 | - | flex-direction: column; | |
| 1199 | - | } | |
| 1200 | - | ||
| 1201 | 1169 | .md\:space-x-4 > :not([hidden]) ~ :not([hidden]) { | |
| 1202 | 1170 | --tw-space-x-reverse: 0; | |
| 1203 | 1171 | margin-right: calc(1rem * var(--tw-space-x-reverse)); | |
| @@ -1210,12 +1178,6 @@ video { | |||
| 1210 | 1178 | margin-bottom: calc(0px * var(--tw-space-y-reverse)); | |
| 1211 | 1179 | } | |
| 1212 | 1180 | ||
| 1213 | - | .md\:space-y-6 > :not([hidden]) ~ :not([hidden]) { | |
| 1214 | - | --tw-space-y-reverse: 0; | |
| 1215 | - | margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse))); | |
| 1216 | - | margin-bottom: calc(1.5rem * var(--tw-space-y-reverse)); | |
| 1217 | - | } | |
| 1218 | - | ||
| 1219 | 1181 | .md\:p-0 { | |
| 1220 | 1182 | padding: 0px; | |
| 1221 | 1183 | } | |
| @@ -1224,11 +1186,6 @@ video { | |||
| 1224 | 1186 | padding: 2rem; | |
| 1225 | 1187 | } | |
| 1226 | 1188 | ||
| 1227 | - | .md\:py-8 { | |
| 1228 | - | padding-top: 2rem; | |
| 1229 | - | padding-bottom: 2rem; | |
| 1230 | - | } | |
| 1231 | - | ||
| 1232 | 1189 | .md\:pt-10 { | |
| 1233 | 1190 | padding-top: 2.5rem; | |
| 1234 | 1191 | } | |
| @@ -1238,11 +1195,6 @@ video { | |||
| 1238 | 1195 | line-height: 2rem; | |
| 1239 | 1196 | } | |
| 1240 | 1197 | ||
| 1241 | - | .md\:text-3xl { | |
| 1242 | - | font-size: 1.875rem; | |
| 1243 | - | line-height: 2.25rem; | |
| 1244 | - | } | |
| 1245 | - | ||
| 1246 | 1198 | .md\:text-xl { | |
| 1247 | 1199 | font-size: 1.25rem; | |
| 1248 | 1200 | line-height: 1.75rem; | |
| @@ -1254,10 +1206,6 @@ video { | |||
| 1254 | 1206 | display: flex; | |
| 1255 | 1207 | } | |
| 1256 | 1208 | ||
| 1257 | - | .lg\:w-72 { | |
| 1258 | - | width: 18rem; | |
| 1259 | - | } | |
| 1260 | - | ||
| 1261 | 1209 | .lg\:w-64 { | |
| 1262 | 1210 | width: 16rem; | |
| 1263 | 1211 | } | |
| @@ -1278,10 +1226,6 @@ video { | |||
| 1278 | 1226 | justify-content: flex-start; | |
| 1279 | 1227 | } | |
| 1280 | 1228 | ||
| 1281 | - | .lg\:justify-center { | |
| 1282 | - | justify-content: center; | |
| 1283 | - | } | |
| 1284 | - | ||
| 1285 | 1229 | .lg\:space-y-6 > :not([hidden]) ~ :not([hidden]) { | |
| 1286 | 1230 | --tw-space-y-reverse: 0; | |
| 1287 | 1231 | margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse))); | |
| @@ -1297,16 +1241,6 @@ video { | |||
| 1297 | 1241 | font-size: 2.25rem; | |
| 1298 | 1242 | line-height: 2.5rem; | |
| 1299 | 1243 | } | |
| 1300 | - | ||
| 1301 | - | .lg\:text-2xl { | |
| 1302 | - | font-size: 1.5rem; | |
| 1303 | - | line-height: 2rem; | |
| 1304 | - | } | |
| 1305 | - | ||
| 1306 | - | .lg\:text-3xl { | |
| 1307 | - | font-size: 1.875rem; | |
| 1308 | - | line-height: 2.25rem; | |
| 1309 | - | } | |
| 1310 | 1244 | } | |
| 1311 | 1245 | ||
| 1312 | 1246 | @media (min-width: 1280px) { | |
| @@ -575,10 +575,6 @@ video { | |||||
| 575 | } | 575 | } | ||
| 576 | } | 576 | } | ||
| 577 | 577 | ||||
| 578 | - | .fixed { | |||
| 579 | - | position: fixed; | |||
| 580 | - | } | |||
| 581 | - | ||||
| 582 | .my-2 { | 578 | .my-2 { | ||
| 583 | margin-top: 0.5rem; | 579 | margin-top: 0.5rem; | ||
| 584 | margin-bottom: 0.5rem; | 580 | margin-bottom: 0.5rem; | ||
| @@ -676,24 +672,11 @@ video { | |||||
| 676 | width: 100%; | 672 | width: 100%; | ||
| 677 | } | 673 | } | ||
| 678 | 674 | ||||
| 679 | - | .w-10 { | |||
| 680 | - | width: 2.5rem; | |||
| 681 | - | } | |||
| 682 | - | ||||
| 683 | .min-w-fit { | 675 | .min-w-fit { | ||
| 684 | min-width: -moz-fit-content; | 676 | min-width: -moz-fit-content; | ||
| 685 | min-width: fit-content; | 677 | min-width: fit-content; | ||
| 686 | } | 678 | } | ||
| 687 | 679 | ||||
| 688 | - | .max-w-fit { | |||
| 689 | - | max-width: -moz-fit-content; | |||
| 690 | - | max-width: fit-content; | |||
| 691 | - | } | |||
| 692 | - | ||||
| 693 | - | .max-w-screen-lg { | |||
| 694 | - | max-width: 1024px; | |||
| 695 | - | } | |||
| 696 | - | ||||
| 697 | .flex-1 { | 680 | .flex-1 { | ||
| 698 | flex: 1 1 0%; | 681 | flex: 1 1 0%; | ||
| 699 | } | 682 | } | ||
| @@ -702,6 +685,14 @@ video { | |||||
| 702 | flex-grow: 1; | 685 | flex-grow: 1; | ||
| 703 | } | 686 | } | ||
| 704 | 687 | ||||
| 688 | + | .table-auto { | |||
| 689 | + | table-layout: auto; | |||
| 690 | + | } | |||
| 691 | + | ||||
| 692 | + | .table-fixed { | |||
| 693 | + | table-layout: fixed; | |||
| 694 | + | } | |||
| 695 | + | ||||
| 705 | .flex-row { | 696 | .flex-row { | ||
| 706 | flex-direction: row; | 697 | flex-direction: row; | ||
| 707 | } | 698 | } | ||
| @@ -730,10 +721,6 @@ video { | |||||
| 730 | justify-content: space-between; | 721 | justify-content: space-between; | ||
| 731 | } | 722 | } | ||
| 732 | 723 | ||||
| 733 | - | .justify-evenly { | |||
| 734 | - | justify-content: space-evenly; | |||
| 735 | - | } | |||
| 736 | - | ||||
| 737 | .justify-items-center { | 724 | .justify-items-center { | ||
| 738 | justify-items: center; | 725 | justify-items: center; | ||
| 739 | } | 726 | } | ||
| @@ -879,6 +866,14 @@ video { | |||||
| 879 | padding-bottom: 1rem; | 866 | padding-bottom: 1rem; | ||
| 880 | } | 867 | } | ||
| 881 | 868 | ||||
| 869 | + | .text-left { | |||
| 870 | + | text-align: left; | |||
| 871 | + | } | |||
| 872 | + | ||||
| 873 | + | .text-center { | |||
| 874 | + | text-align: center; | |||
| 875 | + | } | |||
| 876 | + | ||||
| 882 | .align-middle { | 877 | .align-middle { | ||
| 883 | vertical-align: middle; | 878 | vertical-align: middle; | ||
| 884 | } | 879 | } | ||
| @@ -888,6 +883,11 @@ video { | |||||
| 888 | line-height: 2rem; | 883 | line-height: 2rem; | ||
| 889 | } | 884 | } | ||
| 890 | 885 | ||||
| 886 | + | .text-3xl { | |||
| 887 | + | font-size: 1.875rem; | |||
| 888 | + | line-height: 2.25rem; | |||
| 889 | + | } | |||
| 890 | + | ||||
| 891 | .text-4xl { | 891 | .text-4xl { | ||
| 892 | font-size: 2.25rem; | 892 | font-size: 2.25rem; | ||
| 893 | line-height: 2.5rem; | 893 | line-height: 2.5rem; | ||
| @@ -913,15 +913,14 @@ video { | |||||
| 913 | line-height: 1.75rem; | 913 | line-height: 1.75rem; | ||
| 914 | } | 914 | } | ||
| 915 | 915 | ||||
| 916 | - | .text-3xl { | |||
| 917 | - | font-size: 1.875rem; | |||
| 918 | - | line-height: 2.25rem; | |||
| 919 | - | } | |||
| 920 | - | ||||
| 921 | .font-bold { | 916 | .font-bold { | ||
| 922 | font-weight: 700; | 917 | font-weight: 700; | ||
| 923 | } | 918 | } | ||
| 924 | 919 | ||||
| 920 | + | .font-light { | |||
| 921 | + | font-weight: 300; | |||
| 922 | + | } | |||
| 923 | + | ||||
| 925 | .font-semibold { | 924 | .font-semibold { | ||
| 926 | font-weight: 600; | 925 | font-weight: 600; | ||
| 927 | } | 926 | } | ||
| @@ -955,6 +954,11 @@ video { | |||||
| 955 | color: rgb(243 244 246 / var(--tw-text-opacity)); | 954 | color: rgb(243 244 246 / var(--tw-text-opacity)); | ||
| 956 | } | 955 | } | ||
| 957 | 956 | ||||
| 957 | + | .text-gray-400 { | |||
| 958 | + | --tw-text-opacity: 1; | |||
| 959 | + | color: rgb(156 163 175 / var(--tw-text-opacity)); | |||
| 960 | + | } | |||
| 961 | + | ||||
| 958 | .text-gray-500 { | 962 | .text-gray-500 { | ||
| 959 | --tw-text-opacity: 1; | 963 | --tw-text-opacity: 1; | ||
| 960 | color: rgb(107 114 128 / var(--tw-text-opacity)); | 964 | color: rgb(107 114 128 / var(--tw-text-opacity)); | ||
| @@ -990,10 +994,6 @@ video { | |||||
| 990 | color: rgb(255 255 255 / var(--tw-text-opacity)); | 994 | color: rgb(255 255 255 / var(--tw-text-opacity)); | ||
| 991 | } | 995 | } | ||
| 992 | 996 | ||||
| 993 | - | .underline { | |||
| 994 | - | text-decoration-line: underline; | |||
| 995 | - | } | |||
| 996 | - | ||||
| 997 | .shadow { | 997 | .shadow { | ||
| 998 | --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); | 998 | --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); | ||
| 999 | --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); | 999 | --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); | ||
| @@ -1154,50 +1154,18 @@ video { | |||||
| 1154 | display: flex; | 1154 | display: flex; | ||
| 1155 | } | 1155 | } | ||
| 1156 | 1156 | ||||
| 1157 | - | .md\:hidden { | |||
| 1158 | - | display: none; | |||
| 1159 | - | } | |||
| 1160 | - | ||||
| 1161 | .md\:w-1\/2 { | 1157 | .md\:w-1\/2 { | ||
| 1162 | width: 50%; | 1158 | width: 50%; | ||
| 1163 | } | 1159 | } | ||
| 1164 | 1160 | ||||
| 1165 | - | .md\:w-1\/5 { | |||
| 1166 | - | width: 20%; | |||
| 1167 | - | } | |||
| 1168 | - | ||||
| 1169 | .md\:w-2\/6 { | 1161 | .md\:w-2\/6 { | ||
| 1170 | width: 33.333333%; | 1162 | width: 33.333333%; | ||
| 1171 | } | 1163 | } | ||
| 1172 | 1164 | ||||
| 1173 | - | .md\:w-full { | |||
| 1174 | - | width: 100%; | |||
| 1175 | - | } | |||
| 1176 | - | ||||
| 1177 | - | .md\:w-4\/5 { | |||
| 1178 | - | width: 80%; | |||
| 1179 | - | } | |||
| 1180 | - | ||||
| 1181 | - | .md\:w-72 { | |||
| 1182 | - | width: 18rem; | |||
| 1183 | - | } | |||
| 1184 | - | ||||
| 1185 | - | .md\:w-64 { | |||
| 1186 | - | width: 16rem; | |||
| 1187 | - | } | |||
| 1188 | - | ||||
| 1189 | - | .md\:max-w-screen-lg { | |||
| 1190 | - | max-width: 1024px; | |||
| 1191 | - | } | |||
| 1192 | - | ||||
| 1193 | .md\:flex-row { | 1165 | .md\:flex-row { | ||
| 1194 | flex-direction: row; | 1166 | flex-direction: row; | ||
| 1195 | } | 1167 | } | ||
| 1196 | 1168 | ||||
| 1197 | - | .md\:flex-col { | |||
| 1198 | - | flex-direction: column; | |||
| 1199 | - | } | |||
| 1200 | - | ||||
| 1201 | .md\:space-x-4 > :not([hidden]) ~ :not([hidden]) { | 1169 | .md\:space-x-4 > :not([hidden]) ~ :not([hidden]) { | ||
| 1202 | --tw-space-x-reverse: 0; | 1170 | --tw-space-x-reverse: 0; | ||
| 1203 | margin-right: calc(1rem * var(--tw-space-x-reverse)); | 1171 | margin-right: calc(1rem * var(--tw-space-x-reverse)); | ||
| @@ -1210,12 +1178,6 @@ video { | |||||
| 1210 | margin-bottom: calc(0px * var(--tw-space-y-reverse)); | 1178 | margin-bottom: calc(0px * var(--tw-space-y-reverse)); | ||
| 1211 | } | 1179 | } | ||
| 1212 | 1180 | ||||
| 1213 | - | .md\:space-y-6 > :not([hidden]) ~ :not([hidden]) { | |||
| 1214 | - | --tw-space-y-reverse: 0; | |||
| 1215 | - | margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse))); | |||
| 1216 | - | margin-bottom: calc(1.5rem * var(--tw-space-y-reverse)); | |||
| 1217 | - | } | |||
| 1218 | - | ||||
| 1219 | .md\:p-0 { | 1181 | .md\:p-0 { | ||
| 1220 | padding: 0px; | 1182 | padding: 0px; | ||
| 1221 | } | 1183 | } | ||
| @@ -1224,11 +1186,6 @@ video { | |||||
| 1224 | padding: 2rem; | 1186 | padding: 2rem; | ||
| 1225 | } | 1187 | } | ||
| 1226 | 1188 | ||||
| 1227 | - | .md\:py-8 { | |||
| 1228 | - | padding-top: 2rem; | |||
| 1229 | - | padding-bottom: 2rem; | |||
| 1230 | - | } | |||
| 1231 | - | ||||
| 1232 | .md\:pt-10 { | 1189 | .md\:pt-10 { | ||
| 1233 | padding-top: 2.5rem; | 1190 | padding-top: 2.5rem; | ||
| 1234 | } | 1191 | } | ||
| @@ -1238,11 +1195,6 @@ video { | |||||
| 1238 | line-height: 2rem; | 1195 | line-height: 2rem; | ||
| 1239 | } | 1196 | } | ||
| 1240 | 1197 | ||||
| 1241 | - | .md\:text-3xl { | |||
| 1242 | - | font-size: 1.875rem; | |||
| 1243 | - | line-height: 2.25rem; | |||
| 1244 | - | } | |||
| 1245 | - | ||||
| 1246 | .md\:text-xl { | 1198 | .md\:text-xl { | ||
| 1247 | font-size: 1.25rem; | 1199 | font-size: 1.25rem; | ||
| 1248 | line-height: 1.75rem; | 1200 | line-height: 1.75rem; | ||
| @@ -1254,10 +1206,6 @@ video { | |||||
| 1254 | display: flex; | 1206 | display: flex; | ||
| 1255 | } | 1207 | } | ||
| 1256 | 1208 | ||||
| 1257 | - | .lg\:w-72 { | |||
| 1258 | - | width: 18rem; | |||
| 1259 | - | } | |||
| 1260 | - | ||||
| 1261 | .lg\:w-64 { | 1209 | .lg\:w-64 { | ||
| 1262 | width: 16rem; | 1210 | width: 16rem; | ||
| 1263 | } | 1211 | } | ||
| @@ -1278,10 +1226,6 @@ video { | |||||
| 1278 | justify-content: flex-start; | 1226 | justify-content: flex-start; | ||
| 1279 | } | 1227 | } | ||
| 1280 | 1228 | ||||
| 1281 | - | .lg\:justify-center { | |||
| 1282 | - | justify-content: center; | |||
| 1283 | - | } | |||
| 1284 | - | ||||
| 1285 | .lg\:space-y-6 > :not([hidden]) ~ :not([hidden]) { | 1229 | .lg\:space-y-6 > :not([hidden]) ~ :not([hidden]) { | ||
| 1286 | --tw-space-y-reverse: 0; | 1230 | --tw-space-y-reverse: 0; | ||
| 1287 | margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse))); | 1231 | margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse))); | ||
| @@ -1297,16 +1241,6 @@ video { | |||||
| 1297 | font-size: 2.25rem; | 1241 | font-size: 2.25rem; | ||
| 1298 | line-height: 2.5rem; | 1242 | line-height: 2.5rem; | ||
| 1299 | } | 1243 | } | ||
| 1300 | - | ||||
| 1301 | - | .lg\:text-2xl { | |||
| 1302 | - | font-size: 1.5rem; | |||
| 1303 | - | line-height: 2rem; | |||
| 1304 | - | } | |||
| 1305 | - | ||||
| 1306 | - | .lg\:text-3xl { | |||
| 1307 | - | font-size: 1.875rem; | |||
| 1308 | - | line-height: 2.25rem; | |||
| 1309 | - | } | |||
| 1310 | } | 1244 | } | ||
| 1311 | 1245 | ||||
| 1312 | @media (min-width: 1280px) { | 1246 | @media (min-width: 1280px) { | ||