/*
 * Application styles.
 *
 * Everything is prefixed .swcomp- so these pages, which never load the theme,
 * also never collide with it if one is ever embedded.
 */

*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  /* Anchor jumps and scrollIntoView land below the sticky bars, not under
     them. --sticky-offset is measured in app.js; the fallback is the header. */
  scroll-padding-top: calc(var(--sticky-offset, var(--header-height)) + var(--space-4));
}

body.swcomp-body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  line-height: 1.55;
  color: hsl(var(--foreground));
  background: hsl(var(--muted));
  -webkit-font-smoothing: antialiased;
}

a { color: hsl(var(--primary)); }
a:hover { color: hsl(var(--accent-foreground)); }

h1, h2, h3, h4 { margin: 0 0 var(--space-2); font-weight: 600; letter-spacing: -0.01em; line-height: 1.3; }
h1 { font-size: var(--fs-xl); }
h2 { font-size: var(--fs-lg); }
h3 { font-size: var(--fs-base); }
p { margin: 0 0 var(--space-3); }

img { max-width: 100%; height: auto; }

/* Visible only to screen readers, and to keyboard users when focused. */
.swcomp-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;
}

.swcomp-skip-link {
  position: absolute;
  inset-inline-start: -9999px;
  top: 0;
  z-index: 100;
  padding: var(--space-2) var(--space-4);
  background: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
}
.swcomp-skip-link:focus { inset-inline-start: var(--space-4); }

/* The honeypot field must be unreachable for people but present for bots.
   Clipped in place, not pushed off-screen: a -9999px offset on an RTL page
   is scrollable overflow, and phones zoom the whole page out to fit it. */
.swcomp-hp {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

[x-cloak] { display: none !important; }

/* ---------- Layout ---------- */

.swcomp-header {
  background: hsl(var(--background));
  border-bottom: 1px solid hsl(var(--border));
  position: sticky;
  top: 0;
  z-index: 20;
}

.swcomp-header-inner {
  max-width: var(--content-max);
  margin: 0 auto;
  padding: var(--space-3) var(--space-5);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: var(--header-height);
}

.swcomp-brand { display: flex; align-items: center; gap: var(--space-3); text-decoration: none; color: inherit; min-width: 0; }
/* As a link (signed-in users) it keeps its look; the generic a:hover colour does not apply. */
a.swcomp-brand:hover { color: inherit; }
a.swcomp-brand:focus-visible { outline: 2px solid hsl(var(--ring) / .6); outline-offset: 4px; border-radius: var(--radius-sm); }
.swcomp-brand-mark {
  width: 30px; height: 30px;
  border-radius: var(--radius-sm);
  background: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: var(--fs-sm);
  flex-shrink: 0;
}
/* Name above the tagline, never side by side. */
.swcomp-brand-name { display: block; font-size: var(--fs-sm); font-weight: 600; line-height: 1.3; }
.swcomp-brand-sub { display: block; font-size: 11.5px; line-height: 1.3; color: hsl(var(--muted-foreground)); }

.swcomp-header-actions { display: flex; align-items: center; gap: var(--space-3); font-size: var(--fs-sm); }
.swcomp-user-name { color: hsl(var(--muted-foreground)); }

.swcomp-shell { max-width: var(--content-max); margin: 0 auto; display: flex; gap: var(--space-6); padding: var(--space-6) var(--space-5) var(--space-10); align-items: flex-start; }
.swcomp-main { flex: 1; min-width: 0; }
.swcomp-narrow { max-width: var(--form-max); margin: 0 auto; padding: var(--space-8) var(--space-5) var(--space-10); }

/* Vertical stacks of cards (and of page-head / alerts / stats above them).
   Gap, not sibling margin: .swcomp-card + .swcomp-card { margin-top } stairs
   the second card in a multi-column grid, because the adjacent-sibling
   selector cannot tell a column from a row. */
.swcomp-main,
.swcomp-narrow,
.swcomp-stack,
[role="tabpanel"] {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-4);
}
/* page-head still wants --space-5 below it; the parent's gap already
   contributes --space-4, so only the remainder stays as margin. */
.swcomp-main > .swcomp-page-head,
.swcomp-narrow > .swcomp-page-head {
  margin-bottom: calc(var(--space-5) - var(--space-4));
}
.swcomp-main > .swcomp-alert,
.swcomp-narrow > .swcomp-alert,
.swcomp-stack > .swcomp-alert,
[role="tabpanel"] > .swcomp-alert {
  margin-bottom: 0;
}
.swcomp-stack > .swcomp-stats { margin-bottom: 0; }
[role="tabpanel"] > .swcomp-hint { margin-bottom: 0; }

/* ---------- Sidebar ---------- */

.swcomp-sidebar {
  width: var(--sidebar-width);
  flex-shrink: 0;
  background: hsl(var(--background));
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  padding: var(--space-2);
  position: sticky;
  top: calc(var(--sticky-offset, var(--header-height)) + var(--space-4));
}

.swcomp-nav { display: flex; flex-direction: column; gap: 2px; }
.swcomp-nav-item {
  display: flex; align-items: center; gap: var(--space-3);
  padding: 8px var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm); font-weight: 500;
  color: hsl(var(--foreground));
  text-decoration: none;
}
.swcomp-nav-item:hover { background: hsl(var(--secondary)); color: hsl(var(--foreground)); }
.swcomp-nav-item.is-active { background: hsl(var(--accent)); color: hsl(var(--accent-foreground)); font-weight: 600; }
.swcomp-nav-item svg { width: 16px; height: 16px; flex-shrink: 0; }
/* Something in this section waits for the manager (pending recusal requests). */
.swcomp-nav-count {
  margin-inline-start: auto;
  min-width: 20px; height: 20px; padding: 0 6px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px;
  background: hsl(var(--warning)); color: #fff;
  font-size: var(--fs-xs); font-weight: 600; font-variant-numeric: tabular-nums;
}

/* The notification template list uses buttons rather than links, because it
   switches a panel instead of navigating. A bare <button> brings the browser's
   own styling with it, so it has to be reset back to the sidebar's look. */
button.swcomp-nav-item {
  width: 100%;
  border: none;
  background: transparent;
  font-family: inherit;
  font-size: var(--fs-sm);
  text-align: start;
  cursor: pointer;
  justify-content: space-between;
  line-height: 1.4;
}
button.swcomp-nav-item:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px hsl(var(--background)), 0 0 0 4px hsl(var(--ring) / .5);
}
button.swcomp-nav-item > span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

.swcomp-sidebar-toggle { display: none; }

/* ---------- Card ---------- */

.swcomp-card {
  background: hsl(var(--card));
  color: hsl(var(--card-foreground));
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.swcomp-card-header { padding: var(--space-5) var(--space-6) 0; }
.swcomp-card-header h1, .swcomp-card-header h2 { margin-bottom: var(--space-1); }
.swcomp-card-desc { font-size: var(--fs-sm); color: hsl(var(--muted-foreground)); margin: 0; }
.swcomp-card-content { padding: var(--space-5) var(--space-6); }
.swcomp-card-footer {
  padding: var(--space-4) var(--space-6);
  border-top: 1px solid hsl(var(--border));
  display: flex; gap: var(--space-3); justify-content: flex-start; align-items: center;
  flex-wrap: wrap;
}

/* ---------- Buttons ---------- */

.swcomp-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  height: 36px; padding: 0 var(--space-4);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: hsl(var(--primary));
  color: hsl(var(--primary-foreground));
  font-family: inherit; font-size: var(--fs-sm); font-weight: 500;
  cursor: pointer; text-decoration: none;
  white-space: nowrap;
  transition: background-color .12s ease, border-color .12s ease, opacity .12s ease;
}
.swcomp-btn:hover { background: hsl(var(--primary) / .9); color: hsl(var(--primary-foreground)); }
.swcomp-btn:focus-visible { outline: none; box-shadow: 0 0 0 2px hsl(var(--background)), 0 0 0 4px hsl(var(--ring) / .5); }
.swcomp-btn[disabled], .swcomp-btn.is-disabled { opacity: .5; cursor: not-allowed; pointer-events: none; }

