/* ==========================================================
   THEME — change these values to restyle the whole site.
   Every colour on every page comes from this block. This is the
   Salish Sea look; the others people can pick are below it.
   ========================================================== */
:root,
.default-look {
  /* Brand colours */
  --color-primary: #7fb98a;       /* buttons, links, main highlights (sage) */
  --color-primary-dark: #9bcba4;  /* button hover, tag text */
  --color-primary-soft: #24403f;  /* tint behind tags, page glow */
  --color-on-primary: #14222a;    /* text on buttons and other primary-coloured things */
  --color-accent: #6fb3bf;        /* second highlight colour (glacier teal) */

  /* Page colours */
  --color-background: #14222a;    /* page background (night sea) */
  --color-surface: #1e323c;       /* cards and form fields */
  --color-text: #dce7e3;          /* headings and main text (fog) */
  --color-text-muted: #a9bcb6;    /* paragraphs and labels */
  --color-border: #34505a;        /* card, button and form field outlines */

  /* Form messages */
  --color-error: #ffb4a8;
  --color-success: #a6e8b9;
  --color-warning: #f5d67a;       /* "OK" password strength (text) */
  --color-warning-bright: #eab308; /* "OK" password strength (bars) */

  /* Fonts */
  --font-body: Inter, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}

/* ========================================================== */

/* Colour looks visitors can pick with the gear button in the ribbon (see
   SITE_LOOKS in common.js). They're never used on artist pages, which keep
   the artist's own colours. */
:root[data-look='dark'] {
  color-scheme: dark;
  --color-primary: #3b82f6;
  --color-primary-dark: #2563eb;
  --color-primary-soft: #1e2a44;
  --color-on-primary: #ffffff;
  --color-accent: #a78bfa;
  --color-background: #15171c;
  --color-surface: #23262e;
  --color-text: #f3f4f6;
  --color-text-muted: #b4bac6;
  --color-border: #3a3f4b;
  --color-error: #f87171;
  --color-success: #34d399;
  --color-warning: #facc15;
}

:root[data-look='contrast'] {
  color-scheme: light;
  --color-primary: #0033cc;
  --color-primary-dark: #001f80;
  --color-primary-soft: #e5ebff;
  --color-on-primary: #ffffff;
  --color-accent: #5b00b3;
  --color-background: #ffffff;
  --color-surface: #ffffff;
  --color-text: #000000;
  --color-text-muted: #1a1a1a;
  --color-border: #000000;
  --color-error: #990000;
  --color-success: #00592e;
  --color-warning: #7a4d00;
}

:root[data-look='soft'] {
  color-scheme: light;
  --color-primary: #5f7653;
  --color-primary-dark: #4b5e41;
  --color-primary-soft: #e9eee4;
  --color-on-primary: #ffffff;
  --color-accent: #a0675a;
  --color-background: #ded6c8;
  --color-surface: #fbf8f3;
  --color-text: #2e2a25;
  --color-text-muted: #5e564b;
  --color-border: #e0d8ca;
}

:root[data-look='chuckanut'] {
  color-scheme: dark;
  --color-primary: #b0e4c0;       /* mint */
  --color-primary-dark: #c8ecd3;
  --color-primary-soft: #5e3f24;
  --color-on-primary: #13241b;
  --color-accent: #e0b77a;
  --color-background: #2e5e45;    /* evergreen */
  --color-surface: #7a5230;       /* brown */
  --color-text: #fbf3e4;          /* cream */
  --color-text-muted: #ecdcc4;
  --color-border: #9a7350;
  --color-error: #ffcfc7;
  --color-success: #b4f2cc;
  --color-warning: #ffd98a;
}

/* Western Washington University's colours: dark blue page, light blue
   outlines and highlights, white text and light green buttons and links. */
:root[data-look='wwu'] {
  color-scheme: dark;
  --color-primary: #bad80a;       /* WWU light green */
  --color-primary-dark: #d0e85a;
  --color-primary-soft: #002f66;
  --color-on-primary: #003f87;
  --color-accent: #007ac8;        /* WWU light blue */
  --color-background: #003f87;    /* WWU dark blue */
  --color-surface: #0059a8;
  --color-text: #ffffff;
  --color-text-muted: #d6e7f5;
  --color-border: #007ac8;
  --color-error: #ffb4a8;
  --color-success: #a6e8b9;
  --color-warning: #ffc61e;
}

/* Custom: common.js sets the background, card, text and button colours they
   picked (and black or white text for the buttons, whichever reads better);
   the rest are mixed from those. */
:root[data-look='custom'] {
  --color-accent: var(--color-primary);
  --color-primary-dark: color-mix(in srgb, var(--color-primary) 78%, black);
  --color-primary-soft: color-mix(in srgb, var(--color-primary) 14%, var(--color-surface));
  --color-text-muted: color-mix(in srgb, var(--color-text) 72%, var(--color-surface));
  --color-border: color-mix(in srgb, var(--color-text) 14%, var(--color-surface));
}

:root {
  color-scheme: dark; /* dark form controls, to suit the dark colours */
  font-family: var(--font-body);
  /* A soft glow at the top centre, fading into the background colour */
  background: radial-gradient(circle at top,
    color-mix(in srgb, var(--color-primary-soft) 30%, var(--color-background)) 0%,
    var(--color-background) 25%);
  color: var(--color-text);
}

* {
  box-sizing: border-box;
}

/* Anything marked hidden stays hidden, even if a style below gives it a display */
[hidden] {
  display: none !important;
}

html,
body {
  margin: 0;
  min-height: 100%;
}

body {
  display: grid;
  place-items: center;
  min-height: 100vh;
  padding: 1.5rem;
}

.hero-screen {
  width: 100%;
  max-width: 900px;
}

/* Bar across the top of every page but the home page, added by common.js.
   It stretches past the body's padding to reach the edges of the screen. */
body:has(> .site-ribbon) {
  grid-template-rows: auto 1fr;
  padding-top: 0;
}

.site-ribbon {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  align-self: start;
  justify-self: stretch;
  margin: 0 -1.5rem 1.5rem;
  padding: 0.6rem 1.5rem;
  background: color-mix(in srgb, var(--color-surface) 86%, transparent);
  border-bottom: 1px solid var(--color-border);
  backdrop-filter: blur(16px);
  /* Above the page, so the drop-down menus open over it */
  position: relative;
  z-index: 20;
}

/* Logged-in people who chose it in Settings: stays on screen when scrolling */
.site-ribbon.sticky {
  position: sticky;
  top: 0;
}

.ribbon-home {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--color-text);
  font-weight: 700;
  font-size: 1.1rem;
  text-decoration: none;
}

.ribbon-home img {
  width: 40px;
  height: 40px;
}

.ribbon-home:hover span {
  color: var(--color-primary);
}

.ribbon-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-left: auto;
}

/* Smaller than the usual buttons, to fit the bar */
.site-ribbon .button-link {
  min-width: 0;
  padding: 0.5rem 1.1rem;
}

/* The page you're on (or the menu it's in), and the gear button or a menu
   while it's open */
.ribbon-links a[aria-current='page'],
.nav-menu-button.current,
.nav-menu-button[aria-expanded='true'],
.ribbon-gear[aria-expanded='true'] {
  background: var(--color-primary-soft);
  border-color: var(--color-primary);
  color: var(--color-primary-dark);
}

.site-ribbon .ribbon-gear {
  padding: 0.35rem 0.75rem;
  font-size: 1.3rem;
  line-height: 1;
}

