/* ============================================================================
   CoverSmart Design System — Components (opt-in, cs-* namespaced)
   ----------------------------------------------------------------------------
   Every class is prefixed .cs- so it CANNOT collide with existing page CSS.
   Adopt incrementally: swap a page's ad-hoc buttons/cards/inputs for these,
   then delete the page's duplicated rules. Toast styling lives in ui.js.
   ============================================================================ */

/* ── Buttons ────────────────────────────────────────────── */
.cs-btn {
  font-family: var(--cs-font-ui);
  font-weight: 600;
  font-size: var(--cs-fs-sm);
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--cs-space-2);
  padding: 10px 18px;
  border-radius: var(--cs-r);
  border: 1px solid transparent;
  transition: background var(--cs-transition), border-color var(--cs-transition),
              color var(--cs-transition), box-shadow var(--cs-transition), transform .05s ease;
  text-decoration: none;
  white-space: nowrap;
  user-select: none;
}
.cs-btn:active { transform: translateY(1px); }
.cs-btn:focus-visible { outline: none; box-shadow: var(--cs-ring); }
.cs-btn[disabled], .cs-btn.is-disabled { opacity: .5; cursor: not-allowed; pointer-events: none; }

.cs-btn--primary   { background: var(--cs-brand); color: var(--cs-on-brand); }
.cs-btn--primary:hover  { background: var(--cs-brand-hover); }
.cs-btn--primary:active { background: var(--cs-brand-active); }

.cs-btn--secondary { background: var(--cs-surface); color: var(--cs-ink); border-color: var(--cs-border-strong); }
.cs-btn--secondary:hover { border-color: var(--cs-brand); color: var(--cs-brand); }

.cs-btn--ghost { background: transparent; color: var(--cs-brand); }
.cs-btn--ghost:hover { background: var(--cs-brand-soft); }

.cs-btn--danger { background: var(--cs-error); color: #fff; }
.cs-btn--danger:hover { filter: brightness(.94); }

.cs-btn--sm { padding: 7px 13px; font-size: var(--cs-fs-xs); }
.cs-btn--lg { padding: 13px 24px; font-size: 15px; }

/* ── Form controls ──────────────────────────────────────── */
.cs-input, .cs-select, .cs-textarea {
  font-family: var(--cs-font-ui);
  font-size: var(--cs-fs-sm);
  line-height: 1.45;
  color: var(--cs-ink);
  background: var(--cs-surface);
  border: 1px solid var(--cs-border-strong);
  border-radius: var(--cs-r);
  padding: 10px 13px;
  width: 100%;
  transition: border-color var(--cs-transition), box-shadow var(--cs-transition), background var(--cs-transition);
}
.cs-input:hover:not(:focus), .cs-select:hover:not(:focus), .cs-textarea:hover:not(:focus) {
  border-color: var(--cs-ink-3);
}
.cs-input:focus, .cs-select:focus, .cs-textarea:focus {
  outline: none;
  border-color: var(--cs-brand);
  box-shadow: var(--cs-ring);
}
.cs-input::placeholder, .cs-textarea::placeholder { color: var(--cs-ink-3); }
.cs-input:disabled, .cs-select:disabled, .cs-textarea:disabled {
  background: var(--cs-surface-2);
  color: var(--cs-ink-3);
  cursor: not-allowed;
}

/* Native select arrow varies wildly per platform — replace it with our own so
   a select reads as the same control as an input. */
.cs-select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 38px;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2364748B' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  cursor: pointer;
}

.cs-textarea { resize: vertical; }

.cs-field { display: flex; flex-direction: column; gap: var(--cs-space-2); min-width: 0; }
.cs-field > label {
  font-size: var(--cs-fs-xs);
  font-weight: 600;
  color: var(--cs-ink-2);
  display: flex;
  align-items: center;
  gap: 5px;
}
/* Helper text. Deliberately NOT scoped to a direct child of .cs-field — it is
   often wrapped (e.g. sharing a row with a character counter). */
.cs-help,
.cs-field > small {
  font-size: var(--cs-fs-label);
  color: var(--cs-ink-3);
  line-height: var(--cs-lh-snug);
}

/* ── Section divider with a caption ─────────────────────── */
.cs-section {
  display: flex;
  align-items: center;
  gap: var(--cs-space-3);
  font-size: var(--cs-fs-label);
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--cs-ink-3);
}
.cs-section::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--cs-border);
}

/* ── Card ───────────────────────────────────────────────── */
.cs-card {
  background: var(--cs-surface);
  border: 1px solid var(--cs-border);
  border-radius: var(--cs-r-lg);
  box-shadow: var(--cs-shadow-sm);
}
.cs-card--pad { padding: var(--cs-space-5); }