.swcomp-btn-outline {
  background: hsl(var(--background));
  color: hsl(var(--foreground));
  border-color: hsl(var(--border));
  box-shadow: var(--shadow-sm);
}
.swcomp-btn-outline:hover { background: hsl(var(--secondary)); color: hsl(var(--foreground)); }

.swcomp-btn-ghost { background: transparent; color: hsl(var(--foreground)); }
.swcomp-btn-ghost:hover { background: hsl(var(--secondary)); color: hsl(var(--foreground)); }

/* Debug tools (wp-admin → Debug): the warning colour, so they never pass for normal controls. */
.swcomp-btn-debug { background: hsl(var(--warning-bg)); color: hsl(var(--warning)); border-color: hsl(var(--warning) / .35); }
.swcomp-btn-debug:hover { background: hsl(var(--warning) / .15); color: hsl(var(--warning)); }
.swcomp-is-debug .swcomp-header { border-bottom: 3px solid hsl(var(--warning)); }
.swcomp-debug-tag {
  display: inline-flex; align-items: center; flex-wrap: wrap; gap: 4px var(--space-2);
  padding: 5px var(--space-3); border-radius: var(--radius-sm);
  background: hsl(var(--warning-bg)); color: hsl(var(--warning));
  border: 1px solid hsl(var(--warning) / .35);
  font-size: var(--fs-xs); text-decoration: none; line-height: 1.4;
}
.swcomp-debug-tag:hover { background: hsl(var(--warning) / .15); color: hsl(var(--warning)); }
.swcomp-debug-tag-kind {
  background: hsl(var(--warning)); color: #fff;
  border-radius: 999px; padding: 1px 8px; font-weight: 600;
}

.swcomp-btn-destructive { background: hsl(var(--destructive)); color: hsl(var(--destructive-foreground)); }
.swcomp-btn-destructive:hover { background: hsl(var(--destructive) / .9); color: hsl(var(--destructive-foreground)); }

.swcomp-btn-sm { height: 30px; padding: 0 var(--space-3); font-size: var(--fs-xs); }
.swcomp-btn-lg { height: 42px; padding: 0 var(--space-6); font-size: var(--fs-base); }
.swcomp-btn-block { width: 100%; }

/* Buttons sit at the left, the end of a right-to-left line (flex-end, not a physical side). */
.swcomp-btn-row { display: flex; gap: var(--space-3); flex-wrap: wrap; align-items: center; justify-content: flex-end; }
.swcomp-btn-row.is-split { justify-content: space-between; }

/* ---------- Forms ---------- */

.swcomp-field { margin-bottom: var(--space-4); }
.swcomp-field:last-child { margin-bottom: 0; }

.swcomp-label {
  display: block;
  font-size: var(--fs-sm); font-weight: 500;
  margin-bottom: 6px;
}
.swcomp-required { color: hsl(var(--destructive)); }
.swcomp-hint { font-size: var(--fs-xs); color: hsl(var(--muted-foreground)); margin-top: 5px; }

.swcomp-input,
.swcomp-select,
.swcomp-textarea {
  width: 100%;
  min-height: 36px;
  border: 1px solid hsl(var(--input));
  border-radius: var(--radius-sm);
  padding: 7px var(--space-3);
  font-family: inherit; font-size: var(--fs-sm);
  color: hsl(var(--foreground));
  background: hsl(var(--background));
  box-shadow: var(--shadow-sm);
}
.swcomp-textarea { min-height: 110px; resize: vertical; line-height: 1.6; }

/* One chevron, drawn as SVG. The previous two-gradient triangle rendered as a
   pair of stray marks — gradient triangles depend on exact background sizing
   and fall apart at other font sizes and pixel ratios. */
.swcomp-select {
  appearance: none;
  -webkit-appearance: none;
  padding-inline-start: var(--space-3);
  padding-inline-end: var(--space-8);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%2371717a' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: left var(--space-3) center;
  background-size: 12px 8px;
  cursor: pointer;
}

/* In a left-to-right context the chevron belongs on the other side. */
[dir="ltr"] .swcomp-select { background-position: right var(--space-3) center; }

.swcomp-select:disabled { cursor: not-allowed; opacity: .6; }

.swcomp-input:focus,
.swcomp-select:focus,
.swcomp-textarea:focus {
  outline: none;
  border-color: hsl(var(--ring));
  box-shadow: 0 0 0 3px hsl(var(--ring) / .18);
}
.swcomp-input.has-error,
.swcomp-select.has-error,
.swcomp-textarea.has-error { border-color: hsl(var(--destructive)); }

.swcomp-error { font-size: var(--fs-xs); color: hsl(var(--destructive)); margin-top: 5px; }

.swcomp-checkbox { display: flex; align-items: flex-start; gap: var(--space-3); font-size: var(--fs-sm); cursor: pointer; }
.swcomp-checkbox input[type="checkbox"] { width: 16px; height: 16px; margin: 3px 0 0; accent-color: hsl(var(--primary)); flex-shrink: 0; }

.swcomp-row-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4); }
.swcomp-row-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-4); }