/* My pages and Admin as drop-down menus (makeDropDown in common.js). The
   menu opens under its button, lined up with its left edge, or its right
   edge (.align-end) when the button is on the right of the screen. */
.nav-menu {
  position: relative;
}

.nav-menu[hidden] {
  display: none;
}

.nav-menu-arrow {
  margin-left: 0.35rem;
  font-size: 0.8em;
}

.nav-menu-list {
  position: absolute;
  top: calc(100% + 0.35rem);
  left: 0;
  display: grid;
  gap: 0.15rem;
  min-width: 12rem;
  padding: 0.4rem;
  border: 1px solid var(--color-border);
  border-radius: 14px;
  background: var(--color-surface);
  box-shadow: 0 14px 30px rgba(0, 0, 0, 0.25);
}

.nav-menu-list[hidden] {
  display: none;
}

.nav-menu.align-end .nav-menu-list {
  left: auto;
  right: 0;
}

.nav-menu-list a {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 0.85rem;
  border-radius: 9px;
  color: var(--color-text);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.nav-menu-list a[hidden] {
  display: none;
}

.nav-menu-list a:hover,
.nav-menu-list a:focus-visible {
  background: var(--color-primary-soft);
  color: var(--color-primary-dark);
}

.nav-menu-list a[aria-current='page'] {
  background: var(--color-primary);
  color: var(--color-on-primary);
}

/* In edit mode the menus stay open under their buttons, in the ribbon
   rather than over the page, so nothing covers the Done button */
.ribbon-links[data-layout-area] {
  align-items: flex-start;
}

.nav-menu.editing {
  display: grid;
  justify-items: start;
  gap: 0.4rem;
}

.nav-menu.editing .nav-menu-list {
  position: static;
  min-width: 11rem;
  border-style: dashed;
  box-shadow: none;
}

.nav-menu-list .layout-item {
  display: flex;
}

.nav-menu-list .layout-item[hidden] {
  display: none;
}

.nav-menu-list .layout-name {
  flex: 1;
}

/* "Edit button layout" (common.js): the bar of tips and buttons across the
   ribbon, and each button with its arrows, dashed to show it can be moved */
.layout-bar {
  flex-basis: 100%;
  display: grid;
  gap: 0.5rem;
  padding: 0.75rem 0 0.25rem;
  border-top: 1px solid var(--color-border);
}

.layout-bar p {
  margin: 0;
}

.layout-item {
  display: inline-flex;
  align-items: center;
  gap: 0.15rem;
  padding: 0.2rem 0.3rem;
  border: 1px dashed var(--color-primary);
  border-radius: 9999px;
  background: var(--color-surface);
  color: var(--color-text);
  font-weight: 600;
  cursor: grab;
}

.layout-item[hidden] {
  display: none;
}

.layout-item.dragging,
.layout-item-unused {
  opacity: 0.5;
}

/* "Turn off fancy graphics" in the gear panel: nothing fades, glides or
   lifts up on hover (the buttons above glide in common.js, glideButtons) */
[data-plain-motion] *,
[data-plain-motion] *::before,
[data-plain-motion] *::after {
  transition: none !important;
  animation: none !important;
}

[data-plain-motion] .nav-button:hover,
[data-plain-motion] .button-link:hover,
[data-plain-motion] .artist-card:hover {
  transform: none;
}

.layout-name {
  padding: 0 0.35rem;
  white-space: nowrap;
}

.layout-move {
  display: inline-grid;
  place-items: center;
  min-width: 1.9rem;
  min-height: 1.9rem;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 9999px;
  background: transparent;
  color: var(--color-text-muted);
  font: inherit;
  font-size: 0.8rem;
  cursor: pointer;
}

/* ↓ and ↑ are drawn smaller than ◀ and ▶ in most fonts, so they're
   bigger to match */
.layout-move[data-move="menu"],
.layout-move[data-move="admin"],
.layout-move[data-move="ribbon"] {
  font-size: 1.2rem;
  font-weight: 700;
  line-height: 1;
}

.layout-move:hover,
.layout-move:focus-visible {
  border-color: var(--color-primary);
  color: var(--color-text);
}

/* With a mouse or trackpad, the arrows only show on the button the pointer
   is over (or the keyboard is on), so the bar is less busy. They still take
   up their space, so buttons don't jump around. Touch screens always show
   them, because dragging doesn't work well there. */
@media (hover: hover) and (pointer: fine) {
  .layout-move {
    opacity: 0;
    transition: opacity 0.15s;
  }

  /* focus-visible, not focus-within: edit mode starts with the focus on the
     first arrow, which shouldn't keep its arrows showing for mouse users */
  .layout-item:hover .layout-move,
  .layout-item:has(.layout-move:focus-visible) .layout-move {
    opacity: 1;
  }
}

/* Site settings panel under the gear button. It's inside the ribbon, on a
   line of its own, so opening it pushes the page down. */
.prefs-panel {
  flex-basis: 100%;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1rem 2rem;
  padding: 1rem 0 0.25rem;
  border-top: 1px solid var(--color-border);
  color: var(--color-text);
}

.prefs-group {
  display: grid;
  align-content: start;
  gap: 0.5rem;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.prefs-label {
  padding: 0;
  font-weight: 700;
}

.prefs-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
}

.prefs-choice {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  cursor: pointer;
}

.prefs-size {
  min-width: 3.5rem;
  text-align: center;
  font-weight: 600;
}

.prefs-panel select {
  padding: 0.4rem 0.75rem;
  border-radius: 9px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
}

.prefs-panel select:focus {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

.prefs-choice input[type='color'] {
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  background: none;
  cursor: pointer;
}

.prefs-where {
  grid-column: 1 / -1;
  margin: 0;
}

.prefs-where:empty {
  display: none;
}

.hero-card {
  background: color-mix(in srgb, var(--color-surface) 86%, transparent);
  border: 1px solid rgba(148, 163, 184, 0.24);
  border-radius: 32px;
  padding: 3rem;
  backdrop-filter: blur(16px);
  box-shadow: 0 28px 80px rgba(15, 23, 42, 0.09);
  display: grid;
  gap: 2.5rem;
  align-items: center;
}

.hero-copy {
  text-align: center;
}

.hero-copy h1 {
  margin: 0;
  font-size: clamp(2.5rem, 4vw, 4rem);
  line-height: 1.02;
}

.hero-copy p {
  margin: 1.5rem auto 0;
  max-width: 32rem;
  color: var(--color-text-muted);
  font-size: 1.05rem;
  line-height: 1.75;
}

.hero-visual {
  display: grid;
  place-items: center;
  padding: 1.5rem;
  /* Fades from a soft tint of the light highlight colour down to the page background */
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--color-primary-soft) 60%, var(--color-background)),
    var(--color-background));
  border-radius: 28px;
}

/* The sloth links to its artist's page (index.html) */
.hero-visual a {
  display: block;
  width: min(100%, 320px);
  border-radius: 20px;
}

.hero-visual img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 20px;
}

.nav-actions {
  margin-top: 2rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.9rem;
  justify-content: center;
}

.nav-button,
.button-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 118px;
  padding: 0.95rem 1.4rem;
  border-radius: 9999px;
  border: 1px solid transparent;
  background: var(--color-primary);
  color: var(--color-on-primary);
  text-decoration: none;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: transform 180ms ease, background-color 180ms ease, box-shadow 180ms ease;
}

.nav-button:hover,
.button-link:hover {
  background: var(--color-primary-dark);
  transform: translateY(-1px);
  box-shadow: 0 12px 26px color-mix(in srgb, var(--color-primary) 18%, transparent);
}