/* ── Badges (semantic) ──────────────────────────────────── */
.cs-badge {
  font-size: var(--cs-fs-label);
  font-weight: 650;
  padding: 4px 11px;
  border-radius: var(--cs-r-pill);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  line-height: 1.4;
}
.cs-badge::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.cs-badge--success { background: var(--cs-success-bg); color: var(--cs-success-ink); }
.cs-badge--warning { background: var(--cs-warning-bg); color: var(--cs-warning-ink); }
.cs-badge--error   { background: var(--cs-error-bg);   color: var(--cs-error-ink); }
.cs-badge--info    { background: var(--cs-info-bg);    color: var(--cs-info-ink); }
.cs-badge--neutral { background: var(--cs-surface-2);  color: var(--cs-ink-2); }

/* ── Modal / dialog ─────────────────────────────────────────
   Toggle with .is-open (never inline styles). Lock scroll with the
   body.cs-no-scroll class — NOT body.style.overflow, which other page scripts
   reset to 'auto' on their own close and would silently unlock ours. */
.cs-no-scroll { overflow: hidden !important; }

.cs-modal {
  position: fixed;
  inset: 0;
  z-index: var(--cs-z-modal);
  display: none;
  align-items: flex-start;
  justify-content: center;
  padding: var(--cs-space-4);
  background: rgba(15, 23, 41, .55);
  backdrop-filter: blur(8px);
  /* Last-resort escape hatch: if a dialog's content genuinely cannot shrink
     (a min-height'd child, a wide table), the OVERLAY scrolls rather than the
     content being clipped with no way to reach it. */
  overflow-y: auto;
  overscroll-behavior: contain;
}
.cs-modal.is-open { display: flex; }

.cs-modal__dialog {
  background: var(--cs-surface);
  border: 1px solid var(--cs-border);
  border-radius: var(--cs-r-lg);
  box-shadow: var(--cs-shadow-lg);
  width: 100%;
  max-width: 520px;
  /* dvh first (mobile browser chrome shrinks the visual viewport), vh fallback */
  max-height: calc(100vh - 2 * var(--cs-space-4));
  max-height: calc(100dvh - 2 * var(--cs-space-4));
  margin: auto;              /* vertically centres while it still fits */
  display: flex;
  flex-direction: column;
  min-height: 0;             /* lets the flex child actually shrink */
  animation: cs-modal-in .22s cubic-bezier(.2, .8, .2, 1);
}
.cs-modal__dialog--sm { max-width: 400px; }
.cs-modal__dialog--md { max-width: 560px; }
.cs-modal__dialog--lg { max-width: 760px; }

/* A <form> (or any wrapper) between the dialog and its header/body/footer must
   BECOME the flex column, otherwise .cs-modal__body has no bounded height and
   its overflow-y never engages — the content just runs off the dialog with
   nothing to scroll. This is the rule that makes tall forms work.
   The :not([hidden]) guard matters: display:flex would otherwise beat the
   hidden attribute's UA display:none and un-hide swapped-out panels. */
.cs-modal__dialog > form:not([hidden]),
.cs-modal__dialog > div:not([hidden]):not([class*="cs-modal__"]) {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}
.cs-modal [hidden] { display: none !important; }

@keyframes cs-modal-in {
  from { opacity: 0; transform: translateY(8px) scale(.97); }
  to   { opacity: 1; transform: none; }
}

.cs-modal__header {
  flex: 0 0 auto;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--cs-space-4);
  padding: var(--cs-space-5) var(--cs-space-5) var(--cs-space-4);
  border-bottom: 1px solid var(--cs-border);
}
.cs-modal__title { font-size: var(--cs-fs-h3); font-weight: 700; color: var(--cs-ink); line-height: var(--cs-lh-snug); }
.cs-modal__subtitle { font-size: var(--cs-fs-xs); color: var(--cs-ink-3); margin-top: var(--cs-space-1); line-height: var(--cs-lh-snug); }

.cs-modal__close {
  flex: none;
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--cs-ink-3);
  font-size: 20px;
  line-height: 1;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin: -4px -6px 0 0;
  border-radius: var(--cs-r-sm);
  transition: color var(--cs-transition), background var(--cs-transition);
}
.cs-modal__close:hover { color: var(--cs-ink); background: var(--cs-surface-2); }
.cs-modal__close:focus-visible { outline: none; box-shadow: var(--cs-ring); }