/* Repeater rows, used for writers, genres and prizes */
.swcomp-repeater { border: 1px solid hsl(var(--border)); border-radius: var(--radius-sm); overflow: hidden; }
.swcomp-repeater-row {
  display: flex; gap: var(--space-3); align-items: center;
  padding: 8px var(--space-3);
  border-bottom: 1px solid hsl(var(--border));
  background: hsl(var(--background));
}
.swcomp-repeater-row:last-child { border-bottom: none; }
.swcomp-repeater-num {
  width: 22px; height: 22px; border-radius: 999px;
  background: hsl(var(--accent)); color: hsl(var(--accent-foreground));
  font-size: 10.5px; font-weight: 700;
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.swcomp-repeater-row .swcomp-input { border: none; box-shadow: none; min-height: auto; padding: 3px 2px; background: transparent; }
.swcomp-repeater-row .swcomp-input:focus { box-shadow: none; }
.swcomp-icon-btn {
  width: 26px; height: 26px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; background: transparent; border-radius: var(--radius-sm);
  color: hsl(var(--muted-foreground)); cursor: pointer; font-size: 16px; line-height: 1;
}
.swcomp-icon-btn:hover { background: hsl(var(--secondary)); color: hsl(var(--destructive)); }

/* File input, styled as a drop area */
.swcomp-file {
  border: 1px dashed hsl(var(--border));
  border-radius: var(--radius-sm);
  padding: var(--space-5);
  text-align: center;
  background: hsl(var(--background));
  cursor: pointer;
  display: block;
}
.swcomp-file:hover, .swcomp-file.is-dragging { border-color: hsl(var(--ring)); background: hsl(var(--accent)); }
.swcomp-file input[type="file"] { display: none; }
.swcomp-file-name { font-weight: 600; font-size: var(--fs-sm); }
.swcomp-file-meta { font-size: var(--fs-xs); color: hsl(var(--muted-foreground)); margin-top: 4px; }

.swcomp-progress { height: 6px; background: hsl(var(--secondary)); border-radius: 999px; overflow: hidden; margin-top: var(--space-3); }
.swcomp-progress-bar { height: 100%; background: hsl(var(--primary)); transition: width .2s ease; }

/* ---------- Stepper ---------- */

.swcomp-steps { display: flex; align-items: center; list-style: none; padding: 0; margin-bottom: var(--space-6); }
.swcomp-step { display: flex; align-items: center; gap: var(--space-2); }
.swcomp-step-circle {
  width: 26px; height: 26px; border-radius: 999px;
  border: 1px solid hsl(var(--border));
  display: flex; align-items: center; justify-content: center;
  font-size: 11.5px; font-weight: 600;
  color: hsl(var(--muted-foreground));
  background: hsl(var(--background));
  flex-shrink: 0;
}
.swcomp-step.is-done .swcomp-step-circle { background: hsl(var(--primary)); border-color: hsl(var(--primary)); color: hsl(var(--primary-foreground)); }
/* A finished step shows a tick in place of its number. */
.swcomp-step-check { display: none; width: 14px; height: 14px; }
.swcomp-step.is-done .swcomp-step-number { display: none; }
.swcomp-step.is-done .swcomp-step-check { display: block; }
.swcomp-step.is-active .swcomp-step-circle { border-color: hsl(var(--primary)); color: hsl(var(--primary)); }
.swcomp-step-label { font-size: 12.5px; font-weight: 500; color: hsl(var(--muted-foreground)); }
.swcomp-step.is-active .swcomp-step-label { color: hsl(var(--foreground)); font-weight: 600; }
.swcomp-step-line { flex: 1; height: 1px; background: hsl(var(--border)); margin: 0 10px; min-width: 14px; }

/* Settings: the buttons under the entry confirmation, one block per button. */
.swcomp-finish-button { border: 0; margin: 0; padding: var(--space-4) 0; min-width: 0; }
.swcomp-finish-button:first-child { padding-top: 0; }
.swcomp-finish-button:last-child { padding-bottom: 0; }
.swcomp-finish-button + .swcomp-finish-button { border-top: 1px solid hsl(var(--border)); }
.swcomp-finish-button .swcomp-field { margin-bottom: 0; }

/* The entry form's own heading, set per competition, above the stepper. */
.swcomp-form-heading { text-align: center; font-size: var(--fs-2xl); margin-bottom: var(--space-5); }
/* Each step's heading is an h2 under that h1, but keeps the size it had as an h1. */
.swcomp-card-header h2.swcomp-step-heading { font-size: var(--fs-xl); }

/* ---------- Badges ---------- */

.swcomp-badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: var(--fs-xs); font-weight: 600;
  white-space: nowrap;
}
.swcomp-badge-muted { background: hsl(var(--secondary)); color: hsl(var(--secondary-foreground)); }
.swcomp-badge-success { background: hsl(var(--success-bg)); color: hsl(var(--success)); }
.swcomp-badge-warning { background: hsl(var(--warning-bg)); color: hsl(var(--warning)); }
.swcomp-badge-destructive { background: hsl(var(--destructive) / .12); color: hsl(var(--destructive)); }
.swcomp-badge-outline { background: hsl(var(--background)); border-color: hsl(var(--border)); color: hsl(var(--muted-foreground)); }
.swcomp-badge-primary { background: hsl(var(--accent)); color: hsl(var(--accent-foreground)); }

/* ---------- Tables ---------- */

.swcomp-table-wrap { overflow-x: auto; }
.swcomp-table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.swcomp-table th {
  text-align: start; font-weight: 600;
  color: hsl(var(--muted-foreground));
  background: hsl(var(--muted));
  padding: 10px var(--space-4);
  border-bottom: 1px solid hsl(var(--border));
  white-space: nowrap;
}
.swcomp-table td { padding: 11px var(--space-4); border-bottom: 1px solid hsl(var(--border)); vertical-align: middle; }
.swcomp-table tbody tr:last-child td { border-bottom: none; }
.swcomp-table tbody tr:hover { background: hsl(var(--muted) / .5); }
.swcomp-table .is-numeric { text-align: center; font-variant-numeric: tabular-nums; }
.swcomp-table a { font-weight: 500; text-decoration: none; }
.swcomp-table a:hover { text-decoration: underline; }

.swcomp-sortable { cursor: pointer; user-select: none; }
.swcomp-sortable:hover { color: hsl(var(--foreground)); }

.swcomp-empty { padding: var(--space-10) var(--space-5); text-align: center; color: hsl(var(--muted-foreground)); font-size: var(--fs-sm); }

/* ---------- Filters and toolbars ---------- */

.swcomp-toolbar {
  display: flex; flex-wrap: wrap; gap: var(--space-3);
  align-items: center;
  padding: var(--space-4) var(--space-6);
  border-bottom: 1px solid hsl(var(--border));
}
.swcomp-toolbar .swcomp-input,
.swcomp-toolbar .swcomp-select { width: auto; min-width: 150px; }
.swcomp-toolbar-spacer { flex: 1; }

.swcomp-tabs { display: flex; gap: var(--space-1); padding: var(--space-1); background: hsl(var(--muted)); border-radius: var(--radius-sm); }
.swcomp-tab {
  padding: 6px var(--space-4);
  border: none; background: transparent; cursor: pointer;
  border-radius: calc(var(--radius-sm) - 2px);
  font-family: inherit; font-size: var(--fs-sm); font-weight: 500;
  color: hsl(var(--muted-foreground));
}
.swcomp-tab.is-active { background: hsl(var(--background)); color: hsl(var(--foreground)); box-shadow: var(--shadow-sm); }

/* ---------- Quick bar ---------- */

/* A second, thinner row under the header holding the handful of things a
   manager reaches for constantly: the public entry address, the competition's
   state, and the shortcuts. Sticky, because "where was that link again" is the
   most common interruption in running a competition. */
.swcomp-quickbar {
  background: hsl(var(--background));
  border-bottom: 1px solid hsl(var(--border));
  position: sticky;
  top: var(--sticky-header, var(--header-height));
  z-index: 19;
}

.swcomp-quickbar-inner {
  max-width: var(--content-max);
  margin: 0 auto;
  padding: 8px var(--space-5);
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
  font-size: var(--fs-xs);
}

.swcomp-quick-item { display: inline-flex; align-items: center; gap: 6px; color: hsl(var(--muted-foreground)); }
.swcomp-quick-item strong { color: hsl(var(--foreground)); font-weight: 600; font-variant-numeric: tabular-nums; }
.swcomp-quickbar a { text-decoration: none; }
.swcomp-quickbar a:hover { text-decoration: underline; }

.swcomp-quick-sep { width: 1px; height: 16px; background: hsl(var(--border)); }
.swcomp-quick-spacer { flex: 1; }

.swcomp-quick-external { display: inline-flex; align-items: center; gap: 4px; font-weight: 500; }
.swcomp-quick-external svg { flex-shrink: 0; }

/* Both bars stay pinned while scrolling, so on a phone they have to stay
   short. Wrapped, the quick bar took four rows and the pair covered a third of
   the screen; instead it keeps to one row that scrolls sideways, and the
   signed-in name (which wrapped the header to three lines) gives way. What a
   manager taps for moves to the front of the row, where it is on screen: the
   entry form link and the counts, "awaiting payment" among them. The
   competition name goes, since the header already says whose site this is. */
