/* Shockholm2026 — project overrides on top of Pico.css
 *
 * Pico is loaded first (pico.min.css); this file customizes it.
 * The PALETTE lives here as CSS variables. To apply a custom color scheme
 * later (e.g. picked from a reference image), edit ONLY the values in the
 * :root block below — no structural changes needed elsewhere.
 *
 * Pico's own theming variables are documented at:
 * https://picocss.com/docs/css-variables
 */

:root {
  /* --- Project palette — light mode --- */
  --sh-primary: #2b6cb0;
  --sh-primary-hover: #245a96;
  --sh-accent: #d97706;
  --sh-success: #16a34a;
  --sh-danger: #dc2626;
  --sh-bg: #fafafa;
  --sh-surface: #ffffff;
  --sh-text: #1f2937;
  --sh-muted: #6b7280;
  --sh-border: #e5e7eb;

  /* --- Map project palette onto Pico's variables --- */
  --pico-primary: var(--sh-primary);
  --pico-primary-hover: var(--sh-primary-hover);
  --pico-primary-background: var(--sh-primary);
  --pico-primary-hover-background: var(--sh-primary-hover);

  /* Slightly tighter container for a mobile-first single-event site */
  --pico-spacing: 1rem;
}

/* --- Dark mode overrides --- */
[data-theme="dark"] {
  --sh-bg: #0f172a;
  --sh-surface: #1e293b;
  --sh-text: #f1f5f9;
  --sh-muted: #94a3b8;
  --sh-border: #334155;
}