.cs-modal__body {
  flex: 1 1 auto;
  min-height: 0;             /* required for overflow-y to take effect */
  padding: var(--cs-space-5);
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  gap: var(--cs-space-5);

  /* Scroll shadows: a soft shading appears at whichever edge has more content
     out of view, and disappears when you reach that end. Without this a scrollable
     panel reads as clipped-and-broken rather than scrollable — macOS/iOS hide
     overlay scrollbars until you actually scroll. Pure CSS: the `local` layers
     move with the content and mask the fixed `scroll` shadow layers.
     Order matters — masks must be painted ON TOP of the shadows. */
  background:
    /* masks (scroll with content) */
    linear-gradient(var(--cs-surface) 30%, transparent) top    / 100% 20px no-repeat local,
    linear-gradient(transparent, var(--cs-surface) 70%) bottom / 100% 20px no-repeat local,
    /* shadows (pinned to the viewport of the scroller) */
    radial-gradient(farthest-side at 50% 0,   rgba(15, 23, 41, .13), transparent) top    / 100% 8px no-repeat,
    radial-gradient(farthest-side at 50% 100%, rgba(15, 23, 41, .13), transparent) bottom / 100% 8px no-repeat;
  background-color: var(--cs-surface);
}
.cs-modal__footer {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--cs-space-3);
  padding: var(--cs-space-4) var(--cs-space-5);
  border-top: 1px solid var(--cs-border);
  background: var(--cs-surface);
  border-radius: 0 0 var(--cs-r-lg) var(--cs-r-lg);
}

/* Scrollbar inside the body reads as part of the panel, not the page */
.cs-modal__body::-webkit-scrollbar { width: 10px; }
.cs-modal__body::-webkit-scrollbar-track { background: transparent; }
.cs-modal__body::-webkit-scrollbar-thumb {
  background: var(--cs-border-strong);
  border-radius: var(--cs-r-pill);
  border: 3px solid var(--cs-surface);
}
.cs-modal__body::-webkit-scrollbar-thumb:hover { background: var(--cs-ink-3); }

@media (max-width: 560px) {
  .cs-modal { padding: var(--cs-space-2); align-items: flex-end; }
  .cs-modal__dialog { max-height: calc(100dvh - 2 * var(--cs-space-2)); }
  .cs-modal__header, .cs-modal__body { padding-left: var(--cs-space-4); padding-right: var(--cs-space-4); }
  .cs-modal__footer { padding-left: var(--cs-space-4); padding-right: var(--cs-space-4); }
}

/* ── Tabs (segmented control) ───────────────────────────────
   Use role="tablist" / role="tab" + aria-selected on the buttons. */
.cs-tabs {
  display: flex;
  gap: 3px;
  padding: 4px;
  background: var(--cs-surface-2);
  border: 1px solid var(--cs-border);
  border-radius: 12px;
}
.cs-tab {
  flex: 1;
  font-family: var(--cs-font-ui);
  font-size: var(--cs-fs-sm);
  font-weight: 600;
  color: var(--cs-ink-3);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 9px;
  padding: 10px 12px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  white-space: nowrap;
  transition: background var(--cs-transition), color var(--cs-transition),
              box-shadow var(--cs-transition), border-color var(--cs-transition);
}
.cs-tab:hover { color: var(--cs-ink-2); background: rgba(255, 255, 255, .6); }
.cs-tab:focus-visible { outline: none; box-shadow: var(--cs-ring); }
.cs-tab.is-active {
  background: var(--cs-surface);
  color: var(--cs-brand);
  border-color: var(--cs-brand-200);
  box-shadow: var(--cs-shadow-sm);
}
.cs-tab.is-active:hover { background: var(--cs-surface); }

/* ── Radio group ────────────────────────────────────────────
   Markup: label.cs-radio > input[type=radio] + span
   The native input is hidden and replaced by a drawn dot, so the control looks
   identical across platforms. Add data-tone="danger|warning|info" to tint the
   selected state semantically (e.g. severity levels). */
.cs-radio-group { display: flex; flex-wrap: wrap; gap: var(--cs-space-2); }
.cs-radio {
  flex: 1 1 0;
  min-width: 92px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: var(--cs-fs-sm);
  font-weight: 500;
  color: var(--cs-ink-2);
  background: var(--cs-surface);
  border: 1px solid var(--cs-border-strong);
  border-radius: var(--cs-r);
  padding: 10px 14px;
  cursor: pointer;
  user-select: none;
  transition: border-color var(--cs-transition), background var(--cs-transition),
              color var(--cs-transition), box-shadow var(--cs-transition);
}
.cs-radio:hover { border-color: var(--cs-ink-3); background: var(--cs-surface-2); }

/* Hide the native control, keep it focusable and screen-reader visible */
.cs-radio > input {
  appearance: none;
  -webkit-appearance: none;
  margin: 0;
  flex: none;
  width: 16px;
  height: 16px;
  border: 1.5px solid var(--cs-border-strong);
  border-radius: 50%;
  cursor: pointer;
  transition: border-color var(--cs-transition), border-width var(--cs-transition);
}
.cs-radio > input:checked {
  border-width: 5px;
  border-color: var(--cs-brand);
}