@media (max-width: 640px) {
  .swcomp-user-name { display: none; }
  .swcomp-quick-name { display: none; }
  .swcomp-quick-form { order: -2; }
  .swcomp-quick-counts { order: -1; }
  .swcomp-quickbar-inner {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    gap: var(--space-3);
    padding-inline: var(--space-4) var(--space-8);
    /* With the scrollbar hidden nothing said the row goes on; it just looked
       cut off. Fading the far edge (the left, in RTL) says it, and the wider
       end padding lets the last item scroll clear of the fade. */
    -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--space-8));
    mask-image: linear-gradient(to right, transparent, #000 var(--space-8));
  }
  .swcomp-quickbar-inner::-webkit-scrollbar { display: none; }
  .swcomp-quick-item { flex-shrink: 0; white-space: nowrap; }

  /* Hiding the signed-in name freed room, but the brand text is still a flex
     child with no shrink target, so "תחרות התסריטאים של ישראל" wraps across
     three lines and the header balloons to ~112px. Same ellipsis idiom as
     .swcomp-progress-name below. */
  .swcomp-brand > span:last-child { min-width: 0; }
  /* Both are inline <span>s — overflow and text-overflow are no-ops on inline
     elements, so the ellipsis never engaged and the name ran under "ניהול".
     display:block gives each its own box to clip against; the <br> that used
     to separate them in app.php was removed as redundant once these stack. */
  .swcomp-brand-name, .swcomp-brand-sub { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* ---------- Progress rows ---------- */

.swcomp-progress-list { display: flex; flex-direction: column; gap: var(--space-3); }
.swcomp-progress-row { display: grid; grid-template-columns: minmax(110px, 1fr) 3fr auto; gap: var(--space-3); align-items: center; font-size: var(--fs-sm); }
.swcomp-progress-name { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.swcomp-progress-row .swcomp-progress { margin: 0; height: 8px; }
.swcomp-progress-bar.is-done { background: hsl(var(--success)); }
.swcomp-progress-count { font-variant-numeric: tabular-nums; color: hsl(var(--muted-foreground)); white-space: nowrap; }

/* ---------- Bar chart ---------- */

/* Deliberately a class rather than inline styles: Alpine's :style with a
   string replaces the whole style attribute, so a bar styled inline would lose
   its width and colour the moment its height was bound. */
.swcomp-bars {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 96px;
}

.swcomp-bar-col {
  flex: 1;
  min-width: 0; /* let the column shrink below its nowrap label's content width */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
  height: 100%;
}

.swcomp-bar {
  width: 100%;
  min-height: 2px;
  background: hsl(var(--primary));
  border-radius: 3px 3px 0 0;
}
.swcomp-bar.is-empty { background: hsl(var(--border)); }

.swcomp-bar-label { font-size: 10px; color: hsl(var(--muted-foreground)); white-space: nowrap; }
.swcomp-bar-value { font-size: 10px; font-weight: 600; color: hsl(var(--foreground)); }

/* ---------- Inline edit affordance ---------- */

.swcomp-editable { position: relative; cursor: pointer; }
.swcomp-editable:hover { background: hsl(var(--accent)); }
/*
  Faint but always present, not hover-only: the pencil is what tells someone
  the cell can be edited at all, and an affordance that only appears once you
  have already found the cell is not doing that job. Hover just brings it up
  to full strength.
*/
.swcomp-edit-pencil {
  opacity: .4;
  margin-inline-start: 4px;
  color: hsl(var(--muted-foreground));
  transition: opacity .12s ease;
}
.swcomp-editable:hover .swcomp-edit-pencil,
.swcomp-editable:focus-visible .swcomp-edit-pencil { opacity: 1; }
.swcomp-edit-pencil svg { width: 12px; height: 12px; vertical-align: -1px; }

/* ---------- Danger zone ---------- */

.swcomp-danger {
  border-color: hsl(var(--destructive) / .35);
}
.swcomp-danger .swcomp-card-header h2 { color: hsl(var(--destructive)); }

/* ---------- Stats ---------- */

/* 150px, not 170px: the dashboard shows five of these, and at a typical
   1440px window 170px left the fifth one stranded on a row of its own. */
.swcomp-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--space-4); margin-bottom: var(--space-5); }
.swcomp-stat {
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  padding: var(--space-4) var(--space-5);
  box-shadow: var(--shadow-sm);
}
.swcomp-stat-label { font-size: var(--fs-xs); color: hsl(var(--muted-foreground)); font-weight: 500; }
.swcomp-stat-value { font-size: var(--fs-2xl); font-weight: 700; line-height: 1.2; margin-top: 2px; font-variant-numeric: tabular-nums; }
.swcomp-stat-sub { font-size: var(--fs-xs); color: hsl(var(--muted-foreground)); margin-top: 2px; }

/* ---------- Alerts ---------- */
/* "Callout" treatment (chosen direction #3, shadcn/ui): a card surface with
   a variant-coloured icon, not a filled colour block. The icon is a single
   CSS mask (data-URI, no extra request) so every existing template — plain
   text, x-text bindings, an inline link, a trailing action button — keeps
   working unchanged; nothing in the markup has to split into title/description. */

.swcomp-alert {
  position: relative;
  display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: flex-start;
  background: hsl(var(--card));
  color: hsl(var(--foreground));
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: var(--space-4);
  padding-inline-start: calc(var(--space-4) + 20px + var(--space-3));
  font-size: var(--fs-sm);
  margin-bottom: var(--space-4);
}
/* A trailing action button (.swcomp-btn, nowrap) competing for space with the
   message on a narrow, non-wrapping row squeezed the text to one word per
   line. flex-wrap plus a sane minimum on the message lets the button drop
   below the text instead once the row is too narrow for both. */
.swcomp-alert > span { flex: 1 1 12rem; min-width: 0; }
.swcomp-alert::before {
  content: "";
  position: absolute;
  inset-inline-start: var(--space-4);
  inset-block-start: var(--space-4);
  width: 20px; height: 20px;
  background-color: currentColor;
  -webkit-mask: var(--swcomp-alert-icon) center / contain no-repeat;
          mask: var(--swcomp-alert-icon) center / contain no-repeat;
}
.swcomp-alert-info {
  --swcomp-alert-icon: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxjaXJjbGUgY3g9IjEyIiBjeT0iMTIiIHI9IjEwIi8+PGxpbmUgeDE9IjEyIiB5MT0iMTYiIHgyPSIxMiIgeTI9IjEyIi8+PGxpbmUgeDE9IjEyIiB5MT0iOCIgeDI9IjEyLjAxIiB5Mj0iOCIvPjwvc3ZnPg==");
  color: hsl(var(--primary));
}
.swcomp-alert-warning {
  --swcomp-alert-icon: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0xMC4yOSAzLjg2IDEuODIgMThhMiAyIDAgMCAwIDEuNzEgM2gxNi45NGEyIDIgMCAwIDAgMS43MS0zTDEzLjcxIDMuODZhMiAyIDAgMCAwLTMuNDIgMFoiLz48bGluZSB4MT0iMTIiIHkxPSI5IiB4Mj0iMTIiIHkyPSIxMyIvPjxsaW5lIHgxPSIxMiIgeTE9IjE3IiB4Mj0iMTIuMDEiIHkyPSIxNyIvPjwvc3ZnPg==");
  color: hsl(var(--warning));
}
.swcomp-alert-error {
  --swcomp-alert-icon: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxjaXJjbGUgY3g9IjEyIiBjeT0iMTIiIHI9IjEwIi8+PGxpbmUgeDE9IjE1IiB5MT0iOSIgeDI9IjkiIHkyPSIxNSIvPjxsaW5lIHgxPSI5IiB5MT0iOSIgeDI9IjE1IiB5Mj0iMTUiLz48L3N2Zz4=");
  color: hsl(var(--destructive));
}
.swcomp-alert-success {
  --swcomp-alert-icon: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0yMCA2IDkgMTdsLTUtNSIvPjwvc3ZnPg==");
  color: hsl(var(--success));
}
.swcomp-alert strong { font-weight: 600; }
/* Text links in an alert take its colour; a link styled as a button keeps the button's look. */
.swcomp-alert a:not(.swcomp-btn) { color: inherit; text-decoration: underline; font-weight: 600; }