/* Forms (sign-up, login, account pages, messages and requests) */
.request-form {
  display: grid;
  gap: 0.5rem;
  width: 100%;
  max-width: 32rem;
  margin: 0 auto;
}

.request-form label {
  margin-top: 0.5rem;
  color: var(--color-text-muted);
  font-size: 0.9rem;
  font-weight: 600;
}

.request-form input,
.request-form textarea {
  padding: 0.85rem 1rem;
  border-radius: 12px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
}

.request-form textarea {
  resize: vertical;
  line-height: 1.5;
}

.request-form input:focus,
.request-form textarea:focus {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

.request-form button {
  justify-self: start;
  margin-top: 1rem;
}

/* Password box with an eye button inside it (signup.html) */
.password-field {
  position: relative;
  display: grid;
}

.password-field input {
  padding-right: 3.25rem; /* room for the button so text doesn't run under it */
}

.request-form .show-password {
  position: absolute;
  top: 50%;
  right: 0.4rem;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  margin: 0;
  padding: 0;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: var(--color-text-muted);
  cursor: pointer;
}

.request-form .show-password:hover {
  background: color-mix(in srgb, var(--color-text-muted) 10%, transparent);
  color: var(--color-text);
}

.request-form .show-password:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

.show-password svg {
  width: 1.35rem;
  height: 1.35rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Closed eye while the password is hidden, open eye while it's showing */
.show-password .eye-open,
.show-password[aria-pressed="true"] .eye-closed { display: none; }
.show-password[aria-pressed="true"] .eye-open { display: block; }

.request-form button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.privacy-note {
  margin-top: 1rem;
  padding: 1rem 1.25rem;
  border-radius: 12px;
  background: var(--color-primary-soft);
}

.privacy-note p {
  margin: 0 0 0.75rem;
  color: var(--color-text-muted);
  font-size: 0.9rem;
  line-height: 1.6;
}

.request-form .consent {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  margin: 0;
  color: var(--color-text);
  font-weight: 600;
  cursor: pointer;
}

.request-form .consent input {
  width: 1.15rem;
  height: 1.15rem;
  margin: 0.15rem 0 0;
  padding: 0;
  accent-color: var(--color-primary);
  flex-shrink: 0;
}

/* Password strength meter (signup.html): three bars + a word */
.strength-meter {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.strength-bars {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.3rem;
  flex: 1;
}

.strength-bars span {
  height: 6px;
  border-radius: 3px;
  background: var(--color-border);
  transition: background-color 180ms ease;
}

.strength-label {
  min-width: 4rem;
  font-size: 0.85rem;
  font-weight: 600;
  text-align: right;
}

.strength-meter.weak   { --strength-color: var(--color-error); }
.strength-meter.ok     { --strength-color: var(--color-warning); --strength-bar-color: var(--color-warning-bright); }
.strength-meter.strong { --strength-color: var(--color-success); }

.strength-meter .strength-label { color: var(--strength-color, var(--color-text-muted)); }
.strength-meter.weak   .strength-bars span:nth-child(-n+1),
.strength-meter.ok     .strength-bars span:nth-child(-n+2),
.strength-meter.strong .strength-bars span { background: var(--strength-bar-color, var(--strength-color)); }

.form-hint {
  margin: 0;
  color: var(--color-text-muted);
  font-size: 0.85rem;
}

.form-status {
  margin: 0;
  min-height: 1.5em;
  font-size: 0.95rem;
}

.form-status.error {
  color: var(--color-error);
}

.form-status.success {
  color: var(--color-success);
}

/* Buttons in a column, all the same width (homepage) */
.nav-actions.stacked {
  flex-direction: column;
  align-items: stretch;
  max-width: 18rem;
  margin-inline: auto;
}

@media (min-width: 768px) {
  .hero-card {
    grid-template-columns: 1fr 1fr;
    gap: 3rem;
    padding: 3.5rem;
  }

  .hero-copy {
    text-align: left;
  }

  /* Line the homepage buttons up with the left-aligned text */
  .nav-actions.stacked {
    margin-inline: 0;
  }
}

/* Single-column card, used by the artist pages */
.hero-card.single-column {
  grid-template-columns: 1fr;
}

.single-column .hero-copy {
  text-align: center;
}

/* Artists list (artists.html) */
.artist-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 220px));
  justify-content: center;
  gap: 1.25rem;
}

.artist-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  padding: 1.5rem 1rem;
  border-radius: 24px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  color: var(--color-text);
  text-align: center;
  text-decoration: none;
  transition: transform 180ms ease, border-color 180ms ease, box-shadow 180ms ease;
}

.artist-card:hover {
  transform: translateY(-2px);
  border-color: var(--color-primary);
  box-shadow: 0 12px 26px color-mix(in srgb, var(--color-primary) 18%, transparent);
}

.artist-card h2 {
  margin: 0.5rem 0 0;
  font-size: 1.15rem;
}

/* Profile pictures, or initials when there's no photo */
.avatar {
  display: block;
  flex-shrink: 0;
  width: 120px;
  height: 120px;
  border-radius: 50%;
  object-fit: cover;
}

.avatar-initials {
  display: grid;
  place-items: center;
  background: linear-gradient(135deg, var(--color-primary), var(--color-accent));
  color: var(--color-on-primary);
  font-size: 2.5rem;
  font-weight: 700;
}

/* Shop filters — one button per artist */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem;
}

.filter-chip {
  padding: 0.55rem 1.1rem;
  border-radius: 9999px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 180ms ease, border-color 180ms ease, color 180ms ease;
}

.filter-chip:hover {
  border-color: var(--color-primary);
}

.filter-chip[aria-pressed="true"] {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-on-primary);
}

/* The shop's search box and order (shop.html) */
.shop-tools {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 0.75rem;
}

.shop-search {
  flex: 1 1 16rem;
  max-width: 28rem;
}

.shop-sort {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--color-text-muted);
  font-size: 0.9rem;
  font-weight: 600;
}

.shop-tools input,
.shop-tools select {
  box-sizing: border-box;
  padding: 0.7rem 1rem;
  border-radius: 9999px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
}

.shop-tools input {
  width: 100%;
}

.shop-tools .shop-price input {
  width: 6.5rem;
}

.shop-tools input:focus,
.shop-tools select:focus {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

/* Previous / Page 2 of 5 / Next under a long list (makePager in common.js) */
.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  flex-wrap: wrap;
  margin: 1.5rem 0 0.5rem;
}

.pager[hidden] {
  display: none;
}

.pager button:disabled {
  opacity: 0.4;
  cursor: default;
}

.pager-where {
  color: var(--color-text-muted);
}

.shop-no-matches {
  text-align: center;
}

/* A filter with its name on the left, e.g. "Status" (admin-messages.html) */
.filter-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.6rem 1rem;
}

.filter-label {
  color: var(--color-text-muted);
  font-size: 0.9rem;
  font-weight: 600;
}

/* Items for sale (shop.html) */
.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 250px));
  justify-content: center;
  gap: 1.25rem;
}

.product-card {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: 24px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
}

.product-image-wrap {
  position: relative;
}

/* The heart button that saves a listing (public-pages.js). On a card it sits in the
   photo's top-right corner, above the link that covers the card. */
.save-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  border: 1px solid var(--color-border);
  border-radius: 9999px;
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  cursor: pointer;
  transition: border-color 180ms ease;
}

