Changes
diff --git a/src/app.cpp b/src/app.cpp
index 8dd10ff..e713e5e 100644
--- a/src/app.cpp
+++ b/src/app.cpp
@@ -3964,10 +3964,15 @@ void App::handleCardIndex(
response.status = 403;
return;
}
+ const bool show_internal = !creator_route &&
+ request.has_param("show_internal") &&
+ request.get_param_value("show_internal") == "1";
auto cards_result = creator_route
? data_source_->getCardsByCreator(
actor->session.user.id, GameContentScope::PUBLIC_ONLY)
- : data_source_->getCards(GameContentScope::INCLUDE_INTERNAL);
+ : data_source_->getCards(show_internal
+ ? GameContentScope::INCLUDE_INTERNAL
+ : GameContentScope::PUBLIC_ONLY);
if(!cards_result)
{
spdlog::error(
@@ -4074,15 +4079,24 @@ void App::handleCardIndex(
const std::string index_route = creator_route
? "creator-cards"
: "card-index";
+ QueryParameters ascending_query = {{"sort", "id"}, {"direction", "asc"}};
+ QueryParameters descending_query = {{"sort", "id"}, {"direction", "desc"}};
+ if(show_internal)
+ {
+ ascending_query.emplace_back("show_internal", "1");
+ descending_query.emplace_back("show_internal", "1");
+ }
inja::json template_data = {
{"ascending_url",
- urlFor(index_route, {}, {{"sort", "id"}, {"direction", "asc"}})},
+ urlFor(index_route, {}, ascending_query)},
{"administrator", !creator_route},
{"cards", std::move(template_cards)},
{"create_url", urlFor("card-new")},
{"descending", descending},
{"descending_url",
- urlFor(index_route, {}, {{"sort", "id"}, {"direction", "desc"}})},
+ urlFor(index_route, {}, descending_query)},
+ {"index_url", urlFor(index_route)},
+ {"show_internal", show_internal},
{"games_url", urlFor("admin-games")},
{"series_url", urlFor("series-index")},
{"title", "Card Collection"},
diff --git a/static/css/styles.css b/static/css/styles.css
index d7cf7c4..72e8f45 100644
--- a/static/css/styles.css
+++ b/static/css/styles.css
@@ -1,47 +1,39 @@
-:root {
+:root
+{
color-scheme: light;
- font-family: "DM Sans", ui-sans-serif, system-ui, sans-serif;
- color: #332f3a;
- background: #f4f1fa;
- --canvas: #f4f1fa;
- --foreground: #332f3a;
- --muted: #635f69;
- --violet: #7c3aed;
- --violet-light: #a78bfa;
- --pink: #db2777;
- --blue: #0ea5e9;
- --page-gutter: clamp(1.25rem, 3vw, 3rem);
- --main-top: 9rem;
- --main-bottom: 7rem;
- --clay-card-shadow:
- 16px 16px 32px rgb(160 150 180 / 20%),
- -10px -10px 24px rgb(255 255 255 / 90%),
- inset 6px 6px 12px rgb(139 92 246 / 3%),
- inset -6px -6px 12px rgb(255 255 255 / 100%);
- --clay-card-shadow-hover:
- 22px 24px 38px rgb(139 92 246 / 24%),
- -12px -12px 28px rgb(255 255 255 / 95%),
- inset 6px 6px 12px rgb(139 92 246 / 5%),
- inset -6px -6px 12px rgb(255 255 255 / 100%);
- --clay-button-shadow:
- 12px 12px 24px rgb(139 92 246 / 30%),
- -8px -8px 16px rgb(255 255 255 / 40%),
- inset 4px 4px 8px rgb(255 255 255 / 40%),
- inset -4px -4px 8px rgb(0 0 0 / 10%);
- --clay-pressed-shadow:
- inset 10px 10px 20px #d9d4e3,
- inset -10px -10px 20px #ffffff;
-}
-
-* {
+ font-family: "Helvetica Neue", Arial, sans-serif;
+ color: #282344;
+ background: #fff5df;
+ --canvas: #fff5df;
+ --foreground: #282344;
+ --muted: #635b77;
+ --accent: #673bc2;
+ --accent-light: #7951cb;
+ --pink: #673bc2;
+ --blue: #19766f;
+ --paper: #fffdf7;
+ --line: #c9b9d5;
+ --page-gutter: clamp(1.25rem, 4vw, 4.5rem);
+ --main-top: 10rem;
+ --main-bottom: 5rem;
+ --panel-shadow: 5px 5px 0 #282344;
+ --panel-shadow-hover: 8px 9px 0 #282344;
+ --button-shadow: 3px 3px 0 #282344;
+ --inset-shadow: none;
+}
+
+*
+{
box-sizing: border-box;
}
-html {
+html
+{
min-width: 20rem;
}
-body {
+body
+{
margin: 0;
min-height: 100vh;
overflow-x: hidden;
@@ -51,51 +43,13 @@ body {
line-height: 1.625;
}
-a {
+a
+{
color: inherit;
}
-.ambient-light {
- position: fixed;
- z-index: -1;
- inset: 0;
- overflow: hidden;
- pointer-events: none;
-}
-
-.ambient-blob {
- position: absolute;
- width: min(60vh, 42rem);
- height: min(60vh, 42rem);
- border-radius: 50%;
- opacity: 0.11;
- filter: blur(4rem);
- animation: clay-float 10s ease-in-out infinite;
-}
-
-.ambient-blob-violet {
- top: -18%;
- left: -12%;
- background: var(--violet);
-}
-
-.ambient-blob-pink {
- top: 22%;
- right: -14%;
- background: var(--pink);
- animation-name: clay-float-delayed;
- animation-delay: -3s;
-}
-
-.ambient-blob-blue {
- bottom: -24%;
- left: 28%;
- background: var(--blue);
- animation-duration: 12s;
- animation-delay: -6s;
-}
-
-.site-header {
+.site-header
+{
position: fixed;
z-index: 100;
top: 1.5rem;
@@ -108,85 +62,89 @@ a {
min-height: 5rem;
margin: 0;
padding: 0.8rem 1rem 0.8rem 1.6rem;
- border: 1px solid rgb(255 255 255 / 75%);
- border-radius: 2.5rem;
- background: rgb(255 255 255 / 68%);
- box-shadow:
- 18px 18px 36px rgb(160 150 180 / 18%),
- -12px -12px 30px rgb(255 255 255 / 90%),
- inset 5px 5px 10px rgb(139 92 246 / 3%),
- inset -5px -5px 10px rgb(255 255 255 / 90%);
- backdrop-filter: blur(1.25rem);
-}
-
-.site-title {
- font-family: Nunito, ui-rounded, sans-serif;
+ border: 1px solid var(--line);
+ border-radius: 1rem;
+ background: var(--paper);
+ box-shadow: none;
+}
+
+.site-title
+{
+ font-family: "Trebuchet MS", "Arial Rounded MT Bold", sans-serif;
font-size: 1.2rem;
- font-weight: 900;
+ font-weight: 700;
letter-spacing: -0.025em;
text-decoration: none;
}
-nav {
+nav
+{
display: flex;
align-items: center;
gap: 0.25rem;
}
-.nav-link {
+.nav-link
+{
display: inline-flex;
min-height: 2.75rem;
align-items: center;
justify-content: center;
padding: 0.65rem 1rem;
- border-radius: 1.25rem;
+ border-radius: 1rem;
color: var(--muted);
font-weight: 700;
text-decoration: none;
transition:
- color 200ms ease,
- background 200ms ease,
- box-shadow 200ms ease,
- transform 200ms ease;
+ color 200ms ease,
+ background 200ms ease,
+ box-shadow 200ms ease,
+ transform 200ms ease;
}
-.nav-link:hover {
- color: var(--violet);
- background: rgb(124 58 237 / 8%);
+.nav-link:hover
+{
+ color: var(--accent);
+ background: rgb(183 53 32 / 8%);
transform: translateY(-0.15rem);
}
-.nav-link:active {
+.nav-link:active
+{
transform: scale(0.92);
- box-shadow: var(--clay-pressed-shadow);
+ box-shadow: none;
}
-.nav-link-primary {
+.nav-link-primary
+{
margin-left: 0.35rem;
padding-inline: 1.25rem;
- background: linear-gradient(145deg, var(--violet-light), var(--violet));
+ background: var(--accent);
color: #ffffff;
- box-shadow: var(--clay-button-shadow);
+ box-shadow: none;
}
-.nav-link-primary:hover {
- background: linear-gradient(145deg, #b7a1fb, #6d28d9);
+.nav-link-primary:hover
+{
+ background: var(--accent);
color: #ffffff;
transform: translateY(-0.25rem);
}
-main {
+main
+{
width: 100%;
min-height: 100vh;
min-height: 100svh;
margin: 0;
padding:
- var(--main-top)
- var(--page-gutter)
- var(--main-bottom);
+ var(--main-top)
+ var(--page-gutter)
+ var(--main-bottom);
}
-.page-heading {
+.page-heading
+{
display: flex;
align-items: end;
justify-content: space-between;
@@ -194,78 +152,83 @@ main {
margin-bottom: 3.25rem;
}
-.eyebrow {
+.eyebrow
+{
margin: 0 0 0.25rem;
- color: var(--violet);
+ color: var(--accent);
font-size: 0.75rem;
font-weight: 700;
letter-spacing: 0.16em;
text-transform: uppercase;
}
-h1 {
+h1
+{
margin: 0;
- font-family: Nunito, ui-rounded, sans-serif;
+ font-family: "Trebuchet MS", "Arial Rounded MT Bold", sans-serif;
font-size: clamp(3rem, 8vw, 5.5rem);
- font-weight: 900;
+ font-weight: 700;
line-height: 1.05;
letter-spacing: -0.06em;
}
-.sort-controls {
+.sort-controls
+{
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.4rem;
padding: 0.55rem;
- border-radius: 1.5rem;
- background: #efebf5;
- box-shadow: var(--clay-pressed-shadow);
+ border-radius: 1rem;
+ background: #f0e5fa;
+ box-shadow: none;
font-size: 0.9rem;
}
-.sort-label {
+.sort-label
+{
padding: 0 0.65rem;
color: var(--muted);
font-size: 0.78rem;
font-weight: 700;
}
-.sort-button {
+.sort-button
+{
display: inline-flex;
min-height: 2.75rem;
align-items: center;
padding: 0.55rem 0.9rem;
- border-radius: 1.1rem;
+ border-radius: 1rem;
color: var(--muted);
font-weight: 700;
text-decoration: none;
transition:
- color 200ms ease,
- box-shadow 200ms ease,
- transform 200ms ease;
+ color 200ms ease,
+ box-shadow 200ms ease,
+ transform 200ms ease;
}
-.sort-button:hover {
- color: var(--violet);
+.sort-button:hover
+{
+ color: var(--accent);
transform: translateY(-0.12rem);
}
-.sort-button:active {
+.sort-button:active
+{
transform: scale(0.92);
}
-.sort-button[aria-current="page"] {
- background: linear-gradient(145deg, var(--violet-light), var(--violet));
+.sort-button[aria-current="page"]
+{
+ background: var(--accent);
color: #ffffff;
- box-shadow:
- 7px 7px 14px rgb(139 92 246 / 24%),
- -5px -5px 12px rgb(255 255 255 / 60%),
- inset 3px 3px 6px rgb(255 255 255 / 35%),
- inset -3px -3px 6px rgb(0 0 0 / 8%);
+ box-shadow: none;
}
-.card-grid {
+.card-grid
+{
display: grid;
grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
gap: clamp(1.5rem, 3vw, 2.5rem);
@@ -274,38 +237,37 @@ h1 {
list-style: none;
}
-.card-tile {
+.card-tile
+{
overflow: hidden;
- border: 1px solid rgb(255 255 255 / 85%);
- border-radius: 2rem;
- background: rgb(255 255 255 / 72%);
- box-shadow: var(--clay-card-shadow);
- backdrop-filter: blur(1.25rem);
+ border: 1px solid var(--line);
+ border-radius: 1rem;
+ background: var(--paper);
+ box-shadow: none;
transition:
- box-shadow 500ms ease,
- transform 500ms cubic-bezier(0.2, 0.8, 0.2, 1);
+ box-shadow 500ms ease,
+ transform 500ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
-.card-tile:hover {
- box-shadow: var(--clay-card-shadow-hover);
+.card-tile:hover
+{
+ box-shadow: none;
transform: translateY(-0.5rem) scale(1.01);
}
-.card-image-link {
+.card-image-link
+{
display: block;
aspect-ratio: 5 / 7;
margin: 0.75rem;
overflow: hidden;
- border-radius: 1.5rem;
- background: #e9e2f2;
- box-shadow:
- inset 7px 7px 14px rgb(174 164 190 / 20%),
- inset -7px -7px 14px rgb(255 255 255 / 85%),
- 4px 4px 10px rgb(139 92 246 / 8%),
- -3px -3px 8px rgb(255 255 255 / 70%);
+ border-radius: 1rem;
+ background: #eddef8;
+ box-shadow: none;
}
-.card-image-link img {
+.card-image-link img
+{
display: block;
width: 100%;
height: 100%;
@@ -313,110 +275,123 @@ h1 {
transition: transform 500ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
-.card-tile:hover .card-image-link img {
+.card-tile:hover .card-image-link img
+{
transform: scale(1.025);
}
-.card-details {
+.card-details
+{
padding: 0.2rem 1.35rem 1.5rem;
}
-.card-id {
+.card-id
+{
display: inline-flex;
min-height: 2.75rem;
align-items: center;
margin-left: -0.5rem;
padding: 0.35rem 0.6rem;
border-radius: 1rem;
- color: var(--violet);
+ color: var(--accent);
font-family: ui-monospace, monospace;
font-size: 0.8rem;
font-weight: 700;
letter-spacing: 0.06em;
text-decoration: none;
transition:
- background 200ms ease,
- transform 200ms ease;
+ background 200ms ease,
+ transform 200ms ease;
}
-.card-id:hover {
- background: rgb(124 58 237 / 8%);
+.card-id:hover
+{
+ background: rgb(183 53 32 / 8%);
transform: translateY(-0.1rem);
}
-.card-id:active {
+.card-id:active
+{
transform: scale(0.92);
}
-.card-details h2 {
+.card-details h2
+{
margin: 0.1rem 0 0;
- font-family: Nunito, ui-rounded, sans-serif;
+ font-family: "Trebuchet MS", "Arial Rounded MT Bold", sans-serif;
font-size: 1.15rem;
font-weight: 800;
line-height: 1.3;
}
-.empty-state {
+.empty-state
+{
display: grid;
min-height: 16rem;
place-items: center;
padding: 2rem;
- border-radius: 2rem;
- background: #efebf5;
- box-shadow: var(--clay-pressed-shadow);
+ border-radius: 1rem;
+ background: #f0e5fa;
+ box-shadow: none;
color: var(--muted);
font-weight: 700;
}
-.card-view {
+.card-view
+{
position: relative;
min-height: 100vh;
min-height: 100svh;
margin:
- calc(0rem - var(--main-top))
- calc(0rem - var(--page-gutter))
- calc(0rem - var(--main-bottom));
+ calc(0rem - var(--main-top))
+ calc(0rem - var(--page-gutter))
+ calc(0rem - var(--main-bottom));
overflow: hidden;
}
-.card-preview-stage {
+.card-preview-stage
+{
position: absolute;
inset: 0;
display: grid;
min-height: 100%;
overflow: hidden;
background:
- radial-gradient(circle at 22% 16%,
- rgb(255 255 255 / 80%), transparent 35%),
- linear-gradient(145deg, #ede7f8, #e2d9f2);
+ radial-gradient(circle at 22% 16%,
+ var(--paper), transparent 35%),
+ linear-gradient(145deg, #ede7f8, #e2d9f2);
isolation: isolate;
}
.card-preview-stage::before,
-.card-preview-stage::after {
+.card-preview-stage::after
+{
position: absolute;
z-index: -1;
width: 16rem;
height: 16rem;
- border-radius: 50%;
+ border-radius: 1rem;
content: "";
filter: blur(3.5rem);
opacity: 0.22;
}
-.card-preview-stage::before {
+.card-preview-stage::before
+{
top: -5rem;
right: -4rem;
background: var(--pink);
}
-.card-preview-stage::after {
+.card-preview-stage::after
+{
bottom: -5rem;
left: -4rem;
background: var(--blue);
}
-.preview-heading {
+.preview-heading
+{
position: absolute;
z-index: 2;
top: var(--main-top);
@@ -429,39 +404,41 @@ h1 {
pointer-events: none;
}
-.preview-heading .eyebrow {
+.preview-heading .eyebrow
+{
margin: 0;
}
.preview-status,
-.preview-hint {
+.preview-hint
+{
margin: 0;
- border: 1px solid rgb(255 255 255 / 70%);
+ border: 1px solid var(--line);
border-radius: 1rem;
- background: rgb(255 255 255 / 64%);
- box-shadow:
- 7px 7px 16px rgb(134 119 158 / 16%),
- -5px -5px 14px rgb(255 255 255 / 70%),
- inset 3px 3px 7px rgb(139 92 246 / 3%),
- inset -3px -3px 7px rgb(255 255 255 / 75%);
+ background: var(--paper);
+ box-shadow: none;
color: var(--muted);
font-size: 0.78rem;
font-weight: 700;
}
-.preview-status {
+.preview-status
+{
padding: 0.35rem 0.65rem;
}
-.preview-status[data-kind="success"] {
- color: var(--violet);
+.preview-status[data-kind="success"]
+{
+ color: var(--accent);
}
-.preview-status[data-kind="error"] {
+.preview-status[data-kind="error"]
+{
color: #a21d53;
}
-#GLCanvas {
+#GLCanvas
+{
display: block;
width: calc(100% - 30rem);
height: 100%;
@@ -471,7 +448,8 @@ h1 {
touch-action: none;
}
-.preview-hint {
+.preview-hint
+{
position: absolute;
right: calc(var(--page-gutter) + 31rem);
bottom: 1.5rem;
@@ -484,25 +462,26 @@ h1 {
pointer-events: none;
}
-.card-info-panel {
+.card-info-panel
+{
position: fixed;
z-index: 40;
top: var(--main-top);
right: var(--page-gutter);
bottom: 1.5rem;
width: min(
- 29rem,
- calc(100% - var(--page-gutter) - var(--page-gutter)));
+ 29rem,
+ calc(100% - var(--page-gutter) - var(--page-gutter)));
overflow: auto;
padding: clamp(1.5rem, 4vw, 2.5rem);
- border: 1px solid rgb(255 255 255 / 82%);
- border-radius: 2.5rem;
- background: rgb(255 255 255 / 70%);
- box-shadow: var(--clay-card-shadow);
- backdrop-filter: blur(1.25rem);
+ border: 1px solid var(--line);
+ border-radius: 1rem;
+ background: var(--paper);
+ box-shadow: none;
}
-.back-link {
+.back-link
+{
display: inline-flex;
min-height: 2.75rem;
align-items: center;
@@ -515,67 +494,72 @@ h1 {
transition: color 200ms ease, transform 200ms ease;
}
-.back-link:hover {
- color: var(--violet);
+.back-link:hover
+{
+ color: var(--accent);
transform: translateX(-0.2rem);
}
-.card-actions {
+.card-actions
+{
display: flex;
justify-content: space-between;
margin: -0.5rem 0 1.5rem -0.65rem;
}
-.card-actions .back-link {
+.card-actions .back-link
+{
margin: 0;
}
-.card-view-id {
+.card-view-id
+{
margin: 0 0 0.4rem;
- color: var(--violet);
+ color: var(--accent);
font-family: ui-monospace, monospace;
font-size: 0.82rem;
font-weight: 800;
letter-spacing: 0.08em;
}
-.card-info-panel h1 {
+.card-info-panel h1
+{
overflow-wrap: anywhere;
font-size: clamp(2.6rem, 6vw, 4.5rem);
}
-.asset-warning {
+.asset-warning
+{
display: grid;
gap: 0.2rem;
margin-top: 1.75rem;
padding: 1rem 1.1rem;
- border-radius: 1.35rem;
+ border-radius: 1rem;
background: #fde7f0;
- box-shadow:
- 8px 8px 18px rgb(190 90 130 / 13%),
- -6px -6px 15px rgb(255 255 255 / 72%),
- inset 3px 3px 8px rgb(190 90 130 / 5%),
- inset -3px -3px 8px rgb(255 255 255 / 65%);
+ box-shadow: none;
color: #812044;
font-size: 0.88rem;
}
-.card-metadata {
+.card-metadata
+{
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0.75rem;
margin: 2rem 0 0;
}
-.card-metadata div {
+.card-metadata div
+{
min-width: 0;
padding: 0.9rem;
- border-radius: 1.25rem;
- background: #efebf5;
- box-shadow: var(--clay-pressed-shadow);
+ border-radius: 1rem;
+ background: #f0e5fa;
+ box-shadow: none;
}
-.card-metadata dt {
+.card-metadata dt
+{
color: var(--muted);
font-size: 0.68rem;
font-weight: 800;
@@ -583,45 +567,53 @@ h1 {
text-transform: uppercase;
}
-.card-metadata dd {
+.card-metadata dd
+{
margin: 0.2rem 0 0;
overflow-wrap: anywhere;
- font-family: Nunito, ui-rounded, sans-serif;
+ font-family: "Trebuchet MS", "Arial Rounded MT Bold", sans-serif;
font-size: 0.95rem;
font-weight: 800;
}
-.game-field-value {
+.game-field-value
+{
white-space: pre-wrap;
}
-.card-info-section {
+.card-info-section
+{
margin-top: 2rem;
padding-top: 1.75rem;
- border-top: 1px solid rgb(99 95 105 / 12%);
+ border-top: 1px solid var(--line);
}
-.card-info-section h2 {
+.card-info-section h2
+{
margin: 0 0 0.75rem;
- font-family: Nunito, ui-rounded, sans-serif;
+ font-family: "Trebuchet MS", "Arial Rounded MT Bold", sans-serif;
font-size: 1rem;
- font-weight: 900;
+ font-weight: 700;
}
.muted-copy,
-.description-copy {
+.description-copy
+{
margin: 0;
}
-.muted-copy {
+.muted-copy
+{
color: var(--muted);
}
-.description-copy {
+.description-copy
+{
white-space: pre-wrap;
}
-.series-list {
+.series-list
+{
display: flex;
flex-wrap: wrap;
gap: 0.55rem;
@@ -630,50 +622,58 @@ h1 {
list-style: none;
}
-.series-list li {
+.series-list li
+{
padding: 0.45rem 0.75rem;
border-radius: 1rem;
- background: rgb(124 58 237 / 9%);
- color: var(--violet);
+ background: rgb(183 53 32 / 9%);
+ color: var(--accent);
font-size: 0.82rem;
font-weight: 800;
}
-.card-form-panel h1 {
+.card-form-panel h1
+{
font-size: clamp(2.6rem, 5vw, 4rem);
}
-.card-form {
+.card-form
+{
margin-top: 2rem;
}
-.form-section {
+.form-section
+{
display: grid;
gap: 1rem;
margin: 0;
padding: 1.75rem 0;
border: 0;
- border-top: 1px solid rgb(99 95 105 / 12%);
+ border-top: 1px solid var(--line);
}
-.form-section[hidden] {
+.form-section[hidden]
+{
display: none;
}
.form-section h2,
-.form-section legend {
+.form-section legend
+{
margin: 0;
padding: 0;
- font-family: Nunito, ui-rounded, sans-serif;
+ font-family: "Trebuchet MS", "Arial Rounded MT Bold", sans-serif;
font-size: 1rem;
- font-weight: 900;
+ font-weight: 700;
}
-.image-source-section legend {
+.image-source-section legend
+{
margin-bottom: 1rem;
}
-.form-field {
+.form-field
+{
display: grid;
gap: 0.45rem;
color: var(--foreground);
@@ -681,7 +681,8 @@ h1 {
font-weight: 800;
}
-.form-field em {
+.form-field em
+{
color: var(--muted);
font-size: 0.74rem;
font-style: normal;
@@ -690,26 +691,27 @@ h1 {
.form-field input,
.form-field select,
-.form-field textarea {
+.form-field textarea
+{
width: 100%;
min-height: 3.25rem;
border: 0;
- border-radius: 1.15rem;
- background: #efebf5;
- box-shadow:
- inset 7px 7px 15px rgb(185 177 198 / 55%),
- inset -7px -7px 15px rgb(255 255 255 / 90%);
+ border-radius: 1rem;
+ background: #f0e5fa;
+ box-shadow: none;
color: var(--foreground);
font: inherit;
font-weight: 600;
}
.form-field input,
-.form-field select {
+.form-field select
+{
padding: 0.75rem 1rem;
}
-.form-field textarea {
+.form-field textarea
+{
min-height: 6rem;
padding: 1rem;
resize: vertical;
@@ -718,58 +720,66 @@ h1 {
.form-field input:focus,
.form-field select:focus,
-.form-field textarea:focus {
- background: rgb(255 255 255 / 84%);
- outline: 0.25rem solid rgb(124 58 237 / 20%);
+.form-field textarea:focus
+{
+ background: var(--paper);
+ outline: 0.25rem solid rgb(183 53 32 / 20%);
}
-.image-field input[type="file"] {
+.image-field input[type="file"]
+{
padding: 0.45rem;
color: var(--muted);
}
-.image-field input[type="file"]::file-selector-button {
+.image-field input[type="file"]::file-selector-button
+{
min-height: 2.4rem;
margin-right: 0.7rem;
padding: 0.45rem 0.8rem;
border: 0;
- border-radius: 0.85rem;
- background: rgb(124 58 237 / 11%);
- color: var(--violet);
+ border-radius: 1rem;
+ background: rgb(183 53 32 / 11%);
+ color: var(--accent);
font: inherit;
font-weight: 800;
cursor: pointer;
}
.image-field small,
-.form-hint {
+.form-hint
+{
margin: 0;
color: var(--muted);
font-size: 0.76rem;
font-weight: 600;
}
-.source-toggle {
+.source-toggle
+{
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0.35rem;
padding: 0.4rem;
- border-radius: 1.35rem;
- background: #efebf5;
- box-shadow: var(--clay-pressed-shadow);
+ border-radius: 1rem;
+ background: #f0e5fa;
+ box-shadow: none;
}
-.source-toggle label {
+.source-toggle label
+{
position: relative;
cursor: pointer;
}
-.source-toggle input {
+.source-toggle input
+{
position: absolute;
opacity: 0;
}
-.source-toggle span {
+.source-toggle span
+{
display: grid;
min-height: 2.75rem;
place-items: center;
@@ -778,99 +788,107 @@ h1 {
font-size: 0.8rem;
font-weight: 800;
transition:
- color 200ms ease,
- box-shadow 200ms ease,
- transform 200ms ease;
-}
-
-.source-toggle input:checked + span {
- background: linear-gradient(145deg, var(--violet-light), var(--violet));
- box-shadow:
- 7px 7px 14px rgb(139 92 246 / 24%),
- -5px -5px 12px rgb(255 255 255 / 60%),
- inset 3px 3px 6px rgb(255 255 255 / 35%),
- inset -3px -3px 6px rgb(0 0 0 / 8%);
+ color 200ms ease,
+ box-shadow 200ms ease,
+ transform 200ms ease;
+}
+
+.source-toggle input:checked + span
+{
+ background: var(--accent);
+ box-shadow: none;
color: #ffffff;
}
-.source-toggle input:focus-visible + span {
- outline: 0.25rem solid rgb(124 58 237 / 30%);
+.source-toggle input:focus-visible + span
+{
+ outline: 0.25rem solid rgb(183 53 32 / 30%);
outline-offset: 0.2rem;
}
-.source-fields {
+.source-fields
+{
display: grid;
gap: 1rem;
}
-.source-fields[hidden] {
+.source-fields[hidden]
+{
display: none;
}
-.form-submit {
+.form-submit
+{
width: 100%;
min-height: 3.5rem;
margin-top: 0.25rem;
border: 0;
- border-radius: 1.25rem;
- background: linear-gradient(145deg, var(--violet-light), var(--violet));
- box-shadow: var(--clay-button-shadow);
+ border-radius: 1rem;
+ background: var(--accent);
+ box-shadow: none;
color: #ffffff;
font: inherit;
font-weight: 800;
cursor: pointer;
transition:
- box-shadow 200ms ease,
- transform 200ms ease;
+ box-shadow 200ms ease,
+ transform 200ms ease;
}
-.form-submit:hover {
- box-shadow: var(--clay-card-shadow-hover);
+.form-submit:hover
+{
+ box-shadow: none;
transform: translateY(-0.2rem);
}
-.form-submit:active {
- box-shadow: var(--clay-pressed-shadow);
+.form-submit:active
+{
+ box-shadow: none;
transform: scale(0.92);
}
-.form-status {
+.form-status
+{
min-height: 1.5rem;
margin: 0.75rem 0 0;
color: var(--muted);
font-size: 0.8rem;
}
-.page-shell {
+.page-shell
+{
width: min(68rem, 100%);
margin-inline: auto;
}
-.form-page {
+.form-page
+{
width: min(40rem, 100%);
padding: clamp(1.5rem, 5vw, 3rem);
- border: 1px solid rgb(255 255 255 / 82%);
- border-radius: 2.5rem;
- background: rgb(255 255 255 / 70%);
- box-shadow: var(--clay-card-shadow);
- backdrop-filter: blur(1.25rem);
+ border: 1px solid var(--line);
+ border-radius: 1rem;
+ background: var(--paper);
+ box-shadow: none;
}
-.standalone-form {
+.standalone-form
+{
display: grid;
gap: 1.25rem;
margin-top: 2rem;
}
.empty-panel,
-.series-admin-list > li {
+.series-admin-list > li
+{
padding: 1.5rem;
- border-radius: 1.75rem;
- background: rgb(255 255 255 / 70%);
- box-shadow: var(--clay-card-shadow);
+ border-radius: 1rem;
+ background: var(--paper);
+ box-shadow: none;
}
-.series-admin-list {
+.series-admin-list
+{
display: grid;
gap: 1.25rem;
margin: 0;
@@ -879,7 +897,8 @@ h1 {
}
.series-admin-list > li,
-.series-admin-actions {
+.series-admin-actions
+{
display: flex;
align-items: center;
justify-content: space-between;
@@ -887,120 +906,120 @@ h1 {
}
.series-admin-list h2,
-.empty-panel h2 {
+.empty-panel h2
+{
margin: 0;
}
-.series-admin-actions a {
- color: var(--violet);
+.series-admin-actions a
+{
+ color: var(--accent);
font-weight: 800;
}
-.destructive-submit {
- background: linear-gradient(145deg, #f87171, #be123c);
+.destructive-submit
+{
+ background: var(--accent);
}
-:focus-visible {
- outline: 0.25rem solid rgb(124 58 237 / 30%);
+:focus-visible
+{
+ outline: 0.25rem solid rgb(183 53 32 / 30%);
outline-offset: 0.2rem;
}
-@keyframes clay-float {
- 0%,
- 100% {
- transform: translateY(0) rotate(0deg);
- }
-
- 50% {
- transform: translateY(-1.25rem) rotate(2deg);
- }
-}
-
-@keyframes clay-float-delayed {
- 0%,
- 100% {
- transform: translateY(0) rotate(0deg);
- }
-
- 50% {
- transform: translateY(-0.95rem) rotate(-2deg);
- }
-}
-
-@media(max-width: 42rem) {
- :root {
+@media(max-width: 42rem)
+{
+ :root
+ {
--main-top: 13rem;
}
- .site-header {
+ .site-header
+ {
min-height: auto;
padding: 1rem;
- border-radius: 2rem;
+ border-radius: 1rem;
}
.site-header,
- .page-heading {
+ .page-heading
+ {
align-items: flex-start;
flex-direction: column;
}
- nav {
+ nav
+ {
width: 100%;
flex-wrap: wrap;
}
- .nav-link {
+ .nav-link
+ {
flex: 1;
padding-inline: 0.7rem;
}
- .nav-link-primary {
+ .nav-link-primary
+ {
flex-basis: 100%;
margin: 0.35rem 0 0;
}
- .page-heading {
+ .page-heading
+ {
margin-bottom: 2.5rem;
}
- .sort-controls {
+ .sort-controls
+ {
width: 100%;
}
- .sort-label {
+ .sort-label
+ {
flex-basis: 100%;
padding-bottom: 0.2rem;
}
- .sort-button {
+ .sort-button
+ {
flex: 1;
justify-content: center;
}
- .card-grid {
+ .card-grid
+ {
grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
}
- .card-metadata {
+ .card-metadata
+ {
grid-template-columns: 1fr;
}
}
-@media(max-width: 62rem) {
- .preview-heading {
+@media(max-width: 62rem)
+{
+ .preview-heading
+ {
right: var(--page-gutter);
}
- #GLCanvas {
+ #GLCanvas
+ {
width: 100%;
}
- .preview-hint {
+ .preview-hint
+ {
right: var(--page-gutter);
bottom: calc(44svh + 2rem);
}
- .card-info-panel {
+ .card-info-panel
+ {
top: auto;
right: 1rem;
bottom: 1rem;
@@ -1011,23 +1030,25 @@ h1 {
}
}
-@media(prefers-reduced-motion: reduce) {
+@media(prefers-reduced-motion: reduce)
+{
*,
*::before,
- *::after {
+ *::after
+ {
scroll-behavior: auto !important;
- animation-duration: 0.01ms !important;
- animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
-.public-main {
+.public-main
+{
display: grid;
place-items: center;
}
-.public-header-note {
+.public-header-note
+{
color: var(--muted);
font-size: 0.78rem;
font-weight: 800;
@@ -1035,7 +1056,8 @@ h1 {
text-transform: uppercase;
}
-.welcome-hero {
+.welcome-hero
+{
display: grid;
width: 100%;
min-height: calc(100svh - var(--main-top) - var(--main-bottom));
@@ -1044,15 +1066,18 @@ h1 {
gap: clamp(3rem, 8vw, 8rem);
}
-.welcome-copy {
+.welcome-copy
+{
max-width: 48rem;
}
-.welcome-copy h1 {
+.welcome-copy h1
+{
font-size: clamp(3.5rem, 8vw, 7.5rem);
}
-.hero-copy {
+.hero-copy
+{
max-width: 40rem;
margin: 2rem 0 2.5rem;
color: var(--muted);
@@ -1061,16 +1086,17 @@ h1 {
.clay-action,
.pull-button,
-.table-action {
+.table-action
+{
display: inline-flex;
min-height: 3.5rem;
align-items: center;
justify-content: center;
padding: 0.75rem 1.5rem;
border: 0;
- border-radius: 1.25rem;
- background: linear-gradient(145deg, var(--violet-light), var(--violet));
- box-shadow: var(--clay-button-shadow);
+ border-radius: 1rem;
+ background: var(--accent);
+ box-shadow: none;
color: #ffffff;
font: inherit;
font-weight: 800;
@@ -1078,42 +1104,48 @@ h1 {
text-decoration: none;
cursor: pointer;
transition:
- box-shadow 200ms ease,
- transform 200ms ease;
+ box-shadow 200ms ease,
+ transform 200ms ease;
}
.clay-action:hover,
.pull-button:hover:not(:disabled),
-.table-action:hover {
- box-shadow: var(--clay-card-shadow-hover);
+.table-action:hover
+{
+ box-shadow: none;
transform: translateY(-0.25rem);
}
.clay-action:active,
.pull-button:active:not(:disabled),
-.table-action:active {
- box-shadow: var(--clay-pressed-shadow);
+.table-action:active
+{
+ box-shadow: none;
transform: scale(0.92);
}
-.clay-action-secondary {
- background: rgb(255 255 255 / 76%);
- color: var(--violet);
+.clay-action-secondary
+{
+ background: var(--paper);
+ color: var(--accent);
}
-.clay-action-danger {
- background: linear-gradient(145deg, #fb7185, #be123c);
+.clay-action-danger
+{
+ background: var(--accent);
color: #ffffff;
}
-.clay-action:disabled {
- box-shadow: var(--clay-pressed-shadow);
+.clay-action:disabled
+{
+ box-shadow: none;
cursor: not-allowed;
opacity: 0.48;
transform: none;
}
-.welcome-preview {
+.welcome-preview
+{
position: relative;
display: grid;
min-height: 36rem;
@@ -1121,38 +1153,37 @@ h1 {
isolation: isolate;
}
-.welcome-card {
+.welcome-card
+{
width: min(20rem, 68vw);
padding: 0.9rem;
- border: 1px solid rgb(255 255 255 / 85%);
- border-radius: 2.5rem;
- background: rgb(255 255 255 / 72%);
- box-shadow:
- 24px 28px 48px rgb(139 92 246 / 24%),
- -14px -14px 32px rgb(255 255 255 / 95%),
- inset 7px 7px 14px rgb(139 92 246 / 4%),
- inset -7px -7px 14px rgb(255 255 255 / 100%);
- backdrop-filter: blur(1.25rem);
+ border: 1px solid var(--line);
+ border-radius: 1rem;
+ background: var(--paper);
+ box-shadow: none;
transform: rotate(4deg);
transition:
- box-shadow 500ms ease,
- transform 500ms ease;
+ box-shadow 500ms ease,
+ transform 500ms ease;
}
-.welcome-card:hover {
- box-shadow: var(--clay-card-shadow-hover);
+.welcome-card:hover
+{
+ box-shadow: none;
transform: translateY(-0.75rem) rotate(1deg) scale(1.02);
}
-.welcome-card img {
+.welcome-card img
+{
display: block;
width: 100%;
aspect-ratio: 5 / 7;
- border-radius: 1.75rem;
+ border-radius: 1rem;
object-fit: cover;
}
-.welcome-preview > p {
+.welcome-preview > p
+{
position: absolute;
right: 0;
bottom: 1rem;
@@ -1164,108 +1195,86 @@ h1 {
text-align: center;
}
-.welcome-orbit {
- position: absolute;
- z-index: -1;
- width: 12rem;
- height: 12rem;
- border-radius: 50%;
- filter: blur(0.25rem);
- opacity: 0.2;
- animation: clay-float 9s ease-in-out infinite;
-}
-
-.welcome-orbit-pink {
- top: 2rem;
- right: 0;
- background: var(--pink);
-}
-
-.welcome-orbit-blue {
- bottom: 3rem;
- left: 0;
- background: var(--blue);
- animation-name: clay-float-delayed;
-}
-
-.public-card {
+.public-card
+{
position: relative;
width: min(42rem, 100%);
padding: clamp(2rem, 6vw, 4rem);
overflow: hidden;
- border: 1px solid rgb(255 255 255 / 82%);
- border-radius: clamp(2rem, 5vw, 3rem);
- background: rgb(255 255 255 / 70%);
- box-shadow:
- 30px 30px 60px #cdc6d9,
- -30px -30px 60px #ffffff,
- inset 10px 10px 20px rgb(139 92 246 / 5%),
- inset -10px -10px 20px rgb(255 255 255 / 80%);
- backdrop-filter: blur(1.25rem);
-}
-
-.public-card h1 {
+ border: 1px solid var(--line);
+ border-radius: 1rem;
+ background: var(--paper);
+ box-shadow: none;
+}
+
+.public-card h1
+{
font-size: clamp(2.65rem, 7vw, 4.5rem);
}
-.public-card-copy {
+.public-card-copy
+{
max-width: 34rem;
margin: 1.25rem 0 0;
color: var(--muted);
font-size: 1.05rem;
}
-.clay-icon {
+.clay-icon
+{
display: inline-grid;
width: 3.5rem;
height: 3.5rem;
place-items: center;
flex: 0 0 auto;
margin-bottom: 1.5rem;
- border-radius: 1.25rem;
- box-shadow:
- 10px 10px 20px rgb(139 92 246 / 20%),
- -7px -7px 14px rgb(255 255 255 / 60%),
- inset 4px 4px 8px rgb(255 255 255 / 35%),
- inset -4px -4px 8px rgb(0 0 0 / 9%);
+ border-radius: 1rem;
+ box-shadow: none;
color: #ffffff;
- font-family: Nunito, ui-rounded, sans-serif;
+ font-family: "Trebuchet MS", "Arial Rounded MT Bold", sans-serif;
font-size: 1.35rem;
- font-weight: 900;
+ font-weight: 700;
}
-.clay-icon-violet {
- background: linear-gradient(145deg, #a78bfa, #7c3aed);
+.clay-icon-violet
+{
+ background: var(--accent);
}
-.clay-icon-pink {
- background: linear-gradient(145deg, #f472b6, #db2777);
+.clay-icon-pink
+{
+ background: var(--accent);
}
-.clay-icon-blue {
- background: linear-gradient(145deg, #38bdf8, #0284c7);
+.clay-icon-blue
+{
+ background: var(--accent);
}
-.message-card {
+.message-card
+{
text-align: center;
}
-.message-card .public-card-copy {
+.message-card .public-card-copy
+{
margin-inline: auto;
}
.message-hint,
-.identity-pill {
+.identity-pill
+{
margin: 1.75rem 0 0;
padding: 1rem 1.25rem;
- border-radius: 1.25rem;
- background: #efebf5;
- box-shadow: var(--clay-pressed-shadow);
+ border-radius: 1rem;
+ background: #f0e5fa;
+ box-shadow: none;
color: var(--muted);
overflow-wrap: anywhere;
}
-.identity-pill {
+.identity-pill
+{
color: var(--foreground);
font-weight: 800;
text-align: center;
@@ -1273,42 +1282,47 @@ h1 {
.collection-page,
.account-page,
-.users-page {
+.users-page
+{
width: 100%;
}
-.collection-heading {
+.collection-heading
+{
align-items: center;
}
-.pull-panel {
+.pull-panel
+{
display: flex;
align-items: center;
gap: 1rem;
padding: 0.75rem;
- border: 1px solid rgb(255 255 255 / 82%);
- border-radius: 2rem;
- background: rgb(255 255 255 / 68%);
- box-shadow: var(--clay-card-shadow);
- backdrop-filter: blur(1.25rem);
+ border: 1px solid var(--line);
+ border-radius: 1rem;
+ background: var(--paper);
+ box-shadow: none;
}
-.pull-count {
+.pull-count
+{
display: grid;
min-width: 8rem;
padding: 0.4rem 0.75rem;
text-align: center;
}
-.pull-count strong {
- color: var(--violet);
- font-family: Nunito, ui-rounded, sans-serif;
+.pull-count strong
+{
+ color: var(--accent);
+ font-family: "Trebuchet MS", "Arial Rounded MT Bold", sans-serif;
font-size: 2rem;
- font-weight: 900;
+ font-weight: 700;
line-height: 1;
}
-.pull-count span {
+.pull-count span
+{
color: var(--muted);
font-size: 0.72rem;
font-weight: 800;
@@ -1316,68 +1330,78 @@ h1 {
text-transform: uppercase;
}
-.pull-button:disabled {
- background: #d8d1e2;
- box-shadow: var(--clay-pressed-shadow);
+.pull-button:disabled
+{
+ background: #d7d3c6;
+ box-shadow: none;
color: var(--muted);
cursor: not-allowed;
}
-.collection-notice {
+.collection-notice
+{
display: flex;
align-items: center;
gap: 1.25rem;
margin-bottom: 2.5rem;
padding: 1.25rem 1.5rem;
- border-radius: 2rem;
- background: rgb(255 255 255 / 70%);
- box-shadow: var(--clay-card-shadow);
+ border-radius: 1rem;
+ background: var(--paper);
+ box-shadow: none;
}
-.collection-notice .clay-icon {
+.collection-notice .clay-icon
+{
margin: 0;
}
-.collection-notice strong {
- font-family: Nunito, ui-rounded, sans-serif;
+.collection-notice strong
+{
+ font-family: "Trebuchet MS", "Arial Rounded MT Bold", sans-serif;
font-size: 1.1rem;
- font-weight: 900;
+ font-weight: 700;
}
-.collection-notice p {
+.collection-notice p
+{
margin: 0;
color: var(--muted);
}
-.collection-empty {
+.collection-empty
+{
display: grid;
min-height: 20rem;
place-items: center;
align-content: center;
padding: 2rem;
- border-radius: 2.5rem;
- background: #efebf5;
- box-shadow: var(--clay-pressed-shadow);
+ border-radius: 1rem;
+ background: #f0e5fa;
+ box-shadow: none;
text-align: center;
}
-.collection-empty .clay-icon {
+.collection-empty .clay-icon
+{
margin: 0 0 1.25rem;
}
-.collection-empty h2 {
+.collection-empty h2
+{
margin: 0;
- font-family: Nunito, ui-rounded, sans-serif;
+ font-family: "Trebuchet MS", "Arial Rounded MT Bold", sans-serif;
font-size: clamp(1.5rem, 4vw, 2rem);
- font-weight: 900;
+ font-weight: 700;
}
-.collection-empty p {
+.collection-empty p
+{
margin: 0.35rem 0 0;
color: var(--muted);
}
-.collection-grid {
+.collection-grid
+{
display: grid;
grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
gap: clamp(1.5rem, 3vw, 2.5rem);
@@ -1386,51 +1410,52 @@ h1 {
list-style: none;
}
-.collection-card {
+.collection-card
+{
min-width: 0;
}
-.collection-card a {
+.collection-card a
+{
position: relative;
display: grid;
height: 100%;
padding: 0.75rem 0.75rem 1.25rem;
overflow: hidden;
- border: 1px solid rgb(255 255 255 / 85%);
- border-radius: 2rem;
- background: rgb(255 255 255 / 72%);
- box-shadow: var(--clay-card-shadow);
+ border: 1px solid var(--line);
+ border-radius: 1rem;
+ background: var(--paper);
+ box-shadow: none;
text-decoration: none;
- backdrop-filter: blur(1.25rem);
transition:
- box-shadow 500ms ease,
- transform 500ms cubic-bezier(0.2, 0.8, 0.2, 1);
+ box-shadow 500ms ease,
+ transform 500ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
-.collection-card a:hover {
- box-shadow: var(--clay-card-shadow-hover);
+.collection-card a:hover
+{
+ box-shadow: none;
transform: translateY(-0.5rem) scale(1.015);
}
-.collection-card a:active {
- box-shadow: var(--clay-pressed-shadow);
+.collection-card a:active
+{
+ box-shadow: none;
transform: scale(0.97);
}
-.collection-image {
+.collection-image
+{
display: block;
aspect-ratio: 5 / 7;
overflow: hidden;
- border-radius: 1.5rem;
- background: #e9e2f2;
- box-shadow:
- inset 7px 7px 14px rgb(174 164 190 / 20%),
- inset -7px -7px 14px rgb(255 255 255 / 85%),
- 4px 4px 10px rgb(139 92 246 / 8%),
- -3px -3px 8px rgb(255 255 255 / 70%);
+ border-radius: 1rem;
+ background: #eddef8;
+ box-shadow: none;
}
-.collection-image img {
+.collection-image img
+{
display: block;
width: 100%;
height: 100%;
@@ -1438,31 +1463,36 @@ h1 {
transition: transform 500ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
-.collection-card a:hover img {
+.collection-card a:hover img
+{
transform: scale(1.035);
}
-.collection-card-details {
+.collection-card-details
+{
display: grid;
gap: 0.1rem;
padding: 1rem 0.6rem 0;
}
-.collection-card-name {
+.collection-card-name
+{
overflow-wrap: anywhere;
- font-family: Nunito, ui-rounded, sans-serif;
+ font-family: "Trebuchet MS", "Arial Rounded MT Bold", sans-serif;
font-size: 1.1rem;
- font-weight: 900;
+ font-weight: 700;
line-height: 1.25;
}
-.collection-card-details > span {
- color: var(--violet);
+.collection-card-details > span
+{
+ color: var(--accent);
font-size: 0.75rem;
font-weight: 800;
}
-.collection-quantity {
+.collection-quantity
+{
position: absolute;
top: 1.35rem;
right: 1.35rem;
@@ -1471,75 +1501,78 @@ h1 {
min-height: 2.75rem;
place-items: center;
padding: 0.35rem 0.6rem;
- border: 2px solid rgb(255 255 255 / 70%);
- border-radius: 50%;
- background: linear-gradient(145deg, #f472b6, #db2777);
- box-shadow:
- 8px 8px 18px rgb(190 36 105 / 30%),
- -5px -5px 12px rgb(255 255 255 / 50%),
- inset 3px 3px 7px rgb(255 255 255 / 35%),
- inset -3px -3px 7px rgb(0 0 0 / 9%);
+ border: 2px solid var(--paper);
+ border-radius: 1rem;
+ background: var(--accent);
+ box-shadow: none;
color: #ffffff;
- font-family: Nunito, ui-rounded, sans-serif;
+ font-family: "Trebuchet MS", "Arial Rounded MT Bold", sans-serif;
font-size: 0.85rem;
- font-weight: 900;
+ font-weight: 700;
}
-.account-grid {
+.account-grid
+{
display: grid;
grid-template-columns: minmax(0, 1.2fr) minmax(18rem, 0.8fr);
gap: clamp(1.5rem, 3vw, 2.5rem);
}
-.settings-card {
+.settings-card
+{
display: grid;
align-content: start;
gap: 1.5rem;
padding: clamp(1.75rem, 4vw, 2.75rem);
- border: 1px solid rgb(255 255 255 / 82%);
- border-radius: 2.5rem;
- background: rgb(255 255 255 / 70%);
- box-shadow: var(--clay-card-shadow);
- backdrop-filter: blur(1.25rem);
+ border: 1px solid var(--line);
+ border-radius: 1rem;
+ background: var(--paper);
+ box-shadow: none;
}
-.settings-card .clay-icon {
+.settings-card .clay-icon
+{
margin: 0;
}
-.settings-label {
+.settings-label
+{
margin: 0 0 0.4rem;
- color: var(--violet);
+ color: var(--accent);
font-size: 0.75rem;
font-weight: 800;
letter-spacing: 0.12em;
text-transform: uppercase;
}
-.settings-card h2 {
+.settings-card h2
+{
margin: 0 0 0.5rem;
- font-family: Nunito, ui-rounded, sans-serif;
+ font-family: "Trebuchet MS", "Arial Rounded MT Bold", sans-serif;
font-size: 1.5rem;
- font-weight: 900;
+ font-weight: 700;
line-height: 1.2;
}
-.account-details {
+.account-details
+{
display: grid;
gap: 0.75rem;
margin: 1.5rem 0 0;
}
-.account-details div {
+.account-details div
+{
display: grid;
gap: 0.15rem;
padding: 1rem 1.25rem;
- border-radius: 1.25rem;
- background: #efebf5;
- box-shadow: var(--clay-pressed-shadow);
+ border-radius: 1rem;
+ background: #f0e5fa;
+ box-shadow: none;
}
-.account-details dt {
+.account-details dt
+{
color: var(--muted);
font-size: 0.7rem;
font-weight: 800;
@@ -1547,43 +1580,48 @@ h1 {
text-transform: uppercase;
}
-.account-details dd {
+.account-details dd
+{
margin: 0;
overflow-wrap: anywhere;
- font-family: Nunito, ui-rounded, sans-serif;
+ font-family: "Trebuchet MS", "Arial Rounded MT Bold", sans-serif;
font-size: 1.05rem;
font-weight: 800;
}
-.settings-card .clay-action {
+.settings-card .clay-action
+{
width: fit-content;
}
-.heading-copy {
+.heading-copy
+{
max-width: 24rem;
margin: 0;
color: var(--muted);
font-size: 1.05rem;
}
-.user-table-shell {
+.user-table-shell
+{
overflow-x: auto;
padding: 1rem;
- border: 1px solid rgb(255 255 255 / 82%);
- border-radius: 2.5rem;
- background: rgb(255 255 255 / 70%);
- box-shadow: var(--clay-card-shadow);
- backdrop-filter: blur(1.25rem);
+ border: 1px solid var(--line);
+ border-radius: 1rem;
+ background: var(--paper);
+ box-shadow: none;
}
-.user-table {
+.user-table
+{
width: 100%;
border-collapse: separate;
border-spacing: 0 0.75rem;
text-align: left;
}
-.user-table th {
+.user-table th
+{
padding: 0 1rem 0.25rem;
color: var(--muted);
font-size: 0.7rem;
@@ -1592,48 +1630,53 @@ h1 {
text-transform: uppercase;
}
-.user-table td {
+.user-table td
+{
padding: 1rem;
- background: #efebf5;
- box-shadow:
- inset 5px 5px 11px rgb(185 177 198 / 40%),
- inset -5px -5px 11px rgb(255 255 255 / 85%);
+ background: #f0e5fa;
+ box-shadow: none;
overflow-wrap: anywhere;
}
-.user-table td:first-child {
- border-radius: 1.25rem 0 0 1.25rem;
+.user-table td:first-child
+{
+ border-radius: 1rem;
}
-.user-table td:last-child {
- border-radius: 0 1.25rem 1.25rem 0;
+.user-table td:last-child
+{
+ border-radius: 1rem;
}
-.role-badge {
+.role-badge
+{
display: inline-flex;
min-height: 2rem;
align-items: center;
padding: 0.3rem 0.75rem;
- border-radius: 999px;
- background: rgb(124 58 237 / 10%);
- color: var(--violet);
+ border-radius: 1rem;
+ background: rgb(183 53 32 / 10%);
+ color: var(--accent);
font-size: 0.72rem;
- font-weight: 900;
+ font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
}
-.user-action {
+.user-action
+{
text-align: right;
}
-.table-action {
+.table-action
+{
min-height: 2.75rem;
padding: 0.5rem 1rem;
font-size: 0.8rem;
}
-.visually-hidden {
+.visually-hidden
+{
position: absolute;
width: 1px;
height: 1px;
@@ -1644,101 +1687,124 @@ h1 {
border: 0;
}
-@media(max-width: 62rem) {
+@media(max-width: 62rem)
+{
.welcome-hero,
- .account-grid {
+ .account-grid
+ {
grid-template-columns: 1fr;
}
- .welcome-copy {
+ .welcome-copy
+ {
text-align: center;
justify-self: center;
}
- .hero-copy {
+ .hero-copy
+ {
margin-inline: auto;
}
- .welcome-preview {
+ .welcome-preview
+ {
min-height: 32rem;
}
- .collection-heading {
+ .collection-heading
+ {
align-items: stretch;
flex-direction: column;
}
- .pull-panel {
+ .pull-panel
+ {
width: fit-content;
}
}
-@media(max-width: 42rem) {
- .public-main {
+@media(max-width: 42rem)
+{
+ .public-main
+ {
padding-top: 10rem;
}
- .public-header {
+ .public-header
+ {
align-items: center;
flex-direction: row;
}
- .public-header-note {
+ .public-header-note
+ {
font-size: 0.65rem;
}
- .welcome-hero {
+ .welcome-hero
+ {
gap: 1rem;
}
- .welcome-copy h1 {
+ .welcome-copy h1
+ {
font-size: clamp(3.25rem, 17vw, 5rem);
}
- .welcome-preview {
+ .welcome-preview
+ {
min-height: 29rem;
}
- .public-card {
+ .public-card
+ {
padding: 2rem 1.5rem;
- border-radius: 2rem;
+ border-radius: 1rem;
}
- .pull-panel {
+ .pull-panel
+ {
width: 100%;
align-items: stretch;
flex-direction: column;
}
.pull-panel form,
- .pull-button {
+ .pull-button
+ {
width: 100%;
}
- .collection-grid {
+ .collection-grid
+ {
grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
gap: 1rem;
}
- .collection-card a {
- border-radius: 1.5rem;
+ .collection-card a
+ {
+ border-radius: 1rem;
}
- .collection-image {
- border-radius: 1.15rem;
+ .collection-image
+ {
+ border-radius: 1rem;
}
- .settings-card {
- border-radius: 2rem;
+ .settings-card
+ {
+ border-radius: 1rem;
}
.settings-card .clay-action,
.settings-card form,
- .settings-card form .clay-action {
+ .settings-card form .clay-action
+ {
width: 100%;
}
- .user-table-shell {
+ .user-table-shell
+ {
padding: 0;
overflow: visible;
border: 0;
@@ -1749,25 +1815,29 @@ h1 {
.user-table,
.user-table tbody,
.user-table tr,
- .user-table td {
+ .user-table td
+ {
display: block;
width: 100%;
}
- .user-table thead {
+ .user-table thead
+ {
display: none;
}
- .user-table tr {
+ .user-table tr
+ {
margin-bottom: 1.25rem;
padding: 1.25rem;
- border: 1px solid rgb(255 255 255 / 82%);
- border-radius: 2rem;
- background: rgb(255 255 255 / 70%);
- box-shadow: var(--clay-card-shadow);
+ border: 1px solid var(--line);
+ border-radius: 1rem;
+ background: var(--paper);
+ box-shadow: none;
}
- .user-table td {
+ .user-table td
+ {
display: grid;
grid-template-columns: 6rem minmax(0, 1fr);
gap: 0.75rem;
@@ -1776,7 +1846,8 @@ h1 {
box-shadow: none;
}
- .user-table td::before {
+ .user-table td::before
+ {
color: var(--muted);
content: attr(data-label);
font-size: 0.68rem;
@@ -1786,23 +1857,27 @@ h1 {
}
.user-table td:first-child,
- .user-table td:last-child {
- border-radius: 0;
+ .user-table td:last-child
+ {
+ border-radius: 1rem;
}
- .user-table .user-action {
+ .user-table .user-action
+ {
display: block;
padding-top: 1rem;
text-align: left;
}
.user-action form,
- .table-action {
+ .table-action
+ {
width: 100%;
}
}
-.management-actions {
+.management-actions
+{
display: flex;
flex-wrap: wrap;
align-items: center;
@@ -1810,16 +1885,19 @@ h1 {
margin-bottom: 2.5rem;
}
-.page-heading .management-actions {
+.page-heading .management-actions
+{
justify-content: flex-end;
margin-bottom: 0;
}
-.games-page {
+.games-page
+{
width: 100%;
}
-.game-admin-grid {
+.game-admin-grid
+{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr));
gap: clamp(1.5rem, 3vw, 2.5rem);
@@ -1828,69 +1906,77 @@ h1 {
list-style: none;
}
-.game-admin-card {
+.game-admin-card
+{
padding: clamp(1.5rem, 4vw, 2.5rem);
- border: 1px solid rgb(255 255 255 / 82%);
- border-radius: 2.5rem;
- background: rgb(255 255 255 / 70%);
- box-shadow: var(--clay-card-shadow);
- backdrop-filter: blur(1.25rem);
+ border: 1px solid var(--line);
+ border-radius: 1rem;
+ background: var(--paper);
+ box-shadow: none;
transition:
- box-shadow 500ms ease,
- transform 500ms cubic-bezier(0.2, 0.8, 0.2, 1);
+ box-shadow 500ms ease,
+ transform 500ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
-.game-admin-card:hover {
- box-shadow: var(--clay-card-shadow-hover);
+.game-admin-card:hover
+{
+ box-shadow: none;
transform: translateY(-0.5rem);
}
-.game-admin-card > header {
+.game-admin-card > header
+{
display: flex;
align-items: center;
gap: 1rem;
}
-.game-admin-card .clay-icon {
+.game-admin-card .clay-icon
+{
margin: 0;
text-transform: uppercase;
}
-.game-admin-card h2 {
+.game-admin-card h2
+{
margin: 0;
- font-family: Nunito, ui-rounded, sans-serif;
+ font-family: "Trebuchet MS", "Arial Rounded MT Bold", sans-serif;
font-size: 1.6rem;
- font-weight: 900;
+ font-weight: 700;
line-height: 1.2;
}
-.game-description {
+.game-description
+{
margin: 1.5rem 0;
color: var(--muted);
white-space: pre-wrap;
}
-.game-field-heading {
+.game-field-heading
+{
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 0.75rem;
- font-family: Nunito, ui-rounded, sans-serif;
- font-weight: 900;
+ font-family: "Trebuchet MS", "Arial Rounded MT Bold", sans-serif;
+ font-weight: 700;
}
-.game-field-heading span {
+.game-field-heading span
+{
display: grid;
min-width: 2rem;
min-height: 2rem;
place-items: center;
- border-radius: 50%;
- background: rgb(124 58 237 / 10%);
- color: var(--violet);
+ border-radius: 1rem;
+ background: rgb(183 53 32 / 10%);
+ color: var(--accent);
font-size: 0.75rem;
}
-.game-field-list {
+.game-field-list
+{
display: grid;
gap: 0.65rem;
margin: 0;
@@ -1898,61 +1984,61 @@ h1 {
list-style: none;
}
-.game-field-list li {
+.game-field-list li
+{
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
padding: 0.9rem 1rem;
- border-radius: 1.25rem;
- background: #efebf5;
- box-shadow:
- inset 5px 5px 11px rgb(185 177 198 / 40%),
- inset -5px -5px 11px rgb(255 255 255 / 85%);
+ border-radius: 1rem;
+ background: #f0e5fa;
+ box-shadow: none;
}
-.game-field-list li > span:first-child {
+.game-field-list li > span:first-child
+{
display: grid;
}
-.game-field-list small {
+.game-field-list small
+{
color: var(--muted);
font-family: ui-monospace, monospace;
}
-.field-type {
+.field-type
+{
padding: 0.3rem 0.65rem;
- border-radius: 999px;
+ border-radius: 1rem;
background: rgb(14 165 233 / 10%);
color: #036b9f;
font-size: 0.7rem;
- font-weight: 900;
+ font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
}
-.internal-badge {
+.internal-badge
+{
display: inline-flex;
align-items: center;
min-height: 1.75rem;
padding: 0.25rem 0.7rem;
border: 1px solid rgb(219 39 119 / 18%);
- border-radius: 999px;
+ border-radius: 1rem;
background: rgb(245 158 11 / 15%);
- box-shadow:
- 4px 4px 9px rgb(160 150 180 / 16%),
- -3px -3px 7px rgb(255 255 255 / 82%),
- inset 2px 2px 4px rgb(255 255 255 / 40%),
- inset -2px -2px 4px rgb(219 39 119 / 8%);
+ box-shadow: none;
color: #9d174d;
font-size: 0.7rem;
- font-weight: 900;
+ font-weight: 700;
letter-spacing: 0.06em;
line-height: 1;
text-transform: uppercase;
}
-.visibility-options {
+.visibility-options
+{
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 1rem;
@@ -1961,90 +2047,104 @@ h1 {
border: 0;
}
-.visibility-options legend {
+.visibility-options legend
+{
grid-column: 1 / -1;
margin-bottom: 0.2rem;
- font-family: Nunito, ui-rounded, sans-serif;
+ font-family: "Trebuchet MS", "Arial Rounded MT Bold", sans-serif;
font-size: 0.9rem;
- font-weight: 900;
+ font-weight: 700;
}
-.visibility-option {
+.visibility-option
+{
display: flex;
align-items: center;
min-height: 4.5rem;
gap: 0.8rem;
padding: 0.9rem 1rem;
- border-radius: 1.25rem;
- background: #efebf5;
- box-shadow: var(--clay-pressed-shadow);
+ border-radius: 1rem;
+ background: #f0e5fa;
+ box-shadow: none;
cursor: pointer;
}
-.visibility-option:has(input:checked) {
- background: rgb(255 255 255 / 84%);
- outline: 0.2rem solid rgb(124 58 237 / 18%);
+.visibility-option:has(input:checked)
+{
+ background: var(--paper);
+ outline: 0.2rem solid rgb(183 53 32 / 18%);
}
-.visibility-option:has(input:focus-visible) {
- outline: 0.25rem solid rgb(124 58 237 / 30%);
+.visibility-option:has(input:focus-visible)
+{
+ outline: 0.25rem solid rgb(183 53 32 / 30%);
}
-.visibility-option input {
+.visibility-option input
+{
width: 1.25rem;
height: 1.25rem;
margin: 0;
- accent-color: var(--violet);
+ accent-color: var(--accent);
}
-.visibility-option span {
+.visibility-option span
+{
display: grid;
gap: 0.2rem;
}
-.visibility-option strong {
- font-family: Nunito, ui-rounded, sans-serif;
- font-weight: 900;
+.visibility-option strong
+{
+ font-family: "Trebuchet MS", "Arial Rounded MT Bold", sans-serif;
+ font-weight: 700;
}
-.visibility-option small {
+.visibility-option small
+{
color: var(--muted);
font-weight: 600;
line-height: 1.35;
}
-@media(max-width: 42rem) {
- .visibility-options {
+@media(max-width: 42rem)
+{
+ .visibility-options
+ {
grid-template-columns: 1fr;
}
}
-.game-editor {
+.game-editor
+{
width: 100%;
}
.clay-form-panel,
-.definition-panel {
+.definition-panel
+{
padding: clamp(1.5rem, 4vw, 2.5rem);
- border: 1px solid rgb(255 255 255 / 82%);
- border-radius: 2.5rem;
- background: rgb(255 255 255 / 70%);
- box-shadow: var(--clay-card-shadow);
- backdrop-filter: blur(1.25rem);
+ border: 1px solid var(--line);
+ border-radius: 1rem;
+ background: var(--paper);
+ box-shadow: none;
}
-.clay-form-panel {
+.clay-form-panel
+{
width: min(52rem, 100%);
}
-.definition-panel {
+.definition-panel
+{
margin-top: 2.5rem;
}
.section-heading,
.definition-list > li,
.definition-actions,
-.choice-row {
+.choice-row
+{
display: flex;
align-items: center;
justify-content: space-between;
@@ -2052,13 +2152,15 @@ h1 {
}
.section-heading h2,
-.definition-copy h3 {
+.definition-copy h3
+{
margin: 0;
- font-family: Nunito, ui-rounded, sans-serif;
- font-weight: 900;
+ font-family: "Trebuchet MS", "Arial Rounded MT Bold", sans-serif;
+ font-weight: 700;
}
-.definition-list {
+.definition-list
+{
display: grid;
gap: 1rem;
margin: 1.75rem 0 0;
@@ -2066,124 +2168,144 @@ h1 {
list-style: none;
}
-.definition-list > li {
+.definition-list > li
+{
padding: 1.25rem;
- border-radius: 1.75rem;
- background: #efebf5;
- box-shadow: var(--clay-pressed-shadow);
+ border-radius: 1rem;
+ background: #f0e5fa;
+ box-shadow: none;
}
-.definition-copy p {
+.definition-copy p
+{
margin: 0;
color: var(--muted);
}
-.definition-actions {
+.definition-actions
+{
flex-wrap: wrap;
justify-content: flex-end;
}
-.definition-actions form {
+.definition-actions form
+{
margin: 0;
}
.definition-actions .clay-action,
-.choice-row .clay-action {
+.choice-row .clay-action
+{
min-height: 2.75rem;
padding: 0.55rem 0.9rem;
}
-.choice-rows {
+.choice-rows
+{
display: grid;
gap: 0.85rem;
margin-bottom: 1rem;
}
-.choice-row input {
+.choice-row input
+{
min-width: 10rem;
min-height: 3.25rem;
flex: 1;
padding: 0.75rem 1rem;
border: 0;
- border-radius: 1.15rem;
- background: #efebf5;
- box-shadow:
- inset 7px 7px 15px rgb(185 177 198 / 55%),
- inset -7px -7px 15px rgb(255 255 255 / 90%);
+ border-radius: 1rem;
+ background: #f0e5fa;
+ box-shadow: none;
color: var(--foreground);
font: inherit;
font-weight: 600;
}
-.choice-row input:focus {
- background: rgb(255 255 255 / 84%);
- outline: 0.25rem solid rgb(124 58 237 / 20%);
+.choice-row input:focus
+{
+ background: var(--paper);
+ outline: 0.25rem solid rgb(183 53 32 / 20%);
}
-.form-tail-actions {
+.form-tail-actions
+{
margin-top: 2rem;
margin-bottom: 0;
}
-.mutation-error-page {
+.mutation-error-page
+{
width: min(56rem, 100%);
}
-.mutation-error-page h1 {
+.mutation-error-page h1
+{
margin-bottom: 2rem;
}
-.error-summary {
+.error-summary
+{
margin-bottom: 2rem;
padding: 1.5rem;
border: 2px solid rgb(190 24 93 / 28%);
- border-radius: 1.75rem;
- background: rgb(255 255 255 / 72%);
- box-shadow: var(--clay-card-shadow);
+ border-radius: 1rem;
+ background: var(--paper);
+ box-shadow: none;
}
.error-summary h2,
-.error-summary p {
+.error-summary p
+{
margin-top: 0;
}
-.error-summary p:last-child {
+.error-summary p:last-child
+{
margin-bottom: 0;
}
-.field-error {
+.field-error
+{
color: #9d174d;
font-weight: 800;
}
-[aria-invalid="true"] {
+[aria-invalid="true"]
+{
border-color: #be185d;
- box-shadow: 0 0 0 0.2rem rgb(190 24 93 / 14%);
+ box-shadow: none;
}
-@media(max-width: 42rem) {
+@media(max-width: 42rem)
+{
.management-actions,
- .page-heading .management-actions {
+ .page-heading .management-actions
+ {
width: 100%;
align-items: stretch;
flex-direction: column;
}
- .management-actions > .clay-action {
+ .management-actions > .clay-action
+ {
width: 100%;
}
- .game-admin-grid {
+ .game-admin-grid
+ {
grid-template-columns: 1fr;
}
- .game-admin-card {
- border-radius: 2rem;
+ .game-admin-card
+ {
+ border-radius: 1rem;
}
.section-heading,
.definition-list > li,
- .choice-row {
+ .choice-row
+ {
align-items: stretch;
flex-direction: column;
}
@@ -2191,7 +2313,613 @@ h1 {
.definition-actions,
.definition-actions form,
.definition-actions .clay-action,
- .choice-row .clay-action {
+ .choice-row .clay-action
+ {
width: 100%;
}
}
+
+/* Sticker book: candy colors, chunky ink, and playful cutouts. */
+body
+{
+ background-image: radial-gradient(#d9b6ed 1.5px, transparent 1.5px);
+ background-size: 24px 24px;
+ font-weight: 400;
+}
+
+.site-header
+{
+ top: 0;
+ right: 0;
+ left: 0;
+ min-height: 6rem;
+ padding: 1rem var(--page-gutter);
+ border: 0;
+ border-bottom: 3px solid var(--foreground);
+ background: var(--canvas);
+ box-shadow: none;
+ gap: 1rem;
+}
+
+.site-title
+{
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ font-size: 1.4rem;
+ line-height: 1.1;
+}
+
+.site-title::before
+{
+ content: "✳";
+ color: var(--accent);
+ font-family: Georgia, serif;
+ font-size: 2.8rem;
+ line-height: 1;
+}
+
+.nav-link,
+.eyebrow,
+.public-header-note,
+.sort-controls,
+.card-id,
+.card-view-id,
+.settings-label,
+.collection-card-details > span
+{
+ font-family: "Trebuchet MS", sans-serif;
+}
+
+.nav-link
+{
+ font-size: 0.78rem;
+ text-transform: uppercase;
+ letter-spacing: 0.04em;
+}
+
+.nav-link:hover
+{
+ background: var(--foreground);
+ color: var(--paper);
+ transform: none;
+}
+
+h1
+{
+ font-weight: 900;
+ letter-spacing: -0.055em;
+ font-size: clamp(3rem, 7vw, 6.75rem);
+}
+
+.page-heading
+{
+ padding-bottom: 2rem;
+ border-bottom: 3px dashed #c9b9d5;
+}
+
+.eyebrow
+{
+ margin-bottom: 1rem;
+}
+
+.card-grid,
+.collection-grid
+{
+ align-items: start;
+}
+
+.card-tile,
+.collection-card a
+{
+ border-color: var(--foreground);
+ box-shadow: 4px 4px 0 #28234425;
+}
+
+.card-tile:hover,
+.collection-card a:hover
+{
+ transform: translateY(-6px) rotate(-1deg);
+ box-shadow: 7px 9px 0 var(--foreground);
+}
+
+.card-details,
+.collection-card-details
+{
+ border-top: 1px solid var(--line);
+ margin-top: 0.75rem;
+}
+
+.collection-quantity
+{
+ border: 1px solid var(--foreground);
+ background: var(--accent);
+ box-shadow: 3px 3px 0 var(--foreground);
+}
+
+.pull-panel
+{
+ border: 1px solid var(--foreground);
+ background: #ffe680;
+}
+
+.pull-count strong
+{
+ font-size: 2.8rem;
+ font-weight: 900;
+}
+
+.clay-action,
+.pull-button,
+.table-action,
+.form-submit
+{
+ border: 1px solid var(--foreground);
+}
+
+.clay-action-secondary
+{
+ background: var(--paper);
+}
+
+.clay-action-danger,
+.destructive-submit
+{
+ background: #8f2520;
+}
+
+.form-field input,
+.form-field textarea,
+.form-field select,
+.choice-row input
+{
+ border: 1px solid #848777;
+ background: var(--paper);
+}
+
+:focus-visible
+{
+ outline: 3px solid var(--accent);
+ outline-offset: 4px;
+}
+
+[aria-invalid="true"]
+{
+ border: 2px solid #9d174d;
+}
+
+.collection-empty,
+.empty-state
+{
+ border: 3px dashed #9b79bb;
+ background: #f0e5fa;
+}
+
+.card-preview-stage
+{
+ background: #e2d7fa;
+}
+
+.card-preview-stage::before,
+.card-preview-stage::after
+{
+ display: none;
+}
+
+.welcome-hero
+{
+ gap: clamp(2rem, 5vw, 6rem);
+}
+
+.welcome-copy h1
+{
+ font-size: clamp(3.5rem, 7.4vw, 7.5rem);
+ line-height: 1.02;
+ font-weight: 900;
+}
+
+.hero-copy
+{
+ max-width: 29rem;
+ font-size: 1.1rem;
+}
+
+.welcome-preview
+{
+ min-height: 37rem;
+ border: 3px solid var(--foreground);
+ border-radius: 48% 48% 2rem 2rem;
+ background: #bde9dc;
+ box-shadow: 8px 8px 0 var(--foreground);
+}
+
+.welcome-preview::before
+{
+ position: absolute;
+ inset: 3rem 0;
+ color: #19766f;
+ content: "✦";
+ font-size: 29rem;
+ line-height: 1;
+ text-align: center;
+ opacity: 0.22;
+ pointer-events: none;
+}
+
+.welcome-card
+{
+ width: min(19rem, 65vw);
+ border: 1px solid var(--foreground);
+ padding: 0.75rem 0.75rem 2.5rem;
+ background: var(--paper);
+ box-shadow: 12px 14px 0 #28234425;
+ transform: rotate(-7deg);
+}
+
+.discovery-sticker
+{
+ position: absolute;
+ z-index: 2;
+ top: 1.5rem;
+ right: 1rem;
+ display: grid;
+ place-content: center;
+ width: 7rem;
+ height: 7rem;
+ border: 3px solid var(--foreground);
+ border-radius: 42% 58% 45% 55%;
+ background: #ffe680;
+ color: var(--foreground);
+ box-shadow: 4px 4px 0 var(--foreground);
+ font: bold 0.85rem/1.4 "Trebuchet MS", sans-serif;
+ text-align: center;
+ transform: rotate(13deg);
+}
+
+.welcome-preview > p
+{
+ bottom: 1.75rem;
+ padding-inline: 1.5rem;
+ font: 0.72rem/1.5 "Trebuchet MS", sans-serif;
+}
+
+.public-card,
+.settings-card,
+.game-admin-card,
+.clay-form-panel,
+.definition-panel,
+.form-page,
+.card-info-panel
+{
+ border: 3px solid var(--foreground);
+ border-radius: 1.5rem;
+ box-shadow: 6px 6px 0 var(--foreground);
+}
+
+.skip-link
+{
+ position: fixed;
+ z-index: 200;
+ top: -6rem;
+ left: 1rem;
+ padding: 0.75rem 1rem;
+ background: var(--foreground);
+ color: var(--paper);
+}
+
+.skip-link:focus
+{
+ top: 1rem;
+}
+
+@media(max-width: 62rem)
+{
+ .site-header
+ {
+ flex-wrap: wrap;
+ }
+
+ .welcome-copy
+ {
+ text-align: left;
+ justify-self: start;
+ }
+
+ .welcome-preview
+ {
+ width: min(100%, 36rem);
+ justify-self: center;
+ }
+}
+
+@media(max-width: 42rem)
+{
+ :root
+ {
+ --main-top: 14rem;
+ }
+
+ .site-header
+ {
+ gap: 0.6rem;
+ }
+
+ .public-header
+ {
+ align-items: flex-start;
+ flex-direction: column;
+ }
+
+ .public-main
+ {
+ padding-top: 10rem;
+ }
+
+ .nav-link
+ {
+ padding-inline: 0.5rem;
+ }
+
+ .welcome-preview
+ {
+ min-height: 33rem;
+ margin-top: 2rem;
+ }
+
+ .card-grid,
+ .collection-grid
+ {
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 1rem;
+ }
+
+ .collection-card a
+ {
+ padding: 0.4rem 0.4rem 0.8rem;
+ }
+
+ .card-image-link
+ {
+ margin: 0.4rem;
+ }
+
+ .collection-card-details,
+ .card-details
+ {
+ padding-inline: 0.3rem;
+ }
+
+ .series-admin-list > li,
+ .series-admin-actions
+ {
+ align-items: flex-start;
+ flex-wrap: wrap;
+ }
+}
+
+.clay-action,
+.pull-button,
+.table-action,
+.form-submit
+{
+ box-shadow: var(--button-shadow);
+}
+
+.clay-action:hover:not(:disabled),
+.pull-button:hover:not(:disabled),
+.table-action:hover:not(:disabled),
+.form-submit:hover:not(:disabled)
+{
+ box-shadow: 5px 5px 0 var(--foreground);
+}
+
+.clay-action:active:not(:disabled),
+.pull-button:active:not(:disabled),
+.table-action:active:not(:disabled),
+.form-submit:active:not(:disabled)
+{
+ box-shadow: none;
+ transform: translate(3px, 3px);
+}
+
+button:disabled
+{
+ box-shadow: none;
+ transform: none;
+}
+
+/* Each mount gets its own sticker-paper color. */
+.card-tile,
+.collection-card a
+{
+ border: 3px solid var(--foreground);
+ border-radius: 1.25rem;
+ background: #e4d6fc;
+ box-shadow: 5px 5px 0 var(--foreground);
+}
+
+.card-tile:nth-child(3n + 2),
+.collection-card:nth-child(3n + 2) a
+{
+ background: #ffe680;
+}
+
+.card-tile:nth-child(3n),
+.collection-card:nth-child(3n) a
+{
+ background: #f9c2dc;
+}
+
+.card-tile:nth-child(even):hover,
+.collection-card:nth-child(even) a:hover
+{
+ transform: translateY(-6px) rotate(2deg);
+}
+
+.card-details,
+.collection-card-details
+{
+ border: 0;
+}
+
+.collection-card-name,
+.card-details h2
+{
+ font-weight: 900;
+}
+
+.collection-quantity
+{
+ border: 2px solid var(--foreground);
+ border-radius: 50%;
+ background: var(--foreground);
+ transform: rotate(8deg);
+}
+
+.site-title
+{
+ font-weight: 900;
+ letter-spacing: -0.06em;
+}
+
+.site-title::before
+{
+ color: #673bc2;
+ transform: rotate(-12deg);
+}
+
+.nav-link:hover
+{
+ background: #ffe680;
+ color: var(--foreground);
+ transform: rotate(-3deg);
+}
+
+.eyebrow
+{
+ display: inline-block;
+ padding: 0.3rem 0.75rem;
+ border: 2px solid var(--foreground);
+ border-radius: 0.5rem;
+ background: #ffe680;
+ color: var(--foreground);
+ letter-spacing: 0.06em;
+ transform: rotate(-2deg);
+}
+
+.welcome-copy h1 span
+{
+ color: var(--accent);
+ text-shadow: 3px 3px 0 #d5bff1;
+}
+
+.clay-action,
+.pull-button,
+.table-action,
+.form-submit
+{
+ border-width: 2px;
+ border-radius: 0.85rem;
+ font-weight: 800;
+}
+
+.pull-panel
+{
+ border-width: 2px;
+ border-radius: 1.25rem;
+ box-shadow: 5px 5px 0 var(--foreground);
+}
+
+.welcome-card
+{
+ border: 3px solid var(--foreground);
+ border-radius: 1.25rem;
+ box-shadow: 8px 10px 0 #28234450;
+}
+
+.welcome-preview > p
+{
+ font-size: 0.85rem;
+ font-weight: 700;
+ color: var(--foreground);
+}
+
+.clay-icon
+{
+ border: 2px solid var(--foreground);
+ box-shadow: 3px 3px 0 var(--foreground);
+ transform: rotate(-8deg);
+}
+
+.clay-icon-pink
+{
+ background: #a52d62;
+}
+
+.clay-icon-blue
+{
+ background: #19766f;
+}
+
+@media(max-width: 42rem)
+{
+ .welcome-preview::before
+ {
+ top: 6rem;
+ font-size: 20rem;
+ }
+
+ .welcome-copy h1
+ {
+ font-size: clamp(3.2rem, 13vw, 5rem);
+ }
+}
+
+/* Native GET switch keeps the card filter shareable without JavaScript. */
+.card-filter
+{
+ margin: 0 0 2rem;
+}
+
+.internal-toggle
+{
+ display: inline-flex;
+ align-items: center;
+ gap: 0.75rem;
+ min-height: 2.75rem;
+ padding: 0.5rem 0.75rem;
+ border: 2px solid var(--foreground);
+ border-radius: 0.85rem;
+ background: var(--paper);
+ color: var(--foreground);
+ font: inherit;
+ font-weight: 700;
+ cursor: pointer;
+}
+
+.toggle-track
+{
+ display: flex;
+ align-items: center;
+ width: 2.75rem;
+ height: 1.5rem;
+ padding: 0.125rem;
+ border: 2px solid var(--foreground);
+ border-radius: 2rem;
+ background: #f0e5fa;
+}
+
+.toggle-track::before
+{
+ width: 1rem;
+ height: 1rem;
+ border-radius: 50%;
+ background: var(--foreground);
+ content: "";
+}
+
+.internal-toggle[aria-checked="true"] .toggle-track
+{
+ justify-content: flex-end;
+ background: #ffe680;
+}
diff --git a/static/foil/card_preview.js b/static/foil/card_preview.js
index 36bbaf6..d83d1b5 100644
--- a/static/foil/card_preview.js
+++ b/static/foil/card_preview.js
@@ -166,7 +166,7 @@ const FOIL_CALIBRATION = Object.freeze({
const OUTPUT_CALIBRATION = Object.freeze({
LEVELS_BLACK_POINT: 0.0,
- LEVELS_WHITE_POINT: 0.88,
+ LEVELS_WHITE_POINT: 0.8,
LEVELS_MIDTONE: 1.0,
});
diff --git a/templates/card_index.html b/templates/card_index.html
index 6ef97dc..9fc84b5 100644
--- a/templates/card_index.html
+++ b/templates/card_index.html
@@ -32,8 +32,23 @@
{% endif %}
</div>
+{% if administrator %}
+<form class="card-filter" method="get" action="{{ index_url }}">
+ <input type="hidden" name="sort" value="id">
+ <input type="hidden" name="direction"
+ value="{% if descending %}desc{% else %}asc{% endif %}">
+ <button class="internal-toggle" type="submit" role="switch"
+ aria-checked="{% if show_internal %}true{% else %}false{% endif %}"
+ name="show_internal"
+ value="{% if show_internal %}0{% else %}1{% endif %}">
+ <span class="toggle-track" aria-hidden="true"></span>
+ Show internal games
+ </button>
+</form>
+{% endif %}
+
{% if length(cards) == 0 %}
-<p class="empty-state">No cards yet.</p>
+<p class="empty-state">No cards match the current filters.</p>
{% endif %}
<ul class="card-grid">
diff --git a/templates/layout.html b/templates/layout.html
index 79ab006..ac47815 100644
--- a/templates/layout.html
+++ b/templates/layout.html
@@ -7,11 +7,7 @@
<link rel="stylesheet" href="{{ url_for("static", "css/styles.css") }}">
</head>
<body>
- <div class="ambient-light" aria-hidden="true">
- <div class="ambient-blob ambient-blob-violet"></div>
- <div class="ambient-blob ambient-blob-pink"></div>
- <div class="ambient-blob ambient-blob-blue"></div>
- </div>
+ <a class="skip-link" href="#MainContent">Skip to content</a>
<header class="site-header">
<a class="site-title" href="{{ url_for("collection") }}">
Card Collection
@@ -33,7 +29,7 @@
<a class="nav-link" href="{{ url_for("account") }}">Account</a>
</nav>
</header>
- <main>
+ <main id="MainContent">
{% block content %}{% endblock %}
</main>
{% block scripts %}{% endblock %}
diff --git a/templates/public_layout.html b/templates/public_layout.html
index 72fcaf8..c33f480 100644
--- a/templates/public_layout.html
+++ b/templates/public_layout.html
@@ -7,16 +7,12 @@
<link rel="stylesheet" href="{{ url_for("static", "css/styles.css") }}">
</head>
<body>
- <div class="ambient-light" aria-hidden="true">
- <div class="ambient-blob ambient-blob-violet"></div>
- <div class="ambient-blob ambient-blob-pink"></div>
- <div class="ambient-blob ambient-blob-blue"></div>
- </div>
+ <a class="skip-link" href="#MainContent">Skip to content</a>
<header class="site-header public-header">
<span class="site-title">Card Collection</span>
<span class="public-header-note">One card every day</span>
</header>
- <main class="public-main">
+ <main id="MainContent" class="public-main">
{% block content %}{% endblock %}
</main>
</body>
diff --git a/templates/welcome.html b/templates/welcome.html
index 285da89..bc79f0d 100644
--- a/templates/welcome.html
+++ b/templates/welcome.html
@@ -2,8 +2,10 @@
{% block content %}
<section class="welcome-hero" aria-labelledby="WelcomeHeading">
<div class="welcome-copy">
- <p class="eyebrow">A tiny daily ritual</p>
- <h1 id="WelcomeHeading">Build a collection that is yours.</h1>
+ <p class="eyebrow">A little surprise. Every day.</p>
+ <h1 id="WelcomeHeading">Meet your next<br>
+ <span>card crush.</span>
+ </h1>
<p class="hero-copy">
Pull one card every day, discover new favorites, and watch your
personal collection take shape.
@@ -13,12 +15,13 @@
</a>
</div>
<div class="welcome-preview" aria-label="Example collectible card">
- <div class="welcome-orbit welcome-orbit-pink"></div>
- <div class="welcome-orbit welcome-orbit-blue"></div>
+ <span class="discovery-sticker" aria-hidden="true">
+ HELLO,<br>NEW FAVORITE!<br>✦
+ </span>
<div class="welcome-card">
<img src="{{ example_url }}" alt="Example collectible card">
</div>
- <p>There is always another card to discover.</p>
+ <p>Your next favorite is in here.</p>
</div>
</section>
{% endblock %}
diff --git a/tests/app_integration_test.cpp b/tests/app_integration_test.cpp
index 42c8b66..45152ca 100644
--- a/tests/app_integration_test.cpp
+++ b/tests/app_integration_test.cpp
@@ -1095,7 +1095,7 @@ TEST(AppIntegrationTest, ServesPagesAndStaticAssets)
EXPECT_EQ(nonexistent_card->status, 404);
EXPECT_EQ(nonexistent_card->body, concealed_card->body);
auto administrator_cards = client.Get(
- "/collection/admin/cards", session_headers);
+ "/collection/admin/cards?show_internal=1", session_headers);
ASSERT_NE(administrator_cards, nullptr);
ASSERT_EQ(administrator_cards->status, 200);
EXPECT_NE(administrator_cards->body.find("Internal"),
diff --git a/tests/app_test.cpp b/tests/app_test.cpp
index ddd7d20..c4b4ec2 100644
--- a/tests/app_test.cpp
+++ b/tests/app_test.cpp
@@ -202,6 +202,72 @@ TEST(AppTest, RendersCardIndex)
EXPECT_LT(second_position, tenth_position);
}
+/// Verify internal filtering, sort persistence, and creator-route isolation.
+TEST(AppTest, TogglesInternalCards)
+{
+ Card public_card = makeCard(1, 1, "Public card");
+ Card internal_card = makeCard(2, 2, "Secret card");
+ internal_card.identity.game_short_name = "secret";
+ public_card.creator_user_id = 1;
+ internal_card.creator_user_id = 1;
+ auto data_source = std::make_unique<AuthenticatedDataSource>(
+ std::vector<Card>{public_card, internal_card},
+ std::vector<Series>{},
+ std::unordered_map<std::int64_t, std::vector<std::int64_t>>{},
+ std::vector<GameDefinitionSnapshot>{
+ {{"pkm", "Public game", "", GameVisibility::PUBLIC, 1}, {}},
+ {{"secret", "Secret game", "", GameVisibility::INTERNAL, 1}, {}}});
+ App app(
+ makeConfig("https://example.test/collection/"),
+ std::move(data_source), deterministicRandom());
+ App::Request request = authenticatedRequest();
+ request.path = "/collection/admin/cards";
+ App::Response hidden_response;
+ app.handleCardIndex(request, hidden_response);
+ ASSERT_EQ(hidden_response.status, 200);
+ EXPECT_NE(hidden_response.body.find("Public card"), std::string::npos);
+ EXPECT_EQ(hidden_response.body.find("Secret card"), std::string::npos);
+ EXPECT_NE(hidden_response.body.find("aria-checked=\"false\""),
+ std::string::npos);
+
+ request.params.emplace("show_internal", "1");
+ request.params.emplace("direction", "desc");
+ App::Response shown_response;
+ app.handleCardIndex(request, shown_response);
+ ASSERT_EQ(shown_response.status, 200);
+ EXPECT_NE(shown_response.body.find("Public card"), std::string::npos);
+ EXPECT_NE(shown_response.body.find("Secret card"), std::string::npos);
+ EXPECT_NE(shown_response.body.find("aria-checked=\"true\""),
+ std::string::npos);
+ EXPECT_NE(shown_response.body.find(
+ "direction=asc&show_internal=1"), std::string::npos);
+ EXPECT_NE(shown_response.body.find(
+ "direction=desc&show_internal=1"), std::string::npos);
+ EXPECT_NE(shown_response.body.find("value=\"desc\""), std::string::npos);
+ EXPECT_LT(shown_response.body.find("Secret card"),
+ shown_response.body.find("Public card"));
+
+ request.params.erase("show_internal");
+ request.params.emplace("show_internal", "0");
+ App::Response off_response;
+ app.handleCardIndex(request, off_response);
+ ASSERT_EQ(off_response.status, 200);
+ EXPECT_EQ(off_response.body.find("Secret card"), std::string::npos);
+ EXPECT_NE(off_response.body.find("aria-checked=\"false\""),
+ std::string::npos);
+
+ request.path = "/collection/creator/cards";
+ request.params.erase("show_internal");
+ request.params.emplace("show_internal", "1");
+ App::Response creator_response;
+ app.handleCardIndex(request, creator_response);
+ ASSERT_EQ(creator_response.status, 200);
+ EXPECT_NE(creator_response.body.find("Public card"), std::string::npos);
+ EXPECT_EQ(creator_response.body.find("Secret card"), std::string::npos);
+ EXPECT_EQ(creator_response.body.find("role=\"switch\""),
+ std::string::npos);
+}
+
/// Verify the create-card page renders its multipart form and preview.
TEST(AppTest, RendersCardCreationForm)
{