/* Dark mode: component colour overrides for hardcoded light values */
[data-theme="dark"] .flash.error   { background: #450a0a; color: #fca5a5; }
[data-theme="dark"] .flash.success { background: #052e16; color: #86efac; }
[data-theme="dark"] .flash.warning { background: #431407; color: #fdba74; }

[data-theme="dark"] .badge-status.badge-pending  { background: #451a03; color: #fcd34d; }
[data-theme="dark"] .badge-status.badge-approved { background: #052e16; color: #6ee7b7; }
[data-theme="dark"] .badge-status.badge-rejected { background: #450a0a; color: #fca5a5; }

[data-theme="dark"] .stat-card--alert             { border-color: #7f1d1d; background: #1c0606; }
[data-theme="dark"] .stat-card--alert .stat-card__value { color: #fca5a5; }

[data-theme="dark"] .photo-card__thumb { background: #0f172a; }

[data-theme="dark"] .phase-upload  { background: #0c1a2e; border-color: #3b82f6; color: #93c5fd; }
[data-theme="dark"] .phase-voting  { background: #022c22; border-color: #22c55e; color: #86efac; }
[data-theme="dark"] .phase-results { background: #1a0a2e; border-color: #a855f7; color: #d8b4fe; }

[data-theme="dark"] .role-pill.role-admin { color: #fcd34d; }
[data-theme="dark"] .role-pill.role-judge { color: #93c5fd; }
[data-theme="dark"] .role-pill.role-user  { color: #94a3b8; }

[data-theme="dark"] .sort-btn { background: var(--sh-surface); color: var(--sh-muted); border-color: var(--sh-border); }
[data-theme="dark"] .sort-btn:hover { color: var(--sh-text); border-color: #475569; }

/* Cross-browser form field normalization — pins font values after Pico so
   Firefox/Safari UA defaults for url/number/select can't slip through. */
input,
textarea,
select {
  font-size: 1rem;
  font-family: inherit;
  line-height: inherit;
}

/* Theme toggle button — icon visibility driven by data-theme on <html> */
.theme-toggle { background: none; border: none; cursor: pointer; color: var(--sh-muted); padding: 0.15rem 0.3rem; line-height: 1; display: flex; align-items: center; }
.theme-toggle:hover { color: var(--sh-text); }
.theme-toggle:focus { outline: none; box-shadow: none; }
.theme-toggle:focus-visible { outline: 2px solid var(--sh-primary); border-radius: 3px; box-shadow: none; }
.theme-toggle .icon-sun  { display: none; }
.theme-toggle .icon-moon { display: block; }
[data-theme="dark"] .theme-toggle .icon-sun  { display: block; }
[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

/* Language switcher — sits next to the theme toggle, brand side of the nav */
.lang-switch { font-size: 0.8rem; color: var(--sh-muted); display: flex; align-items: center; }
.lang-switch a { color: var(--sh-muted); text-decoration: none; }
.lang-switch a:hover { color: var(--sh-text); }
.lang-switch a.lang-switch__active { color: var(--sh-text); font-weight: bold; pointer-events: none; }

/* Home page CTA — QR left, buttons right; two equal blocks */
.home-cta {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
  align-items: stretch;
  margin-bottom: 1.5rem;
}
.home-cta__qr {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.home-cta__buttons {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 0.75rem;
}
.home-cta__buttons a[role="button"] {
  text-align: center;
}
@media (max-width: 540px) {
  .home-cta { grid-template-columns: 1fr; }
}

/* Page chrome */
body {
  background: var(--sh-bg);
  color: var(--sh-text);
}

header.site-header {
  border-bottom: 1px solid var(--sh-border);
  margin-bottom: 1.5rem;
  position: relative; /* anchor for mobile nav dropdown */
}
header.site-header nav {
  align-items: center;
  padding-top: 10px;
  padding-bottom: 10px;
}
header.site-header .brand {
  font-weight: 700;
  font-size: 1.25rem;
  text-decoration: none;
  color: var(--sh-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 55vw;
}
header.site-header nav li a,
header.site-header nav li span {
  white-space: nowrap;
}

/* Hamburger button — hidden on desktop */
.nav-hamburger {
  display: none;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--sh-muted);
  padding: 0.15rem 0.3rem;
  line-height: 1;
  align-items: center;
  flex-shrink: 0;
}
.nav-hamburger:hover { color: var(--sh-text); }
.nav-hamburger:focus { outline: none; box-shadow: none; }
.nav-hamburger:focus-visible { outline: 2px solid var(--sh-primary); border-radius: 3px; }
.nav-hamburger .icon-close { display: none; }
.nav-hamburger .icon-menu  { display: block; }
.nav-hamburger[aria-expanded="true"] .icon-close { display: block; }
.nav-hamburger[aria-expanded="true"] .icon-menu  { display: none; }

@media (max-width: 640px) {
  .nav-hamburger { display: flex; }

  /* Hide the right nav links; they slide in from a dropdown */
  ul.nav-links {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 200;
    background: var(--sh-surface);
    border-bottom: 2px solid var(--sh-border);
    flex-direction: column;
    padding: 0.5rem 1.25rem 0.75rem;
    margin: 0;
    gap: 0;
    box-shadow: 0 4px 12px rgba(0,0,0,0.08);
  }
  ul.nav-links.nav-open { display: flex; }
  ul.nav-links li {
    border-bottom: 1px solid var(--sh-border);
    padding: 0.55rem 0;
  }
  ul.nav-links li:last-child { border-bottom: none; }
  ul.nav-links li a,
  ul.nav-links li span { font-size: 1rem; }

  header.site-header .brand {
    font-size: 1rem;
    max-width: 48vw;
  }
}

/* Photo gallery grid — 2 columns mobile → 3 tablet → 4 desktop */
.photo-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.75rem;
}
@media (min-width: 600px) {
  .photo-grid { grid-template-columns: repeat(3, 1fr); gap: 1rem; }
}
@media (min-width: 900px) {
  .photo-grid { grid-template-columns: repeat(4, 1fr); }
}

.photo-card {
  background: var(--sh-surface);
  border: 1px solid var(--sh-border);
  border-radius: var(--pico-border-radius, 0.375rem);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.photo-card__thumb {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  overflow: hidden;
  background: var(--sh-surface);
}
.photo-card__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: opacity 0.15s;
}
.photo-card__thumb:hover img { opacity: 0.88; }
.photo-card .photo-body {
  padding: 0.5rem 0.6rem;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.875rem;
}

/* Lightbox overlay */
#lb-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.92);
  z-index: 9999;
  align-items: center;
  justify-content: center;
}
#lb-overlay.lb-open { display: flex; }
#lb-img {
  max-width: min(92vw, calc(100vw - 8rem)); /* leave room for nav arrows */
  max-height: 92vh;
  object-fit: contain;
  border-radius: 2px;
  box-shadow: 0 4px 32px rgba(0,0,0,0.5);
  display: block;
  pointer-events: none; /* clicks on image fall through to overlay → close */
}
#lb-close,
#lb-prev,
#lb-next {
  position: fixed;
  background: none;
  border: none;
  color: rgba(255, 255, 255, 0.75);
  cursor: pointer;
  line-height: 1;
  padding: 0.5rem;
  z-index: 10000;
  transition: color 0.15s;
}
#lb-close:hover, #lb-prev:hover, #lb-next:hover { color: #fff; }
#lb-close {
  top: 0.75rem;
  right: 1rem;
  font-size: 2.25rem;
}
#lb-prev,
#lb-next {
  top: 50%;
  transform: translateY(-50%);
  font-size: 3.5rem;
  padding: 0.5rem 0.75rem;
}
#lb-prev { left: 0; }
#lb-next { right: 0; }
#lb-counter {
  position: fixed;
  bottom: 1rem;
  left: 50%;
  transform: translateX(-50%);
  color: rgba(255, 255, 255, 0.55);
  font-size: 0.875rem;
  pointer-events: none;
}
/* Phones: the desktop rule reserves 8rem for the arrows, which costs a 390px screen a third
   of its width. Here the image fills the viewport edge to edge, and the controls float over it
   on translucent discs so they stay visible on bright photos. dvh tracks the browser's
   collapsing toolbar; the vh line is the fallback for browsers without dvh. */
@media (max-width: 640px) {
  #lb-img {
    max-width: 100vw;
    max-height: 100vh;
    max-height: 100dvh;
    border-radius: 0;
    box-shadow: none;
  }
  #lb-close,
  #lb-prev,
  #lb-next {
    background: rgba(0, 0, 0, 0.45);
    color: rgba(255, 255, 255, 0.9);
    border-radius: 999px;
  }
  #lb-close { top: 0.5rem; right: 0.5rem; padding: 0.1rem 0.6rem 0.3rem; font-size: 2rem; }
  #lb-prev,
  #lb-next  { font-size: 2.5rem; padding: 0.1rem 0.75rem 0.4rem; }
  #lb-prev  { left: 0.25rem; }
  #lb-next  { right: 0.25rem; }
  #lb-counter {
    bottom: 0.5rem;
    padding: 0.15rem 0.6rem;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.45);
    color: rgba(255, 255, 255, 0.85);
  }
  #lb-counter:empty { display: none; }
}

/* Badge for pinned/top photos in the post-cutoff gallery */
.badge-top {
  display: inline-block;
  font-size: 0.75rem;
  font-weight: 600;
  color: #fff;
  background: var(--sh-accent);
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
}
.badge-top--pending { background: var(--sh-success); }
.badge-top--reported { background: var(--sh-danger); }

/* Votes-remaining indicator */
.votes-remaining {
  color: var(--sh-muted);
  font-size: 0.9rem;
}

/* Small helper for upload-slots text, flash messages, etc. */
.muted { color: var(--sh-muted); }
.flash {
  padding: 0.75rem 1rem;
  border-radius: var(--pico-border-radius, 0.375rem);
  margin-bottom: 1rem;
}
.flash.error { background: #fef2f2; color: #991b1b; }
.flash.success { background: #f0fdf4; color: #166534; }
.flash.warning { background: #fffbeb; color: #92400e; }

/* Photo status badges on dashboard activity feed */
.badge-status {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.badge-status.badge-pending  { background: #fef3c7; color: #92400e; }
.badge-status.badge-approved { background: #d1fae5; color: #065f46; }
.badge-status.badge-rejected { background: #fee2e2; color: #991b1b; }

/* Report toggle — subtle, keeps photo cards uncluttered */
.report-details {
  margin-top: 0.25rem;
  font-size: 0.8rem;
  color: var(--sh-muted);
}
.report-details summary {
  cursor: pointer;
  list-style: none;
  color: var(--sh-muted);
}
.report-details summary:hover { color: var(--sh-text); }
.report-details textarea { width: 100%; }

/* Phase transition banners */
.phase-banner {
  margin-bottom: 1.25rem;
  padding: 0.75rem 1rem;
  border-radius: var(--pico-border-radius, 0.375rem);
  border-left: 4px solid;
}
.phase-upload  { background: #eff6ff; border-color: #3b82f6; color: #1e3a5f; }
.phase-voting  { background: #f0fdf4; border-color: #22c55e; color: #14532d; }
.phase-results { background: #faf5ff; border-color: #a855f7; color: #4a1d96; }

/* Role indicator — shown in the nav as plain coloured text (no pill background) */
.nav-username { display: none; }
.role-pill {
  display: inline-block;
  font-size: 0.875rem;
  font-weight: 600;
}
.role-pill.role-admin { color: #92400e; }
.role-pill.role-judge { color: #1d4ed8; }
.role-pill.role-user  { color: #6b7280; }

/* Admin-authored free text (rules_body, privacy_body) — preserve the line
   breaks the organizer typed, matching the "line breaks are preserved"
   placeholder hint. */
.rules-body,
.privacy-body {
  white-space: pre-line;
}

/* Admin status tab — stats grid */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
  margin-bottom: 0.5rem;
}
@media (max-width: 640px) {
  .stats-grid { grid-template-columns: repeat(2, 1fr); }
}
.stat-card {
  background: var(--sh-surface);
  border: 1px solid var(--sh-border);
  border-radius: var(--pico-border-radius, 0.375rem);
  padding: 1rem 1.1rem 0.85rem;
}
a.stat-card--link {
  display: block;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  transition: border-color 0.15s;
}
a.stat-card--link:hover {
  border-color: var(--sh-primary);
  text-decoration: none;
}
.stat-card--alert {
  border-color: #fca5a5;
  background: #fff5f5;
}
.stat-card__value {
  font-size: 2rem;
  font-weight: 700;
  line-height: 1;
  color: var(--sh-text);
  margin-bottom: 0.2rem;
}
.stat-card--alert .stat-card__value { color: #b91c1c; }
.stat-card__label {
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--sh-muted);
}
.stat-card__detail {
  font-size: 0.75rem;
  color: var(--sh-muted);
  margin-top: 0.4rem;
}

/* Admin tables: Pico defaults type=submit buttons to width:100%, which
   blows up small action buttons inside table cells. */
.admin-tab-panel td button {
  width: auto;
}

/* Admin sub-header tab bar */
.admin-subnav {
  background: var(--sh-surface);
  border-bottom: 1px solid var(--sh-border);
  margin-bottom: 1.5rem;
  /* No overflow-x:auto here on purpose: any non-visible value on one axis
     forces the other to clip too (a well-known CSS gotcha), which was
     cutting off the Photos dropdown panel. Wrap to a second row instead
     of scrolling — nothing gets hidden or clipped at any width. */
}
.admin-subnav__inner {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  padding: 0;
}
.admin-tab-link {
  display: inline-block;
  padding: 0.65rem 1.1rem;
  font-size: 0.875rem;
  color: var(--sh-muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color 0.15s, border-color 0.15s;
}
.admin-tab-link:hover { color: var(--sh-text); text-decoration: none; }
.admin-tab-link.active {
  color: var(--sh-primary);
  border-bottom-color: var(--sh-primary);
  font-weight: 500;
}

/* Admin subnav: role label (Admin / Judge) shown before the tab links */
.admin-subnav-role {
  display: inline-flex;
  align-items: center;
  padding: 0.65rem 1rem 0.65rem 0;
  font-size: 0.875rem;
  font-weight: 700;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
  border-right: 1px solid var(--sh-border);
  margin-right: 0.25rem;
  letter-spacing: 0.02em;
  color: var(--sh-accent);
}
.admin-subnav-role.role-judge { color: #1d4ed8; }
[data-theme="dark"] .admin-subnav-role.role-judge { color: #93c5fd; }
@media (max-width: 640px) {
  .admin-subnav-role { display: none; }
}

/* Sortable table column header links */
.sort-th {
  color: inherit;
  text-decoration: none;
  white-space: nowrap;
  font-weight: 600;
}
.sort-th:hover { color: var(--sh-primary); text-decoration: none; }
.sort-th--active { color: var(--sh-primary); }

/* Admin subnav mobile toggle — hidden on desktop */
.admin-tab-toggle {
  display: none;
  width: 100%;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.7rem 1.1rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--sh-text);
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  text-align: left;
}
.admin-tab-toggle:focus { outline: none; box-shadow: none; }
.admin-tab-toggle:focus-visible { outline: 2px solid var(--sh-primary); border-radius: 3px; }
.admin-tab-chevron { flex-shrink: 0; transition: transform 0.2s ease; }
.admin-subnav.subnav-open .admin-tab-chevron { transform: rotate(180deg); }

@media (max-width: 640px) {
  .admin-subnav {
    overflow-x: visible; /* dropdown replaces horizontal scroll */
    position: relative;
  }
  .admin-tab-toggle { display: flex; }

  .admin-subnav__inner {
    flex-direction: column;
    white-space: normal;
  }

  /* Links hidden by default on mobile; shown when dropdown is open */
  .admin-subnav__inner .admin-tab-link {
    display: none;
    border-bottom: 1px solid var(--sh-border);
    border-bottom-width: 1px;  /* override the 2px underline from desktop */
    padding: 0.7rem 1.4rem;
    font-size: 0.9rem;
  }
  .admin-subnav__inner > .admin-tab-link:first-of-type {
    border-top: 1px solid var(--sh-border);
  }
  /* Active tab: left accent bar instead of bottom border */
  .admin-subnav__inner .admin-tab-link.active {
    border-bottom-color: var(--sh-border);
    border-left: 3px solid var(--sh-primary);
    padding-left: calc(1.4rem - 3px);
  }
  .admin-subnav.subnav-open .admin-subnav__inner .admin-tab-link { display: block; }
}

/* Admin tab panels — only the active one is visible */
.admin-tab-panel          { display: none; }
.admin-tab-panel.active   { display: block; }

/* Upload slots progress bar (upload page + dashboard) */
.upload-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  align-items: center;
  margin-bottom: 0.75rem;
  font-size: 0.875rem;
}
.upload-slots-bar {
  flex-basis: 100%;
  height: 4px;
  background: var(--sh-border);
  border-radius: 2px;
  overflow: hidden;
}
.upload-slots-bar__fill {
  width: 0; /* actual width set by a --p<n> step modifier (see SEC-001 section) */
  height: 100%;
  background: var(--sh-primary);
  border-radius: 2px;
  transition: width 0.3s;
}

/* Dashboard action buttons — wrap cleanly on mobile */
.dash-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.dash-actions a { margin: 0; }

/* Gallery rank badges */
.badge-rank-1 { background: #f59e0b; color: #fff; }
.badge-rank-2 { background: #9ca3af; color: #fff; }
.badge-rank-3 { background: #d97706; color: #fff; }

/* Gallery sort bar */
.sort-bar {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.75rem;
  flex-wrap: wrap;
}
.sort-label {
  font-size: 0.8rem;
  color: var(--sh-muted);
  margin-right: 0.1rem;
}
.sort-btn {
  display: inline-block;
  font-size: 0.8rem;
  padding: 0.2rem 0.65rem;
  border-radius: 999px;
  border: 1px solid var(--sh-border);
  background: var(--sh-surface);
  color: var(--sh-muted);
  text-decoration: none;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.sort-btn:hover { color: var(--sh-text); border-color: #d1d5db; text-decoration: none; }
.sort-btn--active {
  background: var(--sh-primary);
  border-color: var(--sh-primary);
  color: #fff;
  font-weight: 500;
}
.sort-btn--active:hover { background: var(--sh-primary-hover); border-color: var(--sh-primary-hover); color: #fff; }

/* Admin result box — invite / test link shown at top of Users tab */
.admin-result-box {
  margin-bottom: 1.5rem;
  padding: 1rem 1.25rem;
  border: 2px solid var(--pico-primary);
  border-radius: var(--pico-border-radius);
  background: var(--pico-card-background-color);
}

/* Tooltip — admin test-account links */
.tooltip-wrap {
  position: relative;
  display: inline-block;
}
.tooltip-wrap .tooltip {
  visibility: hidden;
  opacity: 0;
  width: 270px;
  background: #1e293b;
  color: #f8fafc;
  font-size: 0.8rem;
  line-height: 1.45;
  text-align: center;
  border-radius: 6px;
  padding: 0.5rem 0.75rem;
  position: absolute;
  z-index: 100;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  transition: opacity 0.15s ease, transform 0.15s ease;
  pointer-events: none;
  white-space: normal;
}
.tooltip-wrap .tooltip::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -5px;
  border: 5px solid transparent;
  border-top-color: #1e293b;
}
.tooltip-wrap:hover .tooltip,
.tooltip-wrap:focus-within .tooltip {
  visibility: visible;
  opacity: 1;
  transform: translateX(-50%) translateY(-3px);
}

/* Per-photo share bar */
.like-bar {
  display: flex;
  align-items: center;
  margin-top: 0.5rem;
}
.like-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  background: transparent;
  border: none;
  padding: 0.25rem 0.5rem 0.25rem 0;
  cursor: pointer;
  color: var(--sh-muted);
  font-size: 0.85rem;
  transition: color 0.15s;
}
.like-btn:hover       { color: #e11d48; }
.like-btn--active     { color: #e11d48; }

.share-bar {
  display: flex;
  gap: 0.4rem;
  margin-top: 0.5rem;
  align-items: center;
}
.share-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  border: 1px solid var(--pico-muted-border-color);
  background: transparent;
  color: var(--sh-muted);
  cursor: pointer;
  padding: 0;
  transition: background 0.15s, color 0.15s;
  text-decoration: none;
  font-size: 0.75rem;
}
.share-btn:hover          { background: var(--pico-muted-border-color); color: var(--sh-text); }
.share-btn--wa:hover      { background: #dcfce7; color: #15803d; border-color: #86efac; }
.share-btn--fb:hover      { background: #dbeafe; color: #1d4ed8; border-color: #93c5fd; }
.share-btn--copy:hover    { background: var(--sh-surface); color: var(--sh-text); }

/* Footer social icon links — no underline, icon sized to match surrounding text */
.footer-social-link {
  display: inline-flex;
  align-items: center;
  vertical-align: middle;
  text-decoration: none;
  line-height: 1;
  color: inherit;
}
.footer-social-link:hover { color: var(--sh-text); }

/* Voting-open modal: Pico v2 sets dialog { height: inherit } which on a long
   page makes the dialog as tall as the document, centering the article far
   below the visible viewport. Pin it to the actual viewport height. */
#voting-open-modal {
  height: 100dvh;
  max-height: 100dvh;
}
@media (max-width: 640px) {
  #voting-open-modal > article {
    max-width: calc(100vw - 2rem);
    padding: 1.25rem 1rem;
  }
}

/* Cookie notice — informational only, no accept/reject needed (see /tos#cookies) */
.cookie-notice {
  position: fixed;
  left: 1rem;
  right: 1rem;
  bottom: 1rem;
  z-index: 500;
  max-width: 640px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem;
  padding: 0.85rem 1.1rem;
  background: var(--sh-surface);
  border: 1px solid var(--sh-border);
  border-radius: var(--pico-border-radius, 0.375rem);
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
}
.cookie-notice p {
  margin: 0;
  flex: 1 1 auto;
  font-size: 0.85rem;
  color: var(--sh-muted);
  min-width: 220px;
}
.cookie-notice button {
  flex: 0 0 auto;
  width: auto;
  margin: 0;
  white-space: nowrap;
}

/* Occasional idle "shudder" — used on the home page QR code */
@keyframes shudder {
  0%   { transform: translate(0, 0) rotate(0deg); }
  20%  { transform: translate(-2px, 2px) rotate(-1deg); }
  40%  { transform: translate(-2px, -1px) rotate(1deg); }
  60%  { transform: translate(2px, 1px) rotate(0deg); }
  80%  { transform: translate(1px, -2px) rotate(-1deg); }
  100% { transform: translate(0, 0) rotate(0deg); }
}

.js-shudder {
  display: inline-block;
  transform-origin: center;
}

.js-shudder.is-shuddering {
  animation: shudder 0.3s ease;
}

/* ---------------------------------------------------------------------------
 * SEC-001: classes replacing inline style="" attributes across the templates.
 * Each rule reproduces the exact declaration it replaced — no visual change,
 * the point is only to let `style-src` drop 'unsafe-inline' (project plan §10).
 * Small single-purpose helpers are prefixed `u-`; the rest are named by intent.
 * ------------------------------------------------------------------------- */

/* spacing / layout helpers */
.u-m-0        { margin: 0; }
.u-mt-0       { margin-top: 0; }
.u-mt-1       { margin-top: 0.25rem; }
.u-mt-2       { margin-top: 0.5rem; }
.u-mt-3       { margin-top: 0.75rem; }
.u-mt-4       { margin-top: 1rem; }
.u-mt-6       { margin-top: 1.5rem; }
.u-mt-8       { margin-top: 2rem; }
.u-mt-auto    { margin-top: auto; }
.u-ml-1       { margin-left: 0.25rem; }
.u-ml-2       { margin-left: 0.5rem; }
.u-mb-1       { margin-bottom: 0.25rem; }
.u-mb-r4      { margin-bottom: 0.4rem; }
.u-mb-2       { margin-bottom: 0.5rem; }
.u-mb-4       { margin-bottom: 1rem; }
.u-nowrap     { white-space: nowrap; }
.u-flex-wrap  { flex-wrap: wrap; }
.u-w-full     { width: 100%; }
.u-w-9rem     { width: 9rem; }
.u-maxw-200   { max-width: 200px; }
.u-maxw-480   { max-width: 480px; }
.u-flex-1     { flex: 1; }
.u-text-center{ text-align: center; }
.u-dim        { opacity: 0.5; }
.u-hidden     { display: none; }
.u-inline     { display: inline; }

/* font-size helpers (values are ad-hoc in the source; kept 1:1) */
.text-base    { font-size: 1rem; }
.text-sm      { font-size: 0.85rem; }
.text-xxs     { font-size: 0.8rem; }
.text-xs      { font-size: 0.85em; }
.text-note    { font-size: 0.875em; }

/* recurring component patterns */
.form-inline        { display: inline; margin: 0; }
.flex-row-wrap      { display: flex; gap: 1rem; flex-wrap: wrap; }
/* Admin Danger zone: button + plain-language description per row. Fixed button column so
   the descriptions line up; flex-wrap stacks them on narrow screens without a media query. */
.danger-actions     { display: flex; flex-direction: column; gap: 1.25rem; }
.danger-action      { display: flex; gap: 0.5rem 1rem; flex-wrap: wrap; align-items: flex-start; }
.danger-action form { flex: 0 0 16rem; max-width: 100%; margin: 0; }
.danger-action button,
.danger-action input  { width: 100%; margin: 0; }
.danger-action input  { margin-bottom: 0.5rem; }
.danger-action p    { flex: 1 1 18rem; margin: 0; }
.flex-row-center    { display: flex; align-items: center; gap: 1rem; }
.flex-wrap-center-sm{ display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }
.flex-center-sm     { display: flex; justify-content: center; gap: 0.75rem; }
.hr-section         { margin: 1.5rem 0 1rem; }
.btn-compact      { font-size: 0.85rem; padding: 0.25rem 0.75rem; }
.btn-compact-sm   { font-size: 0.8rem; padding: 0.25rem 0.75rem; }
.btn-compact-xs   { font-size: 0.8rem; padding: 0.2rem 0.6rem; }
.btn-icon-lg      { font-size: 1.5rem; padding: 0.25rem 0.75rem; line-height: 1; }
.thumb-xs         { width: 60px; height: 60px; object-fit: cover; border-radius: 4px; }
.thumb-sm         { width: 72px; height: 72px; object-fit: cover; border-radius: 6px; }
.badge-mini       { font-size: 0.65rem; vertical-align: middle; }
.mono-copy        { font-family: monospace; font-size: 0.85em; cursor: pointer; }
.img-fluid        { max-width: 100%; height: auto; border-radius: var(--pico-border-radius, 0.375rem); }
.judge-actions    { display: flex; gap: 0.4rem; margin-top: auto; }
.preview-grid     { display: none; flex-wrap: wrap; gap: 0.5rem; margin: 0.5rem 0; }
.qr-img           { width: 160px; height: 160px; display: block; }
.bordered         { border: 1px solid var(--sh-border); border-radius: 4px; }
.share-btn--insta { display: none; } /* revealed by ui.js only when navigator.share exists */

/* Home-page "demo mode / not live yet" banner — a diagonal sash across the
 * upper-right of the page. Admin-toggleable via the `demo_mode` setting.
 * pointer-events:none so it never blocks the register/login buttons under it. */
.demo-banner {
  position: fixed;
  top: 26vh;
  left: -15%;
  right: -15%;
  z-index: 2000;
  transform: rotate(-15deg);
  transform-origin: center;
  background: var(--sh-danger);
  color: #fff;
  font-weight: 700;
  font-size: 1rem;
  line-height: 1.3;
  text-align: center;
  padding: 0.7rem 1rem;
  box-shadow: 0 3px 18px rgba(0, 0, 0, 0.35);
  pointer-events: none;
}
/* On a phone a long sentence on a 15° ribbon always clips — fall back to a
 * plain full-width red bar in the page flow. Still unmissable. */
@media (max-width: 640px) {
  .demo-banner {
    position: static;
    transform: none;
    left: auto;
    right: auto;
    margin: 0 0 1rem;
    font-size: 0.85rem;
    padding: 0.6rem 0.9rem;
    border-radius: 4px;
    pointer-events: auto;
  }
}

/* Kiosk-link action row (admin slideshow settings) — keep the <a> button and
 * the <button>s inside their one-field <form>s the same size, side by side. */
.slideshow-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  margin-top: 0.75rem;
}
.slideshow-actions form { margin: 0; }
.slideshow-actions a[role="button"],
.slideshow-actions button {
  width: auto;
  margin: 0;
}

/* upload-slots bar fill — was an inline width:% (the only dynamic inline style).
 * Rounded to 5% steps; the base width:0 guards against a non-matching class. */
.upload-slots-bar__fill--p0   { width: 0; }
.upload-slots-bar__fill--p5   { width: 5%; }
.upload-slots-bar__fill--p10  { width: 10%; }
.upload-slots-bar__fill--p15  { width: 15%; }
.upload-slots-bar__fill--p20  { width: 20%; }
.upload-slots-bar__fill--p25  { width: 25%; }
.upload-slots-bar__fill--p30  { width: 30%; }
.upload-slots-bar__fill--p35  { width: 35%; }
.upload-slots-bar__fill--p40  { width: 40%; }
.upload-slots-bar__fill--p45  { width: 45%; }
.upload-slots-bar__fill--p50  { width: 50%; }
.upload-slots-bar__fill--p55  { width: 55%; }
.upload-slots-bar__fill--p60  { width: 60%; }
.upload-slots-bar__fill--p65  { width: 65%; }
.upload-slots-bar__fill--p70  { width: 70%; }
.upload-slots-bar__fill--p75  { width: 75%; }
.upload-slots-bar__fill--p80  { width: 80%; }
.upload-slots-bar__fill--p85  { width: 85%; }
.upload-slots-bar__fill--p90  { width: 90%; }
.upload-slots-bar__fill--p95  { width: 95%; }
.upload-slots-bar__fill--p100 { width: 100%; }

/* /qr — bare signup QR for projecting/printing. Forced white ground (not the
   theme bg) so scanners get maximum contrast in dark mode too. */
/* Standalone 503 page shown while a backup restore runs (views/maintenance.ejs). */
.maintenance-page { max-width: 36rem; padding-top: 15vh; text-align: center; }

.qr-page {
  margin: 0;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
}
.qr-page__img {
  width: min(90vw, 90vh);
  height: auto;
  image-rendering: pixelated;
}

/* Visually hidden, still read by screen readers (e.g. a label for an icon-only column). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* .stack-table: a normal table on wide screens; on phones each row becomes a card whose cells
   are labelled from data-label, so a many-column table doesn't push the page sideways (the
   admin passkey table did). The first cell (.stack-table__title) is the card heading. */
@media (max-width: 640px) {
  .stack-table thead { display: none; }
  .stack-table,
  .stack-table tbody,
  .stack-table tr,
  .stack-table td { display: block; width: 100%; }
  .stack-table tr {
    margin-bottom: 0.75rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--sh-border);
    border-radius: var(--pico-border-radius, 0.25rem);
  }
  .stack-table td { padding: 0.2rem 0; border: none; }
  .stack-table td[data-label]::before {
    content: attr(data-label) ": ";
    color: var(--sh-muted);
  }
  .stack-table__title { font-weight: 600; }
  .stack-table td form { margin: 0.4rem 0 0; }
}