.save-button:hover {
  border-color: var(--color-primary);
}

.save-button:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.save-button[aria-pressed="true"] .save-heart {
  color: var(--color-primary);
}

.save-heart {
  font-size: 1.25rem;
  line-height: 1;
}

.product-card .product-image-wrap .save-button {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
  z-index: 1;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
}

.save-button-text {
  justify-self: start;
  align-self: flex-start;
  padding: 0.5rem 1rem;
  font-weight: 600;
}

.product-image {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
}

.product-image-placeholder {
  display: grid;
  place-items: center;
  background: var(--color-primary-soft);
  color: var(--color-primary-dark);
  font-size: 0.9rem;
}

.product-info {
  display: grid;
  gap: 0.4rem;
  padding: 1rem 1.25rem 1.25rem;
}

.product-info h3 {
  margin: 0;
  font-size: 1.1rem;
}

.product-artist {
  color: var(--color-primary-dark);
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
}

a.product-artist:hover {
  text-decoration: underline;
}

.product-description {
  margin: 0;
  color: var(--color-text-muted);
  font-size: 0.95rem;
  line-height: 1.6;
}

.product-price {
  margin: 0.25rem 0 0;
  font-size: 1.15rem;
  font-weight: 700;
}

/* How it can be bought, and the Buy button, on each shop item */
.product-ways {
  margin: 0;
  color: var(--color-text-muted);
  font-size: 0.85rem;
}

.product-buy {
  margin-top: 0.5rem;
  min-width: 0;
  padding: 0.7rem 1rem;
}

/* In the shop, the title links to the listing's own page, and the link
   stretches over the whole card so clicking anywhere opens it. The card's
   other links and buttons (the seller's name, Buy) sit above it. */
.product-card-link {
  color: inherit;
  text-decoration: none;
}

.product-card-link::after {
  content: '';
  position: absolute;
  inset: 0;
}

.product-card:has(.product-card-link) a:not(.product-card-link),
.product-card:has(.product-card-link) button {
  position: relative;
  z-index: 1;
}

.product-card:has(.product-card-link:hover) h3 {
  text-decoration: underline;
}

.product-card:has(.product-card-link:focus-visible) {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.product-card-link:focus-visible {
  outline: none; /* the card shows it instead */
}

/* The description in full, for admins reviewing an application */
.product-full-description {
  white-space: pre-line;
}

/* A listing's own page (listing.html): big photos one at a time beside the
   details, or above them on small screens */
.listing-page {
  display: grid;
  gap: 2rem;
}

@media (min-width: 768px) {
  .listing-page {
    grid-template-columns: 1.2fr 1fr;
    align-items: start;
  }

  /* "Item not found" has no photos, so keep it centred */
  .listing-page:has(> .hero-copy) {
    grid-template-columns: 1fr;
  }
}

.gallery {
  display: grid;
  gap: 0.75rem;
}

.gallery-frame {
  position: relative;
  overflow: hidden;
  border-radius: 24px;
  background: var(--color-primary-soft);
}

/* The whole photo shows, however it's shaped */
.gallery-photo {
  display: grid;
  width: 100%;
  aspect-ratio: 1;
  object-fit: contain;
}

.gallery:has(.gallery-controls) img.gallery-photo {
  cursor: pointer;
}

.gallery-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.gallery-controls .button-link {
  min-width: 0;
  padding: 0.6rem 1rem;
}

.gallery-counter {
  color: var(--color-text-muted);
  font-size: 0.9rem;
}

.listing-info {
  display: grid;
  gap: 0.5rem;
  justify-items: start;
}

.listing-info h1 {
  margin: 0;
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  line-height: 1.15;
}

.listing-tagline {
  margin: 0.25rem 0 0;
  color: var(--color-text-muted);
  font-size: 1.05rem;
}

.listing-info .nav-button {
  margin-top: 0.5rem;
}

.listing-info .profile-bio p:first-child {
  margin-top: 0.5rem;
}

/* A photo's title under it, in the showcase viewer */
.gallery-caption {
  margin: 0;
  color: var(--color-text-muted);
  text-align: center;
}

/* Sections under an artist's profile (artist.html), like the showcase */
.artist-section {
  display: grid;
  gap: 1rem;
  padding-top: 2rem;
  border-top: 1px solid var(--color-border);
}

/* One artist's commissions page (artist-commissions.html) */
.artist-commissions {
  display: grid;
  gap: 1rem;
  width: 100%;
  max-width: 40rem;
  margin: 0 auto;
}

.artist-commissions h1 {
  margin: 0;
  text-align: center;
}

.artist-commissions .profile-bio p:first-child {
  margin-top: 0;
}

.artist-commissions .kind-prices {
  max-width: none;
}

.artist-commissions .offer-box h2 {
  margin: 0;
  font-size: 1.15rem;
}

.artist-commissions .offer-box .request-form {
  max-width: none;
  margin: 0;
}

.artist-section h2 {
  margin: 0;
  font-size: 1.5rem;
}

.showcase-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 0.75rem;
}

/* One photo in the showcase: a button that opens it big, or a link to a listing */
.showcase-tile {
  position: relative;
  display: block;
  overflow: hidden;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: 16px;
  background: var(--color-surface);
  color: inherit;
  font: inherit;
  text-decoration: none;
  cursor: pointer;
}

.showcase-tile img {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
}

.showcase-tile:hover {
  border-color: var(--color-primary);
}

.showcase-title {
  display: block;
  padding: 0.5rem 0.75rem;
  font-size: 0.9rem;
  text-align: left;
}

.sold-badge.for-sale-badge {
  background: var(--color-primary);
  color: var(--color-on-primary);
}

.showcase-viewer .gallery-photo {
  max-height: 70vh;
}

/* Skills, as tags */
.skill-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.skill-tags li {
  padding: 0.3rem 0.8rem;
  border-radius: 9999px;
  background: var(--color-primary-soft);
  color: var(--color-text);
  font-size: 0.9rem;
}