/* ---------- Toast ---------- */

.swcomp-toasts {
  position: fixed;
  inset-block-end: var(--space-5);
  inset-inline-end: var(--space-5);
  z-index: 60;
  display: flex; flex-direction: column; gap: var(--space-2);
  max-width: 360px;
}
.swcomp-toast {
  background: hsl(var(--background));
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: var(--space-3) var(--space-4);
  font-size: var(--fs-sm);
  display: flex; gap: var(--space-3); align-items: flex-start;
}
.swcomp-toast.is-success { border-inline-start: 3px solid hsl(var(--success)); }
.swcomp-toast.is-error { border-inline-start: 3px solid hsl(var(--destructive)); }
.swcomp-toast.is-info { border-inline-start: 3px solid hsl(var(--primary)); }

/* ---------- Dialog ---------- */

.swcomp-dialog-backdrop {
  position: fixed; inset: 0;
  background: rgb(0 0 0 / .55);
  z-index: 50;
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-5);
}
.swcomp-dialog {
  background: hsl(var(--background));
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  width: 100%; max-width: 480px;
  max-height: 88vh; overflow-y: auto;
}
.swcomp-dialog-header { padding: var(--space-5) var(--space-6) 0; }
.swcomp-dialog-body { padding: var(--space-4) var(--space-6); }
.swcomp-dialog-footer {
  padding: var(--space-4) var(--space-6);
  border-top: 1px solid hsl(var(--border));
  display: flex; gap: var(--space-3); justify-content: flex-end;
}
.swcomp-dialog-lg { max-width: 720px; }
.swcomp-dialog:focus { outline: none; }

/*
  A long document: only the body scrolls, so the header saying what this is and
  the footer holding "I accept" stay in view however far down someone reads.
*/
.swcomp-dialog-scroll {
  display: flex; flex-direction: column;
  overflow: hidden;
}
.swcomp-dialog-scroll .swcomp-dialog-header { flex-shrink: 0; padding-bottom: var(--space-3); border-bottom: 1px solid hsl(var(--border)); }
.swcomp-dialog-scroll .swcomp-dialog-body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.swcomp-dialog-scroll .swcomp-dialog-footer { flex-shrink: 0; flex-wrap: wrap; }
/* Pushes a secondary action (the PDF download) to the opposite edge. */
.swcomp-dialog-footer-start { margin-inline-end: auto; }

/* On a phone the row wrapped and left "I accept" stranded on a line of its
   own. Stacked instead, full width, with the main action first — the markup
   order is secondary-to-primary, so reversing the column puts it on top. */
@media (max-width: 640px) {
  .swcomp-dialog-backdrop { padding: var(--space-3); }
  .swcomp-dialog-scroll .swcomp-dialog-header,
  .swcomp-dialog-scroll .swcomp-dialog-body,
  .swcomp-dialog-scroll .swcomp-dialog-footer { padding-inline: var(--space-4); }
  .swcomp-dialog-scroll .swcomp-dialog-footer { flex-direction: column-reverse; align-items: stretch; gap: var(--space-2); }
  .swcomp-dialog-scroll .swcomp-dialog-footer .swcomp-btn { width: 100%; }
  .swcomp-dialog-scroll .swcomp-dialog-footer-start { margin-inline-end: 0; }
}

/* ---------- Long-form text: the rules ---------- */

.swcomp-prose { font-size: var(--fs-sm); line-height: 1.75; color: hsl(var(--foreground)); }
.swcomp-prose > :first-child { margin-top: 0; }
.swcomp-prose p { margin: 0 0 var(--space-3); }
.swcomp-prose h2, .swcomp-prose h3, .swcomp-prose h4 { margin: var(--space-5) 0 var(--space-2); font-size: var(--fs-base); }
.swcomp-prose ul, .swcomp-prose ol { margin: 0 0 var(--space-3); padding-inline-start: var(--space-6); }
.swcomp-prose li { margin-bottom: var(--space-1); }
.swcomp-prose a { word-break: break-word; }

/* A button that reads as a link: it opens a dialog rather than navigating. */
.swcomp-link-btn {
  background: none; border: 0; padding: 0;
  font: inherit; color: hsl(var(--primary));
  text-decoration: underline; text-underline-offset: 2px;
  cursor: pointer;
}
.swcomp-link-btn:hover { color: hsl(var(--accent-foreground)); }
.swcomp-link-btn:focus-visible { outline: 2px solid hsl(var(--ring) / .6); outline-offset: 2px; border-radius: 2px; }

.swcomp-rules-links {
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4);
  margin-top: var(--space-2);
  padding-inline-start: calc(16px + var(--space-3)); /* under the label text, past the checkbox */
  font-size: var(--fs-sm);
}

/* ---------- Attached file row (settings) ---------- */

.swcomp-textarea-tall { min-height: 260px; }

.swcomp-file-row {
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  margin-bottom: var(--space-3);
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-sm);
  background: hsl(var(--muted) / .5);
  font-size: var(--fs-sm);
}
.swcomp-file-row a { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.swcomp-file-icon { width: 18px; height: 18px; flex-shrink: 0; color: hsl(var(--muted-foreground)); }

/* ---------- Delivery log ---------- */

.swcomp-block { display: block; }
.swcomp-text-destructive { color: hsl(var(--destructive)); }

/* A failed message is the row someone came to this screen to find. */
.swcomp-table tr.is-failed > td { background: hsl(var(--destructive) / .04); }
.swcomp-table tr.is-failed > td:first-child { box-shadow: inset -3px 0 0 hsl(var(--destructive) / .6); }
[dir="ltr"] .swcomp-table tr.is-failed > td:first-child { box-shadow: inset 3px 0 0 hsl(var(--destructive) / .6); }

.swcomp-row-actions { white-space: nowrap; text-align: end; }
.swcomp-row-actions .swcomp-btn + .swcomp-btn { margin-inline-start: var(--space-1); }
/*
  Three actions on a row that already carries six columns: let them wrap onto
  a second line inside the cell rather than push the table past the card.
*/
.swcomp-row-actions.is-wrapping { white-space: normal; min-width: 12rem; }
.swcomp-row-actions.is-wrapping .swcomp-btn { margin-block: 2px; }

.swcomp-log-detail > td { background: hsl(var(--muted) / .6); }

/* The sent email, in a sandboxed frame: its own HTML, none of it able to run. */
.swcomp-mail-frame {
  display: block;
  width: 100%;
  height: 320px;
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius-sm);
  background: #fff;
}

@media (max-width: 640px) {
  .swcomp-row-actions { white-space: normal; text-align: start; }
  .swcomp-row-actions .swcomp-btn { margin-block: 2px; }
}

/* ---------- Settings tabs and the registration-form tab ---------- */

/* Page-level tabs: an underlined row, distinct from the small segmented
   .swcomp-tabs used inside a card. Scrolls sideways on a narrow screen
   rather than wrapping into two rows of tabs. */