.cs-radio:has(> input:checked) {
  border-color: var(--cs-brand);
  background: var(--cs-brand-soft);
  color: var(--cs-brand);
  font-weight: 650;
}
.cs-radio:has(> input:focus-visible) { box-shadow: var(--cs-ring); border-color: var(--cs-brand); }

/* Semantic tints for the selected state */
.cs-radio[data-tone="danger"]:has(> input:checked) {
  border-color: var(--cs-error); background: var(--cs-error-bg); color: var(--cs-error-ink);
}
.cs-radio[data-tone="danger"] > input:checked { border-color: var(--cs-error); }
.cs-radio[data-tone="warning"]:has(> input:checked) {
  border-color: var(--cs-warning); background: var(--cs-warning-bg); color: var(--cs-warning-ink);
}
.cs-radio[data-tone="warning"] > input:checked { border-color: var(--cs-warning); }
.cs-radio[data-tone="info"]:has(> input:checked) {
  border-color: var(--cs-info); background: var(--cs-info-bg); color: var(--cs-info-ink);
}
.cs-radio[data-tone="info"] > input:checked { border-color: var(--cs-info); }

/* ── Dropzone + thumbnails ──────────────────────────────────
   The <input type="file"> is visually hidden; the .cs-dropzone is the click and
   drop target (give it role="button" tabindex="0" and handle Enter/Space). */
.cs-dropzone {
  display: flex;
  align-items: center;
  gap: var(--cs-space-4);
  text-align: left;
  padding: var(--cs-space-4);
  background: var(--cs-surface-2);
  border: 1.5px dashed var(--cs-border-strong);
  border-radius: var(--cs-r);
  cursor: pointer;
  transition: border-color var(--cs-transition), background var(--cs-transition);
}
.cs-dropzone:hover,
.cs-dropzone.is-dragover {
  border-color: var(--cs-brand);
  background: var(--cs-brand-soft);
}
.cs-dropzone.is-dragover { border-style: solid; }
.cs-dropzone:hover .cs-dropzone__icon,
.cs-dropzone.is-dragover .cs-dropzone__icon { color: var(--cs-brand); background: var(--cs-surface); }
.cs-dropzone:focus-visible { outline: none; box-shadow: var(--cs-ring); border-color: var(--cs-brand); }
.cs-dropzone.is-disabled { opacity: .6; cursor: not-allowed; pointer-events: none; }

.cs-dropzone__icon {
  flex: none;
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--cs-r-sm);
  background: var(--cs-surface);
  border: 1px solid var(--cs-border);
  color: var(--cs-ink-3);
  transition: color var(--cs-transition), background var(--cs-transition);
}
.cs-dropzone__copy { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cs-dropzone__text { font-size: var(--cs-fs-sm); font-weight: 600; color: var(--cs-ink-2); }
.cs-dropzone__hint { font-size: var(--cs-fs-label); color: var(--cs-ink-3); line-height: var(--cs-lh-snug); }

.cs-thumbs { display: flex; flex-wrap: wrap; gap: var(--cs-space-3); }
.cs-thumb {
  position: relative;
  width: 84px;
  border-radius: var(--cs-r-sm);
  overflow: hidden;
  border: 1px solid var(--cs-border);
  background: var(--cs-surface-2);
}
.cs-thumb {
  box-shadow: var(--cs-shadow-sm);
  transition: border-color var(--cs-transition), transform var(--cs-transition);
}
.cs-thumb:hover { border-color: var(--cs-border-strong); transform: translateY(-1px); }
.cs-thumb > img { display: block; width: 100%; height: 62px; object-fit: cover; }
.cs-thumb__meta {
  font-size: 10px;
  font-weight: 600;
  color: var(--cs-ink-3);
  padding: 4px 6px;
  background: var(--cs-surface);
  border-top: 1px solid var(--cs-border);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cs-thumb__remove {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--cs-r-pill);
  background: rgba(15, 23, 41, .78);
  color: #fff;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--cs-transition), background var(--cs-transition);
}
.cs-thumb:hover .cs-thumb__remove,
.cs-thumb__remove:focus-visible { opacity: 1; }
.cs-thumb__remove:hover { background: var(--cs-error); }
.cs-thumb__remove:focus-visible { outline: none; box-shadow: var(--cs-ring); }
/* Touch devices have no hover — never hide the only way to remove a file */
@media (hover: none) {
  .cs-thumb__remove { opacity: 1; }
}

/* ── Visually-hidden (screen-reader only) ───────────────────── */
.cs-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;
}