/* Kinds of work, each with its starting price on the right */
.kind-prices {
  display: grid;
  gap: 0.5rem;
  max-width: 32rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.kind-prices li {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem 1rem;
  border-radius: 12px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
}

.kind-price {
  color: var(--color-text-muted);
  white-space: nowrap;
}

.commission-form select {
  width: 100%;
}

/* A commission request's details, on the Messages page */
.commission-details {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.25rem 1rem;
  margin: 0;
  font-size: 0.95rem;
}

.commission-details dt {
  color: var(--color-text-muted);
}

.commission-details dd {
  margin: 0;
}

/* The kinds of work on commissions.html, one row each */
.kind-fieldset {
  display: grid;
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  border: 0;
}

.kind-fieldset legend {
  margin-bottom: 0.5rem;
  padding: 0;
  font-weight: 600;
}

.kind-fieldset .button-link {
  justify-self: start;
}

.kind-list {
  display: grid;
  gap: 0.5rem;
}

.kind-row {
  display: grid;
  grid-template-columns: 1fr 11rem auto;
  align-items: center;
  gap: 0.5rem;
}

@media (max-width: 480px) {
  .kind-row {
    grid-template-columns: 1fr auto;
  }

  .kind-row input:first-child {
    grid-column: 1 / -1;
  }
}

/* A showcase photo's title box, on the Profile page */
.photo-title {
  width: 100%;
  padding: 0.35rem 0.6rem;
  border-radius: 9999px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  font-size: 0.85rem;
}

/* Why a listing can't be bought straight away (listing.html) */
.buy-unavailable {
  margin: 0;
  font-weight: 600;
}

/* Sold items stay visible but faded, with a "Sold" label */
.product-card.is-sold .product-image,
.product-card.is-sold .product-price {
  opacity: 0.45;
}

.sold-badge {
  position: absolute;
  top: 0.75rem;
  left: 0.75rem;
  padding: 0.3rem 0.75rem;
  border-radius: 9999px;
  background: var(--color-text);
  color: var(--color-surface);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* Artist profile (artist.html) */
.profile {
  display: grid;
  gap: 2rem;
  justify-items: center;
  text-align: center;
}

.profile .avatar {
  width: 200px;
  height: 200px;
  font-size: 4rem;
}

.profile h1 {
  margin: 0.5rem 0 0;
  font-size: clamp(2rem, 4vw, 3rem);
  line-height: 1.1;
}

.profile-bio p {
  margin: 1rem 0 0;
  color: var(--color-text-muted);
  line-height: 1.75;
}

@media (min-width: 768px) {
  .profile {
    grid-template-columns: auto 1fr;
    align-items: start;
    justify-items: start;
    text-align: left;
  }

  /* "Artist not found" message has no photo, so keep it centred */
  .profile:has(> .hero-copy) {
    grid-template-columns: 1fr;
    justify-items: center;
    text-align: center;
  }
}

/* Admin screen (admin*.html) */
.hero-screen.admin-screen {
  max-width: 1100px;
}

.admin-screen .hero-card {
  gap: 2rem;
}

/* The Users page (admin-users.html) uses nearly the whole window, with
   less padding and a tighter table, so a whole row of its wide table fits
   on a laptop screen without scrolling. */
.hero-screen.admin-screen.wide-screen {
  max-width: 1800px;
}

.wide-screen .hero-card {
  padding: 1.5rem;
}

body:has(.wide-screen) {
  padding-inline: 0.75rem;
}

.wide-screen .user-table {
  font-size: 0.9rem;
}

.wide-screen .user-table th,
.wide-screen .user-table td {
  padding: 0.6rem 0.55rem;
}

.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1rem;
  margin-bottom: 0.75rem;
}

.stat-tile {
  display: grid;
  gap: 0.25rem;
  padding: 1.25rem;
  border-radius: 20px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
}

.stat-value {
  font-size: 2rem;
  font-weight: 700;
  color: var(--color-text);
}

.stat-label {
  color: var(--color-text-muted);
  font-size: 0.9rem;
}

.request-form.admin-search {
  max-width: none;
  margin-bottom: 0.5rem;
}

/* Wide tables scroll sideways inside this box on small screens */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--color-border);
  border-radius: 16px;
  background: var(--color-surface);
}

.user-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
}

.user-table th,
.user-table td {
  padding: 0.7rem 0.9rem;
  text-align: left;
  border-bottom: 1px solid var(--color-border);
  white-space: nowrap;
}

.user-table th {
  color: var(--color-text-muted);
  font-size: 0.85rem;
  font-weight: 600;
}

.user-table tbody tr:last-child td {
  border-bottom: none;
}

@media (max-width: 600px) {
  .admin-screen .hero-card {
    padding: 1.5rem;
  }
}

/* Account pages (my-listings.html, profile.html, settings.html, ...) */
.hero-screen.account-screen {
  max-width: 1100px;
}

.account-section {
  display: grid;
  gap: 1rem;
  padding-top: 2rem;
  border-top: 1px solid var(--color-border);
}

.account-section h2 {
  margin: 0;
  font-size: 1.5rem;
}

/* The Settings page's one form around several sections: lays the sections
   out as if the form weren't there (settings.html) */
.settings-form {
  display: contents;
}

/* Forms that use the card's full width instead of a narrow column */
.request-form.wide-form {
  max-width: 40rem;
  margin: 0;
}

.request-form select {
  padding: 0.85rem 1rem;
  border-radius: 12px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
}

.request-form select:focus {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

.avatar-editor {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.5rem;
}

/* The Profile page: photo, buttons and form centred as one column, with
   the form's own text still lined up on the left (profile.html) */
.profile-editor {
  justify-items: center;
  text-align: center;
}

.profile-editor .avatar-editor {
  justify-content: center;
}

.profile-editor .request-form.wide-form {
  width: 100%;
  margin-inline: auto;
  text-align: left;
}

.avatar-buttons,
.form-buttons,
.card-buttons {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
}

.form-buttons button {
  margin-top: 0;
}

.request-form .form-buttons {
  margin-top: 1rem;
}

.card-buttons .product-buy {
  flex: 1;
}

/* A file picker that looks like a button: the real input is hidden inside
   the label, and clicking the label opens it. */
.file-button input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.file-button:focus-within {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* Less important buttons: outlined instead of filled */
.button-link.button-quiet {
  background: var(--color-surface);
  border-color: var(--color-border);
  color: var(--color-text);
}

.button-link.button-quiet:hover {
  background: var(--color-primary-soft);
  border-color: var(--color-primary);
}

@media (max-width: 600px) {
  .account-screen .hero-card {
    padding: 1.5rem;
  }
}

/* Account pages that are one column of forms (settings.html, apply.html,
   edit-listing.html): the card is only as wide as that column plus its
   padding, centred on the page, and gets narrower on small screens.
   Anything too wide to wrap scrolls sideways inside the card. */
.hero-screen.account-screen.column-screen {
  max-width: calc(42rem + 7rem + 2px); /* the column, the card's padding and its border */
}

.column-screen .hero-card {
  overflow-x: auto;
}

.column-screen .request-form.wide-form {
  max-width: none;
}

/* The listing preview on edit-listing.html: the shop card and the
   listing's own page, in a box over the page */
.preview-dialog {
  width: min(60rem, calc(100% - 2rem));
  max-height: calc(100% - 2rem);
  padding: 1.5rem;
  border: 1px solid var(--color-border);
  border-radius: 24px;
  background: color-mix(in srgb, var(--color-surface) 86%, var(--color-background));
  color: var(--color-text);
}

.preview-dialog::backdrop {
  background: rgba(15, 23, 42, 0.6);
}

.preview-dialog[open] {
  display: grid;
  gap: 1rem;
}

.preview-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.preview-dialog h2,
.preview-dialog h3,
.preview-dialog .form-hint {
  margin: 0;
}

.preview-dialog h3 {
  padding-top: 1rem;
  border-top: 1px solid var(--color-border);
  font-size: 1.1rem;
}

/* Small line under a stat tile's label, e.g. "9 files · +120" (admin-messages.html) */
.stat-note {
  color: var(--color-text-muted);
  font-size: 0.8rem;
}

.account-section h3 {
  margin: 0.5rem 0 0;
  font-size: 1.1rem;
}

/* The main things to do on a page, e.g. "Add a new listing" */
.action-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

/* A label, box and hint that show or hide together inside a form */
.stacked-field {
  display: grid;
  gap: 0.5rem;
}

/* The category on a listing's page, linking to the shop filtered by it */
.listing-category {
  display: block;
  margin-top: 0.25rem;
  color: var(--color-text-muted);
  font-size: 0.9rem;
}

/* An artist taking commissions, in the shop's commissions view */
.commission-card {
  gap: 0.75rem;
  padding: 1.25rem;
}

.commission-card-artist {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  color: var(--color-text);
  text-align: center;
  text-decoration: none;
}

.commission-card-artist h2 {
  margin: 0;
  font-size: 1.15rem;
}

.commission-card-artist:hover h2 {
  color: var(--color-primary);
}

.commission-card .artist-tagline {
  margin: 0;
  text-align: center;
}

.commission-card .kind-prices li {
  padding: 0.4rem 0.75rem;
  font-size: 0.9rem;
}

.commission-card .skill-tags li {
  font-size: 0.8rem;
}

.commission-card .form-hint {
  margin: 0;
}

.commission-card .nav-button {
  margin-top: auto;
  text-align: center;
}

/* A kind of work that searches for itself when clicked */
.kind-search {
  padding: 0;
  border: 0;
  background: none;
  color: var(--color-text);
  font: inherit;
  text-align: left;
  text-decoration: underline;
  text-decoration-color: var(--color-border);
  text-underline-offset: 0.2em;
  cursor: pointer;
}

.kind-search:hover {
  color: var(--color-primary);
}

.shop-views {
  margin-bottom: 1rem;
}

/* Blocked people in Account settings, each with Unblock */
.blocked-list {
  display: grid;
  gap: 0.5rem;
  margin: 0.75rem 0 0;
  padding: 0;
  list-style: none;
}

.blocked-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

/* The form for reporting a conversation, under its buttons (messages.js) */
.report-form {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--color-border);
}

/* "Price and how to buy" on edit-listing.html: one box for everything about buying */
.how-to-buy {
  display: grid;
  gap: 0.5rem;
  margin: 0.75rem 0 0;
  padding: 0.5rem 1.25rem 1.25rem;
  border: 1px solid var(--color-border);
  border-radius: 16px;
}

.how-to-buy legend {
  padding: 0 0.4rem;
  font-weight: 700;
}

.choice-list {
  display: grid;
  gap: 0.75rem;
  margin: 0.25rem 0;
}

/* Each choice: a bold name, then what it means in plain text */
.choice-list .consent span {
  font-weight: 400;
  color: var(--color-text-muted);
}

.choice-list .consent strong {
  display: block;
  color: var(--color-text);
}

.choice-list .stacked-field {
  margin-left: 1.75rem;
}

/* A label for a group of choices, styled like the other labels */
.field-label {
  margin: 0.75rem 0 0;
  color: var(--color-text-muted);
  font-size: 0.9rem;
  font-weight: 600;
}

/* The listing's photos on edit-listing.html, each with its buttons */
.photo-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: 0.75rem;
}