.swcomp-page-tabs {
  display: flex; gap: var(--space-1);
  margin-bottom: var(--space-5);
  border-bottom: 1px solid hsl(var(--border));
  overflow-x: auto; scrollbar-width: none;
}
.swcomp-page-tabs::-webkit-scrollbar { display: none; }
.swcomp-page-tab {
  flex-shrink: 0;
  padding: var(--space-3) var(--space-4);
  margin-bottom: -1px;
  border: 0; border-bottom: 2px solid transparent;
  background: transparent; cursor: pointer;
  font: inherit; font-size: var(--fs-sm); font-weight: 500;
  color: hsl(var(--muted-foreground));
  white-space: nowrap;
}
.swcomp-page-tab:hover { color: hsl(var(--foreground)); }
.swcomp-page-tab.is-active { color: hsl(var(--foreground)); border-bottom-color: hsl(var(--primary)); font-weight: 600; }
.swcomp-page-tab:focus-visible { outline: none; box-shadow: inset 0 0 0 2px hsl(var(--ring) / .5); border-radius: var(--radius-sm) var(--radius-sm) 0 0; }

/* Every field on the form, one row each, required or not. */
.swcomp-field-list { list-style: none; margin: 0; padding: 0; border: 1px solid hsl(var(--border)); border-radius: var(--radius-sm); }
.swcomp-field-list li {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  font-size: var(--fs-sm);
}
.swcomp-field-list li + li { border-top: 1px solid hsl(var(--border)); }
.swcomp-field-list li.is-locked { background: hsl(var(--muted) / .45); }
.swcomp-field-list li.is-locked .swcomp-field-list-name { color: hsl(var(--muted-foreground)); padding-inline-start: calc(16px + var(--space-3)); }
.swcomp-field-list .swcomp-checkbox { margin: 0; }

/* Marks a step that already has a note, on the step selector. */
.swcomp-dot { display: inline-block; width: 6px; height: 6px; margin-inline-start: 4px; border-radius: 50%; background: hsl(var(--primary)); vertical-align: middle; }

.swcomp-settings-save { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; margin: var(--space-5) 0 var(--space-4); }

/* A manager's note on the entry form, above or below a step's content. */
.swcomp-step-note {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  background: hsl(var(--accent) / .55);
  border-inline-start: 3px solid hsl(var(--primary) / .55);
}
.swcomp-step-note > :last-child { margin-bottom: 0; }
.swcomp-step-note.is-top { margin-bottom: var(--space-5); }
.swcomp-step-note.is-bottom { margin-top: var(--space-5); }

/* ---------- Pagination ---------- */

.swcomp-pagination {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); flex-wrap: wrap;
  padding: var(--space-4) var(--space-6);
  border-top: 1px solid hsl(var(--border));
  font-size: var(--fs-sm); color: hsl(var(--muted-foreground));
}
.swcomp-pagination-controls { display: flex; gap: var(--space-2); align-items: center; }

/* ---------- Description lists ---------- */

.swcomp-dl { display: grid; grid-template-columns: max-content 1fr; gap: var(--space-2) var(--space-5); font-size: var(--fs-sm); margin: 0; }
.swcomp-dl dt { color: hsl(var(--muted-foreground)); font-weight: 500; }
.swcomp-dl dd { margin: 0; }
/* Free text someone typed with line breaks: a judge's explanation, a manager's note. */
.swcomp-pre-line { white-space: pre-line; overflow-wrap: anywhere; }
.swcomp-recusal-note { margin-top: 4px; font-size: var(--fs-xs); color: hsl(var(--muted-foreground)); max-width: 42ch; }

.swcomp-timeline { list-style: none; margin: 0; padding: 0; font-size: var(--fs-sm); }
.swcomp-timeline li {
  padding: var(--space-3) 0 var(--space-3) 0;
  border-bottom: 1px solid hsl(var(--border));
}
.swcomp-timeline li:last-child { border-bottom: none; }
.swcomp-timeline time { color: hsl(var(--muted-foreground)); font-size: var(--fs-xs); }

/* A "from → to" status change built as one text string ("א" + " → " + "ב")
   always pointed right — U+2192 has no bidi mirror, so in RTL it pointed
   back at the old value instead of forward at the new one. Three flex items
   instead of one text run: normal RTL flex places the DOM-first span (from)
   at the line's start (right) and the last span (to) at its end (left), and
   the icon is a plain SVG we draw pointing left ourselves — not text, so no
   bidi resolution applies to it either way. If this page is ever served
   LTR, flip it back. */
.swcomp-status-change { display: inline-flex; align-items: center; gap: 6px; }
.swcomp-status-change svg { width: 14px; height: 14px; flex-shrink: 0; color: hsl(var(--muted-foreground)); }
[dir="ltr"] .swcomp-status-change svg { transform: scaleX(-1); }

/* ---------- Utilities ---------- */

.swcomp-muted { color: hsl(var(--muted-foreground)); }
.swcomp-small { font-size: var(--fs-xs); }
.swcomp-strong { font-weight: 600; }
.swcomp-center { text-align: center; }
.swcomp-nowrap { white-space: nowrap; }
/* A second, quieter line in a table cell, e.g. the email under a judge's name. */
.swcomp-cell-sub { display: block; margin-top: 2px; font-size: var(--fs-xs); color: hsl(var(--muted-foreground)); overflow-wrap: anywhere; }
.swcomp-mt-4 { margin-top: var(--space-4); }
.swcomp-mb-4 { margin-bottom: var(--space-4); }
.swcomp-inline { display: inline-flex; align-items: center; gap: var(--space-2); }

.swcomp-page-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--space-4); flex-wrap: wrap;
  margin-bottom: var(--space-5);
}
.swcomp-page-head h1 { margin-bottom: 2px; }

.swcomp-spinner {
  width: 16px; height: 16px;
  border: 2px solid hsl(var(--border));
  border-top-color: hsl(var(--primary));
  border-radius: 999px;
  animation: swcomp-spin .7s linear infinite;
  display: inline-block;
}
@keyframes swcomp-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .swcomp-spinner { animation-duration: 2s; }
  * { transition-duration: .01ms !important; }
}

/* ---------- Payment ---------- */

.swcomp-payment-details { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); margin-bottom: var(--space-4); }
.swcomp-payment-details th { text-align: start; font-weight: 500; color: hsl(var(--muted-foreground)); padding: 7px 0; width: 40%; }
.swcomp-payment-details td { padding: 7px 0; font-weight: 600; }

.swcomp-sandbox-checkout {
  border: 1px dashed hsl(var(--warning) / .5);
  background: hsl(var(--warning-bg));
  border-radius: var(--radius-sm);
  padding: var(--space-5);
  text-align: center;
}
.swcomp-sandbox-amount { font-size: var(--fs-xl); font-weight: 700; }
.swcomp-sandbox-actions { display: flex; gap: var(--space-3); justify-content: center; flex-wrap: wrap; }

/* ---------- Score entry ---------- */

.swcomp-score-input {
  width: 96px;
  font-size: var(--fs-xl);
  font-weight: 700;
  text-align: center;
  height: 52px;
  font-variant-numeric: tabular-nums;
}
.swcomp-counter { font-size: var(--fs-xs); color: hsl(var(--muted-foreground)); text-align: end; margin-top: 5px; }
.swcomp-counter.is-over { color: hsl(var(--destructive)); font-weight: 600; }

/* The judging card runs in two stages: read the screenplay, then score it. */
.swcomp-stage + .swcomp-stage { margin-top: var(--space-6); padding-top: var(--space-6); border-top: 1px solid hsl(var(--border)); }
.swcomp-stage-head { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-4); }
.swcomp-stage-kicker {
  display: inline-flex; align-items: center;
  height: 24px; padding: 0 10px; border-radius: 999px;
  background: hsl(var(--primary)); color: hsl(var(--primary-foreground));
  font-size: var(--fs-xs); font-weight: 600; white-space: nowrap; flex-shrink: 0;
}
.swcomp-stage-title { margin: 0; font-size: var(--fs-base); font-weight: 600; }