.photo-item {
  display: grid;
  gap: 0.4rem;
  margin: 0;
}

.photo-item img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 16px;
  border: 1px solid var(--color-border);
}

.photo-buttons {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
}

/* "In the shop", in place of Make first on the first photo */
.photo-first {
  color: var(--color-text-muted);
  font-size: 0.85rem;
  font-weight: 600;
}

/* Buttons that delete things */
.button-link.button-quiet.button-danger {
  color: var(--color-error);
}

.button-link.button-quiet.button-danger:hover {
  border-color: var(--color-error);
  background: color-mix(in srgb, var(--color-error) 8%, var(--color-surface));
}

/* A highlighted message box, e.g. "Your account is waiting for approval" */
.notice {
  padding: 1rem 1.25rem;
  border-radius: 16px;
  border: 1px solid var(--color-warning-bright);
  background: color-mix(in srgb, var(--color-warning-bright) 12%, var(--color-surface));
  color: var(--color-text);
  line-height: 1.6;
}

/* Text for screen readers only, e.g. a heading for a column of buttons */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Small buttons inside a table (admin-messages.html) */
.table-button {
  padding: 0.4rem 0.9rem;
  border-radius: 9999px;
  border: 1px solid var(--color-primary);
  background: var(--color-primary);
  color: var(--color-on-primary);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
}

/* A small menu inside a table, e.g. a user's role (admin-users.html) */
.table-select {
  padding: 0.35rem 0.6rem;
  border-radius: 9999px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  font-size: 0.85rem;
}

/* A small number box inside a table, e.g. a listing limit (admin-users.html) */
.table-input {
  width: 4.5rem;
  padding: 0.35rem 0.6rem;
  border-radius: 9999px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  font-size: 0.85rem;
}

.table-input::placeholder {
  color: var(--color-text-muted);
}

/* No up and down arrows in number boxes; people type the number */
.table-input[type='number'] {
  appearance: textfield;
  -moz-appearance: textfield;
}

.table-input::-webkit-inner-spin-button,
.table-input::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

/* The admin pages' content, laid out as if this wrapper weren't there */
.admin-content {
  display: contents;
}

.table-button.button-quiet {
  border-color: var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
}

.table-button:disabled {
  opacity: 0.6;
  cursor: wait;
}

.status-approved {
  color: var(--color-success);
  font-weight: 600;
}

.status-waiting {
  color: var(--color-warning);
  font-weight: 600;
}

/* Pronouns under an artist's name (artist.html) */
.artist-pronouns {
  margin: 0.35rem 0 0;
  color: var(--color-text-muted);
  font-size: 0.95rem;
}

/* Short tagline under an artist's name on their card (artists.html) */
.artist-tagline {
  margin: 0;
  color: var(--color-text-muted);
  font-size: 0.9rem;
  line-height: 1.5;
}

/* An artist's background image behind their profile page (artist.html), set
   by applyBackground() in artist-theme.js. */
html.has-background body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  background: var(--page-image) center / cover no-repeat;
}

/* Make the card more solid over a background image so text stays readable */
.has-background .hero-card {
  background: color-mix(in srgb, var(--color-surface) 94%, transparent);
}

/* Customize your page (customize.html): choices beside a live preview */
.theme-layout {
  display: grid;
  gap: 2rem;
}

@media (min-width: 900px) {
  .theme-layout {
    grid-template-columns: 1fr 1fr;
    align-items: start;
  }
}

.theme-layout h2 {
  margin: 0.5rem 0 0;
  font-size: 1.25rem;
}

.color-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1rem;
}

.color-field {
  display: grid;
  gap: 0.25rem;
}

.color-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.request-form .color-row button {
  margin-top: 0;
}

.request-form input[type="color"] {
  width: 3.5rem;
  height: 2.75rem;
  padding: 0.2rem;
  cursor: pointer;
}

/* The preview box acts like a tiny page: it has its own background, and the
   theme's colours and font are set on it by applyTheme() in artist-theme.js. */
.theme-preview {
  padding: 1.25rem;
  border-radius: 24px;
  border: 1px solid var(--color-border);
  /* Same as the page background (see :root above) */
  background: radial-gradient(circle at top,
    color-mix(in srgb, var(--color-primary-soft) 30%, var(--color-background)) 0%,
    var(--color-background) 25%);
  color: var(--color-text);
  font-family: var(--font-body);
}

.theme-preview.has-background {
  background: var(--page-image) center / cover no-repeat;
}

.theme-preview .hero-card {
  padding: 1.5rem;
  border-radius: 20px;
}

.theme-preview .profile {
  gap: 1rem;
}

.theme-preview .avatar {
  width: 80px;
  height: 80px;
  font-size: 1.75rem;
}

.theme-preview h1 {
  margin: 0;
  font-size: 1.6rem;
}

.theme-preview .button-link {
  margin-top: 0.5rem;
  cursor: default;
}

/* Messages: conversation cards with speech bubbles (messages.html and the
   admin screen's admin-messages.html) */
.conversation-list {
  display: grid;
  gap: 1.25rem;
}

.conversation-card {
  display: grid;
  gap: 1rem;
  padding: 1.25rem;
  border-radius: 20px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
}

.conversation-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
}

.conversation-head h2 {
  margin: 0;
  font-size: 1.2rem;
}

/* The topic, or "New reply" */
.conversation-tag {
  padding: 0.2rem 0.7rem;
  border-radius: 9999px;
  background: var(--color-primary-soft);
  color: var(--color-primary-dark);
  font-size: 0.85rem;
  font-weight: 600;
}

.conversation-date {
  color: var(--color-text-muted);
  font-size: 0.85rem;
}

.conversation-contact {
  margin: -0.5rem 0 0;
  overflow-wrap: anywhere;
}

/* On the Messages page each conversation is folded up to its summary (the
   title, a "New reply" tag, and the start of the latest message) until it's
   clicked. ▸ turns to ▾ when it's open. */
.conversation-summary {
  position: relative;
  display: grid;
  gap: 0.35rem;
  padding-right: 2rem;
  list-style: none;
  cursor: pointer;
}

.conversation-summary::-webkit-details-marker {
  display: none;
}

.conversation-summary::after {
  content: '▸';
  position: absolute;
  top: 0;
  right: 0.25rem;
  color: var(--color-text-muted);
  font-size: 1.2rem;
  line-height: 1.4;
}

.conversation-card[open] > .conversation-summary::after {
  content: '▾';
}

/* No gap left for the folded-away part */
details.conversation-card:not([open]) {
  gap: 0;
}

.conversation-summary:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 6px;
  border-radius: 8px;
}

.conversation-preview {
  overflow: hidden;
  color: var(--color-text-muted);
  font-size: 0.95rem;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.conversation-card[open] .conversation-preview {
  display: none; /* the whole thread is showing */
}

.conversation-body {
  display: grid;
  gap: 1rem;
}

.conversation-body > .conversation-contact {
  margin: 0;
}

/* Archive and Delete, at the bottom of an open conversation */
.conversation-tidy {
  padding-top: 1rem;
  border-top: 1px solid var(--color-border);
}

.thread {
  display: grid;
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* One message. The reader's own sit on the right, in the highlight colour. */
.bubble {
  justify-self: start;
  max-width: min(36rem, 90%);
  padding: 0.75rem 1rem;
  border-radius: 16px 16px 16px 4px;
  border: 1px solid var(--color-border);
  background: var(--color-background);
}

.bubble.mine {
  justify-self: end;
  border-radius: 16px 16px 4px 16px;
  border-color: transparent;
  background: var(--color-primary-soft);
}

.bubble-meta {
  margin: 0 0 0.3rem;
  color: var(--color-text-muted);
  font-size: 0.8rem;
}

.bubble-body {
  margin: 0;
  color: var(--color-text);
  line-height: 1.5;
  white-space: pre-wrap; /* keep their line breaks */
  overflow-wrap: anywhere;
}

.request-form.reply-form {
  max-width: none;
  margin: 0;
}

/* Offers in a conversation (offers.go): the amount and where it's at */
.bubble.offer {
  border: 2px solid var(--color-primary);
}

.offer-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0 0 0.3rem;
  font-weight: 600;
}

.offer-line strong {
  font-size: 1.1rem;
}

.offer-status {
  padding: 0.1rem 0.6rem;
  border-radius: 9999px;
  background: var(--color-surface);
  color: var(--color-text-muted);
  font-size: 0.8rem;
}

.offer-status.offer-accepted {
  background: var(--color-primary);
  color: var(--color-on-primary);
}

.offer-status.offer-replaced,
.offer-status.offer-declined {
  text-decoration: line-through;
}

.offer-actions {
  display: grid;
  gap: 0.75rem;
}

.offer-more summary {
  cursor: pointer;
  font-weight: 600;
}

.request-form.offer-form {
  max-width: 24rem;
  margin: 0.75rem 0 0;
}

/* Buying (Buy online, Ask to meet in person) and making an offer, on a
   listing's page */
.buy-box,
.offer-box {
  display: grid;
  gap: 0.75rem;
  justify-items: start;
  width: 100%;
  margin-top: 0.5rem;
  padding: 1rem 1.25rem;
  border-radius: 16px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
}

.offer-intro {
  margin: 0;
  color: var(--color-text-muted);
}

.buy-box .form-hint {
  margin: 0;
}

/* The form sits in the middle of the box */
.buy-box .request-form.reply-form,
.offer-box .request-form.offer-form {
  width: 100%;
  margin: 0 auto;
}

/* The number of unread messages, on My pages and on Messages */
.unread-badge {
  display: inline-block;
  min-width: 1.4em;
  margin-left: 0.4em;
  padding: 0 0.4em;
  border-radius: 9999px;
  background: var(--color-error);
  color: var(--color-background);
  font-size: 0.8em;
  font-weight: 700;
  line-height: 1.4em;
  text-align: center;
}

/* Traffic page of the admin screen (admin-traffic.html) */
.traffic-filters {
  justify-content: flex-start;
}

/* While a new range loads, the old report stays, faded */
.traffic-report {
  display: grid;
  gap: 2rem;
  transition: opacity 180ms ease;
}

/* While a new page of the report or the shop is loading */
.traffic-report.is-loading,
.product-grid.is-loading {
  opacity: 0.5;
}

/* Two sections side by side on wide screens */
.chart-pair {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
  gap: 2rem;
}

/* Keep each heading tight to its own chart or table, even when the one beside it is taller */
.chart-pair .account-section {
  align-content: start;
}

.chart {
  margin: 0;
}

/* Columns grow up from the bottom; the left gutter holds the guide line values */
.chart-plot {
  position: relative;
  height: 180px;
  margin-left: 2.5rem;
}

.chart-gridline {
  position: absolute;
  left: 0;
  right: 0;
  border-top: 1px solid var(--color-border);
}

.chart-tick {
  position: absolute;
  right: calc(100% + 0.5rem);
  transform: translateY(-50%);
  color: var(--color-text-muted);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
}

.chart-columns {
  position: absolute;
  inset: 0;
  display: grid;
  gap: 2px;
}

/* The whole column height is the hover target, not just the bar */
.chart-column {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  border-radius: 4px;
  outline-offset: 2px;
  cursor: default;
}

.chart-bar {
  width: min(24px, 100%);
  border-radius: 4px 4px 0 0;
  background: var(--color-primary);
}

.chart-column:hover .chart-bar,
.chart-column:focus-visible .chart-bar {
  background: var(--color-primary-dark);
}

.chart-axis {
  display: grid;
  gap: 2px;
  margin: 0.4rem 0 0 2.5rem;
  color: var(--color-text-muted);
  font-size: 0.75rem;
  white-space: nowrap;
}

.chart-axis span {
  min-width: 0;
  text-align: center; /* under its column; long labels spill into the empty ones beside it */
}

.chart-tooltip {
  position: fixed;
  z-index: 10;
  display: grid;
  gap: 0.1rem;
  padding: 0.45rem 0.7rem;
  border-radius: 10px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text-muted);
  font-size: 0.8rem;
  pointer-events: none;
  box-shadow: 0 6px 18px rgb(0 0 0 / 0.25);
}

.chart-tooltip strong {
  color: var(--color-text);
  font-size: 0.95rem;
}

.chart-table {
  margin-top: 0.75rem;
}

.chart-table summary {
  color: var(--color-text-muted);
  font-size: 0.85rem;
  cursor: pointer;
}

.chart-table .table-wrap {
  margin-top: 0.5rem;
  max-height: 20rem;
  overflow-y: auto;
}

/* A number in a table with a thin bar showing its share of the biggest */
.bar-cell {
  min-width: 9rem;
}