.swcomp-rank-cell { font-variant-numeric: tabular-nums; text-align: center; }
.swcomp-rank-top { background: hsl(var(--accent)); }
.swcomp-winner-star { color: hsl(var(--warning)); }

/*
  Judges' scores: one line per judge inside a single cell, instead of a column
  per judge, so the table's width does not grow with the panel. Each line is
  the button that opens the score editor.
*/
.swcomp-table td.swcomp-judge-scores-cell { padding-block: 6px; width: 1%; }
.swcomp-judge-scores { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; width: 15rem; max-width: 100%; }
.swcomp-judge-score {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 2px 6px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: start;
  cursor: pointer;
}
.swcomp-judge-score:hover:not(:disabled) { background: hsl(var(--muted)); }
.swcomp-judge-score:disabled { cursor: default; }
.swcomp-judge-score:focus-visible { outline: 2px solid hsl(var(--ring)); outline-offset: -2px; }
.swcomp-judge-score:hover .swcomp-edit-pencil,
.swcomp-judge-score:focus-visible .swcomp-edit-pencil { opacity: 1; }
.swcomp-judge-score .swcomp-edit-pencil { margin: 0; }
.swcomp-judge-score-name {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: hsl(var(--muted-foreground));
}
.swcomp-judge-score-value {
  white-space: nowrap;
  min-width: 2.5ch;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: end;
}
.swcomp-judge-score-value.is-muted { font-weight: 400; font-size: 12px; color: hsl(var(--muted-foreground)); }
/* A draft counts, but may still change: same number, drawn lighter. */
.swcomp-judge-score-value.is-draft { font-weight: 400; color: hsl(var(--muted-foreground)); }
.swcomp-rank-legend {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 10px 16px;
  border-top: 1px solid hsl(var(--border));
  font-size: 12px;
  color: hsl(var(--muted-foreground));
}

/* ---------- Responsive ---------- */

@media (max-width: 1023px) {
  /* stretch, not the desktop flex-start: in a column, flex-start lets the main
     area size itself to its content, so the ranking table (a column per judge,
     too wide to restack) pushed the whole page sideways instead of scrolling
     inside its own .swcomp-table-wrap. */
  .swcomp-shell { flex-direction: column; align-items: stretch; padding: var(--space-4); gap: var(--space-4); }
  .swcomp-sidebar { width: 100%; position: static; }
  .swcomp-nav { flex-direction: row; overflow-x: auto; gap: var(--space-1); }
  .swcomp-nav-item { white-space: nowrap; }
}

@media (max-width: 640px) {
  .swcomp-narrow { padding: var(--space-4); }
  .swcomp-card-header, .swcomp-card-content { padding-inline: var(--space-4); }
  .swcomp-card-footer, .swcomp-toolbar, .swcomp-pagination { padding-inline: var(--space-4); }
  /* minmax(0, 1fr), not a bare 1fr: a bare 1fr track's automatic minimum is
     its content's min-content, not 0, so unshrinkable content (the bar
     chart's 14 nowrap date labels, e.g.) forced the track past the grid's own
     width — two dashboard cards were rendering ~20px wider than the page,
     landing 1px off its left edge. */
  /* row-gap: 0 — stacked to one column, the grid's own gap (meant as the
     horizontal space between columns) now also runs vertically between the
     stacked cells, on top of each .swcomp-field's own margin-bottom. Left in,
     two fields that happened to share a row-2 got visibly more space between
     them than two that were just consecutive in the flow. Card rows keep the
     gap: they have no field margin to lean on. */
  .swcomp-row-2, .swcomp-row-3 { grid-template-columns: minmax(0, 1fr); row-gap: 0; }
  .swcomp-row-2:has(> .swcomp-card),
  .swcomp-row-3:has(> .swcomp-card) { row-gap: var(--space-4); }
  .swcomp-step-label { display: none; }
  .swcomp-step.is-active .swcomp-step-label { display: inline; }
  .swcomp-dl { grid-template-columns: 1fr; gap: 2px var(--space-4); }
  .swcomp-dl dt { margin-top: var(--space-2); }

  /* 14 nowrap date labels have nowhere near enough room on a phone — thin
     them to every other day (today, the first column, stays put) rather than
     shrinking the font past legible or truncating them. Every bar and its
     value count stay, so the shape of the two weeks is still intact. */
  .swcomp-bar-col:nth-child(even) .swcomp-bar-label { visibility: hidden; }
  .swcomp-toasts { inset-inline: var(--space-4); max-width: none; }

  /* Tables become cards: a 9-column entry table is unreadable on a phone,
     and horizontal scrolling hides the columns that matter most. */
  .swcomp-table.is-stacked thead { display: none; }
  .swcomp-table.is-stacked tbody tr {
    display: block;
    border: 1px solid hsl(var(--border));
    border-radius: var(--radius-sm);
    margin-bottom: var(--space-3);
    padding: var(--space-2) var(--space-3);
    background: hsl(var(--background));
  }
  .swcomp-table.is-stacked td {
    display: flex; justify-content: space-between; gap: var(--space-4);
    border: none; padding: 5px 0; text-align: start;
  }
  .swcomp-table.is-stacked td::before {
    content: attr(data-label);
    font-weight: 500;
    color: hsl(var(--muted-foreground));
    flex-shrink: 0;
  }
  .swcomp-table.is-stacked td:empty { display: none; }
  /* A cell is a flex row here, so a row of buttons has to be told it may wrap. */
  .swcomp-table.is-stacked td.swcomp-row-actions { flex-wrap: wrap; justify-content: flex-start; gap: var(--space-1) var(--space-2); }
  .swcomp-table.is-stacked td.swcomp-row-actions .swcomp-btn + .swcomp-btn { margin-inline-start: 0; }
}

/* ---------- Avatars ---------- */

/* A picture, or two initials on one of six colours: the colour comes from the
   user id, so the same person is always the same colour. */
.swcomp-avatar {
  --avatar-size: 36px;
  width: var(--avatar-size); height: var(--avatar-size);
  flex-shrink: 0;
  border-radius: 50%;
  overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: calc(var(--avatar-size) * .4); font-weight: 600; line-height: 1;
  background: hsl(var(--avatar-bg, var(--secondary)));
  color: hsl(var(--avatar-fg, var(--secondary-foreground)));
  user-select: none;
}
.swcomp-avatar img { width: 100%; height: 100%; max-width: none; object-fit: cover; display: block; }
.swcomp-avatar-sm { --avatar-size: 28px; }
.swcomp-avatar-md { --avatar-size: 36px; }
.swcomp-avatar-lg { --avatar-size: 48px; }
.swcomp-avatar-xl { --avatar-size: 96px; }
.swcomp-avatar.is-tone-1 { --avatar-bg: 180 60% 90%; --avatar-fg: 180 100% 20%; }
.swcomp-avatar.is-tone-2 { --avatar-bg: 230 70% 92%; --avatar-fg: 230 55% 35%; }
.swcomp-avatar.is-tone-3 { --avatar-bg: 38 90% 88%; --avatar-fg: 28 80% 30%; }
.swcomp-avatar.is-tone-4 { --avatar-bg: 345 70% 92%; --avatar-fg: 345 60% 36%; }
.swcomp-avatar.is-tone-5 { --avatar-bg: 150 50% 88%; --avatar-fg: 150 60% 22%; }
.swcomp-avatar.is-tone-6 { --avatar-bg: 270 60% 92%; --avatar-fg: 270 45% 38%; }