.cell-value {
  display: block;
  font-variant-numeric: tabular-nums;
}

.cell-bar {
  display: block;
  height: 6px;
  margin-top: 0.3rem;
  border-radius: 0 4px 4px 0;
  background: var(--color-primary);
}

.status-declined {
  color: var(--color-error);
  font-weight: 600;
}

/* The listings an applicant has drafted (admin-applications.html) */
.application-listings {
  display: grid;
  gap: 0.75rem;
}

.application-listings h3 {
  margin: 0;
  font-size: 1rem;
}

.application-listings .product-grid {
  justify-content: start;
}

/* Someone's profile as admins see it, from a "View profile" button
   (admin-users.html and admin-applications.html; admin-common.js) */
.admin-profile {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 1rem 1.25rem;
  padding: 1rem;
  border-radius: 16px;
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  white-space: normal;
}

.admin-profile .avatar {
  width: 96px;
  height: 96px;
  font-size: 2rem;
}

.admin-profile-details {
  flex: 1 1 18rem;
  min-width: 0;
  text-align: left;
}

.admin-profile-details h3 {
  margin: 0;
}

/* Label above each value: Pronouns, Tagline, Bio */
.admin-profile-fields {
  margin: 0.75rem 0 0;
  max-width: 65ch;
}

.admin-profile-fields dt {
  margin-top: 0.75rem;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.admin-profile-fields dt:first-child {
  margin-top: 0;
}

.admin-profile-fields dd {
  margin: 0.2rem 0 0;
  overflow-wrap: anywhere;
  line-height: 1.6;
}

.admin-profile-fields dd p {
  margin: 0 0 0.6rem;
}

.admin-profile-fields dd p:last-child {
  margin-bottom: 0;
}

/* The last step before deleting an account, in Settings and under a row of
   the Users table (makeDeleteForm in account-common.js) */
.delete-form {
  margin-top: 1rem;
}

.user-table .admin-delete-cell {
  white-space: normal;
}

.admin-delete-cell .delete-form {
  margin: 0.5rem 0;
  max-width: 40rem;
}

/* Sloth scene (my-listings.html): a tree grows and a sloth hanging from it
   waves, in the bottom-left corner. Only on screens wide enough to have
   room beside the page (which is up to 1100px wide), so it never covers
   anything. Two colours from the look: the page background and the main
   colour. Each animation starts from its first frame (fill-mode "both"),
   so things stay hidden until their turn (--t). With "Turn off fancy
   graphics" or a device set to reduce motion, there's no animation and it
   shows the finished picture. Clicking it plays it again (my-listings.js). */
.sloth-scene {
  display: none;
  --bg: var(--color-background);
  --fg: var(--color-primary);
  color: var(--fg);
  cursor: pointer;
}

[data-plain-motion] .sloth-scene {
  cursor: auto; /* nothing to play again */
}

/* The sloth is placed against the page, not the window, so it scrolls
   with everything else */
body:has(> .sloth-scene) {
  position: relative;
}

@media (min-width: 1500px) {
  .sloth-scene {
    display: block;
    position: absolute;
    left: 1.5rem;
    /* Its base starts 1rem above the bottom of the window (100vh), then
       scrolls away with the page. It's square, so its height is --size. */
    --size: min(320px, calc((100vw - 1100px) / 2 - 3rem));
    top: calc(100vh - 1rem - var(--size));
    width: var(--size);
    height: auto;
  }
}

.sloth-scene .draw,
.sloth-scene .line {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sloth-scene .draw {
  stroke-dasharray: 1 1.1; /* one dash as long as the path (pathLength="1") */
}

.sloth-scene .fill {
  fill: currentColor;
}

/* Cut-outs in the face, in the page background colour */
.sloth-scene .hole {
  fill: var(--bg);
}

/* Where things turn and grow from */
.sloth-scene .pop {
  transform-box: fill-box;
  transform-origin: center;
}

.sloth-scene .rise {
  transform-box: fill-box;
  transform-origin: 50% 100%;
}

.sloth-scene #sloth {
  transform-box: view-box;
  transform-origin: 272px 200px; /* the gripping hand */
}

.sloth-scene #wave-arm {
  transform-box: view-box;
  transform-origin: 246px 258px; /* the shoulder */
}

.sloth-scene #wave-hand {
  transform-box: view-box;
  transform-origin: 221px 233px; /* the wrist */
}

.sloth-scene .draw {
  animation: sloth-draw var(--d, 0.5s) var(--t, 0s) cubic-bezier(0.3, 0.7, 0.3, 1) both;
}

.sloth-scene .pop {
  animation: sloth-pop 0.45s var(--t, 0s) cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

.sloth-scene .rise {
  animation: sloth-rise 0.5s var(--t, 0s) cubic-bezier(0.3, 0.7, 0.3, 1) both;
}

/* It swings into place, then sways slowly forever */
.sloth-scene #sloth {
  animation: sloth-hang 1.1s 1.9s ease-out both, sloth-sway 5s 3s ease-in-out infinite;
}

/* One wave: raise, wave, lower. The hand lags behind the arm a little. */
.sloth-scene #wave-arm {
  animation: sloth-wave 3.2s 3s ease-in-out both;
}

.sloth-scene #wave-hand {
  animation: sloth-wrist 3.2s 3s ease-in-out both;
}

@keyframes sloth-draw {
  from { stroke-dashoffset: 1.05; }
  to { stroke-dashoffset: 0; }
}

@keyframes sloth-pop {
  from { transform: scale(0); }
  to { transform: scale(1); }
}

@keyframes sloth-rise {
  from { transform: scaleY(0); }
  to { transform: scaleY(1); }
}

@keyframes sloth-hang {
  0% { opacity: 0; transform: rotate(-28deg) translateY(-8px); }
  15% { opacity: 1; }
  45% { transform: rotate(10deg); }
  72% { transform: rotate(-4deg); }
  100% { opacity: 1; transform: rotate(0); }
}

@keyframes sloth-sway {
  0%, 100% { transform: rotate(0); }
  50% { transform: rotate(2.5deg); }
}

/* Each swing eases in and out (timing functions apply per step) */
@keyframes sloth-wave {
  0% { transform: rotate(0); animation-timing-function: ease-in-out; }
  14% { transform: rotate(26deg); animation-timing-function: ease-in-out; }
  29% { transform: rotate(8deg); animation-timing-function: ease-in-out; }
  44% { transform: rotate(28deg); animation-timing-function: ease-in-out; }
  59% { transform: rotate(8deg); animation-timing-function: ease-in-out; }
  74% { transform: rotate(26deg); animation-timing-function: ease-in-out; }
  100% { transform: rotate(0); }
}

@keyframes sloth-wrist {
  0% { transform: rotate(0); animation-timing-function: ease-in-out; }
  7% { transform: rotate(-6deg); animation-timing-function: ease-in-out; }
  21% { transform: rotate(7deg); animation-timing-function: ease-in-out; }
  36% { transform: rotate(-7deg); animation-timing-function: ease-in-out; }
  51% { transform: rotate(7deg); animation-timing-function: ease-in-out; }
  66% { transform: rotate(-7deg); animation-timing-function: ease-in-out; }
  85% { transform: rotate(5deg); animation-timing-function: ease-in-out; }
  100% { transform: rotate(0); }
}

@media (prefers-reduced-motion: reduce) {
  .sloth-scene,
  .sloth-scene * {
    animation: none !important;
  }

  .sloth-scene {
    cursor: auto;
  }
}