/* ---------- Header account menu ---------- */

.swcomp-user-menu { position: relative; }

.swcomp-user-trigger {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding-block: 3px;
  padding-inline: 3px var(--space-2);
  border: 1px solid transparent;
  border-radius: 999px;
  background: transparent;
  color: hsl(var(--foreground));
  font-family: inherit; font-size: var(--fs-sm);
  cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease;
}
.swcomp-user-trigger:hover,
.swcomp-user-trigger[aria-expanded="true"] { background: hsl(var(--secondary)); border-color: hsl(var(--border)); }
.swcomp-user-trigger:focus-visible { outline: none; box-shadow: 0 0 0 2px hsl(var(--background)), 0 0 0 4px hsl(var(--ring) / .5); }
.swcomp-user-trigger-name { color: hsl(var(--muted-foreground)); max-width: 14rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.swcomp-user-trigger-chevron { color: hsl(var(--muted-foreground)); transition: transform .15s ease; }
.swcomp-user-trigger[aria-expanded="true"] .swcomp-user-trigger-chevron { transform: rotate(180deg); }

/* Above the header (20), below dialogs (50). Opens towards the page, under
   the button, aligned with the header's end edge. */
.swcomp-menu {
  position: absolute;
  top: calc(100% + 6px);
  inset-inline-end: 0;
  z-index: 30;
  width: 290px;
  max-width: calc(100vw - 2 * var(--space-4));
  padding: var(--space-1);
  background: hsl(var(--popover));
  color: hsl(var(--popover-foreground));
  border: 1px solid hsl(var(--border));
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
}

.swcomp-menu-card { display: flex; gap: var(--space-3); align-items: center; padding: var(--space-3); }
.swcomp-menu-card-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; font-size: var(--fs-xs); line-height: 1.45; }
.swcomp-menu-card-text strong { font-size: var(--fs-sm); font-weight: 600; }
.swcomp-menu-card-text > * { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.swcomp-menu-email { text-align: end; }

.swcomp-menu-progress { margin: 0 var(--space-3) var(--space-2); padding: var(--space-3); border-radius: var(--radius-sm); background: hsl(var(--muted)); font-size: var(--fs-xs); }
.swcomp-menu-progress .swcomp-progress { margin-top: var(--space-2); }

.swcomp-menu-sep { height: 1px; margin: var(--space-1) 0; background: hsl(var(--border)); }

.swcomp-menu-item {
  display: flex; align-items: center; gap: var(--space-3);
  padding: 8px var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  color: hsl(var(--foreground));
  text-decoration: none;
}
.swcomp-menu-item svg { flex-shrink: 0; color: hsl(var(--muted-foreground)); }
.swcomp-menu-item:hover,
.swcomp-menu-item:focus-visible { background: hsl(var(--accent)); color: hsl(var(--accent-foreground)); outline: none; }
.swcomp-menu-item:hover svg,
.swcomp-menu-item:focus-visible svg { color: currentColor; }

/* On a phone the avatar alone stands for the account (the name gave way in
   the header before), and the menu spans the screen under the header. */
@media (max-width: 640px) {
  .swcomp-user-trigger-name { display: none; }
  .swcomp-user-trigger { padding-inline: 3px 6px; }
  .swcomp-menu {
    position: fixed;
    top: calc(var(--sticky-header, var(--header-height)) + 4px);
    inset-inline: var(--space-3);
    width: auto;
    max-width: none;
  }
}

/* ---------- Profile screen ---------- */

.swcomp-profile-avatar-row { display: flex; align-items: center; gap: var(--space-5); flex-wrap: wrap; margin-bottom: var(--space-5); }
.swcomp-profile-avatar-actions { flex: 1 1 14rem; min-width: 0; }
.swcomp-profile-count { text-align: end; font-variant-numeric: tabular-nums; }

/* Cropping: the image sits at natural size and moves by transform; the round
   hole in the mask is what will be kept. dir="ltr" on the element, so the
   coordinates are the same in a right-to-left page. */
.swcomp-crop-dialog { max-width: 420px; }
.swcomp-crop {
  position: relative;
  width: min(100%, 320px);
  aspect-ratio: 1;
  margin: 0 auto;
  overflow: hidden;
  border-radius: var(--radius);
  background: #18181b;
  touch-action: none;
  cursor: grab;
  user-select: none;
}
.swcomp-crop:active { cursor: grabbing; }
.swcomp-crop:focus-visible { outline: 2px solid hsl(var(--ring)); outline-offset: 3px; }
.swcomp-crop img {
  position: absolute; left: 0; top: 0;
  max-width: none; height: auto;
  transform-origin: 0 0;
  pointer-events: none;
}
.swcomp-crop-mask {
  position: absolute; inset: 0;
  border-radius: 50%;
  border: 2px solid rgb(255 255 255 / .85);
  box-shadow: 0 0 0 999px rgb(0 0 0 / .55);
  pointer-events: none;
}
.swcomp-crop-zoom { display: flex; align-items: center; gap: var(--space-3); margin: var(--space-4) auto 0; width: min(100%, 320px); color: hsl(var(--muted-foreground)); }
.swcomp-crop-zoom input[type="range"] { flex: 1; accent-color: hsl(var(--primary)); }

/* ---------- Judge profile, as managers see it ---------- */

.swcomp-person { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.swcomp-person-text { min-width: 0; }
.swcomp-judge-profile { display: flex; gap: var(--space-5); align-items: flex-start; }
.swcomp-judge-profile .swcomp-pre-line { margin: var(--space-2) 0 0; }
@media (max-width: 640px) {
  .swcomp-judge-profile { flex-direction: column; gap: var(--space-3); }
}
/* ---------- Payments ledger (entry page) ---------- */

/* Paid · refunded · net · fee, in one row that wraps on a phone. */
.swcomp-ledger-totals {
  display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-6);
  margin: 0; padding: var(--space-3) var(--space-4);
  background: hsl(var(--muted) / .6); border-radius: var(--radius-sm);
}
.swcomp-ledger-totals > div { display: flex; flex-direction: column; min-width: 90px; }
.swcomp-ledger-totals dt { font-size: var(--fs-xs); color: hsl(var(--muted-foreground)); }
.swcomp-ledger-totals dd { margin: 0; font-variant-numeric: tabular-nums; font-size: var(--fs-base); }

/* Attempts that took no money: folded away, they are for when something went wrong. */
.swcomp-ledger-attempts > summary { cursor: pointer; font-size: var(--fs-sm); color: hsl(var(--muted-foreground)); padding: var(--space-2) 0; }
.swcomp-ledger-attempts[open] > summary { margin-bottom: var(--space-2); }

/* ---------- Entrant card: a manager's read-only view, and a copied link ---------- */

.swcomp-card-preview-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); }
.swcomp-card-link { border-top: 1px solid hsl(var(--border)); padding-top: var(--space-4); }

/* A table with many columns (the entries list has nine): the same look with
   less air between the columns, so short fixed fields like a phone number or a
   date keep their own line and the long names take the slack. */
.swcomp-table.is-dense th,
.swcomp-table.is-dense td { padding-inline: 10px; }

/* A row of buttons on the right of a page heading (pause, resume, send now). */
.swcomp-page-actions { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }

/* A stat whose value is a date or a time, not a number: the big numeric size
   would wrap a formatted date onto three lines in the queue card. */
.swcomp-stat-value-sm { font-size: var(--fs-base); font-weight: 600; line-height: 1.3; margin-top: 2px; }
